#include "json_parse.hpp" #include #include #include namespace smartbotic::db { namespace { nlohmann::json convert(yyjson_val* v) { if (!v) { return nullptr; } switch (yyjson_get_type(v)) { case YYJSON_TYPE_NULL: return nullptr; case YYJSON_TYPE_BOOL: return yyjson_get_bool(v); case YYJSON_TYPE_NUM: switch (yyjson_get_subtype(v)) { case YYJSON_SUBTYPE_UINT: return yyjson_get_uint(v); case YYJSON_SUBTYPE_SINT: return yyjson_get_sint(v); case YYJSON_SUBTYPE_REAL: default: return yyjson_get_real(v); } case YYJSON_TYPE_STR: return std::string(yyjson_get_str(v), yyjson_get_len(v)); case YYJSON_TYPE_ARR: { nlohmann::json out = nlohmann::json::array(); size_t idx, max; yyjson_val* elem; yyjson_arr_foreach(v, idx, max, elem) { out.push_back(convert(elem)); } return out; } case YYJSON_TYPE_OBJ: { nlohmann::json out = nlohmann::json::object(); size_t idx, max; yyjson_val* key; yyjson_val* val; yyjson_obj_foreach(v, idx, max, key, val) { out[std::string(yyjson_get_str(key), yyjson_get_len(key))] = convert(val); } return out; } default: return nullptr; } } } // namespace nlohmann::json parse_to_nlohmann(const char* data, size_t length) { // Null guard only. Empty buffers (length == 0) deliberately fall through // to yyjson, which returns a positional "empty content" error — keeping // the parse_error message shape consistent with non-empty malformed // inputs across all 17 callsites. if (!data) { throw nlohmann::json::parse_error::create( 101, 0, "null input buffer", nullptr); } yyjson_read_err err{}; yyjson_doc* doc = yyjson_read_opts( const_cast(data), length, YYJSON_READ_NOFLAG, nullptr, &err); if (!doc) { std::string msg = "yyjson parse error: "; msg += err.msg ? err.msg : "unknown"; throw nlohmann::json::parse_error::create( 101, static_cast(err.pos), msg, nullptr); } try { nlohmann::json out = convert(yyjson_doc_get_root(doc)); yyjson_doc_free(doc); return out; } catch (...) { yyjson_doc_free(doc); throw; } } nlohmann::json parse_to_nlohmann(std::string_view bytes) { return parse_to_nlohmann(bytes.data(), bytes.size()); } } // namespace smartbotic::db