Nilorea Library
C utilities for networking, threading, graphics
Loading...
Searching...
No Matches
n_json.c
Go to the documentation of this file.
1/*
2 * Nilorea Library
3 * Copyright (C) 2005-2026 Castagnier Mickael
4 *
5 * Licensed under the Apache License, Version 2.0 (the "License");
6 * you may not use this file except in compliance with the License.
7 * You may obtain a copy of the License at
8 *
9 * http://www.apache.org/licenses/LICENSE-2.0
10 *
11 * Unless required by applicable law or agreed to in writing, software
12 * distributed under the License is distributed on an "AS IS" BASIS,
13 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
14 * implied. See the License for the specific language governing
15 * permissions and limitations under the License.
16 *
17 * SPDX-License-Identifier: Apache-2.0
18 */
19
27#include "nilorea/n_json.h"
28#include "nilorea/n_log.h"
29
30#include <stdlib.h>
31#include <string.h>
32
33#ifdef HAVE_CJSON
34
35#include "cJSON.h"
36#include "nilorea/n_str.h"
37
38/* N_JSON is an opaque alias for cJSON; cast at the boundary. */
39#define AS_CJSON(p) ((cJSON*)(void*)(p))
40#define AS_CONST_CJSON(p) ((const cJSON*)(const void*)(p))
41#define AS_NJSON(p) ((N_JSON*)(void*)(p))
42
43N_JSON* n_json_parse(const char* text) {
44 if (!text)
45 return NULL;
46 return AS_NJSON(cJSON_Parse(text));
47}
48
49N_JSON* n_json_parse_file(const char* path) {
50 N_STR* body = NULL;
51 cJSON* root = NULL;
52 if (!path)
53 return NULL;
54 body = file_to_nstr((char*)path);
55 if (!body || !body->data) {
56 if (body)
57 free_nstr(&body);
58 return NULL;
59 }
60 root = cJSON_Parse(body->data);
61 free_nstr(&body);
62 return AS_NJSON(root);
63}
64
65void n_json_free(N_JSON** root) {
66 if (!root || !*root)
67 return;
68 cJSON_Delete(AS_CJSON(*root));
69 *root = NULL;
70}
71
72N_JSON* n_json_get(const N_JSON* obj, const char* key) {
73 if (!obj || !key)
74 return NULL;
75 return AS_NJSON(cJSON_GetObjectItemCaseSensitive(AS_CONST_CJSON(obj), key));
76}
77
78const char* n_json_string(const N_JSON* obj, const char* key, const char* dflt) {
79 const cJSON* it = obj && key ? cJSON_GetObjectItemCaseSensitive(AS_CONST_CJSON(obj), key) : NULL;
80 if (it && cJSON_IsString(it) && it->valuestring)
81 return it->valuestring;
82 return dflt;
83}
84
85char* n_json_string_dup(const N_JSON* obj, const char* key) {
86 const char* s = n_json_string(obj, key, NULL);
87 return s ? strdup(s) : NULL;
88}
89
90long n_json_int(const N_JSON* obj, const char* key, long dflt) {
91 const cJSON* it = obj && key ? cJSON_GetObjectItemCaseSensitive(AS_CONST_CJSON(obj), key) : NULL;
92 if (it && cJSON_IsNumber(it))
93 return (long)it->valuedouble;
94 return dflt;
95}
96
97int n_json_bool(const N_JSON* obj, const char* key, int dflt) {
98 const cJSON* it = obj && key ? cJSON_GetObjectItemCaseSensitive(AS_CONST_CJSON(obj), key) : NULL;
99 if (it && cJSON_IsBool(it))
100 return cJSON_IsTrue(it) ? 1 : 0;
101 return dflt;
102}
103
104int n_json_is_array(const N_JSON* v) {
105 return (v && cJSON_IsArray(AS_CONST_CJSON(v))) ? 1 : 0;
106}
107
109 return (v && cJSON_IsObject(AS_CONST_CJSON(v))) ? 1 : 0;
110}
111
112size_t n_json_array_size(const N_JSON* arr) {
113 if (!arr || !cJSON_IsArray(AS_CONST_CJSON(arr)))
114 return 0;
115 return (size_t)cJSON_GetArraySize(AS_CONST_CJSON(arr));
116}
117
118N_JSON* n_json_array_at(const N_JSON* arr, size_t i) {
119 if (!arr || !cJSON_IsArray(AS_CONST_CJSON(arr)))
120 return NULL;
121 return AS_NJSON(cJSON_GetArrayItem(AS_CONST_CJSON(arr), (int)i));
122}
123
124const char* n_json_as_string(const N_JSON* v, const char* dflt) {
125 const cJSON* c = AS_CONST_CJSON(v);
126 if (c && cJSON_IsString(c) && c->valuestring)
127 return c->valuestring;
128 return dflt;
129}
130
131#else /* !HAVE_CJSON */
132
133N_JSON* n_json_parse(const char* text) {
134 (void)text;
135 n_log(LOG_ERR, "n_json: cJSON not available (compile with -DHAVE_CJSON)");
136 return NULL;
137}
138N_JSON* n_json_parse_file(const char* path) {
139 (void)path;
140 n_log(LOG_ERR, "n_json: cJSON not available (compile with -DHAVE_CJSON)");
141 return NULL;
142}
143void n_json_free(N_JSON** root) {
144 (void)root;
145}
146N_JSON* n_json_get(const N_JSON* obj, const char* key) {
147 (void)obj;
148 (void)key;
149 return NULL;
150}
151const char* n_json_string(const N_JSON* obj, const char* key, const char* dflt) {
152 (void)obj;
153 (void)key;
154 return dflt;
155}
156char* n_json_string_dup(const N_JSON* obj, const char* key) {
157 (void)obj;
158 (void)key;
159 return NULL;
160}
161long n_json_int(const N_JSON* obj, const char* key, long dflt) {
162 (void)obj;
163 (void)key;
164 return dflt;
165}
166int n_json_bool(const N_JSON* obj, const char* key, int dflt) {
167 (void)obj;
168 (void)key;
169 return dflt;
170}
171int n_json_is_array(const N_JSON* v) {
172 (void)v;
173 return 0;
174}
175int n_json_is_object(const N_JSON* v) {
176 (void)v;
177 return 0;
178}
179size_t n_json_array_size(const N_JSON* arr) {
180 (void)arr;
181 return 0;
182}
183N_JSON* n_json_array_at(const N_JSON* arr, size_t i) {
184 (void)arr;
185 (void)i;
186 return NULL;
187}
188const char* n_json_as_string(const N_JSON* v, const char* dflt) {
189 (void)v;
190 return dflt;
191}
192
193#endif /* HAVE_CJSON */
char * key
#define n_log(__LEVEL__,...)
Logging function wrapper to get line and func.
Definition n_log.h:89
#define LOG_ERR
error conditions
Definition n_log.h:76
N_JSON * n_json_parse(const char *text)
Parse a JSON document from a NUL-terminated string.
Definition n_json.c:43
N_JSON * n_json_array_at(const N_JSON *arr, size_t i)
Get an array element by index.
Definition n_json.c:118
const char * n_json_as_string(const N_JSON *v, const char *dflt)
Get the string value of a node itself (e.g.
Definition n_json.c:124
char * n_json_string_dup(const N_JSON *obj, const char *key)
Duplicate a string member (caller frees), or NULL when absent.
Definition n_json.c:85
size_t n_json_array_size(const N_JSON *arr)
Number of elements in an array node.
Definition n_json.c:112
long n_json_int(const N_JSON *obj, const char *key, long dflt)
Get a numeric member as a long, or a default when absent/not a number.
Definition n_json.c:90
const char * n_json_string(const N_JSON *obj, const char *key, const char *dflt)
Get a string member, or a default when absent/not a string.
Definition n_json.c:78
int n_json_bool(const N_JSON *obj, const char *key, int dflt)
Get a boolean member, or a default when absent/not a boolean.
Definition n_json.c:97
int n_json_is_object(const N_JSON *v)
Report whether a node is a JSON object.
Definition n_json.c:108
void n_json_free(N_JSON **root)
Free a JSON tree and NULL the caller's pointer.
Definition n_json.c:65
struct N_JSON N_JSON
Opaque JSON node (a cJSON node under the hood).
Definition n_json.h:48
N_JSON * n_json_parse_file(const char *path)
Parse a JSON document from a file.
Definition n_json.c:49
int n_json_is_array(const N_JSON *v)
Report whether a node is a JSON array.
Definition n_json.c:104
N_JSON * n_json_get(const N_JSON *obj, const char *key)
Get a child member of an object by key (case-sensitive).
Definition n_json.c:72
char * data
the string
Definition n_str.h:63
#define free_nstr(__ptr)
free a N_STR structure and set the pointer to NULL
Definition n_str.h:203
N_STR * file_to_nstr(char *filename)
Load a whole file into a N_STR.
Definition n_str.c:288
A box including a string and his lenght.
Definition n_str.h:61
#define AS_CJSON(p)
Definition n_json.c:39
#define AS_CONST_CJSON(p)
Definition n_json.c:40
#define AS_NJSON(p)
Definition n_json.c:41
Small public JSON helper, a thin wrapper over the vendored cJSON.
Generic log system.
N_STR and string function declaration.