1 /***************************************************************************
2 * Copyright (c) 2024 Microsoft Corporation
3 *
4 * This program and the accompanying materials are made available under the
5 * terms of the MIT License which is available at
6 * https://opensource.org/licenses/MIT.
7 *
8 * SPDX-License-Identifier: MIT
9 **************************************************************************/
10
11 #include "nx_azure_iot_json_writer.h"
12
13 #include "nx_azure_iot.h"
14
nx_azure_iot_json_wirter_packet_allocator_cb(az_span_allocator_context * allocator_context,az_span * out_next_destination)15 static az_result nx_azure_iot_json_wirter_packet_allocator_cb(az_span_allocator_context* allocator_context,
16 az_span* out_next_destination)
17 {
18 NX_AZURE_IOT_JSON_WRITER *writer_ptr = (NX_AZURE_IOT_JSON_WRITER *)allocator_context -> user_context;
19 NX_PACKET *packet_ptr = writer_ptr -> packet_ptr;
20 NX_PACKET *new_paket_ptr;
21 NX_PACKET *tail_packet_ptr;
22
23 /* Allocate a new packet. */
24 if (nx_packet_allocate(packet_ptr -> nx_packet_pool_owner,
25 &new_paket_ptr, 0, writer_ptr -> wait_option))
26 {
27 return(AZ_ERROR_OUT_OF_MEMORY);
28 }
29
30 if (allocator_context -> minimum_required_size > (INT)(new_paket_ptr -> nx_packet_data_end -
31 new_paket_ptr -> nx_packet_data_start))
32 {
33 nx_packet_release(new_paket_ptr);
34 return(AZ_ERROR_OUT_OF_MEMORY);
35 }
36
37 if (packet_ptr -> nx_packet_last)
38 {
39 tail_packet_ptr = packet_ptr -> nx_packet_last;
40 }
41 else
42 {
43 tail_packet_ptr = packet_ptr;
44 }
45
46 NX_ASSERT((tail_packet_ptr -> nx_packet_data_start + writer_ptr -> nx_tail_packet_offset +
47 (ULONG)(allocator_context -> bytes_used)) <=
48 tail_packet_ptr -> nx_packet_data_end);
49
50 /* Update tail. */
51 tail_packet_ptr -> nx_packet_append_ptr =
52 tail_packet_ptr -> nx_packet_data_start + writer_ptr -> nx_tail_packet_offset +
53 (ULONG)(allocator_context -> bytes_used);
54 tail_packet_ptr -> nx_packet_next = new_paket_ptr;
55
56 /* Update head. */
57 packet_ptr -> nx_packet_length += (ULONG)(allocator_context -> bytes_used);
58 packet_ptr -> nx_packet_last = new_paket_ptr;
59
60 writer_ptr -> nx_tail_packet_offset = 0;
61
62 *out_next_destination = az_span_create(new_paket_ptr -> nx_packet_data_start,
63 (INT)(new_paket_ptr -> nx_packet_data_end -
64 new_paket_ptr -> nx_packet_data_start));
65
66 return(AZ_OK);
67 }
68
nx_azure_iot_json_writer_packet_update(NX_AZURE_IOT_JSON_WRITER * json_writer_ptr)69 static VOID nx_azure_iot_json_writer_packet_update(NX_AZURE_IOT_JSON_WRITER *json_writer_ptr)
70 {
71 NX_PACKET *tail_packet_ptr;
72 UINT last_chunk_size =
73 (UINT)az_span_size(az_json_writer_get_bytes_used_in_destination(&(json_writer_ptr -> json_writer)));
74
75 if (json_writer_ptr -> packet_ptr == NX_NULL)
76 {
77 return;
78 }
79
80 if (json_writer_ptr -> packet_ptr -> nx_packet_last)
81 {
82 tail_packet_ptr = json_writer_ptr -> packet_ptr -> nx_packet_last;
83 }
84 else
85 {
86 tail_packet_ptr = json_writer_ptr -> packet_ptr;
87 }
88
89 NX_ASSERT((tail_packet_ptr -> nx_packet_data_start + json_writer_ptr -> nx_tail_packet_offset +
90 last_chunk_size) <= tail_packet_ptr -> nx_packet_data_end);
91
92 tail_packet_ptr -> nx_packet_append_ptr =
93 tail_packet_ptr -> nx_packet_data_start + json_writer_ptr -> nx_tail_packet_offset + last_chunk_size;
94 json_writer_ptr -> packet_ptr -> nx_packet_length =
95 json_writer_ptr -> nx_packet_init_length + (UINT)json_writer_ptr -> json_writer.total_bytes_written;
96 }
97
nx_azure_iot_json_writer_init(NX_AZURE_IOT_JSON_WRITER * json_writer_ptr,NX_PACKET * packet_ptr,UINT wait_option)98 UINT nx_azure_iot_json_writer_init(NX_AZURE_IOT_JSON_WRITER *json_writer_ptr,
99 NX_PACKET *packet_ptr, UINT wait_option)
100 {
101 az_span span;
102 NX_PACKET *tail_packet_ptr;
103
104 if ((json_writer_ptr == NX_NULL) ||
105 (packet_ptr == NX_NULL))
106 {
107 LogError(LogLiteralArgs("Json writer init fail: INVALID POINTER"));
108 return(NX_AZURE_IOT_INVALID_PARAMETER);
109 }
110
111 memset((VOID *)json_writer_ptr, 0, sizeof(NX_AZURE_IOT_JSON_WRITER));
112
113 if (packet_ptr -> nx_packet_last)
114 {
115 tail_packet_ptr = packet_ptr -> nx_packet_last;
116 }
117 else
118 {
119 tail_packet_ptr = packet_ptr;
120 }
121
122 span = az_span_create(tail_packet_ptr -> nx_packet_append_ptr,
123 (INT)(tail_packet_ptr -> nx_packet_data_end - tail_packet_ptr -> nx_packet_append_ptr));
124
125 if (az_result_failed(az_json_writer_chunked_init(&(json_writer_ptr -> json_writer), span,
126 nx_azure_iot_json_wirter_packet_allocator_cb,
127 (VOID *)json_writer_ptr, NX_NULL)))
128 {
129 LogError(LogLiteralArgs("Json writer failed to init chunked writer"));
130 return(NX_AZURE_IOT_SDK_CORE_ERROR);
131 }
132
133 json_writer_ptr -> packet_ptr = packet_ptr;
134 json_writer_ptr -> wait_option = wait_option;
135 json_writer_ptr -> nx_tail_packet_offset =
136 (ULONG)(tail_packet_ptr -> nx_packet_append_ptr - tail_packet_ptr -> nx_packet_data_start);
137 json_writer_ptr -> nx_packet_init_length = packet_ptr -> nx_packet_length;
138
139 return(NX_AZURE_IOT_SUCCESS);
140 }
141
nx_azure_iot_json_writer_with_buffer_init(NX_AZURE_IOT_JSON_WRITER * json_writer_ptr,UCHAR * buffer_ptr,UINT buffer_len)142 UINT nx_azure_iot_json_writer_with_buffer_init(NX_AZURE_IOT_JSON_WRITER *json_writer_ptr,
143 UCHAR *buffer_ptr, UINT buffer_len)
144 {
145 az_span span;
146
147 if ((json_writer_ptr == NX_NULL) ||
148 (buffer_ptr == NX_NULL))
149 {
150 LogError(LogLiteralArgs("Json writer init fail: INVALID POINTER"));
151 return(NX_AZURE_IOT_INVALID_PARAMETER);
152 }
153
154 memset((VOID *)json_writer_ptr, 0, sizeof(NX_AZURE_IOT_JSON_WRITER));
155
156 span = az_span_create(buffer_ptr, (INT)(buffer_len));
157
158 if (az_result_failed(az_json_writer_init(&(json_writer_ptr -> json_writer), span, NX_NULL)))
159 {
160 LogError(LogLiteralArgs("Json writer failed to init writer"));
161 return(NX_AZURE_IOT_SDK_CORE_ERROR);
162 }
163
164 return(NX_AZURE_IOT_SUCCESS);
165 }
166
nx_azure_iot_json_writer_deinit(NX_AZURE_IOT_JSON_WRITER * json_writer_ptr)167 UINT nx_azure_iot_json_writer_deinit(NX_AZURE_IOT_JSON_WRITER *json_writer_ptr)
168 {
169 if (json_writer_ptr == NX_NULL)
170 {
171 LogError(LogLiteralArgs("Json writer deinit fail: INVALID POINTER"));
172 return(NX_AZURE_IOT_INVALID_PARAMETER);
173 }
174
175 if (json_writer_ptr -> packet_ptr)
176 {
177 json_writer_ptr -> packet_ptr = NX_NULL;
178 }
179
180 return(NX_AZURE_IOT_SUCCESS);
181 }
182
nx_azure_iot_json_writer_get_bytes_used(NX_AZURE_IOT_JSON_WRITER * json_writer_ptr)183 UINT nx_azure_iot_json_writer_get_bytes_used(NX_AZURE_IOT_JSON_WRITER *json_writer_ptr)
184 {
185 if (json_writer_ptr == NX_NULL)
186 {
187 LogError(LogLiteralArgs("Json writer get bytes used fail: INVALID POINTER"));
188 return(NX_AZURE_IOT_INVALID_PARAMETER);
189 }
190
191 return((UINT)json_writer_ptr -> json_writer.total_bytes_written);
192 }
193
nx_azure_iot_json_writer_append_string(NX_AZURE_IOT_JSON_WRITER * json_writer_ptr,const UCHAR * value,UINT value_len)194 UINT nx_azure_iot_json_writer_append_string(NX_AZURE_IOT_JSON_WRITER *json_writer_ptr,
195 const UCHAR *value, UINT value_len)
196 {
197 az_span span = az_span_create((UCHAR *)value, (INT)value_len);
198
199 if (json_writer_ptr == NX_NULL)
200 {
201 LogError(LogLiteralArgs("Json writer append string fail: INVALID POINTER"));
202 return(NX_AZURE_IOT_INVALID_PARAMETER);
203 }
204
205 if (az_result_failed(az_json_writer_append_string(&(json_writer_ptr -> json_writer), span)))
206 {
207 return(NX_AZURE_IOT_SDK_CORE_ERROR);
208 }
209
210 nx_azure_iot_json_writer_packet_update(json_writer_ptr);
211
212 return(NX_AZURE_IOT_SUCCESS);
213 }
214
nx_azure_iot_json_writer_append_json_text(NX_AZURE_IOT_JSON_WRITER * json_writer_ptr,const UCHAR * json,UINT json_len)215 UINT nx_azure_iot_json_writer_append_json_text(NX_AZURE_IOT_JSON_WRITER *json_writer_ptr,
216 const UCHAR *json, UINT json_len)
217 {
218 az_span span = az_span_create((UCHAR *)json, (INT)json_len);
219
220 if (json_writer_ptr == NX_NULL)
221 {
222 LogError(LogLiteralArgs("Json writer append text fail: INVALID POINTER"));
223 return(NX_AZURE_IOT_INVALID_PARAMETER);
224 }
225
226 if (az_result_failed(az_json_writer_append_json_text(&(json_writer_ptr -> json_writer), span)))
227 {
228 return(NX_AZURE_IOT_SDK_CORE_ERROR);
229 }
230
231 nx_azure_iot_json_writer_packet_update(json_writer_ptr);
232
233 return(NX_AZURE_IOT_SUCCESS);
234 }
235
nx_azure_iot_json_writer_append_property_name(NX_AZURE_IOT_JSON_WRITER * json_writer_ptr,const UCHAR * value,UINT value_len)236 UINT nx_azure_iot_json_writer_append_property_name(NX_AZURE_IOT_JSON_WRITER *json_writer_ptr,
237 const UCHAR *value, UINT value_len)
238 {
239 az_span span = az_span_create((UCHAR *)value, (INT)value_len);
240
241 if (json_writer_ptr == NX_NULL)
242 {
243 LogError(LogLiteralArgs("Json writer append property name fail: INVALID POINTER"));
244 return(NX_AZURE_IOT_INVALID_PARAMETER);
245 }
246
247 if (az_result_failed(az_json_writer_append_property_name(&(json_writer_ptr -> json_writer), span)))
248 {
249 return(NX_AZURE_IOT_SDK_CORE_ERROR);
250 }
251
252 nx_azure_iot_json_writer_packet_update(json_writer_ptr);
253
254 return(NX_AZURE_IOT_SUCCESS);
255 }
256
nx_azure_iot_json_writer_append_bool(NX_AZURE_IOT_JSON_WRITER * json_writer_ptr,UINT value)257 UINT nx_azure_iot_json_writer_append_bool(NX_AZURE_IOT_JSON_WRITER *json_writer_ptr, UINT value)
258 {
259 if (json_writer_ptr == NX_NULL)
260 {
261 LogError(LogLiteralArgs("Json writer append bool fail: INVALID POINTER"));
262 return(NX_AZURE_IOT_INVALID_PARAMETER);
263 }
264
265 if (az_result_failed(az_json_writer_append_bool(&(json_writer_ptr -> json_writer), value)))
266 {
267 return(NX_AZURE_IOT_SDK_CORE_ERROR);
268 }
269
270 nx_azure_iot_json_writer_packet_update(json_writer_ptr);
271
272 return(NX_AZURE_IOT_SUCCESS);
273 }
274
nx_azure_iot_json_writer_append_int32(NX_AZURE_IOT_JSON_WRITER * json_writer_ptr,int32_t value)275 UINT nx_azure_iot_json_writer_append_int32(NX_AZURE_IOT_JSON_WRITER *json_writer_ptr, int32_t value)
276 {
277 if (json_writer_ptr == NX_NULL)
278 {
279 LogError(LogLiteralArgs("Json writer append int32 fail: INVALID POINTER"));
280 return(NX_AZURE_IOT_INVALID_PARAMETER);
281 }
282
283 if (az_result_failed(az_json_writer_append_int32(&(json_writer_ptr -> json_writer), value)))
284 {
285 return(NX_AZURE_IOT_SDK_CORE_ERROR);
286 }
287
288 nx_azure_iot_json_writer_packet_update(json_writer_ptr);
289
290 return(NX_AZURE_IOT_SUCCESS);
291 }
292
nx_azure_iot_json_writer_append_double(NX_AZURE_IOT_JSON_WRITER * json_writer_ptr,double value,int32_t fractional_digits)293 UINT nx_azure_iot_json_writer_append_double(NX_AZURE_IOT_JSON_WRITER *json_writer_ptr,
294 double value, int32_t fractional_digits)
295 {
296 if (json_writer_ptr == NX_NULL)
297 {
298 LogError(LogLiteralArgs("Json writer append double fail: INVALID POINTER"));
299 return(NX_AZURE_IOT_INVALID_PARAMETER);
300 }
301
302 if (az_result_failed(az_json_writer_append_double(&(json_writer_ptr -> json_writer), value, fractional_digits)))
303 {
304 return(NX_AZURE_IOT_SDK_CORE_ERROR);
305 }
306
307 nx_azure_iot_json_writer_packet_update(json_writer_ptr);
308
309 return(NX_AZURE_IOT_SUCCESS);
310 }
311
nx_azure_iot_json_writer_append_null(NX_AZURE_IOT_JSON_WRITER * json_writer_ptr)312 UINT nx_azure_iot_json_writer_append_null(NX_AZURE_IOT_JSON_WRITER *json_writer_ptr)
313 {
314 if (json_writer_ptr == NX_NULL)
315 {
316 LogError(LogLiteralArgs("Json writer append null fail: INVALID POINTER"));
317 return(NX_AZURE_IOT_INVALID_PARAMETER);
318 }
319
320 if (az_result_failed(az_json_writer_append_null(&(json_writer_ptr -> json_writer))))
321 {
322 return(NX_AZURE_IOT_SDK_CORE_ERROR);
323 }
324
325 nx_azure_iot_json_writer_packet_update(json_writer_ptr);
326
327 return(NX_AZURE_IOT_SUCCESS);
328 }
329
nx_azure_iot_json_writer_append_begin_object(NX_AZURE_IOT_JSON_WRITER * json_writer_ptr)330 UINT nx_azure_iot_json_writer_append_begin_object(NX_AZURE_IOT_JSON_WRITER *json_writer_ptr)
331 {
332 if (json_writer_ptr == NX_NULL)
333 {
334 LogError(LogLiteralArgs("Json writer append begin object fail: INVALID POINTER"));
335 return(NX_AZURE_IOT_INVALID_PARAMETER);
336 }
337
338 if (az_result_failed(az_json_writer_append_begin_object(&(json_writer_ptr -> json_writer))))
339 {
340 return(NX_AZURE_IOT_SDK_CORE_ERROR);
341 }
342
343 nx_azure_iot_json_writer_packet_update(json_writer_ptr);
344
345 return(NX_AZURE_IOT_SUCCESS);
346 }
347
nx_azure_iot_json_writer_append_begin_array(NX_AZURE_IOT_JSON_WRITER * json_writer_ptr)348 UINT nx_azure_iot_json_writer_append_begin_array(NX_AZURE_IOT_JSON_WRITER *json_writer_ptr)
349 {
350 if (json_writer_ptr == NX_NULL)
351 {
352 LogError(LogLiteralArgs("Json writer append begin array fail: INVALID POINTER"));
353 return(NX_AZURE_IOT_INVALID_PARAMETER);
354 }
355
356 if (az_result_failed(az_json_writer_append_begin_array(&(json_writer_ptr -> json_writer))))
357 {
358 return(NX_AZURE_IOT_SDK_CORE_ERROR);
359 }
360
361 nx_azure_iot_json_writer_packet_update(json_writer_ptr);
362
363 return(NX_AZURE_IOT_SUCCESS);
364 }
365
nx_azure_iot_json_writer_append_end_object(NX_AZURE_IOT_JSON_WRITER * json_writer_ptr)366 UINT nx_azure_iot_json_writer_append_end_object(NX_AZURE_IOT_JSON_WRITER *json_writer_ptr)
367 {
368 if (json_writer_ptr == NX_NULL)
369 {
370 LogError(LogLiteralArgs("Json writer append end object fail: INVALID POINTER"));
371 return(NX_AZURE_IOT_INVALID_PARAMETER);
372 }
373
374 if (az_result_failed(az_json_writer_append_end_object(&(json_writer_ptr -> json_writer))))
375 {
376 return(NX_AZURE_IOT_SDK_CORE_ERROR);
377 }
378
379 nx_azure_iot_json_writer_packet_update(json_writer_ptr);
380
381 return(NX_AZURE_IOT_SUCCESS);
382 }
383
nx_azure_iot_json_writer_append_end_array(NX_AZURE_IOT_JSON_WRITER * json_writer_ptr)384 UINT nx_azure_iot_json_writer_append_end_array(NX_AZURE_IOT_JSON_WRITER *json_writer_ptr)
385 {
386 if (json_writer_ptr == NX_NULL)
387 {
388 LogError(LogLiteralArgs("Json writer append end array fail: INVALID POINTER"));
389 return(NX_AZURE_IOT_INVALID_PARAMETER);
390 }
391
392 if (az_result_failed(az_json_writer_append_end_array(&(json_writer_ptr -> json_writer))))
393 {
394 return(NX_AZURE_IOT_SDK_CORE_ERROR);
395 }
396
397 nx_azure_iot_json_writer_packet_update(json_writer_ptr);
398
399 return(NX_AZURE_IOT_SUCCESS);
400 }
401
nx_azure_iot_json_writer_append_property_with_int32_value(NX_AZURE_IOT_JSON_WRITER * json_writer_ptr,const UCHAR * property_name,UINT property_name_len,int32_t value)402 UINT nx_azure_iot_json_writer_append_property_with_int32_value(NX_AZURE_IOT_JSON_WRITER *json_writer_ptr,
403 const UCHAR *property_name, UINT property_name_len,
404 int32_t value)
405 {
406 return ((UINT)(nx_azure_iot_json_writer_append_property_name(json_writer_ptr, property_name, property_name_len) ||
407 nx_azure_iot_json_writer_append_int32(json_writer_ptr, value)));
408 }
409
nx_azure_iot_json_writer_append_property_with_double_value(NX_AZURE_IOT_JSON_WRITER * json_writer_ptr,const UCHAR * property_name,UINT property_name_len,double value,UINT fractional_digits)410 UINT nx_azure_iot_json_writer_append_property_with_double_value(NX_AZURE_IOT_JSON_WRITER *json_writer_ptr,
411 const UCHAR *property_name, UINT property_name_len,
412 double value, UINT fractional_digits)
413 {
414 return ((UINT)(nx_azure_iot_json_writer_append_property_name(json_writer_ptr, property_name, property_name_len) ||
415 nx_azure_iot_json_writer_append_double(json_writer_ptr, value, (int32_t)fractional_digits)));
416 }
417
nx_azure_iot_json_writer_append_property_with_bool_value(NX_AZURE_IOT_JSON_WRITER * json_writer_ptr,const UCHAR * property_name,UINT property_name_len,UINT value)418 UINT nx_azure_iot_json_writer_append_property_with_bool_value(NX_AZURE_IOT_JSON_WRITER *json_writer_ptr,
419 const UCHAR *property_name, UINT property_name_len,
420 UINT value)
421 {
422 return ((UINT)(nx_azure_iot_json_writer_append_property_name(json_writer_ptr, property_name, property_name_len) ||
423 nx_azure_iot_json_writer_append_bool(json_writer_ptr, value)));
424 }
425
nx_azure_iot_json_writer_append_property_with_string_value(NX_AZURE_IOT_JSON_WRITER * json_writer_ptr,const UCHAR * property_name,UINT property_name_len,const UCHAR * value,UINT value_len)426 UINT nx_azure_iot_json_writer_append_property_with_string_value(NX_AZURE_IOT_JSON_WRITER *json_writer_ptr,
427 const UCHAR *property_name, UINT property_name_len,
428 const UCHAR *value, UINT value_len)
429 {
430 return ((UINT)(nx_azure_iot_json_writer_append_property_name(json_writer_ptr, property_name, property_name_len) ||
431 nx_azure_iot_json_writer_append_string(json_writer_ptr, value, value_len)));
432 }
433