univalue_write.cpp
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 <memory> 9 #include <string> 10 #include <vector> 11 12 static std::string json_escape(const std::string& inS) 13 { 14 std::string outS; 15 outS.reserve(inS.size() * 2); 16 17 for (unsigned int i = 0; i < inS.size(); i++) { 18 unsigned char ch = static_cast<unsigned char>(inS[i]); 19 const char *escStr = escapes[ch]; 20 21 if (escStr) 22 outS += escStr; 23 else 24 outS += static_cast<char>(ch); 25 } 26 27 return outS; 28 } 29 30 // NOLINTNEXTLINE(misc-no-recursion) 31 std::string UniValue::write(unsigned int prettyIndent, 32 unsigned int indentLevel) const 33 { 34 std::string s; 35 s.reserve(1024); 36 37 unsigned int modIndent = indentLevel; 38 if (modIndent == 0) 39 modIndent = 1; 40 41 switch (typ) { 42 case VNULL: 43 s += "null"; 44 break; 45 case VOBJ: 46 writeObject(prettyIndent, modIndent, s); 47 break; 48 case VARR: 49 writeArray(prettyIndent, modIndent, s); 50 break; 51 case VSTR: 52 s += "\"" + json_escape(val) + "\""; 53 break; 54 case VNUM: 55 s += val; 56 break; 57 case VBOOL: 58 s += (val == "1" ? "true" : "false"); 59 break; 60 } 61 62 return s; 63 } 64 65 static void indentStr(unsigned int prettyIndent, unsigned int indentLevel, std::string& s) 66 { 67 s.append(prettyIndent * indentLevel, ' '); 68 } 69 70 // NOLINTNEXTLINE(misc-no-recursion) 71 void UniValue::writeArray(unsigned int prettyIndent, unsigned int indentLevel, std::string& s) const 72 { 73 s += "["; 74 if (prettyIndent) 75 s += "\n"; 76 77 for (unsigned int i = 0; i < values.size(); i++) { 78 if (prettyIndent) 79 indentStr(prettyIndent, indentLevel, s); 80 s += values[i].write(prettyIndent, indentLevel + 1); 81 if (i != (values.size() - 1)) { 82 s += ","; 83 } 84 if (prettyIndent) 85 s += "\n"; 86 } 87 88 if (prettyIndent) 89 indentStr(prettyIndent, indentLevel - 1, s); 90 s += "]"; 91 } 92 93 // NOLINTNEXTLINE(misc-no-recursion) 94 void UniValue::writeObject(unsigned int prettyIndent, unsigned int indentLevel, std::string& s) const 95 { 96 s += "{"; 97 if (prettyIndent) 98 s += "\n"; 99 100 for (unsigned int i = 0; i < keys.size(); i++) { 101 if (prettyIndent) 102 indentStr(prettyIndent, indentLevel, s); 103 s += "\"" + json_escape(keys[i]) + "\":"; 104 if (prettyIndent) 105 s += " "; 106 s += values.at(i).write(prettyIndent, indentLevel + 1); 107 if (i != (values.size() - 1)) 108 s += ","; 109 if (prettyIndent) 110 s += "\n"; 111 } 112 113 if (prettyIndent) 114 indentStr(prettyIndent, indentLevel - 1, s); 115 s += "}"; 116 } 117