Separate jsons with closed braces.
| 89 | |
| 90 | // Separate jsons with closed braces. |
| 91 | bool JsonLoader::Reader::get_next_json(butil::IOBuf* json1) { |
| 92 | if (_file_buf.empty()) { |
| 93 | if (!read_some()) { |
| 94 | return false; |
| 95 | } |
| 96 | } |
| 97 | json1->clear(); |
| 98 | while (1) { |
| 99 | butil::IOBufAsZeroCopyInputStream it(_file_buf); |
| 100 | const void* data = NULL; |
| 101 | int size = 0; |
| 102 | int total_size = 0; |
| 103 | int skipped = 0; |
| 104 | for (; it.Next(&data, &size); total_size += size) { |
| 105 | for (int i = 0; i < size; ++i) { |
| 106 | const char c = ((const char*)data)[i]; |
| 107 | if (_brace_depth == 0) { |
| 108 | // skip any character until the first left brace is found. |
| 109 | if (c != '{') { |
| 110 | ++skipped; |
| 111 | continue; |
| 112 | } |
| 113 | } |
| 114 | switch (c) { |
| 115 | case '{': |
| 116 | if (!_quoted) { |
| 117 | ++_brace_depth; |
| 118 | } else { |
| 119 | VLOG(1) << "Quoted left brace"; |
| 120 | } |
| 121 | break; |
| 122 | case '}': |
| 123 | if (!_quoted) { |
| 124 | --_brace_depth; |
| 125 | if (_brace_depth == 0) { |
| 126 | // the braces are closed, a complete object. |
| 127 | _file_buf.cutn(json1, total_size + i + 1); |
| 128 | json1->pop_front(skipped); |
| 129 | return possibly_valid_json(*json1); |
| 130 | } else if (_brace_depth < 0) { |
| 131 | LOG(ERROR) << "More right braces than left braces"; |
| 132 | return false; |
| 133 | } |
| 134 | } else { |
| 135 | VLOG(1) << "Quoted right brace"; |
| 136 | } |
| 137 | break; |
| 138 | case '"': |
| 139 | if (_quoted) { |
| 140 | if (_quote_char == '"') { |
| 141 | _quoted = false; |
| 142 | } |
| 143 | } else { |
| 144 | _quoted = true; |
| 145 | _quote_char = '"'; |
| 146 | } |
| 147 | break; |
| 148 | case '\'': |
no test coverage detected