8#include <bluegrass/meta/for_each.hpp>
46 :_start(start),_pos(start),_end(start+s){}
53 inline void skip(
size_t s ){ _pos += s; }
62 inline bool read(
void* d,
size_t s ) {
63 eosio::check(
size_t(_end - _pos) >= (
size_t)s,
"datastream attempted to read past the end" );
76 inline bool write(
const char* d,
size_t s ) {
77 eosio::check( _end - _pos >= (int32_t)s,
"datastream attempted to write past the end" );
78 memcpy( (
void*)_pos, d, s );
90 eosio::check( _end - _pos >= 1,
"datastream attempted to write past the end" );
102 inline bool write(
const void* d,
size_t s ) {
103 eosio::check( _end - _pos >= (int32_t)s,
"datastream attempted to write past the end" );
104 memcpy( (
void*)_pos, d, s );
128 inline bool get(
unsigned char& c ) {
return get( *(
char*)&c ); }
136 inline bool get(
char& c )
149 T
pos()
const {
return _pos; }
150 inline bool valid()
const {
return _pos <= _end && _pos >= _start; }
159 inline bool seekp(
size_t p) { _pos = _start + p;
return _pos <= _end; }
208 inline bool skip(
size_t s ) { _size += s;
return true; }
216 inline bool write(
const char* ,
size_t s ) { _size += s;
return true; }
224 inline bool write(
char ) { _size++;
return true; }
232 inline bool write(
const void* ,
size_t s ) { _size += s;
return true; }
239 inline bool put(
char ) { ++_size;
return true; }
246 inline bool valid()
const {
return true; }
254 inline bool seekp(
size_t p) { _size = p;
return true; }
261 inline size_t tellp()
const {
return _size; }
284template<
typename Stream,
typename T>
285inline datastream<Stream>&
operator<<(datastream<Stream>& ds,
const std::list<T>& l) {
286 ds << unsigned_int( l.size() );
287 for (
const auto& elem : l )
300template<
typename Stream,
typename T>
318template<
typename Stream,
typename T>
319inline datastream<Stream>&
operator<<(datastream<Stream>& ds,
const std::deque<T>& d) {
320 ds << unsigned_int( d.size() );
321 for (
const auto& elem : d )
334template<
typename Stream,
typename T>
352template<
typename Stream,
typename... Ts>
353inline datastream<Stream>&
operator<<(datastream<Stream>& ds,
const std::variant<Ts...>& var) {
354 unsigned_int index = var.index();
356 std::visit([&ds](
auto& val){ ds << val; }, var);
360template<
int I,
typename Stream,
typename... Ts>
362 if constexpr (I < std::variant_size_v<std::variant<Ts...>>) {
364 std::variant_alternative_t<I, std::variant<Ts...>> tmp;
366 var.template emplace<I>(std::move(tmp));
368 deserialize<I+1>(ds,var,i);
383template<
typename Stream,
typename... Ts>
387 deserialize<0>(ds,var,index);
400template<
typename Stream,
typename T1,
typename T2>
401datastream<Stream>&
operator<<( datastream<Stream>& ds,
const std::pair<T1, T2>& t ) {
402 ds << std::get<0>(t);
403 ds << std::get<1>(t);
416template<
typename Stream,
typename T1,
typename T2>
422 t = std::pair<T1, T2>{t1, t2};
434template<
typename Stream,
typename T>
435inline datastream<Stream>&
operator<<(datastream<Stream>& ds,
const std::optional<T>& opt) {
436 char valid = opt.has_value();
451template<
typename Stream,
typename T>
472template<
typename Stream>
473inline datastream<Stream>&
operator<<(datastream<Stream>& ds,
const bool& d) {
474 return ds << uint8_t(d);
485template<
typename Stream>
501template<
typename Stream>
502datastream<Stream>&
operator << ( datastream<Stream>& ds,
const std::string& v ) {
503 ds << unsigned_int( v.size() );
505 ds.write(v.data(), v.size());
517template<
typename Stream>
519 std::vector<char> tmp;
522 v = std::string(tmp.data(),tmp.data()+tmp.size());
538template<
typename Stream,
typename T, std::
size_t N>
539datastream<Stream>&
operator << ( datastream<Stream>& ds,
const std::array<T,N>& v ) {
540 for(
const auto& i : v )
556template<
typename Stream,
typename T, std::
size_t N>
563namespace _datastream_detail {
573 return std::is_pointer<T>::value ||
574 std::is_null_pointer<T>::value ||
575 std::is_member_pointer<T>::value;
587 return std::is_arithmetic<T>::value ||
588 std::is_enum<T>::value;
612template<typename Stream, typename T, std::enable_if_t<_datastream_detail::is_pointer<T>()>* =
nullptr>
614 static_assert(!_datastream_detail::is_pointer<T>(),
"Pointers should not be serialized" );
627template<
typename Stream,
typename T,
std::size_t N,
628 std::enable_if_t<!_datastream_detail::is_primitive<T>() &&
629 !_datastream_detail::is_pointer<T>()>* =
nullptr>
630datastream<Stream>&
operator << ( datastream<Stream>& ds,
const T (&v)[N] ) {
631 ds << unsigned_int( N );
646template<
typename Stream,
typename T,
std::size_t N,
647 std::enable_if_t<_datastream_detail::is_primitive<T>()>* =
nullptr>
648datastream<Stream>&
operator << ( datastream<Stream>& ds,
const T (&v)[N] ) {
649 ds << unsigned_int( N );
650 ds.write((
char*)&v[0],
sizeof(v));
664template<
typename Stream,
typename T,
std::size_t N,
665 std::enable_if_t<!_datastream_detail::is_primitive<T>() &&
666 !_datastream_detail::is_pointer<T>()>* =
nullptr>
686template<
typename Stream,
typename T,
std::size_t N,
687 std::enable_if_t<_datastream_detail::is_primitive<T>()>* =
nullptr>
692 ds.
read((
char*)&v[0],
sizeof(v));
704template<
typename Stream,
typename T,
705 std::enable_if_t<_datastream_detail::is_primitive<T>()>* =
nullptr>
706datastream<Stream>&
operator << ( datastream<Stream>& ds,
const std::vector<T>& v ) {
707 ds << unsigned_int( v.size() );
708 ds.write( (
const void*)v.data(), v.size()*
sizeof(T) );
721template<
typename Stream,
typename T,
722 std::enable_if_t<!_datastream_detail::is_primitive<T>()>* =
nullptr>
723datastream<Stream>&
operator << ( datastream<Stream>& ds,
const std::vector<T>& v ) {
724 ds << unsigned_int( v.size() );
725 for(
const auto& i : v )
738template<
typename Stream,
typename T,
739 std::enable_if_t<_datastream_detail::is_primitive<T>()>* =
nullptr>
744 ds.
read( (
char*)v.data(), v.size()*
sizeof(T) );
757template<
typename Stream,
typename T,
758 std::enable_if_t<!_datastream_detail::is_primitive<T>()>* =
nullptr>
777template<
typename Stream,
typename T>
778datastream<Stream>&
operator << ( datastream<Stream>& ds,
const std::basic_string<T>& s ) {
779 ds << unsigned_int(s.size());
781 ds.write(s.data(), s.size()*
sizeof(T));
794template<
typename Stream,
typename T>
799 ds.
read(s.data(), s.size()*
sizeof(T));
812template<
typename Stream>
813datastream<Stream>&
operator << ( datastream<Stream>& ds,
const std::basic_string<uint8_t>& s ) {
814 ds << unsigned_int(s.size());
816 ds.write(s.data(), s.size());
829template<
typename Stream>
834 ds.
read(s.data(), s.size());
848template<
typename Stream,
typename T>
849datastream<Stream>&
operator << ( datastream<Stream>& ds,
const std::set<T>& s ) {
850 ds << unsigned_int( s.size() );
851 for(
const auto& i : s ) {
867template<
typename Stream,
typename T>
875 s.emplace( std::move(v) );
890template<
typename Stream,
typename K,
typename V>
891datastream<Stream>&
operator << ( datastream<Stream>& ds,
const std::map<K,V>& m ) {
892 ds << unsigned_int( m.size() );
893 for(
const auto& i : m ) {
894 ds << i.first << i.second;
909template<
typename Stream,
typename K,
typename V>
917 m.emplace( std::move(k), std::move(v) );
931template<
typename Stream,
typename... Args>
932datastream<Stream>&
operator<<( datastream<Stream>& ds,
const std::tuple<Args...>& t ) {
933 bluegrass::meta::for_each( t, [&](
const auto& i ) {
948template<
typename Stream,
typename... Args>
950 bluegrass::meta::for_each( t, [&](
auto& i ) {
967 bluegrass::meta::for_each_field(v, [&](
const auto& field) {
984 bluegrass::meta::for_each_field(v, [&](
auto& field) {
999template<typename Stream, typename T, std::enable_if_t<_datastream_detail::is_primitive<T>()>* =
nullptr>
1000datastream<Stream>&
operator<<( datastream<Stream>& ds,
const T& v ) {
1001 ds.write( (
const char*)&v,
sizeof(T) );
1014template<typename Stream, typename T, std::enable_if_t<_datastream_detail::is_primitive<T>()>* =
nullptr>
1016 ds.
read( (
char*)&v,
sizeof(T) );
1062 return unpack<T>( bytes.data(), bytes.size() );
1089std::vector<char>
pack(
const T& value ) {
1090 std::vector<char>
result;