mirror of
https://github.com/monero-project/monero.git
synced 2025-05-02 16:16:09 -04:00
moved all stuff to github
This commit is contained in:
parent
095fbeeb67
commit
296ae46ed8
388 changed files with 95937 additions and 469 deletions
169
src/serialization/binary_archive.h
Normal file
169
src/serialization/binary_archive.h
Normal file
|
@ -0,0 +1,169 @@
|
|||
// Copyright (c) 2012-2013 The Cryptonote developers
|
||||
// Distributed under the MIT/X11 software license, see the accompanying
|
||||
// file COPYING or http://www.opensource.org/licenses/mit-license.php.
|
||||
|
||||
/* binary_archive.h
|
||||
*
|
||||
* Portable (low-endian) binary archive */
|
||||
#pragma once
|
||||
|
||||
#include <cassert>
|
||||
#include <iostream>
|
||||
#include <iterator>
|
||||
#include <boost/type_traits/make_unsigned.hpp>
|
||||
|
||||
#include "common/varint.h"
|
||||
#include "warnings.h"
|
||||
|
||||
PUSH_WARNINGS
|
||||
DISABLE_VS_WARNINGS(4244)
|
||||
|
||||
//TODO: fix size_t warning in x32 platform
|
||||
|
||||
template <class Stream, bool IsSaving>
|
||||
struct binary_archive_base
|
||||
{
|
||||
typedef Stream stream_type;
|
||||
typedef binary_archive_base<Stream, IsSaving> base_type;
|
||||
typedef boost::mpl::bool_<IsSaving> is_saving;
|
||||
|
||||
typedef uint8_t variant_tag_type;
|
||||
|
||||
explicit binary_archive_base(stream_type &s) : stream_(s) { }
|
||||
|
||||
void tag(const char *) { }
|
||||
void begin_object() { }
|
||||
void end_object() { }
|
||||
void begin_variant() { }
|
||||
void end_variant() { }
|
||||
stream_type &stream() { return stream_; }
|
||||
protected:
|
||||
stream_type &stream_;
|
||||
};
|
||||
|
||||
template <bool W>
|
||||
struct binary_archive;
|
||||
|
||||
template <>
|
||||
struct binary_archive<false> : public binary_archive_base<std::istream, false>
|
||||
{
|
||||
explicit binary_archive(stream_type &s) : base_type(s) {
|
||||
stream_type::streampos pos = stream_.tellg();
|
||||
stream_.seekg(0, std::ios_base::end);
|
||||
eof_pos_ = stream_.tellg();
|
||||
stream_.seekg(pos);
|
||||
}
|
||||
|
||||
template <class T>
|
||||
void serialize_int(T &v)
|
||||
{
|
||||
serialize_uint(*(typename boost::make_unsigned<T>::type *)&v);
|
||||
}
|
||||
|
||||
template <class T>
|
||||
void serialize_uint(T &v, size_t width = sizeof(T))
|
||||
{
|
||||
T ret = 0;
|
||||
unsigned shift = 0;
|
||||
for (size_t i = 0; i < width; i++) {
|
||||
//std::cerr << "tell: " << stream_.tellg() << " value: " << ret << std::endl;
|
||||
char c;
|
||||
stream_.get(c);
|
||||
T b = (unsigned char)c;
|
||||
ret += (b << shift);
|
||||
shift += 8;
|
||||
}
|
||||
v = ret;
|
||||
}
|
||||
void serialize_blob(void *buf, size_t len, const char *delimiter="") { stream_.read((char *)buf, len); }
|
||||
|
||||
template <class T>
|
||||
void serialize_varint(T &v)
|
||||
{
|
||||
serialize_uvarint(*(typename boost::make_unsigned<T>::type *)(&v));
|
||||
}
|
||||
|
||||
template <class T>
|
||||
void serialize_uvarint(T &v)
|
||||
{
|
||||
typedef std::istreambuf_iterator<char> it;
|
||||
tools::read_varint(it(stream_), it(), v); // XXX handle failure
|
||||
}
|
||||
void begin_array(size_t &s)
|
||||
{
|
||||
serialize_varint(s);
|
||||
}
|
||||
void begin_array() { }
|
||||
|
||||
void delimit_array() { }
|
||||
void end_array() { }
|
||||
|
||||
void begin_string(const char *delimiter="\"") { }
|
||||
void end_string(const char *delimiter="\"") { }
|
||||
|
||||
void read_variant_tag(variant_tag_type &t) {
|
||||
serialize_int(t);
|
||||
}
|
||||
|
||||
size_t remaining_bytes() {
|
||||
if (!stream_.good())
|
||||
return 0;
|
||||
//std::cerr << "tell: " << stream_.tellg() << std::endl;
|
||||
assert(stream_.tellg() <= eof_pos_);
|
||||
return eof_pos_ - stream_.tellg();
|
||||
}
|
||||
protected:
|
||||
std::streamoff eof_pos_;
|
||||
};
|
||||
|
||||
template <>
|
||||
struct binary_archive<true> : public binary_archive_base<std::ostream, true>
|
||||
{
|
||||
explicit binary_archive(stream_type &s) : base_type(s) { }
|
||||
|
||||
template <class T>
|
||||
void serialize_int(T v)
|
||||
{
|
||||
serialize_uint(static_cast<typename boost::make_unsigned<T>::type>(v));
|
||||
}
|
||||
template <class T>
|
||||
void serialize_uint(T v)
|
||||
{
|
||||
for (size_t i = 0; i < sizeof(T); i++) {
|
||||
stream_.put((char)(v & 0xff));
|
||||
if (1 < sizeof(T)) {
|
||||
v >>= 8;
|
||||
}
|
||||
}
|
||||
}
|
||||
void serialize_blob(void *buf, size_t len, const char *delimiter="") { stream_.write((char *)buf, len); }
|
||||
|
||||
template <class T>
|
||||
void serialize_varint(T &v)
|
||||
{
|
||||
serialize_uvarint(*(typename boost::make_unsigned<T>::type *)(&v));
|
||||
}
|
||||
|
||||
template <class T>
|
||||
void serialize_uvarint(T &v)
|
||||
{
|
||||
typedef std::ostreambuf_iterator<char> it;
|
||||
tools::write_varint(it(stream_), v);
|
||||
}
|
||||
void begin_array(size_t s)
|
||||
{
|
||||
serialize_varint(s);
|
||||
}
|
||||
void begin_array() { }
|
||||
void delimit_array() { }
|
||||
void end_array() { }
|
||||
|
||||
void begin_string(const char *delimiter="\"") { }
|
||||
void end_string(const char *delimiter="\"") { }
|
||||
|
||||
void write_variant_tag(variant_tag_type t) {
|
||||
serialize_int(t);
|
||||
}
|
||||
};
|
||||
|
||||
POP_WARNINGS
|
28
src/serialization/binary_utils.h
Normal file
28
src/serialization/binary_utils.h
Normal file
|
@ -0,0 +1,28 @@
|
|||
// Copyright (c) 2012-2013 The Cryptonote developers
|
||||
// Distributed under the MIT/X11 software license, see the accompanying
|
||||
// file COPYING or http://www.opensource.org/licenses/mit-license.php.
|
||||
|
||||
#include <sstream>
|
||||
#include "binary_archive.h"
|
||||
|
||||
namespace serialization {
|
||||
|
||||
template <class T>
|
||||
bool parse_binary(const std::string &blob, T &v)
|
||||
{
|
||||
std::istringstream istr(blob);
|
||||
binary_archive<false> iar(istr);
|
||||
return ::serialization::serialize(iar, v);
|
||||
}
|
||||
|
||||
template<class T>
|
||||
bool dump_binary(T& v, std::string& blob)
|
||||
{
|
||||
std::stringstream ostr;
|
||||
binary_archive<true> oar(ostr);
|
||||
bool success = ::serialization::serialize(oar, v);
|
||||
blob = ostr.str();
|
||||
return success && ostr.good();
|
||||
};
|
||||
|
||||
} // namespace serialization
|
62
src/serialization/crypto.h
Normal file
62
src/serialization/crypto.h
Normal file
|
@ -0,0 +1,62 @@
|
|||
// Copyright (c) 2012-2013 The Cryptonote developers
|
||||
// Distributed under the MIT/X11 software license, see the accompanying
|
||||
// file COPYING or http://www.opensource.org/licenses/mit-license.php.
|
||||
|
||||
#include "serialization.h"
|
||||
#include "debug_archive.h"
|
||||
#include "crypto/chacha8.h"
|
||||
#include "crypto/crypto.h"
|
||||
#include "crypto/hash.h"
|
||||
|
||||
// read
|
||||
template <template <bool> class Archive>
|
||||
bool do_serialize(Archive<false> &ar, std::vector<crypto::signature> &v)
|
||||
{
|
||||
size_t cnt = v.size();
|
||||
v.clear();
|
||||
|
||||
// very basic sanity check
|
||||
if (ar.remaining_bytes() < cnt*sizeof(crypto::signature)) {
|
||||
ar.stream().setstate(std::ios::failbit);
|
||||
return false;
|
||||
}
|
||||
|
||||
v.reserve(cnt);
|
||||
for (size_t i = 0; i < cnt; i++) {
|
||||
v.resize(i+1);
|
||||
ar.serialize_blob(&(v[i]), sizeof(crypto::signature), "");
|
||||
if (!ar.stream().good())
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
// write
|
||||
template <template <bool> class Archive>
|
||||
bool do_serialize(Archive<true> &ar, std::vector<crypto::signature> &v)
|
||||
{
|
||||
if (0 == v.size()) return true;
|
||||
ar.begin_string();
|
||||
size_t cnt = v.size();
|
||||
for (size_t i = 0; i < cnt; i++) {
|
||||
ar.serialize_blob(&(v[i]), sizeof(crypto::signature), "");
|
||||
if (!ar.stream().good())
|
||||
return false;
|
||||
}
|
||||
ar.end_string();
|
||||
return true;
|
||||
}
|
||||
|
||||
BLOB_SERIALIZER(crypto::chacha8_iv);
|
||||
BLOB_SERIALIZER(crypto::hash);
|
||||
BLOB_SERIALIZER(crypto::public_key);
|
||||
BLOB_SERIALIZER(crypto::secret_key);
|
||||
BLOB_SERIALIZER(crypto::key_derivation);
|
||||
BLOB_SERIALIZER(crypto::key_image);
|
||||
BLOB_SERIALIZER(crypto::signature);
|
||||
VARIANT_TAG(debug_archive, crypto::hash, "hash");
|
||||
VARIANT_TAG(debug_archive, crypto::public_key, "public_key");
|
||||
VARIANT_TAG(debug_archive, crypto::secret_key, "secret_key");
|
||||
VARIANT_TAG(debug_archive, crypto::key_derivation, "key_derivation");
|
||||
VARIANT_TAG(debug_archive, crypto::key_image, "key_image");
|
||||
VARIANT_TAG(debug_archive, crypto::signature, "signature");
|
28
src/serialization/debug_archive.h
Normal file
28
src/serialization/debug_archive.h
Normal file
|
@ -0,0 +1,28 @@
|
|||
// Copyright (c) 2012-2013 The Cryptonote developers
|
||||
// Distributed under the MIT/X11 software license, see the accompanying
|
||||
// file COPYING or http://www.opensource.org/licenses/mit-license.php.
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "json_archive.h"
|
||||
#include "variant.h"
|
||||
|
||||
template <bool W>
|
||||
struct debug_archive : public json_archive<W> {
|
||||
typedef typename json_archive<W>::stream_type stream_type;
|
||||
|
||||
debug_archive(stream_type &s) : json_archive<W>(s) { }
|
||||
};
|
||||
|
||||
template <class T>
|
||||
struct serializer<debug_archive<true>, T>
|
||||
{
|
||||
static void serialize(debug_archive<true> &ar, T &v)
|
||||
{
|
||||
ar.begin_object();
|
||||
ar.tag(variant_serialization_traits<debug_archive<true>, T>::get_tag());
|
||||
serializer<json_archive<true>, T>::serialize(ar, v);
|
||||
ar.end_object();
|
||||
ar.stream() << std::endl;
|
||||
}
|
||||
};
|
145
src/serialization/json_archive.h
Normal file
145
src/serialization/json_archive.h
Normal file
|
@ -0,0 +1,145 @@
|
|||
// Copyright (c) 2012-2013 The Cryptonote developers
|
||||
// Distributed under the MIT/X11 software license, see the accompanying
|
||||
// file COPYING or http://www.opensource.org/licenses/mit-license.php.
|
||||
|
||||
/* json_archive.h
|
||||
*
|
||||
* JSON archive */
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "serialization.h"
|
||||
#include <cassert>
|
||||
#include <iostream>
|
||||
#include <iomanip>
|
||||
|
||||
template <class Stream, bool IsSaving>
|
||||
struct json_archive_base
|
||||
{
|
||||
typedef Stream stream_type;
|
||||
typedef json_archive_base<Stream, IsSaving> base_type;
|
||||
typedef boost::mpl::bool_<IsSaving> is_saving;
|
||||
|
||||
typedef const char *variant_tag_type;
|
||||
|
||||
json_archive_base(stream_type &s, bool indent = false) : stream_(s), indent_(indent), object_begin(false), depth_(0) { }
|
||||
|
||||
void tag(const char *tag) {
|
||||
if (!object_begin)
|
||||
stream_ << ", ";
|
||||
make_indent();
|
||||
stream_ << '"' << tag << "\": ";
|
||||
object_begin = false;
|
||||
}
|
||||
|
||||
void begin_object()
|
||||
{
|
||||
stream_ << "{";
|
||||
++depth_;
|
||||
object_begin = true;
|
||||
}
|
||||
|
||||
void end_object()
|
||||
{
|
||||
--depth_;
|
||||
make_indent();
|
||||
stream_ << "}";
|
||||
}
|
||||
|
||||
void begin_variant() { begin_object(); }
|
||||
void end_variant() { end_object(); }
|
||||
Stream &stream() { return stream_; }
|
||||
|
||||
protected:
|
||||
void make_indent()
|
||||
{
|
||||
if (indent_)
|
||||
{
|
||||
stream_ << '\n' << std::string(2 * depth_, ' ');
|
||||
}
|
||||
}
|
||||
|
||||
protected:
|
||||
stream_type &stream_;
|
||||
bool indent_;
|
||||
bool object_begin;
|
||||
size_t depth_;
|
||||
};
|
||||
|
||||
template <bool W>
|
||||
struct json_archive;
|
||||
|
||||
template <>
|
||||
struct json_archive<true> : public json_archive_base<std::ostream, true>
|
||||
{
|
||||
json_archive(stream_type &s, bool indent = false) : base_type(s, indent) { }
|
||||
|
||||
template<typename T>
|
||||
static auto promote_to_printable_integer_type(T v) -> decltype(+v)
|
||||
{
|
||||
// Unary operator '+' performs integral promotion on type T [expr.unary.op].
|
||||
// If T is signed or unsigned char, it's promoted to int and printed as number.
|
||||
return +v;
|
||||
}
|
||||
|
||||
template <class T>
|
||||
void serialize_int(T v)
|
||||
{
|
||||
stream_ << std::dec << promote_to_printable_integer_type(v);
|
||||
}
|
||||
|
||||
void serialize_blob(void *buf, size_t len, const char *delimiter="\"") {
|
||||
begin_string(delimiter);
|
||||
for (size_t i = 0; i < len; i++) {
|
||||
unsigned char c = ((unsigned char *)buf)[i];
|
||||
stream_ << std::hex << std::setw(2) << std::setfill('0') << (int)c;
|
||||
}
|
||||
end_string(delimiter);
|
||||
}
|
||||
|
||||
template <class T>
|
||||
void serialize_varint(T &v)
|
||||
{
|
||||
stream_ << std::dec << promote_to_printable_integer_type(v);
|
||||
}
|
||||
|
||||
void begin_string(const char *delimiter="\"")
|
||||
{
|
||||
stream_ << delimiter;
|
||||
}
|
||||
|
||||
void end_string(const char *delimiter="\"")
|
||||
{
|
||||
stream_ << delimiter;
|
||||
}
|
||||
|
||||
void begin_array(size_t s=0)
|
||||
{
|
||||
inner_array_size_ = s;
|
||||
++depth_;
|
||||
stream_ << "[ ";
|
||||
}
|
||||
|
||||
void delimit_array()
|
||||
{
|
||||
stream_ << ", ";
|
||||
}
|
||||
|
||||
void end_array()
|
||||
{
|
||||
--depth_;
|
||||
if (0 < inner_array_size_)
|
||||
{
|
||||
make_indent();
|
||||
}
|
||||
stream_ << "]";
|
||||
}
|
||||
|
||||
void write_variant_tag(const char *t)
|
||||
{
|
||||
tag(t);
|
||||
}
|
||||
|
||||
private:
|
||||
size_t inner_array_size_;
|
||||
};
|
19
src/serialization/json_utils.h
Normal file
19
src/serialization/json_utils.h
Normal file
|
@ -0,0 +1,19 @@
|
|||
// Copyright (c) 2012-2013 The Cryptonote developers
|
||||
// Distributed under the MIT/X11 software license, see the accompanying
|
||||
// file COPYING or http://www.opensource.org/licenses/mit-license.php.
|
||||
|
||||
#include <sstream>
|
||||
#include "json_archive.h"
|
||||
|
||||
namespace serialization {
|
||||
|
||||
template<class T>
|
||||
std::string dump_json(T &v)
|
||||
{
|
||||
std::stringstream ostr;
|
||||
json_archive<true> oar(ostr);
|
||||
assert(serialization::serialize(oar, v));
|
||||
return ostr.str();
|
||||
};
|
||||
|
||||
} // namespace serialization
|
146
src/serialization/serialization.h
Normal file
146
src/serialization/serialization.h
Normal file
|
@ -0,0 +1,146 @@
|
|||
// Copyright (c) 2012-2013 The Cryptonote developers
|
||||
// Distributed under the MIT/X11 software license, see the accompanying
|
||||
// file COPYING or http://www.opensource.org/licenses/mit-license.php.
|
||||
|
||||
/* serialization.h
|
||||
*
|
||||
* Simple templated serialization API */
|
||||
|
||||
#pragma once
|
||||
#include <vector>
|
||||
#include <string>
|
||||
#include <boost/type_traits/is_integral.hpp>
|
||||
|
||||
template <class T>
|
||||
struct is_blob_type { typedef boost::false_type type; };
|
||||
template <class T>
|
||||
struct has_free_serializer { typedef boost::true_type type; };
|
||||
|
||||
template <class Archive, class T>
|
||||
struct serializer
|
||||
{
|
||||
static bool serialize(Archive &ar, T &v) {
|
||||
return serialize(ar, v, typename boost::is_integral<T>::type(), typename is_blob_type<T>::type());
|
||||
}
|
||||
static bool serialize(Archive &ar, T &v, boost::false_type, boost::true_type) {
|
||||
ar.serialize_blob(&v, sizeof(v));
|
||||
return true;
|
||||
}
|
||||
static bool serialize(Archive &ar, T &v, boost::true_type, boost::false_type) {
|
||||
ar.serialize_int(v);
|
||||
return true;
|
||||
}
|
||||
static bool serialize(Archive &ar, T &v, boost::false_type, boost::false_type) {
|
||||
//serialize_custom(ar, v, typename has_free_serializer<T>::type());
|
||||
return v.do_serialize(ar);
|
||||
}
|
||||
static void serialize_custom(Archive &ar, T &v, boost::true_type) {
|
||||
}
|
||||
};
|
||||
|
||||
template <class Archive, class T>
|
||||
inline bool do_serialize(Archive &ar, T &v)
|
||||
{
|
||||
return ::serializer<Archive, T>::serialize(ar, v);
|
||||
}
|
||||
|
||||
#ifndef __GNUC__
|
||||
#ifndef constexpr
|
||||
#define constexpr
|
||||
#endif
|
||||
#endif
|
||||
|
||||
#define BLOB_SERIALIZER(T) \
|
||||
template<> struct is_blob_type<T> { typedef boost::true_type type; }
|
||||
#define FREE_SERIALIZER(T) \
|
||||
template<> struct has_free_serializer<T> { typedef boost::true_type type; }
|
||||
#define VARIANT_TAG(A, T, Tg) \
|
||||
template <bool W> struct variant_serialization_traits<A<W>, T> { static inline typename A<W>::variant_tag_type get_tag() { return Tg; } }
|
||||
#define BEGIN_SERIALIZE() \
|
||||
template <bool W, template <bool> class Archive> bool do_serialize(Archive<W> &ar) {
|
||||
#define BEGIN_SERIALIZE_OBJECT() \
|
||||
template <bool W, template <bool> class Archive> bool do_serialize(Archive<W> &ar) { ar.begin_object(); bool r = do_serialize_object(ar); ar.end_object(); return r; } \
|
||||
template <bool W, template <bool> class Archive> bool do_serialize_object(Archive<W> &ar){
|
||||
#define PREPARE_CUSTOM_VECTOR_SERIALIZATION(size, vec) ::serialization::detail::prepare_custom_vector_serialization(size, vec, typename Archive<W>::is_saving())
|
||||
|
||||
#define END_SERIALIZE() return true;}
|
||||
|
||||
|
||||
#define VALUE(f) \
|
||||
do { \
|
||||
ar.tag(#f); \
|
||||
bool r = ::do_serialize(ar, f); \
|
||||
if (!r || !ar.stream().good()) return false; \
|
||||
} while(0);
|
||||
#define FIELD_N(t, f) \
|
||||
do { \
|
||||
ar.tag(t); \
|
||||
bool r = ::do_serialize(ar, f); \
|
||||
if (!r || !ar.stream().good()) return false; \
|
||||
} while(0);
|
||||
#define FIELDS(f) \
|
||||
bool r = ::do_serialize(ar, f); \
|
||||
if (!r || !ar.stream().good()) return false;
|
||||
#define FIELD(f) \
|
||||
do { \
|
||||
ar.tag(#f); \
|
||||
bool r = ::do_serialize(ar, f); \
|
||||
if (!r || !ar.stream().good()) return false; \
|
||||
} while(0);
|
||||
#define VARINT_FIELD(f) \
|
||||
do { \
|
||||
ar.tag(#f); \
|
||||
ar.serialize_varint(f); \
|
||||
if (!ar.stream().good()) return false; \
|
||||
} while(0);
|
||||
|
||||
namespace serialization {
|
||||
namespace detail
|
||||
{
|
||||
template <typename T>
|
||||
void prepare_custom_vector_serialization(size_t size, std::vector<T>& vec, const boost::mpl::bool_<true>& /*is_saving*/)
|
||||
{
|
||||
}
|
||||
|
||||
template <typename T>
|
||||
void prepare_custom_vector_serialization(size_t size, std::vector<T>& vec, const boost::mpl::bool_<false>& /*is_saving*/)
|
||||
{
|
||||
vec.resize(size);
|
||||
}
|
||||
|
||||
template<class Stream>
|
||||
bool do_check_stream_state(Stream& s, boost::mpl::bool_<true>)
|
||||
{
|
||||
return s.good();
|
||||
}
|
||||
|
||||
template<class Stream>
|
||||
bool do_check_stream_state(Stream& s, boost::mpl::bool_<false>)
|
||||
{
|
||||
bool result = false;
|
||||
if (s.good())
|
||||
{
|
||||
std::ios_base::iostate state = s.rdstate();
|
||||
result = EOF == s.peek();
|
||||
s.setstate(state);
|
||||
}
|
||||
return result;
|
||||
}
|
||||
}
|
||||
|
||||
template<class Archive>
|
||||
bool check_stream_state(Archive& ar)
|
||||
{
|
||||
return detail::do_check_stream_state(ar.stream(), typename Archive::is_saving());
|
||||
}
|
||||
|
||||
template <class Archive, class T>
|
||||
inline bool serialize(Archive &ar, T &v)
|
||||
{
|
||||
bool r = do_serialize(ar, v);
|
||||
return r && check_stream_state(ar);
|
||||
}
|
||||
}
|
||||
|
||||
#include "string.h"
|
||||
#include "vector.h"
|
35
src/serialization/string.h
Normal file
35
src/serialization/string.h
Normal file
|
@ -0,0 +1,35 @@
|
|||
// Copyright (c) 2012-2013 The Cryptonote developers
|
||||
// Distributed under the MIT/X11 software license, see the accompanying
|
||||
// file COPYING or http://www.opensource.org/licenses/mit-license.php.
|
||||
|
||||
#pragma once
|
||||
#include <memory>
|
||||
#include "serialization.h"
|
||||
|
||||
template <template <bool> class Archive>
|
||||
inline bool do_serialize(Archive<false>& ar, std::string& str)
|
||||
{
|
||||
size_t size = 0;
|
||||
ar.serialize_varint(size);
|
||||
if (ar.remaining_bytes() < size)
|
||||
{
|
||||
ar.stream().setstate(std::ios::failbit);
|
||||
return false;
|
||||
}
|
||||
|
||||
std::unique_ptr<std::string::value_type[]> buf(new std::string::value_type[size]);
|
||||
ar.serialize_blob(buf.get(), size);
|
||||
str.erase();
|
||||
str.append(buf.get(), size);
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
template <template <bool> class Archive>
|
||||
inline bool do_serialize(Archive<true>& ar, std::string& str)
|
||||
{
|
||||
size_t size = str.size();
|
||||
ar.serialize_varint(size);
|
||||
ar.serialize_blob(const_cast<std::string::value_type*>(str.c_str()), size);
|
||||
return true;
|
||||
}
|
110
src/serialization/variant.h
Normal file
110
src/serialization/variant.h
Normal file
|
@ -0,0 +1,110 @@
|
|||
// Copyright (c) 2012-2013 The Cryptonote developers
|
||||
// Distributed under the MIT/X11 software license, see the accompanying
|
||||
// file COPYING or http://www.opensource.org/licenses/mit-license.php.
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <boost/variant/variant.hpp>
|
||||
#include <boost/variant/apply_visitor.hpp>
|
||||
#include <boost/variant/static_visitor.hpp>
|
||||
#include <boost/mpl/empty.hpp>
|
||||
#include <boost/mpl/if.hpp>
|
||||
#include <boost/mpl/front.hpp>
|
||||
#include <boost/mpl/pop_front.hpp>
|
||||
#include "serialization.h"
|
||||
|
||||
template <class Archive, class T>
|
||||
struct variant_serialization_traits
|
||||
{
|
||||
};
|
||||
|
||||
template <class Archive, class Variant, class TBegin, class TEnd>
|
||||
struct variant_reader
|
||||
{
|
||||
typedef typename Archive::variant_tag_type variant_tag_type;
|
||||
typedef typename boost::mpl::next<TBegin>::type TNext;
|
||||
typedef typename boost::mpl::deref<TBegin>::type current_type;
|
||||
|
||||
static inline bool read(Archive &ar, Variant &v, variant_tag_type t)
|
||||
{
|
||||
if (variant_serialization_traits<Archive, current_type>::get_tag() == t) {
|
||||
current_type x;
|
||||
if(!::do_serialize(ar, x))
|
||||
{
|
||||
ar.stream().setstate(std::ios::failbit);
|
||||
return false;
|
||||
}
|
||||
v = x;
|
||||
} else {
|
||||
return variant_reader<Archive, Variant, TNext, TEnd>::read(ar, v, t);
|
||||
}
|
||||
return true;
|
||||
}
|
||||
};
|
||||
|
||||
template <class Archive, class Variant, class TBegin>
|
||||
struct variant_reader<Archive, Variant, TBegin, TBegin>
|
||||
{
|
||||
typedef typename Archive::variant_tag_type variant_tag_type;
|
||||
|
||||
static inline bool read(Archive &ar, Variant &v, variant_tag_type t)
|
||||
{
|
||||
ar.stream().setstate(std::ios::failbit);
|
||||
return false;
|
||||
}
|
||||
|
||||
};
|
||||
|
||||
|
||||
template <template <bool> class Archive, BOOST_VARIANT_ENUM_PARAMS(typename T)>
|
||||
struct serializer<Archive<false>, boost::variant<BOOST_VARIANT_ENUM_PARAMS(T)>>
|
||||
{
|
||||
typedef boost::variant<BOOST_VARIANT_ENUM_PARAMS(T)> variant_type;
|
||||
typedef typename Archive<false>::variant_tag_type variant_tag_type;
|
||||
typedef typename variant_type::types types;
|
||||
|
||||
static bool serialize(Archive<false> &ar, variant_type &v) {
|
||||
variant_tag_type t;
|
||||
ar.begin_variant();
|
||||
ar.read_variant_tag(t);
|
||||
if(!variant_reader<Archive<false>, variant_type, typename boost::mpl::begin<types>::type, typename boost::mpl::end<types>::type>::read(ar, v, t))
|
||||
{
|
||||
ar.stream().setstate(std::ios::failbit);
|
||||
return false;
|
||||
}
|
||||
ar.end_variant();
|
||||
return true;
|
||||
}
|
||||
};
|
||||
|
||||
template <template <bool> class Archive, BOOST_VARIANT_ENUM_PARAMS(typename T)>
|
||||
struct serializer<Archive<true>, boost::variant<BOOST_VARIANT_ENUM_PARAMS(T)>>
|
||||
{
|
||||
typedef boost::variant<BOOST_VARIANT_ENUM_PARAMS(T)> variant_type;
|
||||
//typedef typename Archive<true>::variant_tag_type variant_tag_type;
|
||||
|
||||
struct visitor : public boost::static_visitor<bool>
|
||||
{
|
||||
Archive<true> &ar;
|
||||
|
||||
visitor(Archive<true> &a) : ar(a) { }
|
||||
|
||||
template <class T>
|
||||
bool operator ()(T &rv) const
|
||||
{
|
||||
ar.begin_variant();
|
||||
ar.write_variant_tag(variant_serialization_traits<Archive<true>, T>::get_tag());
|
||||
if(!::do_serialize(ar, rv))
|
||||
{
|
||||
ar.stream().setstate(std::ios::failbit);
|
||||
return false;
|
||||
}
|
||||
ar.end_variant();
|
||||
return true;
|
||||
}
|
||||
};
|
||||
|
||||
static bool serialize(Archive<true> &ar, variant_type &v) {
|
||||
return boost::apply_visitor(visitor(ar), v);
|
||||
}
|
||||
};
|
74
src/serialization/vector.h
Normal file
74
src/serialization/vector.h
Normal file
|
@ -0,0 +1,74 @@
|
|||
// Copyright (c) 2012-2013 The Cryptonote developers
|
||||
// Distributed under the MIT/X11 software license, see the accompanying
|
||||
// file COPYING or http://www.opensource.org/licenses/mit-license.php.
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "serialization.h"
|
||||
|
||||
namespace serialization
|
||||
{
|
||||
namespace detail
|
||||
{
|
||||
template <typename Archive, class T>
|
||||
bool serialize_vector_element(Archive& ar, T& e)
|
||||
{
|
||||
return ::do_serialize(ar, e);
|
||||
}
|
||||
|
||||
template <typename Archive>
|
||||
bool serialize_vector_element(Archive& ar, uint64_t& e)
|
||||
{
|
||||
ar.serialize_varint(e);
|
||||
return true;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
template <template <bool> class Archive, class T>
|
||||
bool do_serialize(Archive<false> &ar, std::vector<T> &v)
|
||||
{
|
||||
size_t cnt;
|
||||
ar.begin_array(cnt);
|
||||
if (!ar.stream().good())
|
||||
return false;
|
||||
v.clear();
|
||||
|
||||
// very basic sanity check
|
||||
if (ar.remaining_bytes() < cnt) {
|
||||
ar.stream().setstate(std::ios::failbit);
|
||||
return false;
|
||||
}
|
||||
|
||||
v.reserve(cnt);
|
||||
for (size_t i = 0; i < cnt; i++) {
|
||||
if (i > 0)
|
||||
ar.delimit_array();
|
||||
v.resize(i+1);
|
||||
if (!::serialization::detail::serialize_vector_element(ar, v[i]))
|
||||
return false;
|
||||
if (!ar.stream().good())
|
||||
return false;
|
||||
}
|
||||
ar.end_array();
|
||||
return true;
|
||||
}
|
||||
|
||||
template <template <bool> class Archive, class T>
|
||||
bool do_serialize(Archive<true> &ar, std::vector<T> &v)
|
||||
{
|
||||
size_t cnt = v.size();
|
||||
ar.begin_array(cnt);
|
||||
for (size_t i = 0; i < cnt; i++) {
|
||||
if (!ar.stream().good())
|
||||
return false;
|
||||
if (i > 0)
|
||||
ar.delimit_array();
|
||||
if(!::serialization::detail::serialize_vector_element(ar, v[i]))
|
||||
return false;
|
||||
if (!ar.stream().good())
|
||||
return false;
|
||||
}
|
||||
ar.end_array();
|
||||
return true;
|
||||
}
|
Loading…
Add table
Add a link
Reference in a new issue