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