datastream.hpp 12.3 KB
Newer Older
1 2 3 4
/**
 *  @file db.h
 *  @copyright defined in eos/LICENSE.txt
 */
5
#pragma once
6 7 8 9
#include <eosiolib/system.h>
#include <eosiolib/memory.h>
#include <eosiolib/vector.hpp>
#include <eosiolib/varint.hpp>
10
#include <string>
11 12


P
Pravin 已提交
13
namespace eosio {
14 15 16
/**
 *  @brief A data stream for reading and writing data in the form of bytes
 */
17 18 19 20
template<typename T>
class datastream {
   public:
      datastream( T start, size_t s )
21
      :_start(start),_pos(start),_end(start+s){}
A
arhag 已提交
22

23 24 25 26 27
     /**
      *  Skips a specified number of bytes from this stream
      *  @brief Skips a specific number of bytes from this stream
      *  @param s The number of bytes to skip
      */
28
      inline void skip( size_t s ){ _pos += s; }
A
arhag 已提交
29

30 31 32 33 34 35
     /**
      *  Reads a specified number of bytes from the stream into a buffer
      *  @brief Reads a specified number of bytes from this stream into a buffer
      *  @param d pointer to the destination buffer
      *  @param s the number of bytes to read
      */
36
      inline bool read( char* d, size_t s ) {
37
        eosio_assert( size_t(_end - _pos) >= (size_t)s, "read" );
38 39 40 41
        memcpy( d, _pos, s );
        _pos += s;
        return true;
      }
42 43 44 45 46 47 48

     /**
      *  Writes a specified number of bytes into the stream from a buffer
      *  @brief Writes a specified number of bytes into the stream from a buffer
      *  @param d pointer to the source buffer
      *  @param s The number of bytes to write
      */
49
      inline bool write( const char* d, size_t s ) {
50
        eosio_assert( _end - _pos >= (int32_t)s, "write" );
51 52 53 54
        memcpy( _pos, d, s );
        _pos += s;
        return true;
      }
A
arhag 已提交
55

56 57 58 59 60
     /**
      *  Writes a byte into the stream
      *  @brief Writes a byte into the stream
      *  @param c byte to write
      */
A
arhag 已提交
61
      inline bool put(char c) {
62
        eosio_assert( _pos < _end, "put" );
A
arhag 已提交
63 64
        *_pos = c;
        ++_pos;
65 66
        return true;
      }
A
arhag 已提交
67

68 69 70 71 72
     /**
      *  Reads a byte from the stream
      *  @brief Reads a byte from the stream
      *  @param c reference to destination byte
      */
73
      inline bool get( unsigned char& c ) { return get( *(char*)&c ); }
A
arhag 已提交
74
      inline bool get( char& c )
75
      {
76
        eosio_assert( _pos < _end, "get" );
77
        c = *_pos;
A
arhag 已提交
78
        ++_pos;
79 80
        return true;
      }
81 82 83 84 85 86 87 88

     /**
      *  Retrieves the current position of the stream
      *  @brief Retrieves the current position of the stream
      *  @return the current position of the stream
      */
      T pos()const { return _pos; }
      inline bool valid()const { return _pos <= _end && _pos >= _start;  }
A
arhag 已提交
89

90 91 92 93 94 95 96 97 98 99 100 101
     /**
      *  Sets the position within the current stream
      *  @brief Sets the position within the current stream
      *  @param p offset relative to the origin
      */
      inline bool seekp(size_t p) { _pos = _start + p; return _pos <= _end; }

     /**
      *  Gets the position within the current stream
      *  @brief Gets the position within the current stream
      *  @return p the position within the current stream
      */
D
Daniel Larimer 已提交
102
      inline size_t tellp()const      { return size_t(_pos - _start); }
A
arhag 已提交
103

104 105 106 107 108 109
     /**
      *  Returns the number of remaining bytes that can be read/skipped
      *  @brief Returns the number of remaining bytes that can be read/skipped
      *  @return number of remaining bytes
      */
      inline size_t remaining()const  { return _end - _pos; }
110 111 112 113 114 115
    private:
      T _start;
      T _pos;
      T _end;
};

116 117 118
/**
 *  @brief Specialization of datastream used to help determine the final size of a serialized value
 */
119 120 121
template<>
class datastream<size_t> {
   public:
122
     datastream( size_t init_size = 0):_size(init_size){}
123 124 125 126 127 128 129 130 131 132 133
     inline bool     skip( size_t s )                 { _size += s; return true;  }
     inline bool     write( const char* ,size_t s )  { _size += s; return true;  }
     inline bool     put(char )                      { ++_size; return  true;    }
     inline bool     valid()const                     { return true;              }
     inline bool     seekp(size_t p)                  { _size = p;  return true;  }
     inline size_t   tellp()const                     { return _size;             }
     inline size_t   remaining()const                 { return 0;                 }
  private:
     size_t _size;
};

134
/**
A
arhag 已提交
135 136
 *  Serialize a key256 into a stream
 *  @brief Serialize a key256
137 138 139
 *  @param ds stream to write
 *  @param d value to serialize
 */
140
template<typename Stream>
A
arhag 已提交
141 142
inline datastream<Stream>& operator<<(datastream<Stream>& ds, const key256 d) {
  ds.write( (const char*)d.data(), d.size() );
143 144
  return ds;
}
145
/**
A
arhag 已提交
146 147
 *  Deserialize a key256 from a stream
 *  @brief Deserialize a key256
148 149 150
 *  @param ds stream to read
 *  @param d destination for deserialized value
 */
151
template<typename Stream>
A
arhag 已提交
152 153
inline datastream<Stream>& operator>>(datastream<Stream>& ds, key256& d) {
  ds.read((char*)d.data(), d.size() );
154 155 156
  return ds;
}

157 158 159 160 161 162
/**
 *  Serialize a uint128_t into a stream
 *  @brief Serialize a uint128_t
 *  @param ds stream to write
 *  @param d value to serialize
 */
163 164 165 166 167
template<typename Stream>
inline datastream<Stream>& operator<<(datastream<Stream>& ds, const uint128_t d) {
  ds.write( (const char*)&d, sizeof(d) );
  return ds;
}
168 169 170 171 172 173
/**
 *  Deserialize a uint128_t from a stream
 *  @brief Deserialize a uint128_t
 *  @param ds stream to read
 *  @param d destination for deserialized value
 */
174 175 176 177 178 179
template<typename Stream>
inline datastream<Stream>& operator>>(datastream<Stream>& ds, uint128_t& d) {
  ds.read((char*)&d, sizeof(d) );
  return ds;
}

180 181 182 183 184 185
/**
 *  Serialize a int128_t into a stream
 *  @brief Serialize a int128_t
 *  @param ds stream to write
 *  @param d value to serialize
 */
186 187 188 189 190
template<typename Stream>
inline datastream<Stream>& operator<<(datastream<Stream>& ds, const int128_t d) {
  ds.write( (const char*)&d, sizeof(d) );
  return ds;
}
191 192 193 194 195 196
/**
 *  Deserialize a int128_t from a stream
 *  @brief Deserialize a int128_t
 *  @param ds stream to read
 *  @param d destination for deserialized value
 */
197 198 199 200 201 202
template<typename Stream>
inline datastream<Stream>& operator>>(datastream<Stream>& ds, int128_t& d) {
  ds.read((char*)&d, sizeof(d) );
  return ds;
}

203 204 205 206 207 208
/**
 *  Serialize a int32_t into a stream
 *  @brief Serialize a int32_t
 *  @param ds stream to write
 *  @param d value to serialize
 */
209 210 211 212 213
template<typename Stream>
inline datastream<Stream>& operator<<(datastream<Stream>& ds, const int32_t d) {
  ds.write( (const char*)&d, sizeof(d) );
  return ds;
}
214 215 216 217 218 219
/**
 *  Deserialize a int32_t from a stream
 *  @brief Deserialize a int32_t
 *  @param ds stream to read
 *  @param d destination for deserialized value
 */
220 221 222 223 224 225
template<typename Stream>
inline datastream<Stream>& operator>>(datastream<Stream>& ds, int32_t& d) {
  ds.read((char*)&d, sizeof(d) );
  return ds;
}

226 227 228 229 230 231
/**
 *  Serialize a uint32_t into a stream
 *  @brief Serialize a uint32_t
 *  @param ds stream to write
 *  @param d value to serialize
 */
232 233 234 235 236
template<typename Stream>
inline datastream<Stream>& operator<<(datastream<Stream>& ds, const uint32_t d) {
  ds.write( (const char*)&d, sizeof(d) );
  return ds;
}
237 238 239 240 241 242
/**
 *  Deserialize a uint32_t from a stream
 *  @brief Deserialize a uint32_t
 *  @param ds stream to read
 *  @param d destination for deserialized value
 */
243 244 245 246 247 248
template<typename Stream>
inline datastream<Stream>& operator>>(datastream<Stream>& ds, uint32_t& d) {
  ds.read((char*)&d, sizeof(d) );
  return ds;
}

249 250 251 252 253 254 255 256 257 258 259 260 261
template<typename Stream>
inline datastream<Stream>& operator<<(datastream<Stream>& ds, const bool& d) {
  return ds << uint8_t(d);
}
template<typename Stream>
inline datastream<Stream>& operator>>(datastream<Stream>& ds, bool& d) {
  uint8_t t;
  ds >> t;
  d = t;
  return ds;
}


262 263 264 265 266 267
/**
 *  Serialize a int64_t into a stream
 *  @brief Serialize a int64_t
 *  @param ds stream to write
 *  @param d value to serialize
 */
268 269 270 271 272
template<typename Stream>
inline datastream<Stream>& operator<<(datastream<Stream>& ds, const int64_t d) {
  ds.write( (const char*)&d, sizeof(d) );
  return ds;
}
273 274 275 276 277 278
/**
 *  Deserialize a int64_t from a stream
 *  @brief Deserialize a int64_t
 *  @param ds stream to read
 *  @param d destination for deserialized value
 */
279 280 281 282 283 284
template<typename Stream>
inline datastream<Stream>& operator>>(datastream<Stream>& ds, int64_t& d) {
  ds.read((char*)&d, sizeof(d) );
  return ds;
}

285 286 287 288 289 290
/**
 *  Serialize a uint64_t into a stream
 *  @brief Serialize a uint64_t
 *  @param ds stream to write
 *  @param d value to serialize
 */
291 292 293 294 295
template<typename Stream>
inline datastream<Stream>& operator<<(datastream<Stream>& ds, const uint64_t d) {
  ds.write( (const char*)&d, sizeof(d) );
  return ds;
}
296 297 298 299 300 301
/**
 *  Deserialize a uint64_t from a stream
 *  @brief Deserialize a uint64_t
 *  @param ds stream to read
 *  @param d destination for deserialized value
 */
302 303 304 305 306 307
template<typename Stream>
inline datastream<Stream>& operator>>(datastream<Stream>& ds, uint64_t& d) {
  ds.read((char*)&d, sizeof(d) );
  return ds;
}

308 309 310 311 312 313
/**
 *  Serialize a int16_t into a stream
 *  @brief Serialize a int16_t
 *  @param ds stream to write
 *  @param d value to serialize
 */
314 315 316 317 318
template<typename Stream>
inline datastream<Stream>& operator<<(datastream<Stream>& ds, const int16_t d) {
  ds.write( (const char*)&d, sizeof(d) );
  return ds;
}
319 320 321 322 323 324
/**
 *  Deserialize a int16_t from a stream
 *  @brief Deserialize a int16_t
 *  @param ds stream to read
 *  @param d destination for deserialized value
 */
325 326 327 328 329 330
template<typename Stream>
inline datastream<Stream>& operator>>(datastream<Stream>& ds, int16_t& d) {
  ds.read((char*)&d, sizeof(d) );
  return ds;
}

331 332 333 334 335 336
/**
 *  Serialize a uint16_t into a stream
 *  @brief Serialize a uint16_t
 *  @param ds stream to write
 *  @param d value to serialize
 */
337 338 339 340 341
template<typename Stream>
inline datastream<Stream>& operator<<(datastream<Stream>& ds, const uint16_t d) {
  ds.write( (const char*)&d, sizeof(d) );
  return ds;
}
342 343 344 345 346 347
/**
 *  Deserialize a uint16_t from a stream
 *  @brief Deserialize a uint16_t
 *  @param ds stream to read
 *  @param d destination for deserialized value
 */
348 349 350 351 352 353
template<typename Stream>
inline datastream<Stream>& operator>>(datastream<Stream>& ds, uint16_t& d) {
  ds.read((char*)&d, sizeof(d) );
  return ds;
}

354 355 356 357 358 359
/**
 *  Serialize a int8_t into a stream
 *  @brief Serialize a int8_t
 *  @param ds stream to write
 *  @param d value to serialize
 */
360 361 362 363 364
template<typename Stream>
inline datastream<Stream>& operator<<(datastream<Stream>& ds, const int8_t d) {
  ds.write( (const char*)&d, sizeof(d) );
  return ds;
}
365 366 367 368 369 370
/**
 *  Deserialize a int8_t from a stream
 *  @brief Deserialize a int8_t
 *  @param ds stream to read
 *  @param d destination for deserialized value
 */
371 372 373 374 375 376
template<typename Stream>
inline datastream<Stream>& operator>>(datastream<Stream>& ds, int8_t& d) {
  ds.read((char*)&d, sizeof(d) );
  return ds;
}

377 378 379 380 381 382
/**
 *  Serialize a uint8_t into a stream
 *  @brief Serialize a uint8_t
 *  @param ds stream to write
 *  @param d value to serialize
 */
383 384 385 386 387
template<typename Stream>
inline datastream<Stream>& operator<<(datastream<Stream>& ds, const uint8_t d) {
  ds.write( (const char*)&d, sizeof(d) );
  return ds;
}
388 389 390 391 392 393
/**
 *  Deserialize a uint8_t from a stream
 *  @brief Deserialize a uint8_t
 *  @param ds stream to read
 *  @param d destination for deserialized value
 */
394 395 396 397 398
template<typename Stream>
inline datastream<Stream>& operator>>(datastream<Stream>& ds, uint8_t& d) {
  ds.read((char*)&d, sizeof(d) );
  return ds;
}
399

400 401 402 403 404 405 406 407 408 409 410 411 412 413 414 415 416 417
template<typename DataStream>
DataStream& operator << ( DataStream& ds, const std::string& v ) {
   ds << unsigned_int( v.size() );
   for( const auto& i : v )
      ds << i;
   return ds;
}

template<typename DataStream>
DataStream& operator >> ( DataStream& ds, std::string& v ) {
   unsigned_int s;
   ds >> s;
   v.resize(s.value);
   for( auto& i : v )
      ds >> i;
   return ds;
}

418 419 420 421 422 423 424 425 426 427 428 429 430 431 432 433 434 435 436 437 438 439 440 441 442 443 444 445
template<typename DataStream, typename T>
DataStream& operator << ( DataStream& ds, const vector<T>& v ) {
   ds << unsigned_int( v.size() );
   for( const auto& i : v )
      ds << i;
   return ds;
}

template<typename DataStream, typename T>
DataStream& operator >> ( DataStream& ds, vector<T>& v ) {
   unsigned_int s;
   ds >> s;
   v.resize(s.value);
   for( auto& i : v )
      ds >> i;
   return ds;
}

template<typename T>
T unpack( const char* buffer, size_t len ) {
   T result;
   datastream<const char*> ds(buffer,len);
   ds >> result;
   return result;
}

template<typename T>
size_t pack_size( const T& value ) {
A
arhag 已提交
446
  datastream<size_t> ps;
447 448 449 450 451 452 453 454 455 456 457 458 459 460
  ps << value;
  return ps.tellp();
}

template<typename T>
bytes pack( const T& value ) {
  bytes result;
  result.resize(pack_size(value));

  datastream<char*> ds( result.data(), result.size() );
  ds << value;
  return result;
}

A
Anton Perkov 已提交
461
}