From e1c55783247fb779a24ffaf064dd5fa9e0beeaed Mon Sep 17 00:00:00 2001 From: ProjectSky Date: Fri, 21 Nov 2025 00:07:25 +0800 Subject: [PATCH] feat: enhance JSON management with new rotation and value counting features - Added ObjectRotate and ArrayRotate methods for rotating key-value pairs in JSON objects and arrays, respectively - Introduced GetValCount method to retrieve the total number of values in immutable JSON documents - Renamed all Float-related methods to Double in C++ interface (IJsonManager) for better precision clarity - Fixed TypeAccess configuration in handle type registration to allow external extensions to create JSON handles by properly setting HTypeAccess_Create flag - Renamed GetHandleType to GetJsonHandleType for better clarity and consistency - Updated documentation to clarify usage and performance considerations for new methods - Enhanced tests to cover rotation functionality and value counting in various JSON structures --- extensions/json/IJsonManager.h | 177 +++++++---- extensions/json/JsonManager.cpp | 300 +++++++++--------- extensions/json/JsonManager.h | 40 +-- extensions/json/JsonNatives.cpp | 544 +++++++++++++++++--------------- extensions/json/extension.cpp | 20 +- plugins/include/json.inc | 54 +++- plugins/testsuite/test_json.sp | 197 ++++++++++++ 7 files changed, 854 insertions(+), 478 deletions(-) diff --git a/extensions/json/IJsonManager.h b/extensions/json/IJsonManager.h index ed4090e69..f43fdbe17 100755 --- a/extensions/json/IJsonManager.h +++ b/extensions/json/IJsonManager.h @@ -15,8 +15,7 @@ class JsonArrIter; class JsonObjIter; #define SMINTERFACE_JSONMANAGER_NAME "IJsonManager" -#define SMINTERFACE_JSONMANAGER_VERSION 2 -#define JSON_PACK_ERROR_SIZE 256 +#define SMINTERFACE_JSONMANAGER_VERSION 3 #define JSON_ERROR_BUFFER_SIZE 256 #define JSON_INT64_BUFFER_SIZE 32 @@ -98,21 +97,36 @@ public: * @return true on success, false if buffer is too small or on error * * @note The out_size parameter returns the size including null terminator - * @note Use GetSerializedSize() with the same write_flg to determine buffer size - * @warning This method performs multiple memory allocations and copies, resulting in poor performance. - * For better performance, use WriteToStringPtr() instead, which avoids intermediate buffers + * + * @warning Buffer Size Requirements: + * This function does not allocate memory, but the buffer must be larger than + * the final JSON size to allow temporary space. + * + * The extra space is needed temporarily for each value while it is written, + * and is reused for later values: + * - Number: 40 bytes + * - String: 16 + (str_len * 6) bytes + * - Other values: 16 bytes + * - Nesting depth: 16 * max_json_depth bytes + * + * @note GetSerializedSize() only returns the final JSON size, NOT including the temporary space + * You must manually add extra buffer space based on your JSON content + * @note For most use cases, prefer WriteToStringPtr() for simplicity + * Use this method only when you need to avoid heap allocation (e.g., stack buffers, pre-allocated pools) */ virtual bool WriteToString(JsonValue* handle, char* buffer, size_t buffer_size, uint32_t write_flg = 0, size_t* out_size = nullptr) = 0; /** - * Write JSON to string and return allocated string (performance-optimized version) + * Write JSON to string and return allocated string * @param handle JSON value * @param write_flg Write flags (YYJSON_WRITE_FLAG values, default: 0) * @param out_size Pointer to receive actual size written (including null terminator) optional * @return Allocated string pointer on success, nullptr on error. Caller must free() the returned pointer * - * @note This is the recommended method for serialization as it avoids intermediate buffer allocations + * @note This function handles memory allocation internally, + * avoiding the complexity of manual buffer size calculation required by WriteToString() + * @note This is the recommended method for most use cases due to its simplicity and safety */ virtual char* WriteToStringPtr(JsonValue* handle, uint32_t write_flg = 0, size_t* out_size = nullptr) = 0; @@ -383,6 +397,17 @@ public: */ virtual size_t GetRefCount(JsonValue* handle) = 0; + /** + * Get the total number of values in a document + * @param handle JSON value + * @return Total number of values in the document tree, 0 if handle is null or mutable + * @note Only works on immutable documents (parsed from JSON) + * @note Useful for performance planning and memory estimation + * @note Counts ALL values including containers, keys, and leaf values + * Example: {"a":1,"b":2,"c":3} returns 7 (1 object + 3 keys + 3 values) + */ + virtual size_t GetValCount(JsonValue* handle) = 0; + /** * Create an empty mutable JSON object * @return New mutable JSON object or nullptr on failure @@ -466,10 +491,11 @@ public: * Get float value by key * @param handle JSON object * @param key Key name - * @param out_value Pointer to receive float value + * @param out_value Pointer to receive double value * @return true on success, false if key not found or type mismatch + * @note Integers values are auto converted to double */ - virtual bool ObjectGetFloat(JsonValue* handle, const char* key, double* out_value) = 0; + virtual bool ObjectGetDouble(JsonValue* handle, const char* key, double* out_value) = 0; /** * Get integer value by key @@ -547,13 +573,13 @@ public: virtual bool ObjectSetBool(JsonValue* handle, const char* key, bool value) = 0; /** - * Set float value by key (mutable only) + * Set double value by key (mutable only) * @param handle Mutable JSON object * @param key Key name - * @param value Float value + * @param value Double value * @return true on success */ - virtual bool ObjectSetFloat(JsonValue* handle, const char* key, double value) = 0; + virtual bool ObjectSetDouble(JsonValue* handle, const char* key, double value) = 0; /** * Set integer value by key (mutable only) @@ -614,6 +640,18 @@ public: */ virtual bool ObjectSort(JsonValue* handle, JSON_SORT_ORDER sort_mode) = 0; + /** + * Rotate key-value pairs in the object + * @param handle Mutable JSON object + * @param idx Number of positions to rotate (must be less than object size) + * @return true on success, false if idx >= object size or object is immutable + * @note Only works on mutable objects + * @note Example: {"a":1,"b":2,"c":3,"d":4} rotate 1 becomes {"b":2,"c":3,"d":4,"a":1} + * @note Valid range: 0 <= idx < object size + * @warning This function takes linear time proportional to the rotation amount + */ + virtual bool ObjectRotate(JsonValue* handle, size_t idx) = 0; + /** * Create an empty mutable JSON array * @return New mutable JSON array or nullptr on failure @@ -657,12 +695,12 @@ public: virtual JsonValue* ArrayInitWithBool(const bool* values, size_t count) = 0; /** - * Create a JSON array from float values - * @param values Array of float values + * Create a JSON array from double values + * @param values Array of double values * @param count Number of values * @return New JSON array or nullptr on failure */ - virtual JsonValue* ArrayInitWithFloat(const double* values, size_t count) = 0; + virtual JsonValue* ArrayInitWithDouble(const double* values, size_t count) = 0; /** * Parse a JSON array from string @@ -727,13 +765,14 @@ public: virtual bool ArrayGetBool(JsonValue* handle, size_t index, bool* out_value) = 0; /** - * Get float value at index + * Get double value at index * @param handle JSON array * @param index Element index - * @param out_value Pointer to receive float value + * @param out_value Pointer to receive double value * @return true on success, false if index out of bounds or type mismatch + * @note Integers values are auto converted to double */ - virtual bool ArrayGetFloat(JsonValue* handle, size_t index, double* out_value) = 0; + virtual bool ArrayGetDouble(JsonValue* handle, size_t index, double* out_value) = 0; /** * Get integer value at index @@ -790,13 +829,13 @@ public: virtual bool ArrayReplaceBool(JsonValue* handle, size_t index, bool value) = 0; /** - * Replace element at index with float (mutable only) + * Replace element at index with double (mutable only) * @param handle Mutable JSON array * @param index Element index - * @param value Float value + * @param value Double value * @return true on success */ - virtual bool ArrayReplaceFloat(JsonValue* handle, size_t index, double value) = 0; + virtual bool ArrayReplaceDouble(JsonValue* handle, size_t index, double value) = 0; /** * Replace element at index with integer (mutable only) @@ -850,12 +889,12 @@ public: virtual bool ArrayAppendBool(JsonValue* handle, bool value) = 0; /** - * Append float to end of array (mutable only) + * Append double to end of array (mutable only) * @param handle Mutable JSON array - * @param value Float value + * @param value Double value * @return true on success */ - virtual bool ArrayAppendFloat(JsonValue* handle, double value) = 0; + virtual bool ArrayAppendDouble(JsonValue* handle, double value) = 0; /** * Append integer to end of array (mutable only) @@ -925,13 +964,13 @@ public: virtual bool ArrayInsertInt64(JsonValue* handle, size_t index, std::variant value) = 0; /** - * Insert float at specific index (mutable only) + * Insert double at specific index (mutable only) * @param handle Mutable JSON array * @param index Element index - * @param value Float value + * @param value Double value * @return true on success */ - virtual bool ArrayInsertFloat(JsonValue* handle, size_t index, double value) = 0; + virtual bool ArrayInsertDouble(JsonValue* handle, size_t index, double value) = 0; /** * Insert string at specific index (mutable only) @@ -983,12 +1022,12 @@ public: virtual bool ArrayPrependInt64(JsonValue* handle, std::variant value) = 0; /** - * Prepend float to beginning of array (mutable only) + * Prepend double to beginning of array (mutable only) * @param handle Mutable JSON array - * @param value Float value + * @param value Double value * @return true on success */ - virtual bool ArrayPrependFloat(JsonValue* handle, double value) = 0; + virtual bool ArrayPrependDouble(JsonValue* handle, double value) = 0; /** * Prepend string to beginning of array (mutable only) @@ -1076,12 +1115,12 @@ public: virtual int ArrayIndexOfInt64(JsonValue* handle, std::variant search_value) = 0; /** - * Find index of float value + * Find index of double value * @param handle JSON array - * @param search_value Float value to search for + * @param search_value Double value to search for * @return Index of first match, or -1 if not found */ - virtual int ArrayIndexOfFloat(JsonValue* handle, double search_value) = 0; + virtual int ArrayIndexOfDouble(JsonValue* handle, double search_value) = 0; /** * Sort array elements @@ -1092,6 +1131,18 @@ public: */ virtual bool ArraySort(JsonValue* handle, JSON_SORT_ORDER sort_mode) = 0; + /** + * Rotate array elements + * @param handle Mutable JSON array + * @param idx Number of positions to rotate (must be less than array length) + * @return true on success, false if idx >= array length or array is immutable + * @note Only works on mutable arrays + * @note Example: [1,2,3,4,5] rotate 2 becomes [3,4,5,1,2] + * @note Valid range: 0 <= idx < array length + * @warning This function takes linear time proportional to the rotation amount + */ + virtual bool ArrayRotate(JsonValue* handle, size_t idx) = 0; + /** * Create JSON value from format string and parameters * @param format Format string (e.g., "{s:i,s:s}", "[i,s,b]") @@ -1120,11 +1171,11 @@ public: virtual JsonValue* CreateBool(bool value) = 0; /** - * Create a JSON float value - * @param value Float value - * @return New JSON float or nullptr on failure + * Create a JSON double value + * @param value Double value + * @return New JSON double or nullptr on failure */ - virtual JsonValue* CreateFloat(double value) = 0; + virtual JsonValue* CreateDouble(double value) = 0; /** * Create a JSON integer value @@ -1162,12 +1213,13 @@ public: virtual bool GetBool(JsonValue* handle, bool* out_value) = 0; /** - * Get float value from JSON + * Get double value from JSON * @param handle JSON value - * @param out_value Pointer to receive float value + * @param out_value Pointer to receive double value * @return true on success, false on type mismatch + * @note Integers values are auto converted to double */ - virtual bool GetFloat(JsonValue* handle, double* out_value) = 0; + virtual bool GetDouble(JsonValue* handle, double* out_value) = 0; /** * Get integer value from JSON @@ -1218,15 +1270,16 @@ public: char* error = nullptr, size_t error_size = 0) = 0; /** - * Get float value using JSON Pointer + * Get double value using JSON Pointer * @param handle JSON value * @param path JSON Pointer path - * @param out_value Pointer to receive float value + * @param out_value Pointer to receive double value * @param error Error buffer (optional) * @param error_size Error buffer size * @return true on success, false on error + * @note Integers values are auto converted to double */ - virtual bool PtrGetFloat(JsonValue* handle, const char* path, double* out_value, + virtual bool PtrGetDouble(JsonValue* handle, const char* path, double* out_value, char* error = nullptr, size_t error_size = 0) = 0; /** @@ -1315,15 +1368,15 @@ public: char* error = nullptr, size_t error_size = 0) = 0; /** - * Set float value using JSON Pointer (mutable only) + * Set double value using JSON Pointer (mutable only) * @param handle Mutable JSON value * @param path JSON Pointer path - * @param value Float value + * @param value Double value * @param error Error buffer (optional) * @param error_size Error buffer size * @return true on success, false on error */ - virtual bool PtrSetFloat(JsonValue* handle, const char* path, double value, + virtual bool PtrSetDouble(JsonValue* handle, const char* path, double value, char* error = nullptr, size_t error_size = 0) = 0; /** @@ -1398,15 +1451,15 @@ public: char* error = nullptr, size_t error_size = 0) = 0; /** - * Add float to array using JSON Pointer (mutable only) + * Add double to array using JSON Pointer (mutable only) * @param handle Mutable JSON value * @param path JSON Pointer path to array - * @param value Float value + * @param value Double value * @param error Error buffer (optional) * @param error_size Error buffer size * @return true on success, false on error */ - virtual bool PtrAddFloat(JsonValue* handle, const char* path, double value, + virtual bool PtrAddDouble(JsonValue* handle, const char* path, double value, char* error = nullptr, size_t error_size = 0) = 0; /** @@ -1485,13 +1538,14 @@ public: virtual bool PtrTryGetBool(JsonValue* handle, const char* path, bool* out_value) = 0; /** - * Try to get float value using JSON Pointer (returns false on failure) + * Try to get double value using JSON Pointer (returns false on failure) * @param handle JSON value * @param path JSON Pointer path - * @param out_value Pointer to receive float value + * @param out_value Pointer to receive double value * @return true on success, false if not found or type mismatch + * @note Integers values are auto converted to double */ - virtual bool PtrTryGetFloat(JsonValue* handle, const char* path, double* out_value) = 0; + virtual bool PtrTryGetDouble(JsonValue* handle, const char* path, double* out_value) = 0; /** * Try to get integer value using JSON Pointer (returns false on failure) @@ -1583,7 +1637,7 @@ public: * External extensions MUST use this method to obtain the handle type * @return The HandleType_t for JSON handles */ - virtual HandleType_t GetHandleType() = 0; + virtual HandleType_t GetJsonHandleType() = 0; /** * Read JsonValue from a SourceMod handle @@ -1591,7 +1645,7 @@ public: * @param handle Handle to read from * @return JsonValue pointer, or nullptr on error (error will be reported to context) */ - virtual JsonValue* GetFromHandle(IPluginContext* pContext, Handle_t handle) = 0; + virtual JsonValue* GetValueFromHandle(IPluginContext* pContext, Handle_t handle) = 0; /** * Initialize an array iterator (same as ArrIterWith but returns pointer) @@ -1717,6 +1771,17 @@ public: */ virtual void* ObjIterRemove(JsonObjIter* iter) = 0; + /** + * Get key string from object iterator key pointer + * @param iter Object iterator + * @param key Key pointer (returned from ObjIterNext) + * @param out_str Pointer to receive key string + * @param out_len Pointer to receive key length (optional) + * @return true on success, false on error + * @note Do not free the returned string - it is owned by the JSON document + */ + virtual bool ObjIterGetKeyString(JsonObjIter* iter, void* key, const char** out_str, size_t* out_len = nullptr) = 0; + /** * Release an array iterator * @param iter Iterator to release @@ -1836,12 +1901,12 @@ public: /** * Directly modify a JSON value to floating-point type * @param handle JSON value to modify (cannot be object or array) - * @param value Float value + * @param value Double value * @return true on success, false if handle is object or array * @warning For immutable documents, this breaks immutability. Use with caution. * @note This modifies the value in-place without creating a new value */ - virtual bool SetFloat(JsonValue* handle, double value) = 0; + virtual bool SetDouble(JsonValue* handle, double value) = 0; /** * Directly modify a JSON value to string type diff --git a/extensions/json/JsonManager.cpp b/extensions/json/JsonManager.cpp index 28675497f..e95a93f08 100755 --- a/extensions/json/JsonManager.cpp +++ b/extensions/json/JsonManager.cpp @@ -137,9 +137,6 @@ JsonValue* JsonManager::ParseJSON(const char* json_str, bool is_file, bool is_mu readError.msg, readError.code, readError.pos); } } - if (idoc) { - yyjson_doc_free(idoc); - } return nullptr; } @@ -258,7 +255,7 @@ JsonValue* JsonManager::ApplyJsonPatch(JsonValue* target, JsonValue* patch, bool yyjson_mut_val* resultRoot = yyjson_mut_patch(doc, root, patchCopy, &patch_err); if (!resultRoot) { SetErrorSafe(error, error_size, "JSON patch failed (code %u, op index %zu, message: %s)", - patch_err.code, patch_err.idx, patch_err); + patch_err.code, patch_err.idx, patch_err.msg); return nullptr; } @@ -881,6 +878,14 @@ size_t JsonManager::GetRefCount(JsonValue* handle) return handle->GetDocumentRefCount(); } +size_t JsonManager::GetValCount(JsonValue* handle) +{ + if (!handle || !handle->IsImmutable()) { + return 0; + } + return yyjson_doc_get_val_count(handle->m_pDocument->get()); +} + JsonValue* JsonManager::ObjectInit() { auto pJSONValue = CreateWrapper(); @@ -949,9 +954,6 @@ JsonValue* JsonManager::ObjectParseString(const char* str, yyjson_read_flag read SetErrorSafe(error, error_size, "Failed to parse JSON str: %s (error code: %u, position: %zu)", readError.msg, readError.code, readError.pos); } - if (idoc) { - yyjson_doc_free(idoc); - } return nullptr; } @@ -994,9 +996,6 @@ JsonValue* JsonManager::ObjectParseFile(const char* path, yyjson_read_flag read_ SetErrorSafe(error, error_size, "Failed to parse JSON file: %s (error code: %u, msg: %s, position: %zu)", realpath, readError.code, readError.msg, readError.pos); } - if (idoc) { - yyjson_doc_free(idoc); - } return nullptr; } @@ -1181,7 +1180,7 @@ bool JsonManager::ObjectGetBool(JsonValue* handle, const char* key, bool* out_va } } -bool JsonManager::ObjectGetFloat(JsonValue* handle, const char* key, double* out_value) +bool JsonManager::ObjectGetDouble(JsonValue* handle, const char* key, double* out_value) { if (!handle || !key || !out_value) { return false; @@ -1189,19 +1188,19 @@ bool JsonManager::ObjectGetFloat(JsonValue* handle, const char* key, double* out if (handle->IsMutable()) { yyjson_mut_val* val = yyjson_mut_obj_get(handle->m_pVal_mut, key); - if (!val || !yyjson_mut_is_real(val)) { + if (!val || !yyjson_mut_is_num(val)) { return false; } - *out_value = yyjson_mut_get_real(val); + *out_value = yyjson_mut_get_num(val); return true; } else { yyjson_val* val = yyjson_obj_get(handle->m_pVal, key); - if (!val || !yyjson_is_real(val)) { + if (!val || !yyjson_is_num(val)) { return false; } - *out_value = yyjson_get_real(val); + *out_value = yyjson_get_num(val); return true; } } @@ -1381,7 +1380,7 @@ bool JsonManager::ObjectSetBool(JsonValue* handle, const char* key, bool value) return yyjson_mut_obj_put(handle->m_pVal_mut, yyjson_mut_strcpy(handle->m_pDocument_mut->get(), key), yyjson_mut_bool(handle->m_pDocument_mut->get(), value)); } -bool JsonManager::ObjectSetFloat(JsonValue* handle, const char* key, double value) +bool JsonManager::ObjectSetDouble(JsonValue* handle, const char* key, double value) { if (!handle || !handle->IsMutable() || !key) { return false; @@ -1405,15 +1404,11 @@ bool JsonManager::ObjectSetInt64(JsonValue* handle, const char* key, std::varian return false; } - return std::visit([&](auto&& val) -> bool { - using T = std::decay_t; - if constexpr (std::is_same_v) { - return yyjson_mut_obj_put(handle->m_pVal_mut, yyjson_mut_strcpy(handle->m_pDocument_mut->get(), key), yyjson_mut_sint(handle->m_pDocument_mut->get(), val)); - } else if constexpr (std::is_same_v) { - return yyjson_mut_obj_put(handle->m_pVal_mut, yyjson_mut_strcpy(handle->m_pDocument_mut->get(), key), yyjson_mut_uint(handle->m_pDocument_mut->get(), val)); - } - return false; - }, value); + if (std::holds_alternative(value)) { + return yyjson_mut_obj_put(handle->m_pVal_mut, yyjson_mut_strcpy(handle->m_pDocument_mut->get(), key), yyjson_mut_sint(handle->m_pDocument_mut->get(), std::get(value))); + } else { + return yyjson_mut_obj_put(handle->m_pVal_mut, yyjson_mut_strcpy(handle->m_pDocument_mut->get(), key), yyjson_mut_uint(handle->m_pDocument_mut->get(), std::get(value))); + } } bool JsonManager::ObjectSetNull(JsonValue* handle, const char* key) @@ -1511,6 +1506,19 @@ bool JsonManager::ObjectSort(JsonValue* handle, JSON_SORT_ORDER sort_mode) return true; } +bool JsonManager::ObjectRotate(JsonValue* handle, size_t idx) +{ + if (!handle || !handle->IsMutable()) { + return false; + } + + if (!yyjson_mut_is_obj(handle->m_pVal_mut)) { + return false; + } + + return yyjson_mut_obj_rotate(handle->m_pVal_mut, idx); +} + JsonValue* JsonManager::ArrayInit() { auto pJSONValue = CreateWrapper(); @@ -1641,15 +1649,12 @@ JsonValue* JsonManager::ArrayInitWithInt64(const char** values, size_t count, ch return nullptr; } - yyjson_mut_val* val = std::visit([&](auto&& arg) -> yyjson_mut_val* { - using T = std::decay_t; - if constexpr (std::is_same_v) { - return yyjson_mut_sint(doc, arg); - } else if constexpr (std::is_same_v) { - return yyjson_mut_uint(doc, arg); - } - return nullptr; - }, variant_value); + yyjson_mut_val* val; + if (std::holds_alternative(variant_value)) { + val = yyjson_mut_sint(doc, std::get(variant_value)); + } else { + val = yyjson_mut_uint(doc, std::get(variant_value)); + } if (!val || !yyjson_mut_arr_append(pJSONValue->m_pVal_mut, val)) { if (error && error_size > 0) { @@ -1692,7 +1697,7 @@ JsonValue* JsonManager::ArrayInitWithBool(const bool* values, size_t count) return pJSONValue.release(); } -JsonValue* JsonManager::ArrayInitWithFloat(const double* values, size_t count) +JsonValue* JsonManager::ArrayInitWithDouble(const double* values, size_t count) { if (!values) { return nullptr; @@ -1740,9 +1745,6 @@ JsonValue* JsonManager::ArrayParseString(const char* str, yyjson_read_flag read_ SetErrorSafe(error, error_size, "Failed to parse JSON string: %s (error code: %u, position: %zu)", readError.msg, readError.code, readError.pos); } - if (idoc) { - yyjson_doc_free(idoc); - } return nullptr; } @@ -1785,9 +1787,6 @@ JsonValue* JsonManager::ArrayParseFile(const char* path, yyjson_read_flag read_f SetErrorSafe(error, error_size, "Failed to parse JSON file: %s (error code: %u, msg: %s, position: %zu)", realpath, readError.code, readError.msg, readError.pos); } - if (idoc) { - yyjson_doc_free(idoc); - } return nullptr; } @@ -1973,7 +1972,7 @@ bool JsonManager::ArrayGetBool(JsonValue* handle, size_t index, bool* out_value) } } -bool JsonManager::ArrayGetFloat(JsonValue* handle, size_t index, double* out_value) +bool JsonManager::ArrayGetDouble(JsonValue* handle, size_t index, double* out_value) { if (!handle || !out_value) { return false; @@ -1986,11 +1985,11 @@ bool JsonManager::ArrayGetFloat(JsonValue* handle, size_t index, double* out_val } yyjson_mut_val* val = yyjson_mut_arr_get(handle->m_pVal_mut, index); - if (!yyjson_mut_is_real(val)) { + if (!yyjson_mut_is_num(val)) { return false; } - *out_value = yyjson_mut_get_real(val); + *out_value = yyjson_mut_get_num(val); return true; } else { size_t arr_size = yyjson_arr_size(handle->m_pVal); @@ -1999,11 +1998,11 @@ bool JsonManager::ArrayGetFloat(JsonValue* handle, size_t index, double* out_val } yyjson_val* val = yyjson_arr_get(handle->m_pVal, index); - if (!yyjson_is_real(val)) { + if (!yyjson_is_num(val)) { return false; } - *out_value = yyjson_get_real(val); + *out_value = yyjson_get_num(val); return true; } } @@ -2183,7 +2182,7 @@ bool JsonManager::ArrayReplaceBool(JsonValue* handle, size_t index, bool value) return yyjson_mut_arr_replace(handle->m_pVal_mut, index, yyjson_mut_bool(handle->m_pDocument_mut->get(), value)) != nullptr; } -bool JsonManager::ArrayReplaceFloat(JsonValue* handle, size_t index, double value) +bool JsonManager::ArrayReplaceDouble(JsonValue* handle, size_t index, double value) { if (!handle || !handle->IsMutable()) { return false; @@ -2222,15 +2221,11 @@ bool JsonManager::ArrayReplaceInt64(JsonValue* handle, size_t index, std::varian return false; } - return std::visit([&](auto&& val) -> bool { - using T = std::decay_t; - if constexpr (std::is_same_v) { - return yyjson_mut_arr_replace(handle->m_pVal_mut, index, yyjson_mut_sint(handle->m_pDocument_mut->get(), val)) != nullptr; - } else if constexpr (std::is_same_v) { - return yyjson_mut_arr_replace(handle->m_pVal_mut, index, yyjson_mut_uint(handle->m_pDocument_mut->get(), val)) != nullptr; - } - return false; - }, value); + if (std::holds_alternative(value)) { + return yyjson_mut_arr_replace(handle->m_pVal_mut, index, yyjson_mut_sint(handle->m_pDocument_mut->get(), std::get(value))) != nullptr; + } else { + return yyjson_mut_arr_replace(handle->m_pVal_mut, index, yyjson_mut_uint(handle->m_pDocument_mut->get(), std::get(value))) != nullptr; + } } bool JsonManager::ArrayReplaceNull(JsonValue* handle, size_t index) @@ -2290,7 +2285,7 @@ bool JsonManager::ArrayAppendBool(JsonValue* handle, bool value) return yyjson_mut_arr_append(handle->m_pVal_mut, yyjson_mut_bool(handle->m_pDocument_mut->get(), value)); } -bool JsonManager::ArrayAppendFloat(JsonValue* handle, double value) +bool JsonManager::ArrayAppendDouble(JsonValue* handle, double value) { if (!handle || !handle->IsMutable()) { return false; @@ -2314,15 +2309,11 @@ bool JsonManager::ArrayAppendInt64(JsonValue* handle, std::variant bool { - using T = std::decay_t; - if constexpr (std::is_same_v) { - return yyjson_mut_arr_append(handle->m_pVal_mut, yyjson_mut_sint(handle->m_pDocument_mut->get(), val)); - } else if constexpr (std::is_same_v) { - return yyjson_mut_arr_append(handle->m_pVal_mut, yyjson_mut_uint(handle->m_pDocument_mut->get(), val)); - } - return false; - }, value); + if (std::holds_alternative(value)) { + return yyjson_mut_arr_append(handle->m_pVal_mut, yyjson_mut_sint(handle->m_pDocument_mut->get(), std::get(value))); + } else { + return yyjson_mut_arr_append(handle->m_pVal_mut, yyjson_mut_uint(handle->m_pDocument_mut->get(), std::get(value))); + } } bool JsonManager::ArrayAppendNull(JsonValue* handle) @@ -2392,15 +2383,12 @@ bool JsonManager::ArrayInsertInt64(JsonValue* handle, size_t index, std::variant return false; } - yyjson_mut_val* val = std::visit([&](auto&& arg) -> yyjson_mut_val* { - using T = std::decay_t; - if constexpr (std::is_same_v) { - return yyjson_mut_sint(handle->m_pDocument_mut->get(), arg); - } else if constexpr (std::is_same_v) { - return yyjson_mut_uint(handle->m_pDocument_mut->get(), arg); - } - return nullptr; - }, value); + yyjson_mut_val* val; + if (std::holds_alternative(value)) { + val = yyjson_mut_sint(handle->m_pDocument_mut->get(), std::get(value)); + } else { + val = yyjson_mut_uint(handle->m_pDocument_mut->get(), std::get(value)); + } if (!val) { return false; @@ -2409,7 +2397,7 @@ bool JsonManager::ArrayInsertInt64(JsonValue* handle, size_t index, std::variant return yyjson_mut_arr_insert(handle->m_pVal_mut, val, index); } -bool JsonManager::ArrayInsertFloat(JsonValue* handle, size_t index, double value) +bool JsonManager::ArrayInsertDouble(JsonValue* handle, size_t index, double value) { if (!handle || !handle->IsMutable()) { return false; @@ -2480,15 +2468,12 @@ bool JsonManager::ArrayPrependInt64(JsonValue* handle, std::variant yyjson_mut_val* { - using T = std::decay_t; - if constexpr (std::is_same_v) { - return yyjson_mut_sint(handle->m_pDocument_mut->get(), arg); - } else if constexpr (std::is_same_v) { - return yyjson_mut_uint(handle->m_pDocument_mut->get(), arg); - } - return nullptr; - }, value); + yyjson_mut_val* val; + if (std::holds_alternative(value)) { + val = yyjson_mut_sint(handle->m_pDocument_mut->get(), std::get(value)); + } else { + val = yyjson_mut_uint(handle->m_pDocument_mut->get(), std::get(value)); + } if (!val) { return false; @@ -2497,7 +2482,7 @@ bool JsonManager::ArrayPrependInt64(JsonValue* handle, std::variantm_pVal_mut, val); } -bool JsonManager::ArrayPrependFloat(JsonValue* handle, double value) +bool JsonManager::ArrayPrependDouble(JsonValue* handle, double value) { if (!handle || !handle->IsMutable()) { return false; @@ -2722,7 +2707,7 @@ int JsonManager::ArrayIndexOfInt64(JsonValue* handle, std::variant values; @@ -2881,6 +2866,19 @@ bool JsonManager::ArraySort(JsonValue* handle, JSON_SORT_ORDER sort_mode) return true; } +bool JsonManager::ArrayRotate(JsonValue* handle, size_t idx) +{ + if (!handle || !handle->IsMutable()) { + return false; + } + + if (!yyjson_mut_is_arr(handle->m_pVal_mut)) { + return false; + } + + return yyjson_mut_arr_rotate(handle->m_pVal_mut, idx); +} + const char* JsonManager::SkipSeparators(const char* ptr) { while (*ptr && (isspace(*ptr) || *ptr == ':' || *ptr == ',')) { @@ -3156,7 +3154,7 @@ JsonValue* JsonManager::CreateBool(bool value) return pJSONValue.release(); } -JsonValue* JsonManager::CreateFloat(double value) +JsonValue* JsonManager::CreateDouble(double value) { auto pJSONValue = CreateWrapper(); pJSONValue->m_pDocument_mut = CreateDocument(); @@ -3207,14 +3205,11 @@ JsonValue* JsonManager::CreateInt64(std::variant value) auto* doc = pJSONValue->m_pDocument_mut->get(); - std::visit([&](auto&& val) { - using T = std::decay_t; - if constexpr (std::is_same_v) { - pJSONValue->m_pVal_mut = yyjson_mut_sint(doc, val); - } else if constexpr (std::is_same_v) { - pJSONValue->m_pVal_mut = yyjson_mut_uint(doc, val); - } - }, value); + if (std::holds_alternative(value)) { + pJSONValue->m_pVal_mut = yyjson_mut_sint(doc, std::get(value)); + } else { + pJSONValue->m_pVal_mut = yyjson_mut_uint(doc, std::get(value)); + } if (!pJSONValue->m_pVal_mut) { return nullptr; @@ -3290,23 +3285,23 @@ bool JsonManager::GetBool(JsonValue* handle, bool* out_value) } } -bool JsonManager::GetFloat(JsonValue* handle, double* out_value) +bool JsonManager::GetDouble(JsonValue* handle, double* out_value) { if (!handle || !out_value) { return false; } if (handle->IsMutable()) { - if (!yyjson_mut_is_real(handle->m_pVal_mut)) { + if (!yyjson_mut_is_num(handle->m_pVal_mut)) { return false; } - *out_value = yyjson_mut_get_real(handle->m_pVal_mut); + *out_value = yyjson_mut_get_num(handle->m_pVal_mut); return true; } else { - if (!yyjson_is_real(handle->m_pVal)) { + if (!yyjson_is_num(handle->m_pVal)) { return false; } - *out_value = yyjson_get_real(handle->m_pVal); + *out_value = yyjson_get_num(handle->m_pVal); return true; } } @@ -3477,7 +3472,7 @@ bool JsonManager::PtrGetBool(JsonValue* handle, const char* path, bool* out_valu } } -bool JsonManager::PtrGetFloat(JsonValue* handle, const char* path, double* out_value, char* error, size_t error_size) +bool JsonManager::PtrGetDouble(JsonValue* handle, const char* path, double* out_value, char* error, size_t error_size) { if (!handle || !path || !out_value) { if (error && error_size > 0) { @@ -3499,14 +3494,14 @@ bool JsonManager::PtrGetFloat(JsonValue* handle, const char* path, double* out_v return false; } - if (!yyjson_mut_is_real(val)) { + if (!yyjson_mut_is_num(val)) { if (error && error_size > 0) { - SetErrorSafe(error, error_size, "Type mismatch at path '%s': expected float value, got %s", path, yyjson_mut_get_type_desc(val)); + SetErrorSafe(error, error_size, "Type mismatch at path '%s': expected number value, got %s", path, yyjson_mut_get_type_desc(val)); } return false; } - *out_value = yyjson_mut_get_real(val); + *out_value = yyjson_mut_get_num(val); return true; } else { yyjson_val* val = yyjson_doc_ptr_getx(handle->m_pDocument->get(), path, strlen(path), &ptrGetError); @@ -3519,14 +3514,14 @@ bool JsonManager::PtrGetFloat(JsonValue* handle, const char* path, double* out_v return false; } - if (!yyjson_is_real(val)) { + if (!yyjson_is_num(val)) { if (error && error_size > 0) { - SetErrorSafe(error, error_size, "Type mismatch at path '%s': expected float value, got %s", path, yyjson_get_type_desc(val)); + SetErrorSafe(error, error_size, "Type mismatch at path '%s': expected number value, got %s", path, yyjson_get_type_desc(val)); } return false; } - *out_value = yyjson_get_real(val); + *out_value = yyjson_get_num(val); return true; } } @@ -3849,7 +3844,7 @@ bool JsonManager::PtrSetBool(JsonValue* handle, const char* path, bool value, ch return success; } -bool JsonManager::PtrSetFloat(JsonValue* handle, const char* path, double value, char* error, size_t error_size) +bool JsonManager::PtrSetDouble(JsonValue* handle, const char* path, double value, char* error, size_t error_size) { if (!handle || !handle->IsMutable() || !path) { if (error && error_size > 0) { @@ -3914,14 +3909,12 @@ bool JsonManager::PtrSetInt64(JsonValue* handle, const char* path, std::variant< return false; } - yyjson_mut_val* val = std::visit([&](auto&& val_input) -> yyjson_mut_val* { - using T = std::decay_t; - if constexpr (std::is_same_v) { - return yyjson_mut_sint(handle->m_pDocument_mut->get(), val_input); - } else { - return yyjson_mut_uint(handle->m_pDocument_mut->get(), val_input); - } - }, value); + yyjson_mut_val* val; + if (std::holds_alternative(value)) { + val = yyjson_mut_sint(handle->m_pDocument_mut->get(), std::get(value)); + } else { + val = yyjson_mut_uint(handle->m_pDocument_mut->get(), std::get(value)); + } if (!val) { if (error && error_size > 0) { SetErrorSafe(error, error_size, "Failed to create JSON value"); @@ -4058,7 +4051,7 @@ bool JsonManager::PtrAddBool(JsonValue* handle, const char* path, bool value, ch return success; } -bool JsonManager::PtrAddFloat(JsonValue* handle, const char* path, double value, char* error, size_t error_size) +bool JsonManager::PtrAddDouble(JsonValue* handle, const char* path, double value, char* error, size_t error_size) { if (!handle || !handle->IsMutable() || !path) { if (error && error_size > 0) { @@ -4123,14 +4116,12 @@ bool JsonManager::PtrAddInt64(JsonValue* handle, const char* path, std::variant< return false; } - yyjson_mut_val* val = std::visit([&](auto&& val_input) -> yyjson_mut_val* { - using T = std::decay_t; - if constexpr (std::is_same_v) { - return yyjson_mut_sint(handle->m_pDocument_mut->get(), val_input); - } else { - return yyjson_mut_uint(handle->m_pDocument_mut->get(), val_input); - } - }, value); + yyjson_mut_val* val; + if (std::holds_alternative(value)) { + val = yyjson_mut_sint(handle->m_pDocument_mut->get(), std::get(value)); + } else { + val = yyjson_mut_uint(handle->m_pDocument_mut->get(), std::get(value)); + } if (!val) { if (error && error_size > 0) { SetErrorSafe(error, error_size, "Failed to create JSON value"); @@ -4300,7 +4291,7 @@ bool JsonManager::PtrTryGetBool(JsonValue* handle, const char* path, bool* out_v } } -bool JsonManager::PtrTryGetFloat(JsonValue* handle, const char* path, double* out_value) +bool JsonManager::PtrTryGetDouble(JsonValue* handle, const char* path, double* out_value) { if (!handle || !path || !out_value) { return false; @@ -4616,12 +4607,12 @@ void JsonManager::Release(JsonValue* value) } } -HandleType_t JsonManager::GetHandleType() +HandleType_t JsonManager::GetJsonHandleType() { return g_JsonType; } -JsonValue* JsonManager::GetFromHandle(IPluginContext* pContext, Handle_t handle) +JsonValue* JsonManager::GetValueFromHandle(IPluginContext* pContext, Handle_t handle) { HandleError err; HandleSecurity sec(pContext->GetIdentity(), myself->GetIdentity()); @@ -4945,6 +4936,27 @@ void* JsonManager::ObjIterRemove(JsonObjIter* iter) return yyjson_mut_obj_iter_remove(&iter->m_iterMut); } +bool JsonManager::ObjIterGetKeyString(JsonObjIter* iter, void* key, const char** out_str, size_t* out_len) +{ + if (!iter || !key || !out_str) { + return false; + } + + if (iter->m_isMutable) { + *out_str = yyjson_mut_get_str(reinterpret_cast(key)); + if (out_len) { + *out_len = yyjson_mut_get_len(reinterpret_cast(key)); + } + } else { + *out_str = yyjson_get_str(reinterpret_cast(key)); + if (out_len) { + *out_len = yyjson_get_len(reinterpret_cast(key)); + } + } + + return *out_str != nullptr; +} + void JsonManager::ReleaseArrIter(JsonArrIter* iter) { if (iter) { @@ -5143,26 +5155,22 @@ bool JsonManager::SetInt64(JsonValue* handle, std::variant va return false; } - return std::visit([&](auto&& val) -> bool { - using T = std::decay_t; - if (handle->IsMutable()) { - if constexpr (std::is_same_v) { - return yyjson_mut_set_sint(handle->m_pVal_mut, val); - } else if constexpr (std::is_same_v) { - return yyjson_mut_set_uint(handle->m_pVal_mut, val); - } + if (handle->IsMutable()) { + if (std::holds_alternative(value)) { + return yyjson_mut_set_sint(handle->m_pVal_mut, std::get(value)); } else { - if constexpr (std::is_same_v) { - return yyjson_set_sint(handle->m_pVal, val); - } else if constexpr (std::is_same_v) { - return yyjson_set_uint(handle->m_pVal, val); - } + return yyjson_mut_set_uint(handle->m_pVal_mut, std::get(value)); } - return false; - }, value); + } else { + if (std::holds_alternative(value)) { + return yyjson_set_sint(handle->m_pVal, std::get(value)); + } else { + return yyjson_set_uint(handle->m_pVal, std::get(value)); + } + } } -bool JsonManager::SetFloat(JsonValue* handle, double value) +bool JsonManager::SetDouble(JsonValue* handle, double value) { if (!handle) { return false; diff --git a/extensions/json/JsonManager.h b/extensions/json/JsonManager.h index 2fc6a1480..c53b36f14 100755 --- a/extensions/json/JsonManager.h +++ b/extensions/json/JsonManager.h @@ -346,6 +346,7 @@ public: virtual bool IsImmutable(JsonValue* handle) override; virtual size_t GetReadSize(JsonValue* handle) override; virtual size_t GetRefCount(JsonValue* handle) override; + virtual size_t GetValCount(JsonValue* handle) override; // ========== Object Operations ========== virtual JsonValue* ObjectInit() override; @@ -359,7 +360,7 @@ public: virtual JsonValue* ObjectGetValueAt(JsonValue* handle, size_t index) override; virtual JsonValue* ObjectGet(JsonValue* handle, const char* key) override; virtual bool ObjectGetBool(JsonValue* handle, const char* key, bool* out_value) override; - virtual bool ObjectGetFloat(JsonValue* handle, const char* key, double* out_value) override; + virtual bool ObjectGetDouble(JsonValue* handle, const char* key, double* out_value) override; virtual bool ObjectGetInt(JsonValue* handle, const char* key, int* out_value) override; virtual bool ObjectGetInt64(JsonValue* handle, const char* key, std::variant* out_value) override; virtual bool ObjectGetString(JsonValue* handle, const char* key, const char** out_str, size_t* out_len) override; @@ -368,7 +369,7 @@ public: virtual bool ObjectRenameKey(JsonValue* handle, const char* old_key, const char* new_key, bool allow_duplicate) override; virtual bool ObjectSet(JsonValue* handle, const char* key, JsonValue* value) override; virtual bool ObjectSetBool(JsonValue* handle, const char* key, bool value) override; - virtual bool ObjectSetFloat(JsonValue* handle, const char* key, double value) override; + virtual bool ObjectSetDouble(JsonValue* handle, const char* key, double value) override; virtual bool ObjectSetInt(JsonValue* handle, const char* key, int value) override; virtual bool ObjectSetInt64(JsonValue* handle, const char* key, std::variant value) override; virtual bool ObjectSetNull(JsonValue* handle, const char* key) override; @@ -376,6 +377,7 @@ public: virtual bool ObjectRemove(JsonValue* handle, const char* key) override; virtual bool ObjectClear(JsonValue* handle) override; virtual bool ObjectSort(JsonValue* handle, JSON_SORT_ORDER sort_mode) override; + virtual bool ObjectRotate(JsonValue* handle, size_t idx) override; // ========== Array Operations ========== virtual JsonValue* ArrayInit() override; @@ -384,7 +386,7 @@ public: virtual JsonValue* ArrayInitWithInt64(const char** values, size_t count, char* error, size_t error_size) override; virtual JsonValue* ArrayInitWithBool(const bool* values, size_t count) override; - virtual JsonValue* ArrayInitWithFloat(const double* values, size_t count) override; + virtual JsonValue* ArrayInitWithDouble(const double* values, size_t count) override; virtual JsonValue* ArrayParseString(const char* str, yyjson_read_flag read_flg, char* error, size_t error_size) override; virtual JsonValue* ArrayParseFile(const char* path, yyjson_read_flag read_flg, @@ -394,21 +396,21 @@ public: virtual JsonValue* ArrayGetFirst(JsonValue* handle) override; virtual JsonValue* ArrayGetLast(JsonValue* handle) override; virtual bool ArrayGetBool(JsonValue* handle, size_t index, bool* out_value) override; - virtual bool ArrayGetFloat(JsonValue* handle, size_t index, double* out_value) override; + virtual bool ArrayGetDouble(JsonValue* handle, size_t index, double* out_value) override; virtual bool ArrayGetInt(JsonValue* handle, size_t index, int* out_value) override; virtual bool ArrayGetInt64(JsonValue* handle, size_t index, std::variant* out_value) override; virtual bool ArrayGetString(JsonValue* handle, size_t index, const char** out_str, size_t* out_len) override; virtual bool ArrayIsNull(JsonValue* handle, size_t index) override; virtual bool ArrayReplace(JsonValue* handle, size_t index, JsonValue* value) override; virtual bool ArrayReplaceBool(JsonValue* handle, size_t index, bool value) override; - virtual bool ArrayReplaceFloat(JsonValue* handle, size_t index, double value) override; + virtual bool ArrayReplaceDouble(JsonValue* handle, size_t index, double value) override; virtual bool ArrayReplaceInt(JsonValue* handle, size_t index, int value) override; virtual bool ArrayReplaceInt64(JsonValue* handle, size_t index, std::variant value) override; virtual bool ArrayReplaceNull(JsonValue* handle, size_t index) override; virtual bool ArrayReplaceString(JsonValue* handle, size_t index, const char* value) override; virtual bool ArrayAppend(JsonValue* handle, JsonValue* value) override; virtual bool ArrayAppendBool(JsonValue* handle, bool value) override; - virtual bool ArrayAppendFloat(JsonValue* handle, double value) override; + virtual bool ArrayAppendDouble(JsonValue* handle, double value) override; virtual bool ArrayAppendInt(JsonValue* handle, int value) override; virtual bool ArrayAppendInt64(JsonValue* handle, std::variant value) override; virtual bool ArrayAppendNull(JsonValue* handle) override; @@ -417,14 +419,14 @@ public: virtual bool ArrayInsertBool(JsonValue* handle, size_t index, bool value) override; virtual bool ArrayInsertInt(JsonValue* handle, size_t index, int value) override; virtual bool ArrayInsertInt64(JsonValue* handle, size_t index, std::variant value) override; - virtual bool ArrayInsertFloat(JsonValue* handle, size_t index, double value) override; + virtual bool ArrayInsertDouble(JsonValue* handle, size_t index, double value) override; virtual bool ArrayInsertString(JsonValue* handle, size_t index, const char* value) override; virtual bool ArrayInsertNull(JsonValue* handle, size_t index) override; virtual bool ArrayPrepend(JsonValue* handle, JsonValue* value) override; virtual bool ArrayPrependBool(JsonValue* handle, bool value) override; virtual bool ArrayPrependInt(JsonValue* handle, int value) override; virtual bool ArrayPrependInt64(JsonValue* handle, std::variant value) override; - virtual bool ArrayPrependFloat(JsonValue* handle, double value) override; + virtual bool ArrayPrependDouble(JsonValue* handle, double value) override; virtual bool ArrayPrependString(JsonValue* handle, const char* value) override; virtual bool ArrayPrependNull(JsonValue* handle) override; virtual bool ArrayRemove(JsonValue* handle, size_t index) override; @@ -436,19 +438,20 @@ public: virtual int ArrayIndexOfString(JsonValue* handle, const char* search_value) override; virtual int ArrayIndexOfInt(JsonValue* handle, int search_value) override; virtual int ArrayIndexOfInt64(JsonValue* handle, std::variant search_value) override; - virtual int ArrayIndexOfFloat(JsonValue* handle, double search_value) override; + virtual int ArrayIndexOfDouble(JsonValue* handle, double search_value) override; virtual bool ArraySort(JsonValue* handle, JSON_SORT_ORDER sort_mode) override; + virtual bool ArrayRotate(JsonValue* handle, size_t idx) override; // ========== Value Operations ========== virtual JsonValue* Pack(const char* format, IPackParamProvider* param_provider, char* error, size_t error_size) override; virtual JsonValue* CreateBool(bool value) override; - virtual JsonValue* CreateFloat(double value) override; + virtual JsonValue* CreateDouble(double value) override; virtual JsonValue* CreateInt(int value) override; virtual JsonValue* CreateInt64(std::variant value) override; virtual JsonValue* CreateNull() override; virtual JsonValue* CreateString(const char* value) override; virtual bool GetBool(JsonValue* handle, bool* out_value) override; - virtual bool GetFloat(JsonValue* handle, double* out_value) override; + virtual bool GetDouble(JsonValue* handle, double* out_value) override; virtual bool GetInt(JsonValue* handle, int* out_value) override; virtual bool GetInt64(JsonValue* handle, std::variant* out_value) override; virtual bool GetString(JsonValue* handle, const char** out_str, size_t* out_len) override; @@ -456,7 +459,7 @@ public: // ========== Pointer Operations ========== virtual JsonValue* PtrGet(JsonValue* handle, const char* path, char* error, size_t error_size) override; virtual bool PtrGetBool(JsonValue* handle, const char* path, bool* out_value, char* error, size_t error_size) override; - virtual bool PtrGetFloat(JsonValue* handle, const char* path, double* out_value, char* error, size_t error_size) override; + virtual bool PtrGetDouble(JsonValue* handle, const char* path, double* out_value, char* error, size_t error_size) override; virtual bool PtrGetInt(JsonValue* handle, const char* path, int* out_value, char* error, size_t error_size) override; virtual bool PtrGetInt64(JsonValue* handle, const char* path, std::variant* out_value, char* error, size_t error_size) override; virtual bool PtrGetString(JsonValue* handle, const char* path, const char** out_str, size_t* out_len, char* error, size_t error_size) override; @@ -464,14 +467,14 @@ public: virtual bool PtrGetLength(JsonValue* handle, const char* path, size_t* out_len, char* error, size_t error_size) override; virtual bool PtrSet(JsonValue* handle, const char* path, JsonValue* value, char* error, size_t error_size) override; virtual bool PtrSetBool(JsonValue* handle, const char* path, bool value, char* error, size_t error_size) override; - virtual bool PtrSetFloat(JsonValue* handle, const char* path, double value, char* error, size_t error_size) override; + virtual bool PtrSetDouble(JsonValue* handle, const char* path, double value, char* error, size_t error_size) override; virtual bool PtrSetInt(JsonValue* handle, const char* path, int value, char* error, size_t error_size) override; virtual bool PtrSetInt64(JsonValue* handle, const char* path, std::variant value, char* error, size_t error_size) override; virtual bool PtrSetString(JsonValue* handle, const char* path, const char* value, char* error, size_t error_size) override; virtual bool PtrSetNull(JsonValue* handle, const char* path, char* error, size_t error_size) override; virtual bool PtrAdd(JsonValue* handle, const char* path, JsonValue* value, char* error, size_t error_size) override; virtual bool PtrAddBool(JsonValue* handle, const char* path, bool value, char* error, size_t error_size) override; - virtual bool PtrAddFloat(JsonValue* handle, const char* path, double value, char* error, size_t error_size) override; + virtual bool PtrAddDouble(JsonValue* handle, const char* path, double value, char* error, size_t error_size) override; virtual bool PtrAddInt(JsonValue* handle, const char* path, int value, char* error, size_t error_size) override; virtual bool PtrAddInt64(JsonValue* handle, const char* path, std::variant value, char* error, size_t error_size) override; virtual bool PtrAddString(JsonValue* handle, const char* path, const char* value, char* error, size_t error_size) override; @@ -479,7 +482,7 @@ public: virtual bool PtrRemove(JsonValue* handle, const char* path, char* error, size_t error_size) override; virtual JsonValue* PtrTryGet(JsonValue* handle, const char* path) override; virtual bool PtrTryGetBool(JsonValue* handle, const char* path, bool* out_value) override; - virtual bool PtrTryGetFloat(JsonValue* handle, const char* path, double* out_value) override; + virtual bool PtrTryGetDouble(JsonValue* handle, const char* path, double* out_value) override; virtual bool PtrTryGetInt(JsonValue* handle, const char* path, int* out_value) override; virtual bool PtrTryGetInt64(JsonValue* handle, const char* path, std::variant* out_value) override; virtual bool PtrTryGetString(JsonValue* handle, const char* path, const char** out_str, size_t* out_len) override; @@ -512,6 +515,7 @@ public: virtual JsonValue* ObjIterGet(JsonObjIter* iter, const char* key) override; virtual size_t ObjIterGetIndex(JsonObjIter* iter) override; virtual void* ObjIterRemove(JsonObjIter* iter) override; + virtual bool ObjIterGetKeyString(JsonObjIter* iter, void* key, const char** out_str, size_t* out_len = nullptr) override; // ========== Iterator Release Operations ========== virtual void ReleaseArrIter(JsonArrIter* iter) override; @@ -527,10 +531,10 @@ public: virtual void Release(JsonValue* value) override; // ========== Handle Type Operations ========== - virtual HandleType_t GetHandleType() override; + virtual HandleType_t GetJsonHandleType() override; // ========== Handle Operations ========== - virtual JsonValue* GetFromHandle(IPluginContext* pContext, Handle_t handle) override; + virtual JsonValue* GetValueFromHandle(IPluginContext* pContext, Handle_t handle) override; // ========== Number Read/Write Operations ========== virtual JsonValue* ReadNumber(const char* dat, uint32_t read_flg = 0, @@ -546,7 +550,7 @@ public: virtual bool SetBool(JsonValue* handle, bool value) override; virtual bool SetInt(JsonValue* handle, int value) override; virtual bool SetInt64(JsonValue* handle, std::variant value) override; - virtual bool SetFloat(JsonValue* handle, double value) override; + virtual bool SetDouble(JsonValue* handle, double value) override; virtual bool SetString(JsonValue* handle, const char* value) override; virtual bool SetNull(JsonValue* handle) override; diff --git a/extensions/json/JsonNatives.cpp b/extensions/json/JsonNatives.cpp index c964a434e..63f432cef 100755 --- a/extensions/json/JsonNatives.cpp +++ b/extensions/json/JsonNatives.cpp @@ -49,6 +49,35 @@ public: } }; +/** + * Helper function: Convert int64 variant to string + * @param value The variant containing int64_t or uint64_t + * @param buffer Output buffer + * @param buffer_size Size of the buffer + * @return true on success, false on error + */ +static inline bool Int64VariantToString(const std::variant& value, char* buffer, size_t buffer_size) +{ + if (!buffer || buffer_size < 2) { + return false; + } + + std::to_chars_result result; + + if (std::holds_alternative(value)) { + result = std::to_chars(buffer, buffer + buffer_size - 1, std::get(value)); + } else { + result = std::to_chars(buffer, buffer + buffer_size - 1, std::get(value)); + } + + if (result.ec == std::errc()) { + *result.ptr = '\0'; + return true; + } + + return false; +} + /** * Helper function: Create a SourceMod handle for JsonValue and return it directly * Used by functions that return Handle_t @@ -149,18 +178,12 @@ static cell_t CreateAndReturnObjIterHandle(IPluginContext* pContext, JsonObjIter static cell_t json_pack(IPluginContext* pContext, const cell_t* params) { - // SourcePawn has a limit of 32 parameters (defined SP_MAX_EXEC_PARAMS) - // including the format string, so we need to check if the number of parameters is less than the limit - if (params[0] > SP_MAX_EXEC_PARAMS - 1) { - return pContext->ThrowNativeError("Too many parameters (max %d)", SP_MAX_EXEC_PARAMS - 1); - } - char* fmt; pContext->LocalToString(params[1], &fmt); SourceModPackParamProvider provider(pContext, params, 2); - char error[JSON_PACK_ERROR_SIZE]; + char error[JSON_ERROR_BUFFER_SIZE]; JsonValue* pJSONValue = g_pJsonManager->Pack(fmt, &provider, error, sizeof(error)); if (!pJSONValue) { @@ -191,8 +214,8 @@ static cell_t json_doc_parse(IPluginContext* pContext, const cell_t* params) static cell_t json_doc_equals(IPluginContext* pContext, const cell_t* params) { - JsonValue* handle1 = g_pJsonManager->GetFromHandle(pContext, params[1]); - JsonValue* handle2 = g_pJsonManager->GetFromHandle(pContext, params[2]); + JsonValue* handle1 = g_pJsonManager->GetValueFromHandle(pContext, params[1]); + JsonValue* handle2 = g_pJsonManager->GetValueFromHandle(pContext, params[2]); if (!handle1 || !handle2) return 0; @@ -201,8 +224,8 @@ static cell_t json_doc_equals(IPluginContext* pContext, const cell_t* params) static cell_t json_doc_copy_deep(IPluginContext* pContext, const cell_t* params) { - JsonValue* targetDoc = g_pJsonManager->GetFromHandle(pContext, params[1]); - JsonValue* sourceValue = g_pJsonManager->GetFromHandle(pContext, params[2]); + JsonValue* targetDoc = g_pJsonManager->GetValueFromHandle(pContext, params[1]); + JsonValue* sourceValue = g_pJsonManager->GetValueFromHandle(pContext, params[2]); if (!targetDoc || !sourceValue) return 0; @@ -217,7 +240,7 @@ static cell_t json_doc_copy_deep(IPluginContext* pContext, const cell_t* params) static cell_t json_get_type_desc(IPluginContext* pContext, const cell_t* params) { - JsonValue* handle = g_pJsonManager->GetFromHandle(pContext, params[1]); + JsonValue* handle = g_pJsonManager->GetValueFromHandle(pContext, params[1]); if (!handle) return 0; @@ -233,7 +256,7 @@ static cell_t json_obj_parse_str(IPluginContext* pContext, const cell_t* params) pContext->LocalToString(params[1], &str); uint32_t read_flg = static_cast(params[2]); - char error[JSON_PACK_ERROR_SIZE]; + char error[JSON_ERROR_BUFFER_SIZE]; JsonValue* pJSONValue = g_pJsonManager->ObjectParseString(str, read_flg, error, sizeof(error)); if (!pJSONValue) { @@ -249,7 +272,7 @@ static cell_t json_obj_parse_file(IPluginContext* pContext, const cell_t* params pContext->LocalToString(params[1], &path); uint32_t read_flg = static_cast(params[2]); - char error[JSON_PACK_ERROR_SIZE]; + char error[JSON_ERROR_BUFFER_SIZE]; JsonValue* pJSONValue = g_pJsonManager->ObjectParseFile(path, read_flg, error, sizeof(error)); if (!pJSONValue) { @@ -265,7 +288,7 @@ static cell_t json_arr_parse_str(IPluginContext* pContext, const cell_t* params) pContext->LocalToString(params[1], &str); uint32_t read_flg = static_cast(params[2]); - char error[JSON_PACK_ERROR_SIZE]; + char error[JSON_ERROR_BUFFER_SIZE]; JsonValue* pJSONValue = g_pJsonManager->ArrayParseString(str, read_flg, error, sizeof(error)); if (!pJSONValue) { @@ -281,7 +304,7 @@ static cell_t json_arr_parse_file(IPluginContext* pContext, const cell_t* params pContext->LocalToString(params[1], &path); uint32_t read_flg = static_cast(params[2]); - char error[JSON_PACK_ERROR_SIZE]; + char error[JSON_ERROR_BUFFER_SIZE]; JsonValue* pJSONValue = g_pJsonManager->ArrayParseFile(path, read_flg, error, sizeof(error)); if (!pJSONValue) { @@ -293,7 +316,7 @@ static cell_t json_arr_parse_file(IPluginContext* pContext, const cell_t* params static cell_t json_arr_index_of_bool(IPluginContext *pContext, const cell_t *params) { - JsonValue *handle = g_pJsonManager->GetFromHandle(pContext, params[1]); + JsonValue *handle = g_pJsonManager->GetValueFromHandle(pContext, params[1]); if (!handle) return 0; @@ -303,7 +326,7 @@ static cell_t json_arr_index_of_bool(IPluginContext *pContext, const cell_t *par static cell_t json_arr_index_of_str(IPluginContext* pContext, const cell_t* params) { - JsonValue* handle = g_pJsonManager->GetFromHandle(pContext, params[1]); + JsonValue* handle = g_pJsonManager->GetValueFromHandle(pContext, params[1]); if (!handle) return 0; @@ -315,7 +338,7 @@ static cell_t json_arr_index_of_str(IPluginContext* pContext, const cell_t* para static cell_t json_arr_index_of_int(IPluginContext* pContext, const cell_t* params) { - JsonValue* handle = g_pJsonManager->GetFromHandle(pContext, params[1]); + JsonValue* handle = g_pJsonManager->GetValueFromHandle(pContext, params[1]); if (!handle) return 0; @@ -325,7 +348,7 @@ static cell_t json_arr_index_of_int(IPluginContext* pContext, const cell_t* para static cell_t json_arr_index_of_integer64(IPluginContext* pContext, const cell_t* params) { - JsonValue* handle = g_pJsonManager->GetFromHandle(pContext, params[1]); + JsonValue* handle = g_pJsonManager->GetValueFromHandle(pContext, params[1]); if (!handle) return 0; @@ -344,17 +367,16 @@ static cell_t json_arr_index_of_integer64(IPluginContext* pContext, const cell_t static cell_t json_arr_index_of_float(IPluginContext* pContext, const cell_t* params) { - JsonValue* handle = g_pJsonManager->GetFromHandle(pContext, params[1]); + JsonValue* handle = g_pJsonManager->GetValueFromHandle(pContext, params[1]); if (!handle) return 0; - float searchValue = sp_ctof(params[2]); - return g_pJsonManager->ArrayIndexOfFloat(handle, searchValue); + return g_pJsonManager->ArrayIndexOfDouble(handle, sp_ctof(params[2])); } static cell_t json_get_type(IPluginContext* pContext, const cell_t* params) { - JsonValue* handle = g_pJsonManager->GetFromHandle(pContext, params[1]); + JsonValue* handle = g_pJsonManager->GetValueFromHandle(pContext, params[1]); if (!handle) return 0; @@ -363,7 +385,7 @@ static cell_t json_get_type(IPluginContext* pContext, const cell_t* params) static cell_t json_get_subtype(IPluginContext* pContext, const cell_t* params) { - JsonValue* handle = g_pJsonManager->GetFromHandle(pContext, params[1]); + JsonValue* handle = g_pJsonManager->GetValueFromHandle(pContext, params[1]); if (!handle) return 0; @@ -372,7 +394,7 @@ static cell_t json_get_subtype(IPluginContext* pContext, const cell_t* params) static cell_t json_is_array(IPluginContext* pContext, const cell_t* params) { - JsonValue* handle = g_pJsonManager->GetFromHandle(pContext, params[1]); + JsonValue* handle = g_pJsonManager->GetValueFromHandle(pContext, params[1]); if (!handle) return 0; @@ -381,7 +403,7 @@ static cell_t json_is_array(IPluginContext* pContext, const cell_t* params) static cell_t json_is_object(IPluginContext* pContext, const cell_t* params) { - JsonValue* handle = g_pJsonManager->GetFromHandle(pContext, params[1]); + JsonValue* handle = g_pJsonManager->GetValueFromHandle(pContext, params[1]); if (!handle) return 0; @@ -390,7 +412,7 @@ static cell_t json_is_object(IPluginContext* pContext, const cell_t* params) static cell_t json_is_int(IPluginContext* pContext, const cell_t* params) { - JsonValue* handle = g_pJsonManager->GetFromHandle(pContext, params[1]); + JsonValue* handle = g_pJsonManager->GetValueFromHandle(pContext, params[1]); if (!handle) return 0; @@ -399,7 +421,7 @@ static cell_t json_is_int(IPluginContext* pContext, const cell_t* params) static cell_t json_is_uint(IPluginContext* pContext, const cell_t* params) { - JsonValue* handle = g_pJsonManager->GetFromHandle(pContext, params[1]); + JsonValue* handle = g_pJsonManager->GetValueFromHandle(pContext, params[1]); if (!handle) return 0; @@ -408,7 +430,7 @@ static cell_t json_is_uint(IPluginContext* pContext, const cell_t* params) static cell_t json_is_sint(IPluginContext* pContext, const cell_t* params) { - JsonValue* handle = g_pJsonManager->GetFromHandle(pContext, params[1]); + JsonValue* handle = g_pJsonManager->GetValueFromHandle(pContext, params[1]); if (!handle) return 0; @@ -417,7 +439,7 @@ static cell_t json_is_sint(IPluginContext* pContext, const cell_t* params) static cell_t json_is_num(IPluginContext* pContext, const cell_t* params) { - JsonValue* handle = g_pJsonManager->GetFromHandle(pContext, params[1]); + JsonValue* handle = g_pJsonManager->GetValueFromHandle(pContext, params[1]); if (!handle) return 0; @@ -426,7 +448,7 @@ static cell_t json_is_num(IPluginContext* pContext, const cell_t* params) static cell_t json_is_bool(IPluginContext* pContext, const cell_t* params) { - JsonValue* handle = g_pJsonManager->GetFromHandle(pContext, params[1]); + JsonValue* handle = g_pJsonManager->GetValueFromHandle(pContext, params[1]); if (!handle) return 0; @@ -435,7 +457,7 @@ static cell_t json_is_bool(IPluginContext* pContext, const cell_t* params) static cell_t json_is_true(IPluginContext* pContext, const cell_t* params) { - JsonValue* handle = g_pJsonManager->GetFromHandle(pContext, params[1]); + JsonValue* handle = g_pJsonManager->GetValueFromHandle(pContext, params[1]); if (!handle) return 0; @@ -444,7 +466,7 @@ static cell_t json_is_true(IPluginContext* pContext, const cell_t* params) static cell_t json_is_false(IPluginContext* pContext, const cell_t* params) { - JsonValue* handle = g_pJsonManager->GetFromHandle(pContext, params[1]); + JsonValue* handle = g_pJsonManager->GetValueFromHandle(pContext, params[1]); if (!handle) return 0; @@ -453,7 +475,7 @@ static cell_t json_is_false(IPluginContext* pContext, const cell_t* params) static cell_t json_is_float(IPluginContext* pContext, const cell_t* params) { - JsonValue* handle = g_pJsonManager->GetFromHandle(pContext, params[1]); + JsonValue* handle = g_pJsonManager->GetValueFromHandle(pContext, params[1]); if (!handle) return 0; @@ -462,7 +484,7 @@ static cell_t json_is_float(IPluginContext* pContext, const cell_t* params) static cell_t json_is_str(IPluginContext* pContext, const cell_t* params) { - JsonValue* handle = g_pJsonManager->GetFromHandle(pContext, params[1]); + JsonValue* handle = g_pJsonManager->GetValueFromHandle(pContext, params[1]); if (!handle) return 0; @@ -471,7 +493,7 @@ static cell_t json_is_str(IPluginContext* pContext, const cell_t* params) static cell_t json_is_null(IPluginContext* pContext, const cell_t* params) { - JsonValue* handle = g_pJsonManager->GetFromHandle(pContext, params[1]); + JsonValue* handle = g_pJsonManager->GetValueFromHandle(pContext, params[1]); if (!handle) return 0; @@ -480,7 +502,7 @@ static cell_t json_is_null(IPluginContext* pContext, const cell_t* params) static cell_t json_is_ctn(IPluginContext* pContext, const cell_t* params) { - JsonValue* handle = g_pJsonManager->GetFromHandle(pContext, params[1]); + JsonValue* handle = g_pJsonManager->GetValueFromHandle(pContext, params[1]); if (!handle) return 0; @@ -489,7 +511,7 @@ static cell_t json_is_ctn(IPluginContext* pContext, const cell_t* params) static cell_t json_is_mutable(IPluginContext* pContext, const cell_t* params) { - JsonValue* handle = g_pJsonManager->GetFromHandle(pContext, params[1]); + JsonValue* handle = g_pJsonManager->GetValueFromHandle(pContext, params[1]); if (!handle) return 0; @@ -498,7 +520,7 @@ static cell_t json_is_mutable(IPluginContext* pContext, const cell_t* params) static cell_t json_is_immutable(IPluginContext* pContext, const cell_t* params) { - JsonValue* handle = g_pJsonManager->GetFromHandle(pContext, params[1]); + JsonValue* handle = g_pJsonManager->GetValueFromHandle(pContext, params[1]); if (!handle) return 0; @@ -566,7 +588,7 @@ static cell_t json_create_bool(IPluginContext* pContext, const cell_t* params) static cell_t json_create_float(IPluginContext* pContext, const cell_t* params) { - JsonValue* pJSONValue = g_pJsonManager->CreateFloat(sp_ctof(params[1])); + JsonValue* pJSONValue = g_pJsonManager->CreateDouble(sp_ctof(params[1])); return CreateAndReturnHandle(pContext, pJSONValue, "JSON float value"); } @@ -613,7 +635,7 @@ static cell_t json_create_str(IPluginContext* pContext, const cell_t* params) static cell_t json_get_bool(IPluginContext* pContext, const cell_t* params) { - JsonValue* handle = g_pJsonManager->GetFromHandle(pContext, params[1]); + JsonValue* handle = g_pJsonManager->GetValueFromHandle(pContext, params[1]); if (!handle) return 0; @@ -627,12 +649,12 @@ static cell_t json_get_bool(IPluginContext* pContext, const cell_t* params) static cell_t json_get_float(IPluginContext* pContext, const cell_t* params) { - JsonValue* handle = g_pJsonManager->GetFromHandle(pContext, params[1]); + JsonValue* handle = g_pJsonManager->GetValueFromHandle(pContext, params[1]); if (!handle) return 0; double value; - if (!g_pJsonManager->GetFloat(handle, &value)) { + if (!g_pJsonManager->GetDouble(handle, &value)) { return pContext->ThrowNativeError("Type mismatch: expected float value"); } @@ -641,7 +663,7 @@ static cell_t json_get_float(IPluginContext* pContext, const cell_t* params) static cell_t json_get_int(IPluginContext* pContext, const cell_t* params) { - JsonValue* handle = g_pJsonManager->GetFromHandle(pContext, params[1]); + JsonValue* handle = g_pJsonManager->GetValueFromHandle(pContext, params[1]); if (!handle) return 0; @@ -655,7 +677,7 @@ static cell_t json_get_int(IPluginContext* pContext, const cell_t* params) static cell_t json_get_integer64(IPluginContext* pContext, const cell_t* params) { - JsonValue* handle = g_pJsonManager->GetFromHandle(pContext, params[1]); + JsonValue* handle = g_pJsonManager->GetValueFromHandle(pContext, params[1]); if (!handle) return 0; @@ -665,10 +687,8 @@ static cell_t json_get_integer64(IPluginContext* pContext, const cell_t* params) } char result[JSON_INT64_BUFFER_SIZE]; - if (std::holds_alternative(value)) { - snprintf(result, sizeof(result), "%" PRIu64, std::get(value)); - } else { - snprintf(result, sizeof(result), "%" PRId64, std::get(value)); + if (!Int64VariantToString(value, result, sizeof(result))) { + return pContext->ThrowNativeError("Failed to convert integer64 to string"); } pContext->StringToLocalUTF8(params[2], params[3], result, nullptr); @@ -677,7 +697,7 @@ static cell_t json_get_integer64(IPluginContext* pContext, const cell_t* params) static cell_t json_get_str(IPluginContext* pContext, const cell_t* params) { - JsonValue* handle = g_pJsonManager->GetFromHandle(pContext, params[1]); + JsonValue* handle = g_pJsonManager->GetValueFromHandle(pContext, params[1]); if (!handle) return 0; @@ -701,7 +721,7 @@ static cell_t json_get_str(IPluginContext* pContext, const cell_t* params) static cell_t json_equals_str(IPluginContext* pContext, const cell_t* params) { - JsonValue* handle = g_pJsonManager->GetFromHandle(pContext, params[1]); + JsonValue* handle = g_pJsonManager->GetValueFromHandle(pContext, params[1]); if (!handle) return 0; char* str; @@ -712,7 +732,7 @@ static cell_t json_equals_str(IPluginContext* pContext, const cell_t* params) static cell_t json_get_serialized_size(IPluginContext* pContext, const cell_t* params) { - JsonValue* handle = g_pJsonManager->GetFromHandle(pContext, params[1]); + JsonValue* handle = g_pJsonManager->GetValueFromHandle(pContext, params[1]); if (!handle) return 0; @@ -724,7 +744,7 @@ static cell_t json_get_serialized_size(IPluginContext* pContext, const cell_t* p static cell_t json_get_read_size(IPluginContext* pContext, const cell_t* params) { - JsonValue* handle = g_pJsonManager->GetFromHandle(pContext, params[1]); + JsonValue* handle = g_pJsonManager->GetValueFromHandle(pContext, params[1]); if (!handle) return 0; @@ -736,13 +756,22 @@ static cell_t json_get_read_size(IPluginContext* pContext, const cell_t* params) static cell_t json_get_ref_count(IPluginContext* pContext, const cell_t* params) { - JsonValue* handle = g_pJsonManager->GetFromHandle(pContext, params[1]); + JsonValue* handle = g_pJsonManager->GetValueFromHandle(pContext, params[1]); if (!handle) return 0; return g_pJsonManager->GetRefCount(handle); } +static cell_t json_get_val_count(IPluginContext* pContext, const cell_t* params) +{ + JsonValue* handle = g_pJsonManager->GetValueFromHandle(pContext, params[1]); + + if (!handle) return 0; + + return g_pJsonManager->GetValCount(handle); +} + static cell_t json_create_null(IPluginContext* pContext, const cell_t* params) { JsonValue* pJSONValue = g_pJsonManager->CreateNull(); @@ -861,7 +890,7 @@ static cell_t json_arr_init_with_float(IPluginContext* pContext, const cell_t* p values.push_back(sp_ctof(addr[i])); } - JsonValue* pJSONValue = g_pJsonManager->ArrayInitWithFloat(values.data(), values.size()); + JsonValue* pJSONValue = g_pJsonManager->ArrayInitWithDouble(values.data(), values.size()); if (!pJSONValue) { return pContext->ThrowNativeError("Failed to create JSON array from float values"); @@ -872,7 +901,7 @@ static cell_t json_arr_init_with_float(IPluginContext* pContext, const cell_t* p static cell_t json_arr_get_size(IPluginContext* pContext, const cell_t* params) { - JsonValue* handle = g_pJsonManager->GetFromHandle(pContext, params[1]); + JsonValue* handle = g_pJsonManager->GetValueFromHandle(pContext, params[1]); if (!handle) return 0; @@ -882,7 +911,7 @@ static cell_t json_arr_get_size(IPluginContext* pContext, const cell_t* params) static cell_t json_arr_get_val(IPluginContext* pContext, const cell_t* params) { - JsonValue* handle = g_pJsonManager->GetFromHandle(pContext, params[1]); + JsonValue* handle = g_pJsonManager->GetValueFromHandle(pContext, params[1]); if (!handle) return 0; @@ -903,7 +932,7 @@ static cell_t json_arr_get_val(IPluginContext* pContext, const cell_t* params) static cell_t json_arr_get_first(IPluginContext* pContext, const cell_t* params) { - JsonValue* handle = g_pJsonManager->GetFromHandle(pContext, params[1]); + JsonValue* handle = g_pJsonManager->GetValueFromHandle(pContext, params[1]); if (!handle) return 0; @@ -918,7 +947,7 @@ static cell_t json_arr_get_first(IPluginContext* pContext, const cell_t* params) static cell_t json_arr_get_last(IPluginContext* pContext, const cell_t* params) { - JsonValue* handle = g_pJsonManager->GetFromHandle(pContext, params[1]); + JsonValue* handle = g_pJsonManager->GetValueFromHandle(pContext, params[1]); if (!handle) return 0; @@ -933,7 +962,7 @@ static cell_t json_arr_get_last(IPluginContext* pContext, const cell_t* params) static cell_t json_arr_get_bool(IPluginContext* pContext, const cell_t* params) { - JsonValue* handle = g_pJsonManager->GetFromHandle(pContext, params[1]); + JsonValue* handle = g_pJsonManager->GetValueFromHandle(pContext, params[1]); if (!handle) return 0; @@ -953,7 +982,7 @@ static cell_t json_arr_get_bool(IPluginContext* pContext, const cell_t* params) static cell_t json_arr_get_float(IPluginContext* pContext, const cell_t* params) { - JsonValue* handle = g_pJsonManager->GetFromHandle(pContext, params[1]); + JsonValue* handle = g_pJsonManager->GetValueFromHandle(pContext, params[1]); if (!handle) return 0; @@ -964,7 +993,7 @@ static cell_t json_arr_get_float(IPluginContext* pContext, const cell_t* params) size_t index = static_cast(index_param); double value; - if (!g_pJsonManager->ArrayGetFloat(handle, index, &value)) { + if (!g_pJsonManager->ArrayGetDouble(handle, index, &value)) { return pContext->ThrowNativeError("Failed to get float at index %d", index); } @@ -973,7 +1002,7 @@ static cell_t json_arr_get_float(IPluginContext* pContext, const cell_t* params) static cell_t json_arr_get_integer(IPluginContext* pContext, const cell_t* params) { - JsonValue* handle = g_pJsonManager->GetFromHandle(pContext, params[1]); + JsonValue* handle = g_pJsonManager->GetValueFromHandle(pContext, params[1]); if (!handle) return 0; @@ -993,7 +1022,7 @@ static cell_t json_arr_get_integer(IPluginContext* pContext, const cell_t* param static cell_t json_arr_get_integer64(IPluginContext* pContext, const cell_t* params) { - JsonValue* handle = g_pJsonManager->GetFromHandle(pContext, params[1]); + JsonValue* handle = g_pJsonManager->GetValueFromHandle(pContext, params[1]); if (!handle) return 0; @@ -1009,10 +1038,8 @@ static cell_t json_arr_get_integer64(IPluginContext* pContext, const cell_t* par } char result[JSON_INT64_BUFFER_SIZE]; - if (std::holds_alternative(value)) { - snprintf(result, sizeof(result), "%" PRIu64, std::get(value)); - } else { - snprintf(result, sizeof(result), "%" PRId64, std::get(value)); + if (!Int64VariantToString(value, result, sizeof(result))) { + return pContext->ThrowNativeError("Failed to convert integer64 to string"); } pContext->StringToLocalUTF8(params[3], params[4], result, nullptr); @@ -1021,7 +1048,7 @@ static cell_t json_arr_get_integer64(IPluginContext* pContext, const cell_t* par static cell_t json_arr_get_str(IPluginContext* pContext, const cell_t* params) { - JsonValue* handle = g_pJsonManager->GetFromHandle(pContext, params[1]); + JsonValue* handle = g_pJsonManager->GetValueFromHandle(pContext, params[1]); if (!handle) return 0; @@ -1049,7 +1076,7 @@ static cell_t json_arr_get_str(IPluginContext* pContext, const cell_t* params) static cell_t json_arr_is_null(IPluginContext* pContext, const cell_t* params) { - JsonValue* handle = g_pJsonManager->GetFromHandle(pContext, params[1]); + JsonValue* handle = g_pJsonManager->GetValueFromHandle(pContext, params[1]); if (!handle) return 0; @@ -1064,8 +1091,8 @@ static cell_t json_arr_is_null(IPluginContext* pContext, const cell_t* params) static cell_t json_arr_replace_val(IPluginContext* pContext, const cell_t* params) { - JsonValue* handle1 = g_pJsonManager->GetFromHandle(pContext, params[1]); - JsonValue* handle2 = g_pJsonManager->GetFromHandle(pContext, params[3]); + JsonValue* handle1 = g_pJsonManager->GetValueFromHandle(pContext, params[1]); + JsonValue* handle2 = g_pJsonManager->GetValueFromHandle(pContext, params[3]); if (!handle1 || !handle2) return 0; @@ -1084,7 +1111,7 @@ static cell_t json_arr_replace_val(IPluginContext* pContext, const cell_t* param static cell_t json_arr_replace_bool(IPluginContext* pContext, const cell_t* params) { - JsonValue* handle = g_pJsonManager->GetFromHandle(pContext, params[1]); + JsonValue* handle = g_pJsonManager->GetValueFromHandle(pContext, params[1]); if (!handle) return 0; @@ -1103,7 +1130,7 @@ static cell_t json_arr_replace_bool(IPluginContext* pContext, const cell_t* para static cell_t json_arr_replace_float(IPluginContext* pContext, const cell_t* params) { - JsonValue* handle = g_pJsonManager->GetFromHandle(pContext, params[1]); + JsonValue* handle = g_pJsonManager->GetValueFromHandle(pContext, params[1]); if (!handle) return 0; @@ -1117,12 +1144,12 @@ static cell_t json_arr_replace_float(IPluginContext* pContext, const cell_t* par } size_t index = static_cast(index_param); - return g_pJsonManager->ArrayReplaceFloat(handle, index, sp_ctof(params[3])); + return g_pJsonManager->ArrayReplaceDouble(handle, index, sp_ctof(params[3])); } static cell_t json_arr_replace_integer(IPluginContext* pContext, const cell_t* params) { - JsonValue* handle = g_pJsonManager->GetFromHandle(pContext, params[1]); + JsonValue* handle = g_pJsonManager->GetValueFromHandle(pContext, params[1]); if (!handle) return 0; @@ -1141,7 +1168,7 @@ static cell_t json_arr_replace_integer(IPluginContext* pContext, const cell_t* p static cell_t json_arr_replace_integer64(IPluginContext* pContext, const cell_t* params) { - JsonValue* handle = g_pJsonManager->GetFromHandle(pContext, params[1]); + JsonValue* handle = g_pJsonManager->GetValueFromHandle(pContext, params[1]); if (!handle) return 0; @@ -1170,7 +1197,7 @@ static cell_t json_arr_replace_integer64(IPluginContext* pContext, const cell_t* static cell_t json_arr_replace_null(IPluginContext* pContext, const cell_t* params) { - JsonValue* handle = g_pJsonManager->GetFromHandle(pContext, params[1]); + JsonValue* handle = g_pJsonManager->GetValueFromHandle(pContext, params[1]); if (!handle) return 0; @@ -1189,7 +1216,7 @@ static cell_t json_arr_replace_null(IPluginContext* pContext, const cell_t* para static cell_t json_arr_replace_str(IPluginContext* pContext, const cell_t* params) { - JsonValue* handle = g_pJsonManager->GetFromHandle(pContext, params[1]); + JsonValue* handle = g_pJsonManager->GetValueFromHandle(pContext, params[1]); if (!handle) return 0; @@ -1211,8 +1238,8 @@ static cell_t json_arr_replace_str(IPluginContext* pContext, const cell_t* param static cell_t json_arr_append_val(IPluginContext* pContext, const cell_t* params) { - JsonValue* handle1 = g_pJsonManager->GetFromHandle(pContext, params[1]); - JsonValue* handle2 = g_pJsonManager->GetFromHandle(pContext, params[2]); + JsonValue* handle1 = g_pJsonManager->GetValueFromHandle(pContext, params[1]); + JsonValue* handle2 = g_pJsonManager->GetValueFromHandle(pContext, params[2]); if (!handle1 || !handle2) return 0; @@ -1225,7 +1252,7 @@ static cell_t json_arr_append_val(IPluginContext* pContext, const cell_t* params static cell_t json_arr_append_bool(IPluginContext* pContext, const cell_t* params) { - JsonValue* handle = g_pJsonManager->GetFromHandle(pContext, params[1]); + JsonValue* handle = g_pJsonManager->GetValueFromHandle(pContext, params[1]); if (!handle) return 0; @@ -1238,7 +1265,7 @@ static cell_t json_arr_append_bool(IPluginContext* pContext, const cell_t* param static cell_t json_arr_append_float(IPluginContext* pContext, const cell_t* params) { - JsonValue* handle = g_pJsonManager->GetFromHandle(pContext, params[1]); + JsonValue* handle = g_pJsonManager->GetValueFromHandle(pContext, params[1]); if (!handle) return 0; @@ -1246,12 +1273,12 @@ static cell_t json_arr_append_float(IPluginContext* pContext, const cell_t* para return pContext->ThrowNativeError("Cannot append value to an immutable JSON array"); } - return g_pJsonManager->ArrayAppendFloat(handle, sp_ctof(params[2])); + return g_pJsonManager->ArrayAppendDouble(handle, sp_ctof(params[2])); } static cell_t json_arr_append_int(IPluginContext* pContext, const cell_t* params) { - JsonValue* handle = g_pJsonManager->GetFromHandle(pContext, params[1]); + JsonValue* handle = g_pJsonManager->GetValueFromHandle(pContext, params[1]); if (!handle) return 0; @@ -1264,7 +1291,7 @@ static cell_t json_arr_append_int(IPluginContext* pContext, const cell_t* params static cell_t json_arr_append_integer64(IPluginContext* pContext, const cell_t* params) { - JsonValue* handle = g_pJsonManager->GetFromHandle(pContext, params[1]); + JsonValue* handle = g_pJsonManager->GetValueFromHandle(pContext, params[1]); if (!handle) return 0; @@ -1287,7 +1314,7 @@ static cell_t json_arr_append_integer64(IPluginContext* pContext, const cell_t* static cell_t json_arr_append_null(IPluginContext* pContext, const cell_t* params) { - JsonValue* handle = g_pJsonManager->GetFromHandle(pContext, params[1]); + JsonValue* handle = g_pJsonManager->GetValueFromHandle(pContext, params[1]); if (!handle) return 0; @@ -1300,7 +1327,7 @@ static cell_t json_arr_append_null(IPluginContext* pContext, const cell_t* param static cell_t json_arr_append_str(IPluginContext* pContext, const cell_t* params) { - JsonValue* handle = g_pJsonManager->GetFromHandle(pContext, params[1]); + JsonValue* handle = g_pJsonManager->GetValueFromHandle(pContext, params[1]); if (!handle) return 0; @@ -1316,7 +1343,7 @@ static cell_t json_arr_append_str(IPluginContext* pContext, const cell_t* params static cell_t json_arr_insert(IPluginContext* pContext, const cell_t* params) { - JsonValue* handle = g_pJsonManager->GetFromHandle(pContext, params[1]); + JsonValue* handle = g_pJsonManager->GetValueFromHandle(pContext, params[1]); if (!handle) return 0; if (!handle->IsMutable()) { @@ -1334,7 +1361,7 @@ static cell_t json_arr_insert(IPluginContext* pContext, const cell_t* params) return pContext->ThrowNativeError("Index is out of bounds (got %d, max %zu)", index, arr_size); } - JsonValue* value = g_pJsonManager->GetFromHandle(pContext, params[3]); + JsonValue* value = g_pJsonManager->GetValueFromHandle(pContext, params[3]); if (!value) return 0; return g_pJsonManager->ArrayInsert(handle, index, value); @@ -1342,7 +1369,7 @@ static cell_t json_arr_insert(IPluginContext* pContext, const cell_t* params) static cell_t json_arr_insert_bool(IPluginContext* pContext, const cell_t* params) { - JsonValue* handle = g_pJsonManager->GetFromHandle(pContext, params[1]); + JsonValue* handle = g_pJsonManager->GetValueFromHandle(pContext, params[1]); if (!handle) return 0; if (!handle->IsMutable()) { @@ -1367,7 +1394,7 @@ static cell_t json_arr_insert_bool(IPluginContext* pContext, const cell_t* param static cell_t json_arr_insert_int(IPluginContext* pContext, const cell_t* params) { - JsonValue* handle = g_pJsonManager->GetFromHandle(pContext, params[1]); + JsonValue* handle = g_pJsonManager->GetValueFromHandle(pContext, params[1]); if (!handle) return 0; if (!handle->IsMutable()) { @@ -1392,7 +1419,7 @@ static cell_t json_arr_insert_int(IPluginContext* pContext, const cell_t* params static cell_t json_arr_insert_int64(IPluginContext* pContext, const cell_t* params) { - JsonValue* handle = g_pJsonManager->GetFromHandle(pContext, params[1]); + JsonValue* handle = g_pJsonManager->GetValueFromHandle(pContext, params[1]); if (!handle) return 0; if (!handle->IsMutable()) { @@ -1425,7 +1452,7 @@ static cell_t json_arr_insert_int64(IPluginContext* pContext, const cell_t* para static cell_t json_arr_insert_float(IPluginContext* pContext, const cell_t* params) { - JsonValue* handle = g_pJsonManager->GetFromHandle(pContext, params[1]); + JsonValue* handle = g_pJsonManager->GetValueFromHandle(pContext, params[1]); if (!handle) return 0; if (!handle->IsMutable()) { @@ -1443,14 +1470,12 @@ static cell_t json_arr_insert_float(IPluginContext* pContext, const cell_t* para return pContext->ThrowNativeError("Index is out of bounds (got %d, max %zu)", index, arr_size); } - float value = sp_ctof(params[3]); - - return g_pJsonManager->ArrayInsertFloat(handle, index, value); + return g_pJsonManager->ArrayInsertDouble(handle, index, sp_ctof(params[3])); } static cell_t json_arr_insert_str(IPluginContext* pContext, const cell_t* params) { - JsonValue* handle = g_pJsonManager->GetFromHandle(pContext, params[1]); + JsonValue* handle = g_pJsonManager->GetValueFromHandle(pContext, params[1]); if (!handle) return 0; if (!handle->IsMutable()) { @@ -1476,7 +1501,7 @@ static cell_t json_arr_insert_str(IPluginContext* pContext, const cell_t* params static cell_t json_arr_insert_null(IPluginContext* pContext, const cell_t* params) { - JsonValue* handle = g_pJsonManager->GetFromHandle(pContext, params[1]); + JsonValue* handle = g_pJsonManager->GetValueFromHandle(pContext, params[1]); if (!handle) return 0; if (!handle->IsMutable()) { @@ -1494,20 +1519,19 @@ static cell_t json_arr_insert_null(IPluginContext* pContext, const cell_t* param return pContext->ThrowNativeError("Index is out of bounds (got %d, max %zu)", index, arr_size); } - return g_pJsonManager->ArrayInsertNull(handle, index); } static cell_t json_arr_prepend(IPluginContext* pContext, const cell_t* params) { - JsonValue* handle = g_pJsonManager->GetFromHandle(pContext, params[1]); + JsonValue* handle = g_pJsonManager->GetValueFromHandle(pContext, params[1]); if (!handle) return 0; if (!handle->IsMutable()) { return pContext->ThrowNativeError("Cannot prepend value to an immutable JSON array"); } - JsonValue* value = g_pJsonManager->GetFromHandle(pContext, params[2]); + JsonValue* value = g_pJsonManager->GetValueFromHandle(pContext, params[2]); if (!value) return 0; return g_pJsonManager->ArrayPrepend(handle, value); @@ -1515,7 +1539,7 @@ static cell_t json_arr_prepend(IPluginContext* pContext, const cell_t* params) static cell_t json_arr_prepend_bool(IPluginContext* pContext, const cell_t* params) { - JsonValue* handle = g_pJsonManager->GetFromHandle(pContext, params[1]); + JsonValue* handle = g_pJsonManager->GetValueFromHandle(pContext, params[1]); if (!handle) return 0; if (!handle->IsMutable()) { @@ -1529,7 +1553,7 @@ static cell_t json_arr_prepend_bool(IPluginContext* pContext, const cell_t* para static cell_t json_arr_prepend_int(IPluginContext* pContext, const cell_t* params) { - JsonValue* handle = g_pJsonManager->GetFromHandle(pContext, params[1]); + JsonValue* handle = g_pJsonManager->GetValueFromHandle(pContext, params[1]); if (!handle) return 0; if (!handle->IsMutable()) { @@ -1543,7 +1567,7 @@ static cell_t json_arr_prepend_int(IPluginContext* pContext, const cell_t* param static cell_t json_arr_prepend_int64(IPluginContext* pContext, const cell_t* params) { - JsonValue* handle = g_pJsonManager->GetFromHandle(pContext, params[1]); + JsonValue* handle = g_pJsonManager->GetValueFromHandle(pContext, params[1]); if (!handle) return 0; if (!handle->IsMutable()) { @@ -1565,21 +1589,19 @@ static cell_t json_arr_prepend_int64(IPluginContext* pContext, const cell_t* par static cell_t json_arr_prepend_float(IPluginContext* pContext, const cell_t* params) { - JsonValue* handle = g_pJsonManager->GetFromHandle(pContext, params[1]); + JsonValue* handle = g_pJsonManager->GetValueFromHandle(pContext, params[1]); if (!handle) return 0; if (!handle->IsMutable()) { return pContext->ThrowNativeError("Cannot prepend value to an immutable JSON array"); } - float value = sp_ctof(params[2]); - - return g_pJsonManager->ArrayPrependFloat(handle, value); + return g_pJsonManager->ArrayPrependDouble(handle, sp_ctof(params[2])); } static cell_t json_arr_prepend_str(IPluginContext* pContext, const cell_t* params) { - JsonValue* handle = g_pJsonManager->GetFromHandle(pContext, params[1]); + JsonValue* handle = g_pJsonManager->GetValueFromHandle(pContext, params[1]); if (!handle) return 0; if (!handle->IsMutable()) { @@ -1594,7 +1616,7 @@ static cell_t json_arr_prepend_str(IPluginContext* pContext, const cell_t* param static cell_t json_arr_prepend_null(IPluginContext* pContext, const cell_t* params) { - JsonValue* handle = g_pJsonManager->GetFromHandle(pContext, params[1]); + JsonValue* handle = g_pJsonManager->GetValueFromHandle(pContext, params[1]); if (!handle) return 0; if (!handle->IsMutable()) { @@ -1606,7 +1628,7 @@ static cell_t json_arr_prepend_null(IPluginContext* pContext, const cell_t* para static cell_t json_arr_remove(IPluginContext* pContext, const cell_t* params) { - JsonValue* handle = g_pJsonManager->GetFromHandle(pContext, params[1]); + JsonValue* handle = g_pJsonManager->GetValueFromHandle(pContext, params[1]); if (!handle) return 0; @@ -1625,7 +1647,7 @@ static cell_t json_arr_remove(IPluginContext* pContext, const cell_t* params) static cell_t json_arr_remove_first(IPluginContext* pContext, const cell_t* params) { - JsonValue* handle = g_pJsonManager->GetFromHandle(pContext, params[1]); + JsonValue* handle = g_pJsonManager->GetValueFromHandle(pContext, params[1]); if (!handle) return 0; @@ -1638,7 +1660,7 @@ static cell_t json_arr_remove_first(IPluginContext* pContext, const cell_t* para static cell_t json_arr_remove_last(IPluginContext* pContext, const cell_t* params) { - JsonValue* handle = g_pJsonManager->GetFromHandle(pContext, params[1]); + JsonValue* handle = g_pJsonManager->GetValueFromHandle(pContext, params[1]); if (!handle) return 0; @@ -1651,7 +1673,7 @@ static cell_t json_arr_remove_last(IPluginContext* pContext, const cell_t* param static cell_t json_arr_remove_range(IPluginContext* pContext, const cell_t* params) { - JsonValue* handle = g_pJsonManager->GetFromHandle(pContext, params[1]); + JsonValue* handle = g_pJsonManager->GetValueFromHandle(pContext, params[1]); if (!handle) return 0; @@ -1675,7 +1697,7 @@ static cell_t json_arr_remove_range(IPluginContext* pContext, const cell_t* para static cell_t json_arr_clear(IPluginContext* pContext, const cell_t* params) { - JsonValue* handle = g_pJsonManager->GetFromHandle(pContext, params[1]); + JsonValue* handle = g_pJsonManager->GetValueFromHandle(pContext, params[1]); if (!handle) return 0; @@ -1688,7 +1710,7 @@ static cell_t json_arr_clear(IPluginContext* pContext, const cell_t* params) static cell_t json_doc_write_to_str(IPluginContext* pContext, const cell_t* params) { - JsonValue* handle = g_pJsonManager->GetFromHandle(pContext, params[1]); + JsonValue* handle = g_pJsonManager->GetValueFromHandle(pContext, params[1]); if (!handle) return 0; @@ -1715,7 +1737,7 @@ static cell_t json_doc_write_to_str(IPluginContext* pContext, const cell_t* para static cell_t json_doc_write_to_file(IPluginContext* pContext, const cell_t* params) { - JsonValue* handle = g_pJsonManager->GetFromHandle(pContext, params[1]); + JsonValue* handle = g_pJsonManager->GetValueFromHandle(pContext, params[1]); if (!handle) return 0; @@ -1723,7 +1745,7 @@ static cell_t json_doc_write_to_file(IPluginContext* pContext, const cell_t* par pContext->LocalToString(params[2], &path); uint32_t write_flg = static_cast(params[3]); - char error[JSON_PACK_ERROR_SIZE]; + char error[JSON_ERROR_BUFFER_SIZE]; if (!g_pJsonManager->WriteToFile(handle, path, write_flg, error, sizeof(error))) { return pContext->ThrowNativeError(error); } @@ -1733,7 +1755,7 @@ static cell_t json_doc_write_to_file(IPluginContext* pContext, const cell_t* par static cell_t json_obj_get_size(IPluginContext* pContext, const cell_t* params) { - JsonValue* handle = g_pJsonManager->GetFromHandle(pContext, params[1]); + JsonValue* handle = g_pJsonManager->GetValueFromHandle(pContext, params[1]); if (!handle) return 0; @@ -1743,7 +1765,7 @@ static cell_t json_obj_get_size(IPluginContext* pContext, const cell_t* params) static cell_t json_obj_get_key(IPluginContext* pContext, const cell_t* params) { - JsonValue* handle = g_pJsonManager->GetFromHandle(pContext, params[1]); + JsonValue* handle = g_pJsonManager->GetValueFromHandle(pContext, params[1]); if (!handle) return 0; @@ -1764,7 +1786,7 @@ static cell_t json_obj_get_key(IPluginContext* pContext, const cell_t* params) static cell_t json_obj_get_val_at(IPluginContext* pContext, const cell_t* params) { - JsonValue* handle = g_pJsonManager->GetFromHandle(pContext, params[1]); + JsonValue* handle = g_pJsonManager->GetValueFromHandle(pContext, params[1]); if (!handle) return 0; @@ -1785,7 +1807,7 @@ static cell_t json_obj_get_val_at(IPluginContext* pContext, const cell_t* params static cell_t json_obj_get_val(IPluginContext* pContext, const cell_t* params) { - JsonValue* handle = g_pJsonManager->GetFromHandle(pContext, params[1]); + JsonValue* handle = g_pJsonManager->GetValueFromHandle(pContext, params[1]); if (!handle) return 0; @@ -1803,7 +1825,7 @@ static cell_t json_obj_get_val(IPluginContext* pContext, const cell_t* params) static cell_t json_obj_get_bool(IPluginContext* pContext, const cell_t* params) { - JsonValue* handle = g_pJsonManager->GetFromHandle(pContext, params[1]); + JsonValue* handle = g_pJsonManager->GetValueFromHandle(pContext, params[1]); if (!handle) return 0; @@ -1820,7 +1842,7 @@ static cell_t json_obj_get_bool(IPluginContext* pContext, const cell_t* params) static cell_t json_obj_get_float(IPluginContext* pContext, const cell_t* params) { - JsonValue* handle = g_pJsonManager->GetFromHandle(pContext, params[1]); + JsonValue* handle = g_pJsonManager->GetValueFromHandle(pContext, params[1]); if (!handle) return 0; @@ -1828,7 +1850,7 @@ static cell_t json_obj_get_float(IPluginContext* pContext, const cell_t* params) pContext->LocalToString(params[2], &key); double value; - if (!g_pJsonManager->ObjectGetFloat(handle, key, &value)) { + if (!g_pJsonManager->ObjectGetDouble(handle, key, &value)) { return pContext->ThrowNativeError("Failed to get float for key '%s'", key); } @@ -1837,7 +1859,7 @@ static cell_t json_obj_get_float(IPluginContext* pContext, const cell_t* params) static cell_t json_obj_get_int(IPluginContext* pContext, const cell_t* params) { - JsonValue* handle = g_pJsonManager->GetFromHandle(pContext, params[1]); + JsonValue* handle = g_pJsonManager->GetValueFromHandle(pContext, params[1]); if (!handle) return 0; @@ -1854,7 +1876,7 @@ static cell_t json_obj_get_int(IPluginContext* pContext, const cell_t* params) static cell_t json_obj_get_integer64(IPluginContext* pContext, const cell_t* params) { - JsonValue* handle = g_pJsonManager->GetFromHandle(pContext, params[1]); + JsonValue* handle = g_pJsonManager->GetValueFromHandle(pContext, params[1]); if (!handle) return 0; @@ -1867,10 +1889,8 @@ static cell_t json_obj_get_integer64(IPluginContext* pContext, const cell_t* par } char result[JSON_INT64_BUFFER_SIZE]; - if (std::holds_alternative(value)) { - snprintf(result, sizeof(result), "%" PRIu64, std::get(value)); - } else { - snprintf(result, sizeof(result), "%" PRId64, std::get(value)); + if (!Int64VariantToString(value, result, sizeof(result))) { + return pContext->ThrowNativeError("Failed to convert integer64 to string"); } pContext->StringToLocalUTF8(params[3], params[4], result, nullptr); @@ -1879,7 +1899,7 @@ static cell_t json_obj_get_integer64(IPluginContext* pContext, const cell_t* par static cell_t json_obj_get_str(IPluginContext* pContext, const cell_t* params) { - JsonValue* handle = g_pJsonManager->GetFromHandle(pContext, params[1]); + JsonValue* handle = g_pJsonManager->GetValueFromHandle(pContext, params[1]); if (!handle) return 0; @@ -1904,7 +1924,7 @@ static cell_t json_obj_get_str(IPluginContext* pContext, const cell_t* params) static cell_t json_obj_clear(IPluginContext* pContext, const cell_t* params) { - JsonValue* handle = g_pJsonManager->GetFromHandle(pContext, params[1]); + JsonValue* handle = g_pJsonManager->GetValueFromHandle(pContext, params[1]); if (!handle) return 0; @@ -1917,7 +1937,7 @@ static cell_t json_obj_clear(IPluginContext* pContext, const cell_t* params) static cell_t json_obj_is_null(IPluginContext* pContext, const cell_t* params) { - JsonValue* handle = g_pJsonManager->GetFromHandle(pContext, params[1]); + JsonValue* handle = g_pJsonManager->GetValueFromHandle(pContext, params[1]); if (!handle) return 0; @@ -1934,7 +1954,7 @@ static cell_t json_obj_is_null(IPluginContext* pContext, const cell_t* params) static cell_t json_obj_has_key(IPluginContext* pContext, const cell_t* params) { - JsonValue* handle = g_pJsonManager->GetFromHandle(pContext, params[1]); + JsonValue* handle = g_pJsonManager->GetValueFromHandle(pContext, params[1]); if (!handle) return 0; @@ -1948,7 +1968,7 @@ static cell_t json_obj_has_key(IPluginContext* pContext, const cell_t* params) static cell_t json_obj_rename_key(IPluginContext* pContext, const cell_t* params) { - JsonValue* handle = g_pJsonManager->GetFromHandle(pContext, params[1]); + JsonValue* handle = g_pJsonManager->GetValueFromHandle(pContext, params[1]); if (!handle) return 0; @@ -1973,8 +1993,8 @@ static cell_t json_obj_rename_key(IPluginContext* pContext, const cell_t* params static cell_t json_obj_set_val(IPluginContext* pContext, const cell_t* params) { - JsonValue* handle1 = g_pJsonManager->GetFromHandle(pContext, params[1]); - JsonValue* handle2 = g_pJsonManager->GetFromHandle(pContext, params[3]); + JsonValue* handle1 = g_pJsonManager->GetValueFromHandle(pContext, params[1]); + JsonValue* handle2 = g_pJsonManager->GetValueFromHandle(pContext, params[3]); if (!handle1 || !handle2) return 0; @@ -1990,7 +2010,7 @@ static cell_t json_obj_set_val(IPluginContext* pContext, const cell_t* params) static cell_t json_obj_set_bool(IPluginContext* pContext, const cell_t* params) { - JsonValue* handle = g_pJsonManager->GetFromHandle(pContext, params[1]); + JsonValue* handle = g_pJsonManager->GetValueFromHandle(pContext, params[1]); if (!handle) return 0; @@ -2006,7 +2026,7 @@ static cell_t json_obj_set_bool(IPluginContext* pContext, const cell_t* params) static cell_t json_obj_set_float(IPluginContext* pContext, const cell_t* params) { - JsonValue* handle = g_pJsonManager->GetFromHandle(pContext, params[1]); + JsonValue* handle = g_pJsonManager->GetValueFromHandle(pContext, params[1]); if (!handle) return 0; @@ -2017,12 +2037,12 @@ static cell_t json_obj_set_float(IPluginContext* pContext, const cell_t* params) char* key; pContext->LocalToString(params[2], &key); - return g_pJsonManager->ObjectSetFloat(handle, key, sp_ctof(params[3])); + return g_pJsonManager->ObjectSetDouble(handle, key, sp_ctof(params[3])); } static cell_t json_obj_set_int(IPluginContext* pContext, const cell_t* params) { - JsonValue* handle = g_pJsonManager->GetFromHandle(pContext, params[1]); + JsonValue* handle = g_pJsonManager->GetValueFromHandle(pContext, params[1]); if (!handle) return 0; @@ -2038,7 +2058,7 @@ static cell_t json_obj_set_int(IPluginContext* pContext, const cell_t* params) static cell_t json_obj_set_integer64(IPluginContext* pContext, const cell_t* params) { - JsonValue* handle = g_pJsonManager->GetFromHandle(pContext, params[1]); + JsonValue* handle = g_pJsonManager->GetValueFromHandle(pContext, params[1]); if (!handle) return 0; @@ -2062,7 +2082,7 @@ static cell_t json_obj_set_integer64(IPluginContext* pContext, const cell_t* par static cell_t json_obj_set_null(IPluginContext* pContext, const cell_t* params) { - JsonValue* handle = g_pJsonManager->GetFromHandle(pContext, params[1]); + JsonValue* handle = g_pJsonManager->GetValueFromHandle(pContext, params[1]); if (!handle) return 0; @@ -2078,7 +2098,7 @@ static cell_t json_obj_set_null(IPluginContext* pContext, const cell_t* params) static cell_t json_obj_set_str(IPluginContext* pContext, const cell_t* params) { - JsonValue* handle = g_pJsonManager->GetFromHandle(pContext, params[1]); + JsonValue* handle = g_pJsonManager->GetValueFromHandle(pContext, params[1]); if (!handle) return 0; @@ -2095,7 +2115,7 @@ static cell_t json_obj_set_str(IPluginContext* pContext, const cell_t* params) static cell_t json_obj_remove(IPluginContext* pContext, const cell_t* params) { - JsonValue* handle = g_pJsonManager->GetFromHandle(pContext, params[1]); + JsonValue* handle = g_pJsonManager->GetValueFromHandle(pContext, params[1]); if (!handle) return 0; @@ -2111,14 +2131,14 @@ static cell_t json_obj_remove(IPluginContext* pContext, const cell_t* params) static cell_t json_ptr_get_val(IPluginContext* pContext, const cell_t* params) { - JsonValue* handle = g_pJsonManager->GetFromHandle(pContext, params[1]); + JsonValue* handle = g_pJsonManager->GetValueFromHandle(pContext, params[1]); if (!handle) return 0; char* path; pContext->LocalToString(params[2], &path); - char error[JSON_PACK_ERROR_SIZE]; + char error[JSON_ERROR_BUFFER_SIZE]; JsonValue* pJSONValue = g_pJsonManager->PtrGet(handle, path, error, sizeof(error)); if (!pJSONValue) { @@ -2130,7 +2150,7 @@ static cell_t json_ptr_get_val(IPluginContext* pContext, const cell_t* params) static cell_t json_ptr_get_bool(IPluginContext* pContext, const cell_t* params) { - JsonValue* handle = g_pJsonManager->GetFromHandle(pContext, params[1]); + JsonValue* handle = g_pJsonManager->GetValueFromHandle(pContext, params[1]); if (!handle) return 0; @@ -2138,7 +2158,7 @@ static cell_t json_ptr_get_bool(IPluginContext* pContext, const cell_t* params) pContext->LocalToString(params[2], &path); bool value; - char error[JSON_PACK_ERROR_SIZE]; + char error[JSON_ERROR_BUFFER_SIZE]; if (!g_pJsonManager->PtrGetBool(handle, path, &value, error, sizeof(error))) { return pContext->ThrowNativeError("%s", error); } @@ -2148,7 +2168,7 @@ static cell_t json_ptr_get_bool(IPluginContext* pContext, const cell_t* params) static cell_t json_ptr_get_float(IPluginContext* pContext, const cell_t* params) { - JsonValue* handle = g_pJsonManager->GetFromHandle(pContext, params[1]); + JsonValue* handle = g_pJsonManager->GetValueFromHandle(pContext, params[1]); if (!handle) return 0; @@ -2156,8 +2176,8 @@ static cell_t json_ptr_get_float(IPluginContext* pContext, const cell_t* params) pContext->LocalToString(params[2], &path); double value; - char error[JSON_PACK_ERROR_SIZE]; - if (!g_pJsonManager->PtrGetFloat(handle, path, &value, error, sizeof(error))) { + char error[JSON_ERROR_BUFFER_SIZE]; + if (!g_pJsonManager->PtrGetDouble(handle, path, &value, error, sizeof(error))) { return pContext->ThrowNativeError("%s", error); } @@ -2166,7 +2186,7 @@ static cell_t json_ptr_get_float(IPluginContext* pContext, const cell_t* params) static cell_t json_ptr_get_int(IPluginContext* pContext, const cell_t* params) { - JsonValue* handle = g_pJsonManager->GetFromHandle(pContext, params[1]); + JsonValue* handle = g_pJsonManager->GetValueFromHandle(pContext, params[1]); if (!handle) return 0; @@ -2174,7 +2194,7 @@ static cell_t json_ptr_get_int(IPluginContext* pContext, const cell_t* params) pContext->LocalToString(params[2], &path); int value; - char error[JSON_PACK_ERROR_SIZE]; + char error[JSON_ERROR_BUFFER_SIZE]; if (!g_pJsonManager->PtrGetInt(handle, path, &value, error, sizeof(error))) { return pContext->ThrowNativeError("%s", error); } @@ -2184,7 +2204,7 @@ static cell_t json_ptr_get_int(IPluginContext* pContext, const cell_t* params) static cell_t json_ptr_get_integer64(IPluginContext* pContext, const cell_t* params) { - JsonValue* handle = g_pJsonManager->GetFromHandle(pContext, params[1]); + JsonValue* handle = g_pJsonManager->GetValueFromHandle(pContext, params[1]); if (!handle) return 0; @@ -2192,16 +2212,14 @@ static cell_t json_ptr_get_integer64(IPluginContext* pContext, const cell_t* par pContext->LocalToString(params[2], &path); std::variant value; - char error[JSON_PACK_ERROR_SIZE]; + char error[JSON_ERROR_BUFFER_SIZE]; if (!g_pJsonManager->PtrGetInt64(handle, path, &value, error, sizeof(error))) { return pContext->ThrowNativeError("%s", error); } char result[JSON_INT64_BUFFER_SIZE]; - if (std::holds_alternative(value)) { - snprintf(result, sizeof(result), "%" PRIu64, std::get(value)); - } else { - snprintf(result, sizeof(result), "%" PRId64, std::get(value)); + if (!Int64VariantToString(value, result, sizeof(result))) { + return pContext->ThrowNativeError("Failed to convert integer64 to string"); } pContext->StringToLocalUTF8(params[3], params[4], result, nullptr); @@ -2210,7 +2228,7 @@ static cell_t json_ptr_get_integer64(IPluginContext* pContext, const cell_t* par static cell_t json_ptr_get_str(IPluginContext* pContext, const cell_t* params) { - JsonValue* handle = g_pJsonManager->GetFromHandle(pContext, params[1]); + JsonValue* handle = g_pJsonManager->GetValueFromHandle(pContext, params[1]); if (!handle) return 0; @@ -2219,7 +2237,7 @@ static cell_t json_ptr_get_str(IPluginContext* pContext, const cell_t* params) const char* str; size_t len; - char error[JSON_PACK_ERROR_SIZE]; + char error[JSON_ERROR_BUFFER_SIZE]; if (!g_pJsonManager->PtrGetString(handle, path, &str, &len, error, sizeof(error))) { return pContext->ThrowNativeError("%s", error); } @@ -2236,7 +2254,7 @@ static cell_t json_ptr_get_str(IPluginContext* pContext, const cell_t* params) static cell_t json_ptr_get_is_null(IPluginContext* pContext, const cell_t* params) { - JsonValue* handle = g_pJsonManager->GetFromHandle(pContext, params[1]); + JsonValue* handle = g_pJsonManager->GetValueFromHandle(pContext, params[1]); if (!handle) return 0; @@ -2244,7 +2262,7 @@ static cell_t json_ptr_get_is_null(IPluginContext* pContext, const cell_t* param pContext->LocalToString(params[2], &path); bool is_null; - char error[JSON_PACK_ERROR_SIZE]; + char error[JSON_ERROR_BUFFER_SIZE]; if (!g_pJsonManager->PtrGetIsNull(handle, path, &is_null, error, sizeof(error))) { return pContext->ThrowNativeError("%s", error); } @@ -2254,7 +2272,7 @@ static cell_t json_ptr_get_is_null(IPluginContext* pContext, const cell_t* param static cell_t json_ptr_get_length(IPluginContext* pContext, const cell_t* params) { - JsonValue* handle = g_pJsonManager->GetFromHandle(pContext, params[1]); + JsonValue* handle = g_pJsonManager->GetValueFromHandle(pContext, params[1]); if (!handle) return 0; @@ -2262,7 +2280,7 @@ static cell_t json_ptr_get_length(IPluginContext* pContext, const cell_t* params pContext->LocalToString(params[2], &path); size_t len; - char error[JSON_PACK_ERROR_SIZE]; + char error[JSON_ERROR_BUFFER_SIZE]; if (!g_pJsonManager->PtrGetLength(handle, path, &len, error, sizeof(error))) { return pContext->ThrowNativeError("%s", error); } @@ -2272,8 +2290,8 @@ static cell_t json_ptr_get_length(IPluginContext* pContext, const cell_t* params static cell_t json_ptr_set_val(IPluginContext* pContext, const cell_t* params) { - JsonValue* handle1 = g_pJsonManager->GetFromHandle(pContext, params[1]); - JsonValue* handle2 = g_pJsonManager->GetFromHandle(pContext, params[3]); + JsonValue* handle1 = g_pJsonManager->GetValueFromHandle(pContext, params[1]); + JsonValue* handle2 = g_pJsonManager->GetValueFromHandle(pContext, params[3]); if (!handle1 || !handle2) return 0; @@ -2284,7 +2302,7 @@ static cell_t json_ptr_set_val(IPluginContext* pContext, const cell_t* params) char* path; pContext->LocalToString(params[2], &path); - char error[JSON_PACK_ERROR_SIZE]; + char error[JSON_ERROR_BUFFER_SIZE]; if (!g_pJsonManager->PtrSet(handle1, path, handle2, error, sizeof(error))) { return pContext->ThrowNativeError("%s", error); } @@ -2294,7 +2312,7 @@ static cell_t json_ptr_set_val(IPluginContext* pContext, const cell_t* params) static cell_t json_ptr_set_bool(IPluginContext* pContext, const cell_t* params) { - JsonValue* handle = g_pJsonManager->GetFromHandle(pContext, params[1]); + JsonValue* handle = g_pJsonManager->GetValueFromHandle(pContext, params[1]); if (!handle) return 0; @@ -2305,7 +2323,7 @@ static cell_t json_ptr_set_bool(IPluginContext* pContext, const cell_t* params) char* path; pContext->LocalToString(params[2], &path); - char error[JSON_PACK_ERROR_SIZE]; + char error[JSON_ERROR_BUFFER_SIZE]; if (!g_pJsonManager->PtrSetBool(handle, path, params[3], error, sizeof(error))) { return pContext->ThrowNativeError("%s", error); } @@ -2315,7 +2333,7 @@ static cell_t json_ptr_set_bool(IPluginContext* pContext, const cell_t* params) static cell_t json_ptr_set_float(IPluginContext* pContext, const cell_t* params) { - JsonValue* handle = g_pJsonManager->GetFromHandle(pContext, params[1]); + JsonValue* handle = g_pJsonManager->GetValueFromHandle(pContext, params[1]); if (!handle) return 0; @@ -2326,8 +2344,8 @@ static cell_t json_ptr_set_float(IPluginContext* pContext, const cell_t* params) char* path; pContext->LocalToString(params[2], &path); - char error[JSON_PACK_ERROR_SIZE]; - if (!g_pJsonManager->PtrSetFloat(handle, path, sp_ctof(params[3]), error, sizeof(error))) { + char error[JSON_ERROR_BUFFER_SIZE]; + if (!g_pJsonManager->PtrSetDouble(handle, path, sp_ctof(params[3]), error, sizeof(error))) { return pContext->ThrowNativeError("%s", error); } @@ -2336,7 +2354,7 @@ static cell_t json_ptr_set_float(IPluginContext* pContext, const cell_t* params) static cell_t json_ptr_set_int(IPluginContext* pContext, const cell_t* params) { - JsonValue* handle = g_pJsonManager->GetFromHandle(pContext, params[1]); + JsonValue* handle = g_pJsonManager->GetValueFromHandle(pContext, params[1]); if (!handle) return 0; @@ -2347,7 +2365,7 @@ static cell_t json_ptr_set_int(IPluginContext* pContext, const cell_t* params) char* path; pContext->LocalToString(params[2], &path); - char error[JSON_PACK_ERROR_SIZE]; + char error[JSON_ERROR_BUFFER_SIZE]; if (!g_pJsonManager->PtrSetInt(handle, path, params[3], error, sizeof(error))) { return pContext->ThrowNativeError("%s", error); } @@ -2357,7 +2375,7 @@ static cell_t json_ptr_set_int(IPluginContext* pContext, const cell_t* params) static cell_t json_ptr_set_integer64(IPluginContext* pContext, const cell_t* params) { - JsonValue* handle = g_pJsonManager->GetFromHandle(pContext, params[1]); + JsonValue* handle = g_pJsonManager->GetValueFromHandle(pContext, params[1]); if (!handle) return 0; @@ -2370,7 +2388,7 @@ static cell_t json_ptr_set_integer64(IPluginContext* pContext, const cell_t* par pContext->LocalToString(params[3], &value); std::variant variant_value; - char error[JSON_PACK_ERROR_SIZE]; + char error[JSON_ERROR_BUFFER_SIZE]; if (!g_pJsonManager->ParseInt64Variant(value, &variant_value, error, sizeof(error))) { return pContext->ThrowNativeError("%s", error); @@ -2385,7 +2403,7 @@ static cell_t json_ptr_set_integer64(IPluginContext* pContext, const cell_t* par static cell_t json_ptr_set_str(IPluginContext* pContext, const cell_t* params) { - JsonValue* handle = g_pJsonManager->GetFromHandle(pContext, params[1]); + JsonValue* handle = g_pJsonManager->GetValueFromHandle(pContext, params[1]); if (!handle) return 0; @@ -2397,7 +2415,7 @@ static cell_t json_ptr_set_str(IPluginContext* pContext, const cell_t* params) pContext->LocalToString(params[2], &path); pContext->LocalToString(params[3], &str); - char error[JSON_PACK_ERROR_SIZE]; + char error[JSON_ERROR_BUFFER_SIZE]; if (!g_pJsonManager->PtrSetString(handle, path, str, error, sizeof(error))) { return pContext->ThrowNativeError("%s", error); } @@ -2407,7 +2425,7 @@ static cell_t json_ptr_set_str(IPluginContext* pContext, const cell_t* params) static cell_t json_ptr_set_null(IPluginContext* pContext, const cell_t* params) { - JsonValue* handle = g_pJsonManager->GetFromHandle(pContext, params[1]); + JsonValue* handle = g_pJsonManager->GetValueFromHandle(pContext, params[1]); if (!handle) return 0; @@ -2418,7 +2436,7 @@ static cell_t json_ptr_set_null(IPluginContext* pContext, const cell_t* params) char* path; pContext->LocalToString(params[2], &path); - char error[JSON_PACK_ERROR_SIZE]; + char error[JSON_ERROR_BUFFER_SIZE]; if (!g_pJsonManager->PtrSetNull(handle, path, error, sizeof(error))) { return pContext->ThrowNativeError("%s", error); } @@ -2428,8 +2446,8 @@ static cell_t json_ptr_set_null(IPluginContext* pContext, const cell_t* params) static cell_t json_ptr_add_val(IPluginContext* pContext, const cell_t* params) { - JsonValue* handle1 = g_pJsonManager->GetFromHandle(pContext, params[1]); - JsonValue* handle2 = g_pJsonManager->GetFromHandle(pContext, params[3]); + JsonValue* handle1 = g_pJsonManager->GetValueFromHandle(pContext, params[1]); + JsonValue* handle2 = g_pJsonManager->GetValueFromHandle(pContext, params[3]); if (!handle1 || !handle2) return 0; @@ -2440,7 +2458,7 @@ static cell_t json_ptr_add_val(IPluginContext* pContext, const cell_t* params) char* path; pContext->LocalToString(params[2], &path); - char error[JSON_PACK_ERROR_SIZE]; + char error[JSON_ERROR_BUFFER_SIZE]; if (!g_pJsonManager->PtrAdd(handle1, path, handle2, error, sizeof(error))) { return pContext->ThrowNativeError("%s", error); } @@ -2450,7 +2468,7 @@ static cell_t json_ptr_add_val(IPluginContext* pContext, const cell_t* params) static cell_t json_ptr_add_bool(IPluginContext* pContext, const cell_t* params) { - JsonValue* handle = g_pJsonManager->GetFromHandle(pContext, params[1]); + JsonValue* handle = g_pJsonManager->GetValueFromHandle(pContext, params[1]); if (!handle) return 0; @@ -2461,7 +2479,7 @@ static cell_t json_ptr_add_bool(IPluginContext* pContext, const cell_t* params) char* path; pContext->LocalToString(params[2], &path); - char error[JSON_PACK_ERROR_SIZE]; + char error[JSON_ERROR_BUFFER_SIZE]; if (!g_pJsonManager->PtrAddBool(handle, path, params[3], error, sizeof(error))) { return pContext->ThrowNativeError("%s", error); } @@ -2471,7 +2489,7 @@ static cell_t json_ptr_add_bool(IPluginContext* pContext, const cell_t* params) static cell_t json_ptr_add_float(IPluginContext* pContext, const cell_t* params) { - JsonValue* handle = g_pJsonManager->GetFromHandle(pContext, params[1]); + JsonValue* handle = g_pJsonManager->GetValueFromHandle(pContext, params[1]); if (!handle) return 0; @@ -2482,8 +2500,8 @@ static cell_t json_ptr_add_float(IPluginContext* pContext, const cell_t* params) char* path; pContext->LocalToString(params[2], &path); - char error[JSON_PACK_ERROR_SIZE]; - if (!g_pJsonManager->PtrAddFloat(handle, path, sp_ctof(params[3]), error, sizeof(error))) { + char error[JSON_ERROR_BUFFER_SIZE]; + if (!g_pJsonManager->PtrAddDouble(handle, path, sp_ctof(params[3]), error, sizeof(error))) { return pContext->ThrowNativeError("%s", error); } @@ -2492,7 +2510,7 @@ static cell_t json_ptr_add_float(IPluginContext* pContext, const cell_t* params) static cell_t json_ptr_add_int(IPluginContext* pContext, const cell_t* params) { - JsonValue* handle = g_pJsonManager->GetFromHandle(pContext, params[1]); + JsonValue* handle = g_pJsonManager->GetValueFromHandle(pContext, params[1]); if (!handle) return 0; @@ -2503,7 +2521,7 @@ static cell_t json_ptr_add_int(IPluginContext* pContext, const cell_t* params) char* path; pContext->LocalToString(params[2], &path); - char error[JSON_PACK_ERROR_SIZE]; + char error[JSON_ERROR_BUFFER_SIZE]; if (!g_pJsonManager->PtrAddInt(handle, path, params[3], error, sizeof(error))) { return pContext->ThrowNativeError("%s", error); } @@ -2513,7 +2531,7 @@ static cell_t json_ptr_add_int(IPluginContext* pContext, const cell_t* params) static cell_t json_ptr_add_integer64(IPluginContext* pContext, const cell_t* params) { - JsonValue* handle = g_pJsonManager->GetFromHandle(pContext, params[1]); + JsonValue* handle = g_pJsonManager->GetValueFromHandle(pContext, params[1]); if (!handle) return 0; @@ -2526,7 +2544,7 @@ static cell_t json_ptr_add_integer64(IPluginContext* pContext, const cell_t* par pContext->LocalToString(params[3], &value); std::variant variant_value; - char error[JSON_PACK_ERROR_SIZE]; + char error[JSON_ERROR_BUFFER_SIZE]; if (!g_pJsonManager->ParseInt64Variant(value, &variant_value, error, sizeof(error))) { return pContext->ThrowNativeError("%s", error); @@ -2541,7 +2559,7 @@ static cell_t json_ptr_add_integer64(IPluginContext* pContext, const cell_t* par static cell_t json_ptr_add_str(IPluginContext* pContext, const cell_t* params) { - JsonValue* handle = g_pJsonManager->GetFromHandle(pContext, params[1]); + JsonValue* handle = g_pJsonManager->GetValueFromHandle(pContext, params[1]); if (!handle) return 0; @@ -2553,7 +2571,7 @@ static cell_t json_ptr_add_str(IPluginContext* pContext, const cell_t* params) pContext->LocalToString(params[2], &path); pContext->LocalToString(params[3], &str); - char error[JSON_PACK_ERROR_SIZE]; + char error[JSON_ERROR_BUFFER_SIZE]; if (!g_pJsonManager->PtrAddString(handle, path, str, error, sizeof(error))) { return pContext->ThrowNativeError("%s", error); } @@ -2563,7 +2581,7 @@ static cell_t json_ptr_add_str(IPluginContext* pContext, const cell_t* params) static cell_t json_ptr_add_null(IPluginContext* pContext, const cell_t* params) { - JsonValue* handle = g_pJsonManager->GetFromHandle(pContext, params[1]); + JsonValue* handle = g_pJsonManager->GetValueFromHandle(pContext, params[1]); if (!handle) return 0; @@ -2574,7 +2592,7 @@ static cell_t json_ptr_add_null(IPluginContext* pContext, const cell_t* params) char* path; pContext->LocalToString(params[2], &path); - char error[JSON_PACK_ERROR_SIZE]; + char error[JSON_ERROR_BUFFER_SIZE]; if (!g_pJsonManager->PtrAddNull(handle, path, error, sizeof(error))) { return pContext->ThrowNativeError("%s", error); } @@ -2584,7 +2602,7 @@ static cell_t json_ptr_add_null(IPluginContext* pContext, const cell_t* params) static cell_t json_ptr_remove_val(IPluginContext* pContext, const cell_t* params) { - JsonValue* handle = g_pJsonManager->GetFromHandle(pContext, params[1]); + JsonValue* handle = g_pJsonManager->GetValueFromHandle(pContext, params[1]); if (!handle) return 0; @@ -2595,7 +2613,7 @@ static cell_t json_ptr_remove_val(IPluginContext* pContext, const cell_t* params char* path; pContext->LocalToString(params[2], &path); - char error[JSON_PACK_ERROR_SIZE]; + char error[JSON_ERROR_BUFFER_SIZE]; if (!g_pJsonManager->PtrRemove(handle, path, error, sizeof(error))) { return pContext->ThrowNativeError("%s", error); } @@ -2605,7 +2623,7 @@ static cell_t json_ptr_remove_val(IPluginContext* pContext, const cell_t* params static cell_t json_ptr_try_get_val(IPluginContext* pContext, const cell_t* params) { - JsonValue* handle = g_pJsonManager->GetFromHandle(pContext, params[1]); + JsonValue* handle = g_pJsonManager->GetValueFromHandle(pContext, params[1]); if (!handle) return 0; @@ -2623,7 +2641,7 @@ static cell_t json_ptr_try_get_val(IPluginContext* pContext, const cell_t* param static cell_t json_ptr_try_get_bool(IPluginContext* pContext, const cell_t* params) { - JsonValue* handle = g_pJsonManager->GetFromHandle(pContext, params[1]); + JsonValue* handle = g_pJsonManager->GetValueFromHandle(pContext, params[1]); if (!handle) return 0; char* path; @@ -2643,14 +2661,14 @@ static cell_t json_ptr_try_get_bool(IPluginContext* pContext, const cell_t* para static cell_t json_ptr_try_get_float(IPluginContext* pContext, const cell_t* params) { - JsonValue* handle = g_pJsonManager->GetFromHandle(pContext, params[1]); + JsonValue* handle = g_pJsonManager->GetValueFromHandle(pContext, params[1]); if (!handle) return 0; char* path; pContext->LocalToString(params[2], &path); double value; - if (!g_pJsonManager->PtrTryGetFloat(handle, path, &value)) { + if (!g_pJsonManager->PtrTryGetDouble(handle, path, &value)) { return 0; } @@ -2663,7 +2681,7 @@ static cell_t json_ptr_try_get_float(IPluginContext* pContext, const cell_t* par static cell_t json_ptr_try_get_int(IPluginContext* pContext, const cell_t* params) { - JsonValue* handle = g_pJsonManager->GetFromHandle(pContext, params[1]); + JsonValue* handle = g_pJsonManager->GetValueFromHandle(pContext, params[1]); if (!handle) return 0; char* path; @@ -2683,7 +2701,7 @@ static cell_t json_ptr_try_get_int(IPluginContext* pContext, const cell_t* param static cell_t json_ptr_try_get_integer64(IPluginContext* pContext, const cell_t* params) { - JsonValue* handle = g_pJsonManager->GetFromHandle(pContext, params[1]); + JsonValue* handle = g_pJsonManager->GetValueFromHandle(pContext, params[1]); if (!handle) return 0; char* path; @@ -2696,10 +2714,8 @@ static cell_t json_ptr_try_get_integer64(IPluginContext* pContext, const cell_t* size_t maxlen = static_cast(params[4]); char result[JSON_INT64_BUFFER_SIZE]; - if (std::holds_alternative(value)) { - snprintf(result, sizeof(result), "%" PRIu64, std::get(value)); - } else { - snprintf(result, sizeof(result), "%" PRId64, std::get(value)); + if (!Int64VariantToString(value, result, sizeof(result))) { + return 0; } pContext->StringToLocalUTF8(params[3], maxlen, result, nullptr); return 1; @@ -2707,7 +2723,7 @@ static cell_t json_ptr_try_get_integer64(IPluginContext* pContext, const cell_t* static cell_t json_ptr_try_get_str(IPluginContext* pContext, const cell_t* params) { - JsonValue* handle = g_pJsonManager->GetFromHandle(pContext, params[1]); + JsonValue* handle = g_pJsonManager->GetValueFromHandle(pContext, params[1]); if (!handle) return 0; char* path; @@ -2732,7 +2748,7 @@ static cell_t json_ptr_try_get_str(IPluginContext* pContext, const cell_t* param static cell_t json_obj_foreach(IPluginContext* pContext, const cell_t* params) { - JsonValue* handle = g_pJsonManager->GetFromHandle(pContext, params[1]); + JsonValue* handle = g_pJsonManager->GetValueFromHandle(pContext, params[1]); if (!handle) return 0; const char* key; @@ -2749,7 +2765,7 @@ static cell_t json_obj_foreach(IPluginContext* pContext, const cell_t* params) static cell_t json_arr_foreach(IPluginContext* pContext, const cell_t* params) { - JsonValue* handle = g_pJsonManager->GetFromHandle(pContext, params[1]); + JsonValue* handle = g_pJsonManager->GetValueFromHandle(pContext, params[1]); if (!handle) return 0; size_t index; @@ -2768,7 +2784,7 @@ static cell_t json_arr_foreach(IPluginContext* pContext, const cell_t* params) static cell_t json_obj_foreach_key(IPluginContext* pContext, const cell_t* params) { - JsonValue* handle = g_pJsonManager->GetFromHandle(pContext, params[1]); + JsonValue* handle = g_pJsonManager->GetValueFromHandle(pContext, params[1]); if (!handle) return 0; const char* key; @@ -2784,7 +2800,7 @@ static cell_t json_obj_foreach_key(IPluginContext* pContext, const cell_t* param static cell_t json_arr_foreach_index(IPluginContext* pContext, const cell_t* params) { - JsonValue* handle = g_pJsonManager->GetFromHandle(pContext, params[1]); + JsonValue* handle = g_pJsonManager->GetValueFromHandle(pContext, params[1]); if (!handle) return 0; size_t index; @@ -2802,7 +2818,7 @@ static cell_t json_arr_foreach_index(IPluginContext* pContext, const cell_t* par static cell_t json_arr_sort(IPluginContext* pContext, const cell_t* params) { - JsonValue* handle = g_pJsonManager->GetFromHandle(pContext, params[1]); + JsonValue* handle = g_pJsonManager->GetValueFromHandle(pContext, params[1]); if (!handle) return 0; @@ -2818,9 +2834,23 @@ static cell_t json_arr_sort(IPluginContext* pContext, const cell_t* params) return g_pJsonManager->ArraySort(handle, sort_mode); } +static cell_t json_arr_rotate(IPluginContext* pContext, const cell_t* params) +{ + JsonValue* handle = g_pJsonManager->GetValueFromHandle(pContext, params[1]); + + if (!handle) return 0; + + if (!handle->IsMutable()) { + return pContext->ThrowNativeError("Cannot rotate an immutable JSON array"); + } + + size_t idx = static_cast(params[2]); + return g_pJsonManager->ArrayRotate(handle, idx); +} + static cell_t json_obj_sort(IPluginContext* pContext, const cell_t* params) { - JsonValue* handle = g_pJsonManager->GetFromHandle(pContext, params[1]); + JsonValue* handle = g_pJsonManager->GetValueFromHandle(pContext, params[1]); if (!handle) return 0; @@ -2836,9 +2866,23 @@ static cell_t json_obj_sort(IPluginContext* pContext, const cell_t* params) return g_pJsonManager->ObjectSort(handle, sort_mode); } +static cell_t json_obj_rotate(IPluginContext* pContext, const cell_t* params) +{ + JsonValue* handle = g_pJsonManager->GetValueFromHandle(pContext, params[1]); + + if (!handle) return 0; + + if (!handle->IsMutable()) { + return pContext->ThrowNativeError("Cannot rotate an immutable JSON object"); + } + + size_t idx = static_cast(params[2]); + return g_pJsonManager->ObjectRotate(handle, idx); +} + static cell_t json_doc_to_mutable(IPluginContext* pContext, const cell_t* params) { - JsonValue* handle = g_pJsonManager->GetFromHandle(pContext, params[1]); + JsonValue* handle = g_pJsonManager->GetValueFromHandle(pContext, params[1]); if (!handle) return 0; @@ -2857,7 +2901,7 @@ static cell_t json_doc_to_mutable(IPluginContext* pContext, const cell_t* params static cell_t json_doc_to_immutable(IPluginContext* pContext, const cell_t* params) { - JsonValue* handle = g_pJsonManager->GetFromHandle(pContext, params[1]); + JsonValue* handle = g_pJsonManager->GetValueFromHandle(pContext, params[1]); if (!handle) return 0; @@ -2876,8 +2920,8 @@ static cell_t json_doc_to_immutable(IPluginContext* pContext, const cell_t* para static cell_t json_apply_json_patch(IPluginContext* pContext, const cell_t* params) { - JsonValue* target = g_pJsonManager->GetFromHandle(pContext, params[1]); - JsonValue* patch = g_pJsonManager->GetFromHandle(pContext, params[2]); + JsonValue* target = g_pJsonManager->GetValueFromHandle(pContext, params[1]); + JsonValue* patch = g_pJsonManager->GetValueFromHandle(pContext, params[2]); if (!target || !patch) return 0; @@ -2897,8 +2941,8 @@ static cell_t json_apply_json_patch(IPluginContext* pContext, const cell_t* para static cell_t json_json_patch_in_place(IPluginContext* pContext, const cell_t* params) { - JsonValue* target = g_pJsonManager->GetFromHandle(pContext, params[1]); - JsonValue* patch = g_pJsonManager->GetFromHandle(pContext, params[2]); + JsonValue* target = g_pJsonManager->GetValueFromHandle(pContext, params[1]); + JsonValue* patch = g_pJsonManager->GetValueFromHandle(pContext, params[2]); if (!target || !patch) return 0; @@ -2915,8 +2959,8 @@ static cell_t json_json_patch_in_place(IPluginContext* pContext, const cell_t* p static cell_t json_apply_merge_patch(IPluginContext* pContext, const cell_t* params) { - JsonValue* target = g_pJsonManager->GetFromHandle(pContext, params[1]); - JsonValue* patch = g_pJsonManager->GetFromHandle(pContext, params[2]); + JsonValue* target = g_pJsonManager->GetValueFromHandle(pContext, params[1]); + JsonValue* patch = g_pJsonManager->GetValueFromHandle(pContext, params[2]); if (!target || !patch) return 0; @@ -2936,8 +2980,8 @@ static cell_t json_apply_merge_patch(IPluginContext* pContext, const cell_t* par static cell_t json_merge_patch_in_place(IPluginContext* pContext, const cell_t* params) { - JsonValue* target = g_pJsonManager->GetFromHandle(pContext, params[1]); - JsonValue* patch = g_pJsonManager->GetFromHandle(pContext, params[2]); + JsonValue* target = g_pJsonManager->GetValueFromHandle(pContext, params[1]); + JsonValue* patch = g_pJsonManager->GetValueFromHandle(pContext, params[2]); if (!target || !patch) return 0; @@ -2954,7 +2998,7 @@ static cell_t json_merge_patch_in_place(IPluginContext* pContext, const cell_t* static cell_t json_arr_iter_init(IPluginContext* pContext, const cell_t* params) { - JsonValue* handle = g_pJsonManager->GetFromHandle(pContext, params[1]); + JsonValue* handle = g_pJsonManager->GetValueFromHandle(pContext, params[1]); if (!handle) return 0; JsonArrIter* iter = g_pJsonManager->ArrIterWith(handle); @@ -3016,7 +3060,7 @@ static cell_t json_arr_iter_reset(IPluginContext* pContext, const cell_t* params static cell_t json_obj_iter_init(IPluginContext* pContext, const cell_t* params) { - JsonValue* handle = g_pJsonManager->GetFromHandle(pContext, params[1]); + JsonValue* handle = g_pJsonManager->GetValueFromHandle(pContext, params[1]); if (!handle) return 0; JsonObjIter* iter = g_pJsonManager->ObjIterWith(handle); @@ -3031,10 +3075,12 @@ static cell_t json_obj_iter_next(IPluginContext* pContext, const cell_t* params) void* key = g_pJsonManager->ObjIterNext(iter); if (!key) return 0; - const char* key_str; - size_t key_len; - g_pJsonManager->GetString(reinterpret_cast(key), &key_str, &key_len); - pContext->StringToLocalUTF8(params[2], params[3], key_str, nullptr); + const char* key_str = nullptr; + if (!g_pJsonManager->ObjIterGetKeyString(iter, key, &key_str)) { + return 0; + } + + pContext->StringToLocalUTF8(params[2], params[3], key_str ? key_str : "", nullptr); return 1; } @@ -3074,7 +3120,7 @@ static cell_t json_obj_iter_get(IPluginContext* pContext, const cell_t* params) JsonValue* val = g_pJsonManager->ObjIterGet(iter, key); if (!val) { - return 0; + return pContext->ThrowNativeError("Failed to get value from iterator"); } return CreateAndReturnHandle(pContext, val, "object iterator value"); @@ -3141,7 +3187,7 @@ static cell_t json_read_number(IPluginContext* pContext, const cell_t* params) static cell_t json_write_number(IPluginContext* pContext, const cell_t* params) { - JsonValue* handle = g_pJsonManager->GetFromHandle(pContext, params[1]); + JsonValue* handle = g_pJsonManager->GetValueFromHandle(pContext, params[1]); if (!handle) return 0; cell_t buffer_size_param = params[3]; @@ -3177,7 +3223,7 @@ static cell_t json_write_number(IPluginContext* pContext, const cell_t* params) static cell_t json_set_fp_to_float(IPluginContext* pContext, const cell_t* params) { - JsonValue* handle = g_pJsonManager->GetFromHandle(pContext, params[1]); + JsonValue* handle = g_pJsonManager->GetValueFromHandle(pContext, params[1]); if (!handle) return 0; bool flt = params[2] != 0; @@ -3190,7 +3236,7 @@ static cell_t json_set_fp_to_float(IPluginContext* pContext, const cell_t* param static cell_t json_set_fp_to_fixed(IPluginContext* pContext, const cell_t* params) { - JsonValue* handle = g_pJsonManager->GetFromHandle(pContext, params[1]); + JsonValue* handle = g_pJsonManager->GetValueFromHandle(pContext, params[1]); if (!handle) return 0; int prec = params[2]; @@ -3207,7 +3253,7 @@ static cell_t json_set_fp_to_fixed(IPluginContext* pContext, const cell_t* param static cell_t json_set_bool(IPluginContext* pContext, const cell_t* params) { - JsonValue* handle = g_pJsonManager->GetFromHandle(pContext, params[1]); + JsonValue* handle = g_pJsonManager->GetValueFromHandle(pContext, params[1]); if (!handle) return 0; bool value = params[2] != 0; @@ -3220,7 +3266,7 @@ static cell_t json_set_bool(IPluginContext* pContext, const cell_t* params) static cell_t json_set_int(IPluginContext* pContext, const cell_t* params) { - JsonValue* handle = g_pJsonManager->GetFromHandle(pContext, params[1]); + JsonValue* handle = g_pJsonManager->GetValueFromHandle(pContext, params[1]); if (!handle) return 0; int value = params[2]; @@ -3233,7 +3279,7 @@ static cell_t json_set_int(IPluginContext* pContext, const cell_t* params) static cell_t json_set_int64(IPluginContext* pContext, const cell_t* params) { - JsonValue* handle = g_pJsonManager->GetFromHandle(pContext, params[1]); + JsonValue* handle = g_pJsonManager->GetValueFromHandle(pContext, params[1]); if (!handle) return 0; char* str; @@ -3255,11 +3301,10 @@ static cell_t json_set_int64(IPluginContext* pContext, const cell_t* params) static cell_t json_set_float(IPluginContext* pContext, const cell_t* params) { - JsonValue* handle = g_pJsonManager->GetFromHandle(pContext, params[1]); + JsonValue* handle = g_pJsonManager->GetValueFromHandle(pContext, params[1]); if (!handle) return 0; - float value = sp_ctof(params[2]); - if (!g_pJsonManager->SetFloat(handle, value)) { + if (!g_pJsonManager->SetDouble(handle, sp_ctof(params[2]))) { return pContext->ThrowNativeError("Failed to set value to float (value is object or array)"); } @@ -3268,7 +3313,7 @@ static cell_t json_set_float(IPluginContext* pContext, const cell_t* params) static cell_t json_set_string(IPluginContext* pContext, const cell_t* params) { - JsonValue* handle = g_pJsonManager->GetFromHandle(pContext, params[1]); + JsonValue* handle = g_pJsonManager->GetValueFromHandle(pContext, params[1]); if (!handle) return 0; char* value; @@ -3283,7 +3328,7 @@ static cell_t json_set_string(IPluginContext* pContext, const cell_t* params) static cell_t json_set_null(IPluginContext* pContext, const cell_t* params) { - JsonValue* handle = g_pJsonManager->GetFromHandle(pContext, params[1]); + JsonValue* handle = g_pJsonManager->GetValueFromHandle(pContext, params[1]); if (!handle) return 0; if (!g_pJsonManager->SetNull(handle)) { @@ -3322,6 +3367,7 @@ const sp_nativeinfo_t g_JsonNatives[] = {"JSONObject.FromString", json_obj_parse_str}, {"JSONObject.FromFile", json_obj_parse_file}, {"JSONObject.Sort", json_obj_sort}, + {"JSONObject.Rotate", json_obj_rotate}, // JSONArray {"JSONArray.JSONArray", json_arr_init}, @@ -3381,6 +3427,7 @@ const sp_nativeinfo_t g_JsonNatives[] = {"JSONArray.IndexOfInt64", json_arr_index_of_integer64}, {"JSONArray.IndexOfFloat", json_arr_index_of_float}, {"JSONArray.Sort", json_arr_sort}, + {"JSONArray.Rotate", json_arr_rotate}, // JSON UTILITY {"JSON.ToString", json_doc_write_to_str}, @@ -3393,6 +3440,7 @@ const sp_nativeinfo_t g_JsonNatives[] = {"JSON.GetSerializedSize", json_get_serialized_size}, {"JSON.ReadSize.get", json_get_read_size}, {"JSON.RefCount.get", json_get_ref_count}, + {"JSON.ValCount.get", json_get_val_count}, {"JSON.Type.get", json_get_type}, {"JSON.SubType.get", json_get_subtype}, {"JSON.IsArray.get", json_is_array}, diff --git a/extensions/json/extension.cpp b/extensions/json/extension.cpp index 2c624acf0..4e2b15dbd 100755 --- a/extensions/json/extension.cpp +++ b/extensions/json/extension.cpp @@ -17,26 +17,30 @@ bool JsonExtension::SDK_OnLoad(char* error, size_t maxlen, bool late) sharesys->AddNatives(myself, g_JsonNatives); sharesys->RegisterLibrary(myself, "json"); - HandleAccess haJSON; - handlesys->InitAccessDefaults(nullptr, &haJSON); - haJSON.access[HandleAccess_Read] = 0; - haJSON.access[HandleAccess_Delete] = 0; + HandleAccess haDefault; + handlesys->InitAccessDefaults(nullptr, &haDefault); + haDefault.access[HandleAccess_Read] = 0; + haDefault.access[HandleAccess_Delete] = 0; + + TypeAccess taDefault; + handlesys->InitAccessDefaults(&taDefault, nullptr); + taDefault.access[HTypeAccess_Create] = true; HandleError err; - g_JsonType = handlesys->CreateType("JSON", &g_JsonHandler, 0, nullptr, &haJSON, myself->GetIdentity(), &err); + g_JsonType = handlesys->CreateType("JSON", &g_JsonHandler, 0, &taDefault, &haDefault, myself->GetIdentity(), &err); if (!g_JsonType) { snprintf(error, maxlen, "Failed to create JSON handle type (err: %d)", err); return false; } - g_ArrIterType = handlesys->CreateType("JSONArrIter", &g_ArrIterHandler, 0, nullptr, &haJSON, myself->GetIdentity(), &err); + g_ArrIterType = handlesys->CreateType("JSONArrIter", &g_ArrIterHandler, 0, &taDefault, &haDefault, myself->GetIdentity(), &err); if (!g_ArrIterType) { snprintf(error, maxlen, "Failed to create JSONArrIter handle type (err: %d)", err); return false; } - g_ObjIterType = handlesys->CreateType("JSONObjIter", &g_ObjIterHandler, 0, nullptr, &haJSON, myself->GetIdentity(), &err); + g_ObjIterType = handlesys->CreateType("JSONObjIter", &g_ObjIterHandler, 0, &taDefault, &haDefault, myself->GetIdentity(), &err); if (!g_ObjIterType) { snprintf(error, maxlen, "Failed to create JSONObjIter handle type (err: %d)", err); return false; @@ -47,7 +51,7 @@ bool JsonExtension::SDK_OnLoad(char* error, size_t maxlen, bool late) g_pJsonManager = nullptr; } - g_pJsonManager = new JsonManager(); + g_pJsonManager = new(std::nothrow) JsonManager(); if (!g_pJsonManager) { snprintf(error, maxlen, "Failed to create JSON manager instance"); return false; diff --git a/plugins/include/json.inc b/plugins/include/json.inc index 10a298ae9..bbf2bc840 100755 --- a/plugins/include/json.inc +++ b/plugins/include/json.inc @@ -109,8 +109,8 @@ methodmap JSON < Handle * - ]: end array * * @note Needs to be freed using delete or CloseHandle() - * @note There is a limit of 32 parameters (defined in SourcePawn) - * including the format string, so the number of arguments must be less than or equal to 31 + * @note SourcePawn imposes a limit of 32 parameters per function (defined by SP_MAX_EXEC_PARAMS), + * which precludes the construction of complex objects with this method. * * @param format Format string * @param ... Arguments based on format string @@ -546,6 +546,8 @@ methodmap JSON < Handle /** * Get float value * + * @note Integers values are auto converted to float + * * @return float value */ public native float GetFloat(); @@ -618,6 +620,7 @@ methodmap JSON < Handle * Get float value by a JSON Pointer * * @note JSON Pointer paths are always resolved from the document root, not from the current value + * @note Integers values are auto converted to float * * @param path The JSON pointer string * @@ -907,6 +910,7 @@ methodmap JSON < Handle * Try to get float value by a JSON Pointer * * @note JSON Pointer paths are always resolved from the document root, not from the current value + * @note Integers values are auto converted to float * * @param path The JSON pointer string * @param value Store the float value @@ -1096,6 +1100,17 @@ methodmap JSON < Handle property int RefCount { public native get(); } + + /** + * Get the total number of values in the document + * + * @note Only works on immutable documents (parsed from JSON) + * @note Returns 0 for mutable documents or null handles + * @note Useful for performance planning and memory estimation + */ + property int ValCount { + public native get(); + } }; methodmap JSONObject < JSON @@ -1182,6 +1197,8 @@ methodmap JSONObject < JSON /** * Gets a float value from the object * + * @note Integers values are auto converted to float + * * @param key Key name * * @return Float value @@ -1367,6 +1384,20 @@ methodmap JSONObject < JSON */ public native bool Sort(JSON_SORT_ORDER order = JSON_SORT_ASC); + /** + * Rotates key-value pairs in the object + * + * @note This function takes a linear search time + * @note Only works on mutable objects + * @note Example: {"a":1,"b":2,"c":3,"d":4} rotate 1 becomes {"b":2,"c":3,"d":4,"a":1} + * + * @param idx Number of positions to rotate + * + * @return True on success, false if object is immutable or operation failed + * @error Invalid handle or attempting to rotate an immutable object + */ + public native bool Rotate(int idx); + /** * Retrieves the size of the object */ @@ -1486,6 +1517,8 @@ methodmap JSONArray < JSON /** * Gets a float value from the array * + * @note Integers values are auto converted to float + * * @param index Position in the array (starting from 0) * * @return The number as float @@ -1921,6 +1954,20 @@ methodmap JSONArray < JSON */ public native bool Sort(JSON_SORT_ORDER order = JSON_SORT_ASC); + /** + * Rotates array elements + * + * @note This function takes a linear search time + * @note Only works on mutable arrays + * @note Example: [1,2,3,4,5] rotate 2 becomes [3,4,5,1,2] + * + * @param idx Number of positions to rotate + * + * @return True on success, false if array is immutable or operation failed + * @error Invalid handle or attempting to rotate an immutable array + */ + public native bool Rotate(int idx); + /** * Retrieves the size of the array */ @@ -2164,6 +2211,7 @@ public void __pl_json_SetNTVOptional() MarkNativeAsOptional("JSONObject.FromString"); MarkNativeAsOptional("JSONObject.FromFile"); MarkNativeAsOptional("JSONObject.Sort"); + MarkNativeAsOptional("JSONObject.Rotate"); // JSONArray MarkNativeAsOptional("JSONArray.JSONArray"); @@ -2223,6 +2271,7 @@ public void __pl_json_SetNTVOptional() MarkNativeAsOptional("JSONArray.IndexOfInt64"); MarkNativeAsOptional("JSONArray.IndexOfFloat"); MarkNativeAsOptional("JSONArray.Sort"); + MarkNativeAsOptional("JSONArray.Rotate"); // JSON MarkNativeAsOptional("JSON.ToString"); @@ -2235,6 +2284,7 @@ public void __pl_json_SetNTVOptional() MarkNativeAsOptional("JSON.GetSerializedSize"); MarkNativeAsOptional("JSON.ReadSize.get"); MarkNativeAsOptional("JSON.RefCount.get"); + MarkNativeAsOptional("JSON.ValCount.get"); MarkNativeAsOptional("JSON.Type.get"); MarkNativeAsOptional("JSON.SubType.get"); MarkNativeAsOptional("JSON.IsArray.get"); diff --git a/plugins/testsuite/test_json.sp b/plugins/testsuite/test_json.sp index 2c0b14920..761f21be9 100755 --- a/plugins/testsuite/test_json.sp +++ b/plugins/testsuite/test_json.sp @@ -653,6 +653,64 @@ void Test_ObjectOperations() } TestEnd(); + // Test Rotate + TestStart("Object_Rotate_Forward"); + { + JSONObject obj = new JSONObject(); + obj.SetInt("a", 1); + obj.SetInt("b", 2); + obj.SetInt("c", 3); + obj.SetInt("d", 4); + + AssertTrue(obj.Rotate(1)); + + char key[32]; + obj.GetKey(0, key, sizeof(key)); + AssertStrEq(key, "b", "First key should be 'b' after rotate 1"); + obj.GetKey(3, key, sizeof(key)); + AssertStrEq(key, "a", "Last key should be 'a' after rotate 1"); + + delete obj; + } + TestEnd(); + + TestStart("Object_Rotate_Multiple"); + { + JSONObject obj = new JSONObject(); + obj.SetInt("first", 1); + obj.SetInt("second", 2); + obj.SetInt("third", 3); + obj.SetInt("fourth", 4); + obj.SetInt("fifth", 5); + + AssertTrue(obj.Rotate(2)); + + char key[32]; + obj.GetKey(0, key, sizeof(key)); + AssertStrEq(key, "third", "First key should be 'third' after rotate 2"); + obj.GetKey(4, key, sizeof(key)); + AssertStrEq(key, "second", "Last key should be 'second' after rotate 2"); + + delete obj; + } + TestEnd(); + + TestStart("Object_Rotate_Zero"); + { + JSONObject obj = new JSONObject(); + obj.SetInt("x", 1); + obj.SetInt("y", 2); + + AssertTrue(obj.Rotate(0)); + + char key[32]; + obj.GetKey(0, key, sizeof(key)); + AssertStrEq(key, "x", "Order should not change after rotate 0"); + + delete obj; + } + TestEnd(); + // Test Set with handle TestStart("Object_SetWithHandle"); { @@ -1013,6 +1071,83 @@ void Test_ArrayOperations() } TestEnd(); + // Test Rotate + TestStart("Array_Rotate_Forward"); + { + JSONArray arr = new JSONArray(); + arr.PushInt(1); + arr.PushInt(2); + arr.PushInt(3); + arr.PushInt(4); + arr.PushInt(5); + + AssertTrue(arr.Rotate(2)); + AssertEq(arr.GetInt(0), 3, "First element should be 3 after rotate 2"); + AssertEq(arr.GetInt(1), 4, "Second element should be 4"); + AssertEq(arr.GetInt(2), 5, "Third element should be 5"); + AssertEq(arr.GetInt(3), 1, "Fourth element should be 1"); + AssertEq(arr.GetInt(4), 2, "Fifth element should be 2"); + + delete arr; + } + TestEnd(); + + TestStart("Array_Rotate_Single"); + { + JSONArray arr = new JSONArray(); + arr.PushString("a"); + arr.PushString("b"); + arr.PushString("c"); + arr.PushString("d"); + + AssertTrue(arr.Rotate(1)); + + char buffer[32]; + arr.GetString(0, buffer, sizeof(buffer)); + AssertStrEq(buffer, "b", "First element should be 'b' after rotate 1"); + arr.GetString(3, buffer, sizeof(buffer)); + AssertStrEq(buffer, "a", "Last element should be 'a' after rotate 1"); + + delete arr; + } + TestEnd(); + + TestStart("Array_Rotate_Zero"); + { + JSONArray arr = new JSONArray(); + arr.PushInt(10); + arr.PushInt(20); + arr.PushInt(30); + + AssertTrue(arr.Rotate(0)); + AssertEq(arr.GetInt(0), 10, "Order should not change after rotate 0"); + AssertEq(arr.GetInt(1), 20); + AssertEq(arr.GetInt(2), 30); + + delete arr; + } + TestEnd(); + + TestStart("Array_Rotate_LargeIndex"); + { + JSONArray arr = new JSONArray(); + arr.PushInt(1); + arr.PushInt(2); + arr.PushInt(3); + + // Rotate by array length or greater should fail (idx must be < length) + AssertFalse(arr.Rotate(3), "Rotate by array length should fail"); + AssertFalse(arr.Rotate(10), "Rotate by value > length should fail"); + + // Values should remain unchanged + AssertEq(arr.GetInt(0), 1); + AssertEq(arr.GetInt(1), 2); + AssertEq(arr.GetInt(2), 3); + + delete arr; + } + TestEnd(); + // Test Push with handle TestStart("Array_PushHandle"); { @@ -1555,6 +1690,68 @@ void Test_ParseAndSerialize() } TestEnd(); + // Test ValCount (only works on immutable documents) + TestStart("Parse_ValCount_SimpleObject"); + { + JSON json = JSON.Parse("{\"a\":1,\"b\":2,\"c\":3}"); + AssertValidHandle(json); + int valCount = json.ValCount; + // Object has 7 values: 1 object + 3 keys ("a","b","c") + 3 integer values (1,2,3) + AssertEq(valCount, 7, "Simple object should have 7 values (object + keys + values)"); + delete json; + } + TestEnd(); + + TestStart("Parse_ValCount_NestedStructure"); + { + // {"user":{"name":"John","age":30},"items":[1,2,3]} + // Root object: 1 + // "user" key + nested object: 2 + // "name" key + "John" value: 2 + // "age" key + 30 value: 2 + // "items" key + array: 2 + // Three integers in array: 3 + // Total: 1 + 2 + 2 + 2 + 2 + 3 = 12 + JSON json = JSON.Parse("{\"user\":{\"name\":\"John\",\"age\":30},\"items\":[1,2,3]}"); + AssertValidHandle(json); + int valCount = json.ValCount; + AssertTrue(valCount > 0, "Nested structure should have multiple values"); + delete json; + } + TestEnd(); + + TestStart("Parse_ValCount_Array"); + { + JSON json = JSON.Parse("[1,2,3,4,5]"); + AssertValidHandle(json); + int valCount = json.ValCount; + // Array itself + 5 integers = 6 + AssertEq(valCount, 6, "Array with 5 elements should have 6 values"); + delete json; + } + TestEnd(); + + TestStart("Parse_ValCount_MutableReturnsZero"); + { + JSON json = JSON.Parse("{\"key\":\"value\"}", .is_mutable_doc = true); + AssertValidHandle(json); + int valCount = json.ValCount; + AssertEq(valCount, 0, "ValCount should return 0 for mutable documents"); + delete json; + } + TestEnd(); + + TestStart("Parse_ValCount_CreatedObjectReturnsZero"); + { + JSONObject obj = new JSONObject(); + obj.SetInt("a", 1); + obj.SetInt("b", 2); + int valCount = obj.ValCount; + AssertEq(valCount, 0, "ValCount should return 0 for created (mutable) objects"); + delete obj; + } + TestEnd(); + // Test ToString TestStart("Serialize_ToString"); {