#pragma once #include #include #include #include #include #include #include // 添加limits头文件 #include // 添加异常处理 namespace SimpleJson { class Json { public: // 添加Integer类型 enum class Type { Null, Boolean, Integer, Number, String, Array, Object }; using Array = std::vector; using Object = std::unordered_map; private: Type type_; union { bool boolVal; int intVal; // 新增int类型存储 double numVal; }; std::shared_ptr strVal; std::shared_ptr arrVal; std::shared_ptr objVal; public: // 添加int构造函数 Json() : type_(Type::Null) {} Json(std::nullptr_t) : type_(Type::Null) {} Json(bool b) : type_(Type::Boolean), boolVal(b) {} Json(int i) : type_(Type::Integer), intVal(i) {} // 新增 Json(double d) : type_(Type::Number), numVal(d) {} Json(const std::string& s) : type_(Type::String), strVal(std::make_shared(s)) {} Json(const char* s) : type_(Type::String), strVal(std::make_shared(s)) {} Json(const Array& a) : type_(Type::Array), arrVal(std::make_shared(a)) {} Json(const Object& o) : type_(Type::Object), objVal(std::make_shared(o)) {} Type type() const { return type_; } // 添加int访问器 bool asBool() const { if (type_ != Type::Boolean) return false; else return boolVal; } int asInt() const { // 新增 if (type_ == Type::Integer) return intVal; if (type_ == Type::Number) return static_cast(numVal); else return -1; } double asNumber() const { if (type_ == Type::Integer) return intVal; if (type_ == Type::Number) return numVal; else return -1; } const std::string& asString() const { static const std::string emptyString = ""; if (type_ != Type::String) return emptyString; else return *strVal; } const Array& asArray() const { if (type_ != Type::Array) throw std::runtime_error("Not an array"); return *arrVal; } const Object& asObject() const { if (type_ != Type::Object) throw std::runtime_error("Not an object"); return *objVal; } // 序列化支持整数 std::string stringify() const { switch (type_) { case Type::Null: return "null"; case Type::Boolean: return boolVal ? "true" : "false"; case Type::Integer: return std::to_string(intVal); // 新增 case Type::Number: { // 避免多余的零和小数点 std::string numStr = std::to_string(numVal); // 删除末尾多余的零 auto pos = numStr.find('.'); if (pos != std::string::npos) { // 删除末尾连续的零 while (numStr.back() == '0') numStr.pop_back(); // 如果只剩小数点,也删除 if (numStr.back() == '.') numStr.pop_back(); } return numStr; } case Type::String: return "\"" + escape(*strVal) + "\""; case Type::Array: { std::string out = "["; for (size_t i = 0; i < arrVal->size(); ++i) { if (i > 0) out += ","; out += (*arrVal)[i].stringify(); } return out + "]"; } case Type::Object: { std::string out = "{"; size_t i = 0; for (auto& kv : *objVal) { if (i++ > 0) out += ","; out += "\"" + escape(kv.first) + "\":" + kv.second.stringify(); } return out + "}"; } } return "null"; } // 解析增强数字处理 static Json parse(const std::string& json) { size_t i = 0; return parseValue(json, i); } // 在 class Json 里加上 bool isNull() const { return type_ == Type::Null; } Json getOrNull(const std::string& key) const { if (type_ != Type::Object || !objVal) return Json(nullptr); auto it = objVal->find(key); if (it == objVal->end()) return Json(nullptr); return it->second; } private: static std::string escape(const std::string& s) { std::string out; for (char c : s) { switch (c) { case '\"': out += "\\\""; break; case '\\': out += "\\\\"; break; case '\b': out += "\\b"; break; case '\f': out += "\\f"; break; case '\n': out += "\\n"; break; case '\r': out += "\\r"; break; case '\t': out += "\\t"; break; default: if (std::iscntrl(static_cast(c))) { char buf[7]; snprintf(buf, sizeof(buf), "\\u%04x", static_cast(c)); out += buf; } else { out += c; } } } return out; } static void skipWhitespace(const std::string& s, size_t& i) { while (i < s.length() && std::isspace(static_cast(s[i]))) ++i; } static Json parseValue(const std::string& s, size_t& i) { skipWhitespace(s, i); if (i >= s.length()) throw std::runtime_error("Unexpected end of JSON"); if (s[i] == 'n') return parseNull(s, i); if (s[i] == 't' || s[i] == 'f') return parseBool(s, i); if (s[i] == '-' || std::isdigit(static_cast(s[i]))) return parseNumber(s, i); if (s[i] == '"') return parseString(s, i); if (s[i] == '[') return parseArray(s, i); if (s[i] == '{') return parseObject(s, i); throw std::runtime_error("Invalid JSON at position " + std::to_string(i)); } static Json parseNull(const std::string& s, size_t& i) { if (s.substr(i, 4) == "null") { i += 4; return nullptr; } throw std::runtime_error("Invalid null"); } static Json parseBool(const std::string& s, size_t& i) { if (s.substr(i, 4) == "true") { i += 4; return true; } if (s.substr(i, 5) == "false") { i += 5; return false; } throw std::runtime_error("Invalid boolean"); } // 增强数字解析 static Json parseNumber(const std::string& s, size_t& i) { size_t start = i; bool isDouble = false; // 处理符号 if (s[i] == '-') ++i; // 整数部分 if (i < s.length() && s[i] == '0') { ++i; // 前导零 } else if (i < s.length() && std::isdigit(static_cast(s[i]))) { while (i < s.length() && std::isdigit(static_cast(s[i]))) ++i; } else { throw std::runtime_error("Invalid number format"); } // 小数部分 if (i < s.length() && s[i] == '.') { isDouble = true; ++i; if (i >= s.length() || !std::isdigit(static_cast(s[i]))) { throw std::runtime_error("Invalid decimal part"); } while (i < s.length() && std::isdigit(static_cast(s[i]))) ++i; } // 指数部分 if (i < s.length() && (s[i] == 'e' || s[i] == 'E')) { isDouble = true; ++i; if (i < s.length() && (s[i] == '+' || s[i] == '-')) ++i; if (i >= s.length() || !std::isdigit(static_cast(s[i]))) { throw std::runtime_error("Invalid exponent part"); } while (i < s.length() && std::isdigit(static_cast(s[i]))) ++i; } std::string numStr = s.substr(start, i - start); try { if (isDouble) { return Json(std::stod(numStr)); } else { long long val = std::stoll(numStr); if (val >= std::numeric_limits::min() && val <= std::numeric_limits::max()) { return Json(static_cast(val)); } return Json(static_cast(val)); } } catch (const std::exception& e) { throw std::runtime_error("Invalid number: " + numStr); } } static Json parseString(const std::string& s, size_t& i) { ++i; // skip " std::string result; while (i < s.length()) { char c = s[i++]; if (c == '\"') break; if (c == '\\') { if (i >= s.length()) throw std::runtime_error("Unterminated string escape"); char esc = s[i++]; switch (esc) { case '\"': result += '\"'; break; case '\\': result += '\\'; break; case '/': result += '/'; break; case 'b': result += '\b'; break; case 'f': result += '\f'; break; case 'n': result += '\n'; break; case 'r': result += '\r'; break; case 't': result += '\t'; break; case 'u': { // Unicode转义 if (i + 4 > s.length()) throw std::runtime_error("Invalid unicode escape"); std::string hexStr = s.substr(i, 4); i += 4; try { unsigned int code = std::stoul(hexStr, nullptr, 16); // 简化处理:直接存储UTF-8字节(实际应转换为UTF-8) result += static_cast(code & 0xFF); } catch (...) { throw std::runtime_error("Invalid unicode code: " + hexStr); } break; } default: result += esc; break; } } else { result += c; } } return Json(result); } static Json parseArray(const std::string& s, size_t& i) { ++i; // skip [ Array arr; skipWhitespace(s, i); if (i < s.length() && s[i] == ']') { ++i; return arr; } while (true) { arr.push_back(parseValue(s, i)); skipWhitespace(s, i); if (i < s.length() && s[i] == ']') { ++i; break; } if (i >= s.length() || s[i] != ',') throw std::runtime_error("Expected ',' in array"); ++i; skipWhitespace(s, i); } return arr; } static Json parseObject(const std::string& s, size_t& i) { ++i; // skip { Object obj; skipWhitespace(s, i); if (i < s.length() && s[i] == '}') { ++i; return obj; } while (true) { skipWhitespace(s, i); if (i >= s.length() || s[i] != '\"') throw std::runtime_error("Expected string key"); Json key = parseString(s, i); skipWhitespace(s, i); if (i >= s.length() || s[i] != ':') throw std::runtime_error("Expected ':' in object"); ++i; Json value = parseValue(s, i); obj[key.asString()] = value; skipWhitespace(s, i); if (i < s.length() && s[i] == '}') { ++i; break; } if (i >= s.length() || s[i] != ',') throw std::runtime_error("Expected ',' in object"); ++i; } return obj; } }; }