11cb0ef41Sopenharmony_ci#include "json_utils.h" 21cb0ef41Sopenharmony_ci 31cb0ef41Sopenharmony_cinamespace node { 41cb0ef41Sopenharmony_ci 51cb0ef41Sopenharmony_cistd::string EscapeJsonChars(std::string_view str) { 61cb0ef41Sopenharmony_ci // 'static constexpr' is slightly better than static const 71cb0ef41Sopenharmony_ci // since the initialization occurs at compile time. 81cb0ef41Sopenharmony_ci // See https://lemire.me/blog/I3Cah 91cb0ef41Sopenharmony_ci static constexpr std::string_view control_symbols[0x20] = { 101cb0ef41Sopenharmony_ci "\\u0000", "\\u0001", "\\u0002", "\\u0003", "\\u0004", "\\u0005", 111cb0ef41Sopenharmony_ci "\\u0006", "\\u0007", "\\b", "\\t", "\\n", "\\u000b", 121cb0ef41Sopenharmony_ci "\\f", "\\r", "\\u000e", "\\u000f", "\\u0010", "\\u0011", 131cb0ef41Sopenharmony_ci "\\u0012", "\\u0013", "\\u0014", "\\u0015", "\\u0016", "\\u0017", 141cb0ef41Sopenharmony_ci "\\u0018", "\\u0019", "\\u001a", "\\u001b", "\\u001c", "\\u001d", 151cb0ef41Sopenharmony_ci "\\u001e", "\\u001f"}; 161cb0ef41Sopenharmony_ci 171cb0ef41Sopenharmony_ci std::string ret; 181cb0ef41Sopenharmony_ci size_t last_pos = 0; 191cb0ef41Sopenharmony_ci size_t pos = 0; 201cb0ef41Sopenharmony_ci for (; pos < str.size(); ++pos) { 211cb0ef41Sopenharmony_ci std::string replace; 221cb0ef41Sopenharmony_ci char ch = str[pos]; 231cb0ef41Sopenharmony_ci if (ch == '\\') { 241cb0ef41Sopenharmony_ci replace = "\\\\"; 251cb0ef41Sopenharmony_ci } else if (ch == '\"') { 261cb0ef41Sopenharmony_ci replace = "\\\""; 271cb0ef41Sopenharmony_ci } else { 281cb0ef41Sopenharmony_ci size_t num = static_cast<size_t>(ch); 291cb0ef41Sopenharmony_ci if (num < 0x20) replace = control_symbols[num]; 301cb0ef41Sopenharmony_ci } 311cb0ef41Sopenharmony_ci if (!replace.empty()) { 321cb0ef41Sopenharmony_ci if (pos > last_pos) { 331cb0ef41Sopenharmony_ci ret += str.substr(last_pos, pos - last_pos); 341cb0ef41Sopenharmony_ci } 351cb0ef41Sopenharmony_ci last_pos = pos + 1; 361cb0ef41Sopenharmony_ci ret += replace; 371cb0ef41Sopenharmony_ci } 381cb0ef41Sopenharmony_ci } 391cb0ef41Sopenharmony_ci // Append any remaining symbols. 401cb0ef41Sopenharmony_ci if (last_pos < str.size()) { 411cb0ef41Sopenharmony_ci ret += str.substr(last_pos, pos - last_pos); 421cb0ef41Sopenharmony_ci } 431cb0ef41Sopenharmony_ci return ret; 441cb0ef41Sopenharmony_ci} 451cb0ef41Sopenharmony_ci 461cb0ef41Sopenharmony_cistd::string Reindent(const std::string& str, int indent_depth) { 471cb0ef41Sopenharmony_ci if (indent_depth <= 0) return str; 481cb0ef41Sopenharmony_ci const std::string indent(indent_depth, ' '); 491cb0ef41Sopenharmony_ci std::string out; 501cb0ef41Sopenharmony_ci std::string::size_type pos = 0; 511cb0ef41Sopenharmony_ci for (;;) { 521cb0ef41Sopenharmony_ci std::string::size_type prev_pos = pos; 531cb0ef41Sopenharmony_ci pos = str.find('\n', pos); 541cb0ef41Sopenharmony_ci 551cb0ef41Sopenharmony_ci out.append(indent); 561cb0ef41Sopenharmony_ci 571cb0ef41Sopenharmony_ci if (pos == std::string::npos) { 581cb0ef41Sopenharmony_ci out.append(str, prev_pos, std::string::npos); 591cb0ef41Sopenharmony_ci break; 601cb0ef41Sopenharmony_ci } else { 611cb0ef41Sopenharmony_ci pos++; 621cb0ef41Sopenharmony_ci out.append(str, prev_pos, pos - prev_pos); 631cb0ef41Sopenharmony_ci } 641cb0ef41Sopenharmony_ci } 651cb0ef41Sopenharmony_ci 661cb0ef41Sopenharmony_ci return out; 671cb0ef41Sopenharmony_ci} 681cb0ef41Sopenharmony_ci 691cb0ef41Sopenharmony_ci} // namespace node 70