GeezerVison is showing github.com — src: move JSONWriter into its own file · nodejs/node@f284d59
File treeExpand file treeCollapse file tree Open diff view settings Expand file treeCollapse file tree Open diff view settings Collapse file Copy file name to clipboardExpand all lines: node.gyp +3-1Lines changed: 3 additions & 1 deletion | Original file line number | Diff line number | Diff line change |
|---|
| 560 | 560 | 'src/js_native_api_v8.h', | 561 | 561 | 'src/js_native_api_v8_internals.h', | 562 | 562 | 'src/js_stream.cc', | | 563 | + 'src/json_utils.cc', | 563 | 564 | 'src/module_wrap.cc', | 564 | 565 | 'src/node.cc', | 565 | 566 | 'src/node_api.cc', | | 644 | 645 | 'src/histogram.h', | 645 | 646 | 'src/histogram-inl.h', | 646 | 647 | 'src/js_stream.h', | | 648 | + 'src/json_utils.h', | 647 | 649 | 'src/large_pages/node_large_page.cc', | 648 | 650 | 'src/large_pages/node_large_page.h', | 649 | 651 | 'src/memory_tracker.h', | | 1141 | 1143 | 'test/cctest/test_linked_binding.cc', | 1142 | 1144 | 'test/cctest/test_per_process.cc', | 1143 | 1145 | 'test/cctest/test_platform.cc', | 1144 | | - 'test/cctest/test_report_util.cc', | | 1146 | + 'test/cctest/test_json_utils.cc', | 1145 | 1147 | 'test/cctest/test_sockaddr.cc', | 1146 | 1148 | 'test/cctest/test_traced_value.cc', | 1147 | 1149 | 'test/cctest/test_util.cc', | |
Collapse file Copy file name to clipboard +67Lines changed: 67 additions & 0 deletions | Original file line number | Diff line number | Diff line change |
|---|
| | 1 | +#include "json_utils.h" | | 2 | + | | 3 | +namespace node { | | 4 | + | | 5 | +std::string EscapeJsonChars(const std::string& str) { | | 6 | + const std::string control_symbols[0x20] = { | | 7 | + "\\u0000", "\\u0001", "\\u0002", "\\u0003", "\\u0004", "\\u0005", | | 8 | + "\\u0006", "\\u0007", "\\b", "\\t", "\\n", "\\v", "\\f", "\\r", | | 9 | + "\\u000e", "\\u000f", "\\u0010", "\\u0011", "\\u0012", "\\u0013", | | 10 | + "\\u0014", "\\u0015", "\\u0016", "\\u0017", "\\u0018", "\\u0019", | | 11 | + "\\u001a", "\\u001b", "\\u001c", "\\u001d", "\\u001e", "\\u001f" | | 12 | + }; | | 13 | + | | 14 | + std::string ret; | | 15 | + size_t last_pos = 0; | | 16 | + size_t pos = 0; | | 17 | + for (; pos < str.size(); ++pos) { | | 18 | + std::string replace; | | 19 | + char ch = str[pos]; | | 20 | + if (ch == '\\') { | | 21 | + replace = "\\\\"; | | 22 | + } else if (ch == '\"') { | | 23 | + replace = "\\\""; | | 24 | + } else { | | 25 | + size_t num = static_cast<size_t>(ch); | | 26 | + if (num < 0x20) replace = control_symbols[num]; | | 27 | + } | | 28 | + if (!replace.empty()) { | | 29 | + if (pos > last_pos) { | | 30 | + ret += str.substr(last_pos, pos - last_pos); | | 31 | + } | | 32 | + last_pos = pos + 1; | | 33 | + ret += replace; | | 34 | + } | | 35 | + } | | 36 | + // Append any remaining symbols. | | 37 | + if (last_pos < str.size()) { | | 38 | + ret += str.substr(last_pos, pos - last_pos); | | 39 | + } | | 40 | + return ret; | | 41 | +} | | 42 | + | | 43 | +std::string Reindent(const std::string& str, int indent_depth) { | | 44 | + std::string indent; | | 45 | + for (int i = 0; i < indent_depth; i++) indent += ' '; | | 46 | + | | 47 | + std::string out; | | 48 | + std::string::size_type pos = 0; | | 49 | + do { | | 50 | + std::string::size_type prev_pos = pos; | | 51 | + pos = str.find('\n', pos); | | 52 | + | | 53 | + out.append(indent); | | 54 | + | | 55 | + if (pos == std::string::npos) { | | 56 | + out.append(str, prev_pos, std::string::npos); | | 57 | + break; | | 58 | + } else { | | 59 | + pos++; | | 60 | + out.append(str, prev_pos, pos - prev_pos); | | 61 | + } | | 62 | + } while (true); | | 63 | + | | 64 | + return out; | | 65 | +} | | 66 | + | | 67 | +} // namespace node |
Collapse file Copy file name to clipboard +160Lines changed: 160 additions & 0 deletions | Original file line number | Diff line number | Diff line change |
|---|
| | 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 | + | | 10 | +namespace node { | | 11 | + | | 12 | +std::string EscapeJsonChars(const std::string& str); | | 13 | +std::string Reindent(const std::string& str, int indentation); | | 14 | + | | 15 | +// JSON compiler definitions. | | 16 | +class JSONWriter { | | 17 | + public: | | 18 | + JSONWriter(std::ostream& out, bool compact) | | 19 | + : out_(out), compact_(compact) {} | | 20 | + | | 21 | + private: | | 22 | + inline void indent() { indent_ += 2; } | | 23 | + inline void deindent() { indent_ -= 2; } | | 24 | + inline void advance() { | | 25 | + if (compact_) return; | | 26 | + for (int i = 0; i < indent_; i++) out_ << ' '; | | 27 | + } | | 28 | + inline void write_one_space() { | | 29 | + if (compact_) return; | | 30 | + out_ << ' '; | | 31 | + } | | 32 | + inline void write_new_line() { | | 33 | + if (compact_) return; | | 34 | + out_ << '\n'; | | 35 | + } | | 36 | + | | 37 | + public: | | 38 | + inline void json_start() { | | 39 | + if (state_ == kAfterValue) out_ << ','; | | 40 | + write_new_line(); | | 41 | + advance(); | | 42 | + out_ << '{'; | | 43 | + indent(); | | 44 | + state_ = kObjectStart; | | 45 | + } | | 46 | + | | 47 | + inline void json_end() { | | 48 | + write_new_line(); | | 49 | + deindent(); | | 50 | + advance(); | | 51 | + out_ << '}'; | | 52 | + state_ = kAfterValue; | | 53 | + } | | 54 | + template <typename T> | | 55 | + inline void json_objectstart(T key) { | | 56 | + if (state_ == kAfterValue) out_ << ','; | | 57 | + write_new_line(); | | 58 | + advance(); | | 59 | + write_string(key); | | 60 | + out_ << ':'; | | 61 | + write_one_space(); | | 62 | + out_ << '{'; | | 63 | + indent(); | | 64 | + state_ = kObjectStart; | | 65 | + } | | 66 | + | | 67 | + template <typename T> | | 68 | + inline void json_arraystart(T key) { | | 69 | + if (state_ == kAfterValue) out_ << ','; | | 70 | + write_new_line(); | | 71 | + advance(); | | 72 | + write_string(key); | | 73 | + out_ << ':'; | | 74 | + write_one_space(); | | 75 | + out_ << '['; | | 76 | + indent(); | | 77 | + state_ = kObjectStart; | | 78 | + } | | 79 | + inline void json_objectend() { | | 80 | + write_new_line(); | | 81 | + deindent(); | | 82 | + advance(); | | 83 | + out_ << '}'; | | 84 | + if (indent_ == 0) { | | 85 | + // Top-level object is complete, so end the line. | | 86 | + out_ << '\n'; | | 87 | + } | | 88 | + state_ = kAfterValue; | | 89 | + } | | 90 | + | | 91 | + inline void json_arrayend() { | | 92 | + write_new_line(); | | 93 | + deindent(); | | 94 | + advance(); | | 95 | + out_ << ']'; | | 96 | + state_ = kAfterValue; | | 97 | + } | | 98 | + template <typename T, typename U> | | 99 | + inline void json_keyvalue(const T& key, const U& value) { | | 100 | + if (state_ == kAfterValue) out_ << ','; | | 101 | + write_new_line(); | | 102 | + advance(); | | 103 | + write_string(key); | | 104 | + out_ << ':'; | | 105 | + write_one_space(); | | 106 | + write_value(value); | | 107 | + state_ = kAfterValue; | | 108 | + } | | 109 | + | | 110 | + template <typename U> | | 111 | + inline void json_element(const U& value) { | | 112 | + if (state_ == kAfterValue) out_ << ','; | | 113 | + write_new_line(); | | 114 | + advance(); | | 115 | + write_value(value); | | 116 | + state_ = kAfterValue; | | 117 | + } | | 118 | + | | 119 | + struct Null {}; // Usable as a JSON value. | | 120 | + | | 121 | + struct ForeignJSON { | | 122 | + std::string as_string; | | 123 | + }; | | 124 | + | | 125 | + private: | | 126 | + template <typename T, | | 127 | + typename test_for_number = typename std:: | | 128 | + enable_if<std::numeric_limits<T>::is_specialized, bool>::type> | | 129 | + inline void write_value(T number) { | | 130 | + if (std::is_same<T, bool>::value) | | 131 | + out_ << (number ? "true" : "false"); | | 132 | + else | | 133 | + out_ << number; | | 134 | + } | | 135 | + | | 136 | + inline void write_value(Null null) { out_ << "null"; } | | 137 | + inline void write_value(const char* str) { write_string(str); } | | 138 | + inline void write_value(const std::string& str) { write_string(str); } | | 139 | + | | 140 | + inline void write_value(const ForeignJSON& json) { | | 141 | + out_ << Reindent(json.as_string, indent_); | | 142 | + } | | 143 | + | | 144 | + inline void write_string(const std::string& str) { | | 145 | + out_ << '"' << EscapeJsonChars(str) << '"'; | | 146 | + } | | 147 | + inline void write_string(const char* str) { write_string(std::string(str)); } | | 148 | + | | 149 | + enum JSONState { kObjectStart, kAfterValue }; | | 150 | + std::ostream& out_; | | 151 | + bool compact_; | | 152 | + int indent_ = 0; | | 153 | + int state_ = kObjectStart; | | 154 | +}; | | 155 | + | | 156 | +} // namespace node | | 157 | + | | 158 | +#endif // defined(NODE_WANT_INTERNALS) && NODE_WANT_INTERNALS | | 159 | + | | 160 | +#endif // SRC_JSON_UTILS_H_ |
Collapse file Copy file name to clipboardExpand all lines: src/node_report.cc +3Lines changed: 3 additions & 0 deletions | Original file line number | Diff line number | Diff line change |
|---|
| 1 | 1 | #include "env-inl.h" | | 2 | +#include "json_utils.h" | 2 | 3 | #include "node_report.h" | 3 | 4 | #include "debug_utils-inl.h" | 4 | 5 | #include "diagnosticfilename-inl.h" | | 16 | 17 | #include <dlfcn.h> | 17 | 18 | #endif | 18 | 19 |
| | 20 | +#include <iostream> | 19 | 21 | #include <cstring> | 20 | 22 | #include <ctime> | 21 | 23 | #include <cwctype> | @@ -30,6 +32,7 @@ using node::arraysize; | 30 | 32 | using node::ConditionVariable; | 31 | 33 | using node::DiagnosticFilename; | 32 | 34 | using node::Environment; | | 35 | +using node::JSONWriter; | 33 | 36 | using node::Mutex; | 34 | 37 | using node::NativeSymbolDebuggingContext; | 35 | 38 | using node::TIME_TYPE; | |
|