00001 00026 #ifndef ODVA_ETHERNETIP_SEQUENCED_DATA_ITEM_H 00027 #define ODVA_ETHERNETIP_SEQUENCED_DATA_ITEM_H 00028 00029 #include <string> 00030 00031 #include "odva_ethernetip/eip_types.h" 00032 #include "odva_ethernetip/serialization/reader.h" 00033 #include "odva_ethernetip/serialization/writer.h" 00034 #include "odva_ethernetip/serialization/serializable.h" 00035 00036 namespace eip { 00037 00038 using std::string; 00039 using serialization::Serializable; 00040 using serialization::Reader; 00041 using serialization::Writer; 00042 00048 template <class T> 00049 class SequencedDataItem : public T 00050 { 00051 public: 00052 EIP_UINT sequence_num; 00053 00054 SequencedDataItem(EIP_UINT sequence = 0) : sequence_num(sequence), already_deserializing(false) { } 00055 00060 virtual size_t getLength() const 00061 { 00062 return sizeof(sequence_num) + T::getLength(); 00063 } 00064 00071 virtual Writer& serialize(Writer& writer) const 00072 { 00073 writer.write(sequence_num); 00074 return T::serialize(writer); 00075 } 00076 00080 virtual Reader& deserialize(Reader& reader, size_t length) 00081 { 00082 if (already_deserializing) return T::deserialize(reader, length - sizeof(sequence_num)); 00083 reader.read(sequence_num); 00084 already_deserializing = true; 00085 T::deserialize(reader, length - sizeof(sequence_num)); 00086 already_deserializing = false; 00087 return reader; 00088 } 00089 00096 virtual Reader& deserialize(Reader& reader) 00097 { 00098 if (already_deserializing) return T::deserialize(reader); 00099 reader.read(sequence_num); 00100 already_deserializing = true; 00101 T::deserialize(reader); 00102 already_deserializing = false; 00103 return reader; 00104 } 00105 00106 private: 00107 // TODO: this is a total hack, and probably shows that this approach isn't working 00108 bool already_deserializing; 00109 }; 00110 00111 } // namespace eip 00112 00113 #endif // ODVA_ETHERNETIP_SEQUENCED_DATA_ITEM_H