00001
00002
00003
00004
00005
00006
00007
00008 #ifndef __WVSERIALIZE_H
00009 #define __WVSERIALIZE_H
00010
00011 #include "wvbuf.h"
00012 #include "wvstringlist.h"
00013
00014 #ifndef _WIN32
00015 # if HAVE_INTTYPES_H
00016 # include <inttypes.h>
00017 # else
00018 # if HAVE_STDINT_H
00019 # include <stdint.h>
00020 # endif
00021 # endif
00022 #include <netinet/in.h>
00023 #else
00024 typedef __int8 int8_t;
00025 typedef unsigned __int8 uint8_t;
00026 typedef __int16 int16_t;
00027 typedef unsigned __int16 uint16_t;
00028 typedef __int32 int32_t;
00029 typedef unsigned __int32 uint32_t;
00030 typedef __int64 int64_t;
00031 typedef unsigned __int64 uint64_t;
00032 #include <winsock2.h>
00033 #endif
00034
00041 template <typename T>
00042 inline void wv_serialize(WvBuf &buf, const T &t)
00043 {
00044 _wv_serialize(buf, t);
00045 }
00046
00047
00052 inline int32_t _wv_htonl(int32_t i)
00053 {
00054 return htonl(i);
00055 }
00056 inline int16_t _wv_htons(int16_t i)
00057 {
00058 return htons(i);
00059 }
00060
00064 inline uint64_t ntohll(uint64_t n)
00065 {
00066 #ifdef WORDS_BIGENDIAN
00067 return n;
00068 #else
00069 return (((uint64_t)ntohl(n)) << 32) | ntohl(n >> 32);
00070 #endif
00071 }
00072
00073 inline uint64_t htonll(uint64_t n)
00074 {
00075 #ifdef WORDS_BIGENDIAN
00076 return n;
00077 #else
00078 return (((uint64_t)htonl(n)) << 32) | htonl(n >> 32);
00079 #endif
00080 }
00081
00091 template <typename T>
00092 void wv_serialize_scalar(WvBuf &buf, const T t)
00093 {
00094 if (sizeof(T) == 8)
00095 {
00096 int64_t i = htonll(t);
00097 buf.put(&i, 8);
00098 }
00099 else if (sizeof(T) == 4)
00100 {
00101 int32_t i = _wv_htonl(t);
00102 buf.put(&i, 4);
00103 }
00104 else if (sizeof(T) == 2)
00105 {
00106 int32_t i = _wv_htons(t);
00107 buf.put(&i, 2);
00108 }
00109 else if (sizeof(T) == 1)
00110 buf.put(&t, 1);
00111 else
00112 assert(0);
00113 }
00114
00115 inline void _wv_serialize(WvBuf &buf, long long i)
00116 { wv_serialize_scalar(buf, i); }
00117 inline void _wv_serialize(WvBuf &buf, unsigned long long i)
00118 { wv_serialize_scalar(buf, i); }
00119 inline void _wv_serialize(WvBuf &buf, long i)
00120 { wv_serialize_scalar(buf, i); }
00121 inline void _wv_serialize(WvBuf &buf, unsigned long i)
00122 { wv_serialize_scalar(buf, i); }
00123 inline void _wv_serialize(WvBuf &buf, int i)
00124 { wv_serialize_scalar(buf, i); }
00125 inline void _wv_serialize(WvBuf &buf, unsigned int i)
00126 { wv_serialize_scalar(buf, i); }
00127 inline void _wv_serialize(WvBuf &buf, short i)
00128 { wv_serialize_scalar(buf, i); }
00129 inline void _wv_serialize(WvBuf &buf, unsigned short i)
00130 { wv_serialize_scalar(buf, i); }
00131 inline void _wv_serialize(WvBuf &buf, bool i)
00132 { wv_serialize_scalar(buf, i); }
00133
00135 inline void _wv_serialize(WvBuf &buf, char i)
00136 { wv_serialize_scalar(buf, i); }
00137 inline void _wv_serialize(WvBuf &buf, signed char i)
00138 { wv_serialize_scalar(buf, i); }
00139 inline void _wv_serialize(WvBuf &buf, unsigned char i)
00140 { wv_serialize_scalar(buf, i); }
00141
00142
00149 inline void _wv_serialize(WvBuf &buf, WvStringParm s)
00150 {
00151 if (!s.isnull())
00152 buf.putstr(s);
00153 buf.put("", 1);
00154 }
00155
00156
00161 inline void _wv_serialize(WvBuf &buf, const WvBuf &inbuf)
00162 {
00163 wv_serialize(buf, inbuf.used());
00164 buf.put(const_cast<WvBuf *>(&inbuf)->peek(0, inbuf.used()), inbuf.used());
00165 }
00166
00167
00173 template <typename T>
00174 void _wv_serialize(WvBuf &buf, const WvList<T> &list)
00175 {
00176
00177 _wv_serialize(buf, (size_t)list.count());
00178
00179
00180 typename WvList<T>::Iter i(list);
00181 for (i.rewind(); i.next(); )
00182 _wv_serialize(buf, *i);
00183 }
00184
00185
00186
00188 template <typename T>
00189 T _wv_deserialize(WvBuf &buf);
00190
00191
00199 template <typename T>
00200 class WvDeserialize
00201 {
00202 public:
00203 static T go(WvBuf &buf)
00204 { return _wv_deserialize<T>(buf); }
00205 };
00206
00207
00220
00221
00222 template <typename T>
00223 class WvDeserialize<T *>
00224 {
00225 public:
00226 static T *go(WvBuf &buf)
00227 { return new T(_wv_deserialize<T>(buf)); }
00228 };
00229
00230
00231
00251 template <typename T>
00252 inline T wv_deserialize(WvBuf &buf)
00253 {
00254 return WvDeserialize<T>::go(buf);
00255 }
00256
00257
00262 inline int32_t _wv_ntohl(int32_t i)
00263 {
00264 return ntohl(i);
00265 }
00266 inline int16_t _wv_ntohs(int16_t i)
00267 {
00268 return ntohs(i);
00269 }
00270
00271
00277 template <typename T>
00278 inline T wv_deserialize_scalar(WvBuf &buf)
00279 {
00280 if (buf.used() < sizeof(T))
00281 return 0;
00282
00283 if (sizeof(T) == 8)
00284 return (T) ntohll(*(int64_t *)buf.get(8));
00285 else if (sizeof(T) == 4)
00286 return (T) _wv_ntohl(*(int32_t *)buf.get(4));
00287 else if (sizeof(T) == 2)
00288 return (T) _wv_ntohs(*(int16_t *)buf.get(2));
00289 else if (sizeof(T) == 1)
00290 return (T) *(int8_t *)buf.get(1);
00291 else
00292 assert(0);
00293 }
00294
00295 template <typename T>
00296 inline T xwv_deserialize_scalar(WvBuf &buf)
00297 {
00298 return 0;
00299 }
00300
00301 template <>
00302 inline long long _wv_deserialize<long long>(WvBuf &buf)
00303 { return wv_deserialize_scalar<long long>(buf); }
00304 template <>
00305 inline unsigned long long _wv_deserialize<unsigned long long>(WvBuf &buf)
00306 { return wv_deserialize_scalar<unsigned long long>(buf); }
00307 template <>
00308 inline long _wv_deserialize<long>(WvBuf &buf)
00309 { return wv_deserialize_scalar<long>(buf); }
00310 template <>
00311 inline unsigned long _wv_deserialize<unsigned long>(WvBuf &buf)
00312 { return wv_deserialize_scalar<unsigned long>(buf); }
00313 template <>
00314 inline int _wv_deserialize<int>(WvBuf &buf)
00315 { return wv_deserialize_scalar<int>(buf); }
00316 template <>
00317 inline unsigned int _wv_deserialize<unsigned int>(WvBuf &buf)
00318 { return wv_deserialize_scalar<unsigned int>(buf); }
00319 template <>
00320 inline short _wv_deserialize<short>(WvBuf &buf)
00321 { return wv_deserialize_scalar<short>(buf); }
00322 template <>
00323 inline unsigned short _wv_deserialize<unsigned short>(WvBuf &buf)
00324 { return wv_deserialize_scalar<unsigned short>(buf); }
00325 template <>
00326 inline bool _wv_deserialize<bool>(WvBuf &buf)
00327 { return wv_deserialize_scalar<bool>(buf); }
00328 template <>
00329 inline char _wv_deserialize<char>(WvBuf &buf)
00330 { return wv_deserialize_scalar<char>(buf); }
00331 template <>
00332 inline signed char _wv_deserialize<signed char>(WvBuf &buf)
00333 { return wv_deserialize_scalar<signed char>(buf); }
00334 template <>
00335 inline unsigned char _wv_deserialize<unsigned char>(WvBuf &buf)
00336 { return wv_deserialize_scalar<unsigned char>(buf); }
00337
00343 template <>
00344 extern WvString _wv_deserialize<WvString>(WvBuf &buf);
00345
00346
00348
00349 template <>
00350 class WvDeserialize<WvBuf *>
00351 {
00352 public:
00353 static inline WvBuf *go(WvBuf &buf)
00354 {
00355 size_t len = wv_deserialize<size_t>(buf);
00356 WvBuf *outbuf = new WvInPlaceBuf(new char[len], 0, len, true);
00357 outbuf->merge(buf, len);
00358 return outbuf;
00359 }
00360 };
00361
00362
00364 template <typename T>
00365 class WvDeserialize<WvList<T> *>
00366 {
00367 public:
00368 static WvList<T> *go(WvBuf &buf)
00369 {
00370 WvList<T> *list = new WvList<T>;
00371 size_t nelems = wv_deserialize<size_t>(buf);
00372
00373 for (size_t count = 0; count < nelems; count++)
00374 {
00375 T t = wv_deserialize<T>(buf);
00376 list->append(new T(t), true);
00377 }
00378
00379 return list;
00380 }
00381 };
00382
00383 template <>
00384 class WvDeserialize<WvStringList*>
00385 {
00386 public:
00387 static WvStringList *go(WvBuf &buf)
00388 {
00389 WvStringList *list = new WvStringList();
00390 size_t nelems = wv_deserialize<size_t>(buf);
00391
00392 for (size_t count = 0; count < nelems; count++)
00393 {
00394 WvString str = wv_deserialize<WvString>(buf);
00395 list->append(str);
00396 }
00397
00398 return list;
00399 }
00400 };
00401
00402 #endif // __WVSERIALIZE_H