[winpr,utils] add JSON parser wrapper

as we now support cJSON and json-c we need to wrap the functions we use.
also allows drop in replacements for older cJSON versions lacking
certain functions.
This commit is contained in:
akallabeth 2024-05-14 14:58:29 +02:00
parent 29bb435ecc
commit 1b735a5c17
No known key found for this signature in database
GPG Key ID: A49454A3FC909FD5
5 changed files with 792 additions and 0 deletions

View File

@ -1,9 +1,18 @@
include(CMakeFindDependencyMacro)
if(NOT "@WITH_JSON_DISABLED@" AND NOT "@BUILD_SHARED_LIBS@")
if("@JSONC_FOUND@" AND NOT "@WITH_CJSON_REQUIRED@")
find_dependency(JSONC)
elseif("@CJSON_FOUND@")
find_dependency(cJSON)
endif()
endif()
@PACKAGE_INIT@
set(WinPR_VERSION_MAJOR "@WINPR_VERSION_MAJOR@")
set(WinPR_VERSION_MINOR "@WINPR_VERSION_MINOR@")
set(WinPR_VERSION_REVISION "@WINPR_VERSION_REVISION@")
set(WITH_WINPR_JSON "@WITH_WINPR_JSON@")
set_and_check(WinPR_INCLUDE_DIR "@PACKAGE_WINPR_INCLUDE_DIR@")

View File

@ -34,6 +34,8 @@
#cmakedefine WITH_INTERNAL_MD4
#cmakedefine WITH_INTERNAL_MD5
#cmakedefine WITH_WINPR_JSON
#cmakedefine WITH_DEBUG_NTLM
#cmakedefine WITH_DEBUG_THREADS
#cmakedefine WITH_DEBUG_EVENTS

View File

@ -0,0 +1,93 @@
/**
* FreeRDP: A Remote Desktop Protocol Implementation
* JSON parser wrapper
*
* Copyright 2024 Armin Novak <anovak@thincast.com>
* Copyright 2024 Thincast Technologies GmbH
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#ifndef WINPR_UTILS_JSON
#define WINPR_UTILS_JSON
#include <winpr/winpr.h>
#include <winpr/string.h>
#include <winpr/wtypes.h>
#ifdef __cplusplus
extern "C"
{
#endif
typedef void WINPR_JSON;
WINPR_API int WINPR_JSON_version(char* buffer, size_t len);
WINPR_API WINPR_JSON* WINPR_JSON_Parse(const char* value);
WINPR_API WINPR_JSON* WINPR_JSON_ParseWithLength(const char* value, size_t buffer_length);
WINPR_API void WINPR_JSON_Delete(WINPR_JSON* item);
WINPR_API size_t WINPR_JSON_GetArraySize(const WINPR_JSON* array);
WINPR_API WINPR_JSON* WINPR_JSON_GetArrayItem(const WINPR_JSON* array, size_t index);
WINPR_API WINPR_JSON* WINPR_JSON_GetObjectItem(const WINPR_JSON* object, const char* string);
WINPR_API WINPR_JSON* WINPR_JSON_GetObjectItemCaseSensitive(const WINPR_JSON* object,
const char* string);
WINPR_API BOOL WINPR_JSON_HasObjectItem(const WINPR_JSON* object, const char* string);
WINPR_API const char* WINPR_JSON_GetErrorPtr(void);
WINPR_API const char* WINPR_JSON_GetStringValue(WINPR_JSON* item);
WINPR_API double WINPR_JSON_GetNumberValue(const WINPR_JSON* item);
WINPR_API BOOL WINPR_JSON_IsInvalid(const WINPR_JSON* item);
WINPR_API BOOL WINPR_JSON_IsFalse(const WINPR_JSON* item);
WINPR_API BOOL WINPR_JSON_IsTrue(const WINPR_JSON* item);
WINPR_API BOOL WINPR_JSON_IsBool(const WINPR_JSON* item);
WINPR_API BOOL WINPR_JSON_IsNull(const WINPR_JSON* item);
WINPR_API BOOL WINPR_JSON_IsNumber(const WINPR_JSON* item);
WINPR_API BOOL WINPR_JSON_IsString(const WINPR_JSON* item);
WINPR_API BOOL WINPR_JSON_IsArray(const WINPR_JSON* item);
WINPR_API BOOL WINPR_JSON_IsObject(const WINPR_JSON* item);
WINPR_API WINPR_JSON* WINPR_JSON_CreateNull(void);
WINPR_API WINPR_JSON* WINPR_JSON_CreateTrue(void);
WINPR_API WINPR_JSON* WINPR_JSON_CreateFalse(void);
WINPR_API WINPR_JSON* WINPR_JSON_CreateBool(BOOL boolean);
WINPR_API WINPR_JSON* WINPR_JSON_CreateNumber(double num);
WINPR_API WINPR_JSON* WINPR_JSON_CreateString(const char* string);
WINPR_API WINPR_JSON* WINPR_JSON_CreateArray(void);
WINPR_API WINPR_JSON* WINPR_JSON_CreateObject(void);
WINPR_API WINPR_JSON* WINPR_JSON_AddNullToObject(WINPR_JSON* object, const char* name);
WINPR_API WINPR_JSON* WINPR_JSON_AddTrueToObject(WINPR_JSON* object, const char* name);
WINPR_API WINPR_JSON* WINPR_JSON_AddFalseToObject(WINPR_JSON* object, const char* name);
WINPR_API WINPR_JSON* WINPR_JSON_AddBoolToObject(WINPR_JSON* object, const char* name,
BOOL boolean);
WINPR_API WINPR_JSON* WINPR_JSON_AddNumberToObject(WINPR_JSON* object, const char* name,
double number);
WINPR_API WINPR_JSON* WINPR_JSON_AddStringToObject(WINPR_JSON* object, const char* name,
const char* string);
WINPR_API WINPR_JSON* WINPR_JSON_AddObjectToObject(WINPR_JSON* object, const char* name);
WINPR_API WINPR_JSON* WINPR_JSON_AddArrayToObject(WINPR_JSON* object, const char* name);
WINPR_API char* WINPR_JSON_Print(WINPR_JSON* item);
WINPR_API char* WINPR_JSON_PrintUnformatted(WINPR_JSON* item);
#ifdef __cplusplus
}
#endif
#endif

View File

@ -16,6 +16,7 @@
# limitations under the License.
include(CheckFunctionExists)
include(CMakeDependentOption)
set(CMAKE_INCLUDE_CURRENT_DIR ON)
@ -185,6 +186,42 @@ if (WINPR_HAVE_UNWIND_H)
endif()
endif()
option(WITH_JSON_DISABLED "Build without any JSON support" OFF)
CMAKE_DEPENDENT_OPTION(WITH_CJSON_REQUIRED "Build with cJSON (fail if not found)" OFF "NOT WITH_JSON_DISABLED" OFF)
CMAKE_DEPENDENT_OPTION(WITH_JSONC_REQUIRED "Build with JSON-C (fail if not found)" OFF "NOT WITH_JSON_DISABLED" OFF)
if (NOT WITH_JSON_DISABLED)
if (WITH_CJSON_REQUIRED)
find_package(cJSON REQUIRED)
else()
find_package(cJSON)
endif()
if (WITH_JSONC_REQUIRED)
find_package(JSONC REQUIRED)
else()
find_package(JSONC)
endif()
if (JSONC_FOUND AND NOT WITH_CJSON_REQUIRED)
winpr_library_add_private(${JSONC_LIBRARIES})
winpr_include_directory_add(${JSONC_INCLUDE_DIRS})
winpr_definition_add(-DWITH_JSONC)
set(WITH_WINPR_JSON ON CACHE INTERNAL "internal")
elseif (CJSON_FOUND)
winpr_library_add_private(${CJSON_LIBRARIES})
winpr_include_directory_add(${CJSON_INCLUDE_DIRS})
winpr_definition_add(-DWITH_CJSON)
set(WITH_WINPR_JSON ON CACHE INTERNAL "internal")
else()
set(WITH_WINPR_JSON OFF CACHE INTERNAL "internal")
message("compiling without JSON support. Install cJSON or json-c to enable")
endif()
else()
set(WITH_WINPR_JSON OFF CACHE INTERNAL "internal")
message("forced compile without JSON support. Set -DWITH_JSON_DISABLED=OFF to enable compile time detection")
endif()
winpr_module_add(json/json.c)
winpr_module_add(${SRCS}
${COLLECTIONS_SRCS}
${WLOG_SRCS}

View File

@ -0,0 +1,651 @@
/**
* FreeRDP: A Remote Desktop Protocol Implementation
* JSON parser wrapper
*
* Copyright 2024 Armin Novak <anovak@thincast.com>
* Copyright 2024 Thincast Technologies GmbH
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#include <math.h>
#include <winpr/json.h>
#include <winpr/assert.h>
#if defined(WITH_CJSON)
#include <cjson/cJSON.h>
#endif
#if defined(WITH_JSONC)
#include <json-c/json.h>
#endif
#if defined(WITH_CJSON)
#if CJSON_VERSION_MAJOR == 1
#if CJSON_VERSION_MINOR <= 7
#if CJSON_VERSION_PATCH < 13
#define USE_CJSON_COMPAT
#endif
#endif
#endif
#endif
#if defined(USE_CJSON_COMPAT)
static double cJSON_GetNumberValue(const cJSON* const prop)
{
#ifndef NAN
#ifdef _WIN32
#define NAN sqrt(-1.0)
#define COMPAT_NAN_UNDEF
#else
#define NAN 0.0 / 0.0
#define COMPAT_NAN_UNDEF
#endif
#endif
if (!cJSON_IsNumber(prop))
return NAN;
char* val = cJSON_GetStringValue(prop);
if (!val)
return NAN;
errno = 0;
char* endptr = NULL;
double dval = strtod(val, &endptr);
if (val == endptr)
return NAN;
if (endptr != NULL)
return NAN;
if (errno != 0)
return NAN;
return dval;
#ifdef COMPAT_NAN_UNDEF
#undef NAN
#endif
}
static cJSON* cJSON_ParseWithLength(const char* value, size_t buffer_length)
{
// Check for string '\0' termination.
const size_t slen = strnlen(value, buffer_length);
if (slen >= buffer_length)
{
if (value[buffer_length] != '\0')
return NULL;
}
return cJSON_Parse(value);
}
#endif
int WINPR_JSON_version(char* buffer, size_t len)
{
#if defined(WITH_JSONC)
return _snprintf(buffer, len, "json-c %s", json_c_version());
#elif defined(WITH_CJSON)
return _snprintf(buffer, len, "cJSON %s", cJSON_Version());
#else
return _snprintf(buffer, len, "JSON support not available");
#endif
}
WINPR_JSON* WINPR_JSON_Parse(const char* value)
{
#if defined(WITH_JSONC)
return json_tokener_parse(value);
#elif defined(WITH_CJSON)
return cJSON_Parse(value);
#else
WINPR_UNUSED(value);
return NULL;
#endif
}
WINPR_JSON* WINPR_JSON_ParseWithLength(const char* value, size_t buffer_length)
{
#if defined(WITH_JSONC)
WINPR_ASSERT(buffer_length <= INT_MAX);
json_tokener* tok = json_tokener_new();
if (!tok)
return NULL;
json_object* obj = json_tokener_parse_ex(tok, value, (int)buffer_length);
json_tokener_free(tok);
return obj;
#elif defined(WITH_CJSON)
return cJSON_ParseWithLength(value, buffer_length);
#else
WINPR_UNUSED(value);
WINPR_UNUSED(buffer_length);
return NULL;
#endif
}
void WINPR_JSON_Delete(WINPR_JSON* item)
{
#if defined(WITH_JSONC)
json_object_put((json_object*)item);
#elif defined(WITH_CJSON)
cJSON_Delete((cJSON*)item);
#else
WINPR_UNUSED(item);
#endif
}
WINPR_JSON* WINPR_JSON_GetArrayItem(const WINPR_JSON* array, size_t index)
{
#if defined(WITH_JSONC)
return json_object_array_get_idx((const json_object*)array, index);
#elif defined(WITH_CJSON)
WINPR_ASSERT(index <= INT_MAX);
return cJSON_GetArrayItem((const cJSON*)array, (INT)index);
#else
WINPR_UNUSED(array);
WINPR_UNUSED(index);
return NULL;
#endif
}
size_t WINPR_JSON_GetArraySize(const WINPR_JSON* array)
{
#if defined(WITH_JSONC)
return json_object_array_length((const json_object*)array);
#elif defined(WITH_CJSON)
const int rc = cJSON_GetArraySize((const cJSON*)array);
if (rc <= 0)
return 0;
return (size_t)rc;
#else
WINPR_UNUSED(array);
return 0;
#endif
}
WINPR_JSON* WINPR_JSON_GetObjectItem(const WINPR_JSON* const object, const char* const string)
{
#if defined(WITH_JSONC)
return json_object_object_get((const json_object*)object, string);
#elif defined(WITH_CJSON)
return cJSON_GetObjectItem((const cJSON*)object, string);
#else
WINPR_UNUSED(object);
WINPR_UNUSED(string);
return NULL;
#endif
}
WINPR_JSON* WINPR_JSON_GetObjectItemCaseSensitive(const WINPR_JSON* const object,
const char* const string)
{
#if defined(WITH_JSONC)
return json_object_object_get((const json_object*)object, string);
#elif defined(WITH_CJSON)
return cJSON_GetObjectItemCaseSensitive((const cJSON*)object, string);
#else
WINPR_UNUSED(object);
WINPR_UNUSED(string);
return NULL;
#endif
}
BOOL WINPR_JSON_HasObjectItem(const WINPR_JSON* object, const char* string)
{
#if defined(WITH_JSONC)
return json_object_object_get_ex((const json_object*)object, string, NULL);
#elif defined(WITH_CJSON)
return cJSON_HasObjectItem((const cJSON*)object, string);
#else
WINPR_UNUSED(object);
WINPR_UNUSED(string);
return FALSE;
#endif
}
const char* WINPR_JSON_GetErrorPtr(void)
{
#if defined(WITH_JSONC)
return json_util_get_last_err();
#elif defined(WITH_CJSON)
return cJSON_GetErrorPtr();
#else
return NULL;
#endif
}
const char* WINPR_JSON_GetStringValue(WINPR_JSON* item)
{
#if defined(WITH_JSONC)
return json_object_get_string((json_object*)item);
#elif defined(WITH_CJSON)
return cJSON_GetStringValue((cJSON*)item);
#else
WINPR_UNUSED(item);
return NULL;
#endif
}
double WINPR_JSON_GetNumberValue(const WINPR_JSON* const item)
{
#if defined(WITH_JSONC)
return json_object_get_double((const json_object*)item);
#elif defined(WITH_CJSON)
return cJSON_GetNumberValue((const cJSON*)item);
#else
WINPR_UNUSED(item);
return nan(NULL);
#endif
}
BOOL WINPR_JSON_IsInvalid(const WINPR_JSON* const item)
{
#if defined(WITH_JSONC)
if (WINPR_JSON_IsArray(item))
return FALSE;
if (WINPR_JSON_IsObject(item))
return FALSE;
if (WINPR_JSON_IsNull(item))
return FALSE;
if (WINPR_JSON_IsNumber(item))
return FALSE;
if (WINPR_JSON_IsBool(item))
return FALSE;
if (WINPR_JSON_IsString(item))
return FALSE;
return TRUE;
#elif defined(WITH_CJSON)
return cJSON_IsInvalid((const cJSON*)item);
#else
WINPR_UNUSED(item);
return TRUE;
#endif
}
BOOL WINPR_JSON_IsFalse(const WINPR_JSON* const item)
{
#if defined(WITH_JSONC)
if (!json_object_is_type((const json_object*)item, json_type_boolean))
return FALSE;
json_bool val = json_object_get_boolean((const json_object*)item);
return val == 0;
#elif defined(WITH_CJSON)
return cJSON_IsFalse((const cJSON*)item);
#else
WINPR_UNUSED(item);
return FALSE;
#endif
}
BOOL WINPR_JSON_IsTrue(const WINPR_JSON* const item)
{
#if defined(WITH_JSONC)
if (!json_object_is_type((const json_object*)item, json_type_boolean))
return FALSE;
json_bool val = json_object_get_boolean((const json_object*)item);
return val != 0;
#elif defined(WITH_CJSON)
return cJSON_IsTrue((const cJSON*)item);
#else
WINPR_UNUSED(item);
return FALSE;
#endif
}
BOOL WINPR_JSON_IsBool(const WINPR_JSON* const item)
{
#if defined(WITH_JSONC)
return json_object_is_type((const json_object*)item, json_type_boolean);
#elif defined(WITH_CJSON)
return cJSON_IsBool((const cJSON*)item);
#else
WINPR_UNUSED(item);
return FALSE;
#endif
}
BOOL WINPR_JSON_IsNull(const WINPR_JSON* const item)
{
#if defined(WITH_JSONC)
return json_object_is_type((const json_object*)item, json_type_null);
#elif defined(WITH_CJSON)
return cJSON_IsNull((const cJSON*)item);
#else
WINPR_UNUSED(item);
return FALSE;
#endif
}
BOOL WINPR_JSON_IsNumber(const WINPR_JSON* const item)
{
#if defined(WITH_JSONC)
return json_object_is_type((const json_object*)item, json_type_int) ||
json_object_is_type((const json_object*)item, json_type_double);
#elif defined(WITH_CJSON)
return cJSON_IsNumber((const cJSON*)item);
#else
WINPR_UNUSED(item);
return FALSE;
#endif
}
BOOL WINPR_JSON_IsString(const WINPR_JSON* const item)
{
#if defined(WITH_JSONC)
return json_object_is_type((const json_object*)item, json_type_string);
#elif defined(WITH_CJSON)
return cJSON_IsString((const cJSON*)item);
#else
WINPR_UNUSED(item);
return FALSE;
#endif
}
BOOL WINPR_JSON_IsArray(const WINPR_JSON* const item)
{
#if defined(WITH_JSONC)
return json_object_is_type((const json_object*)item, json_type_array);
#elif defined(WITH_CJSON)
return cJSON_IsArray((const cJSON*)item);
#else
WINPR_UNUSED(item);
return FALSE;
#endif
}
BOOL WINPR_JSON_IsObject(const WINPR_JSON* const item)
{
#if defined(WITH_JSONC)
return json_object_is_type((const json_object*)item, json_type_object);
#elif defined(WITH_CJSON)
return cJSON_IsObject((const cJSON*)item);
#else
WINPR_UNUSED(item);
return FALSE;
#endif
}
WINPR_JSON* WINPR_JSON_CreateNull(void)
{
#if defined(WITH_JSONC)
return json_object_new_null();
#elif defined(WITH_CJSON)
return cJSON_CreateNull();
#else
return NULL;
#endif
}
WINPR_JSON* WINPR_JSON_CreateTrue(void)
{
#if defined(WITH_JSONC)
return json_object_new_boolean(TRUE);
#elif defined(WITH_CJSON)
return cJSON_CreateTrue();
#else
return NULL;
#endif
}
WINPR_JSON* WINPR_JSON_CreateFalse(void)
{
#if defined(WITH_JSONC)
return json_object_new_boolean(FALSE);
#elif defined(WITH_CJSON)
return cJSON_CreateFalse();
#else
return NULL;
#endif
}
WINPR_JSON* WINPR_JSON_CreateBool(BOOL boolean)
{
#if defined(WITH_JSONC)
return json_object_new_boolean(boolean);
#elif defined(WITH_CJSON)
return cJSON_CreateBool(boolean);
#else
WINPR_UNUSED(boolean);
return NULL;
#endif
}
WINPR_JSON* WINPR_JSON_CreateNumber(double num)
{
#if defined(WITH_JSONC)
return json_object_new_double(num);
#elif defined(WITH_CJSON)
return cJSON_CreateNumber(num);
#else
WINPR_UNUSED(num);
return NULL;
#endif
}
WINPR_JSON* WINPR_JSON_CreateString(const char* string)
{
#if defined(WITH_JSONC)
return json_object_new_string(string);
#elif defined(WITH_CJSON)
return cJSON_CreateString(string);
#else
WINPR_UNUSED(string);
return NULL;
#endif
}
WINPR_JSON* WINPR_JSON_CreateArray(void)
{
#if defined(WITH_JSONC)
return json_object_new_array();
#elif defined(WITH_CJSON)
return cJSON_CreateArray();
#else
return NULL;
#endif
}
WINPR_JSON* WINPR_JSON_CreateObject(void)
{
#if defined(WITH_JSONC)
return json_object_new_object();
#elif defined(WITH_CJSON)
return cJSON_CreateObject();
#else
return NULL;
#endif
}
WINPR_JSON* WINPR_JSON_AddNullToObject(WINPR_JSON* const object, const char* const name)
{
#if defined(WITH_JSONC)
struct json_object* obj = json_object_new_null();
if (json_object_object_add((json_object*)object, name, obj) != 0)
{
json_object_put(obj);
return NULL;
}
return obj;
#elif defined(WITH_CJSON)
return cJSON_AddNullToObject((cJSON*)object, name);
#else
WINPR_UNUSED(object);
WINPR_UNUSED(name);
return NULL;
#endif
}
WINPR_JSON* WINPR_JSON_AddTrueToObject(WINPR_JSON* const object, const char* const name)
{
#if defined(WITH_JSONC)
struct json_object* obj = json_object_new_boolean(TRUE);
if (json_object_object_add((json_object*)object, name, obj) != 0)
{
json_object_put(obj);
return NULL;
}
return obj;
#elif defined(WITH_CJSON)
return cJSON_AddTrueToObject((cJSON*)object, name);
#else
WINPR_UNUSED(object);
WINPR_UNUSED(name);
return NULL;
#endif
}
WINPR_JSON* WINPR_JSON_AddFalseToObject(WINPR_JSON* const object, const char* const name)
{
#if defined(WITH_JSONC)
struct json_object* obj = json_object_new_boolean(FALSE);
if (json_object_object_add((json_object*)object, name, obj) != 0)
{
json_object_put(obj);
return NULL;
}
return obj;
#elif defined(WITH_CJSON)
return cJSON_AddFalseToObject((cJSON*)object, name);
#else
WINPR_UNUSED(object);
WINPR_UNUSED(name);
return NULL;
#endif
}
WINPR_JSON* WINPR_JSON_AddBoolToObject(WINPR_JSON* const object, const char* const name,
BOOL boolean)
{
#if defined(WITH_JSONC)
struct json_object* obj = json_object_new_boolean(boolean);
if (json_object_object_add((json_object*)object, name, obj) != 0)
{
json_object_put(obj);
return NULL;
}
return obj;
#elif defined(WITH_CJSON)
return cJSON_AddBoolToObject((cJSON*)object, name, boolean);
#else
WINPR_UNUSED(object);
WINPR_UNUSED(name);
WINPR_UNUSED(boolean);
return NULL;
#endif
}
WINPR_JSON* WINPR_JSON_AddNumberToObject(WINPR_JSON* const object, const char* const name,
double number)
{
#if defined(WITH_JSONC)
struct json_object* obj = json_object_new_double(number);
if (json_object_object_add((json_object*)object, name, obj) != 0)
{
json_object_put(obj);
return NULL;
}
return obj;
#elif defined(WITH_CJSON)
return cJSON_AddNumberToObject((cJSON*)object, name, number);
#else
WINPR_UNUSED(object);
WINPR_UNUSED(name);
WINPR_UNUSED(number);
return NULL;
#endif
}
WINPR_JSON* WINPR_JSON_AddStringToObject(WINPR_JSON* const object, const char* const name,
const char* const string)
{
#if defined(WITH_JSONC)
struct json_object* obj = json_object_new_string(string);
if (json_object_object_add((json_object*)object, name, obj) != 0)
{
json_object_put(obj);
return NULL;
}
return obj;
#elif defined(WITH_CJSON)
return cJSON_AddStringToObject((cJSON*)object, name, string);
#else
WINPR_UNUSED(object);
WINPR_UNUSED(name);
WINPR_UNUSED(string);
return NULL;
#endif
}
WINPR_JSON* WINPR_JSON_AddObjectToObject(WINPR_JSON* const object, const char* const name)
{
#if defined(WITH_JSONC)
struct json_object* obj = json_object_new_object();
if (json_object_object_add((json_object*)object, name, obj) != 0)
{
json_object_put(obj);
return NULL;
}
return obj;
#elif defined(WITH_CJSON)
return cJSON_AddObjectToObject((cJSON*)object, name);
#else
WINPR_UNUSED(object);
WINPR_UNUSED(name);
return NULL;
#endif
}
WINPR_JSON* WINPR_JSON_AddArrayToObject(WINPR_JSON* const object, const char* const name)
{
#if defined(WITH_JSONC)
struct json_object* obj = json_object_new_array();
if (json_object_object_add((json_object*)object, name, obj) != 0)
{
json_object_put(obj);
return NULL;
}
return obj;
#elif defined(WITH_CJSON)
return cJSON_AddArrayToObject((cJSON*)object, name);
#else
WINPR_UNUSED(object);
WINPR_UNUSED(name);
return NULL;
#endif
}
char* WINPR_JSON_Print(WINPR_JSON* item)
{
#if defined(WITH_JSONC)
const char* str = json_object_to_json_string_ext((json_object*)item, JSON_C_TO_STRING_PRETTY);
if (!str)
return NULL;
return _strdup(str);
#elif defined(WITH_CJSON)
return cJSON_Print((const cJSON*)item);
#else
WINPR_UNUSED(item);
return NULL;
#endif
}
char* WINPR_JSON_PrintUnformatted(WINPR_JSON* item)
{
#if defined(WITH_JSONC)
const char* str = json_object_to_json_string_ext((json_object*)item, JSON_C_TO_STRING_PLAIN);
if (!str)
return NULL;
return _strdup(str);
#elif defined(WITH_CJSON)
return cJSON_PrintUnformatted((const cJSON*)item);
#else
WINPR_UNUSED(item);
return NULL;
#endif
}