/ 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 <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