00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030
00031
00032
00033
00034
00035
00036
00037
00038
00039
00040
00041
00042
00043
00044
00045
00046 #ifndef __CXUTILS_PACKET_H
00047 #define __CXUTILS_PACKET_H
00048
00049 #include <limits.h>
00050 #include <string>
00051 #include <vector>
00052 #include <list>
00053 #include "cxbase.h"
00054
00055 #define CX_PACKET_BYTE_SWAP_16(a) \
00056 (((a & 0xFF00) >> 8)| \
00057 ((a & 0x00FF) << 8)) \
00058
00059 #define CX_PACKET_BYTE_SWAP_32(a) \
00060 (((a & 0xFF000000) >> 24)| \
00061 ((a & 0x00FF0000) >> 8) | \
00062 ((a & 0x0000FF00) << 8) | \
00063 ((a & 0x000000FF) << 24)) \
00064
00065 #define CX_PACKET_BYTE_SWAP_64(a) \
00066 (((a & 0xFF00000000000000ULL) >> 56)| \
00067 ((a & 0x00FF000000000000ULL) >> 40)| \
00068 ((a & 0x0000FF0000000000ULL) >> 24)| \
00069 ((a & 0x000000FF00000000ULL) >> 8 )| \
00070 ((a & 0x00000000FF000000ULL) << 8 )| \
00071 ((a & 0x0000000000FF0000ULL) << 24)| \
00072 ((a & 0x000000000000FF00ULL) << 40)| \
00073 ((a & 0x00000000000000FFULL) << 56)) \
00074
00075
00076 namespace CxUtils
00077 {
00078 const unsigned int CX_PACKET_OK = 1;
00079 const unsigned int CX_PACKET_FAILURE = 0;
00080 const unsigned int CX_PACKET_BLOCK_SIZE = 32;
00081 const unsigned int CX_PACKET_LITTLE_ENDIAN = 0;
00082 const unsigned int CX_PACKET_BIG_ENDIAN = 1;
00083
00098 class CX_UTILS_DLL Packet
00099 {
00100 friend class Wrapper;
00101 public:
00102 typedef std::vector<Packet> List;
00103 typedef std::list<Packet> Queue;
00104
00105
00106
00107
00108
00109
00110
00111
00112 class CX_UTILS_DLL Wrapper
00113 {
00114 public:
00115 Wrapper();
00116 Wrapper(const Wrapper& wrapper);
00117 Wrapper(unsigned char* buffer, const unsigned int len);
00118 ~Wrapper();
00119 bool Create(unsigned char* buffer, const unsigned int len);
00120 void Clear();
00121 Packet* operator->();
00122 const Packet* operator->() const;
00123 Packet* GetData();
00124 const Packet* GetData() const;
00125 Wrapper& operator=(const Wrapper& wrapper);
00126 private:
00127 CxUtils::Packet* mPacket;
00128 };
00129 Packet(const unsigned int border = CX_PACKET_LITTLE_ENDIAN);
00130 Packet(const Packet& another);
00131 virtual ~Packet();
00132 int SetByteOrder(const unsigned int order = CX_PACKET_LITTLE_ENDIAN);
00133 int SetWritePos(const unsigned int pos = 0);
00134 int SetReadPos(const unsigned int pos = 0) const;
00135 int SetLength(const unsigned int len = 0);
00136 int Delete(const unsigned int len, const unsigned int start = 0);
00137 int Insert(const unsigned char *buff, const unsigned int len, const unsigned int pos = 0);
00138 int InsertCharacter(const unsigned char value, const unsigned int count, const unsigned int pos = 0);
00139 unsigned int GetByteOrder() const;
00140 unsigned int GetWritePos() const;
00141 unsigned int GetReadPos() const;
00142 unsigned int Size() const;
00143 unsigned int Length() const;
00144 unsigned int Reserved() const { return mReserved; }
00145 void Reserve(const unsigned int size);
00146
00147 virtual int Write(const unsigned char val, const unsigned int pos = UINT_MAX);
00148 virtual int Write(const char val, const unsigned int pos = UINT_MAX);
00149 virtual int Write(const int val, const unsigned int pos = UINT_MAX);
00150 virtual int Write(const short val, const unsigned int pos = UINT_MAX);
00151 virtual int Write(const unsigned short val, const unsigned int pos = UINT_MAX);
00152 virtual int Write(const unsigned int val, const unsigned int pos = UINT_MAX);
00153 virtual int Write(const long long int val, const unsigned int pos = UINT_MAX);
00154 virtual int Write(const unsigned long long int val, const unsigned int pos = UINT_MAX);
00155 virtual int Write(const float val, const unsigned int pos = UINT_MAX);
00156 virtual int Write(const double val, const unsigned int pos = UINT_MAX);
00157 virtual int Write(const unsigned char* buff, const unsigned int len, const unsigned int pos = UINT_MAX);
00158 virtual int Write(const Packet& packet, const unsigned int pos = UINT_MAX);
00159 virtual int Write(const std::string& str, const unsigned int pos = UINT_MAX);
00160 virtual int WriteByte(const unsigned char byte) { return Write(byte); }
00161
00162 virtual int Read(unsigned char& val, const unsigned int pos = UINT_MAX) const;
00163 virtual int Read(char& val, const unsigned int pos = UINT_MAX) const;
00164 virtual int Read(int& val, const unsigned int pos = UINT_MAX) const;
00165 virtual int Read(short& val, const unsigned int pos = UINT_MAX) const;
00166 virtual int Read(unsigned short& val, const unsigned int pos = UINT_MAX) const;
00167 virtual int Read(unsigned int& val, const unsigned int pos = UINT_MAX) const;
00168 virtual int Read(long long int& val, const unsigned int pos = UINT_MAX) const;
00169 virtual int Read(unsigned long long int& val, const unsigned int pos = UINT_MAX) const;
00170 virtual int Read(float& val, const unsigned int pos = UINT_MAX) const;
00171 virtual int Read(double& val, const unsigned int pos = UINT_MAX) const;
00172 virtual int Read(unsigned char *buff, const unsigned int len, const unsigned int pos = UINT_MAX) const;
00173 virtual int Read(Packet& packet, const unsigned int len, const unsigned int pos = UINT_MAX) const;
00174 virtual int Read(std::string& str, const unsigned int len, const unsigned int pos = UINT_MAX) const;
00175
00176 static int Read(const unsigned char *buff, const unsigned int len, const unsigned int pos, char& val, const unsigned int border = CX_PACKET_LITTLE_ENDIAN);
00177 static int Read(const unsigned char *buff, const unsigned int len, const unsigned int pos, unsigned char& val, const unsigned int border = CX_PACKET_LITTLE_ENDIAN);
00178 static int Read(const unsigned char *buff, const unsigned int len, const unsigned int pos, int& val, const unsigned int border = CX_PACKET_LITTLE_ENDIAN);
00179 static int Read(const unsigned char *buff, const unsigned int len, const unsigned int pos, short& val, const unsigned int border = CX_PACKET_LITTLE_ENDIAN);
00180 static int Read(const unsigned char *buff, const unsigned int len, const unsigned int pos, unsigned short& val, const unsigned int border = CX_PACKET_LITTLE_ENDIAN);
00181 static int Read(const unsigned char *buff, const unsigned int len, const unsigned int pos, unsigned int& val, const unsigned int border = CX_PACKET_LITTLE_ENDIAN);
00182 static int Read(const unsigned char *buff, const unsigned int len, const unsigned int pos, long long int& val, const unsigned int border = CX_PACKET_LITTLE_ENDIAN);
00183 static int Read(const unsigned char *buff, const unsigned int len, const unsigned int pos, unsigned long long int& val, const unsigned int border = CX_PACKET_LITTLE_ENDIAN);
00184 static int Read(const unsigned char *buff, const unsigned int len, const unsigned int pos, float& val, const unsigned int border = CX_PACKET_LITTLE_ENDIAN);
00185 static int Read(const unsigned char *buff, const unsigned int len, const unsigned int pos, double& val, const unsigned int border = CX_PACKET_LITTLE_ENDIAN);
00186
00187 void Clear(const bool setZeroFlag = true);
00188 void Destroy();
00189 void Print(const unsigned int bytesPerLine = 8) const;
00196 inline static unsigned int GetMachineEndianness()
00197 {
00198 static int endianness = -1;
00199
00200 if( endianness == -1 )
00201 {
00202 int i = 1;
00203 char *p = (char *) &i;
00204 if (p[0] == 1)
00205 {
00206 endianness = CX_PACKET_LITTLE_ENDIAN;
00207 }
00208 else {
00209 endianness = CX_PACKET_BIG_ENDIAN;
00210 }
00211 }
00212 return endianness;
00213 }
00214 const unsigned char* Ptr() const;
00215 unsigned char* Ptr();
00216 Packet& operator=(const Packet& another);
00217 Packet& operator+=(const Packet& another);
00218 unsigned char operator[](const unsigned int index) const;
00219 static bool LoadWiresharkCapturePacketExport(const std::string& filename,
00220 Packet::List& packets);
00221 protected:
00222 void GrowPacket(unsigned int size);
00223 unsigned char* mpPacket;
00224 unsigned int mLength;
00225 unsigned int mReserved;
00226 unsigned int mWritePos;
00227 unsigned int mReadPos;
00228 unsigned int mByteOrder;
00229 bool mWrappedPacketFlag;
00230
00231 template <class T>
00232 static inline int WritePacket(Packet* p, const T val, const unsigned int pos = UINT_MAX)
00233 {
00234 if (!p)
00235 return 0;
00236
00237 bool overwrite = false;
00238 unsigned int epos = 0;
00239
00240
00241
00242 if(pos == UINT_MAX)
00243 {
00244 epos = p->mWritePos;
00245 }
00246 else
00247 {
00248 overwrite = true;
00249 epos = pos;
00250 }
00251
00252 if(epos > p->mLength || epos == UINT_MAX)
00253 {
00254 return 0;
00255 }
00256
00257 T data;
00258 unsigned int bytes = sizeof(data);
00259
00260 if(p->GetMachineEndianness() != p->mByteOrder && bytes > 1)
00261 {
00262 switch(bytes)
00263 {
00264 case 2:
00265 data = (T)CX_PACKET_BYTE_SWAP_16(val);
00266 break;
00267 case 4:
00268 data = (T)CX_PACKET_BYTE_SWAP_32(val);
00269 break;
00270 case 8:
00271 data = (T)CX_PACKET_BYTE_SWAP_64(val);
00272 break;
00273 default:
00274 data = val;
00275 break;
00276 };
00277 }
00278 else
00279 {
00280 data = val;
00281 }
00282
00283
00284
00285 if((epos + bytes) > p->mReserved && p->mWrappedPacketFlag)
00286 {
00287 return 0;
00288 }
00289
00290
00291
00292 while((epos + bytes) > p->mReserved)
00293 {
00294 p->GrowPacket( epos + bytes + 2 );
00295 }
00296
00297 memcpy(&p->mpPacket[epos], &data, bytes);
00298
00299
00300
00301
00302 if(!overwrite)
00303 p->mWritePos += bytes;
00304
00305 if (epos + bytes > p->mLength)
00306 {
00307 p->mLength = epos + bytes;
00308 if(p->mLength < p->mReserved)
00309 {
00310 p->mpPacket[p->mLength] = 0;
00311 }
00312 }
00313
00314 return bytes;
00315 }
00316
00318 template <class T>
00319 static inline int ReadPacket(const Packet* packet, T& val, unsigned int pos = UINT_MAX)
00320 {
00321 Packet* p = (Packet* )(packet);
00322 if(!p->mpPacket)
00323 return 0;
00324
00325 bool useReadPos = false;
00326 unsigned int dpos = 0;
00327
00328
00329
00330 if(pos == UINT_MAX)
00331 {
00332 useReadPos = true;
00333 dpos = p->mReadPos;
00334 }
00335 else {
00336 dpos = pos;
00337 }
00338 unsigned int bytes = sizeof(val);
00339 if(dpos + bytes <= p->mLength)
00340 {
00341 memcpy(&val, &p->mpPacket[dpos], bytes);
00342
00343 if(p->GetMachineEndianness() != p->mByteOrder && bytes > 1)
00344 {
00345 switch(bytes)
00346 {
00347 case 2:
00348 val = (T)CX_PACKET_BYTE_SWAP_16(val);
00349 break;
00350 case 4:
00351 val = (T)CX_PACKET_BYTE_SWAP_32(val);
00352 break;
00353 case 8:
00354 val = (T)CX_PACKET_BYTE_SWAP_64(val);
00355 break;
00356 default:
00357 val = val;
00358 break;
00359 };
00360 }
00361
00362
00363
00364 if(useReadPos)
00365 {
00366 p->mReadPos += bytes;
00367 }
00368 return bytes;
00369 }
00370 else
00371 return 0;
00372 }
00373
00375 template <class T>
00376 static inline int ReadAtPos(const unsigned char *buff, const unsigned int len, const unsigned int pos, T& val, unsigned int border = CX_PACKET_LITTLE_ENDIAN)
00377 {
00378 if(!buff || len == 0 || pos >= len || border > 1)
00379 return 0;
00380
00381
00382 unsigned int bytes = sizeof(val);
00383 if(pos + bytes <= len)
00384 {
00385 memcpy(&val, &buff[pos], bytes);
00386
00387 if(Packet::GetMachineEndianness() != border && bytes > 1)
00388 {
00389 switch(bytes)
00390 {
00391 case 2:
00392 val = (T)CX_PACKET_BYTE_SWAP_16(val);
00393 break;
00394 case 4:
00395 val = (T)CX_PACKET_BYTE_SWAP_32(val);
00396 break;
00397 case 8:
00398 val = (T)CX_PACKET_BYTE_SWAP_64(val);
00399 break;
00400 default:
00401 val = val;
00402 break;
00403 };
00404 }
00405 return bytes;
00406 }
00407 else
00408 return 0;
00409 }
00410 };
00411 }
00412
00413 #endif
00414
00415