Bitcoin ABC  0.22.12
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 <string>
6 #include <sstream>
7 #include <stdint.h>
8 #include <stdio.h>
9 #include "univalue.h"
10 #include "univalue_escapes.h"
11 
12 namespace {
13 struct UniValueStreamWriter {
14  std::string str;
15 
16  UniValueStreamWriter() {
17  str.reserve(1024);
18  }
19 
20  std::string getString() {
21 #if __cplusplus >= 201103L
22  return std::move(str);
23 #else
24  std::string ret;
25  std::swap(ret, str);
26  return ret;
27 #endif
28  }
29 
30  void put(char c) {
31  str.push_back(c);
32  }
33  void put(char c, size_t nFill) {
34  str.append(nFill, c);
35  }
36  void write(const char *s) {
37  str.append(s);
38  }
39  void write(const std::string &s) {
40  str.append(s);
41  }
42 
43  void indentStr(unsigned int prettyIndent, unsigned int indentLevel) {
44  put(' ', prettyIndent * indentLevel);
45  }
46 
47  void escapeJson(const std::string &inS);
48  void writeAny(unsigned int prettyIndent, unsigned int indentLevel, const UniValue &obj);
49  void writeArray(unsigned int prettyIndent, unsigned int indentLevel, const UniValue &obj);
50  void writeObject(unsigned int prettyIndent, unsigned int indentLevel, const UniValue &obj);
51 };
52 
53 void UniValueStreamWriter::escapeJson(const std::string &inS) {
54  size_t len = inS.length();
55  for (size_t i = 0; i < len; i++) {
56  const char ch = inS[i];
57  const char * const escStr = escapes[uint8_t(ch)];
58 
59  if (escStr) {
60  write(escStr);
61  } else {
62  put(ch);
63  }
64  }
65 }
66 
67 void UniValueStreamWriter::writeAny(unsigned int prettyIndent, unsigned int indentLevel, const UniValue &obj) {
68  unsigned int modIndent = indentLevel;
69  if (modIndent == 0) {
70  modIndent = 1;
71  }
72 
73  switch (obj.typ) {
74  case UniValue::VNULL:
75  write("null");
76  break;
77  case UniValue::VOBJ:
78  writeObject(prettyIndent, modIndent, obj);
79  break;
80  case UniValue::VARR:
81  writeArray(prettyIndent, modIndent, obj);
82  break;
83  case UniValue::VSTR:
84  put('"');
85  escapeJson(obj.val);
86  put('"');
87  break;
88  case UniValue::VNUM:
89  write(obj.val);
90  break;
91  case UniValue::VBOOL:
92  write(obj.val == "1" ? "true" : "false");
93  break;
94  }
95 }
96 
97 void UniValueStreamWriter::writeArray(unsigned int prettyIndent, unsigned int indentLevel, const UniValue &obj) {
98  put('[');
99  if (prettyIndent) {
100  put('\n');
101  }
102 
103  const size_t nValues = obj.values.size();
104  for (size_t i = 0; i < nValues; ++i) {
105  if (prettyIndent) {
106  indentStr(prettyIndent, indentLevel);
107  }
108  writeAny(prettyIndent, indentLevel + 1, obj.values[i]);
109  if (i != nValues - 1) {
110  put(',');
111  }
112  if (prettyIndent) {
113  put('\n');
114  }
115  }
116 
117  if (prettyIndent) {
118  indentStr(prettyIndent, indentLevel - 1);
119  }
120  put(']');
121 }
122 
123 void UniValueStreamWriter::writeObject(unsigned int prettyIndent, unsigned int indentLevel, const UniValue &obj) {
124  put('{');
125  if (prettyIndent) {
126  put('\n');
127  }
128 
129  // Note: if typ == VOBJ, then keys.size() == values.size() always, so we can
130  // use the non-bounds-checking operator[]() for both keys and values here 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 }
158 
159 std::string UniValue::write(unsigned int prettyIndent, unsigned int indentLevel) const {
160  UniValueStreamWriter ss;
161  ss.writeAny(prettyIndent, indentLevel, *this);
162  return ss.getString();
163 }
static std::string escapes[256]
Definition: gen.cpp:16
std::vector< UniValue > values
Definition: univalue.h:118
std::string write(unsigned int prettyIndent=0, unsigned int indentLevel=0) const
std::string val
Definition: univalue.h:116
UniValue::VType typ
Definition: univalue.h:115
std::vector< std::string > keys
Definition: univalue.h:117