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 /**
12  * @file nx_azure_iot_json_reader.h
13  *
14  */
15 
16 #ifndef NX_AZURE_IOT_JSON_READER_H
17 #define NX_AZURE_IOT_JSON_READER_H
18 
19 #include "azure/core/az_json.h"
20 #include "nx_api.h"
21 
22 #ifdef __cplusplus
23 extern   "C" {
24 #endif
25 
26 #ifndef NX_AZURE_IOT_READER_MAX_LIST
27 #define NX_AZURE_IOT_READER_MAX_LIST                (15)
28 #endif /* NX_AZURE_IOT_READER_MAX_LIST */
29 
30 /**
31  * Defines symbols for the various kinds of JSON tokens that make up any JSON text.
32  */
33 #define NX_AZURE_IOT_READER_TOKEN_NONE              AZ_JSON_TOKEN_NONE
34 #define NX_AZURE_IOT_READER_TOKEN_BEGIN_OBJECT      AZ_JSON_TOKEN_BEGIN_OBJECT
35 #define NX_AZURE_IOT_READER_TOKEN_END_OBJECT        AZ_JSON_TOKEN_END_OBJECT
36 #define NX_AZURE_IOT_READER_TOKEN_BEGIN_ARRAY       AZ_JSON_TOKEN_BEGIN_ARRAY
37 #define NX_AZURE_IOT_READER_TOKEN_END_ARRAY         AZ_JSON_TOKEN_END_ARRAY
38 #define NX_AZURE_IOT_READER_TOKEN_PROPERTY_NAME     AZ_JSON_TOKEN_PROPERTY_NAME
39 #define NX_AZURE_IOT_READER_TOKEN_STRING            AZ_JSON_TOKEN_STRING
40 #define NX_AZURE_IOT_READER_TOKEN_NUMBER            AZ_JSON_TOKEN_NUMBER
41 #define NX_AZURE_IOT_READER_TOKEN_TRUE              AZ_JSON_TOKEN_TRUE
42 #define NX_AZURE_IOT_READER_TOKEN_FALSE             AZ_JSON_TOKEN_FALSE
43 #define NX_AZURE_IOT_READER_TOKEN_NULL              AZ_JSON_TOKEN_NULL
44 
45 /**
46  * @brief Returns the JSON tokens contained within a JSON buffer, one at a time.
47  *
48  */
49 typedef struct NX_AZURE_IOT_READER_STRUCT
50 {
51       NX_PACKET *packet_ptr;
52       az_json_reader json_reader;
53       az_span span_list[NX_AZURE_IOT_READER_MAX_LIST];
54       ULONG json_length;
55 } NX_AZURE_IOT_JSON_READER;
56 
57 /**
58  * @brief Initializes an #NX_AZURE_IOT_JSON_READER to read the JSON payload contained within the provided
59  * buffer.
60  *
61  * @param[out] reader_ptr A pointer to an #NX_AZURE_IOT_JSON_READER instance to initialize.
62  * @param[in] buffer_ptr An pointer to buffer containing the JSON text to read.
63  * @param[in] buffer_len Length of buffer.
64  *
65  * @return An `UINT` value indicating the result of the operation.
66  * @retval #NX_AZURE_IOT_SUCCESS The #NX_AZURE_IOT_JSON_READER is initialized successfully.
67  * @retval other Initialization failed.
68  *
69  */
70 UINT nx_azure_iot_json_reader_with_buffer_init(NX_AZURE_IOT_JSON_READER *reader_ptr,
71                                                const UCHAR *buffer_ptr, UINT buffer_len);
72 
73 /**
74  * @brief Initializes an #NX_AZURE_IOT_JSON_READER to read the JSON payload contained within #NX_PACKET
75  *
76  * @param[out] reader_ptr A pointer to an #NX_AZURE_IOT_JSON_READER instance to initialize.
77  * @param[in] packet_ptr A pointer to #NX_PACKET containing the JSON text
78  *
79  * @return An `UINT` value indicating the result of the operation.
80  * @retval #NX_AZURE_IOT_SUCCESS The #NX_AZURE_IOT_JSON_READER is initialized successfully.
81  * @retval other Initialization failed.
82  *
83  * @remarks Ownership of #NX_PACKET is taken by the reader.
84  */
85 UINT nx_azure_iot_json_reader_init(NX_AZURE_IOT_JSON_READER *reader_ptr,
86                                    NX_PACKET *packet_ptr);
87 
88 /**
89  * @brief De-initializes an #NX_AZURE_IOT_JSON_READER
90  *
91  * @param[in] reader_ptr A pointer to an #NX_AZURE_IOT_JSON_READER instance to de-initialize
92  *
93  * @return An `UINT` value indicating the result of the operation.
94  * @retval #NX_AZURE_IOT_SUCCESS The #NX_AZURE_IOT_JSON_READER is de-initialized successfully.
95  */
96 UINT nx_azure_iot_json_reader_deinit(NX_AZURE_IOT_JSON_READER *reader_ptr);
97 
98 /**
99  * @brief Reads the next token in the JSON text and updates the reader state.
100  *
101  * @param[in] reader_ptr A pointer to an #NX_AZURE_IOT_JSON_READER instance containing the JSON to
102  * read.
103  *
104  * @return An `UINT` value indicating the result of the operation.
105  * @retval #NX_AZURE_IOT_SUCCESS The token was read successfully.
106  */
107 UINT nx_azure_iot_json_reader_next_token(NX_AZURE_IOT_JSON_READER *reader_ptr);
108 
109 /**
110  * @brief Reads and skips over any nested JSON elements.
111  *
112  * @param[in] reader_ptr A pointer to an #NX_AZURE_IOT_JSON_READER instance containing the JSON to
113  * read.
114  *
115  * @return An `UINT` value indicating the result of the operation.
116  * @retval #NX_AZURE_IOT_SUCCESS The children of the current JSON token are skipped successfully.
117  *
118  * @remarks If the current token kind is a property name, the reader first moves to the property
119  * value. Then, if the token kind is start of an object or array, the reader moves to the matching
120  * end object or array. For all other token kinds, the reader doesn't move and returns #NX_AZURE_IOT_SUCCESS.
121  */
122 UINT nx_azure_iot_json_reader_skip_children(NX_AZURE_IOT_JSON_READER *reader_ptr);
123 
124 /**
125  * @brief Gets the JSON token's boolean value.
126  *
127  * @param[in] reader_ptr A pointer to an #NX_AZURE_IOT_JSON_READER instance.
128  * @param[out] value_ptr A pointer to a variable to receive the value.
129  *
130  * @return An `UINT` value indicating the result of the operation.
131  * @retval #NX_AZURE_IOT_SUCCESS The boolean value is returned.
132  */
133 UINT nx_azure_iot_json_reader_token_bool_get(NX_AZURE_IOT_JSON_READER *reader_ptr,
134                                              UINT *value_ptr);
135 
136 /**
137  * @brief Gets the JSON token's number as a 32-bit unsigned integer.
138  *
139  * @param[in] reader_ptr A pointer to an #NX_AZURE_IOT_JSON_READER instance.
140  * @param[out] value_ptr A pointer to a variable to receive the value.
141  *
142  * @return An `UINT` value indicating the result of the operation.
143  * @retval #NX_AZURE_IOT_SUCCESS The number is returned.
144  */
145 UINT nx_azure_iot_json_reader_token_uint32_get(NX_AZURE_IOT_JSON_READER *reader_ptr,
146                                                uint32_t *value_ptr);
147 
148 /**
149  * @brief Gets the JSON token's number as a 32-bit signed integer.
150  *
151  * @param[in] reader_ptr A pointer to an #NX_AZURE_IOT_JSON_READER instance.
152  * @param[out] value_ptr A pointer to a variable to receive the value.
153  *
154  * @return An `UINT` value indicating the result of the operation.
155  * @retval #NX_AZURE_IOT_SUCCESS The number is returned.
156  */
157 UINT nx_azure_iot_json_reader_token_int32_get(NX_AZURE_IOT_JSON_READER *reader_ptr,
158                                               int32_t *value_ptr);
159 
160 /**
161  * @brief Gets the JSON token's number as a `double`.
162  *
163  * @param[in] reader_ptr A pointer to an #NX_AZURE_IOT_JSON_READER instance.
164  * @param[out] value_ptr A pointer to a variable to receive the value.
165  *
166  * @return An `UINT` value indicating the result of the operation.
167  * @retval #NX_AZURE_IOT_SUCCESS The number is returned.
168  */
169 UINT nx_azure_iot_json_reader_token_double_get(NX_AZURE_IOT_JSON_READER *reader_ptr,
170                                                double *value_ptr);
171 
172 /**
173  * @brief Gets the JSON token's string after unescaping it, if required.
174  *
175  * @param[in] reader_ptr A pointer to an #NX_AZURE_IOT_JSON_READER instance.
176  * @param[out] buffer_ptr A pointer to a buffer where the string should be copied into.
177  * @param[in] buffer_size The maximum available space within the buffer referred to by buffer_ptr.
178  * @param[out] bytes_copied Contains the number of bytes written to the \p
179  * destination which denote the length of the unescaped string.
180  *
181  * @return An `UINT` value indicating the result of the operation.
182  * @retval #NX_AZURE_IOT_SUCCESS The property name was appended successfully.
183  */
184 UINT nx_azure_iot_json_reader_token_string_get(NX_AZURE_IOT_JSON_READER *reader_ptr,
185                                                UCHAR *buffer_ptr, UINT buffer_size, UINT *bytes_copied);
186 
187 /**
188  * @brief Determines whether the unescaped JSON token value that the #NX_AZURE_IOT_JSON_READER points to is
189  * equal to the expected text within the provided buffer bytes by doing a case-sensitive comparison.
190  *
191  * @param[in] reader_ptr A pointer to an #NX_AZURE_IOT_JSON_READER instance containing the JSON string token.
192  * @param[in] expected_text_ptr A pointer to lookup text to compare the token against.
193  * @param[in] expected_text_len Length of expected_text_ptr.
194  *
195  * @return `1` if the current JSON token value in the JSON source semantically matches the
196  * expected lookup text, with the exact casing; otherwise, `0`.
197  *
198  * @remarks This operation is only valid for the string and property name token kinds. For all other
199  * token kinds, it returns 0.
200  */
201 UINT nx_azure_iot_json_reader_token_is_text_equal(NX_AZURE_IOT_JSON_READER *reader_ptr,
202                                                   UCHAR *expected_text_ptr, UINT expected_text_len);
203 
204 /**
205  * @brief Determines type of token currently #NX_AZURE_IOT_JSON_READER points to.
206  *
207  * @param[in] reader_ptr A pointer to an #NX_AZURE_IOT_JSON_READER instance.
208  *
209  * @return An `UINT` value indicating the type of token.
210  */
211 UINT nx_azure_iot_json_reader_token_type(NX_AZURE_IOT_JSON_READER *reader_ptr);
212 
213 #ifdef __cplusplus
214 }
215 #endif
216 #endif /* NX_AZURE_IOT_JSON_READER_H */
217