Main Page | Modules | Class Hierarchy | Alphabetical List | Class List | Directories | File List | Class Members | File Members | Related Pages

wvserialize.h

00001 /* -*- Mode: C++ -*-
00002  * Worldvisions Weaver Software:
00003  *   Copyright (C) 1997-2002 Net Integration Technologies, Inc.
00004  *
00005  * Code to serialize objects into WvBufs, and more code to read WvBufs and
00006  * construct objects from them.
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); // terminating nul
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     // save the number of elements
00177     _wv_serialize(buf, (size_t)list.count());
00178     
00179     // save the elements
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 // note: this has to be a class because we use partial template
00221 // specialization, which doesn't work on functions.
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 // FIXME: it should be possible to do this without using a class!
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

Generated on Sun Jul 10 17:30:57 2005 for WvStreams by  doxygen 1.4.0