From c021e5e7fbdaa21e4a527d4fb8d6cbfee7362fe3 Mon Sep 17 00:00:00 2001 From: Gary Talent Date: Thu, 30 May 2024 22:13:01 -0500 Subject: [PATCH] [ox/oc] Fix OC not dealing with certain int types properly --- deps/ox/src/ox/oc/read.cpp | 129 ------------------------------------ deps/ox/src/ox/oc/read.hpp | 68 ++++++++++--------- deps/ox/src/ox/oc/write.hpp | 12 +++- 3 files changed, 49 insertions(+), 160 deletions(-) diff --git a/deps/ox/src/ox/oc/read.cpp b/deps/ox/src/ox/oc/read.cpp index d2b1ff90..fb5ef3f6 100644 --- a/deps/ox/src/ox/oc/read.cpp +++ b/deps/ox/src/ox/oc/read.cpp @@ -36,135 +36,6 @@ OrganicClawReader::OrganicClawReader(Json::Value json, int unionIdx) noexcept: m_unionIdx(unionIdx) { } -Error OrganicClawReader::field(const char *key, int8_t *val) noexcept { - auto err = OxError(0); - if (targetValid()) { - const auto &jv = value(key); - if (jv.empty()) { - *val = 0; - } else if (jv.isInt()) { - *val = static_cast(jv.asInt()); - } else { - err = OxError(1, "Type mismatch"); - } - } - ++m_fieldIt; - return err; -} - -Error OrganicClawReader::field(const char *key, int16_t *val) noexcept { - auto err = OxError(0); - if (targetValid()) { - const auto &jv = value(key); - if (jv.empty()) { - *val = 0; - } else if (jv.isInt()) { - *val = static_cast(jv.asInt()); - } else { - err = OxError(1, "Type mismatch"); - } - } - ++m_fieldIt; - return err; -} - -Error OrganicClawReader::field(const char *key, int32_t *val) noexcept { - auto err = OxError(0); - if (targetValid()) { - const auto &jv = value(key); - if (jv.empty()) { - *val = 0; - } else if (jv.isInt()) { - *val = static_cast(jv.asInt()); - } else { - err = OxError(1, "Type mismatch"); - } - } - ++m_fieldIt; - return err; -} - -Error OrganicClawReader::field(const char *key, int64_t *val) noexcept { - auto err = OxError(0); - if (targetValid()) { - const auto &jv = value(key); - if (jv.empty()) { - *val = 0; - } else if (jv.isInt() || jv.isInt64()) { - *val = static_cast(jv.asInt64()); - } else { - err = OxError(1, "Type mismatch"); - } - } - ++m_fieldIt; - return err; -} - - -Error OrganicClawReader::field(const char *key, uint8_t *val) noexcept { - auto err = OxError(0); - if (targetValid()) { - const auto &jv = value(key); - if (jv.empty()) { - *val = 0; - } else if (jv.isUInt()) { - *val = static_cast(jv.asUInt()); - } else { - err = OxError(1, "Type mismatch"); - } - } - ++m_fieldIt; - return err; -} - -Error OrganicClawReader::field(const char *key, uint16_t *val) noexcept { - auto err = OxError(0); - if (targetValid()) { - const auto &jv = value(key); - if (jv.empty()) { - *val = 0; - } else if (jv.isUInt()) { - *val = static_cast(jv.asUInt()); - } else { - err = OxError(1, "Type mismatch"); - } - } - ++m_fieldIt; - return err; -} - -Error OrganicClawReader::field(const char *key, uint32_t *val) noexcept { - auto err = OxError(0); - if (targetValid()) { - const auto &jv = value(key); - if (jv.empty()) { - *val = 0; - } else if (jv.isUInt()) { - *val = static_cast(jv.asUInt()); - } else { - err = OxError(1, "Type mismatch"); - } - } - ++m_fieldIt; - return err; -} - -Error OrganicClawReader::field(const char *key, uint64_t *val) noexcept { - auto err = OxError(0); - if (targetValid()) { - const auto &jv = value(key); - if (jv.empty()) { - *val = 0; - } else if (jv.isUInt() || jv.isUInt64()) { - *val = static_cast(jv.asUInt64()); - } else { - err = OxError(1, "Type mismatch"); - } - } - ++m_fieldIt; - return err; -} - Error OrganicClawReader::field(const char *key, bool *val) noexcept { auto err = OxError(0); if (targetValid()) { diff --git a/deps/ox/src/ox/oc/read.hpp b/deps/ox/src/ox/oc/read.hpp index b254d49f..2db945a7 100644 --- a/deps/ox/src/ox/oc/read.hpp +++ b/deps/ox/src/ox/oc/read.hpp @@ -41,16 +41,6 @@ class OrganicClawReader { explicit OrganicClawReader(Json::Value json, int unionIdx = -1) noexcept; - Error field(const char *key, int8_t *val) noexcept; - Error field(const char *key, int16_t *val) noexcept; - Error field(const char *key, int32_t *val) noexcept; - Error field(const char *key, int64_t *val) noexcept; - - Error field(const char *key, uint8_t *val) noexcept; - Error field(const char *key, uint16_t *val) noexcept; - Error field(const char *key, uint32_t *val) noexcept; - Error field(const char *key, uint64_t *val) noexcept; - Error field(const char *key, bool *val) noexcept; // array handler @@ -144,28 +134,46 @@ class OrganicClawReader { template Error OrganicClawReader::field(const char *key, T *val) noexcept { auto err = OxError(0); - if constexpr(isVector_v) { - const auto &srcVal = value(key); - const auto srcSize = srcVal.size(); - oxReturnError(ox::resizeVector(*val, srcSize)); - err = field(key, val->data(), val->size()); - } else if constexpr(isArray_v) { - const auto &srcVal = value(key); - const auto srcSize = srcVal.size(); - if (srcSize > val->size()) { - err = OxError(1, "Input array is too long"); - } else { + try { + if constexpr (is_integer_v) { + if (targetValid()) { + auto const&jv = value(key); + auto const rightType = sizeof(T) == 8 ? + (ox::is_signed_v ? jv.isInt64() : jv.isUInt64()) : + (ox::is_signed_v ? jv.isInt() : jv.isUInt()); + if (jv.empty()) { + *val = 0; + } else if (rightType) { + *val = static_cast(jv.asUInt()); + } else { + err = OxError(1, "Type mismatch"); + } + } + } else if constexpr (isVector_v) { + const auto&srcVal = value(key); + const auto srcSize = srcVal.size(); + oxReturnError(ox::resizeVector(*val, srcSize)); err = field(key, val->data(), val->size()); + } else if constexpr (isArray_v) { + const auto&srcVal = value(key); + const auto srcSize = srcVal.size(); + if (srcSize > val->size()) { + err = OxError(1, "Input array is too long"); + } else { + err = field(key, val->data(), val->size()); + } + } else if (targetValid()) { + const auto&jv = value(key); + if (jv.empty() || jv.isObject()) { + auto reader = child(key); + ModelHandlerInterface handler(&reader); + err = model(&handler, val); + } else { + err = OxError(1, "Type mismatch"); + } } - } else if (targetValid()) { - const auto &jv = value(key); - if (jv.empty() || jv.isObject()) { - auto reader = child(key); - ModelHandlerInterface handler(&reader); - err = model(&handler, val); - } else { - err = OxError(1, "Type mismatch"); - } + } catch (Json::LogicError const&) { + err = OxError(1, "error reading JSON data"); } ++m_fieldIt; return err; diff --git a/deps/ox/src/ox/oc/write.hpp b/deps/ox/src/ox/oc/write.hpp index af050404..10489e39 100644 --- a/deps/ox/src/ox/oc/write.hpp +++ b/deps/ox/src/ox/oc/write.hpp @@ -209,7 +209,17 @@ Error OrganicClawWriter::field(const char *key, const T *val, std::size_t len) n template Error OrganicClawWriter::field(const char *key, const T *val) noexcept { - if constexpr(isVector_v || isArray_v) { + if constexpr(is_integer_v) { + if (targetValid() && (*val || m_json.isArray())) { + // the int type needs to be normalized because jsoncpp doesn't + // factor in every permutation unsigned long, etc. + if constexpr(ox::is_signed_v) { + value(key) = static_cast>(*val); + } else { + value(key) = static_cast>(*val); + } + } + } else if constexpr(isVector_v || isArray_v) { return field(key, val->data(), val->size()); } else if (val && targetValid()) { OrganicClawWriter w;