1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
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_;
};
|