-
Notifications
You must be signed in to change notification settings - Fork 30k
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
src: move JSONWriter into its own file
The JSONWriter feature is not inherently related to the report feature in any way. As a drive-by fix, remove a number of unused header includes. PR-URL: #32552 Reviewed-By: Colin Ihrig <[email protected]> Reviewed-By: Gus Caplan <[email protected]> Reviewed-By: James M Snell <[email protected]> Reviewed-By: Richard Lau <[email protected]>
- Loading branch information
Showing
7 changed files
with
238 additions
and
225 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,67 @@ | ||
#include "json_utils.h" | ||
|
||
namespace node { | ||
|
||
std::string EscapeJsonChars(const std::string& str) { | ||
const std::string control_symbols[0x20] = { | ||
"\\u0000", "\\u0001", "\\u0002", "\\u0003", "\\u0004", "\\u0005", | ||
"\\u0006", "\\u0007", "\\b", "\\t", "\\n", "\\v", "\\f", "\\r", | ||
"\\u000e", "\\u000f", "\\u0010", "\\u0011", "\\u0012", "\\u0013", | ||
"\\u0014", "\\u0015", "\\u0016", "\\u0017", "\\u0018", "\\u0019", | ||
"\\u001a", "\\u001b", "\\u001c", "\\u001d", "\\u001e", "\\u001f" | ||
}; | ||
|
||
std::string ret; | ||
size_t last_pos = 0; | ||
size_t pos = 0; | ||
for (; pos < str.size(); ++pos) { | ||
std::string replace; | ||
char ch = str[pos]; | ||
if (ch == '\\') { | ||
replace = "\\\\"; | ||
} else if (ch == '\"') { | ||
replace = "\\\""; | ||
} else { | ||
size_t num = static_cast<size_t>(ch); | ||
if (num < 0x20) replace = control_symbols[num]; | ||
} | ||
if (!replace.empty()) { | ||
if (pos > last_pos) { | ||
ret += str.substr(last_pos, pos - last_pos); | ||
} | ||
last_pos = pos + 1; | ||
ret += replace; | ||
} | ||
} | ||
// Append any remaining symbols. | ||
if (last_pos < str.size()) { | ||
ret += str.substr(last_pos, pos - last_pos); | ||
} | ||
return ret; | ||
} | ||
|
||
std::string Reindent(const std::string& str, int indent_depth) { | ||
std::string indent; | ||
for (int i = 0; i < indent_depth; i++) indent += ' '; | ||
|
||
std::string out; | ||
std::string::size_type pos = 0; | ||
do { | ||
std::string::size_type prev_pos = pos; | ||
pos = str.find('\n', pos); | ||
|
||
out.append(indent); | ||
|
||
if (pos == std::string::npos) { | ||
out.append(str, prev_pos, std::string::npos); | ||
break; | ||
} else { | ||
pos++; | ||
out.append(str, prev_pos, pos - prev_pos); | ||
} | ||
} while (true); | ||
|
||
return out; | ||
} | ||
|
||
} // namespace node |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,160 @@ | ||
#ifndef SRC_JSON_UTILS_H_ | ||
#define SRC_JSON_UTILS_H_ | ||
|
||
#if defined(NODE_WANT_INTERNALS) && NODE_WANT_INTERNALS | ||
|
||
#include <iomanip> | ||
#include <ostream> | ||
#include <limits> | ||
|
||
namespace node { | ||
|
||
std::string EscapeJsonChars(const std::string& str); | ||
std::string Reindent(const std::string& str, int indentation); | ||
|
||
// JSON compiler definitions. | ||
class JSONWriter { | ||
public: | ||
JSONWriter(std::ostream& out, bool compact) | ||
: out_(out), compact_(compact) {} | ||
|
||
private: | ||
inline void indent() { indent_ += 2; } | ||
inline void deindent() { indent_ -= 2; } | ||
inline void advance() { | ||
if (compact_) return; | ||
for (int i = 0; i < indent_; i++) out_ << ' '; | ||
} | ||
inline void write_one_space() { | ||
if (compact_) return; | ||
out_ << ' '; | ||
} | ||
inline void write_new_line() { | ||
if (compact_) return; | ||
out_ << '\n'; | ||
} | ||
|
||
public: | ||
inline void json_start() { | ||
if (state_ == kAfterValue) out_ << ','; | ||
write_new_line(); | ||
advance(); | ||
out_ << '{'; | ||
indent(); | ||
state_ = kObjectStart; | ||
} | ||
|
||
inline void json_end() { | ||
write_new_line(); | ||
deindent(); | ||
advance(); | ||
out_ << '}'; | ||
state_ = kAfterValue; | ||
} | ||
template <typename T> | ||
inline void json_objectstart(T key) { | ||
if (state_ == kAfterValue) out_ << ','; | ||
write_new_line(); | ||
advance(); | ||
write_string(key); | ||
out_ << ':'; | ||
write_one_space(); | ||
out_ << '{'; | ||
indent(); | ||
state_ = kObjectStart; | ||
} | ||
|
||
template <typename T> | ||
inline void json_arraystart(T key) { | ||
if (state_ == kAfterValue) out_ << ','; | ||
write_new_line(); | ||
advance(); | ||
write_string(key); | ||
out_ << ':'; | ||
write_one_space(); | ||
out_ << '['; | ||
indent(); | ||
state_ = kObjectStart; | ||
} | ||
inline void json_objectend() { | ||
write_new_line(); | ||
deindent(); | ||
advance(); | ||
out_ << '}'; | ||
if (indent_ == 0) { | ||
// Top-level object is complete, so end the line. | ||
out_ << '\n'; | ||
} | ||
state_ = kAfterValue; | ||
} | ||
|
||
inline void json_arrayend() { | ||
write_new_line(); | ||
deindent(); | ||
advance(); | ||
out_ << ']'; | ||
state_ = kAfterValue; | ||
} | ||
template <typename T, typename U> | ||
inline void json_keyvalue(const T& key, const U& value) { | ||
if (state_ == kAfterValue) out_ << ','; | ||
write_new_line(); | ||
advance(); | ||
write_string(key); | ||
out_ << ':'; | ||
write_one_space(); | ||
write_value(value); | ||
state_ = kAfterValue; | ||
} | ||
|
||
template <typename U> | ||
inline void json_element(const U& value) { | ||
if (state_ == kAfterValue) out_ << ','; | ||
write_new_line(); | ||
advance(); | ||
write_value(value); | ||
state_ = kAfterValue; | ||
} | ||
|
||
struct Null {}; // Usable as a JSON value. | ||
|
||
struct ForeignJSON { | ||
std::string as_string; | ||
}; | ||
|
||
private: | ||
template <typename T, | ||
typename test_for_number = typename std:: | ||
enable_if<std::numeric_limits<T>::is_specialized, bool>::type> | ||
inline void write_value(T number) { | ||
if (std::is_same<T, bool>::value) | ||
out_ << (number ? "true" : "false"); | ||
else | ||
out_ << number; | ||
} | ||
|
||
inline void write_value(Null null) { out_ << "null"; } | ||
inline void write_value(const char* str) { write_string(str); } | ||
inline void write_value(const std::string& str) { write_string(str); } | ||
|
||
inline void write_value(const ForeignJSON& json) { | ||
out_ << Reindent(json.as_string, indent_); | ||
} | ||
|
||
inline void write_string(const std::string& str) { | ||
out_ << '"' << EscapeJsonChars(str) << '"'; | ||
} | ||
inline void write_string(const char* str) { write_string(std::string(str)); } | ||
|
||
enum JSONState { kObjectStart, kAfterValue }; | ||
std::ostream& out_; | ||
bool compact_; | ||
int indent_ = 0; | ||
int state_ = kObjectStart; | ||
}; | ||
|
||
} // namespace node | ||
|
||
#endif // defined(NODE_WANT_INTERNALS) && NODE_WANT_INTERNALS | ||
|
||
#endif // SRC_JSON_UTILS_H_ |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Oops, something went wrong.