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