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_reader.h"
12 
13 #include "nx_azure_iot.h"
14 
nx_azure_iot_json_reader_translate_error_code(NX_AZURE_IOT_JSON_READER * reader_ptr,az_result core_result)15 static UINT nx_azure_iot_json_reader_translate_error_code(NX_AZURE_IOT_JSON_READER *reader_ptr,
16                                                           az_result core_result)
17 {
18     if (az_result_failed(core_result))
19     {
20         if (core_result == AZ_ERROR_JSON_READER_DONE)
21         {
22             return(NX_AZURE_IOT_NOT_FOUND);
23         }
24 
25         if (reader_ptr -> json_length == 0)
26         {
27             return(NX_AZURE_IOT_EMPTY_JSON);
28         }
29 
30         return(NX_AZURE_IOT_SDK_CORE_ERROR);
31     }
32 
33     return(NX_AZURE_IOT_SUCCESS);
34 }
35 
nx_azure_iot_json_reader_with_buffer_init(NX_AZURE_IOT_JSON_READER * reader_ptr,const UCHAR * buffer_ptr,UINT buffer_len)36 UINT nx_azure_iot_json_reader_with_buffer_init(NX_AZURE_IOT_JSON_READER *reader_ptr,
37                                                const UCHAR *buffer_ptr, UINT buffer_len)
38 {
39 az_span span = az_span_create((UCHAR *)buffer_ptr, (INT)buffer_len);
40 
41     if ((reader_ptr == NX_NULL) ||
42         (buffer_ptr == NX_NULL))
43     {
44         return(NX_AZURE_IOT_INVALID_PARAMETER);
45     }
46 
47     memset(reader_ptr, 0, sizeof(NX_AZURE_IOT_JSON_READER));
48 
49     /* Allow initializing with zero size buffer, as any futher call will fail for empty JSON */
50     if (buffer_len == 0)
51     {
52         reader_ptr -> json_reader.token.kind = AZ_JSON_TOKEN_NONE;
53 
54         return(NX_AZURE_IOT_SUCCESS);
55     }
56 
57     reader_ptr -> json_length = (ULONG)buffer_len;
58 
59     if (az_result_failed(az_json_reader_init(&(reader_ptr -> json_reader),
60                                              span, NX_NULL)))
61     {
62         return(NX_AZURE_IOT_SDK_CORE_ERROR);
63     }
64 
65     return(NX_AZURE_IOT_SUCCESS);
66 }
67 
nx_azure_iot_json_reader_init(NX_AZURE_IOT_JSON_READER * reader_ptr,NX_PACKET * packet_ptr)68 UINT nx_azure_iot_json_reader_init(NX_AZURE_IOT_JSON_READER *reader_ptr,
69                                    NX_PACKET *packet_ptr)
70 {
71 UINT count = 0;
72 
73     if ((reader_ptr == NX_NULL) ||
74         (packet_ptr == NX_NULL))
75     {
76         return(NX_AZURE_IOT_INVALID_PARAMETER);
77     }
78 
79     memset(reader_ptr, 0, sizeof(NX_AZURE_IOT_JSON_READER));
80 
81     reader_ptr -> packet_ptr = packet_ptr;
82 
83     /* Allow initializing with zero size packet, as any futher call will fail for empty JSON */
84     if (packet_ptr -> nx_packet_length == 0)
85     {
86         reader_ptr -> json_reader.token.kind = AZ_JSON_TOKEN_NONE;
87 
88         return(NX_AZURE_IOT_SUCCESS);
89     }
90 
91     reader_ptr -> json_length = packet_ptr -> nx_packet_length;
92 
93     while (packet_ptr != NX_NULL)
94     {
95         if (count >= NX_AZURE_IOT_READER_MAX_LIST)
96         {
97             return(NX_AZURE_IOT_INSUFFICIENT_BUFFER_SPACE);
98         }
99 
100         reader_ptr -> span_list[count] = az_span_create(packet_ptr -> nx_packet_prepend_ptr,
101                                                         (INT)(packet_ptr -> nx_packet_append_ptr -
102                                                               packet_ptr -> nx_packet_prepend_ptr));
103 
104         packet_ptr = packet_ptr -> nx_packet_next;
105         count++;
106     }
107 
108     if (az_result_failed(az_json_reader_chunked_init(&(reader_ptr -> json_reader),
109                                                      reader_ptr -> span_list,
110                                                      (INT)count, NX_NULL)))
111     {
112         return(NX_AZURE_IOT_SDK_CORE_ERROR);
113     }
114 
115     return(NX_AZURE_IOT_SUCCESS);
116 }
117 
nx_azure_iot_json_reader_deinit(NX_AZURE_IOT_JSON_READER * reader_ptr)118 UINT nx_azure_iot_json_reader_deinit(NX_AZURE_IOT_JSON_READER *reader_ptr)
119 {
120     if ((reader_ptr == NX_NULL))
121     {
122         return(NX_AZURE_IOT_INVALID_PARAMETER);
123     }
124 
125     if (reader_ptr -> packet_ptr)
126     {
127         reader_ptr -> packet_ptr = NX_NULL;
128     }
129 
130     return(NX_AZURE_IOT_SUCCESS);
131 }
132 
nx_azure_iot_json_reader_token_is_text_equal(NX_AZURE_IOT_JSON_READER * reader_ptr,UCHAR * value_ptr,UINT value_len)133 UINT nx_azure_iot_json_reader_token_is_text_equal(NX_AZURE_IOT_JSON_READER *reader_ptr,
134                                                   UCHAR *value_ptr, UINT value_len)
135 {
136 az_span span = az_span_create(value_ptr, (INT)value_len);
137 
138     if ((reader_ptr == NX_NULL) ||
139         (value_ptr == NX_NULL) || (value_len == 0))
140     {
141         return(NX_AZURE_IOT_INVALID_PARAMETER);
142     }
143 
144     return((UINT)az_json_token_is_text_equal(&(reader_ptr -> json_reader.token), span));
145 }
146 
nx_azure_iot_json_reader_next_token(NX_AZURE_IOT_JSON_READER * reader_ptr)147 UINT nx_azure_iot_json_reader_next_token(NX_AZURE_IOT_JSON_READER *reader_ptr)
148 {
149 az_result core_result;
150 
151     if ((reader_ptr == NX_NULL))
152     {
153         return(NX_AZURE_IOT_INVALID_PARAMETER);
154     }
155 
156     core_result = az_json_reader_next_token(&(reader_ptr -> json_reader));
157 
158     return(nx_azure_iot_json_reader_translate_error_code(reader_ptr, core_result));
159 }
160 
nx_azure_iot_json_reader_skip_children(NX_AZURE_IOT_JSON_READER * reader_ptr)161 UINT nx_azure_iot_json_reader_skip_children(NX_AZURE_IOT_JSON_READER *reader_ptr)
162 {
163 az_result core_result;
164 
165     if ((reader_ptr == NX_NULL))
166     {
167         return(NX_AZURE_IOT_INVALID_PARAMETER);
168     }
169 
170     core_result = az_json_reader_skip_children(&(reader_ptr -> json_reader));
171 
172     return(nx_azure_iot_json_reader_translate_error_code(reader_ptr, core_result));
173 }
174 
nx_azure_iot_json_reader_token_bool_get(NX_AZURE_IOT_JSON_READER * reader_ptr,UINT * value_ptr)175 UINT nx_azure_iot_json_reader_token_bool_get(NX_AZURE_IOT_JSON_READER *reader_ptr,
176                                              UINT *value_ptr)
177 {
178 bool bool_value;
179 
180     if ((reader_ptr == NX_NULL) || (value_ptr == NX_NULL))
181     {
182         return(NX_AZURE_IOT_INVALID_PARAMETER);
183     }
184 
185     if (az_result_failed(az_json_token_get_boolean(&(reader_ptr -> json_reader.token), &bool_value)))
186     {
187         return(NX_AZURE_IOT_SDK_CORE_ERROR);
188     }
189 
190     *value_ptr = bool_value;
191 
192     return(NX_AZURE_IOT_SUCCESS);
193 }
194 
nx_azure_iot_json_reader_token_uint32_get(NX_AZURE_IOT_JSON_READER * reader_ptr,uint32_t * value_ptr)195 UINT nx_azure_iot_json_reader_token_uint32_get(NX_AZURE_IOT_JSON_READER *reader_ptr,
196                                                uint32_t *value_ptr)
197 {
198     if ((reader_ptr == NX_NULL) || (value_ptr == NX_NULL))
199     {
200         return(NX_AZURE_IOT_INVALID_PARAMETER);
201     }
202 
203     if (az_result_failed(az_json_token_get_uint32(&(reader_ptr -> json_reader.token), value_ptr)))
204     {
205         return(NX_AZURE_IOT_SDK_CORE_ERROR);
206     }
207 
208     return(NX_AZURE_IOT_SUCCESS);
209 }
210 
nx_azure_iot_json_reader_token_int32_get(NX_AZURE_IOT_JSON_READER * reader_ptr,int32_t * value_ptr)211 UINT nx_azure_iot_json_reader_token_int32_get(NX_AZURE_IOT_JSON_READER *reader_ptr,
212                                               int32_t *value_ptr)
213 {
214     if ((reader_ptr == NX_NULL) || (value_ptr == NX_NULL))
215     {
216         return(NX_AZURE_IOT_INVALID_PARAMETER);
217     }
218 
219     if (az_result_failed(az_json_token_get_int32(&(reader_ptr -> json_reader.token), value_ptr)))
220     {
221         return(NX_AZURE_IOT_SDK_CORE_ERROR);
222     }
223 
224     return(NX_AZURE_IOT_SUCCESS);
225 }
226 
nx_azure_iot_json_reader_token_double_get(NX_AZURE_IOT_JSON_READER * reader_ptr,double * value_ptr)227 UINT  nx_azure_iot_json_reader_token_double_get(NX_AZURE_IOT_JSON_READER *reader_ptr,
228                                                 double *value_ptr)
229 {
230     if ((reader_ptr == NX_NULL) || (value_ptr == NX_NULL))
231     {
232         return(NX_AZURE_IOT_INVALID_PARAMETER);
233     }
234 
235     if (az_result_failed(az_json_token_get_double(&(reader_ptr -> json_reader.token), value_ptr)))
236     {
237         return(NX_AZURE_IOT_SDK_CORE_ERROR);
238     }
239 
240     return(NX_AZURE_IOT_SUCCESS);
241 }
242 
nx_azure_iot_json_reader_token_string_get(NX_AZURE_IOT_JSON_READER * reader_ptr,UCHAR * buffer_ptr,UINT buffer_size,UINT * bytes_copied)243 UINT nx_azure_iot_json_reader_token_string_get(NX_AZURE_IOT_JSON_READER *reader_ptr,
244                                                UCHAR *buffer_ptr, UINT buffer_size,
245                                                UINT *bytes_copied)
246 {
247 int32_t bytes;
248 
249     if ((reader_ptr == NX_NULL) ||
250         (buffer_ptr == NX_NULL) ||
251         (buffer_size == 0) ||
252         (bytes_copied == NX_NULL))
253     {
254         return(NX_AZURE_IOT_INVALID_PARAMETER);
255     }
256 
257     if (az_result_failed(az_json_token_get_string(&(reader_ptr -> json_reader.token),
258                                                   (CHAR *)buffer_ptr, (INT)buffer_size,
259                                                   &bytes)))
260     {
261         return(NX_AZURE_IOT_SDK_CORE_ERROR);
262     }
263 
264     *bytes_copied = (UINT)bytes;
265 
266     return(NX_AZURE_IOT_SUCCESS);
267 }
268 
nx_azure_iot_json_reader_token_type(NX_AZURE_IOT_JSON_READER * reader_ptr)269 UINT nx_azure_iot_json_reader_token_type(NX_AZURE_IOT_JSON_READER *reader_ptr)
270 {
271     if ((reader_ptr == NX_NULL))
272     {
273         return(NX_AZURE_IOT_INVALID_PARAMETER);
274     }
275 
276     return(reader_ptr -> json_reader.token.kind);
277 }
278