#include "json_utils.h" #include std::string json_trim(const std::string& s) { size_t b = s.find_first_not_of(" \t\r\n"); if (b == std::string::npos) return ""; size_t e = s.find_last_not_of(" \t\r\n"); return s.substr(b, e - b + 1); } static bool is_ws(char c) { return c == ' ' || c == '\t' || c == '\r' || c == '\n'; } std::string json_get_raw(const std::string& text, const std::string& key) { std::string k = "\"" + key + "\""; size_t pos = 0; while ((pos = text.find(k, pos)) != std::string::npos) { bool key_ok = true; if (pos > 0) { char c = text[pos - 1]; if (isalnum((unsigned char)c) || c == '_') key_ok = false; } if (key_ok) { size_t p = pos + k.size(); while (p < text.size() && is_ws(text[p])) ++p; // 跳过空白 if (p >= text.size()) return ""; if (text[p] != ':') { pos = pos + 1; continue; } ++p; while (p < text.size() && is_ws(text[p])) ++p; // 跳过冒号后空白 if (p >= text.size()) return ""; char c = text[p]; if (c == '"') { // 字符串:读到配对引号 size_t q = p + 1; while (q < text.size() && text[q] != '"') ++q; return text.substr(p, q - p + 1); } else if (c == '{' || c == '[') { char close = (c == '{') ? '}' : ']'; int depth = 0; size_t q = p; for (; q < text.size(); ++q) { if (text[q] == '"') { ++q; while (q < text.size() && text[q] != '"') ++q; } else if (text[q] == c) ++depth; else if (text[q] == close) { --depth; if (depth == 0) { ++q; break; } } } return text.substr(p, q - p); } else { // 数字 / true / false / null size_t q = p; while (q < text.size() && text[q] != ',' && text[q] != '}' && text[q] != ']' && !is_ws(text[q])) ++q; return text.substr(p, q - p); } } pos = pos + 1; } return ""; } static std::string unquote(const std::string& raw) { std::string t = json_trim(raw); if (t.size() >= 2 && t[0] == '"' && t[t.size() - 1] == '"') return t.substr(1, t.size() - 2); return t; } bool json_get_string(const std::string& text, const std::string& key, std::string& out) { std::string raw = json_get_raw(text, key); if (raw.empty()) return false; out = unquote(raw); return true; } bool json_get_number(const std::string& text, const std::string& key, double& out) { std::string raw = json_get_raw(text, key); if (raw.empty()) return false; std::string t = json_trim(raw); if (t.empty()) return false; try { out = std::stod(t); return true; } catch (...) { return false; } } bool json_get_bool(const std::string& text, const std::string& key, bool& out) { std::string raw = json_get_raw(text, key); if (raw.empty()) return false; std::string t = json_trim(raw); if (t == "true") { out = true; return true; } if (t == "false") { out = false; return true; } double d; if (json_get_number(text, key, d)) { out = (d != 0); return true; } return false; } int json_get_point_array(const std::string& text, const std::string& key, std::vector>& out) { std::string raw = json_get_raw(text, key); if (raw.empty()) return 0; std::string t = json_trim(raw); if (t.empty() || t[0] != '[') return 0; // 逐个匹配 "[数,数]" 子元素 size_t i = 1; int cnt = 0; while (i < t.size()) { size_t l = t.find('[', i); if (l == std::string::npos) break; size_t r = t.find(']', l); if (r == std::string::npos) break; std::string ele = t.substr(l + 1, r - l - 1); size_t comma = ele.find(','); if (comma != std::string::npos) { try { double a = std::stod(json_trim(ele.substr(0, comma))); double b = std::stod(json_trim(ele.substr(comma + 1))); out.push_back(std::make_pair(a, b)); ++cnt; } catch (...) {} } i = r + 1; } return cnt; } // ---- 分组两级查找实现 ---- std::string json_get_raw(const std::string& text, const std::string& group, const std::string& key) { std::string obj = group.empty() ? text : json_get_raw(text, group); if (obj.empty()) return ""; return json_get_raw(obj, key); } bool json_get_string(const std::string& text, const std::string& group, const std::string& key, std::string& out) { std::string raw = json_get_raw(text, group, key); if (raw.empty()) return false; out = unquote(raw); return true; } bool json_get_number(const std::string& text, const std::string& group, const std::string& key, double& out) { std::string raw = json_get_raw(text, group, key); if (raw.empty()) return false; std::string t = json_trim(raw); if (t.empty()) return false; try { out = std::stod(t); return true; } catch (...) { return false; } } bool json_get_bool(const std::string& text, const std::string& group, const std::string& key, bool& out) { std::string raw = json_get_raw(text, group, key); if (raw.empty()) return false; std::string t = json_trim(raw); if (t == "true") { out = true; return true; } if (t == "false") { out = false; return true; } double d; if (json_get_number(text, group, key, d)) { out = (d != 0); return true; } return false; } int json_get_point_array(const std::string& text, const std::string& group, const std::string& key, std::vector>& out) { std::string raw = json_get_raw(text, group, key); if (raw.empty()) return 0; std::string t = json_trim(raw); if (t.empty() || t[0] != '[') return 0; // 逐个匹配 "[数,数]" 子元素 size_t i = 1; int cnt = 0; while (i < t.size()) { size_t l = t.find('[', i); if (l == std::string::npos) break; size_t r = t.find(']', l); if (r == std::string::npos) break; std::string ele = t.substr(l + 1, r - l - 1); size_t comma = ele.find(','); if (comma != std::string::npos) { try { double a = std::stod(json_trim(ele.substr(0, comma))); double b = std::stod(json_trim(ele.substr(comma + 1))); out.push_back(std::make_pair(a, b)); ++cnt; } catch (...) {} } i = r + 1; } return cnt; }