00001
00002
00003
00004
00005
00006
00007
00008 #ifndef __WVSERIALIZE_H
00009 #define __WVSERIALIZE_H
00010
00011 #include "wvbuf.h"
00012 #include <stdint.h>
00013 #ifndef _WIN32
00014 #include <netinet/in.h>
00015 #endif
00016
00017
00018
00019
00020
00021
00022
00023 template <typename T>
00024 inline void wv_serialize(WvBuf &buf, const T &t)
00025 {
00026 _wv_serialize(buf, t);
00027 }
00028
00029
00030
00031
00032
00033
00034 inline int32_t _wv_htonl(int32_t i)
00035 {
00036 return htonl(i);
00037 }
00038
00039
00040
00041
00042
00043
00044
00045
00046
00047
00048
00049
00050 template <typename T>
00051 void wv_serialize_scalar(WvBuf &buf, const T t)
00052 {
00053 if (sizeof(T) == 8)
00054 {
00055
00056
00057 buf.put(&t, 8);
00058 }
00059 else if (sizeof(T) == 4)
00060 {
00061 int32_t i = _wv_htonl(t);
00062 buf.put(&i, 4);
00063 }
00064 else if (sizeof(T) == 2)
00065 {
00066 int32_t i = htons(t);
00067 buf.put(&i, 2);
00068 }
00069 else if (sizeof(T) == 1)
00070 buf.put(&t, 1);
00071 else
00072 assert(0);
00073 }
00074
00075 inline void _wv_serialize(WvBuf &buf, long long i)
00076 { wv_serialize_scalar(buf, i); }
00077 inline void _wv_serialize(WvBuf &buf, unsigned long long i)
00078 { wv_serialize_scalar(buf, i); }
00079 inline void _wv_serialize(WvBuf &buf, long i)
00080 { wv_serialize_scalar(buf, i); }
00081 inline void _wv_serialize(WvBuf &buf, unsigned long i)
00082 { wv_serialize_scalar(buf, i); }
00083 inline void _wv_serialize(WvBuf &buf, int i)
00084 { wv_serialize_scalar(buf, i); }
00085 inline void _wv_serialize(WvBuf &buf, unsigned int i)
00086 { wv_serialize_scalar(buf, i); }
00087 inline void _wv_serialize(WvBuf &buf, short i)
00088 { wv_serialize_scalar(buf, i); }
00089 inline void _wv_serialize(WvBuf &buf, unsigned short i)
00090 { wv_serialize_scalar(buf, i); }
00091 inline void _wv_serialize(WvBuf &buf, bool i)
00092 { wv_serialize_scalar(buf, i); }
00093
00094
00095 inline void _wv_serialize(WvBuf &buf, char i)
00096 { wv_serialize_scalar(buf, i); }
00097 inline void _wv_serialize(WvBuf &buf, signed char i)
00098 { wv_serialize_scalar(buf, i); }
00099 inline void _wv_serialize(WvBuf &buf, unsigned char i)
00100 { wv_serialize_scalar(buf, i); }
00101
00102
00103
00104
00105
00106
00107
00108
00109 inline void _wv_serialize(WvBuf &buf, WvStringParm s)
00110 {
00111 if (!s.isnull())
00112 buf.putstr(s);
00113 buf.put("", 1);
00114 }
00115
00116
00117
00118
00119
00120
00121 inline void _wv_serialize(WvBuf &buf, const WvBuf &inbuf)
00122 {
00123 wv_serialize(buf, inbuf.used());
00124 buf.put(const_cast<WvBuf *>(&inbuf)->peek(0, inbuf.used()), inbuf.used());
00125 }
00126
00127
00128
00129
00130
00131
00132
00133 template <typename T>
00134 void _wv_serialize(WvBuf &buf, const WvList<T> &list)
00135 {
00136
00137 _wv_serialize(buf, (size_t)list.count());
00138
00139
00140 typename WvList<T>::Iter i(list);
00141 for (i.rewind(); i.next(); )
00142 _wv_serialize(buf, *i);
00143 }
00144
00145
00146
00147
00148 template <typename T>
00149 T _wv_deserialize(WvBuf &buf);
00150
00151
00152
00153
00154
00155
00156
00157
00158
00159 template <typename T>
00160 class WvDeserialize
00161 {
00162 public:
00163 static T go(WvBuf &buf)
00164 { return _wv_deserialize<T>(buf); }
00165 };
00166
00167
00168
00169
00170
00171
00172
00173
00174
00175
00176
00177
00178
00179
00180
00181
00182 template <typename T>
00183 class WvDeserialize<T *>
00184 {
00185 public:
00186 static T *go(WvBuf &buf)
00187 { return new T(_wv_deserialize<T>(buf)); }
00188 };
00189
00190
00191
00192
00193
00194
00195
00196
00197
00198
00199
00200
00201
00202
00203
00204
00205
00206
00207
00208
00209
00210
00211 template <typename T>
00212 inline T wv_deserialize(WvBuf &buf)
00213 {
00214 return WvDeserialize<T>::go(buf);
00215 }
00216
00217
00218
00219
00220
00221
00222 inline int32_t _wv_ntohl(int32_t i)
00223 {
00224 return ntohl(i);
00225 }
00226
00227
00228
00229
00230
00231
00232
00233 template <typename T>
00234 inline T wv_deserialize_scalar(WvBuf &buf)
00235 {
00236 if (buf.used() < sizeof(T))
00237 return 0;
00238
00239 if (sizeof(T) == 8)
00240 {
00241
00242
00243 return (T) *(int64_t *)buf.get(8);
00244 }
00245 else if (sizeof(T) == 4)
00246 return (T) _wv_ntohl(*(int32_t *)buf.get(4));
00247 else if (sizeof(T) == 2)
00248 return (T) ntohs(*(int16_t *)buf.get(2));
00249 else if (sizeof(T) == 1)
00250 return (T) *(int8_t *)buf.get(1);
00251 else
00252 assert(0);
00253 }
00254
00255 template <typename T>
00256 inline T xwv_deserialize_scalar(WvBuf &buf)
00257 {
00258 return 0;
00259 }
00260
00261 template <>
00262 inline long long _wv_deserialize<long long>(WvBuf &buf)
00263 { return wv_deserialize_scalar<long long>(buf); }
00264 template <>
00265 inline unsigned long long _wv_deserialize<unsigned long long>(WvBuf &buf)
00266 { return wv_deserialize_scalar<unsigned long long>(buf); }
00267 template <>
00268 inline long _wv_deserialize<long>(WvBuf &buf)
00269 { return wv_deserialize_scalar<long>(buf); }
00270 template <>
00271 inline unsigned long _wv_deserialize<unsigned long>(WvBuf &buf)
00272 { return wv_deserialize_scalar<unsigned long>(buf); }
00273 template <>
00274 inline int _wv_deserialize<int>(WvBuf &buf)
00275 { return wv_deserialize_scalar<int>(buf); }
00276 template <>
00277 inline unsigned int _wv_deserialize<unsigned int>(WvBuf &buf)
00278 { return wv_deserialize_scalar<unsigned int>(buf); }
00279 template <>
00280 inline short _wv_deserialize<short>(WvBuf &buf)
00281 { return wv_deserialize_scalar<short>(buf); }
00282 template <>
00283 inline unsigned short _wv_deserialize<unsigned short>(WvBuf &buf)
00284 { return wv_deserialize_scalar<unsigned short>(buf); }
00285 template <>
00286 inline bool _wv_deserialize<bool>(WvBuf &buf)
00287 { return wv_deserialize_scalar<bool>(buf); }
00288 template <>
00289 inline char _wv_deserialize<char>(WvBuf &buf)
00290 { return wv_deserialize_scalar<char>(buf); }
00291 template <>
00292 inline signed char _wv_deserialize<signed char>(WvBuf &buf)
00293 { return wv_deserialize_scalar<signed char>(buf); }
00294 template <>
00295 inline unsigned char _wv_deserialize<unsigned char>(WvBuf &buf)
00296 { return wv_deserialize_scalar<unsigned char>(buf); }
00297
00298
00299
00300
00301
00302
00303 template <>
00304 extern WvString _wv_deserialize<WvString>(WvBuf &buf);
00305
00306
00307
00308
00309 template <>
00310 class WvDeserialize<WvBuf *>
00311 {
00312 public:
00313 static inline WvBuf *go(WvBuf &buf)
00314 {
00315 size_t len = wv_deserialize<size_t>(buf);
00316 WvBuf *outbuf = new WvInPlaceBuf(new char[len], 0, len, true);
00317 outbuf->merge(buf, len);
00318 return outbuf;
00319 }
00320 };
00321
00322
00323
00324 template <typename T>
00325 class WvDeserialize<WvList<T> *>
00326 {
00327 public:
00328 static WvList<T> *go(WvBuf &buf)
00329 {
00330 WvList<T> *list = new WvList<T>;
00331 size_t nelems = wv_deserialize<size_t>(buf);
00332
00333 for (size_t count = 0; count < nelems; count++)
00334 {
00335 T t = wv_deserialize<T>(buf);
00336 list->append(new T(t), true);
00337 }
00338
00339 return list;
00340 }
00341 };
00342
00343
00344 #endif // __WVSERIALIZE_H