Main Page   Class Hierarchy   Compound List   File List   Compound Members   File Members  

netutil.h

Go to the documentation of this file.
00001 //***************************************************************************
00002 // This source code is copyrighted 2002 by Google Inc.  All rights
00003 // reserved.  You are given a limited license to use this source code for
00004 // purposes of participating in the Google programming contest.  If you
00005 // choose to use or distribute the source code for any other purpose, you
00006 // must either (1) first obtain written approval from Google, or (2)
00007 // prominently display the foregoing copyright notice and the following
00008 // warranty and liability disclaimer on each copy used or distributed.
00009 // 
00010 // The source code and repository (the "Software") is provided "AS IS",
00011 // with no warranty, express or implied, including but not limited to the
00012 // implied warranties of merchantability and fitness for a particular
00013 // use.  In no event shall Google Inc. be liable for any damages, direct
00014 // or indirect, even if advised of the possibility of such damages.
00015 //***************************************************************************
00016 
00017 
00018 #ifndef _NETUTIL_H
00019 #define _NETUTIL_H
00020 
00021 /*      Encoder                 -- For encoding data into byte stream
00022         Decoder                 -- For decoding data from byte stream
00023 */
00024 
00025 #include <string.h>
00026 #include <algorithm>        // for min
00027 #include "basictypes.h"
00028 #include "varint.h"
00029 
00030 
00031 /* Class for encoding data into a memory buffer */
00032 class Encoder {
00033  public:
00034   // Empty constructor to create uninitialized encoder
00035   inline Encoder() { }
00036 
00037   // Initialize encoder to encode into "buf"
00038   explicit Encoder(void* buf, int maxn);
00039   void reset(void* buf, int maxn);
00040 
00041   // Encoding routines.  Note that these do not check bounds
00042   void put8(unsigned char v);
00043   void put16(uint16 v);
00044   void put32(uint32 v);
00045   void put64(uint64 v);
00046   void putn(const void* mem, int n);
00047   void putcn(const void* mem, int c, int n); // put no more than n byte,
00048                                              // stopping when c is put
00049   void puts(const void* mem);                // put a c-string including \0
00050   void putfloat(float f);
00051   void putdouble(double d);
00052 
00053   // Support for variable length encoding with 7 bits per byte
00054   // (these are just simple wrappers around the Varint module)
00055   static const int kVarintMax32 = Varint::kMax32;
00056   static const int kVarintMax64 = Varint::kMax64;
00057 
00058   void put_varint32(uint32 v);
00059   void put_varint64(uint64 v);
00060   void put_varsigned32(int32 v);        // Signed 32-bit encoding
00061   static int varint32_length(uint32 v); // Length of var encoding of "v"
00062   static int varint64_length(uint64 v); // Length of var encoding of "v"
00063 
00064   // Return number of bytes encoded so far
00065   int length() const;
00066 
00067  private:
00068   unsigned char* orig_;
00069   unsigned char* buf_;
00070   unsigned char* limit_;
00071 
00072   DISALLOW_EVIL_CONSTRUCTORS(Encoder);
00073 };
00074 
00075 /* Class for decoding data from a memory buffer */
00076 class Decoder {
00077  public:
00078   // Empty constructor to create uninitialized decoder
00079   inline Decoder() { }
00080 
00081   // NOTE: for efficiency reasons, this is not virtual.  so don't add
00082   // any members that really need to be destructed, and be careful about
00083   // inheritance.
00084   ~Decoder() { }
00085 
00086   // Initialize decoder to decode from "buf"
00087   explicit Decoder(const void* buf, int maxn);
00088   void reset(const void* buf, int maxn);
00089 
00090   // Decoding routines.  Note that these do not check bounds
00091   unsigned char  get8();
00092   uint16 get16();
00093   uint32 get32();
00094   uint64 get64();
00095   float  getfloat();
00096   double getdouble();
00097   void   getn(void* mem, int n);
00098   void   getcn(void* mem, int c, int n);    // get no more than n bytes,
00099                                             // stopping after c is got
00100   void   gets(void* mem, int n);            // get a c-string no more than
00101                                             // n bytes. always appends '\0'
00102   void   skip(int n);
00103   unsigned char const* ptr();         // Return pointer to current position in buffer
00104 
00105   // "get_varint" actually checks bounds
00106   bool get_varint32(uint32* v);
00107   bool get_varint64(uint64* v);
00108   bool get_varsigned32(int32* v);
00109 
00110   int pos() const;
00111   // Return number of bytes decoded so far
00112 
00113   int avail() const;
00114   // Return number of available bytes to read
00115  private:
00116   const unsigned char* orig_;
00117   const unsigned char* buf_;
00118   const unsigned char* limit_;
00119 };
00120 
00121 /***** Implementation details.  Clients should ignore them. *****/
00122 
00123 inline Encoder::Encoder(void* b, int maxn) {
00124   orig_ = buf_ = reinterpret_cast<unsigned char*>(b);
00125   limit_ = orig_ + maxn;
00126 }
00127 
00128 inline void Encoder::reset(void* b, int maxn) {
00129   orig_ = buf_ = reinterpret_cast<unsigned char*>(b);
00130   limit_ = orig_ + maxn;
00131 }
00132 
00133 inline int Encoder::length() const {
00134   return (buf_ - orig_);
00135 }
00136 
00137 inline void Encoder::putn(const void* src, int n) {
00138   memcpy(buf_, src, n);
00139   buf_ += n;
00140 }
00141 
00142 inline void Encoder::putcn(const void* src, int c, int n) {
00143   unsigned char *old = buf_;
00144   buf_ = static_cast<unsigned char *>(memccpy(buf_, src, c, n));
00145   if (buf_ == NULL)
00146     buf_ = old + n;
00147 }
00148 
00149 inline void Encoder::puts(const void* src) {
00150   putcn(src, '\0', limit_ - buf_);
00151 }
00152 
00153 inline void Encoder::put_varint32(uint32 v) {
00154   buf_ = reinterpret_cast<unsigned char*>
00155          (Varint::Encode32(reinterpret_cast<char*>(buf_), v));
00156 }
00157 
00158 inline void Encoder::put_varint64(uint64 v) {
00159   buf_ = reinterpret_cast<unsigned char*>
00160          (Varint::Encode64(reinterpret_cast<char*>(buf_), v));
00161 }
00162 
00163 inline void Encoder::put_varsigned32(int32 n) {
00164   // Encode sign in low-bit
00165   int sign = (n < 0) ? 1 : 0;
00166   uint32 mag = (n < 0) ? -n : n;
00167   put_varint32((mag << 1) | sign);
00168 }
00169 
00170 inline Decoder::Decoder(const void* b, int maxn) {
00171   orig_ = buf_ = reinterpret_cast<const unsigned char*>(b);
00172   limit_ = orig_ + maxn;
00173 }
00174 
00175 inline void Decoder::reset(const void* b, int maxn) {
00176   orig_ = buf_ = reinterpret_cast<const unsigned char*>(b);
00177   limit_ = orig_ + maxn;
00178 }
00179 
00180 inline int Decoder::pos() const {
00181   return (buf_ - orig_);
00182 }
00183 
00184 inline int Decoder::avail() const {
00185   return (limit_ - buf_);
00186 }
00187 
00188 inline void Decoder::getn(void* dst, int n) {
00189   memcpy(dst, buf_, n);
00190   buf_ += n;
00191 }
00192 
00193 inline void Decoder::getcn(void* dst, int c, int n) {
00194   void *ptr;
00195   ptr = memccpy(dst, buf_, c, n);
00196   if (ptr == NULL)
00197     buf_ = buf_ + n;
00198   else
00199     buf_ = buf_ + (reinterpret_cast<typeof(buf_)>(ptr) -
00200                    reinterpret_cast<typeof(buf_)>(dst));
00201 }
00202 
00203 inline void Decoder::gets(void* dst, int n) {
00204   int len = min((n - 1), (limit_ - buf_));
00205   (reinterpret_cast<char *>(dst))[len] = '\0';
00206   getcn(dst, '\0', len);
00207 }
00208 
00209 inline void Decoder::skip(int n) {
00210   buf_ += n;
00211 }
00212 
00213 inline unsigned char const* Decoder::ptr() {
00214   return buf_;
00215 }
00216 
00217 inline bool Decoder::get_varsigned32(int32* v) {
00218   uint32 coding;
00219   if (get_varint32(&coding)) {
00220     int sign = coding & 1;
00221     int32 mag = coding >> 1;
00222     *v = sign ? -mag : mag;
00223     return true;
00224   } else {
00225     return false;
00226   }
00227 }
00228 
00229 
00230 #ifdef __i386__ /* __i386__ */
00231 
00232 /* On i386, misaligned operations are no slower than decomposed
00233    byte-wise operations, and the host data is little-endian, so we
00234    have particularly efficient implementations. */
00235 
00236 inline void Encoder::put8(unsigned char v) {
00237   *buf_ = v;
00238   buf_ += sizeof(v);
00239 }
00240 
00241 inline void Encoder::put16(uint16 v) {
00242   *(reinterpret_cast<uint16*>(buf_)) = v;
00243   buf_ += sizeof(v);
00244 }
00245 
00246 inline void Encoder::put32(uint32 v) {
00247   *(reinterpret_cast<uint32*>(buf_)) = v;
00248   buf_ += sizeof(v);
00249 }
00250 
00251 inline void Encoder::put64(uint64 v) {
00252   *(reinterpret_cast<uint64*>(buf_)) = v;
00253   buf_ += sizeof(v);
00254 }
00255 
00256 inline void Encoder::putfloat(float f) {
00257   *(reinterpret_cast<float*>(buf_)) = f;
00258   buf_ += sizeof(f);
00259 }
00260 
00261 inline void Encoder::putdouble(double d) {
00262   *(reinterpret_cast<float*>(buf_)) = d;
00263   buf_ += sizeof(d);
00264 }
00265 
00266 
00267 
00268 inline unsigned char Decoder::get8() {
00269   const unsigned char v = *buf_;
00270   buf_ += sizeof(v);
00271   return v;
00272 }
00273 
00274 inline uint16 Decoder::get16() {
00275   const uint16 v = *(reinterpret_cast<const uint16*>(buf_));
00276   buf_ += sizeof(v);
00277   return v;
00278 }
00279 
00280 inline uint32 Decoder::get32() {
00281   const uint32 v = *(reinterpret_cast<const uint32*>(buf_));
00282   buf_ += sizeof(v);
00283   return v;
00284 }
00285 
00286 inline uint64 Decoder::get64() {
00287   const uint64 v = *(reinterpret_cast<const uint64*>(buf_));
00288   buf_ += sizeof(v);
00289   return v;
00290 }
00291 
00292 
00293 #else
00294 
00295 inline void Encoder::put8(unsigned char v) {
00296   *buf_ = v;
00297   buf_ += sizeof(v);
00298 }
00299 
00300 inline void Encoder::put16(uint16 v) {
00301   *buf_++ = (unsigned char)v;
00302   *buf_++ = (unsigned char)(v >> 8);
00303 }
00304 
00305 inline void Encoder::put32(uint32 v) {
00306   *buf_++ = (unsigned char)v;
00307   *buf_++ = (unsigned char)(v >> 8);
00308   *buf_++ = (unsigned char)(v >> 16);
00309   *buf_++ = (unsigned char)(v >> 24);
00310 }
00311 
00312 inline void Encoder::put64(uint64 v) {
00313   *buf_++ = (unsigned char)v;
00314   *buf_++ = (unsigned char)(v >> 8);
00315   *buf_++ = (unsigned char)(v >> 16);
00316   *buf_++ = (unsigned char)(v >> 24);
00317   *buf_++ = (unsigned char)(v >> 32);
00318   *buf_++ = (unsigned char)(v >> 40);
00319   *buf_++ = (unsigned char)(v >> 48);
00320   *buf_++ = (unsigned char)(v >> 56);
00321 }
00322 
00323 
00324 inline void Encoder::putfloat(float f) {
00325   assert(sizeof(f) == 4);
00326   *buf_++ = *(((unsigned char*)(&f)) + 0);
00327   *buf_++ = *(((unsigned char*)(&f)) + 1);
00328   *buf_++ = *(((unsigned char*)(&f)) + 2);
00329   *buf_++ = *(((unsigned char*)(&f)) + 3);
00330 }
00331 
00332 inline void Encoder::putdouble(double d) {
00333   assert(sizeof(d) == 8);
00334   *buf_++ = *(((unsigned char*)(&d)) + 0);
00335   *buf_++ = *(((unsigned char*)(&d)) + 1);
00336   *buf_++ = *(((unsigned char*)(&d)) + 2);
00337   *buf_++ = *(((unsigned char*)(&d)) + 3);
00338   *buf_++ = *(((unsigned char*)(&d)) + 4);
00339   *buf_++ = *(((unsigned char*)(&d)) + 5);
00340   *buf_++ = *(((unsigned char*)(&d)) + 6);
00341   *buf_++ = *(((unsigned char*)(&d)) + 7);
00342 }
00343 
00344 inline unsigned char Decoder::get8() {
00345   const unsigned char v = *buf_;
00346   buf_ += sizeof(v);
00347   return v;
00348 }
00349 
00350 inline uint16 Decoder::get16() {
00351   const uint16 v = buf_[0] + ((uint16)buf_[1] << 8);
00352   buf_ += sizeof(v);
00353   return v;
00354 }
00355 
00356 inline uint32 Decoder::get32() {
00357   const uint32 v = buf_[0]                 + ((uint32)buf_[1] << 8) +
00358                    ((uint32)buf_[2] << 16) + ((uint32)buf_[3] << 24);
00359   buf_ += sizeof(v);
00360   return v;
00361 }
00362 
00363 inline uint64 Decoder::get64() {
00364   const uint64 v =  buf_[0]                 + ((uint64)buf_[1] << 8) +
00365                     ((uint64)buf_[2] << 16) + ((uint64)buf_[3] << 24) +
00366                     ((uint64)buf_[4] << 32) + ((uint64)buf_[5] << 40) +
00367                     ((uint64)buf_[6] << 48) + ((uint64)buf_[7] << 56);
00368   buf_ += sizeof(v);
00369   return v;
00370 }
00371 
00372 
00373 #endif /* __i386__ */
00374 
00375 inline float Decoder::getfloat() {
00376   float v;
00377   memcpy(&v, buf_, sizeof(v));
00378   buf_ += sizeof(v);
00379   return v;
00380 }
00381 
00382 inline double Decoder::getdouble() {
00383   double v;
00384   memcpy(&v, buf_, sizeof(v));
00385   buf_ += sizeof(v);
00386   return v;
00387 }
00388 
00389 #endif /* _NETUTIL_H */

Generated on Wed May 29 11:37:14 2002 for MarkovPR by doxygen1.2.15