cjson_bindings/
cjson_ffi.rs

1#![allow(non_upper_case_globals)]
2#![allow(non_camel_case_types)]
3#![allow(non_snake_case)]
4#![allow(dead_code)]
5#![allow(clashing_extern_declarations)]
6
7use core::ffi::{c_char, c_double, c_int, c_void};
8
9// ========================
10// COSTANTI
11// ========================
12
13pub const cJSON_Invalid: c_int = 0;
14pub const cJSON_False: c_int = 1 << 0;
15pub const cJSON_True: c_int = 1 << 1;
16pub const cJSON_NULL: c_int = 1 << 2;
17pub const cJSON_Number: c_int = 1 << 3;
18pub const cJSON_String: c_int = 1 << 4;
19pub const cJSON_Array: c_int = 1 << 5;
20pub const cJSON_Object: c_int = 1 << 6;
21pub const cJSON_Raw: c_int = 1 << 7;
22
23pub const cJSON_IsReference: c_int = 256;
24pub const cJSON_StringIsConst: c_int = 512;
25
26pub const CJSON_VERSION_MAJOR: c_int = 1;
27pub const CJSON_VERSION_MINOR: c_int = 7;
28pub const CJSON_VERSION_PATCH: c_int = 19;
29
30pub const CJSON_NESTING_LIMIT: c_int = 1000;
31pub const CJSON_CIRCULAR_LIMIT: c_int = 10000;
32
33// ========================
34// TYPES
35// ========================
36
37// Struct cJSON
38#[repr(C)]
39pub struct cJSON {
40    pub next: *mut cJSON,
41    pub prev: *mut cJSON,
42    pub child: *mut cJSON,
43    pub type_: c_int, // "type" it is a reserved keyword in Rust
44    pub valuestring: *mut c_char,
45    pub valueint: c_int,
46    pub valuedouble: c_double,
47    pub string: *mut c_char,
48}
49
50pub type cJSON_bool = c_int;
51
52// cJSON_Hooks struct
53#[repr(C)]
54pub struct cJSON_Hooks {
55    pub malloc_fn: Option<unsafe extern "C" fn(size: usize) -> *mut c_void>,
56    pub free_fn: Option<unsafe extern "C" fn(ptr: *mut c_void)>,
57}
58
59// ========================
60// FUNCTIONS C (declare extern "C")
61// ========================
62
63unsafe extern "C" {
64    pub fn cJSON_Version() -> *const c_char;
65
66    pub fn cJSON_InitHooks(hooks: *mut cJSON_Hooks);
67
68    pub fn cJSON_Parse(value: *const c_char) -> *mut cJSON;
69    pub fn cJSON_ParseWithLength(value: *const c_char, buffer_length: usize) -> *mut cJSON;
70    pub fn cJSON_ParseWithOpts(
71        value: *const c_char,
72        return_parse_end: *mut *const c_char,
73        require_null_terminated: cJSON_bool,
74    ) -> *mut cJSON;
75    pub fn cJSON_ParseWithLengthOpts(
76        value: *const c_char,
77        buffer_length: usize,
78        return_parse_end: *mut *const c_char,
79        require_null_terminated: cJSON_bool,
80    ) -> *mut cJSON;
81
82    pub fn cJSON_Print(item: *const cJSON) -> *mut c_char;
83    pub fn cJSON_PrintUnformatted(item: *const cJSON) -> *mut c_char;
84    pub fn cJSON_PrintBuffered(item: *const cJSON, prebuffer: c_int, fmt: cJSON_bool) -> *mut c_char;
85    pub fn cJSON_PrintPreallocated(
86        item: *mut cJSON,
87        buffer: *mut c_char,
88        length: c_int,
89        format: cJSON_bool,
90    ) -> cJSON_bool;
91
92    pub fn cJSON_Delete(item: *mut cJSON);
93
94    pub fn cJSON_GetArraySize(array: *const cJSON) -> c_int;
95    pub fn cJSON_GetArrayItem(array: *const cJSON, index: c_int) -> *mut cJSON;
96    pub fn cJSON_GetObjectItem(object: *const cJSON, string: *const c_char) -> *mut cJSON;
97    pub fn cJSON_GetObjectItemCaseSensitive(object: *const cJSON, string: *const c_char) -> *mut cJSON;
98    pub fn cJSON_HasObjectItem(object: *const cJSON, string: *const c_char) -> cJSON_bool;
99
100    pub fn cJSON_GetErrorPtr() -> *const c_char;
101
102    pub fn cJSON_GetStringValue(item: *const cJSON) -> *const c_char;
103    pub fn cJSON_GetNumberValue(item: *const cJSON) -> c_double;
104
105    pub fn cJSON_IsInvalid(item: *const cJSON) -> cJSON_bool;
106    pub fn cJSON_IsFalse(item: *const cJSON) -> cJSON_bool;
107    pub fn cJSON_IsTrue(item: *const cJSON) -> cJSON_bool;
108    pub fn cJSON_IsBool(item: *const cJSON) -> cJSON_bool;
109    pub fn cJSON_IsNull(item: *const cJSON) -> cJSON_bool;
110    pub fn cJSON_IsNumber(item: *const cJSON) -> cJSON_bool;
111    pub fn cJSON_IsString(item: *const cJSON) -> cJSON_bool;
112    pub fn cJSON_IsArray(item: *const cJSON) -> cJSON_bool;
113    pub fn cJSON_IsObject(item: *const cJSON) -> cJSON_bool;
114    pub fn cJSON_IsRaw(item: *const cJSON) -> cJSON_bool;
115
116    pub fn cJSON_CreateNull() -> *mut cJSON;
117    pub fn cJSON_CreateTrue() -> *mut cJSON;
118    pub fn cJSON_CreateFalse() -> *mut cJSON;
119    pub fn cJSON_CreateBool(boolean: cJSON_bool) -> *mut cJSON;
120    pub fn cJSON_CreateNumber(num: c_double) -> *mut cJSON;
121    pub fn cJSON_CreateString(string: *const c_char) -> *mut cJSON;
122    pub fn cJSON_CreateRaw(raw: *const c_char) -> *mut cJSON;
123    pub fn cJSON_CreateArray() -> *mut cJSON;
124    pub fn cJSON_CreateObject() -> *mut cJSON;
125
126    pub fn cJSON_CreateStringReference(string: *const c_char) -> *mut cJSON;
127    pub fn cJSON_CreateObjectReference(child: *const cJSON) -> *mut cJSON;
128    pub fn cJSON_CreateArrayReference(child: *const cJSON) -> *mut cJSON;
129
130    pub fn cJSON_CreateIntArray(numbers: *const c_int, count: c_int) -> *mut cJSON;
131    pub fn cJSON_CreateFloatArray(numbers: *const f32, count: c_int) -> *mut cJSON;
132    pub fn cJSON_CreateDoubleArray(numbers: *const c_double, count: c_int) -> *mut cJSON;
133    pub fn cJSON_CreateStringArray(strings: *const *const c_char, count: c_int) -> *mut cJSON;
134
135    pub fn cJSON_AddItemToArray(array: *mut cJSON, item: *mut cJSON) -> cJSON_bool;
136    pub fn cJSON_AddItemToObject(object: *mut cJSON, string: *const c_char, item: *mut cJSON) -> cJSON_bool;
137    pub fn cJSON_AddItemToObjectCS(object: *mut cJSON, string: *const c_char, item: *mut cJSON) -> cJSON_bool;
138    pub fn cJSON_AddItemReferenceToArray(array: *mut cJSON, item: *mut cJSON) -> cJSON_bool;
139    pub fn cJSON_AddItemReferenceToObject(object: *mut cJSON, string: *const c_char, item: *mut cJSON) -> cJSON_bool;
140
141    pub fn cJSON_DetachItemViaPointer(parent: *mut cJSON, item: *mut cJSON) -> *mut cJSON;
142    pub fn cJSON_DetachItemFromArray(array: *mut cJSON, which: c_int) -> *mut cJSON;
143    pub fn cJSON_DeleteItemFromArray(array: *mut cJSON, which: c_int);
144    pub fn cJSON_DetachItemFromObject(object: *mut cJSON, string: *const c_char) -> *mut cJSON;
145    pub fn cJSON_DetachItemFromObjectCaseSensitive(object: *mut cJSON, string: *const c_char) -> *mut cJSON;
146    pub fn cJSON_DeleteItemFromObject(object: *mut cJSON, string: *const c_char);
147    pub fn cJSON_DeleteItemFromObjectCaseSensitive(object: *mut cJSON, string: *const c_char);
148
149    pub fn cJSON_InsertItemInArray(array: *mut cJSON, which: c_int, newitem: *mut cJSON) -> cJSON_bool;
150    pub fn cJSON_ReplaceItemViaPointer(parent: *mut cJSON, item: *mut cJSON, replacement: *mut cJSON) -> cJSON_bool;
151    pub fn cJSON_ReplaceItemInArray(array: *mut cJSON, which: c_int, newitem: *mut cJSON) -> cJSON_bool;
152    pub fn cJSON_ReplaceItemInObject(object: *mut cJSON, string: *const c_char, newitem: *mut cJSON) -> cJSON_bool;
153    pub fn cJSON_ReplaceItemInObjectCaseSensitive(object: *mut cJSON, string: *const c_char, newitem: *mut cJSON) -> cJSON_bool;
154
155    pub fn cJSON_Duplicate(item: *const cJSON, recurse: cJSON_bool) -> *mut cJSON;
156    pub fn cJSON_Compare(a: *const cJSON, b: *const cJSON, case_sensitive: cJSON_bool) -> cJSON_bool;
157
158    pub fn cJSON_Minify(json: *mut c_char);
159
160    pub fn cJSON_AddNullToObject(object: *mut cJSON, name: *const c_char) -> *mut cJSON;
161    pub fn cJSON_AddTrueToObject(object: *mut cJSON, name: *const c_char) -> *mut cJSON;
162    pub fn cJSON_AddFalseToObject(object: *mut cJSON, name: *const c_char) -> *mut cJSON;
163    pub fn cJSON_AddBoolToObject(object: *mut cJSON, name: *const c_char, boolean: cJSON_bool) -> *mut cJSON;
164    pub fn cJSON_AddNumberToObject(object: *mut cJSON, name: *const c_char, number: c_double) -> *mut cJSON;
165    pub fn cJSON_AddStringToObject(object: *mut cJSON, name: *const c_char, string: *const c_char) -> *mut cJSON;
166    pub fn cJSON_AddRawToObject(object: *mut cJSON, name: *const c_char, raw: *const c_char) -> *mut cJSON;
167    pub fn cJSON_AddObjectToObject(object: *mut cJSON, name: *const c_char) -> *mut cJSON;
168    pub fn cJSON_AddArrayToObject(object: *mut cJSON, name: *const c_char) -> *mut cJSON;
169
170    pub fn cJSON_SetNumberHelper(object: *mut cJSON, number: c_double) -> c_double;
171    pub fn cJSON_SetValuestring(object: *mut cJSON, valuestring: *const c_char) -> *mut c_char;
172
173    pub fn cJSON_malloc(size: usize) -> *mut c_void;
174    pub fn cJSON_free(object: *mut c_void);
175}
176
177// ========================
178// MACRO (translated from C to Rust)
179// ========================
180
181// cJSON_SetIntValue
182#[macro_export]
183macro_rules! cJSON_SetIntValue {
184    ($object:expr, $number:expr) => {
185        if let Some(obj) = unsafe { $object.as_mut() } {
186            obj.valueint = $number;
187            obj.valuedouble = $number as f64;
188            $number
189        } else {
190            $number
191        }
192    };
193}
194
195// cJSON_SetNumberValue
196#[macro_export]
197macro_rules! cJSON_SetNumberValue {
198    ($object:expr, $number:expr) => {
199        if let Some(obj) = unsafe { $object.as_mut() } {
200            crate::cJSON_SetNumberHelper(obj, $number as f64)
201        } else {
202            $number as f64
203        }
204    };
205}
206
207// cJSON_SetBoolValue
208#[macro_export]
209macro_rules! cJSON_SetBoolValue {
210    ($object:expr, $boolValue:expr) => {
211        if let Some(obj) = unsafe { $object.as_mut() } {
212            if (obj.type_ & (crate::cJSON_False | crate::cJSON_True)) != 0 {
213                obj.type_ = (obj.type_ & !(crate::cJSON_False | crate::cJSON_True)) | if $boolValue { crate::cJSON_True } else { crate::cJSON_False };
214                obj.type_
215            } else {
216                crate::cJSON_Invalid
217            }
218        } else {
219            crate::cJSON_Invalid
220        }
221    };
222}
223
224// cJSON_ArrayForEach
225#[macro_export]
226macro_rules! cJSON_ArrayForEach {
227    ($element:ident, $array:expr) => {
228        let mut $element = if let Some(arr) = unsafe { $array.as_ref() } {
229            arr.child
230        } else {
231            core::ptr::null_mut()
232        };
233        while !($element).is_null() {
234            {
235                // body of the loop goes here
236            }
237            $element = unsafe { (*$element).next };
238        }
239    };
240}
241
242// // ========================
243// // FUNZIONI DI UTILITÀ (opzionali)
244// // ========================
245
246// // Wrapper sicuro per cJSON_Delete (evita double free)
247// pub unsafe fn cJSON_Delete_safe(item: *mut cJSON) {
248//     if !item.is_null() {
249//         unsafe { cJSON_Delete(item); }
250//     }
251// }
252
253// // Wrapper per cJSON_Parse con gestione errori — usa alloc::string::String
254// pub unsafe fn cJSON_Parse_safe(json_str: &str) -> Option<*mut cJSON> {
255//     let c_str = CString::new(json_str).ok()?;
256//     let ptr = unsafe { cJSON_Parse(c_str.as_ptr()) };
257//     if ptr.is_null() {
258//         None
259//     } else {
260//         Some(ptr)
261//     }
262// }
263
264// // Wrapper per cJSON_Print con deallocazione automatica — ritorna alloc::string::String
265// pub unsafe fn cJSON_Print_safe(item: *mut cJSON) -> Option<String> {
266//     if item.is_null() {
267//         return None;
268//     }
269//     let c_str = unsafe { cJSON_Print(item) };
270//     if c_str.is_null() {
271//         return None;
272//     }
273//     let rust_str = unsafe { CStr::from_ptr(c_str).to_string_lossy().into_owned() };
274//     unsafe { cJSON_free(c_str as *mut c_void); }
275//     Some(rust_str)
276// }
277
278// // Wrapper per cJSON_GetStringValue — ritorna String
279// pub unsafe fn cJSON_GetStringValue_safe(item: *const cJSON) -> Option<String> {
280//     if item.is_null() {
281//         return None;
282//     }
283//     let c_str = unsafe { cJSON_GetStringValue(item) };
284//     if c_str.is_null() {
285//         return None;
286//     }
287//     Some(unsafe { CStr::from_ptr(c_str).to_string_lossy().into_owned() })
288// }
289
290// // Wrapper per cJSON_GetNumberValue — ritorna f64
291// pub unsafe fn cJSON_GetNumberValue_safe(item: *const cJSON) -> Option<f64> {
292//     if item.is_null() {
293//         return None;
294//     }
295//     Some(unsafe { cJSON_GetNumberValue(item) })
296// }