00001 00026 #ifndef ODVA_ETHERNETIP_SERIALIZATION_SERIALIZABLE_BUFFER_H 00027 #define ODVA_ETHERNETIP_SERIALIZATION_SERIALIZABLE_BUFFER_H 00028 00029 #include <boost/asio.hpp> 00030 00031 #include "odva_ethernetip/serialization/serializable.h" 00032 #include "odva_ethernetip/serialization/writer.h" 00033 #include "odva_ethernetip/serialization/reader.h" 00034 #include "odva_ethernetip/serialization/buffer_reader.h" 00035 00036 using boost::asio::mutable_buffer; 00037 using boost::asio::buffer_size; 00038 00039 namespace eip { 00040 namespace serialization { 00041 00045 class SerializableBuffer : public Serializable 00046 { 00047 public: 00048 00053 SerializableBuffer() : data_(NULL, 0), allocated_buffer_(NULL) { } 00054 00059 SerializableBuffer(mutable_buffer data) : data_(data), allocated_buffer_(NULL) { } 00060 00061 virtual ~SerializableBuffer() 00062 { 00063 deleteAllocatedBuffer(); 00064 data_ = mutable_buffer(NULL, 0); 00065 } 00066 00071 virtual size_t getLength() const 00072 { 00073 return buffer_size(data_); 00074 } 00075 00080 virtual mutable_buffer getData() const 00081 { 00082 return data_; 00083 } 00084 00089 virtual void setData(mutable_buffer data) 00090 { 00091 // TODO: It's possible that the user could pass in the same buffer again, 00092 // or a subset of it. That would be absurd, but possible. 00093 deleteAllocatedBuffer(); 00094 data_ = data; 00095 } 00096 00103 virtual Writer& serialize(Writer& writer) const 00104 { 00105 writer.writeBuffer(data_); 00106 return writer; 00107 } 00108 00118 virtual Reader& deserialize(Reader& reader, size_t length) 00119 { 00120 // with a BufferReader, we can read without copying 00121 BufferReader* br = dynamic_cast<BufferReader*>(&reader); 00122 if (br) 00123 { 00124 deleteAllocatedBuffer(); 00125 data_ = br->readBuffer(length); 00126 } 00127 else 00128 { 00129 if (length != buffer_size(data_)) 00130 { 00131 // must allocate a new buffer 00132 deleteAllocatedBuffer(); 00133 allocated_buffer_ = new char[length]; 00134 data_ = buffer(allocated_buffer_, length); 00135 } 00136 reader.readBuffer(data_); 00137 } 00138 return reader; 00139 } 00140 00148 virtual Reader& deserialize(Reader& reader) 00149 { 00150 reader.readBuffer(data_); 00151 return reader; 00152 } 00153 00154 void operator=(mutable_buffer b) 00155 { 00156 data_ = b; 00157 } 00158 00159 private: 00160 mutable_buffer data_; 00161 char* allocated_buffer_; 00162 00166 void deleteAllocatedBuffer() 00167 { 00168 if (allocated_buffer_) 00169 { 00170 delete[] allocated_buffer_; 00171 allocated_buffer_ = NULL; 00172 } 00173 } 00174 }; 00175 00176 } // namespace serialization 00177 } // namespace eip 00178 #endif // ODVA_ETHERNETIP_SERIALIZATION_SERIALIZABLE_BUFFER_H