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 #if _MSC_VER
00025 typedef __int8 int8_t;
00026 typedef unsigned __int8 uint8_t;
00027 typedef __int16 int16_t;
00028 typedef unsigned __int16 uint16_t;
00029 typedef __int32 int32_t;
00030 typedef unsigned __int32 uint32_t;
00031 typedef __int64 int64_t;
00032 typedef unsigned __int64 uint64_t;
00033 #endif
00034 #include <winsock2.h>
00035 #endif
00036
00043 template <typename T>
00044 inline void wv_serialize(WvBuf &buf, const T &t)
00045 {
00046 _wv_serialize(buf, t);
00047 }
00048
00049
00054 inline int32_t _wv_htonl(int32_t i)
00055 {
00056 return htonl(i);
00057 }
00058 inline int16_t _wv_htons(int16_t i)
00059 {
00060 return htons(i);
00061 }
00062
00066 inline uint64_t ntohll(uint64_t n)
00067 {
00068 #ifdef WORDS_BIGENDIAN
00069 return n;
00070 #else
00071 return (((uint64_t)ntohl(n)) << 32) | ntohl(n >> 32);
00072 #endif
00073 }
00074
00075 inline uint64_t htonll(uint64_t n)
00076 {
00077 #ifdef WORDS_BIGENDIAN
00078 return n;
00079 #else
00080 return (((uint64_t)htonl(n)) << 32) | htonl(n >> 32);
00081 #endif
00082 }
00083
00093 template <typename T>
00094 void wv_serialize_scalar(WvBuf &buf, const T t)
00095 {
00096 if (sizeof(T) == 8)
00097 {
00098 int64_t i = htonll(t);
00099 buf.put(&i, 8);
00100 }
00101 else if (sizeof(T) == 4)
00102 {
00103 int32_t i = _wv_htonl(t);
00104 buf.put(&i, 4);
00105 }
00106 else if (sizeof(T) == 2)
00107 {
00108 int32_t i = _wv_htons(t);
00109 buf.put(&i, 2);
00110 }
00111 else if (sizeof(T) == 1)
00112 buf.put(&t, 1);
00113 else
00114 assert(0);
00115 }
00116
00117 inline void _wv_serialize(WvBuf &buf, long long i)
00118 { wv_serialize_scalar(buf, i); }
00119 inline void _wv_serialize(WvBuf &buf, unsigned long long i)
00120 { wv_serialize_scalar(buf, i); }
00121 inline void _wv_serialize(WvBuf &buf, long i)
00122 { wv_serialize_scalar(buf, i); }
00123 inline void _wv_serialize(WvBuf &buf, unsigned long i)
00124 { wv_serialize_scalar(buf, i); }
00125 inline void _wv_serialize(WvBuf &buf, int i)
00126 { wv_serialize_scalar(buf, i); }
00127 inline void _wv_serialize(WvBuf &buf, unsigned int i)
00128 { wv_serialize_scalar(buf, i); }
00129 inline void _wv_serialize(WvBuf &buf, short i)
00130 { wv_serialize_scalar(buf, i); }
00131 inline void _wv_serialize(WvBuf &buf, unsigned short i)
00132 { wv_serialize_scalar(buf, i); }
00133 inline void _wv_serialize(WvBuf &buf, bool i)
00134 { wv_serialize_scalar(buf, i); }
00135
00137 inline void _wv_serialize(WvBuf &buf, char i)
00138 { wv_serialize_scalar(buf, i); }
00139 inline void _wv_serialize(WvBuf &buf, signed char i)
00140 { wv_serialize_scalar(buf, i); }
00141 inline void _wv_serialize(WvBuf &buf, unsigned char i)
00142 { wv_serialize_scalar(buf, i); }
00143
00144
00151 inline void _wv_serialize(WvBuf &buf, WvStringParm s)
00152 {
00153 if (!s.isnull())
00154 buf.putstr(s);
00155 buf.put("", 1);
00156 }
00157
00159 inline void wv_serialize(WvBuf &buf, const char *t)
00160 {
00161 _wv_serialize(buf, t);
00162 }
00163
00164
00169 inline void _wv_serialize(WvBuf &buf, const WvBuf &inbuf)
00170 {
00171 wv_serialize(buf, inbuf.used());
00172 buf.put(const_cast<WvBuf *>(&inbuf)->peek(0, inbuf.used()), inbuf.used());
00173 }
00174
00175
00181 template <typename T>
00182 void _wv_serialize(WvBuf &buf, const WvList<T> &list)
00183 {
00184
00185 _wv_serialize(buf, (size_t)list.count());
00186
00187
00188 typename WvList<T>::Iter i(list);
00189 for (i.rewind(); i.next(); )
00190 _wv_serialize(buf, *i);
00191 }
00192
00193
00194
00196 template <typename T>
00197 T _wv_deserialize(WvBuf &buf);
00198
00199
00207 template <typename T>
00208 class WvDeserialize
00209 {
00210 public:
00211 static T go(WvBuf &buf)
00212 { return _wv_deserialize<T>(buf); }
00213 };
00214
00215
00228
00229
00230 template <typename T>
00231 class WvDeserialize<T *>
00232 {
00233 public:
00234 static T *go(WvBuf &buf)
00235 { return new T(_wv_deserialize<T>(buf)); }
00236 };
00237
00238
00239
00259 template <typename T>
00260 inline T wv_deserialize(WvBuf &buf)
00261 {
00262 return WvDeserialize<T>::go(buf);
00263 }
00264
00265
00270 inline int32_t _wv_ntohl(int32_t i)
00271 {
00272 return ntohl(i);
00273 }
00274 inline int16_t _wv_ntohs(int16_t i)
00275 {
00276 return ntohs(i);
00277 }
00278
00279
00285 template <typename T>
00286 inline T wv_deserialize_scalar(WvBuf &buf)
00287 {
00288 if (buf.used() < sizeof(T))
00289 return 0;
00290
00291 if (sizeof(T) == 8)
00292 return (T) ntohll(*(int64_t *)buf.get(8));
00293 else if (sizeof(T) == 4)
00294 return (T) _wv_ntohl(*(int32_t *)buf.get(4));
00295 else if (sizeof(T) == 2)
00296 return (T) _wv_ntohs(*(int16_t *)buf.get(2));
00297 else if (sizeof(T) == 1)
00298 return (T) *(int8_t *)buf.get(1);
00299 else
00300 assert(0);
00301 }
00302
00303 template <typename T>
00304 inline T xwv_deserialize_scalar(WvBuf &buf)
00305 {
00306 return 0;
00307 }
00308
00309 template <>
00310 inline long long _wv_deserialize<long long>(WvBuf &buf)
00311 { return wv_deserialize_scalar<long long>(buf); }
00312 template <>
00313 inline unsigned long long _wv_deserialize<unsigned long long>(WvBuf &buf)
00314 { return wv_deserialize_scalar<unsigned long long>(buf); }
00315 template <>
00316 inline long _wv_deserialize<long>(WvBuf &buf)
00317 { return wv_deserialize_scalar<long>(buf); }
00318 template <>
00319 inline unsigned long _wv_deserialize<unsigned long>(WvBuf &buf)
00320 { return wv_deserialize_scalar<unsigned long>(buf); }
00321 template <>
00322 inline int _wv_deserialize<int>(WvBuf &buf)
00323 { return wv_deserialize_scalar<int>(buf); }
00324 template <>
00325 inline unsigned int _wv_deserialize<unsigned int>(WvBuf &buf)
00326 { return wv_deserialize_scalar<unsigned int>(buf); }
00327 template <>
00328 inline short _wv_deserialize<short>(WvBuf &buf)
00329 { return wv_deserialize_scalar<short>(buf); }
00330 template <>
00331 inline unsigned short _wv_deserialize<unsigned short>(WvBuf &buf)
00332 { return wv_deserialize_scalar<unsigned short>(buf); }
00333 template <>
00334 inline bool _wv_deserialize<bool>(WvBuf &buf)
00335 { return wv_deserialize_scalar<bool>(buf); }
00336 template <>
00337 inline char _wv_deserialize<char>(WvBuf &buf)
00338 { return wv_deserialize_scalar<char>(buf); }
00339 template <>
00340 inline signed char _wv_deserialize<signed char>(WvBuf &buf)
00341 { return wv_deserialize_scalar<signed char>(buf); }
00342 template <>
00343 inline unsigned char _wv_deserialize<unsigned char>(WvBuf &buf)
00344 { return wv_deserialize_scalar<unsigned char>(buf); }
00345
00351 template <>
00352 WvString _wv_deserialize<WvString>(WvBuf &buf);
00353
00354
00356
00357 template <>
00358 class WvDeserialize<WvBuf *>
00359 {
00360 public:
00361 static WvBuf *go(WvBuf &buf)
00362 {
00363 size_t len = wv_deserialize<size_t>(buf);
00364 WvBuf *outbuf = new WvInPlaceBuf(new char[len], 0, len, true);
00365 outbuf->merge(buf, len);
00366 return outbuf;
00367 }
00368 };
00369
00370
00372 template <typename T>
00373 class WvDeserialize<WvList<T> *>
00374 {
00375 public:
00376 static WvList<T> *go(WvBuf &buf)
00377 {
00378 WvList<T> *list = new WvList<T>;
00379 size_t nelems = wv_deserialize<size_t>(buf);
00380
00381 for (size_t count = 0; count < nelems; count++)
00382 {
00383 T t = wv_deserialize<T>(buf);
00384 list->append(new T(t), true);
00385 }
00386
00387 return list;
00388 }
00389 };
00390
00391 template <>
00392 class WvDeserialize<WvStringList*>
00393 {
00394 public:
00395 static WvStringList *go(WvBuf &buf)
00396 {
00397 WvStringList *list = new WvStringList();
00398 size_t nelems = wv_deserialize<size_t>(buf);
00399
00400 for (size_t count = 0; count < nelems; count++)
00401 {
00402 WvString str = wv_deserialize<WvString>(buf);
00403 list->append(str);
00404 }
00405
00406 return list;
00407 }
00408 };
00409
00410 #endif // __WVSERIALIZE_H