• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 #ifndef SRC_JSON_UTILS_H_
2 #define SRC_JSON_UTILS_H_
3 
4 #if defined(NODE_WANT_INTERNALS) && NODE_WANT_INTERNALS
5 
6 #include <iomanip>
7 #include <ostream>
8 #include <limits>
9 #include <string>
10 
11 namespace node {
12 
13 std::string EscapeJsonChars(const std::string& str);
14 std::string Reindent(const std::string& str, int indentation);
15 
16 // JSON compiler definitions.
17 class JSONWriter {
18  public:
JSONWriter(std::ostream & out,bool compact)19   JSONWriter(std::ostream& out, bool compact)
20     : out_(out), compact_(compact) {}
21 
22  private:
indent()23   inline void indent() { indent_ += 2; }
deindent()24   inline void deindent() { indent_ -= 2; }
advance()25   inline void advance() {
26     if (compact_) return;
27     for (int i = 0; i < indent_; i++) out_ << ' ';
28   }
write_one_space()29   inline void write_one_space() {
30     if (compact_) return;
31     out_ << ' ';
32   }
write_new_line()33   inline void write_new_line() {
34     if (compact_) return;
35     out_ << '\n';
36   }
37 
38  public:
json_start()39   inline void json_start() {
40     if (state_ == kAfterValue) out_ << ',';
41     write_new_line();
42     advance();
43     out_ << '{';
44     indent();
45     state_ = kObjectStart;
46   }
47 
json_end()48   inline void json_end() {
49     write_new_line();
50     deindent();
51     advance();
52     out_ << '}';
53     state_ = kAfterValue;
54   }
55   template <typename T>
json_objectstart(T key)56   inline void json_objectstart(T key) {
57     if (state_ == kAfterValue) out_ << ',';
58     write_new_line();
59     advance();
60     write_string(key);
61     out_ << ':';
62     write_one_space();
63     out_ << '{';
64     indent();
65     state_ = kObjectStart;
66   }
67 
68   template <typename T>
json_arraystart(T key)69   inline void json_arraystart(T key) {
70     if (state_ == kAfterValue) out_ << ',';
71     write_new_line();
72     advance();
73     write_string(key);
74     out_ << ':';
75     write_one_space();
76     out_ << '[';
77     indent();
78     state_ = kObjectStart;
79   }
json_objectend()80   inline void json_objectend() {
81     write_new_line();
82     deindent();
83     advance();
84     out_ << '}';
85     if (indent_ == 0) {
86       // Top-level object is complete, so end the line.
87       out_ << '\n';
88     }
89     state_ = kAfterValue;
90   }
91 
json_arrayend()92   inline void json_arrayend() {
93     write_new_line();
94     deindent();
95     advance();
96     out_ << ']';
97     state_ = kAfterValue;
98   }
99   template <typename T, typename U>
json_keyvalue(const T & key,const U & value)100   inline void json_keyvalue(const T& key, const U& value) {
101     if (state_ == kAfterValue) out_ << ',';
102     write_new_line();
103     advance();
104     write_string(key);
105     out_ << ':';
106     write_one_space();
107     write_value(value);
108     state_ = kAfterValue;
109   }
110 
111   template <typename U>
json_element(const U & value)112   inline void json_element(const U& value) {
113     if (state_ == kAfterValue) out_ << ',';
114     write_new_line();
115     advance();
116     write_value(value);
117     state_ = kAfterValue;
118   }
119 
120   struct Null {};  // Usable as a JSON value.
121 
122   struct ForeignJSON {
123     std::string as_string;
124   };
125 
126  private:
127   template <typename T,
128             typename test_for_number = typename std::
129                 enable_if<std::numeric_limits<T>::is_specialized, bool>::type>
write_value(T number)130   inline void write_value(T number) {
131     if (std::is_same<T, bool>::value)
132       out_ << (number ? "true" : "false");
133     else
134       out_ << number;
135   }
136 
write_value(Null null)137   inline void write_value(Null null) { out_ << "null"; }
write_value(const char * str)138   inline void write_value(const char* str) { write_string(str); }
write_value(const std::string & str)139   inline void write_value(const std::string& str) { write_string(str); }
140 
write_value(const ForeignJSON & json)141   inline void write_value(const ForeignJSON& json) {
142     out_ << Reindent(json.as_string, indent_);
143   }
144 
write_string(const std::string & str)145   inline void write_string(const std::string& str) {
146     out_ << '"' << EscapeJsonChars(str) << '"';
147   }
write_string(const char * str)148   inline void write_string(const char* str) { write_string(std::string(str)); }
149 
150   enum JSONState { kObjectStart, kAfterValue };
151   std::ostream& out_;
152   bool compact_;
153   int indent_ = 0;
154   int state_ = kObjectStart;
155 };
156 
157 }  // namespace node
158 
159 #endif  // defined(NODE_WANT_INTERNALS) && NODE_WANT_INTERNALS
160 
161 #endif  // SRC_JSON_UTILS_H_
162