00001 
00002 
00003 
00004 #include "tpt_pickler.h"
00005 #include <sys/stat.h>
00006 #include <cassert>
00007 
00008 #ifdef __CYGWIN__
00009 #define stat64  stat
00010 #endif
00011 
00012 namespace tpt
00013 {
00014 
00015   uint64_t
00016   getFileSize(const std::string& fname)
00017   {
00018     struct stat64 buf;
00019     stat64(fname.c_str(),&buf);
00020     return buf.st_size;
00021   }
00022 
00023   template <typename T>
00024   void
00025   binwrite_unsigned_integer(std::ostream& out, T data)
00026   {
00027     char c;
00028     while (data >= 128)
00029       {
00030         out.put(data%128);
00031         data = data >> 7;
00032       }
00033     c = data;
00034     out.put(c|char(-128)); 
00035   }
00036 
00037   template<typename T>
00038   void
00039   binread_unsigned_integer(std::istream& in, T& data)
00040   {
00041     char c, mask=127;
00042     in.clear();
00043     in.get(c);
00044     data = c&mask;
00045 
00046     if (c < 0) return;
00047     in.get(c);
00048     data += T(c&mask) << 7;
00049     if (c < 0) return;
00050     in.get(c);
00051     data += T(c&mask) << 14;
00052     if (c < 0) return;
00053     in.get(c);
00054     data += T(c&mask) << 21;
00055     if (c < 0) return;
00056     in.get(c);
00057     data += T(c&mask) << 28;
00058     if (c < 0) return;
00059     in.get(c);
00060     data += T(c&mask) << 35;
00061     if (c < 0) return;
00062     in.get(c);
00063     data += T(c&mask) << 42;
00064     if (c < 0) return;
00065     in.get(c);
00066     data += T(c&mask) << 49;
00067     if (c < 0) return;
00068     in.get(c);
00069     data += T(c&mask) << 56;
00070     if (c < 0) return;
00071     in.get(c);
00072     data += T(c&mask) << 63;
00073   }
00074 
00075   void
00076   binwrite(std::ostream& out, unsigned char data)
00077   {
00078     binwrite_unsigned_integer(out, data);
00079   }
00080 
00081   void
00082   binwrite(std::ostream& out, unsigned short data)
00083   {
00084     binwrite_unsigned_integer(out, data);
00085   }
00086 
00087   void
00088   binwrite(std::ostream& out, unsigned long data)
00089   {
00090     binwrite_unsigned_integer(out, data);
00091   }
00092 
00093   void
00094   binwrite(std::ostream& out, unsigned long long data)
00095   {
00096     binwrite_unsigned_integer(out, data);
00097   }
00098 
00099 #if __WORDSIZE == 64
00100   void
00101   binwrite(std::ostream& out, unsigned int data)
00102   {
00103     binwrite_unsigned_integer(out, data);
00104   }
00105 #else
00106   void
00107   binwrite(std::ostream& out, size_t data)
00108   {
00109     binwrite_unsigned_integer(out, data);
00110   }
00111 #endif
00112 
00113   void
00114   binread(std::istream& in, unsigned short& data)
00115   {
00116     assert(sizeof(data)==2);
00117     char c, mask=127;
00118     in.clear();
00119     in.get(c);
00120     data = c&mask;
00121     if (c < 0) return;
00122     in.get(c);
00123     data += uint16_t(c&mask) << 7;
00124     if (c < 0) return;
00125     in.get(c);
00126     data += uint16_t(c&mask) << 14;
00127   }
00128 
00129   void
00130   binread(std::istream& in, unsigned int& data)
00131   {
00132     assert(sizeof(data) == 4);
00133     char c, mask=127;
00134     in.clear();
00135     in.get(c);
00136     data = c&mask;
00137     if (c < 0) return;
00138     in.get(c);
00139     data += uint32_t(c&mask) << 7;
00140     if (c < 0) return;
00141     in.get(c);
00142     data += uint32_t(c&mask) << 14;
00143     if (c < 0) return;
00144     in.get(c);
00145     data += uint32_t(c&mask) << 21;
00146     if (c < 0) return;
00147     in.get(c);
00148     data += uint32_t(c&mask) << 28;
00149   }
00150 
00151   void
00152   binread(std::istream& in, unsigned long& data)
00153   {
00154 #if __WORDSIZE == 32
00155     assert(sizeof(unsigned long)==4);
00156 #else
00157     assert(sizeof(unsigned long)==8);
00158 #endif
00159     char c, mask=127;
00160     in.get(c);
00161     data = c&mask;
00162     if (c < 0) return;
00163     in.get(c);
00164     data += static_cast<unsigned long long>(c&mask) << 7;
00165     if (c < 0) return;
00166     in.get(c);
00167     data += static_cast<unsigned long long>(c&mask) << 14;
00168     if (c < 0) return;
00169     in.get(c);
00170     data += static_cast<unsigned long long>(c&mask) << 21;
00171     if (c < 0) return;
00172     in.get(c);
00173     data += static_cast<unsigned long long>(c&mask) << 28;
00174 #if __WORDSIZE == 64
00175     if (c < 0) return;
00176     in.get(c);
00177     data += static_cast<unsigned long long>(c&mask) << 35;
00178     if (c < 0) return;
00179     in.get(c);
00180     data += static_cast<unsigned long long>(c&mask) << 42;
00181     if (c < 0) return;
00182     in.get(c);
00183 
00184     data += static_cast<unsigned long long>(c&mask) << 49;
00185     if (c < 0) return;
00186     in.get(c);
00187 
00188     data += static_cast<unsigned long long>(c&mask) << 56;
00189     if (c < 0) return;
00190     in.get(c);
00191 
00192     data += static_cast<unsigned long long>(c&mask) << 63;
00193 #endif
00194   }
00195 
00196   void
00197   binread(std::istream& in, unsigned long long& data)
00198   {
00199     assert(sizeof(unsigned long long)==8);
00200     char c, mask=127;
00201     in.get(c);
00202     data = c&mask;
00203     if (c < 0) return;
00204     in.get(c);
00205     data += static_cast<unsigned long long>(c&mask) << 7;
00206     if (c < 0) return;
00207     in.get(c);
00208     data += static_cast<unsigned long long>(c&mask) << 14;
00209     if (c < 0) return;
00210     in.get(c);
00211     data += static_cast<unsigned long long>(c&mask) << 21;
00212     if (c < 0) return;
00213     in.get(c);
00214     data += static_cast<unsigned long long>(c&mask) << 28;
00215     if (c < 0) return;
00216     in.get(c);
00217     data += static_cast<unsigned long long>(c&mask) << 35;
00218     if (c < 0) return;
00219     in.get(c);
00220     data += static_cast<unsigned long long>(c&mask) << 42;
00221     if (c < 0) return;
00222     in.get(c);
00223     data += static_cast<unsigned long long>(c&mask) << 49;
00224     if (c < 0) return;
00225     in.get(c);
00226     data += static_cast<unsigned long long>(c&mask) << 56;
00227     if (c < 0) return;
00228     in.get(c);
00229     data += static_cast<unsigned long long>(c&mask) << 63;
00230   }
00231 
00232   
00233   void
00234   binwrite(std::ostream& out, std::string const& s)
00235   {
00236     size_t len = s.size();
00237     binwrite(out,len);
00238     out.write(s.c_str(),len);
00239   }
00240 
00241   void
00242   binread(std::istream& in, std::string& s)
00243   {
00244     size_t len;
00245     binread(in,len);
00246     if (!in) return;
00247     char buf[len+1];
00248     in.read(buf,len);
00249     buf[len] = 0;
00250     s = buf;
00251   }
00252 
00253   void
00254   binwrite(std::ostream& out, float x)
00255   {
00256     
00257     
00258     out.write(reinterpret_cast<char*>(&x),sizeof(float));
00259   }
00260 
00261   void
00262   binread(std::istream& in, float& x)
00263   {
00264     
00265     
00266     in.read(reinterpret_cast<char*>(&x),sizeof(x));
00267   }
00268 
00269 
00270   char const *binread(char const* p, uint16_t& buf)
00271   {
00272     static char mask = 127;
00273     buf = (*p)&mask;
00274     if (*p++ < 0) return p;
00275     buf += uint16_t((*p)&mask)<<7;
00276     if (*p++ < 0) return p;
00277     buf += uint16_t((*p)&mask)<<14;
00278 #ifndef NDEBUG
00279     assert(*p++ < 0);
00280 #else
00281     ++p;
00282 #endif
00283     return p;
00284   }
00285 
00286 #ifdef __clang__
00287   char const *binread(char const* p, size_t& buf)
00288   {
00289           return binread(p, (uint32_t&) buf);
00290   }
00291 #endif
00292 
00293   char const *binread(char const* p, uint32_t& buf)
00294   {
00295     static char mask = 127;
00296 
00297     if (*p < 0)
00298       {
00299         buf = (*p)&mask;
00300         return ++p;
00301       }
00302     buf = *p;
00303     if (*(++p) < 0)
00304       {
00305         buf += uint32_t((*p)&mask)<<7;
00306         return ++p;
00307       }
00308     buf += uint32_t(*p)<<7;
00309     if (*(++p) < 0)
00310       {
00311         buf += uint32_t((*p)&mask)<<14;
00312         return ++p;
00313       }
00314     buf += uint32_t(*p)<<14;
00315     if (*(++p) < 0)
00316       {
00317         buf += uint32_t((*p)&mask)<<21;
00318         return ++p;
00319       }
00320     buf += uint32_t(*p)<<21;
00321 #ifndef NDEBUG
00322     assert(*(++p) < 0);
00323 #else
00324     ++p;
00325 #endif
00326     buf += uint32_t((*p)&mask)<<28;
00327     return ++p;
00328   }
00329 
00330   char const *binread(char const* p, filepos_type& buf)
00331   {
00332     static char mask = 127;
00333 
00334     if (*p < 0)
00335       {
00336         buf = (*p)&mask;
00337         return ++p;
00338       }
00339     buf = *p;
00340     if (*(++p) < 0)
00341       {
00342         buf += filepos_type((*p)&mask)<<7;
00343         return ++p;
00344       }
00345     buf += filepos_type(*p)<<7;
00346     if (*(++p) < 0)
00347       {
00348         buf += filepos_type((*p)&mask)<<14;
00349         return ++p;
00350       }
00351     buf += filepos_type(*p)<<14;
00352     if (*(++p) < 0)
00353       {
00354         buf += filepos_type((*p)&mask)<<21;
00355         return ++p;
00356       }
00357     buf += filepos_type(*p)<<21;
00358     if (*(++p) < 0)
00359       {
00360         buf += filepos_type((*p)&mask)<<28;
00361         return ++p;
00362       }
00363     buf += filepos_type(*p)<<28;
00364     if (*(++p) < 0)
00365       {
00366         buf += filepos_type((*p)&mask)<<35;
00367         return ++p;
00368       }
00369     buf += filepos_type(*p)<<35;
00370     if (*(++p) < 0)
00371       {
00372         buf += filepos_type((*p)&mask)<<42;
00373         return ++p;
00374       }
00375     buf += filepos_type(*p)<<42;
00376     if (*(++p) < 0)
00377       {
00378         buf += filepos_type((*p)&mask)<<49;
00379         return ++p;
00380       }
00381     buf += filepos_type(*p)<<49;
00382     if (*(++p) < 0)
00383       {
00384         buf += filepos_type((*p)&mask)<<56;
00385         return ++p;
00386       }
00387     buf += filepos_type(*p)<<56;
00388 #ifndef NDEBUG
00389     assert(*(++p) < 0);
00390 #else
00391     ++p;
00392 #endif
00393     buf += filepos_type((*p)&mask)<<63;
00394     return ++p;
00395   }
00396 
00397   char const *binread(char const* p, float& buf)
00398   {
00399     buf = *reinterpret_cast<float const*>(p);
00400     return p+sizeof(float);
00401   }
00402 
00403 }