From 63c18bba6c55081d3da94d44276dc32980df0a74 Mon Sep 17 00:00:00 2001 From: Flummi Date: Mon, 11 Jul 2022 13:10:17 +0000 Subject: [PATCH] https://github.com/alliedmodders/amxmodx/pull/993 --- modules/json/IJsonMngr.h | 42 ++++++++++++++++++++++++++++ modules/json/JsonMngr.cpp | 5 ++++ modules/json/JsonMngr.h | 18 ++++++++++++ modules/json/JsonNatives.cpp | 53 ++++++++++++++++++++++++++++++++++++ plugins/include/json.inc | 46 +++++++++++++++++++++++++++++++ 5 files changed, 164 insertions(+) diff --git a/modules/json/IJsonMngr.h b/modules/json/IJsonMngr.h index 6928c209..ee3a08e3 100644 --- a/modules/json/IJsonMngr.h +++ b/modules/json/IJsonMngr.h @@ -232,6 +232,15 @@ namespace AMXX */ virtual const char *ValueToString(JS_Handle value) = 0; + /** + * @brief Gets a string data length. + * + * @param value JSON handle + * + * @return Length of string data + */ + virtual size_t ValueToStringLen(JS_Handle value) = 0; + /** * @brief Gets a number. * @@ -277,6 +286,16 @@ namespace AMXX */ virtual const char *ArrayGetString(JS_Handle array, size_t index) = 0; + /** + * @brief Gets string data length from the array. + * + * @param array JSON handle + * @param index Position in the array (starting from 0) + * + * @return Length of string data + */ + virtual size_t ArrayGetStringLen(JS_Handle array, size_t index) = 0; + /** * @brief Gets a number from the array. * @@ -468,6 +487,20 @@ namespace AMXX */ virtual const char *ObjectGetString(JS_Handle object, const char *name, bool dotfunc = false) = 0; + /** + * @brief Gets string data length from the object. + * + * @note If dot notation is used some values may be inaccessible + * because valid names in JSON can contain dots. + * + * @param object JSON handle + * @param name Key name + * @param dotfunc True to use dot notation, false to not + * + * @return Length of string data + */ + virtual size_t ObjectGetStringLen(JS_Handle object, const char *name, bool dotfunc = false) = 0; + /** * @brief Gets a number from the object. * @@ -696,6 +729,15 @@ namespace AMXX */ virtual char *SerialToString(JS_Handle value, bool pretty) = 0; + /** + * @brief Slashes should be escaped or not when serializing JSON. + * + * @note This function sets a global setting and is not thread safe. + * + * @param escape_slashes True to escape slashes, false to not + */ + virtual void EscapeSlashes(int escape_slashes) = 0; + /** * @brief Frees serialized string. * diff --git a/modules/json/JsonMngr.cpp b/modules/json/JsonMngr.cpp index c48dcfae..83384ad5 100644 --- a/modules/json/JsonMngr.cpp +++ b/modules/json/JsonMngr.cpp @@ -465,3 +465,8 @@ char *JSONMngr::SerialToString(JS_Handle value, bool pretty) return (result) ? result : nullptr; } + +void JSONMngr::EscapeSlashes(int escape_slashes) +{ + json_set_escape_slashes(escape_slashes); +} diff --git a/modules/json/JsonMngr.h b/modules/json/JsonMngr.h index eb115558..bc0bd332 100644 --- a/modules/json/JsonMngr.h +++ b/modules/json/JsonMngr.h @@ -69,6 +69,10 @@ class JSONMngr : public IJSONMngr // Convert functions const char *ValueToString(JS_Handle value) override; + inline size_t ValueToStringLen(JS_Handle value) override + { + return json_value_get_string_len(m_Handles[value]->m_pValue); + } inline double ValueToNum(JS_Handle value) override { return json_value_get_number(m_Handles[value]->m_pValue); @@ -81,6 +85,10 @@ class JSONMngr : public IJSONMngr // Wrappers for Array API bool ArrayGetValue(JS_Handle array, size_t index, JS_Handle *handle) override; const char *ArrayGetString(JS_Handle array, size_t index) override; + inline size_t ArrayGetStringLen(JS_Handle array, size_t index) override + { + return json_array_get_string_len(m_Handles[array]->m_pArray, index); + } inline bool ArrayGetBool(JS_Handle array, size_t index) override { return json_array_get_boolean(m_Handles[array]->m_pArray, index) == 1; @@ -142,6 +150,15 @@ class JSONMngr : public IJSONMngr // Get functions bool ObjectGetValue(JS_Handle object, const char *name, JS_Handle *handle, bool dotfunc) override; const char *ObjectGetString(JS_Handle object, const char *name, bool dotfunc) override; + inline size_t ObjectGetStringLen(JS_Handle object, const char *name, bool dotfunc) override + { + if (!dotfunc) + { + return json_object_get_string_len(m_Handles[object]->m_pObject, name); + } + + return json_object_dotget_string_len(m_Handles[object]->m_pObject, name); + } double ObjectGetNum(JS_Handle object, const char *name, bool dotfunc) override; bool ObjectGetBool(JS_Handle object, const char *name, bool dotfunc) override; inline size_t ObjectGetCount(JS_Handle object) override @@ -171,6 +188,7 @@ class JSONMngr : public IJSONMngr bool SerialToBuffer(JS_Handle value, char *buffer, size_t size, bool pretty) override; bool SerialToFile(JS_Handle value, const char *filepath, bool pretty) override; char *SerialToString(JS_Handle value, bool pretty) override; + void EscapeSlashes(int escape_slashes) override; inline void FreeString(char *string) override { json_free_serialized_string(string); diff --git a/modules/json/JsonNatives.cpp b/modules/json/JsonNatives.cpp index 46871bfe..d752a7b6 100644 --- a/modules/json/JsonNatives.cpp +++ b/modules/json/JsonNatives.cpp @@ -231,6 +231,19 @@ static cell AMX_NATIVE_CALL amxx_json_get_number(AMX *amx, cell *params) return static_cast(JsonMngr->ValueToNum(value)); } +//native json_get_string_len(const JSON:value); +static cell AMX_NATIVE_CALL amxx_json_get_string_len(AMX *amx, cell *params) +{ + auto value = params[1]; + if (!JsonMngr->IsValidHandle(value)) + { + MF_LogError(amx, AMX_ERR_NATIVE, "Invalid JSON value! %d", value); + return 0; + } + + return JsonMngr->ValueToStringLen(value); +} + //native Float:json_get_real(const JSON:value); static cell AMX_NATIVE_CALL amxx_json_get_real(AMX *amx, cell *params) { @@ -290,6 +303,19 @@ static cell AMX_NATIVE_CALL amxx_json_array_get_string(AMX *amx, cell *params) return MF_SetAmxStringUTF8Char(amx, params[3], string, strlen(string), params[4]); } +//native json_array_get_string_len(const JSON:array, index); +static cell AMX_NATIVE_CALL amxx_json_array_get_string_len(AMX *amx, cell *params) +{ + auto array = params[1]; + if (!JsonMngr->IsValidHandle(array, Handle_Array)) + { + MF_LogError(amx, AMX_ERR_NATIVE, "Invalid JSON array! %d", array); + return 0; + } + + return JsonMngr->ArrayGetStringLen(array, params[2]); +} + //native json_array_get_number(const JSON:array, index); static cell AMX_NATIVE_CALL amxx_json_array_get_number(AMX *amx, cell *params) { @@ -578,6 +604,22 @@ static cell AMX_NATIVE_CALL amxx_json_object_get_string(AMX *amx, cell *params) return MF_SetAmxStringUTF8Char(amx, params[3], string, strlen(string), params[4]); } +//native json_object_get_string_len(const JSON:object, const name[], bool:dotfunc = false); +static cell AMX_NATIVE_CALL amxx_json_object_get_string_len(AMX *amx, cell *params) +{ + auto object = params[1]; + if (!JsonMngr->IsValidHandle(object, Handle_Object)) + { + MF_LogError(amx, AMX_ERR_NATIVE, "Invalid JSON object! %d", object); + return 0; + } + + int len; + auto name = MF_GetAmxString(amx, params[2], 0, &len); + + return JsonMngr->ObjectGetStringLen(object, name, params[3] != 0); +} + //native json_object_get_number(const JSON:object, const name[], bool:dotfunc = false); static cell AMX_NATIVE_CALL amxx_json_object_get_number(AMX *amx, cell *params) { @@ -871,6 +913,13 @@ static cell AMX_NATIVE_CALL amxx_json_serial_to_file(AMX *amx, cell *params) return JsonMngr->SerialToFile(value, path, params[3] != 0); } +//native json_set_escape_slashes(bool:escape_slashes = true); +static cell AMX_NATIVE_CALL amxx_json_set_escape_slashes(AMX *amx, cell *params) +{ + JsonMngr->EscapeSlashes(params[1] != 0); + return 1; +} + AMX_NATIVE_INFO JsonNatives[] = { { "json_parse", amxx_json_parse }, @@ -888,11 +937,13 @@ AMX_NATIVE_INFO JsonNatives[] = { "json_deep_copy", amxx_json_deep_copy }, { "json_free", amxx_json_free }, { "json_get_string", amxx_json_get_string }, + { "json_get_string_len", amxx_json_get_string_len }, { "json_get_number", amxx_json_get_number }, { "json_get_real", amxx_json_get_real }, { "json_get_bool", amxx_json_get_bool }, { "json_array_get_value", amxx_json_array_get_value }, { "json_array_get_string", amxx_json_array_get_string }, + { "json_array_get_string_len", amxx_json_array_get_string_len }, { "json_array_get_count", amxx_json_array_get_count }, { "json_array_get_number", amxx_json_array_get_number }, { "json_array_get_real", amxx_json_array_get_real }, @@ -913,6 +964,7 @@ AMX_NATIVE_INFO JsonNatives[] = { "json_array_clear", amxx_json_array_clear }, { "json_object_get_value", amxx_json_object_get_value }, { "json_object_get_string", amxx_json_object_get_string }, + { "json_object_get_string_len", amxx_json_object_get_string_len }, { "json_object_get_number", amxx_json_object_get_number }, { "json_object_get_real", amxx_json_object_get_real }, { "json_object_get_bool", amxx_json_object_get_bool }, @@ -931,6 +983,7 @@ AMX_NATIVE_INFO JsonNatives[] = { "json_serial_size", amxx_json_serial_size }, { "json_serial_to_string", amxx_json_serial_to_string }, { "json_serial_to_file", amxx_json_serial_to_file }, + { "json_set_escape_slashes", amxx_json_set_escape_slashes }, { nullptr, nullptr } }; diff --git a/plugins/include/json.inc b/plugins/include/json.inc index 61f608db..af892c58 100644 --- a/plugins/include/json.inc +++ b/plugins/include/json.inc @@ -228,6 +228,16 @@ native bool:json_free(&JSON:handle); */ native json_get_string(const JSON:value, buffer[], maxlen); +/** + * Gets string data length. + * + * @param value JSON handle + * + * @return Length of string data + * @error If passed value is not a valid handle + */ +native json_get_string_len(const JSON:value); + /** * Gets a number. * @@ -284,6 +294,17 @@ native JSON:json_array_get_value(const JSON:array, index); */ native json_array_get_string(const JSON:array, index, buffer[], maxlen); +/** + * Gets string data length from the array. + * + * @param array Array handle + * @param index Position in the array (starting from 0) + * + * @return Length of string data from the array + * @error If passed handle is not a valid array + */ +native json_array_get_string_len(const JSON:array, index); + /** * Gets a number from the array. * @@ -519,6 +540,21 @@ native JSON:json_object_get_value(const JSON:object, const name[], bool:dot_not */ native json_object_get_string(const JSON:object, const name[], buffer[], maxlen, bool:dot_not = false); +/** + * Gets string data length from the object. + * + * @note If dot notation is used some values may be inaccessible + * because valid names in JSON can contain dots. + * + * @param object Object handle + * @param name Key name + * @param dot_not True to use dot notation, false to not + * + * @return Length of string data from the object + * @error If passed handle is not a valid object + */ +native json_object_get_string_len(const JSON:object, const name[], bool:dot_not = false); + /** * Gets a number from the object. * @@ -775,3 +811,13 @@ native json_serial_to_string(const JSON:value, buffer[], maxlen, bool:pretty = f * @error If passed handle is not a valid value */ native bool:json_serial_to_file(const JSON:value, const file[], bool:pretty = false); + +/** + * Sets if slashes should be escaped or not when serializing JSON. By default slashes are escaped. + * + * @note This function sets a global setting and is not thread safe. + * + * @param escape_slashes True to escape slashes, false to not + */ + native json_set_escape_slashes(bool:escape_slashes = true); + \ No newline at end of file