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 }