| 1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192 |
- #include "json_parse.hpp"
- #include <yyjson.h>
- #include <stdexcept>
- #include <string>
- 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<char*>(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<size_t>(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
|