00001
00002 #ifndef INCLUDED_DataEvent_h_
00003 #define INCLUDED_DataEvent_h_
00004
00005 #include "Events/EventBase.h"
00006 #include <sstream>
00007 #include <libxml/tree.h>
00008
00009
00010 template<class T, int TID=-1>
00011 class DataEvent : public EventBase {
00012 public:
00013
00014
00015 DataEvent() : EventBase(), data() {}
00016 DataEvent(const T& d, EventGeneratorID_t gid, size_t sid, EventTypeID_t tid, unsigned int dur=0) : EventBase(gid,sid,tid,dur), data(d) {}
00017 DataEvent(const T& d, EventGeneratorID_t gid, size_t sid, EventTypeID_t tid, unsigned int dur, const std::string& n, float mag) : EventBase(gid,sid,tid,dur,n,mag), data(d) {}
00018
00019
00020 DataEvent(const DataEvent& evt) : EventBase(evt), data(evt.data) {}
00021
00022
00023 const DataEvent& operator=(const DataEvent& evt) { EventBase::operator=(evt); data=evt.data; return *this; }
00024
00025 virtual EventBase* clone() const { return new DataEvent<T>(*this); }
00026
00027
00028 void setData(const T& d) { data=d; }
00029 const T& getData() const { return data; }
00030 T& getData() { return data; }
00031
00032 inline static unsigned int encode(const T& x, char buf[], unsigned int cap) { if(cap<sizeof(T)) return 0; memcpy(buf,(const void*)&x,sizeof(x)); return sizeof(x); }
00033 inline static unsigned int decode(T& x, const char buf[], unsigned int cap) { if(cap<sizeof(T)) return 0; memcpy((void*)&x,buf,sizeof(x)); return sizeof(x); }
00034
00035 virtual unsigned int getBinSize() const;
00036 virtual unsigned int loadBinaryBuffer(const char buf[], unsigned int len);
00037 virtual unsigned int saveBinaryBuffer(char buf[], unsigned int len) const;
00038 virtual void loadXML(xmlNode* node);
00039 virtual void saveXML(xmlNode * node) const;
00040
00041 virtual classTypeID_t getClassTypeID() const { return autoRegisterDataEvent; }
00042
00043 virtual void getDataFromString(std::stringstream &s);
00044 virtual void sendDataToString(std::stringstream &s) const;
00045
00046 protected:
00047 T data;
00048
00049
00050 static EventBase::classTypeID_t registerDataType(EventBase::classTypeID_t classid) {
00051 #if !defined(__GNUC__) || __GNUC__>3 || __GNUC__==3 && __GNUC_MINOR__>3
00052
00053
00054 registry_t& reg = getTypeRegistry();
00055 return reg.registerType<DataEvent>(classid);
00056 #else // using gcc 3.3.x or prior
00057
00058 return getTypeRegistry().registerFactory(classid,new EventBase::registry_t::FactoryType< DataEvent<T,TID> >);
00059 #endif
00060 }
00061 static const EventBase::classTypeID_t autoRegisterDataEvent;
00062 };
00063
00064 #define DATAEVENT_IMPLEMENTATION(_abstract_type, _implementation) \
00065 template<> void DataEvent<_abstract_type, -1>::getDataFromString(std::stringstream &ss) \
00066 { _implementation x; ss >> x; data = (_abstract_type)x; } \
00067 template<> void DataEvent<_abstract_type, -1>::sendDataToString(std::stringstream &ss) const { ss << (_implementation)data; }
00068
00069 #define DATAEVENT_IMPLEMENTATION_H(_abstract_type, _implementation) \
00070 template<> void DataEvent<_abstract_type, -1>::getDataFromString(std::stringstream &ss); \
00071 template<> void DataEvent<_abstract_type, -1>::sendDataToString(std::stringstream &ss) const;
00072
00073 #define DATAEVENT_IMPLEMENTATION_CC(_abstract_type, _implementation) \
00074 template<> void DataEvent<_abstract_type, -1>::getDataFromString(std::stringstream &ss) \
00075 { _implementation x; ss >> x; data = (_abstract_type)x; } \
00076 template<> void DataEvent<_abstract_type, -1>::sendDataToString(std::stringstream &ss) const { ss << (_implementation)data; }
00077
00078
00079
00080
00081 template<class T, int TID>
00082 const EventBase::classTypeID_t DataEvent<T,TID>::autoRegisterDataEvent=DataEvent<T,TID>::registerDataType(makeClassTypeID("DATA")+(TID<0?static_cast<EventBase::classTypeID_t>(getTypeRegistry().getNumTypes()):static_cast<EventBase::classTypeID_t>(TID)));
00083
00084 template<class T, int TID>
00085 unsigned int DataEvent<T,TID>::getBinSize() const {
00086 unsigned int used=EventBase::getBinSize();
00087 if(saveFormat==XML)
00088 return used;
00089
00090 used+=creatorSize("EventBase::DataEvent");
00091 used+=getSerializedSize(data);
00092 return used;
00093 }
00094
00095 template<class T, int TID>
00096 unsigned int DataEvent<T,TID>::loadBinaryBuffer(const char buf[], unsigned int len) {
00097 unsigned int origlen=len;
00098 if(!checkInc(EventBase::loadBinaryBuffer(buf,len),buf,len)) return 0;
00099 if(!checkCreatorInc("EventBase::DataEvent",buf,len,true)) return 0;
00100 unsigned int used = decode(data,buf,len);
00101 if(used==0) return 0; else { buf+=used; len-=used; }
00102 return origlen-len;
00103 }
00104
00105 template<class T, int TID>
00106 unsigned int DataEvent<T,TID>::saveBinaryBuffer(char buf[], unsigned int len) const {
00107 unsigned int origlen=len;
00108 if(!checkInc(EventBase::saveBinaryBuffer(buf,len),buf,len)) return 0;
00109 if(!saveCreatorInc("EventBase::DataEvent",buf,len)) return 0;
00110 unsigned int used = encode(data,buf,len);
00111 if(used==0) return 0; else { buf+=used; len-=used; }
00112 return origlen-len;
00113 }
00114
00115 template<class T, int TID>
00116 void DataEvent<T,TID>::loadXML(xmlNode* node) {
00117 if(node==NULL)
00118 return;
00119
00120 EventBase::loadXML(node);
00121
00122 for(xmlNode* cur = skipToElement(node->children); cur!=NULL; cur = skipToElement(cur->next)) {
00123 if(xmlStrcmp(cur->name, (const xmlChar *)"param"))
00124 continue;
00125
00126 xmlChar * name = xmlGetProp(cur,(const xmlChar*)"name");
00127 if(name==NULL)
00128 throw bad_format(cur,"property missing name");
00129
00130 xmlChar * val = xmlGetProp(cur,(const xmlChar*)"value");
00131 if(val==NULL)
00132 throw bad_format(cur,"property missing value");
00133
00134
00135
00136 if(xmlStrcmp(name, (const xmlChar *)"data")==0) {
00137 std::stringstream ss((const char*)val);
00138 DataEvent<T,-1>::getDataFromString(ss);
00139 xmlFree(val);
00140 xmlFree(name);
00141 }
00142 }
00143 }
00144
00145 template<class T, int TID>
00146 void DataEvent<T,TID>::getDataFromString(std::stringstream&) {
00147 std::cout << "DataEvent failure: don't know how to read data of this type." << std::endl;
00148 }
00149
00150 template<> void DataEvent<unsigned char, -1>::getDataFromString(std::stringstream &ss);
00151 template<> void DataEvent<unsigned short int, -1>::getDataFromString(std::stringstream &ss);
00152 template<> void DataEvent<unsigned int, -1>::getDataFromString(std::stringstream &ss);
00153 template<> void DataEvent<int, -1>::getDataFromString(std::stringstream &ss);
00154 template<> void DataEvent<float, -1>::getDataFromString(std::stringstream &ss);
00155 template<> void DataEvent<double, -1>::getDataFromString(std::stringstream &ss);
00156
00157 template<class T, int TID>
00158 void DataEvent<T,TID>::sendDataToString(std::stringstream&) const {
00159 std::cout << "DataEvent failure: don't know how to encode data of this type as a string." << std::endl;
00160 }
00161
00162 template<> void DataEvent<unsigned char, -1>::sendDataToString(std::stringstream &ss) const;
00163 template<> void DataEvent<unsigned short int, -1>::sendDataToString(std::stringstream &ss) const;
00164 template<> void DataEvent<unsigned int, -1>::sendDataToString(std::stringstream &ss) const;
00165 template<> void DataEvent<int, -1>::sendDataToString(std::stringstream &ss) const;
00166 template<> void DataEvent<float, -1>::sendDataToString(std::stringstream &ss) const;
00167 template<> void DataEvent<double, -1>::sendDataToString(std::stringstream &ss) const;
00168
00169 template<class T, int TID>
00170 void DataEvent<T,TID>::saveXML(xmlNode* node) const {
00171 if(node==NULL)
00172 return;
00173 EventBase::saveXML(node);
00174
00175
00176 for(xmlNode* cur = skipToElement(node->children); cur!=NULL; ) {
00177 if(xmlStrcmp(cur->name, (const xmlChar *)"param")==0) {
00178 xmlUnlinkNode(cur);
00179 xmlFreeNode(cur);
00180 cur = skipToElement(node->children);
00181 } else
00182 cur = skipToElement(cur->next);
00183 }
00184
00185
00186 xmlNode* cur=xmlNewChild(node,NULL,(const xmlChar*)"param",NULL); \
00187 if(cur==NULL) \
00188 throw bad_format(node,"Error: DataEvent xml error on saving param"); \
00189 xmlSetProp(cur,(const xmlChar*)"name",(const xmlChar*)"data"); \
00190 std::stringstream ss;
00191 DataEvent<T,-1>::sendDataToString(ss);
00192 xmlSetProp(cur,(const xmlChar*)"value",(const xmlChar*)ss.str().c_str());
00193 }
00194
00195
00196
00197
00198
00199
00200 #endif