<commit_before>#include "zmq.h"
#include <iostream>
#include "AliHLTDataTypes.h"
#include "AliHLTComponent.h"
#include "AliHLTMessage.h"
#include "TClass.h"
#include "TMap.h"
#include "TPRegexp.h"
#include "TObjString.h"
#include "TList.h"
#include "TMessage.h"
#include "TRint.h"
#include "TApplication.h"
#include <time.h>
#include <string>
#include <map>
#include "AliZMQhelpers.h"

//this is meant to become a class, hence the structure with global vars etc.
//Also the code is rather flat - it is a bit of a playground to test ideas.
//TODO structure this at some point, e.g. introduce a SIMPLE unified way of handling
//zmq payloads, maybe a AliZMQmessage class which would by default be multipart and provide
//easy access to payloads based on topic or so (a la HLT GetFirstInputObject() etc...)

//methods
int ProcessOptionString(TString arguments);
int InitZMQ();
void* work(void* param);
int Run();

//configuration vars
TString fZMQconfigIN   = "";
TString fZMQconfigOUT  = "";
TString fZMQconfigMON  = "";

Bool_t  fSendOnMerge = kTRUE;
Bool_t  fResetOnSend = kFALSE;

//ZMQ stuff
void* fZMQcontext = NULL;    //ze zmq context

void* fZMQmon = NULL;        //the request-reply socket, here we request the merged data
void* fZMQout = NULL;        //the monitoring socket, here we publish a copy of the data
void* fZMQin  = NULL;        //the in socket - entry point for the data to be merged.
int inType = -1;
int outType = -1;
int monType = -1;

int fZMQtimeout = -1;
int fZMQmaxQueueSize = 100;
int fSleep = 0;
bool fVerbose = false;

const char* fUSAGE =
  "ZMQproxy: a simple monitored ZMQ proxy\n"
  "options:\n"
  " -in : socket in\n"
  " -out : socket out\n"
  " -mon : monitor socket\n"
  " -sleep : sleep between polls (ms) (if in is a REQ socket)\n"
  " -timeout : timeout for a poll (ms)\n"
  ;

int capture(void* capture, zmq_msg_t* msg, int more = 0)
{
  int rc = 0;
  if (!capture) return 0;
  zmq_msg_t ctrl;
  rc = zmq_msg_init(&ctrl);
  if (rc<0) return -1;
  rc = zmq_msg_copy(&ctrl, msg);
  if (rc<0) return -1;
  return zmq_msg_send(&ctrl, capture, more?ZMQ_SNDMORE:0);
}

int forward(void* from, void* to, void* mon, zmq_msg_t* msg)
{
  int rc = 0;
  int more = 0;
  size_t moresize = sizeof(more);
  while (true)
  {
    rc = zmq_msg_recv(msg,from,0);
    if (rc<0) return -1;
    rc = zmq_getsockopt(from, ZMQ_RCVMORE, &more, &moresize);
    if (from!=mon) {
      rc = capture(mon,msg,more);
    }
    if (rc<0) return -1;
    rc = zmq_msg_send(msg,to,more?ZMQ_SNDMORE:0);
    if (rc<0) return -1;
    if (more==0) break;
  }
  if (fVerbose) printf("forwarded...\n");
  return 0;
}

//_______________________________________________________________________________________
int Run()
{
  int rc = 0;

  bool interrunpted = false;
  while (!interrunpted)
  {
    //send the requests first
    //it is OK to block if there is no remote end
    //the use case is to go from REQ->PUB for the event display
    //otherwise the reconnect can take a while
    if (inType==ZMQ_REQ) {
      if (fVerbose) printf("requesting on %p %s\n",fZMQin, fZMQconfigIN.Data());
      rc = alizmq_msg_send("","",fZMQin,0);
    }
    if (outType==ZMQ_REQ) {
      if (fVerbose) printf("requesting on %s\n",fZMQconfigOUT.Data());
      alizmq_msg_send("","",fZMQout,0);
    }

    //poll socket readiness for sending
    Int_t noutSockets=2;
    zmq_pollitem_t outSockets[] = {
      { fZMQin, 0, ZMQ_POLLOUT, 0 },
      { fZMQout, 0, ZMQ_POLLOUT, 0 },
      { fZMQmon, 0, ZMQ_POLLOUT, 0 },
    };
    rc = zmq_poll(outSockets, noutSockets, fZMQtimeout); //poll outSockets
    if (rc==-1 && errno==ETERM)
    {
      //this can only happen if the context was terminated, one of the inSockets are
      //not valid or operation was interrupted
      Printf("zmq_poll (out) was interrupted! rc = %i, %s", rc, zmq_strerror(errno));
      break;
    }
    //in
    if (outSockets[0].revents & ZMQ_POLLOUT)
    {
      if (fVerbose) printf("socket (%p) %s signals ZMQ_POLLOUT\n",fZMQin, fZMQconfigIN.Data());
    }
    //out
    if (outSockets[1].revents & ZMQ_POLLOUT)
    {
      if (fVerbose) printf("socket %p (%s) signals ZMQ_POLLOUT\n", fZMQout, fZMQconfigOUT.Data());
    }
    //mon
    if (outSockets[2].revents & ZMQ_POLLOUT)
    {
      if (fVerbose) printf("socket %p (%s) signals ZMQ_POLLOUT\n", fZMQmon, fZMQconfigMON.Data());
    }

    //poll incoming data
    Int_t ninSockets=3;
    zmq_pollitem_t inSockets[] = {
      { fZMQin, 0, ZMQ_POLLIN, 0 },
      { fZMQout, 0, ZMQ_POLLIN, 0 },
      { fZMQmon, 0, ZMQ_POLLIN, 0 },
    };

    if (fVerbose) printf("starting poll in\n");
    int pollrc = zmq_poll(inSockets, ninSockets, fZMQtimeout); //poll inSockets
    if (pollrc==-1 && errno==ETERM)
    {
      //this can only happen if the context was terminated, one of the inSockets are
      //not valid or operation was interrupted
      Printf("zmq_poll (in) was interrupted! rc = %i, %s", rc, zmq_strerror(errno));
      break;
    }

    zmq_msg_t msg;
    zmq_msg_init(&msg);
    //in
    if (inSockets[0].revents & ZMQ_POLLIN)
    {
      if (fVerbose) printf("data in on %s\n",fZMQconfigIN.Data());
      if (outSockets[1].events & ZMQ_POLLOUT)
      {
        rc = forward(fZMQin,fZMQout,fZMQmon,&msg);
      }
    }
    //out
    if (inSockets[1].revents & ZMQ_POLLIN)
    {
      if (fVerbose) printf("data in on %s\n",fZMQconfigOUT.Data());
      if (outSockets[0].events & ZMQ_POLLOUT)
      {
        rc = forward(fZMQout,fZMQin,fZMQmon,&msg);
      }
    }
    //mon
    if (inSockets[2].revents & ZMQ_POLLIN)
    {
      if (fVerbose) printf("data in on %s\n",fZMQconfigMON.Data());
      if (outSockets[2].events & ZMQ_POLLOUT)
      {
        rc = forward(fZMQmon,fZMQmon,NULL,&msg);
      }
    }
    zmq_msg_close(&msg);

    //if we time out (waiting for a response) reinit the REQ socket(s)
    if (pollrc==0)
    {
      if (inType==ZMQ_REQ) {
        if (fVerbose) printf("no reply from %s in %i ms, server died?\n",
            fZMQconfigIN.Data(), fZMQtimeout);
        rc = alizmq_socket_init(fZMQin, fZMQcontext, fZMQconfigIN.Data(),
            -1, fZMQmaxQueueSize);
        if (fVerbose) printf("rc of reinit %i\n",rc);
      }
      if (outType==ZMQ_REQ) {
        if (fVerbose) printf("no reply from %s in %i ms, server died?\n",
            fZMQconfigOUT.Data(), fZMQtimeout);
        rc = alizmq_socket_init(fZMQout, fZMQcontext, fZMQconfigOUT.Data(),
            -1, fZMQmaxQueueSize);
        if (fVerbose) printf("rc of reinit %i\n",rc);
      }
      if (monType==ZMQ_REQ) {
        if (fVerbose) printf("no reply from %s in %i ms, server died?\n",
            fZMQconfigMON.Data(), fZMQtimeout);
        rc = alizmq_socket_init(fZMQmon, fZMQcontext, fZMQconfigMON.Data(),
            -1, fZMQmaxQueueSize);
        if (fVerbose) printf("rc of reinit %i\n",rc);
      }
    }

    if (fSleep>0) usleep(fSleep);
  }

  return rc;
}

//_______________________________________________________________________________________
int InitZMQ()
{
  //init or reinit stuff
  int rc = 0;
  inType = alizmq_socket_init(fZMQin,  fZMQcontext, fZMQconfigIN.Data(), -1, fZMQmaxQueueSize);
  outType = alizmq_socket_init(fZMQout, fZMQcontext, fZMQconfigOUT.Data(), -1, fZMQmaxQueueSize);
  monType = alizmq_socket_init(fZMQmon, fZMQcontext, fZMQconfigMON.Data(), -1, fZMQmaxQueueSize);
  printf("socket init (in,out,mon): %i, %i, %i, %s, %s, %s\n",inType,outType,monType,alizmq_socket_name(inType),alizmq_socket_name(outType),alizmq_socket_name(monType));
  return rc;
}

//______________________________________________________________________________
int ProcessOptionString(TString arguments)
{
  //process passed options
  aliStringVec* options = AliOptionParser::TokenizeOptionString(arguments);
  int nOptions = 0;
  for (aliStringVec::iterator i=options->begin(); i!=options->end(); ++i)
  {
    const TString& option = i->first;
    const TString& value = i->second;
    if (option.EqualTo("ZMQconfigIN") || option.EqualTo("in"))
    {
      fZMQconfigIN = value;
    }
    else if (option.EqualTo("ZMQconfigOUT") || option.EqualTo("out"))
    {
      fZMQconfigOUT = value;
    }
    else if (option.EqualTo("ZMQconfigMON") || option.EqualTo("mon"))
    {
      fZMQconfigMON = value;
    }
    else if (option.EqualTo("Verbose"))
    {
      fVerbose = true;
    }
    else if (option.EqualTo("sleep"))
    {
      fSleep = value.Atoi() * 1000;
    }
    else if (option.EqualTo("timeout"))
    {
      fZMQtimeout = value.Atoi();
    }
    else
    {
      nOptions=-1;
      break;
    }
    nOptions++;
  }
  delete options; //tidy up

  return nOptions;
}

//_______________________________________________________________________________________
int main(int argc, char** argv)
{
  int mainReturnCode=0;

  //process args
  TString argString = AliOptionParser::GetFullArgString(argc,argv);
  if (ProcessOptionString(argString)<=0)
  {
    printf("%s",fUSAGE);
    return 1;
  }

  //the context
  fZMQcontext = alizmq_context();

  //init stuff
  if (InitZMQ()<0) {
    Printf("failed init");
    return 1;
  }

  Run();

  //destroy ZMQ sockets
  zmq_close(fZMQmon);
  zmq_close(fZMQin);
  //zmq_close(fZMQout);
  zmq_ctx_destroy(fZMQcontext);
  return mainReturnCode;
}

<commit_msg>ZMQproxy: update self doc<commit_after>#include "zmq.h"
#include <iostream>
#include "AliHLTDataTypes.h"
#include "AliHLTComponent.h"
#include "AliHLTMessage.h"
#include "TClass.h"
#include "TMap.h"
#include "TPRegexp.h"
#include "TObjString.h"
#include "TList.h"
#include "TMessage.h"
#include "TRint.h"
#include "TApplication.h"
#include <time.h>
#include <string>
#include <map>
#include "AliZMQhelpers.h"

//this is meant to become a class, hence the structure with global vars etc.
//Also the code is rather flat - it is a bit of a playground to test ideas.
//TODO structure this at some point, e.g. introduce a SIMPLE unified way of handling
//zmq payloads, maybe a AliZMQmessage class which would by default be multipart and provide
//easy access to payloads based on topic or so (a la HLT GetFirstInputObject() etc...)

//methods
int ProcessOptionString(TString arguments);
int InitZMQ();
void* work(void* param);
int Run();

//configuration vars
TString fZMQconfigIN   = "";
TString fZMQconfigOUT  = "";
TString fZMQconfigMON  = "";

Bool_t  fSendOnMerge = kTRUE;
Bool_t  fResetOnSend = kFALSE;

//ZMQ stuff
void* fZMQcontext = NULL;    //ze zmq context

void* fZMQmon = NULL;        //the request-reply socket, here we request the merged data
void* fZMQout = NULL;        //the monitoring socket, here we publish a copy of the data
void* fZMQin  = NULL;        //the in socket - entry point for the data to be merged.
int inType = -1;
int outType = -1;
int monType = -1;

int fZMQtimeout = -1;
int fZMQmaxQueueSize = 100;
int fSleep = 0;
bool fVerbose = false;

const char* fUSAGE =
  "ZMQproxy: a simple monitored ZMQ proxy\n"
  "caveat: using a REQ socket causes a custom request to be sent;\n"
  "        only the reply is forwardedto the backend.\n"
  "        For request forwarding use DEALER-ROUTER.\n"
  "options:\n"
  " -in : socket in\n"
  " -out : socket out\n"
  " -mon : monitor socket\n"
  " -sleep : sleep between polls (ms) (if in is a REQ socket)\n"
  " -timeout : timeout for a poll (ms)\n"
  ;

int capture(void* capture, zmq_msg_t* msg, int more = 0)
{
  int rc = 0;
  if (!capture) return 0;
  zmq_msg_t ctrl;
  rc = zmq_msg_init(&ctrl);
  if (rc<0) return -1;
  rc = zmq_msg_copy(&ctrl, msg);
  if (rc<0) return -1;
  return zmq_msg_send(&ctrl, capture, more?ZMQ_SNDMORE:0);
}

int forward(void* from, void* to, void* mon, zmq_msg_t* msg)
{
  int rc = 0;
  int more = 0;
  size_t moresize = sizeof(more);
  while (true)
  {
    rc = zmq_msg_recv(msg,from,0);
    if (rc<0) return -1;
    rc = zmq_getsockopt(from, ZMQ_RCVMORE, &more, &moresize);
    if (from!=mon) {
      rc = capture(mon,msg,more);
    }
    if (rc<0) return -1;
    rc = zmq_msg_send(msg,to,more?ZMQ_SNDMORE:0);
    if (rc<0) return -1;
    if (more==0) break;
  }
  if (fVerbose) printf("forwarded...\n");
  return 0;
}

//_______________________________________________________________________________________
int Run()
{
  int rc = 0;

  bool interrunpted = false;
  while (!interrunpted)
  {
    //send the requests first
    //it is OK to block if there is no remote end
    //the use case is to go from REQ->PUB for the event display
    //otherwise the reconnect can take a while
    if (inType==ZMQ_REQ) {
      if (fVerbose) printf("requesting on %p %s\n",fZMQin, fZMQconfigIN.Data());
      rc = alizmq_msg_send("","",fZMQin,0);
    }
    if (outType==ZMQ_REQ) {
      if (fVerbose) printf("requesting on %s\n",fZMQconfigOUT.Data());
      alizmq_msg_send("","",fZMQout,0);
    }

    //poll socket readiness for sending
    Int_t noutSockets=2;
    zmq_pollitem_t outSockets[] = {
      { fZMQin, 0, ZMQ_POLLOUT, 0 },
      { fZMQout, 0, ZMQ_POLLOUT, 0 },
      { fZMQmon, 0, ZMQ_POLLOUT, 0 },
    };
    rc = zmq_poll(outSockets, noutSockets, fZMQtimeout); //poll outSockets
    if (rc==-1 && errno==ETERM)
    {
      //this can only happen if the context was terminated, one of the inSockets are
      //not valid or operation was interrupted
      Printf("zmq_poll (out) was interrupted! rc = %i, %s", rc, zmq_strerror(errno));
      break;
    }
    //in
    if (outSockets[0].revents & ZMQ_POLLOUT)
    {
      if (fVerbose) printf("socket (%p) %s signals ZMQ_POLLOUT\n",fZMQin, fZMQconfigIN.Data());
    }
    //out
    if (outSockets[1].revents & ZMQ_POLLOUT)
    {
      if (fVerbose) printf("socket %p (%s) signals ZMQ_POLLOUT\n", fZMQout, fZMQconfigOUT.Data());
    }
    //mon
    if (outSockets[2].revents & ZMQ_POLLOUT)
    {
      if (fVerbose) printf("socket %p (%s) signals ZMQ_POLLOUT\n", fZMQmon, fZMQconfigMON.Data());
    }

    //poll incoming data
    Int_t ninSockets=3;
    zmq_pollitem_t inSockets[] = {
      { fZMQin, 0, ZMQ_POLLIN, 0 },
      { fZMQout, 0, ZMQ_POLLIN, 0 },
      { fZMQmon, 0, ZMQ_POLLIN, 0 },
    };

    if (fVerbose) printf("starting poll in\n");
    int pollrc = zmq_poll(inSockets, ninSockets, fZMQtimeout); //poll inSockets
    if (pollrc==-1 && errno==ETERM)
    {
      //this can only happen if the context was terminated, one of the inSockets are
      //not valid or operation was interrupted
      Printf("zmq_poll (in) was interrupted! rc = %i, %s", rc, zmq_strerror(errno));
      break;
    }

    zmq_msg_t msg;
    zmq_msg_init(&msg);
    //in
    if (inSockets[0].revents & ZMQ_POLLIN)
    {
      if (fVerbose) printf("data in on %s\n",fZMQconfigIN.Data());
      if (outSockets[1].events & ZMQ_POLLOUT)
      {
        rc = forward(fZMQin,fZMQout,fZMQmon,&msg);
      }
    }
    //out
    if (inSockets[1].revents & ZMQ_POLLIN)
    {
      if (fVerbose) printf("data in on %s\n",fZMQconfigOUT.Data());
      if (outSockets[0].events & ZMQ_POLLOUT)
      {
        rc = forward(fZMQout,fZMQin,fZMQmon,&msg);
      }
    }
    //mon
    if (inSockets[2].revents & ZMQ_POLLIN)
    {
      if (fVerbose) printf("data in on %s\n",fZMQconfigMON.Data());
      if (outSockets[2].events & ZMQ_POLLOUT)
      {
        rc = forward(fZMQmon,fZMQmon,NULL,&msg);
      }
    }
    zmq_msg_close(&msg);

    //if we time out (waiting for a response) reinit the REQ socket(s)
    if (pollrc==0)
    {
      if (inType==ZMQ_REQ) {
        if (fVerbose) printf("no reply from %s in %i ms, server died?\n",
            fZMQconfigIN.Data(), fZMQtimeout);
        rc = alizmq_socket_init(fZMQin, fZMQcontext, fZMQconfigIN.Data(),
            -1, fZMQmaxQueueSize);
        if (fVerbose) printf("rc of reinit %i\n",rc);
      }
      if (outType==ZMQ_REQ) {
        if (fVerbose) printf("no reply from %s in %i ms, server died?\n",
            fZMQconfigOUT.Data(), fZMQtimeout);
        rc = alizmq_socket_init(fZMQout, fZMQcontext, fZMQconfigOUT.Data(),
            -1, fZMQmaxQueueSize);
        if (fVerbose) printf("rc of reinit %i\n",rc);
      }
      if (monType==ZMQ_REQ) {
        if (fVerbose) printf("no reply from %s in %i ms, server died?\n",
            fZMQconfigMON.Data(), fZMQtimeout);
        rc = alizmq_socket_init(fZMQmon, fZMQcontext, fZMQconfigMON.Data(),
            -1, fZMQmaxQueueSize);
        if (fVerbose) printf("rc of reinit %i\n",rc);
      }
    }

    if (fSleep>0) usleep(fSleep);
  }

  return rc;
}

//_______________________________________________________________________________________
int InitZMQ()
{
  //init or reinit stuff
  int rc = 0;
  inType = alizmq_socket_init(fZMQin,  fZMQcontext, fZMQconfigIN.Data(), -1, fZMQmaxQueueSize);
  outType = alizmq_socket_init(fZMQout, fZMQcontext, fZMQconfigOUT.Data(), -1, fZMQmaxQueueSize);
  monType = alizmq_socket_init(fZMQmon, fZMQcontext, fZMQconfigMON.Data(), -1, fZMQmaxQueueSize);
  printf("socket init (in,out,mon): %i, %i, %i, %s, %s, %s\n",inType,outType,monType,alizmq_socket_name(inType),alizmq_socket_name(outType),alizmq_socket_name(monType));
  return rc;
}

//______________________________________________________________________________
int ProcessOptionString(TString arguments)
{
  //process passed options
  aliStringVec* options = AliOptionParser::TokenizeOptionString(arguments);
  int nOptions = 0;
  for (aliStringVec::iterator i=options->begin(); i!=options->end(); ++i)
  {
    const TString& option = i->first;
    const TString& value = i->second;
    if (option.EqualTo("ZMQconfigIN") || option.EqualTo("in"))
    {
      fZMQconfigIN = value;
    }
    else if (option.EqualTo("ZMQconfigOUT") || option.EqualTo("out"))
    {
      fZMQconfigOUT = value;
    }
    else if (option.EqualTo("ZMQconfigMON") || option.EqualTo("mon"))
    {
      fZMQconfigMON = value;
    }
    else if (option.EqualTo("Verbose"))
    {
      fVerbose = true;
    }
    else if (option.EqualTo("sleep"))
    {
      fSleep = value.Atoi() * 1000;
    }
    else if (option.EqualTo("timeout"))
    {
      fZMQtimeout = value.Atoi();
    }
    else
    {
      nOptions=-1;
      break;
    }
    nOptions++;
  }
  delete options; //tidy up

  return nOptions;
}

//_______________________________________________________________________________________
int main(int argc, char** argv)
{
  int mainReturnCode=0;

  //process args
  TString argString = AliOptionParser::GetFullArgString(argc,argv);
  if (ProcessOptionString(argString)<=0)
  {
    printf("%s",fUSAGE);
    return 1;
  }

  //the context
  fZMQcontext = alizmq_context();

  //init stuff
  if (InitZMQ()<0) {
    Printf("failed init");
    return 1;
  }

  Run();

  //destroy ZMQ sockets
  zmq_close(fZMQmon);
  zmq_close(fZMQin);
  //zmq_close(fZMQout);
  zmq_ctx_destroy(fZMQcontext);
  return mainReturnCode;
}

<|endoftext|>


<commit_before>// Copyright (c) 2021 ASMlover. All rights reserved.
//
//  _____         _             _
// |_   _|_ _  __| |_ __   ___ | | ___
//   | |/ _` |/ _` | '_ \ / _ \| |/ _ \
//   | | (_| | (_| | |_) | (_) | |  __/
//   |_|\__,_|\__,_| .__/ \___/|_|\___|
//                 |_|
//
// Redistribution and use in source and binary forms, with or without
// modification, are permitted provided that the following conditions
// are met:
//
//  * Redistributions of source code must retain the above copyright
//    notice, this list ofconditions and the following disclaimer.
//
//  * Redistributions in binary form must reproduce the above copyright
//    notice, this list of conditions and the following disclaimer in
//    the documentation and/or other materialsprovided with the
//    distribution.
//
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
// FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
// COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
// INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
// BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
// LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
// CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
// LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
// ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
// POSSIBILITY OF SUCH DAMAGE.
#include "../common/harness.hh"
#include "lexer.hh"

TADPOLE_TEST(TadpoleLexer) {
  using TK = tadpole::TokenKind;
#define TESTEQ(k) TADPOLE_CHECK_EQ(lex.next_token().kind(), k)
#define DUMPLEX() do {\
    for (;;) {\
      auto t = lex.next_token();\
      std::fprintf(stdout, "%-24s | %-32s | %d\n",\
          tadpole::get_kind_name(t.kind()),\
          t.as_cstring(),\
          t.lineno());\
      if (t.kind() == TK::TK_EOF)\
        break;\
    }\
  } while (false)

  {
    std::string s =
      "print(\"Welcome to Tadpole !!!\");\nvar v = 34 * 56 / 22.45 + (88.76 - 27.4);";
    tadpole::Lexer lex(s);
    DUMPLEX();
  }

  {
    std::string s = "var a = 56;";
    tadpole::Lexer lex(s);
    TESTEQ(TK::KW_VAR);
    TESTEQ(TK::TK_IDENTIFIER);
    TESTEQ(TK::TK_EQ);
    TESTEQ(TK::TK_NUMERIC);
    TESTEQ(TK::TK_SEMI);
    TESTEQ(TK::TK_EOF);
  }

  {
    std::string s = "print(\"23 + 45 =\", 23 + 45);";
    tadpole::Lexer lex(s);
    TESTEQ(TK::TK_IDENTIFIER);
    TESTEQ(TK::TK_LPAREN);
    TESTEQ(TK::TK_STRING);
    TESTEQ(TK::TK_COMMA);
    TESTEQ(TK::TK_NUMERIC);
    TESTEQ(TK::TK_PLUS);
    TESTEQ(TK::TK_NUMERIC);
    TESTEQ(TK::TK_RPAREN);
    TESTEQ(TK::TK_SEMI);
    TESTEQ(TK::TK_EOF);
  }

#undef DUMPLEX
#undef TESTEQ
}
<commit_msg>:white_check_mark: test(lexer): updated the test for lexer<commit_after>// Copyright (c) 2021 ASMlover. All rights reserved.
//
//  _____         _             _
// |_   _|_ _  __| |_ __   ___ | | ___
//   | |/ _` |/ _` | '_ \ / _ \| |/ _ \
//   | | (_| | (_| | |_) | (_) | |  __/
//   |_|\__,_|\__,_| .__/ \___/|_|\___|
//                 |_|
//
// Redistribution and use in source and binary forms, with or without
// modification, are permitted provided that the following conditions
// are met:
//
//  * Redistributions of source code must retain the above copyright
//    notice, this list ofconditions and the following disclaimer.
//
//  * Redistributions in binary form must reproduce the above copyright
//    notice, this list of conditions and the following disclaimer in
//    the documentation and/or other materialsprovided with the
//    distribution.
//
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
// FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
// COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
// INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
// BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
// LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
// CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
// LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
// ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
// POSSIBILITY OF SUCH DAMAGE.
#include "../common/harness.hh"
#include "lexer.hh"

TADPOLE_TEST(TadpoleLexer) {
  using TK = tadpole::TokenKind;
#define TESTEQ(k) TADPOLE_CHECK_EQ(lex.next_token().kind(), k)
#define DUMPLEX() do {\
    for (;;) {\
      auto t = lex.next_token();\
      std::fprintf(stdout, "%-24s | %-32s | %d\n",\
          tadpole::get_kind_name(t.kind()),\
          t.as_cstring(),\
          t.lineno());\
      if (t.kind() == TK::TK_EOF)\
        break;\
    }\
  } while (false)

  {
    std::string s =
      "print(\"Welcome to Tadpole !!!\");\nvar v = 34 * 56 / 22.45 + (88.76 - 27.4);";
    tadpole::Lexer lex(s);
    DUMPLEX();
  }

  {
    std::string s = "var a = 56;";
    tadpole::Lexer lex(s);
    TESTEQ(TK::KW_VAR);
    TESTEQ(TK::TK_IDENTIFIER);
    TESTEQ(TK::TK_EQ);
    TESTEQ(TK::TK_NUMERIC);
    TESTEQ(TK::TK_SEMI);
    TESTEQ(TK::TK_EOF);
  }

  {
    std::string s = "print(\"23 + 45 =\", 23 + 45);";
    tadpole::Lexer lex(s);
    TESTEQ(TK::TK_IDENTIFIER);
    TESTEQ(TK::TK_LPAREN);
    TESTEQ(TK::TK_STRING);
    TESTEQ(TK::TK_COMMA);
    TESTEQ(TK::TK_NUMERIC);
    TESTEQ(TK::TK_PLUS);
    TESTEQ(TK::TK_NUMERIC);
    TESTEQ(TK::TK_RPAREN);
    TESTEQ(TK::TK_SEMI);
    TESTEQ(TK::TK_EOF);
  }

  {
    std::string s = "fn show_msg(msg) { print(msg); }";
    tadpole::Lexer lex(s);
    TESTEQ(TK::KW_FN);
    TESTEQ(TK::TK_IDENTIFIER);
    TESTEQ(TK::TK_LPAREN);
    TESTEQ(TK::TK_IDENTIFIER);
    TESTEQ(TK::TK_RPAREN);
    TESTEQ(TK::TK_LBRACE);
    TESTEQ(TK::TK_IDENTIFIER);
    TESTEQ(TK::TK_LPAREN);
    TESTEQ(TK::TK_IDENTIFIER);
    TESTEQ(TK::TK_RPAREN);
    TESTEQ(TK::TK_SEMI);
    TESTEQ(TK::TK_RBRACE);
    TESTEQ(TK::TK_EOF);
  }

#undef DUMPLEX
#undef TESTEQ
}
<|endoftext|>


<commit_before>/**************************************************************************
 * Copyright(c) 2007-2009, ALICE Experiment at CERN, All rights reserved. *
 *                                                                        *
 * Author: The ALICE Off-line Project.                                    *
 * Contributors are mentioned in the code where appropriate.              *
 *                                                                        *
 * Permission to use, copy, modify and distribute this software and its   *
 * documentation strictly for non-commercial purposes is hereby granted   *
 * without fee, provided that the above copyright notice appears in all   *
 * copies and that both the copyright notice and this permission notice   *
 * appear in the supporting documentation. The authors make no claims     *
 * about the suitability of this software for any purpose. It is          *
 * provided "as is" without express or implied warranty.                  *
 **************************************************************************/

/* $Id$*/

///////////////////////////////////////////////////////////////////////////////
///
/// This class provides access to ITS SDD digits in raw data.
///
///////////////////////////////////////////////////////////////////////////////

#include "AliITSRawStreamSDD.h"
#include "AliRawReader.h"
#include "AliLog.h"

ClassImp(AliITSRawStreamSDD)

const UInt_t AliITSRawStreamSDD::fgkCodeLength[8] =  {8, 18, 2, 3, 4, 5, 6, 7};

//______________________________________________________________________
AliITSRawStreamSDD::AliITSRawStreamSDD(AliRawReader* rawReader) :
  AliITSRawStream(rawReader),
fDDLModuleMap(0),
fData(0),
fEventId(0),
fCarlosId(-1),
fChannel(0),
fJitter(0),
fDDL(0),
fEndWords(0),
fResetSkip(0)
{
// create an object to read ITS SDD raw digits
  fDDLModuleMap=new AliITSDDLModuleMapSDD();
  fDDLModuleMap->SetDefaultMap();
  Reset();
  for(Int_t im=0;im<kSDDModules;im++){
    fLowThresholdArray[im][0]=0;
    fLowThresholdArray[im][1]=0;
  }
  for(Int_t i=0;i<kFifoWords;i++) fNfifo[i]=0;
  for(Int_t i=0;i<kDDLsNumber;i++) fSkip[i]=0;
  fRawReader->Reset();
  fRawReader->Select("ITSSDD");

  for(Short_t i=0; i<kCarlosWords; i++) fICarlosWord[i]=0x30000000 + i; // 805306368+i;
  for(Short_t i=0; i<kFifoWords; i++) fIFifoWord[i]=0x30000010 + i;  // 805306384+i;
}

//______________________________________________________________________
AliITSRawStreamSDD::AliITSRawStreamSDD(const AliITSRawStreamSDD& rs) :
AliITSRawStream(rs.fRawReader),
fDDLModuleMap(rs.fDDLModuleMap),
fData(0),
fEventId(0),
fCarlosId(-1),
fChannel(0),
fJitter(0),
fDDL(0),
fEndWords(0),
fResetSkip(0)
{
  // copy constructor
  AliError("Copy constructor should not be used.");
}
//__________________________________________________________________________
AliITSRawStreamSDD& AliITSRawStreamSDD::operator=(const AliITSRawStreamSDD& rs) {
  // assignment operator
  if (this!=&rs) {}
  AliError("Assignment opertator should not be used.");
  return *this;
}

//______________________________________________________________________
AliITSRawStreamSDD::~AliITSRawStreamSDD(){
  if(fDDLModuleMap) delete fDDLModuleMap;
}
//______________________________________________________________________
UInt_t AliITSRawStreamSDD::ReadBits()
{
// read bits from the given channel
  UInt_t result = (fChannelData[fCarlosId][fChannel] & ((1<<fReadBits[fCarlosId][fChannel]) - 1));
  fChannelData[fCarlosId][fChannel] >>= fReadBits[fCarlosId][fChannel];
  fLastBit[fCarlosId][fChannel] -= fReadBits[fCarlosId][fChannel];
  return result;
}

//______________________________________________________________________
Int_t AliITSRawStreamSDD::DecompAmbra(Int_t value) const
{
  // AMBRA decompression (from 8 to 10 bit)

  if ((value & 0x80) == 0) {
    return value & 0x7f;
  } else if ((value & 0x40) == 0) {
    return 0x081 + ((value & 0x3f) << 1);
  } else if ((value & 0x20) == 0) {
    return 0x104 + ((value & 0x1f) << 3);
  } else {
    return 0x208 + ((value & 0x1f) << 4);
  }

}

//______________________________________________________________________
Bool_t AliITSRawStreamSDD::Next()
{
// read the next raw digit
// returns kFALSE if there is no digit left
// returns kTRUE and fCompletedModule=kFALSE when a digit is found
// returns kTRUE and fCompletedModule=kTRUE  when a module is completed (=3x3FFFFFFF footer words)

  fPrevModuleID = fModuleID;
  fDDL=fRawReader->GetDDLID();
  fCompletedModule=kFALSE;

  while (kTRUE) {
    if(fResetSkip==0){
      Bool_t kSkip = SkipHeaderWord();
      fResetSkip=1;
      if(!kSkip) return kSkip;
    }

    if ((fChannel < 0) || (fCarlosId < 0) || (fChannel >= 2) || (fCarlosId >= kModulesPerDDL) || (fLastBit[fCarlosId][fChannel] < fReadBits[fCarlosId][fChannel]) ) {
      if (!fRawReader->ReadNextInt(fData)) return kFALSE;  // read next word
      Int_t ddln = fRawReader->GetDDLID();
      if(ddln!=fDDL) {
	Reset();
	fDDL=fRawReader->GetDDLID();
      }
      if(ddln < 0 || ddln > (kDDLsNumber-1)) ddln  = 0;

      fChannel = -1;
      if((fData >> 16) == 0x7F00){ // jitter word
	fResetSkip=0;
	fEndWords=0;
	continue;
      }

      UInt_t nData28= fData >> 28;
      UInt_t nData30= fData >> 30;

      if (nData28== 0x02) {           // header
	fEventId = (fData >> 3) & 0x07FF;
      } else if (nData28== 0x04) {
	// JTAG word -- do nothing
      } else if (nData28== 0x03) {    // Carlos and FIFO words or Footers
	if(fData>=fICarlosWord[0]&&fData<=fICarlosWord[11]) { // Carlos Word
	  if(fEndWords==12) continue; // out of event
	  fCarlosId = fData-fICarlosWord[0];
	  Int_t iFifoIdx = fCarlosId/3;
	  fNfifo[iFifoIdx] = fCarlosId;
	} else if (fData>=fIFifoWord[0]&&fData<=fIFifoWord[3]){ // FIFO word
	  if(fEndWords==12) continue; // out of event
	  fCarlosId = fNfifo[fData-fIFifoWord[0]];
	} else if(fData==0x3FFFFFFF){ // Carlos footer
	  if(fCarlosId>=0 && fCarlosId<kModulesPerDDL){
	    fICountFoot[fCarlosId]++; // stop before the last word (last word=jitter)
	    if(fICountFoot[fCarlosId]==3){
	      fCompletedModule=kTRUE;
	      //	      printf("Completed module %d DDL %d\n",fCarlosId,ddln);
	      return kTRUE;
	    }
	  }
	} else if(fData==0x3F1F1F1F){ // CarlosRX footer
	  fEndWords++;
	  if(fEndWords<=12) continue;
	}else{
	  fRawReader->AddMajorErrorLog(kDataError,"Too many footers");
	  AliWarning(Form("invalid data: too many footers\n", fData));
	  return kFALSE;
	}
      } else if (nData30 == 0x02 || nData30 == 0x03) {
	fChannel = nData30-2;
	if(fCarlosId>=0 && fChannel>=0 && fCarlosId <kModulesPerDDL && fChannel<2){
	  fChannelData[fCarlosId][fChannel] +=
	    (ULong64_t(fData & 0x3FFFFFFF) << fLastBit[fCarlosId][fChannel]);
	  fLastBit[fCarlosId][fChannel] += 30;
	}
      } else {                               // unknown data format
	fRawReader->AddMajorErrorLog(kDataFormatErr,Form("Invalid data %8.8x",fData));
	AliWarning(Form("invalid data: %8.8x\n", fData));
	return kFALSE;
      }

      if(fCarlosId>=0 && fCarlosId <kModulesPerDDL){
	 fModuleID = GetModuleNumber(ddln,fCarlosId);
      }
    } else {  // decode data
      if (fReadCode[fCarlosId][fChannel]) {// read the next code word
	fChannelCode[fCarlosId][fChannel] = ReadBits();
	fReadCode[fCarlosId][fChannel] = kFALSE;
	fReadBits[fCarlosId][fChannel] = fgkCodeLength[fChannelCode[fCarlosId][fChannel]];
      } else {                      // read the next data word
	UInt_t data = ReadBits();
	fReadCode[fCarlosId][fChannel] = kTRUE;
	fReadBits[fCarlosId][fChannel] = 3;
	if (fChannelCode[fCarlosId][fChannel] == 0) {         // set the time bin
	  fTimeBin[fCarlosId][fChannel] = data;
	} else if (fChannelCode[fCarlosId][fChannel] == 1) {  // next anode
	  fTimeBin[fCarlosId][fChannel] = 0;
	  fAnode[fCarlosId][fChannel]++;
	} else {                                   // ADC signal data
	  fSignal = DecompAmbra(data + (1 << fChannelCode[fCarlosId][fChannel]) + fLowThresholdArray[fModuleID-kSPDModules][fChannel]);
	  fCoord1 = fAnode[fCarlosId][fChannel];
	  fCoord2 = fTimeBin[fCarlosId][fChannel];
	  fTimeBin[fCarlosId][fChannel]++;
	  //printf("Data read, Module=%d , Anode=%d , Time=%d , Charge=%d\n",fModuleID,fCoord1,fCoord2,fSignal);
	  return kTRUE;
	}
      }
    }
  }
  return kFALSE;
}

//______________________________________________________________________
void AliITSRawStreamSDD::Reset(){

  //reset data member for a new ddl
  for(Int_t i=0;i<2;i++){
    for(Int_t ic=0;ic<kModulesPerDDL;ic++){
      fChannelData[ic][i]=0;
      fLastBit[ic][i]=0;
      fChannelCode[ic][i]=0;
      fReadCode[ic][i]=kTRUE;
      fReadBits[ic][i]=3;
      fTimeBin[ic][i]=0;
      fAnode[ic][i]=0;
    }
    fLowThreshold[i]=0;
  }
  for(Int_t i=0;i<kModulesPerDDL;i++) fICountFoot[i]=0;
}

//______________________________________________________________________
Bool_t AliITSRawStreamSDD::SkipHeaderWord(){
  // skip the 1 DDL header word = 0xffffffff
  while (kTRUE) {
    if (!fRawReader->ReadNextInt(fData)) return kFALSE;
    if ((fData >> 30) == 0x01) continue;  // JTAG word
    if(fData==0xFFFFFFFF) return kTRUE;
  }
}

<commit_msg>Modifs to increase the speed of the SDD raw streamer (F.Prino)<commit_after>/**************************************************************************
 * Copyright(c) 2007-2009, ALICE Experiment at CERN, All rights reserved. *
 *                                                                        *
 * Author: The ALICE Off-line Project.                                    *
 * Contributors are mentioned in the code where appropriate.              *
 *                                                                        *
 * Permission to use, copy, modify and distribute this software and its   *
 * documentation strictly for non-commercial purposes is hereby granted   *
 * without fee, provided that the above copyright notice appears in all   *
 * copies and that both the copyright notice and this permission notice   *
 * appear in the supporting documentation. The authors make no claims     *
 * about the suitability of this software for any purpose. It is          *
 * provided "as is" without express or implied warranty.                  *
 **************************************************************************/

/* $Id$*/

///////////////////////////////////////////////////////////////////////////////
///
/// This class provides access to ITS SDD digits in raw data.
///
///////////////////////////////////////////////////////////////////////////////

#include "AliITSRawStreamSDD.h"
#include "AliRawReader.h"
#include "AliLog.h"

ClassImp(AliITSRawStreamSDD)

const UInt_t AliITSRawStreamSDD::fgkCodeLength[8] =  {8, 18, 2, 3, 4, 5, 6, 7};

//______________________________________________________________________
AliITSRawStreamSDD::AliITSRawStreamSDD(AliRawReader* rawReader) :
  AliITSRawStream(rawReader),
fDDLModuleMap(0),
fData(0),
fEventId(0),
fCarlosId(-1),
fChannel(0),
fJitter(0),
fDDL(0),
fEndWords(0),
fResetSkip(0)
{
// create an object to read ITS SDD raw digits
  fDDLModuleMap=new AliITSDDLModuleMapSDD();
  fDDLModuleMap->SetDefaultMap();
  Reset();
  for(Int_t im=0;im<kSDDModules;im++){
    fLowThresholdArray[im][0]=0;
    fLowThresholdArray[im][1]=0;
  }
  for(Int_t i=0;i<kFifoWords;i++) fNfifo[i]=0;
  for(Int_t i=0;i<kDDLsNumber;i++) fSkip[i]=0;
  fRawReader->Reset();
  fRawReader->Select("ITSSDD");

  for(Short_t i=0; i<kCarlosWords; i++) fICarlosWord[i]=0x30000000 + i; // 805306368+i;
  for(Short_t i=0; i<kFifoWords; i++) fIFifoWord[i]=0x30000010 + i;  // 805306384+i;
}

//______________________________________________________________________
AliITSRawStreamSDD::AliITSRawStreamSDD(const AliITSRawStreamSDD& rs) :
AliITSRawStream(rs.fRawReader),
fDDLModuleMap(rs.fDDLModuleMap),
fData(0),
fEventId(0),
fCarlosId(-1),
fChannel(0),
fJitter(0),
fDDL(0),
fEndWords(0),
fResetSkip(0)
{
  // copy constructor
  AliError("Copy constructor should not be used.");
}
//__________________________________________________________________________
AliITSRawStreamSDD& AliITSRawStreamSDD::operator=(const AliITSRawStreamSDD& rs) {
  // assignment operator
  if (this!=&rs) {}
  AliError("Assignment opertator should not be used.");
  return *this;
}

//______________________________________________________________________
AliITSRawStreamSDD::~AliITSRawStreamSDD(){
  if(fDDLModuleMap) delete fDDLModuleMap;
}
//______________________________________________________________________
UInt_t AliITSRawStreamSDD::ReadBits()
{
// read bits from the given channel
  UInt_t result = (fChannelData[fCarlosId][fChannel] & ((1<<fReadBits[fCarlosId][fChannel]) - 1));
  fChannelData[fCarlosId][fChannel] >>= fReadBits[fCarlosId][fChannel];
  fLastBit[fCarlosId][fChannel] -= fReadBits[fCarlosId][fChannel];
  return result;
}

//______________________________________________________________________
Int_t AliITSRawStreamSDD::DecompAmbra(Int_t value) const
{
  // AMBRA decompression (from 8 to 10 bit)

  if ((value & 0x80) == 0) {
    return value & 0x7f;
  } else if ((value & 0x40) == 0) {
    return 0x081 + ((value & 0x3f) << 1);
  } else if ((value & 0x20) == 0) {
    return 0x104 + ((value & 0x1f) << 3);
  } else {
    return 0x208 + ((value & 0x1f) << 4);
  }

}

//______________________________________________________________________
Bool_t AliITSRawStreamSDD::Next()
{
// read the next raw digit
// returns kFALSE if there is no digit left
// returns kTRUE and fCompletedModule=kFALSE when a digit is found
// returns kTRUE and fCompletedModule=kTRUE  when a module is completed (=3x3FFFFFFF footer words)

  fPrevModuleID = fModuleID;
  fDDL=fRawReader->GetDDLID();
  fCompletedModule=kFALSE;

  while (kTRUE) {
    if(fResetSkip==0){
      Bool_t kSkip = SkipHeaderWord();
      fResetSkip=1;
      if(!kSkip) return kSkip;
    }

    if ((fChannel < 0) || (fCarlosId < 0) || (fChannel >= 2) || (fCarlosId >= kModulesPerDDL) || (fLastBit[fCarlosId][fChannel] < fReadBits[fCarlosId][fChannel]) ) {
      if (!fRawReader->ReadNextInt(fData)) return kFALSE;  // read next word
      Int_t ddln = fRawReader->GetDDLID();
      if(ddln!=fDDL) {
	Reset();
	fDDL=fRawReader->GetDDLID();
      }

      fChannel = -1;
      if((fData >> 16) == 0x7F00){ // jitter word
	fResetSkip=0;
	fEndWords=0;
	continue;
      }

      UInt_t nData28= fData >> 28;
      UInt_t nData30= fData >> 30;

      if (nData28== 0x02) {           // header
	fEventId = (fData >> 3) & 0x07FF;
      } else if (nData28== 0x04) {
	// JTAG word -- do nothing
      } else if (nData28== 0x03) {    // Carlos and FIFO words or Footers
	if(fData>=fICarlosWord[0]&&fData<=fICarlosWord[11]) { // Carlos Word
	  if(fEndWords==12) continue; // out of event
	  fCarlosId = fData-fICarlosWord[0];
	  Int_t iFifoIdx = fCarlosId/3;
	  fNfifo[iFifoIdx] = fCarlosId;
	} else if (fData>=fIFifoWord[0]&&fData<=fIFifoWord[3]){ // FIFO word
	  if(fEndWords==12) continue; // out of event
	  fCarlosId = fNfifo[fData-fIFifoWord[0]];
	} else if(fData==0x3FFFFFFF){ // Carlos footer
	  fICountFoot[fCarlosId]++; // stop before the last word (last word=jitter)
	  if(fICountFoot[fCarlosId]==3){
	    fCompletedModule=kTRUE;
	    //	      printf("Completed module %d DDL %d\n",fCarlosId,ddln);
	    return kTRUE;
	  }
	} else if(fData==0x3F1F1F1F){ // CarlosRX footer
	  fEndWords++;
	  if(fEndWords<=12) continue;
	}else{
	  fRawReader->AddMajorErrorLog(kDataError,"Too many footers");
	  AliWarning(Form("invalid data: too many footers\n", fData));
	  return kFALSE;
	}
      } else if (nData30 == 0x02 || nData30 == 0x03) {
	fChannel = nData30-2;
	fChannelData[fCarlosId][fChannel] +=
	  (ULong64_t(fData & 0x3FFFFFFF) << fLastBit[fCarlosId][fChannel]);
	fLastBit[fCarlosId][fChannel] += 30;
      } else {                               // unknown data format
	fRawReader->AddMajorErrorLog(kDataFormatErr,Form("Invalid data %8.8x",fData));
	AliWarning(Form("invalid data: %8.8x\n", fData));
	return kFALSE;
      }

      if(fCarlosId>=0 && fCarlosId <kModulesPerDDL){
	 fModuleID = GetModuleNumber(ddln,fCarlosId);
      }
    } else {  // decode data
      if (fReadCode[fCarlosId][fChannel]) {// read the next code word
	fChannelCode[fCarlosId][fChannel] = ReadBits();
	fReadCode[fCarlosId][fChannel] = kFALSE;
	fReadBits[fCarlosId][fChannel] = fgkCodeLength[fChannelCode[fCarlosId][fChannel]];
      } else {                      // read the next data word
	UInt_t data = ReadBits();
	fReadCode[fCarlosId][fChannel] = kTRUE;
	fReadBits[fCarlosId][fChannel] = 3;
	if (fChannelCode[fCarlosId][fChannel] == 0) {         // set the time bin
	  fTimeBin[fCarlosId][fChannel] = data;
	} else if (fChannelCode[fCarlosId][fChannel] == 1) {  // next anode
	  fTimeBin[fCarlosId][fChannel] = 0;
	  fAnode[fCarlosId][fChannel]++;
	} else {                                   // ADC signal data
	  fSignal = DecompAmbra(data + (1 << fChannelCode[fCarlosId][fChannel]) + fLowThresholdArray[fModuleID-kSPDModules][fChannel]);
	  fCoord1 = fAnode[fCarlosId][fChannel];
	  fCoord2 = fTimeBin[fCarlosId][fChannel];
	  fTimeBin[fCarlosId][fChannel]++;
	  //printf("Data read, Module=%d , Anode=%d , Time=%d , Charge=%d\n",fModuleID,fCoord1,fCoord2,fSignal);
	  return kTRUE;
	}
      }
    }
  }
  return kFALSE;
}

//______________________________________________________________________
void AliITSRawStreamSDD::Reset(){

  //reset data member for a new ddl
  for(Int_t i=0;i<2;i++){
    for(Int_t ic=0;ic<kModulesPerDDL;ic++){
      fChannelData[ic][i]=0;
      fLastBit[ic][i]=0;
      fChannelCode[ic][i]=0;
      fReadCode[ic][i]=kTRUE;
      fReadBits[ic][i]=3;
      fTimeBin[ic][i]=0;
      fAnode[ic][i]=0;
    }
    fLowThreshold[i]=0;
  }
  for(Int_t i=0;i<kModulesPerDDL;i++) fICountFoot[i]=0;
}

//______________________________________________________________________
Bool_t AliITSRawStreamSDD::SkipHeaderWord(){
  // skip the 1 DDL header word = 0xffffffff
  while (kTRUE) {
    if (!fRawReader->ReadNextInt(fData)) return kFALSE;
    if ((fData >> 30) == 0x01) continue;  // JTAG word
    if(fData==0xFFFFFFFF) return kTRUE;
  }
}

<|endoftext|>


<commit_before>#include "rcppbridge.h"

#include <boost/foreach.hpp>
#include "../JASP-Common/base64.h"
#include <iomanip>

using namespace std;

RcppBridge* RcppBridge::_staticRef;

RcppBridge::RcppBridge()
{
	_staticRef = this;

	_rInside[".read.dataset.native"] = Rcpp::InternalFunction(&RcppBridge::readDataSetStatic);
	_rInside[".read.dataset.header.native"] = Rcpp::InternalFunction(&RcppBridge::readDataSetHeaderStatic);
	_rInside[".callback.native"] = Rcpp::InternalFunction(&RcppBridge::callbackStatic);

	_rInside["jasp.analyses"] = Rcpp::List();
	_rInside.parseEvalQNT("suppressPackageStartupMessages(library(\"RJSONIO\"))");
	_rInside.parseEvalQNT("suppressPackageStartupMessages(library(\"JASP\"))");
}

void RcppBridge::setDataSet(DataSet* dataSet)
{
	_dataSet = dataSet;
}

Json::Value RcppBridge::init(const string &name, const Json::Value &options)
{
	SEXP results;

	_rInside["name"] = name;
	_rInside["options.as.json.string"] = options.toStyledString();
	_rInside.parseEval("init(name=name, options.as.json.string=options.as.json.string)", results);

	string resultsAsString = Rcpp::as<string>(results);

	Json::Reader r;
	Json::Value json;
	r.parse(resultsAsString, json);

	return json;
}

Json::Value RcppBridge::run(const string &name, const Json::Value &options, boost::function<int (Json::Value)> callback)
{
	SEXP results;

	_callback = callback;

	_rInside["name"] = name;
	_rInside["options.as.json.string"] = options.toStyledString();
	_rInside.parseEval("run(name=name, options.as.json.string=options.as.json.string)", results);

	_callback = NULL;

	string resultsAsString = Rcpp::as<string>(results);

	Json::Reader r;
	Json::Value json;
	r.parse(resultsAsString, json);

	return json;
}

Rcpp::DataFrame RcppBridge::readDataSet(const std::map<std::string, Column::ColumnType> &columns)
{
	Rcpp::List list(columns.size());
	Rcpp::CharacterVector columnNames;

	int colNo = 0;

	typedef pair<const string, Column::ColumnType> ColumnInfo;

	BOOST_FOREACH(const ColumnInfo &columnInfo, columns)
	{
		(void)columns;
		string dot = ".";

		string columnName = columnInfo.first;

		string base64 = Base64::encode(dot, columnName);
		columnNames.push_back(base64);

		Column &column = _dataSet->columns().get(columnName);
		Column::ColumnType columnType = column.columnType();

		Column::ColumnType requestedType = columnInfo.second;
		if (requestedType == Column::ColumnTypeUnknown)
			requestedType = columnType;

		int rowCount = column.rowCount();
		int rowNo = 0;

		if (requestedType == Column::ColumnTypeScale)
		{
			if (columnType == Column::ColumnTypeScale)
			{
				Rcpp::NumericVector v(rowCount);

				BOOST_FOREACH(double value, column.AsDoubles)
				{
					(void)column;
					v[rowNo++] = value;
				}

				list[colNo++] = v;
			}
			else if (columnType == Column::ColumnTypeOrdinal || columnType == Column::ColumnTypeNominal)
			{
				Rcpp::IntegerVector v(rowCount);

				BOOST_FOREACH(int value, column.AsInts)
				{
					(void)column;
					v[rowNo++] = column.actualFromRaw(value);
				}

				list[colNo++] = v;
			}
			else // columnType == Column::ColumnTypeNominalText
			{
				Rcpp::IntegerVector v(rowCount);

				BOOST_FOREACH(int value, column.AsInts)
				{
					(void)column;
					v[rowNo++] = column.actualFromRaw(value);
				}

				makeFactor(v, column.labels());

				list[colNo++] = v;
			}
		}
		else // if (requestedType != Column::ColumnTypeScale)
		{
			bool ordinal = (requestedType == Column::ColumnTypeOrdinal);

			Rcpp::IntegerVector v(rowCount);

			if (columnType != Column::ColumnTypeScale)
			{
				BOOST_FOREACH(int value, column.AsInts)
				{
					(void)column;
					v[rowNo++] = value + 1;
				}

				makeFactor(v, column.labels(), ordinal);
			}
			else
			{
				// scale to nominal or ordinal (doesn't really make sense, but we have to do something)

				set<int> uniqueValues;

				BOOST_FOREACH(double value, column.AsDoubles)
				{
					(void)column;
					int intValue = (int)(value * 1000);
					uniqueValues.insert(intValue);
				}

				int index = 0;
				map<int, int> valueToIndex;
				vector<string> labels;

				BOOST_FOREACH(int value, uniqueValues)
				{
					(void)uniqueValues;
					valueToIndex[value] = index;

					stringstream ss;
					ss << ((double)value / 1000);
					labels.push_back(ss.str());

					index++;
				}

				BOOST_FOREACH(double value, column.AsDoubles)
				{
					(void)column;

					if (isnan(value))
						v[rowNo++] = INT_MIN;
					else
					{
						v[rowNo++] = valueToIndex[(int)(value * 1000)] + 1;
					}
				}

				makeFactor(v, labels, ordinal);
			}

			list[colNo++] = v;
		}
	}

	list.attr("names") = columnNames;

	Rcpp::DataFrame dataFrame = Rcpp::DataFrame(list);

	return dataFrame;
}

Rcpp::DataFrame RcppBridge::readDataSetHeader(const std::map<string, Column::ColumnType> &columns)
{
	Rcpp::List list(columns.size());
	Rcpp::CharacterVector columnNames;

	int colNo = 0;

	typedef pair<const string, Column::ColumnType> ColumnInfo;

	BOOST_FOREACH(const ColumnInfo &columnInfo, columns)
	{
		(void)columns;
		string dot = ".";

		string columnName = columnInfo.first;

		string base64 = Base64::encode(dot, columnName);
		columnNames.push_back(base64);

		Column &column = _dataSet->columns().get(columnName);
		Column::ColumnType columnType = column.columnType();

		Column::ColumnType requestedType = columnInfo.second;
		if (requestedType == Column::ColumnTypeUnknown)
			requestedType = columnType;

		if (requestedType == Column::ColumnTypeScale)
		{
			if (columnType == Column::ColumnTypeScale)
			{
				list[colNo++] = Rcpp::NumericVector(0);
			}
			else if (columnType == Column::ColumnTypeOrdinal || columnType == Column::ColumnTypeNominal)
			{
				list[colNo++] = Rcpp::IntegerVector(0);
			}
			else
			{
				Rcpp::IntegerVector v(0);
				makeFactor(v, column.labels());
				list[colNo++] = v;
			}
		}
		else
		{
			bool ordinal = (requestedType == Column::ColumnTypeOrdinal);

			Rcpp::IntegerVector v(0);
			makeFactor(v, column.labels(), ordinal);

			list[colNo++] = v;
		}
	}

	list.attr("names") = columnNames;

	Rcpp::DataFrame dataFrame = Rcpp::DataFrame(list);

	return dataFrame;
}

void RcppBridge::makeFactor(Rcpp::IntegerVector &v, const Labels &levels, bool ordinal)
{
	Rcpp::CharacterVector labels;

	for (int i = 0; i < levels.size(); i++)
		labels.push_back(levels.at(i).text());

	v.attr("levels") = labels;

	vector<string> cla55;
	if (ordinal)
		cla55.push_back("ordered");
	cla55.push_back("factor");

	v.attr("class") = cla55;
}

void RcppBridge::makeFactor(Rcpp::IntegerVector &v, const std::vector<string> &levels, bool ordinal)
{
	v.attr("levels") = levels;

	vector<string> cla55;
	if (ordinal)
		cla55.push_back("ordered");
	cla55.push_back("factor");

	v.attr("class") = cla55;
}

int RcppBridge::callback(SEXP results)
{
	string jsonString = Rcpp::as<string>(results);

	Json::Reader r;
	Json::Value json;
	r.parse(jsonString, json);

	return _callback(json);
}

Rcpp::DataFrame RcppBridge::readDataSetStatic(SEXP columns, SEXP columnsAsNumeric, SEXP columnsAsOrdinal, SEXP columnsAsNominal, SEXP allColumns)
{
	map<string, Column::ColumnType> columnsRequested = marshallSEXPs(columns, columnsAsNumeric, columnsAsOrdinal, columnsAsNominal, allColumns);
	return _staticRef->readDataSet(columnsRequested);
}

Rcpp::DataFrame RcppBridge::readDataSetHeaderStatic(SEXP columns, SEXP columnsAsNumeric, SEXP columnsAsOrdinal, SEXP columnsAsNominal, SEXP allColumns)
{
	map<string, Column::ColumnType> columnsRequested = marshallSEXPs(columns, columnsAsNumeric, columnsAsOrdinal, columnsAsNominal, allColumns);
	return _staticRef->readDataSetHeader(columnsRequested);
}

std::map<string, Column::ColumnType> RcppBridge::marshallSEXPs(SEXP columns, SEXP columnsAsNumeric, SEXP columnsAsOrdinal, SEXP columnsAsNominal, SEXP allColumns)
{
	map<string, Column::ColumnType> columnsRequested;

	if (Rf_isLogical(allColumns) && Rcpp::as<bool>(allColumns))
	{
		(void)_staticRef;
		BOOST_FOREACH(const Column &column, _staticRef->_dataSet->columns())
			columnsRequested[column.name()] = Column::ColumnTypeUnknown;
	}

	if (Rf_isString(columns))
	{
		vector<string> temp = Rcpp::as<vector<string> >(columns);
		for (int i = 0; i < temp.size(); i++)
			columnsRequested[temp.at(i)] = Column::ColumnTypeUnknown;
	}

	if (Rf_isString(columnsAsNumeric))
	{
		vector<string> temp = Rcpp::as<vector<string> >(columnsAsNumeric);
		for (int i = 0; i < temp.size(); i++)
			columnsRequested[temp.at(i)] = Column::ColumnTypeScale;
	}

	if (Rf_isString(columnsAsOrdinal))
	{
		vector<string> temp = Rcpp::as<vector<string> >(columnsAsOrdinal);
		for (int i = 0; i < temp.size(); i++)
			columnsRequested[temp.at(i)] = Column::ColumnTypeOrdinal;
	}

	if (Rf_isString(columnsAsNominal))
	{
		vector<string> temp = Rcpp::as<vector<string> >(columnsAsNominal);
		for (int i = 0; i < temp.size(); i++)
			columnsRequested[temp.at(i)] = Column::ColumnTypeNominal;
	}

	return columnsRequested;
}

SEXP RcppBridge::callbackStatic(SEXP results)
{
	Rcpp::NumericVector control(1);
	control[0] = _staticRef->callback(results);
	return control;
}

<commit_msg>Fix to dataframe loading of ordinals with NAs<commit_after>#include "rcppbridge.h"

#include <boost/foreach.hpp>
#include "../JASP-Common/base64.h"
#include <iomanip>

using namespace std;

RcppBridge* RcppBridge::_staticRef;

RcppBridge::RcppBridge()
{
	_staticRef = this;

	_rInside[".read.dataset.native"] = Rcpp::InternalFunction(&RcppBridge::readDataSetStatic);
	_rInside[".read.dataset.header.native"] = Rcpp::InternalFunction(&RcppBridge::readDataSetHeaderStatic);
	_rInside[".callback.native"] = Rcpp::InternalFunction(&RcppBridge::callbackStatic);

	_rInside["jasp.analyses"] = Rcpp::List();
	_rInside.parseEvalQNT("suppressPackageStartupMessages(library(\"RJSONIO\"))");
	_rInside.parseEvalQNT("suppressPackageStartupMessages(library(\"JASP\"))");
}

void RcppBridge::setDataSet(DataSet* dataSet)
{
	_dataSet = dataSet;
}

Json::Value RcppBridge::init(const string &name, const Json::Value &options)
{
	SEXP results;

	_rInside["name"] = name;
	_rInside["options.as.json.string"] = options.toStyledString();
	_rInside.parseEval("init(name=name, options.as.json.string=options.as.json.string)", results);

	string resultsAsString = Rcpp::as<string>(results);

	Json::Reader r;
	Json::Value json;
	r.parse(resultsAsString, json);

	return json;
}

Json::Value RcppBridge::run(const string &name, const Json::Value &options, boost::function<int (Json::Value)> callback)
{
	SEXP results;

	_callback = callback;

	_rInside["name"] = name;
	_rInside["options.as.json.string"] = options.toStyledString();
	_rInside.parseEval("run(name=name, options.as.json.string=options.as.json.string)", results);

	_callback = NULL;

	string resultsAsString = Rcpp::as<string>(results);

	Json::Reader r;
	Json::Value json;
	r.parse(resultsAsString, json);

	return json;
}

Rcpp::DataFrame RcppBridge::readDataSet(const std::map<std::string, Column::ColumnType> &columns)
{
	Rcpp::List list(columns.size());
	Rcpp::CharacterVector columnNames;

	int colNo = 0;

	typedef pair<const string, Column::ColumnType> ColumnInfo;

	BOOST_FOREACH(const ColumnInfo &columnInfo, columns)
	{
		(void)columns;
		string dot = ".";

		string columnName = columnInfo.first;

		string base64 = Base64::encode(dot, columnName);
		columnNames.push_back(base64);

		Column &column = _dataSet->columns().get(columnName);
		Column::ColumnType columnType = column.columnType();

		Column::ColumnType requestedType = columnInfo.second;
		if (requestedType == Column::ColumnTypeUnknown)
			requestedType = columnType;

		int rowCount = column.rowCount();
		int rowNo = 0;

		if (requestedType == Column::ColumnTypeScale)
		{
			if (columnType == Column::ColumnTypeScale)
			{
				Rcpp::NumericVector v(rowCount);

				BOOST_FOREACH(double value, column.AsDoubles)
				{
					(void)column;
					v[rowNo++] = value;
				}

				list[colNo++] = v;
			}
			else if (columnType == Column::ColumnTypeOrdinal || columnType == Column::ColumnTypeNominal)
			{
				Rcpp::IntegerVector v(rowCount);

				BOOST_FOREACH(int value, column.AsInts)
				{
					(void)column;
					v[rowNo++] = column.actualFromRaw(value);
				}

				list[colNo++] = v;
			}
			else // columnType == Column::ColumnTypeNominalText
			{
				Rcpp::IntegerVector v(rowCount);

				BOOST_FOREACH(int value, column.AsInts)
				{
					(void)column;
					v[rowNo++] = column.actualFromRaw(value);
				}

				makeFactor(v, column.labels());

				list[colNo++] = v;
			}
		}
		else // if (requestedType != Column::ColumnTypeScale)
		{
			bool ordinal = (requestedType == Column::ColumnTypeOrdinal);

			Rcpp::IntegerVector v(rowCount);

			if (columnType != Column::ColumnTypeScale)
			{
				BOOST_FOREACH(int value, column.AsInts)
				{
					(void)column;
					if (value == INT_MIN)
						v[rowNo++] = INT_MIN;
					else
						v[rowNo++] = value + 1;
				}

				makeFactor(v, column.labels(), ordinal);
			}
			else
			{
				// scale to nominal or ordinal (doesn't really make sense, but we have to do something)

				set<int> uniqueValues;

				BOOST_FOREACH(double value, column.AsDoubles)
				{
					(void)column;
					int intValue = (int)(value * 1000);
					uniqueValues.insert(intValue);
				}

				int index = 0;
				map<int, int> valueToIndex;
				vector<string> labels;

				BOOST_FOREACH(int value, uniqueValues)
				{
					(void)uniqueValues;
					valueToIndex[value] = index;

					stringstream ss;
					ss << ((double)value / 1000);
					labels.push_back(ss.str());

					index++;
				}

				BOOST_FOREACH(double value, column.AsDoubles)
				{
					(void)column;

					if (isnan(value))
						v[rowNo++] = INT_MIN;
					else
					{
						v[rowNo++] = valueToIndex[(int)(value * 1000)] + 1;
					}
				}

				makeFactor(v, labels, ordinal);
			}

			list[colNo++] = v;
		}
	}

	list.attr("names") = columnNames;

	Rcpp::DataFrame dataFrame = Rcpp::DataFrame(list);

	return dataFrame;
}

Rcpp::DataFrame RcppBridge::readDataSetHeader(const std::map<string, Column::ColumnType> &columns)
{
	Rcpp::List list(columns.size());
	Rcpp::CharacterVector columnNames;

	int colNo = 0;

	typedef pair<const string, Column::ColumnType> ColumnInfo;

	BOOST_FOREACH(const ColumnInfo &columnInfo, columns)
	{
		(void)columns;
		string dot = ".";

		string columnName = columnInfo.first;

		string base64 = Base64::encode(dot, columnName);
		columnNames.push_back(base64);

		Column &column = _dataSet->columns().get(columnName);
		Column::ColumnType columnType = column.columnType();

		Column::ColumnType requestedType = columnInfo.second;
		if (requestedType == Column::ColumnTypeUnknown)
			requestedType = columnType;

		if (requestedType == Column::ColumnTypeScale)
		{
			if (columnType == Column::ColumnTypeScale)
			{
				list[colNo++] = Rcpp::NumericVector(0);
			}
			else if (columnType == Column::ColumnTypeOrdinal || columnType == Column::ColumnTypeNominal)
			{
				list[colNo++] = Rcpp::IntegerVector(0);
			}
			else
			{
				Rcpp::IntegerVector v(0);
				makeFactor(v, column.labels());
				list[colNo++] = v;
			}
		}
		else
		{
			bool ordinal = (requestedType == Column::ColumnTypeOrdinal);

			Rcpp::IntegerVector v(0);
			makeFactor(v, column.labels(), ordinal);

			list[colNo++] = v;
		}
	}

	list.attr("names") = columnNames;

	Rcpp::DataFrame dataFrame = Rcpp::DataFrame(list);

	return dataFrame;
}

void RcppBridge::makeFactor(Rcpp::IntegerVector &v, const Labels &levels, bool ordinal)
{
	Rcpp::CharacterVector labels;

	for (int i = 0; i < levels.size(); i++)
		labels.push_back(levels.at(i).text());

	v.attr("levels") = labels;

	vector<string> cla55;
	if (ordinal)
		cla55.push_back("ordered");
	cla55.push_back("factor");

	v.attr("class") = cla55;
}

void RcppBridge::makeFactor(Rcpp::IntegerVector &v, const std::vector<string> &levels, bool ordinal)
{
	v.attr("levels") = levels;

	vector<string> cla55;
	if (ordinal)
		cla55.push_back("ordered");
	cla55.push_back("factor");

	v.attr("class") = cla55;
}

int RcppBridge::callback(SEXP results)
{
	string jsonString = Rcpp::as<string>(results);

	Json::Reader r;
	Json::Value json;
	r.parse(jsonString, json);

	return _callback(json);
}

Rcpp::DataFrame RcppBridge::readDataSetStatic(SEXP columns, SEXP columnsAsNumeric, SEXP columnsAsOrdinal, SEXP columnsAsNominal, SEXP allColumns)
{
	map<string, Column::ColumnType> columnsRequested = marshallSEXPs(columns, columnsAsNumeric, columnsAsOrdinal, columnsAsNominal, allColumns);
	return _staticRef->readDataSet(columnsRequested);
}

Rcpp::DataFrame RcppBridge::readDataSetHeaderStatic(SEXP columns, SEXP columnsAsNumeric, SEXP columnsAsOrdinal, SEXP columnsAsNominal, SEXP allColumns)
{
	map<string, Column::ColumnType> columnsRequested = marshallSEXPs(columns, columnsAsNumeric, columnsAsOrdinal, columnsAsNominal, allColumns);
	return _staticRef->readDataSetHeader(columnsRequested);
}

std::map<string, Column::ColumnType> RcppBridge::marshallSEXPs(SEXP columns, SEXP columnsAsNumeric, SEXP columnsAsOrdinal, SEXP columnsAsNominal, SEXP allColumns)
{
	map<string, Column::ColumnType> columnsRequested;

	if (Rf_isLogical(allColumns) && Rcpp::as<bool>(allColumns))
	{
		(void)_staticRef;
		BOOST_FOREACH(const Column &column, _staticRef->_dataSet->columns())
			columnsRequested[column.name()] = Column::ColumnTypeUnknown;
	}

	if (Rf_isString(columns))
	{
		vector<string> temp = Rcpp::as<vector<string> >(columns);
		for (int i = 0; i < temp.size(); i++)
			columnsRequested[temp.at(i)] = Column::ColumnTypeUnknown;
	}

	if (Rf_isString(columnsAsNumeric))
	{
		vector<string> temp = Rcpp::as<vector<string> >(columnsAsNumeric);
		for (int i = 0; i < temp.size(); i++)
			columnsRequested[temp.at(i)] = Column::ColumnTypeScale;
	}

	if (Rf_isString(columnsAsOrdinal))
	{
		vector<string> temp = Rcpp::as<vector<string> >(columnsAsOrdinal);
		for (int i = 0; i < temp.size(); i++)
			columnsRequested[temp.at(i)] = Column::ColumnTypeOrdinal;
	}

	if (Rf_isString(columnsAsNominal))
	{
		vector<string> temp = Rcpp::as<vector<string> >(columnsAsNominal);
		for (int i = 0; i < temp.size(); i++)
			columnsRequested[temp.at(i)] = Column::ColumnTypeNominal;
	}

	return columnsRequested;
}

SEXP RcppBridge::callbackStatic(SEXP results)
{
	Rcpp::NumericVector control(1);
	control[0] = _staticRef->callback(results);
	return control;
}

<|endoftext|>


<commit_before>/***************************************************************************
                          irkick.cpp  -  Implementation of the main window
                             -------------------
    copyright            : (C) 2002 by Gav Wood
    email                : gav@kde.org
***************************************************************************/

// This program is free software.

#include <qwidget.h>
#include <qdialog.h>
#include <qtooltip.h>
#include <qregexp.h>
#include <qtimer.h>
#include <qevent.h>
//Added by qt3to4:
#include <QMouseEvent>
#include <Q3ValueList>
#include <Q3CString>

#include <kdeversion.h>
#include <kapplication.h>
#include <kaction.h>
#if !(KDE_VERSION_MINOR<=1 && KDE_VERSION_RELEASE<=5)
#include <kactioncollection.h>
#endif
#include <ksimpleconfig.h>
#include <ksystemtray.h>
#include <kiconloader.h>
#include <kpassivepopup.h>
#include <kmessagebox.h>
#include <kpopupmenu.h>
#include <kdebug.h>
#include <klocale.h>
#include <kaboutdialog.h>
#include <kaboutkde.h>
#include <kwinmodule.h>
#include <kwin.h>
#include <khelpmenu.h>
#include <kglobal.h>
#include <kstdguiitem.h>

#include <dcopclient.h>
#include <dcopref.h>

#include "profileserver.h"
#include "irkick.h"

void IRKTrayIcon::mousePressEvent(QMouseEvent *e)
{
	KSystemTray::mousePressEvent(new QMouseEvent(QEvent::MouseButtonPress, e->pos(), e->globalPos(), e->button() == Qt::LeftButton ? Qt::RightButton : e->button(), e->state()));
}

IRKick::IRKick(const Q3CString &obj) : QObject(), DCOPObject(obj), npApp(QString::null)
{
    kapp->dcopClient()->setDefaultObject(obj);
	theClient = new KLircClient();

	theTrayIcon = new IRKTrayIcon();
	if(theClient->isConnected())
	{	theTrayIcon->setPixmap(SmallIcon("irkick"));
		QToolTip::add(theTrayIcon, i18n("KDE Lirc Server: Ready."));
	}
	else
	{	theTrayIcon->setPixmap(SmallIcon("irkickoff"));
		QToolTip::add(theTrayIcon, i18n("KDE Lirc Server: No infra-red remote controls found."));
		QTimer::singleShot(10000, this, SLOT(checkLirc()));
	}
	theFlashOff = new QTimer(theTrayIcon);
	connect(theFlashOff, SIGNAL(timeout()), SLOT(flashOff()));

	theResetCount = 0;
	slotReloadConfiguration();
	connect(theClient, SIGNAL(connectionClosed()), this, SLOT(slotClosed()));
	connect(theClient, SIGNAL(remotesRead()), this, SLOT(resetModes()));
	connect(theClient, SIGNAL(commandReceived(const QString &, const QString &, int)), this, SLOT(gotMessage(const QString &, const QString &, int)));

	theTrayIcon->contextMenu()->changeTitle(0, "IRKick");
	theTrayIcon->contextMenu()->insertItem(SmallIcon( "configure" ), i18n("&Configure..."), this, SLOT(slotConfigure()));
	theTrayIcon->contextMenu()->insertSeparator();
	theTrayIcon->contextMenu()->insertItem(SmallIcon( "help" ), KStdGuiItem::help().text(), (new KHelpMenu(theTrayIcon, KGlobal::instance()->aboutData()))->menu());
	theTrayIcon->actionCollection()->action("file_quit")->disconnect(SIGNAL(activated()));
	connect(theTrayIcon->actionCollection()->action("file_quit"), SIGNAL(activated()), SLOT(doQuit()));

	theTrayIcon->show();
}

IRKick::~IRKick()
{
	delete theTrayIcon;
	for(QMap<QString,IRKTrayIcon *>::iterator i = currentModeIcons.begin(); i != currentModeIcons.end(); ++i)
		if(*i) delete *i;
}

void IRKick::slotClosed()
{
	theTrayIcon->setPixmap(SmallIcon("irkickoff"));
	KPassivePopup::message("IRKick", i18n("The infrared system has severed its connection. Remote controls are no longer available."), SmallIcon("irkick"), theTrayIcon);
	QTimer::singleShot(1000, this, SLOT(checkLirc()));
}

void IRKick::checkLirc()
{
	if(!theClient->isConnected())
		if(theClient->connectToLirc())
		{	KPassivePopup::message("IRKick", i18n("A connection to the infrared system has been made. Remote controls may now be available."), SmallIcon("irkick"), theTrayIcon);
			theTrayIcon->setPixmap(SmallIcon("irkick"));
		}
		else
			QTimer::singleShot(10000, this, SLOT(checkLirc()));
}

void IRKick::flashOff()
{
	theTrayIcon->setPixmap(SmallIcon("irkick"));
}

void IRKick::doQuit()
{
	KSimpleConfig theConfig("irkickrc");
	theConfig.setGroup("General");
	switch(KMessageBox::questionYesNoCancel(0, i18n("Should the Infrared Remote Control server start automatically when you begin KDE?"), i18n("Automatically Start?"), i18n("Start Automatically"), i18n("Do Not Start")))
	{	case KMessageBox::No: theConfig.writeEntry("AutoStart", false); break;
		case KMessageBox::Yes: theConfig.writeEntry("AutoStart", true); break;
		case KMessageBox::Cancel: return;
	}
	KApplication::kApplication()->quit();
}

void IRKick::resetModes()
{
	if(theResetCount > 1)
		KPassivePopup::message("IRKick", i18n("Resetting all modes."), SmallIcon("irkick"), theTrayIcon);
	if(!theResetCount)
		allModes.generateNulls(theClient->remotes());

	QStringList remotes = theClient->remotes();
	for(QStringList::iterator i = remotes.begin(); i != remotes.end(); ++i)
	{	currentModes[*i] = allModes.getDefault(*i).name();
		if(theResetCount && currentModeIcons[*i]) delete currentModeIcons[*i];
		currentModeIcons[*i] = 0;
	}
	updateModeIcons();
	theResetCount++;
}

void IRKick::slotReloadConfiguration()
{
	// load configuration from config file
	KSimpleConfig theConfig("irkickrc");
	allActions.loadFromConfig(theConfig);
	allModes.loadFromConfig(theConfig);
	if(currentModes.count() && theResetCount)
		resetModes();
}

void IRKick::slotConfigure()
{
	KApplication::startServiceByDesktopName("kcmlirc");
}

void IRKick::updateModeIcons()
{
	for(QMap<QString,QString>::iterator i = currentModes.begin(); i != currentModes.end(); ++i)
	{	Mode mode = allModes.getMode(i.key(), i.data());
		if(mode.iconFile().isNull() || mode.iconFile().isEmpty())
		{	if(currentModeIcons[i.key()])
			{	delete currentModeIcons[i.key()];
				currentModeIcons[i.key()] = 0;
			}
		}
		else
		{	if(!currentModeIcons[i.key()])
			{	currentModeIcons[i.key()] = new IRKTrayIcon();
				currentModeIcons[i.key()]->show();
				currentModeIcons[i.key()]->contextMenu()->changeTitle(0, mode.remoteName());
				currentModeIcons[i.key()]->actionCollection()->action("file_quit")->setEnabled(false);
			}
			currentModeIcons[i.key()]->setPixmap(KIconLoader().loadIcon(mode.iconFile(), KIcon::Panel));
			QToolTip::add(currentModeIcons[i.key()], mode.remoteName() + ": " + mode.name() + "");
		}
	}
}

bool IRKick::getPrograms(const IRAction &action, QStringList &programs)
{
	DCOPClient *theDC = KApplication::dcopClient();
	programs.clear();

	if(action.unique())
	{	if(theDC->isApplicationRegistered(action.program().utf8()))
			programs += action.program();
	}
	else
	{
		QRegExp r = QRegExp("^" + action.program() + "-(\\d+)$");
		// find all instances...
		QCStringList buf = theDC->registeredApplications();
		for(QCStringList::iterator i = buf.begin(); i != buf.end(); ++i)
		{
			QString program = QString::fromUtf8(*i);
			if(program.contains(r))
				programs += program;
		}
		if(programs.size() > 1 && action.ifMulti() == IM_DONTSEND)
			return false;
		else if(programs.size() > 1 && action.ifMulti() == IM_SENDTOTOP)
		{	Q3ValueList<WId> s = KWinModule().stackingOrder();
			// go through all the (ordered) window pids
			for(Q3ValueList<WId>::iterator i = s.fromLast(); i != s.end(); i--)
			{	int p = KWin::info(*i).pid;
				QString id = action.program() + "-" + QString().setNum(p);
				if(programs.contains(id))
				{	programs.clear();
					programs += id;
					break;
				}
			}
			while(programs.size() > 1) programs.remove(programs.begin());
		}
		else if(programs.size() > 1 && action.ifMulti() == IM_SENDTOBOTTOM)
		{	Q3ValueList<WId> s = KWinModule().stackingOrder();
			// go through all the (ordered) window pids
			for(Q3ValueList<WId>::iterator i = s.begin(); i != s.end(); ++i)
			{	int p = KWin::info(*i).pid;
				QString id = action.program() + "-" + QString().setNum(p);
				if(programs.contains(id))
				{	programs.clear();
					programs += id;
					break;
				}
			}
			while(programs.size() > 1) programs.remove(programs.begin());
		}
	}
	return true;
}

void IRKick::executeAction(const IRAction &action)
{
	DCOPClient *theDC = KApplication::dcopClient();
	QStringList programs;

	if(!getPrograms(action, programs)) return;

	// if programs.size()==0 here, then the app is definately not running.
	if(action.autoStart() && !programs.size())
	{	QString sname = ProfileServer::profileServer()->getServiceName(action.program());
		if(!sname.isNull())
		{
			KPassivePopup::message("IRKick", i18n("Starting %1...").arg(action.application()), SmallIcon("irkick"), theTrayIcon);
			KApplication::startServiceByDesktopName(sname);
		}
	}
	if(action.isJustStart()) return;

	if(!getPrograms(action, programs)) return;

	for(QStringList::iterator i = programs.begin(); i != programs.end(); ++i)
	{	const QString &program = *i;
		if(theDC->isApplicationRegistered(program.utf8()))
		{	QByteArray data; QDataStream arg(&data, QIODevice::WriteOnly);
 arg.setVersion(QDataStream::Qt_3_1);
			kdDebug() << "Sending data (" << program << ", " << action.object() << ", " << action.method().prototypeNR() << endl;
			for(Arguments::const_iterator j = action.arguments().begin(); j != action.arguments().end(); ++j)
			{	kdDebug() << "Got argument..." << endl;
				switch((*j).type())
				{	case QVariant::Int: arg << (*j).toInt(); break;
					case QVariant::CString: arg << (*j).toCString(); break;
					case QVariant::StringList: arg << (*j).toStringList(); break;
					case QVariant::UInt: arg << (*j).toUInt(); break;
					case QVariant::Bool: arg << (*j).toBool(); break;
					case QVariant::Double: arg << (*j).toDouble(); break;
					default: arg << (*j).toString(); break;
				}
			}
			theDC->send(program.utf8(), action.object().utf8(), action.method().prototypeNR().utf8(), data);
		}
	}
}

void IRKick::gotMessage(const QString &theRemote, const QString &theButton, int theRepeatCounter)
{
	kdDebug() << "Got message: " << theRemote << ": " << theButton << " (" << theRepeatCounter << ")" << endl;
	theTrayIcon->setPixmap(SmallIcon("irkickflash"));
	theFlashOff->start(200, true);
	if(!npApp.isNull())
	{
		QString theApp = npApp;
		npApp = QString::null;
		// send notifier by DCOP to npApp/npModule/npMethod(theRemote, theButton);
		QByteArray data; QDataStream arg(&data, QIODevice::WriteOnly);
 arg.setVersion(QDataStream::Qt_3_1);
		arg << theRemote << theButton;
		KApplication::dcopClient()->send(theApp.utf8(), npModule.utf8(), npMethod.utf8(), data);
	}
	else
	{
		if(currentModes[theRemote].isNull()) currentModes[theRemote] = "";
		IRAItList l = allActions.findByModeButton(Mode(theRemote, currentModes[theRemote]), theButton);
		if(!currentModes[theRemote].isEmpty())
			l += allActions.findByModeButton(Mode(theRemote, ""), theButton);
		bool doBefore = true, doAfter = false;
		for(IRAItList::const_iterator i = l.begin(); i != l.end(); ++i)
			if((**i).isModeChange() && !theRepeatCounter)
			{	// mode switch
				currentModes[theRemote] = (**i).modeChange();
				Mode mode = allModes.getMode(theRemote, (**i).modeChange());
				updateModeIcons();
				doBefore = (**i).doBefore();
				doAfter = (**i).doAfter();
				break;
			}

		for(int after = 0; after < 2; after++)
		{	if(doBefore && !after || doAfter && after)
				for(IRAItList::const_iterator i = l.begin(); i != l.end(); ++i)
					if(!(**i).isModeChange() && ((**i).repeat() || !theRepeatCounter))
					{	executeAction(**i);
					}
			if(!after && doAfter)
			{	l = allActions.findByModeButton(Mode(theRemote, currentModes[theRemote]), theButton);
				if(!currentModes[theRemote].isEmpty())
					l += allActions.findByModeButton(Mode(theRemote, ""), theButton);
			}
		}
	}
}

void IRKick::stealNextPress(QString app, QString module, QString method)
{
	npApp = app;
	npModule = module;
	npMethod = method;
}

void IRKick::dontStealNextPress()
{
	npApp = QString::null;
}

#include "irkick.moc"
<commit_msg>Start to fix it<commit_after>/***************************************************************************
                          irkick.cpp  -  Implementation of the main window
                             -------------------
    copyright            : (C) 2002 by Gav Wood
    email                : gav@kde.org
***************************************************************************/

// This program is free software.

#include <qwidget.h>
#include <qdialog.h>
#include <qtooltip.h>
#include <qregexp.h>
#include <qtimer.h>
#include <qevent.h>
//Added by qt3to4:
#include <QMouseEvent>
#include <Q3ValueList>
#include <Q3CString>
#include <kdeversion.h>
#include <kapplication.h>
#include <kaction.h>
#if !(KDE_VERSION_MINOR<=1 && KDE_VERSION_RELEASE<=5)
#include <kactioncollection.h>
#endif
#include <ksimpleconfig.h>
#include <ksystemtray.h>
#include <kiconloader.h>
#include <kpassivepopup.h>
#include <kmessagebox.h>
#include <kpopupmenu.h>
#include <kdebug.h>
#include <klocale.h>
#include <kaboutdialog.h>
#include <kaboutkde.h>
#include <kwinmodule.h>
#include <kwin.h>
#include <khelpmenu.h>
#include <kglobal.h>
#include <kstdguiitem.h>

#include <dcopclient.h>
#include <dcopref.h>

#include "profileserver.h"
#include "irkick.h"

void IRKTrayIcon::mousePressEvent(QMouseEvent *e)
{
	KSystemTray::mousePressEvent(new QMouseEvent(QEvent::MouseButtonPress, e->pos(), e->globalPos(), e->button() == Qt::LeftButton ? Qt::RightButton : e->button(), e->state()));
}

IRKick::IRKick(const Q3CString &obj) : QObject(), DCOPObject(obj), npApp(QString::null)
{
    kapp->dcopClient()->setDefaultObject(obj);
	theClient = new KLircClient();

	theTrayIcon = new IRKTrayIcon();
	if(theClient->isConnected())
	{	theTrayIcon->setPixmap(SmallIcon("irkick"));
		QToolTip::add(theTrayIcon, i18n("KDE Lirc Server: Ready."));
	}
	else
	{	theTrayIcon->setPixmap(SmallIcon("irkickoff"));
		QToolTip::add(theTrayIcon, i18n("KDE Lirc Server: No infra-red remote controls found."));
		QTimer::singleShot(10000, this, SLOT(checkLirc()));
	}
	theFlashOff = new QTimer(theTrayIcon);
	connect(theFlashOff, SIGNAL(timeout()), SLOT(flashOff()));

	theResetCount = 0;
	slotReloadConfiguration();
	connect(theClient, SIGNAL(connectionClosed()), this, SLOT(slotClosed()));
	connect(theClient, SIGNAL(remotesRead()), this, SLOT(resetModes()));
	connect(theClient, SIGNAL(commandReceived(const QString &, const QString &, int)), this, SLOT(gotMessage(const QString &, const QString &, int)));

	theTrayIcon->contextMenu()->changeTitle(0, "IRKick");
	theTrayIcon->contextMenu()->insertItem(SmallIcon( "configure" ), i18n("&Configure..."), this, SLOT(slotConfigure()));
	theTrayIcon->contextMenu()->insertSeparator();
	theTrayIcon->contextMenu()->insertItem(SmallIcon( "help" ), KStdGuiItem::help().text(), (new KHelpMenu(theTrayIcon, KGlobal::instance()->aboutData()))->menu());
	theTrayIcon->actionCollection()->action("file_quit")->disconnect(SIGNAL(activated()));
	connect(theTrayIcon->actionCollection()->action("file_quit"), SIGNAL(activated()), SLOT(doQuit()));

	theTrayIcon->show();
}

IRKick::~IRKick()
{
	delete theTrayIcon;
	for(QMap<QString,IRKTrayIcon *>::iterator i = currentModeIcons.begin(); i != currentModeIcons.end(); ++i)
		if(*i) delete *i;
}

void IRKick::slotClosed()
{
	theTrayIcon->setPixmap(SmallIcon("irkickoff"));
	KPassivePopup::message("IRKick", i18n("The infrared system has severed its connection. Remote controls are no longer available."), SmallIcon("irkick"), theTrayIcon);
	QTimer::singleShot(1000, this, SLOT(checkLirc()));
}

void IRKick::checkLirc()
{
	if(!theClient->isConnected())
		if(theClient->connectToLirc())
		{	KPassivePopup::message("IRKick", i18n("A connection to the infrared system has been made. Remote controls may now be available."), SmallIcon("irkick"), theTrayIcon);
			theTrayIcon->setPixmap(SmallIcon("irkick"));
		}
		else
			QTimer::singleShot(10000, this, SLOT(checkLirc()));
}

void IRKick::flashOff()
{
	theTrayIcon->setPixmap(SmallIcon("irkick"));
}

void IRKick::doQuit()
{
	KSimpleConfig theConfig("irkickrc");
	theConfig.setGroup("General");
	switch(KMessageBox::questionYesNoCancel(0, i18n("Should the Infrared Remote Control server start automatically when you begin KDE?"), i18n("Automatically Start?"), i18n("Start Automatically"), i18n("Do Not Start")))
	{	case KMessageBox::No: theConfig.writeEntry("AutoStart", false); break;
		case KMessageBox::Yes: theConfig.writeEntry("AutoStart", true); break;
		case KMessageBox::Cancel: return;
	}
	KApplication::kApplication()->quit();
}

void IRKick::resetModes()
{
	if(theResetCount > 1)
		KPassivePopup::message("IRKick", i18n("Resetting all modes."), SmallIcon("irkick"), theTrayIcon);
	if(!theResetCount)
		allModes.generateNulls(theClient->remotes());

	QStringList remotes = theClient->remotes();
	for(QStringList::iterator i = remotes.begin(); i != remotes.end(); ++i)
	{	currentModes[*i] = allModes.getDefault(*i).name();
		if(theResetCount && currentModeIcons[*i]) delete currentModeIcons[*i];
		currentModeIcons[*i] = 0;
	}
	updateModeIcons();
	theResetCount++;
}

void IRKick::slotReloadConfiguration()
{
	// load configuration from config file
	KSimpleConfig theConfig("irkickrc");
	allActions.loadFromConfig(theConfig);
	allModes.loadFromConfig(theConfig);
	if(currentModes.count() && theResetCount)
		resetModes();
}

void IRKick::slotConfigure()
{
	KApplication::startServiceByDesktopName("kcmlirc");
}

void IRKick::updateModeIcons()
{
	for(QMap<QString,QString>::iterator i = currentModes.begin(); i != currentModes.end(); ++i)
	{	Mode mode = allModes.getMode(i.key(), i.data());
		if(mode.iconFile().isNull() || mode.iconFile().isEmpty())
		{	if(currentModeIcons[i.key()])
			{	delete currentModeIcons[i.key()];
				currentModeIcons[i.key()] = 0;
			}
		}
		else
		{	if(!currentModeIcons[i.key()])
			{	currentModeIcons[i.key()] = new IRKTrayIcon();
				currentModeIcons[i.key()]->show();
				currentModeIcons[i.key()]->contextMenu()->changeTitle(0, mode.remoteName());
				currentModeIcons[i.key()]->actionCollection()->action("file_quit")->setEnabled(false);
			}
			currentModeIcons[i.key()]->setPixmap(KIconLoader().loadIcon(mode.iconFile(), KIcon::Panel));
			QToolTip::add(currentModeIcons[i.key()], mode.remoteName() + ": " + mode.name() + "");
		}
	}
}

bool IRKick::getPrograms(const IRAction &action, QStringList &programs)
{
	DCOPClient *theDC = KApplication::dcopClient();
	programs.clear();

	if(action.unique())
	{	if(theDC->isApplicationRegistered(action.program().utf8()))
			programs += action.program();
	}
	else
	{
		QRegExp r = QRegExp("^" + action.program() + "-(\\d+)$");
		// find all instances...
		DCOPCStringList buf = theDC->registeredApplications();
		for(DCOPCStringList::iterator i = buf.begin(); i != buf.end(); ++i)
		{
			QString program = QString::fromUtf8(*i);
			if(program.contains(r))
				programs += program;
		}
		if(programs.size() > 1 && action.ifMulti() == IM_DONTSEND)
			return false;
		else if(programs.size() > 1 && action.ifMulti() == IM_SENDTOTOP)
		{	Q3ValueList<WId> s = KWinModule().stackingOrder();
			// go through all the (ordered) window pids
			for(Q3ValueList<WId>::iterator i = s.fromLast(); i != s.end(); i--)
			{	int p = KWin::windowInfo(*i,NET::WMPid).win();
				QString id = action.program() + "-" + QString().setNum(p);
				if(programs.contains(id))
				{	programs.clear();
					programs += id;
					break;
				}
			}
			while(programs.size() > 1) programs.remove(programs.begin());
		}
		else if(programs.size() > 1 && action.ifMulti() == IM_SENDTOBOTTOM)
		{	Q3ValueList<WId> s = KWinModule().stackingOrder();
			// go through all the (ordered) window pids
			for(Q3ValueList<WId>::iterator i = s.begin(); i != s.end(); ++i)
			{	int p = KWin::windowInfo(*i,NET::WMPid).win();
				QString id = action.program() + "-" + QString().setNum(p);
				if(programs.contains(id))
				{	programs.clear();
					programs += id;
					break;
				}
			}
			while(programs.size() > 1) programs.remove(programs.begin());
		}
	}
	return true;
}

void IRKick::executeAction(const IRAction &action)
{
	DCOPClient *theDC = KApplication::dcopClient();
	QStringList programs;

	if(!getPrograms(action, programs)) return;

	// if programs.size()==0 here, then the app is definately not running.
	if(action.autoStart() && !programs.size())
	{	QString sname = ProfileServer::profileServer()->getServiceName(action.program());
		if(!sname.isNull())
		{
			KPassivePopup::message("IRKick", i18n("Starting %1...").arg(action.application()), SmallIcon("irkick"), theTrayIcon);
			KApplication::startServiceByDesktopName(sname);
		}
	}
	if(action.isJustStart()) return;

	if(!getPrograms(action, programs)) return;

	for(QStringList::iterator i = programs.begin(); i != programs.end(); ++i)
	{	const QString &program = *i;
		if(theDC->isApplicationRegistered(program.utf8()))
		{	QByteArray data; QDataStream arg(&data, QIODevice::WriteOnly);
 arg.setVersion(QDataStream::Qt_3_1);
			kdDebug() << "Sending data (" << program << ", " << action.object() << ", " << action.method().prototypeNR() << endl;
			for(Arguments::const_iterator j = action.arguments().begin(); j != action.arguments().end(); ++j)
			{	kdDebug() << "Got argument..." << endl;
				switch((*j).type())
				{	case QVariant::Int: arg << (*j).toInt(); break;
					case QVariant::CString: arg << (*j).toCString(); break;
					case QVariant::StringList: arg << (*j).toStringList(); break;
					case QVariant::UInt: arg << (*j).toUInt(); break;
					case QVariant::Bool: arg << (*j).toBool(); break;
					case QVariant::Double: arg << (*j).toDouble(); break;
					default: arg << (*j).toString(); break;
				}
			}
			theDC->send(program.utf8(), action.object().utf8(), action.method().prototypeNR().utf8(), data);
		}
	}
}

void IRKick::gotMessage(const QString &theRemote, const QString &theButton, int theRepeatCounter)
{
	kdDebug() << "Got message: " << theRemote << ": " << theButton << " (" << theRepeatCounter << ")" << endl;
	theTrayIcon->setPixmap(SmallIcon("irkickflash"));
	theFlashOff->start(200, true);
	if(!npApp.isNull())
	{
		QString theApp = npApp;
		npApp = QString::null;
		// send notifier by DCOP to npApp/npModule/npMethod(theRemote, theButton);
		QByteArray data; QDataStream arg(&data, QIODevice::WriteOnly);
 arg.setVersion(QDataStream::Qt_3_1);
		arg << theRemote << theButton;
		KApplication::dcopClient()->send(theApp.utf8(), npModule.utf8(), npMethod.utf8(), data);
	}
	else
	{
		if(currentModes[theRemote].isNull()) currentModes[theRemote] = "";
		IRAItList l = allActions.findByModeButton(Mode(theRemote, currentModes[theRemote]), theButton);
		if(!currentModes[theRemote].isEmpty())
			l += allActions.findByModeButton(Mode(theRemote, ""), theButton);
		bool doBefore = true, doAfter = false;
		for(IRAItList::const_iterator i = l.begin(); i != l.end(); ++i)
			if((**i).isModeChange() && !theRepeatCounter)
			{	// mode switch
				currentModes[theRemote] = (**i).modeChange();
				Mode mode = allModes.getMode(theRemote, (**i).modeChange());
				updateModeIcons();
				doBefore = (**i).doBefore();
				doAfter = (**i).doAfter();
				break;
			}

		for(int after = 0; after < 2; after++)
		{	if(doBefore && !after || doAfter && after)
				for(IRAItList::const_iterator i = l.begin(); i != l.end(); ++i)
					if(!(**i).isModeChange() && ((**i).repeat() || !theRepeatCounter))
					{	executeAction(**i);
					}
			if(!after && doAfter)
			{	l = allActions.findByModeButton(Mode(theRemote, currentModes[theRemote]), theButton);
				if(!currentModes[theRemote].isEmpty())
					l += allActions.findByModeButton(Mode(theRemote, ""), theButton);
			}
		}
	}
}

void IRKick::stealNextPress(QString app, QString module, QString method)
{
	npApp = app;
	npModule = module;
	npMethod = method;
}

void IRKick::dontStealNextPress()
{
	npApp = QString::null;
}

#include "irkick.moc"
<|endoftext|>


<commit_before>/*=========================================================================

  Program:   Visualization Toolkit
  Module:    TestLabeledGeoView2D.cxx

  Copyright (c) Ken Martin, Will Schroeder, Bill Lorensen
  All rights reserved.
  See Copyright.txt or http://www.kitware.com/Copyright.htm for details.

     This software is distributed WITHOUT ANY WARRANTY; without even
     the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
     PURPOSE.  See the above copyright notice for more information.

=========================================================================*/
/*-------------------------------------------------------------------------
  Copyright 2008 Sandia Corporation.
  Under the terms of Contract DE-AC04-94AL85000 with Sandia Corporation,
  the U.S. Government retains certain rights in this software.
-------------------------------------------------------------------------*/
// .SECTION Description

#include "vtkCamera.h"
#include "vtkGeoAlignedImageSource.h"
#include "vtkGeoAlignedImageRepresentation.h"
#include "vtkGeoFileImageSource.h"
#include "vtkGeoFileTerrainSource.h"
#include "vtkGeoGraphRepresentation2D.h"
#include "vtkGeoProjectionSource.h"
#include "vtkGeoRandomGraphSource.h"
#include "vtkGeoTerrain2D.h"
#include "vtkGeoTerrainNode.h"
#include "vtkGeoView2D.h"
#include "vtkJPEGReader.h"
#include "vtkPolyData.h"
#include "vtkRegressionTestImage.h"
#include "vtkRenderer.h"
#include "vtkRenderWindow.h"
#include "vtkRenderWindowInteractor.h"
#include "vtkSmartPointer.h"
#include "vtkStdString.h"
#include "vtkTestUtilities.h"

#include <vtksys/ios/sstream>

int TestLabeledGeoView2D(int argc, char* argv[])
{
  int proj = 40;
  char* fname = vtkTestUtilities::ExpandDataFileName(
    argc, argv, "Data/NE2_ps_bath_small.jpg");
  vtkStdString imageFile = fname;

  // Create the view
  vtkSmartPointer<vtkRenderWindow> win = vtkSmartPointer<vtkRenderWindow>::New();
  vtkSmartPointer<vtkGeoView2D> view = vtkSmartPointer<vtkGeoView2D>::New();
  view->SetupRenderWindow(win);

  // Create the terrain
  vtkSmartPointer<vtkGeoTerrain2D> terrain =
    vtkSmartPointer<vtkGeoTerrain2D>::New();
  vtkSmartPointer<vtkGeoSource> terrainSource;
  vtkGeoProjectionSource* projSource = vtkGeoProjectionSource::New();
  projSource->SetProjection(proj);
  terrainSource.TakeReference(projSource);
  terrain->SetSource(terrainSource);
  view->SetSurface(terrain);

  // Create background image
  vtkSmartPointer<vtkGeoAlignedImageRepresentation> imageRep =
    vtkSmartPointer<vtkGeoAlignedImageRepresentation>::New();
  vtkSmartPointer<vtkGeoSource> imageSource;
  vtkGeoAlignedImageSource* alignedSource = vtkGeoAlignedImageSource::New();
  vtkSmartPointer<vtkJPEGReader> reader =
    vtkSmartPointer<vtkJPEGReader>::New();
  reader->SetFileName(imageFile.c_str());
  reader->Update();
  alignedSource->SetImage(reader->GetOutput());
  imageSource.TakeReference(alignedSource);
  imageRep->SetSource(imageSource);
  view->AddRepresentation(imageRep);

  vtkSmartPointer<vtkGeoRandomGraphSource> graphSource =
    vtkSmartPointer<vtkGeoRandomGraphSource>::New();
  graphSource->SetNumberOfVertices(500);
  vtkSmartPointer<vtkGeoGraphRepresentation2D> graphRep =
    vtkSmartPointer<vtkGeoGraphRepresentation2D>::New();

  graphRep->SetInputConnection(graphSource->GetOutputPort());
  graphRep->SetVertexLabelArrayName("latitude");
  graphRep->SetUseLabelHierarchy(true);
  graphRep->SetVertexLabelVisibility(true);

  view->AddRepresentation(graphRep);

  // Set up the viewport
  win->SetSize(600, 600);
  vtkSmartPointer<vtkGeoTerrainNode> root =
    vtkSmartPointer<vtkGeoTerrainNode>::New();
  terrainSource->FetchRoot(root);
  double bounds[6];
  root->GetModel()->GetBounds(bounds);
  bounds[0] = bounds[0] - (bounds[1] - bounds[0])*0.01;
  bounds[1] = bounds[1] + (bounds[1] - bounds[0])*0.01;
  bounds[2] = bounds[2] - (bounds[3] - bounds[2])*0.01;
  bounds[3] = bounds[3] + (bounds[3] - bounds[2])*0.01;
  double scalex = (bounds[1] - bounds[0])/2.0;
  double scaley = (bounds[3] - bounds[2])/2.0;
  double scale = (scalex > scaley) ? scalex : scaley;

  view->GetRenderer()->ResetCamera();
  view->GetRenderer()->GetActiveCamera()->SetParallelScale(scale);

  view->Update();
  int retVal = vtkRegressionTestImage(win);
  if (retVal == vtkRegressionTester::DO_INTERACTOR)
    {
    win->GetInteractor()->Initialize();
    win->GetInteractor()->Start();
    }

  terrainSource->ShutDown();
  imageSource->ShutDown();

  delete [] fname;
  return !retVal;
}

<commit_msg>BUG: change projection type to see if malloc bug in libproj4 on stops.<commit_after>/*=========================================================================

  Program:   Visualization Toolkit
  Module:    TestLabeledGeoView2D.cxx

  Copyright (c) Ken Martin, Will Schroeder, Bill Lorensen
  All rights reserved.
  See Copyright.txt or http://www.kitware.com/Copyright.htm for details.

     This software is distributed WITHOUT ANY WARRANTY; without even
     the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
     PURPOSE.  See the above copyright notice for more information.

=========================================================================*/
/*-------------------------------------------------------------------------
  Copyright 2008 Sandia Corporation.
  Under the terms of Contract DE-AC04-94AL85000 with Sandia Corporation,
  the U.S. Government retains certain rights in this software.
-------------------------------------------------------------------------*/
// .SECTION Description

#include "vtkCamera.h"
#include "vtkGeoAlignedImageSource.h"
#include "vtkGeoAlignedImageRepresentation.h"
#include "vtkGeoFileImageSource.h"
#include "vtkGeoFileTerrainSource.h"
#include "vtkGeoGraphRepresentation2D.h"
#include "vtkGeoProjectionSource.h"
#include "vtkGeoRandomGraphSource.h"
#include "vtkGeoTerrain2D.h"
#include "vtkGeoTerrainNode.h"
#include "vtkGeoView2D.h"
#include "vtkJPEGReader.h"
#include "vtkPolyData.h"
#include "vtkRegressionTestImage.h"
#include "vtkRenderer.h"
#include "vtkRenderWindow.h"
#include "vtkRenderWindowInteractor.h"
#include "vtkSmartPointer.h"
#include "vtkStdString.h"
#include "vtkTestUtilities.h"

#include <vtksys/ios/sstream>

int TestLabeledGeoView2D(int argc, char* argv[])
{
  int proj = 35;
  char* fname = vtkTestUtilities::ExpandDataFileName(
    argc, argv, "Data/NE2_ps_bath_small.jpg");
  vtkStdString imageFile = fname;

  // Create the view
  vtkSmartPointer<vtkRenderWindow> win = vtkSmartPointer<vtkRenderWindow>::New();
  vtkSmartPointer<vtkGeoView2D> view = vtkSmartPointer<vtkGeoView2D>::New();
  view->SetupRenderWindow(win);

  // Create the terrain
  vtkSmartPointer<vtkGeoTerrain2D> terrain =
    vtkSmartPointer<vtkGeoTerrain2D>::New();
  vtkSmartPointer<vtkGeoSource> terrainSource;
  vtkGeoProjectionSource* projSource = vtkGeoProjectionSource::New();
  projSource->SetProjection(proj);
  terrainSource.TakeReference(projSource);
  terrain->SetSource(terrainSource);
  view->SetSurface(terrain);

  // Create background image
  vtkSmartPointer<vtkGeoAlignedImageRepresentation> imageRep =
    vtkSmartPointer<vtkGeoAlignedImageRepresentation>::New();
  vtkSmartPointer<vtkGeoSource> imageSource;
  vtkGeoAlignedImageSource* alignedSource = vtkGeoAlignedImageSource::New();
  vtkSmartPointer<vtkJPEGReader> reader =
    vtkSmartPointer<vtkJPEGReader>::New();
  reader->SetFileName(imageFile.c_str());
  reader->Update();
  alignedSource->SetImage(reader->GetOutput());
  imageSource.TakeReference(alignedSource);
  imageRep->SetSource(imageSource);
  view->AddRepresentation(imageRep);

  vtkSmartPointer<vtkGeoRandomGraphSource> graphSource =
    vtkSmartPointer<vtkGeoRandomGraphSource>::New();
  graphSource->SetNumberOfVertices(500);
  vtkSmartPointer<vtkGeoGraphRepresentation2D> graphRep =
    vtkSmartPointer<vtkGeoGraphRepresentation2D>::New();

  graphRep->SetInputConnection(graphSource->GetOutputPort());
  graphRep->SetVertexLabelArrayName("latitude");
  graphRep->SetUseLabelHierarchy(true);
  graphRep->SetVertexLabelVisibility(true);

  view->AddRepresentation(graphRep);

  // Set up the viewport
  win->SetSize(600, 600);
  vtkSmartPointer<vtkGeoTerrainNode> root =
    vtkSmartPointer<vtkGeoTerrainNode>::New();
  terrainSource->FetchRoot(root);
  double bounds[6];
  root->GetModel()->GetBounds(bounds);
  bounds[0] = bounds[0] - (bounds[1] - bounds[0])*0.01;
  bounds[1] = bounds[1] + (bounds[1] - bounds[0])*0.01;
  bounds[2] = bounds[2] - (bounds[3] - bounds[2])*0.01;
  bounds[3] = bounds[3] + (bounds[3] - bounds[2])*0.01;
  double scalex = (bounds[1] - bounds[0])/2.0;
  double scaley = (bounds[3] - bounds[2])/2.0;
  double scale = (scalex > scaley) ? scalex : scaley;

  view->GetRenderer()->ResetCamera();
  view->GetRenderer()->GetActiveCamera()->SetParallelScale(scale);

  view->Update();
  int retVal = vtkRegressionTestImage(win);
  if (retVal == vtkRegressionTester::DO_INTERACTOR)
    {
    win->GetInteractor()->Initialize();
    win->GetInteractor()->Start();
    }

  terrainSource->ShutDown();
  imageSource->ShutDown();

  delete [] fname;
  return !retVal;
}

<|endoftext|>