datastream.hpp 12.1 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){}
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; }
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;
      }
55 56 57 58 59 60
     
     /**
      *  Writes a byte into the stream
      *  @brief Writes a byte into the stream
      *  @param c byte to write
      */
61
      inline bool put(char c) { 
62
        eosio_assert( _pos < _end, "put" );
63 64 65 66
        *_pos = c; 
        ++_pos; 
        return true;
      }
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 74 75
      inline bool get( unsigned char& c ) { return get( *(char*)&c ); }
      inline bool get( char& c ) 
      {
76
        eosio_assert( _pos < _end, "get" );
77 78 79 80
        c = *_pos;
        ++_pos; 
        return true;
      }
81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101

     /**
      *  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;  }
      
     /**
      *  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); }
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 135 136 137 138 139
/**
 *  Serialize a uint256 into a stream
 *  @brief Serialize a uint256
 *  @param ds stream to write
 *  @param d value to serialize
 */
140 141 142 143 144
template<typename Stream>
inline datastream<Stream>& operator<<(datastream<Stream>& ds, const uint256 d) {
  ds.write( (const char*)&d, sizeof(d) );
  return ds;
}
145 146 147 148 149 150
/**
 *  Deserialize a uint256 from a stream
 *  @brief Deserialize a uint256
 *  @param ds stream to read
 *  @param d destination for deserialized value
 */
151 152 153 154 155 156
template<typename Stream>
inline datastream<Stream>& operator>>(datastream<Stream>& ds, uint256& d) {
  ds.read((char*)&d, sizeof(d) );
  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
/**
 *  Serialize a int64_t into a stream
 *  @brief Serialize a int64_t
 *  @param ds stream to write
 *  @param d value to serialize
 */
255 256 257 258 259
template<typename Stream>
inline datastream<Stream>& operator<<(datastream<Stream>& ds, const int64_t d) {
  ds.write( (const char*)&d, sizeof(d) );
  return ds;
}
260 261 262 263 264 265
/**
 *  Deserialize a int64_t from a stream
 *  @brief Deserialize a int64_t
 *  @param ds stream to read
 *  @param d destination for deserialized value
 */
266 267 268 269 270 271
template<typename Stream>
inline datastream<Stream>& operator>>(datastream<Stream>& ds, int64_t& d) {
  ds.read((char*)&d, sizeof(d) );
  return ds;
}

272 273 274 275 276 277
/**
 *  Serialize a uint64_t into a stream
 *  @brief Serialize a uint64_t
 *  @param ds stream to write
 *  @param d value to serialize
 */
278 279 280 281 282
template<typename Stream>
inline datastream<Stream>& operator<<(datastream<Stream>& ds, const uint64_t d) {
  ds.write( (const char*)&d, sizeof(d) );
  return ds;
}
283 284 285 286 287 288
/**
 *  Deserialize a uint64_t from a stream
 *  @brief Deserialize a uint64_t
 *  @param ds stream to read
 *  @param d destination for deserialized value
 */
289 290 291 292 293 294
template<typename Stream>
inline datastream<Stream>& operator>>(datastream<Stream>& ds, uint64_t& d) {
  ds.read((char*)&d, sizeof(d) );
  return ds;
}

295 296 297 298 299 300
/**
 *  Serialize a int16_t into a stream
 *  @brief Serialize a int16_t
 *  @param ds stream to write
 *  @param d value to serialize
 */
301 302 303 304 305
template<typename Stream>
inline datastream<Stream>& operator<<(datastream<Stream>& ds, const int16_t d) {
  ds.write( (const char*)&d, sizeof(d) );
  return ds;
}
306 307 308 309 310 311
/**
 *  Deserialize a int16_t from a stream
 *  @brief Deserialize a int16_t
 *  @param ds stream to read
 *  @param d destination for deserialized value
 */
312 313 314 315 316 317
template<typename Stream>
inline datastream<Stream>& operator>>(datastream<Stream>& ds, int16_t& d) {
  ds.read((char*)&d, sizeof(d) );
  return ds;
}

318 319 320 321 322 323
/**
 *  Serialize a uint16_t into a stream
 *  @brief Serialize a uint16_t
 *  @param ds stream to write
 *  @param d value to serialize
 */
324 325 326 327 328
template<typename Stream>
inline datastream<Stream>& operator<<(datastream<Stream>& ds, const uint16_t d) {
  ds.write( (const char*)&d, sizeof(d) );
  return ds;
}
329 330 331 332 333 334
/**
 *  Deserialize a uint16_t from a stream
 *  @brief Deserialize a uint16_t
 *  @param ds stream to read
 *  @param d destination for deserialized value
 */
335 336 337 338 339 340
template<typename Stream>
inline datastream<Stream>& operator>>(datastream<Stream>& ds, uint16_t& d) {
  ds.read((char*)&d, sizeof(d) );
  return ds;
}

341 342 343 344 345 346
/**
 *  Serialize a int8_t into a stream
 *  @brief Serialize a int8_t
 *  @param ds stream to write
 *  @param d value to serialize
 */
347 348 349 350 351
template<typename Stream>
inline datastream<Stream>& operator<<(datastream<Stream>& ds, const int8_t d) {
  ds.write( (const char*)&d, sizeof(d) );
  return ds;
}
352 353 354 355 356 357
/**
 *  Deserialize a int8_t from a stream
 *  @brief Deserialize a int8_t
 *  @param ds stream to read
 *  @param d destination for deserialized value
 */
358 359 360 361 362 363
template<typename Stream>
inline datastream<Stream>& operator>>(datastream<Stream>& ds, int8_t& d) {
  ds.read((char*)&d, sizeof(d) );
  return ds;
}

364 365 366 367 368 369
/**
 *  Serialize a uint8_t into a stream
 *  @brief Serialize a uint8_t
 *  @param ds stream to write
 *  @param d value to serialize
 */
370 371 372 373 374
template<typename Stream>
inline datastream<Stream>& operator<<(datastream<Stream>& ds, const uint8_t d) {
  ds.write( (const char*)&d, sizeof(d) );
  return ds;
}
375 376 377 378 379 380
/**
 *  Deserialize a uint8_t from a stream
 *  @brief Deserialize a uint8_t
 *  @param ds stream to read
 *  @param d destination for deserialized value
 */
381 382 383 384 385
template<typename Stream>
inline datastream<Stream>& operator>>(datastream<Stream>& ds, uint8_t& d) {
  ds.read((char*)&d, sizeof(d) );
  return ds;
}
386

387 388 389 390 391 392 393 394 395 396 397 398 399 400 401 402 403 404
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;
}

405 406 407 408 409 410 411 412 413 414 415 416 417 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 446 447
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 ) {
  datastream<size_t> ps; 
  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 已提交
448
}
449