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_writer.h 13 * 14 */ 15 16 #ifndef NX_AZURE_IOT_JSON_WRITER_H 17 #define NX_AZURE_IOT_JSON_WRITER_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 /** 27 * @brief Provides forward-only, non-cached writing of UTF-8 encoded JSON text into the provided 28 * buffer. 29 * 30 * @remarks #az_json_writer builds the text sequentially with no caching and by default adheres to 31 * the JSON RFC: https://tools.ietf.org/html/rfc8259. 32 * 33 */ 34 typedef struct NX_AZURE_IOT_JSON_WRITER_STRUCT 35 { 36 NX_PACKET *packet_ptr; 37 az_json_writer json_writer; 38 UINT wait_option; 39 ULONG nx_tail_packet_offset; 40 ULONG nx_packet_init_length; 41 } NX_AZURE_IOT_JSON_WRITER; 42 43 /** 44 * @brief Initializes an #NX_AZURE_IOT_JSON_WRITER which writes JSON text into a NX_PACKET. 45 * 46 * @param[out] json_writer_ptr A pointer to an #NX_AZURE_IOT_JSON_WRITER the instance to initialize. 47 * @param[in] packet_ptr A pointer to #NX_PACKET. 48 * @param[in] wait_option Ticks to wait for allocating next packet 49 * 50 * @return An `UINT` value indicating the result of the operation. 51 * @retval #NX_AZURE_IOT_SUCCESS Successfully initialized JSON writer. 52 */ 53 UINT nx_azure_iot_json_writer_init(NX_AZURE_IOT_JSON_WRITER *json_writer_ptr, 54 NX_PACKET *packet_ptr, UINT wait_option); 55 56 /** 57 * @brief Initializes an #NX_AZURE_IOT_JSON_WRITER which writes JSON text into a buffer passed. 58 * 59 * @param[out] json_writer_ptr A pointer to an #NX_AZURE_IOT_JSON_WRITER the instance to initialize. 60 * @param[in] buffer_ptr A buffer pointer to which JSON text will be written. 61 * @param[in] buffer_len Length of buffer. 62 * 63 * @return An `UINT` value indicating the result of the operation. 64 * @retval #NX_AZURE_IOT_SUCCESS Successfully initialized JSON writer. 65 */ 66 UINT nx_azure_iot_json_writer_with_buffer_init(NX_AZURE_IOT_JSON_WRITER *json_writer_ptr, 67 UCHAR *buffer_ptr, UINT buffer_len); 68 69 /** 70 * @brief Deinitializes an #NX_AZURE_IOT_JSON_WRITER. 71 * 72 * @param[out] json_writer_ptr A pointer to an #NX_AZURE_IOT_JSON_WRITER the instance to de-initialize. 73 * 74 * @return An `UINT` value indicating the result of the operation. 75 * @retval #NX_AZURE_IOT_SUCCESS Successfully de-initialized JSON writer. 76 */ 77 UINT nx_azure_iot_json_writer_deinit(NX_AZURE_IOT_JSON_WRITER *json_writer_ptr); 78 79 /** 80 * @brief Appends the UTF-8 property name and value where value is int32 81 * 82 * @param[in] json_writer_ptr A pointer to an #NX_AZURE_IOT_JSON_WRITER. 83 * @param[in] property_name The UTF-8 encoded property name of the JSON value to be written. The name is 84 * escaped before writing. 85 * @param[in] property_name_len Length of property_name. 86 * @param[in] value The value to be written as a JSON number. 87 * 88 * @return An `UINT` value indicating the result of the operation. 89 * @retval #NX_AZURE_IOT_SUCCESS The property name and int32 value was appended successfully. 90 */ 91 UINT nx_azure_iot_json_writer_append_property_with_int32_value(NX_AZURE_IOT_JSON_WRITER *json_writer_ptr, 92 const UCHAR *property_name, UINT property_name_len, 93 int32_t value); 94 95 /** 96 * @brief Appends the UTF-8 property name and value where value is double 97 * 98 * @param[in] json_writer_ptr A pointer to an #NX_AZURE_IOT_JSON_WRITER. 99 * @param[in] property_name The UTF-8 encoded property name of the JSON value to be written. The name is 100 * escaped before writing. 101 * @param[in] property_name_len Length of property_name. 102 * @param[in] value The value to be written as a JSON number. 103 * @param[in] fractional_digits The number of digits of the value to write after the decimal point and truncate the rest. 104 * 105 * @return An `UINT` value indicating the result of the operation. 106 * @retval #NX_AZURE_IOT_SUCCESS The property name and double value was appended successfully. 107 */ 108 UINT nx_azure_iot_json_writer_append_property_with_double_value(NX_AZURE_IOT_JSON_WRITER *json_writer_ptr, 109 const UCHAR *property_name, UINT property_name_len, 110 double value, UINT fractional_digits); 111 112 /** 113 * @brief Appends the UTF-8 property name and value where value is boolean 114 * 115 * @param[in] json_writer_ptr A pointer to an #NX_AZURE_IOT_JSON_WRITER. 116 * @param[in] property_name The UTF-8 encoded property name of the JSON value to be written. The name is 117 * escaped before writing. 118 * @param[in] property_name_len Length of property_name. 119 * @param[in] value The value to be written as a JSON literal `true` or `false`. 120 * 121 * @return An `UINT` value indicating the result of the operation. 122 * @retval #NX_AZURE_IOT_SUCCESS The property name and bool value was appended successfully. 123 */ 124 UINT nx_azure_iot_json_writer_append_property_with_bool_value(NX_AZURE_IOT_JSON_WRITER *json_writer_ptr, 125 const UCHAR *property_name, UINT property_name_len, 126 UINT value); 127 128 /** 129 * @brief Appends the UTF-8 property name and value where value is string 130 * 131 * @param[in] json_writer_ptr A pointer to an #NX_AZURE_IOT_JSON_WRITER. 132 * @param[in] property_name The UTF-8 encoded property name of the JSON value to be written. The name is 133 * escaped before writing. 134 * @param[in] property_name_len Length of property_name. 135 * @param[in] value The UTF-8 encoded property name of the JSON value to be written. The name is 136 * escaped before writing. 137 * @param[in] value_len Length of value. 138 * 139 * @return An `UINT` value indicating the result of the operation. 140 * @retval #NX_AZURE_IOT_SUCCESS The property name and string value was appended successfully. 141 */ 142 UINT nx_azure_iot_json_writer_append_property_with_string_value(NX_AZURE_IOT_JSON_WRITER *json_writer_ptr, 143 const UCHAR *property_name, UINT property_name_len, 144 const UCHAR *value, UINT value_len); 145 146 /** 147 * @brief Returns the length containing the JSON text written to the underlying buffer. 148 * 149 * @param[in] json_writer_ptr A pointer to an #NX_AZURE_IOT_JSON_WRITER. 150 * 151 * @return An UINT containing the length of JSON text built so far. 152 */ 153 UINT nx_azure_iot_json_writer_get_bytes_used(NX_AZURE_IOT_JSON_WRITER *json_writer_ptr); 154 155 /** 156 * @brief Appends the UTF-8 text value (as a JSON string) into the buffer. 157 * 158 * @param[in] json_writer_ptr A pointer to an #NX_AZURE_IOT_JSON_WRITER. 159 * @param[in] value Pointer of UCHAR buffer that contains UTF-8 encoded value to be written as a JSON string. 160 * The value is escaped before writing. 161 * @param[in] value_len Length of value. 162 * 163 * @return An `UINT` value indicating the result of the operation. 164 * @retval #NX_AZURE_IOT_SUCCESS The string value was appended successfully. 165 */ 166 UINT nx_azure_iot_json_writer_append_string(NX_AZURE_IOT_JSON_WRITER *json_writer_ptr, 167 const UCHAR *value, UINT value_len); 168 169 /** 170 * @brief Appends an existing UTF-8 encoded JSON text into the buffer, useful for appending nested 171 * JSON. 172 * 173 * @param[in] json_writer_ptr A pointer to an #NX_AZURE_IOT_JSON_WRITER. 174 * @param[in] json A pointer to single, possibly nested, valid, UTF-8 encoded, JSON value to be written as 175 * is, without any formatting or spacing changes. No modifications are made to this text, including 176 * escaping. 177 * @param[in] json_len Length of json 178 * 179 * @remarks A single, possibly nested, JSON value is one that starts and ends with {} or [] or is a 180 * single primitive token. The JSON cannot start with an end object or array, or a property name, or 181 * be incomplete. 182 * 183 * @remarks The function validates that the provided JSON to be appended is valid and properly 184 * escaped, and fails otherwise. 185 * 186 * @return An `UINT` value indicating the result of the operation. 187 * @retval #NX_AZURE_IOT_SUCCESS The provided json_text was appended successfully. 188 */ 189 UINT nx_azure_iot_json_writer_append_json_text(NX_AZURE_IOT_JSON_WRITER *json_writer_ptr, 190 const UCHAR *json, UINT json_len); 191 192 /** 193 * @brief Appends the UTF-8 property name (as a JSON string) which is the first part of a name/value 194 * pair of a JSON object. 195 * 196 * @param[in] json_writer_ptr A pointer to an #NX_AZURE_IOT_JSON_WRITER. 197 * @param[in] value The UTF-8 encoded property name of the JSON value to be written. The name is 198 * escaped before writing. 199 * @param[in] value_len Length of name. 200 * 201 * @return An `UINT` value indicating the result of the operation. 202 * @retval #NX_AZURE_IOT_SUCCESS The property name was appended successfully. 203 */ 204 UINT nx_azure_iot_json_writer_append_property_name(NX_AZURE_IOT_JSON_WRITER *json_writer_ptr, 205 const UCHAR *value, UINT value_len); 206 207 /** 208 * @brief Appends a boolean value (as a JSON literal `true` or `false`). 209 * 210 * @param[in] json_writer_ptr A pointer to an #NX_AZURE_IOT_JSON_WRITER. 211 * @param[in] value The value to be written as a JSON literal `true` or `false`. 212 * 213 * @return An `UINT` value indicating the result of the operation. 214 * @retval #NX_AZURE_IOT_SUCCESS The bool was appended successfully. 215 */ 216 UINT nx_azure_iot_json_writer_append_bool(NX_AZURE_IOT_JSON_WRITER *json_writer_ptr, UINT value); 217 218 /** 219 * @brief Appends an `int32_t` number value. 220 * 221 * @param[in] json_writer_ptr A pointer to an #NX_AZURE_IOT_JSON_WRITER. 222 * @param[in] value The value to be written as a JSON number. 223 * 224 * @return An `UINT` value indicating the result of the operation. 225 * @retval #NX_AZURE_IOT_SUCCESS The number was appended successfully. 226 */ 227 UINT nx_azure_iot_json_writer_append_int32(NX_AZURE_IOT_JSON_WRITER *json_writer_ptr, int32_t value); 228 229 /** 230 * @brief Appends a `double` number value. 231 * 232 * @param[in] json_writer_ptr A pointer to an #NX_AZURE_IOT_JSON_WRITER. 233 * @param[in] value The value to be written as a JSON number. 234 * @param[in] fractional_digits The number of digits of the \p value to write after the decimal 235 * point and truncate the rest. 236 * 237 * @return An `UINT` value indicating the result of the operation. 238 * @retval #NX_AZURE_IOT_SUCCESS The number was appended successfully. 239 * 240 * @remark Only finite double values are supported. Values such as `NAN` and `INFINITY` are not 241 * allowed and would lead to invalid JSON being written. 242 * 243 * @remark Non-significant trailing zeros (after the decimal point) are not written, even if \p 244 * fractional_digits is large enough to allow the zero padding. 245 * 246 * @remark The \p fractional_digits must be between 0 and 15 (inclusive). Any value passed in that 247 * is larger will be clamped down to 15. 248 */ 249 UINT nx_azure_iot_json_writer_append_double(NX_AZURE_IOT_JSON_WRITER *json_writer_ptr, 250 double value, int32_t fractional_digits); 251 252 /** 253 * @brief Appends the JSON literal `null`. 254 * 255 * @param[in] json_writer_ptr A pointer to an #NX_AZURE_IOT_JSON_WRITER. 256 * 257 * @return An `UINT` value indicating the result of the operation. 258 * @retval #NX_AZURE_IOT_SUCCESS `null` was appended successfully. 259 */ 260 UINT nx_azure_iot_json_writer_append_null(NX_AZURE_IOT_JSON_WRITER *json_writer_ptr); 261 262 /** 263 * @brief Appends the beginning of a JSON object (i.e. `{`). 264 * 265 * @param[in] json_writer_ptr A pointer to an #NX_AZURE_IOT_JSON_WRITER. 266 * 267 * @return An `UINT` value indicating the result of the operation. 268 * @retval #NX_AZURE_IOT_SUCCESS Object start was appended successfully. 269 */ 270 UINT nx_azure_iot_json_writer_append_begin_object(NX_AZURE_IOT_JSON_WRITER *json_writer_ptr); 271 272 /** 273 * @brief Appends the beginning of a JSON array (i.e. `[`). 274 * 275 * @param[in] json_writer_ptr A pointer to an #NX_AZURE_IOT_JSON_WRITER. 276 * 277 * @return An `UINT` value indicating the result of the operation. 278 * @retval #NX_AZURE_IOT_SUCCESS Array start was appended successfully. 279 */ 280 UINT nx_azure_iot_json_writer_append_begin_array(NX_AZURE_IOT_JSON_WRITER *json_writer_ptr); 281 282 /** 283 * @brief Appends the end of the current JSON object (i.e. `}`). 284 * 285 * @param[in] json_writer_ptr A pointer to an #NX_AZURE_IOT_JSON_WRITER. 286 * 287 * @return An `UINT` value indicating the result of the operation. 288 * @retval #NX_AZURE_IOT_SUCCESS Object end was appended successfully. 289 */ 290 UINT nx_azure_iot_json_writer_append_end_object(NX_AZURE_IOT_JSON_WRITER *json_writer_ptr); 291 292 /** 293 * @brief Appends the end of the current JSON array (i.e. `]`). 294 * 295 * @param[in] json_writer_ptr A pointer to an #NX_AZURE_IOT_JSON_WRITER. 296 * 297 * @return An `UINT` value indicating the result of the operation. 298 * @retval #NX_AZURE_IOT_SUCCESS Array end was appended successfully. 299 */ 300 UINT nx_azure_iot_json_writer_append_end_array(NX_AZURE_IOT_JSON_WRITER *json_writer_ptr); 301 302 #ifdef __cplusplus 303 } 304 #endif 305 #endif /* NX_AZURE_IOT_JSON_WRITER_H */ 306