| 71 | } |
| 72 | |
| 73 | int |
| 74 | esc_json_out(const char *buf, int64_t len, std::ostream &jsonfile) |
| 75 | { |
| 76 | if (buf == nullptr) { |
| 77 | return 0; |
| 78 | } |
| 79 | int64_t idx = 0, prevIdx = 0; |
| 80 | // For an explanation of the algorithm here, see the doxygen comment for |
| 81 | // write_buffered_content. |
| 82 | for (idx = 0; idx < len; idx++) { |
| 83 | char c = *(buf + idx); |
| 84 | switch (c) { |
| 85 | case '"': |
| 86 | case '\\': { |
| 87 | write_buffered_context(buf, prevIdx, idx, jsonfile); |
| 88 | jsonfile << "\\" << c; |
| 89 | break; |
| 90 | } |
| 91 | case '\b': { |
| 92 | write_buffered_context(buf, prevIdx, idx, jsonfile); |
| 93 | jsonfile << "\\b"; |
| 94 | break; |
| 95 | } |
| 96 | case '\f': { |
| 97 | write_buffered_context(buf, prevIdx, idx, jsonfile); |
| 98 | jsonfile << "\\f"; |
| 99 | break; |
| 100 | } |
| 101 | case '\n': { |
| 102 | write_buffered_context(buf, prevIdx, idx, jsonfile); |
| 103 | jsonfile << "\\n"; |
| 104 | break; |
| 105 | } |
| 106 | case '\r': { |
| 107 | write_buffered_context(buf, prevIdx, idx, jsonfile); |
| 108 | jsonfile << "\\r"; |
| 109 | break; |
| 110 | } |
| 111 | case '\t': { |
| 112 | write_buffered_context(buf, prevIdx, idx, jsonfile); |
| 113 | jsonfile << "\\t"; |
| 114 | break; |
| 115 | } |
| 116 | default: { |
| 117 | if (c <= '\x1f') { |
| 118 | auto const original_flags = jsonfile.flags(); |
| 119 | write_buffered_context(buf, prevIdx, idx, jsonfile); |
| 120 | jsonfile << "\\u" << std::hex << std::setw(4) << std::setfill('0') << static_cast<int>(c); |
| 121 | jsonfile.flags(original_flags); |
| 122 | } |
| 123 | break; |
| 124 | // else: The character does not need to be escaped. Do not call |
| 125 | // write_buffered_content so nothing is written and prevIdx remains |
| 126 | // pointing to the first character that needs to be written on the next |
| 127 | // call to write_buffered_content. |
| 128 | } |
| 129 | } |
| 130 | } |
no test coverage detected