EventTranslator.cc
Go to the documentation of this file.00001 #include "EventTranslator.h"
00002 #include "Events/EventRouter.h"
00003 #include "Shared/debuget.h"
00004 #include "Shared/ProjectInterface.h"
00005 #include <iostream>
00006
00007 #ifdef PLATFORM_APERIOS
00008 # include <OPENR/OSubject.h>
00009 #else
00010 # include "IPC/MessageQueue.h"
00011 #endif
00012 #include "IPC/RCRegion.h"
00013
00014 using namespace std;
00015
00016 void
00017 EventTranslator::encodeEvent(const EventBase& event, bool onlyReady) {
00018 event.setSaveFormat(EventBase::BINARY);
00019 EventBase::classTypeID_t header=event.getClassTypeID();
00020 const unsigned int bufsize=LoadSave::getSerializedSize(header)+event.getBinSize();
00021 char * const buf=bufferRequest(bufsize);
00022 if(buf==NULL) {
00023 cerr << "ERROR: EventTranslator unable to transmit event because requested buffer was NULL" << endl;
00024 return;
00025 }
00026 char * cur=buf;
00027 unsigned int remain=bufsize;
00028 if(!LoadSave::encodeInc(header,cur,remain,"Ran out of space encoding event header")) return;
00029 unsigned int used=event.saveBuffer(cur,remain);
00030 if(used==0) {
00031 cerr << "ERROR: EventTranslator unable to transmit event because EventBase::saveBuffer failed (buffer==" << (void*)(cur) << ", size==" << remain << ")" << endl;
00032 post(buf,0,onlyReady);
00033 return;
00034 }
00035 cur+=used;
00036 remain-=used;
00037 ASSERT(cur-buf==(int)(bufsize-remain),"used count does not match offset");
00038 post(buf,bufsize-remain,onlyReady);
00039 return;
00040 }
00041
00042 EventBase*
00043 EventTranslator::decodeEvent(const char * entry, unsigned int size) {
00044 EventBase::classTypeID_t header;
00045 if(!LoadSave::decodeInc(header,entry,size,"Ran out of space decoding event")) return NULL;
00046
00047 EventBase* evt=EventBase::getTypeRegistry().create(header);
00048 if(evt==NULL) {
00049 cerr << "ERROR: EventTranslator unable to translate buffer because header does not match a previously registered class type id" << endl;
00050 return NULL;
00051 }
00052 evt->setSaveFormat(EventBase::BINARY);
00053 if(evt->loadBuffer(entry,size)==0) {
00054 cerr << "ERROR: EventTranlator unable to translate buffer because data is malformed (EventBase::loadBuffer failed)" << endl;
00055 return NULL;
00056 }
00057
00058 return evt;
00059 }
00060
00061 void
00062 NoOpEventTranslator::encodeEvent(const EventBase& event, bool ) {
00063 evtRouter.postEvent(event);
00064 }
00065
00066 char*
00067 IPCEventTranslator::bufferRequest(unsigned int size) {
00068 ASSERT(curRegion==NULL,"WARNING: IPCEventTranslator::bufferRequest() curRegion was not NULL");
00069 try {
00070 lock.lock(ProcessID::getID());
00071 curRegion = new RCRegion(size);
00072 return curRegion->Base();
00073 } catch(...) {
00074 lock.unlock();
00075 curRegion=NULL;
00076 throw;
00077 }
00078 }
00079
00080 void
00081 IPCEventTranslator::post(const char* buf, unsigned int size, bool onlyReady) {
00082 ASSERTRET(curRegion!=NULL,"ERROR: IPCEventTranslator::post(buf,size) was NULL");
00083 if(size==0) {
00084 curRegion->RemoveReference();
00085 curRegion=NULL;
00086 return;
00087 }
00088 if(buf!=curRegion->Base()) {
00089 cerr << "ERROR: IPCEventTranslator::post(buf,size) buf does not match value given from previous bufferRequest()" << endl;
00090 return;
00091 }
00092 #ifdef PLATFORM_APERIOS
00093 if(!onlyReady) {
00094 subject.SetData(curRegion);
00095 subject.NotifyObservers();
00096 } else {
00097 for(ObserverConstIterator it=subject.begin(); it!=subject.end(); ++it) {
00098 if(subject.IsReady(*it)) {
00099 subject.SetData(*it,curRegion);
00100 subject.NotifyObserver(*it);
00101 }
00102 }
00103 }
00104 #else
00105 if(!onlyReady || subject.getMessageSN(subject.newest())==subject.getMessagesRead()) {
00106 try {
00107 subject.sendMessage(curRegion);
00108 } catch(const std::exception& ex) {
00109 static char errmsg[256];
00110 strncpy(errmsg,("Occurred during IPCEventTranslator::post(), dropping interprocess event "+curName).c_str(),256);
00111 ProjectInterface::uncaughtException(__FILE__,__LINE__,errmsg,&ex);
00112 } catch(...) {
00113 static char errmsg[256];
00114 strncpy(errmsg,("Occurred during IPCEventTranslator::post(), dropping interprocess event "+curName).c_str(),256);
00115 ProjectInterface::uncaughtException(__FILE__,__LINE__,errmsg,NULL);
00116 }
00117 }
00118 #endif
00119 curRegion->RemoveReference();
00120 curRegion=NULL;
00121 lock.unlock();
00122 }
00123
00124
00125
00126
00127
00128
00129