1 // Copyright (c) 2023 Huawei Device Co., Ltd.
2 // Licensed under the Apache License, Version 2.0 (the "License");
3 // you may not use this file except in compliance with the License.
4 // You may obtain a copy of the License at
5 //
6 // http://www.apache.org/licenses/LICENSE-2.0
7 //
8 // Unless required by applicable law or agreed to in writing, software
9 // distributed under the License is distributed on an "AS IS" BASIS,
10 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
11 // See the License for the specific language governing permissions and
12 // limitations under the License.
13
14 use std::ffi::{CStr, CString};
15 use std::os::raw::{c_char, c_double, c_int};
16 use std::ptr::*;
17 use ylong_json::*;
18
19 const RFC7159_EXAMPLE1: &str = r#"
20 {
21 "Image": {
22 "Width": 800,
23 "Height": 600,
24 "Title": "View from 15th Floor",
25 "Thumbnail": {
26 "Url": "http://www.example.com/image/481989943",
27 "Height": 125,
28 "Width": 100
29 },
30 "Animated" : false,
31 "IDs": [116, 943, 234, 38793]
32 }
33 }
34 "#;
35
36 macro_rules! test_json {
37 ($json: expr) => {{
38 let target = str_to_c_char("Image");
39 let image = ylong_json_get_object_item($json, target);
40 let _ = CString::from_raw(target);
41
42 assert_eq!(ylong_json_is_object(image), 1);
43
44 let target = str_to_c_char("Width");
45 let width = ylong_json_get_object_item(image, target);
46 let _ = CString::from_raw(target);
47 let mut ptr: c_double = 0f64;
48 assert_eq!(
49 ylong_json_get_double_value_from_number(width, &mut ptr as *mut c_double),
50 1
51 );
52 assert_eq!(ptr, 800f64);
53
54 let target = str_to_c_char("Height");
55 let height = ylong_json_get_object_item(image, target);
56 let _ = CString::from_raw(target);
57 let mut ptr: c_double = 0f64;
58 assert_eq!(
59 ylong_json_get_double_value_from_number(height, &mut ptr as *mut c_double),
60 1
61 );
62 assert_eq!(ptr, 600f64);
63
64 let target = str_to_c_char("Title");
65 let title = ylong_json_get_object_item(image, target);
66 let _ = CString::from_raw(target);
67 let mut ptr: *mut c_char = null_mut::<c_char>();
68 assert_eq!(
69 ylong_json_get_value_from_string(title, &mut ptr as *mut *mut c_char),
70 1
71 );
72 assert_eq!(
73 CStr::from_ptr(ptr).to_str().unwrap(),
74 "View from 15th Floor"
75 );
76
77 let target = str_to_c_char("Thumbnail");
78 let thumbnail = ylong_json_get_object_item(image, target);
79 let _ = CString::from_raw(target);
80 assert_eq!(ylong_json_is_object(thumbnail), 1);
81
82 let target = str_to_c_char("Url");
83 let url = ylong_json_get_object_item(thumbnail, target);
84 let _ = CString::from_raw(target);
85 let mut ptr: *mut c_char = null_mut::<c_char>();
86 assert_eq!(
87 ylong_json_get_value_from_string(url, &mut ptr as *mut *mut c_char),
88 1
89 );
90 assert_eq!(
91 CStr::from_ptr(ptr).to_str().unwrap(),
92 "http://www.example.com/image/481989943"
93 );
94
95 let target = str_to_c_char("Height");
96 let height = ylong_json_get_object_item(thumbnail, target);
97 let _ = CString::from_raw(target);
98 let mut ptr: c_double = 0f64;
99 assert_eq!(
100 ylong_json_get_double_value_from_number(height, &mut ptr as *mut c_double),
101 1
102 );
103 assert_eq!(ptr, 125f64);
104
105 let target = str_to_c_char("Width");
106 let width = ylong_json_get_object_item(thumbnail, target);
107 let _ = CString::from_raw(target);
108 let mut ptr: c_double = 0f64;
109 assert_eq!(
110 ylong_json_get_double_value_from_number(width, &mut ptr as *mut c_double),
111 1
112 );
113 assert_eq!(ptr, 100f64);
114
115 let target = str_to_c_char("Animated");
116 let animated = ylong_json_get_object_item(image, target);
117 let _ = CString::from_raw(target);
118 let mut ptr: c_int = 0;
119 assert_eq!(
120 ylong_json_get_value_from_bool(animated, &mut ptr as *mut c_int),
121 1
122 );
123 assert_eq!(ptr, 0);
124
125 let target = str_to_c_char("IDs");
126 let ids = ylong_json_get_object_item(image, target);
127 let _ = CString::from_raw(target);
128
129 assert_eq!(ylong_json_is_array(ids), 1);
130
131 let item = ylong_json_get_array_item(ids, 0);
132 let mut ptr = 0f64;
133 assert_eq!(
134 ylong_json_get_double_value_from_number(item, &mut ptr as *mut c_double),
135 1
136 );
137 assert_eq!(ptr, 116f64);
138
139 let item = ylong_json_get_array_item(ids, 1);
140 let mut ptr = 0f64;
141 assert_eq!(
142 ylong_json_get_double_value_from_number(item, &mut ptr as *mut c_double),
143 1
144 );
145 assert_eq!(ptr, 943f64);
146
147 let item = ylong_json_get_array_item(ids, 2);
148 let mut ptr = 0f64;
149 assert_eq!(
150 ylong_json_get_double_value_from_number(item, &mut ptr as *mut c_double),
151 1
152 );
153 assert_eq!(ptr, 234f64);
154
155 let item = ylong_json_get_array_item(ids, 3);
156 let mut ptr = 0f64;
157 assert_eq!(
158 ylong_json_get_double_value_from_number(item, &mut ptr as *mut c_double),
159 1
160 );
161 assert_eq!(ptr, 38793f64);
162 }};
163 }
164
165 #[test]
sdv_adapter_test()166 fn sdv_adapter_test() {
167 unsafe {
168 sdv_adapter_parse_and_print();
169 sdv_adapter_parse_memory_check();
170 }
171 }
172
str_to_c_char(str: &str) -> *mut c_char173 unsafe fn str_to_c_char(str: &str) -> *mut c_char {
174 CString::from_vec_unchecked(str.as_bytes().to_vec()).into_raw()
175 }
176
sdv_adapter_parse_and_print()177 unsafe fn sdv_adapter_parse_and_print() {
178 let text = str_to_c_char(RFC7159_EXAMPLE1);
179
180 let msg = null_mut::<c_char>();
181 let mut json = Some(ylong_json_parse(
182 text,
183 &msg as *const *mut c_char as *mut *mut c_char,
184 ));
185
186 for _ in 0..1000 {
187 let curr = json.take().unwrap();
188
189 let curr_str = ylong_json_print_unformatted(curr);
190
191 let msg = null_mut::<c_char>();
192 let new = ylong_json_parse(curr_str, &msg as *const *mut c_char as *mut *mut c_char);
193
194 let _ = CString::from_raw(curr_str);
195
196 test_json!(new);
197
198 json = Some(new);
199 ylong_json_delete(curr);
200 }
201
202 ylong_json_delete(json.take().unwrap());
203
204 // 析构 text
205 let _ = CString::from_raw(text);
206 }
207
sdv_adapter_parse_memory_check()208 unsafe fn sdv_adapter_parse_memory_check() {
209 const TEXT: &str = r#"
210 {
211 "null": null,
212 "true": true,
213 "false": false,
214 "number": 3.14,
215 "string": "Hello World!",
216 "array": [1, 2, 3],
217 "object": {
218 "key1": 1,
219 "key2": 2,
220 "key3": 3
221 }
222 }
223 "#;
224
225 let text = str_to_c_char(TEXT);
226 let msg = null_mut::<c_char>();
227 let json = ylong_json_parse(text, &msg as *const *mut c_char as *mut *mut c_char);
228 let _ = Box::from_raw(text);
229
230 assert!(msg.is_null());
231 let result = ylong_json_print_unformatted(json);
232 ylong_json_free_string(result);
233
234 let duplicate = ylong_json_duplicate(json, 1);
235 ylong_json_delete(duplicate);
236
237 let null = ylong_json_create_null();
238 ylong_json_delete(null);
239
240 let index = str_to_c_char("string");
241 let string = ylong_json_get_object_item(json, index);
242 let content = null_mut::<c_char>();
243 ylong_json_get_value_from_string(string, &content as *const *mut c_char as *mut *mut c_char);
244 let _ = Box::from_raw(index);
245
246 let null = ylong_json_create_null();
247 let index = str_to_c_char("123");
248 ylong_json_add_item_to_object(json, index, null);
249
250 let content = str_to_c_char("aaaa");
251 let string = ylong_json_create_string(content);
252 ylong_json_replace_object_item_by_index(json, index, string);
253 let _ = Box::from_raw(content);
254
255 let removed = ylong_json_remove_object_item_by_index(json, index);
256 ylong_json_delete(removed);
257 let _ = Box::from_raw(index);
258
259 extern "C" fn func(_value: *mut YlongJson) {}
260 ylong_json_for_each_object_item(json, func);
261
262 ylong_json_delete(json);
263 }
264