/ src / univalue / lib / univalue_write.cpp
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