Bitcoin ABC  0.26.3
P2P Digital Currency
univalue_write.cpp
Go to the documentation of this file.
1 // Copyright 2014 BitPay Inc.
2 // Distributed under the MIT software license, see the accompanying
3 // file COPYING or https://opensource.org/licenses/mit-license.php.
4 
5 #include <univalue.h>
6 #include <univalue_escapes.h>
7 
8 #include <cstddef>
9 #include <string>
10 #include <utility>
11 
12 namespace {
13 struct UniValueStreamWriter {
14  std::string str;
15 
16  UniValueStreamWriter() { str.reserve(1024); }
17 
18  std::string getString() {
19 #if __cplusplus >= 201103L
20  return std::move(str);
21 #else
22  std::string ret;
23  std::swap(ret, str);
24  return ret;
25 #endif
26  }
27 
28  void put(char c) { str.push_back(c); }
29  void put(char c, size_t nFill) { str.append(nFill, c); }
30  void write(const char *s) { str.append(s); }
31  void write(const std::string &s) { str.append(s); }
32 
33  void indentStr(unsigned int prettyIndent, unsigned int indentLevel) {
34  put(' ', prettyIndent * indentLevel);
35  }
36 
37  void escapeJson(const std::string &inS);
38  void writeAny(unsigned int prettyIndent, unsigned int indentLevel,
39  const UniValue &obj);
40  void writeArray(unsigned int prettyIndent, unsigned int indentLevel,
41  const UniValue &obj);
42  void writeObject(unsigned int prettyIndent, unsigned int indentLevel,
43  const UniValue &obj);
44 };
45 
46 void UniValueStreamWriter::escapeJson(const std::string &inS) {
47  size_t len = inS.length();
48  for (size_t i = 0; i < len; i++) {
49  const char ch = inS[i];
50  const char *const escStr = escapes[uint8_t(ch)];
51 
52  if (escStr) {
53  write(escStr);
54  } else {
55  put(ch);
56  }
57  }
58 }
59 
60 void UniValueStreamWriter::writeAny(unsigned int prettyIndent,
61  unsigned int indentLevel,
62  const UniValue &obj) {
63  unsigned int modIndent = indentLevel;
64  if (modIndent == 0) {
65  modIndent = 1;
66  }
67 
68  switch (obj.typ) {
69  case UniValue::VNULL:
70  write("null");
71  break;
72  case UniValue::VOBJ:
73  writeObject(prettyIndent, modIndent, obj);
74  break;
75  case UniValue::VARR:
76  writeArray(prettyIndent, modIndent, obj);
77  break;
78  case UniValue::VSTR:
79  put('"');
80  escapeJson(obj.val);
81  put('"');
82  break;
83  case UniValue::VNUM:
84  write(obj.val);
85  break;
86  case UniValue::VBOOL:
87  write(obj.val == "1" ? "true" : "false");
88  break;
89  }
90 }
91 
92 void UniValueStreamWriter::writeArray(unsigned int prettyIndent,
93  unsigned int indentLevel,
94  const UniValue &obj) {
95  put('[');
96  if (prettyIndent) {
97  put('\n');
98  }
99 
100  const size_t nValues = obj.values.size();
101  for (size_t i = 0; i < nValues; ++i) {
102  if (prettyIndent) {
103  indentStr(prettyIndent, indentLevel);
104  }
105  writeAny(prettyIndent, indentLevel + 1, obj.values[i]);
106  if (i != nValues - 1) {
107  put(',');
108  }
109  if (prettyIndent) {
110  put('\n');
111  }
112  }
113 
114  if (prettyIndent) {
115  indentStr(prettyIndent, indentLevel - 1);
116  }
117  put(']');
118 }
119 
120 void UniValueStreamWriter::writeObject(unsigned int prettyIndent,
121  unsigned int indentLevel,
122  const UniValue &obj) {
123  put('{');
124  if (prettyIndent) {
125  put('\n');
126  }
127 
128  // Note: if typ == VOBJ, then keys.size() == values.size() always, so we can
129  // use the non-bounds-checking operator[]() for both keys and values here
130  // safely.
131  const size_t nItems = obj.keys.size();
132  for (size_t i = 0; i < nItems; ++i) {
133  if (prettyIndent) {
134  indentStr(prettyIndent, indentLevel);
135  }
136  put('"');
137  escapeJson(obj.keys[i]);
138  write("\":");
139 
140  if (prettyIndent) {
141  put(' ');
142  }
143  writeAny(prettyIndent, indentLevel + 1, obj.values[i]);
144  if (i != nItems - 1) {
145  put(',');
146  }
147  if (prettyIndent) {
148  put('\n');
149  }
150  }
151 
152  if (prettyIndent) {
153  indentStr(prettyIndent, indentLevel - 1);
154  }
155  put('}');
156 }
157 } // namespace
158 
159 std::string UniValue::write(unsigned int prettyIndent,
160  unsigned int indentLevel) const {
161  UniValueStreamWriter ss;
162  ss.writeAny(prettyIndent, indentLevel, *this);
163  return ss.getString();
164 }
UniValue::VType typ
Definition: univalue.h:127
@ VNULL
Definition: univalue.h:30
@ VOBJ
Definition: univalue.h:31
@ VSTR
Definition: univalue.h:33
@ VARR
Definition: univalue.h:32
@ VNUM
Definition: univalue.h:34
@ VBOOL
Definition: univalue.h:35
std::string write(unsigned int prettyIndent=0, unsigned int indentLevel=0) const
std::vector< UniValue > values
Definition: univalue.h:130
std::vector< std::string > keys
Definition: univalue.h:129
std::string val
Definition: univalue.h:128
static const char * escapes[256]