Azure SDK for Embedded C
az_json.h
Go to the documentation of this file.
1 // Copyright (c) Microsoft Corporation. All rights reserved.
2 // SPDX-License-Identifier: MIT
3 
16 #ifndef _az_JSON_H
17 #define _az_JSON_H
18 
19 #include <azure/core/az_result.h>
20 #include <azure/core/az_span.h>
21 
22 #include <stdbool.h>
23 #include <stdint.h>
24 
25 #include <azure/core/_az_cfg_prefix.h>
26 
30 typedef enum
31 {
44 
49 typedef struct
50 {
51  struct
52  {
53  // This uint64_t container represents a tiny stack to track the state during nested transitions.
54  // The first bit represents the state of the current depth (1 == object, 0 == array).
55  // Each subsequent bit is the parent / containing type (object or array).
56  uint64_t az_json_stack;
57  int32_t current_depth;
58  } _internal;
59 } _az_json_bit_stack;
60 
68 typedef struct
69 {
78 
79  // Avoid using enum as the first field within structs, to allow for { 0 } initialization.
80  // This is a workaround for IAR compiler warning [Pe188]: enumerated type mixed with another type.
81 
85 
90  int32_t size;
91 
92  struct
93  {
98 
102 
106 
109 
112 
115 
118  } _internal;
119 } az_json_token;
120 
121 // TODO: Should the parameters be reversed?
140 
151 AZ_NODISCARD az_result az_json_token_get_boolean(az_json_token const* json_token, bool* out_value);
152 
165 AZ_NODISCARD az_result
166 az_json_token_get_uint64(az_json_token const* json_token, uint64_t* out_value);
167 
180 AZ_NODISCARD az_result
181 az_json_token_get_uint32(az_json_token const* json_token, uint32_t* out_value);
182 
195 AZ_NODISCARD az_result az_json_token_get_int64(az_json_token const* json_token, int64_t* out_value);
196 
209 AZ_NODISCARD az_result az_json_token_get_int32(az_json_token const* json_token, int32_t* out_value);
210 
222 AZ_NODISCARD az_result az_json_token_get_double(az_json_token const* json_token, double* out_value);
223 
241  az_json_token const* json_token,
242  char* destination,
243  int32_t destination_max_size,
244  int32_t* out_string_length);
245 
259 AZ_NODISCARD bool az_json_token_is_text_equal(
260  az_json_token const* json_token,
261  az_span expected_text);
262 
263 /************************************ JSON WRITER ******************/
264 
268 typedef struct
269 {
270  struct
271  {
273  bool unused;
274  } _internal;
276 
287 {
288  az_json_writer_options options = {
289  ._internal = {
290  .unused = false,
291  },
292  };
293 
294  return options;
295 }
296 
304 typedef struct
305 {
310 
311  struct
312  {
315 
317  int32_t bytes_written; // For single contiguous buffer, bytes_written == total_bytes_written
318 
321 
325 
328 
331  az_json_token_kind token_kind; // needed for validation, potentially #if/def with preconditions.
332 
336  _az_json_bit_stack bit_stack; // needed for validation, potentially #if/def with preconditions.
337 
340  } _internal;
342 
357  az_json_writer* out_json_writer,
358  az_span destination_buffer,
359  az_json_writer_options const* options);
360 
382  az_json_writer* out_json_writer,
383  az_span first_destination_buffer,
384  az_span_allocator_fn allocator_callback,
385  void* user_context,
386  az_json_writer_options const* options);
387 
405 AZ_NODISCARD AZ_INLINE az_span
407 {
408  return az_span_slice(
409  json_writer->_internal.destination_buffer, 0, json_writer->_internal.bytes_written);
410 }
411 
432 AZ_NODISCARD az_result az_json_writer_append_string(az_json_writer* ref_json_writer, az_span value);
433 
467 AZ_NODISCARD az_result
469 
489 AZ_NODISCARD az_result
491 
503 AZ_NODISCARD az_result az_json_writer_append_bool(az_json_writer* ref_json_writer, bool value);
504 
522 AZ_NODISCARD az_result az_json_writer_append_int32(az_json_writer* ref_json_writer, int32_t value);
523 
555  az_json_writer* ref_json_writer,
556  double value,
557  int32_t fractional_digits);
558 
569 AZ_NODISCARD az_result az_json_writer_append_null(az_json_writer* ref_json_writer);
570 
584 
598 
610 
622 
623 /************************************ JSON READER ******************/
624 
628 typedef struct
629 {
630  struct
631  {
633  bool unused;
634  } _internal;
636 
647 {
648  az_json_reader_options options = {
649  ._internal = {
650  .unused = false,
651  },
652  };
653 
654  return options;
655 }
656 
663 typedef struct
664 {
668 
672  int32_t current_depth;
673 
674  struct
675  {
678 
682 
686 
689  int32_t buffer_index;
690 
692  int32_t bytes_consumed;
693 
697 
701 
703  _az_json_bit_stack bit_stack;
704 
707  } _internal;
709 
730  az_json_reader* out_json_reader,
731  az_span json_buffer,
732  az_json_reader_options const* options);
733 
759  az_json_reader* out_json_reader,
760  az_span json_buffers[],
761  int32_t number_of_buffers,
762  az_json_reader_options const* options);
763 
776 AZ_NODISCARD az_result az_json_reader_next_token(az_json_reader* ref_json_reader);
777 
794 
816 AZ_NODISCARD az_span az_json_string_unescape(az_span json_string, az_span destination);
817 
818 #include <azure/core/_az_cfg_suffix.h>
819 
820 #endif // _az_JSON_H
az_json_token_get_double
AZ_NODISCARD az_result az_json_token_get_double(az_json_token const *json_token, double *out_value)
Gets the JSON token's number as a double.
az_json_writer_append_end_array
AZ_NODISCARD az_result az_json_writer_append_end_array(az_json_writer *ref_json_writer)
Appends the end of the current JSON array (i.e. ]).
az_result.h
Definition of az_result and helper functions.
az_json_token::pointer_to_first_buffer
az_span * pointer_to_first_buffer
Definition: az_json.h:105
az_json_writer::bytes_written
int32_t bytes_written
The bytes written in the current destination buffer.
Definition: az_json.h:317
AZ_JSON_TOKEN_FALSE
@ AZ_JSON_TOKEN_FALSE
The token kind is the JSON literal false.
Definition: az_json.h:41
az_json_reader
Returns the JSON tokens contained within a JSON buffer, one at a time.
Definition: az_json.h:664
az_json_writer_append_double
AZ_NODISCARD az_result az_json_writer_append_double(az_json_writer *ref_json_writer, double value, int32_t fractional_digits)
Appends a double number value.
az_json_reader_next_token
AZ_NODISCARD az_result az_json_reader_next_token(az_json_reader *ref_json_reader)
Reads the next token in the JSON text and updates the reader state.
az_json_writer_options
Allows the user to define custom behavior when writing JSON using the az_json_writer.
Definition: az_json.h:269
az_json_writer
Provides forward-only, non-cached writing of UTF-8 encoded JSON text into the provided buffer.
Definition: az_json.h:305
az_json_token::end_buffer_offset
int32_t end_buffer_offset
The offset within the particular segment within which this token ends.
Definition: az_json.h:117
az_json_writer_options_default
AZ_NODISCARD AZ_INLINE az_json_writer_options az_json_writer_options_default()
Gets the default json writer options which builds minimized JSON (with no extra white space) accordin...
Definition: az_json.h:286
az_json_writer_append_string
AZ_NODISCARD az_result az_json_writer_append_string(az_json_writer *ref_json_writer, az_span value)
Appends the UTF-8 text value (as a JSON string) into the buffer.
az_json_writer_append_end_object
AZ_NODISCARD az_result az_json_writer_append_end_object(az_json_writer *ref_json_writer)
Appends the end of the current JSON object (i.e. }).
az_json_writer_append_property_name
AZ_NODISCARD az_result az_json_writer_append_property_name(az_json_writer *ref_json_writer, az_span name)
Appends the UTF-8 property name (as a JSON string) which is the first part of a name/value pair of a ...
az_json_token_get_uint32
AZ_NODISCARD az_result az_json_token_get_uint32(az_json_token const *json_token, uint32_t *out_value)
Gets the JSON token's number as a 32-bit unsigned integer.
AZ_JSON_TOKEN_BEGIN_OBJECT
@ AZ_JSON_TOKEN_BEGIN_OBJECT
The token kind is the start of a JSON object.
Definition: az_json.h:33
az_json_reader::json_buffers
az_span * json_buffers
Definition: az_json.h:681
AZ_JSON_TOKEN_END_ARRAY
@ AZ_JSON_TOKEN_END_ARRAY
The token kind is the end of a JSON array.
Definition: az_json.h:36
az_json_reader::total_bytes_consumed
int32_t total_bytes_consumed
Definition: az_json.h:696
az_json_writer_append_begin_object
AZ_NODISCARD az_result az_json_writer_append_begin_object(az_json_writer *ref_json_writer)
Appends the beginning of a JSON object (i.e. {).
az_result
int32_t az_result
The type represents the various success and error conditions.
Definition: az_result.h:46
az_json_reader_options
Allows the user to define custom behavior when reading JSON using the az_json_reader.
Definition: az_json.h:629
az_json_reader::token
az_json_token token
Definition: az_json.h:667
az_json_writer_get_bytes_used_in_destination
AZ_NODISCARD AZ_INLINE az_span az_json_writer_get_bytes_used_in_destination(az_json_writer const *json_writer)
Returns the az_span containing the JSON text written to the underlying buffer so far,...
Definition: az_json.h:406
az_json_token::end_buffer_index
int32_t end_buffer_index
The segment index within the non-contiguous JSON payload where this token ends.
Definition: az_json.h:114
AZ_JSON_TOKEN_END_OBJECT
@ AZ_JSON_TOKEN_END_OBJECT
The token kind is the end of a JSON object.
Definition: az_json.h:34
az_json_reader_options::unused
bool unused
Currently, this is unused, but needed as a placeholder since we can't have an empty struct.
Definition: az_json.h:633
az_json_writer_options::unused
bool unused
Currently, this is unused, but needed as a placeholder since we can't have an empty struct.
Definition: az_json.h:273
az_json_writer::token_kind
az_json_token_kind token_kind
Definition: az_json.h:331
az_json_writer::need_comma
bool need_comma
A state to remember when to emit a comma between JSON array and object elements.
Definition: az_json.h:327
az_json_writer_chunked_init
AZ_NODISCARD az_result az_json_writer_chunked_init(az_json_writer *out_json_writer, az_span first_destination_buffer, az_span_allocator_fn allocator_callback, void *user_context, az_json_writer_options const *options)
Initializes an az_json_writer which writes JSON text into a destination that can contain non-contiguo...
az_json_token_get_boolean
AZ_NODISCARD az_result az_json_token_get_boolean(az_json_token const *json_token, bool *out_value)
Gets the JSON token's boolean.
az_span_allocator_fn
az_result(* az_span_allocator_fn)(az_span_allocator_context *allocator_context, az_span *out_next_destination)
Defines the signature of the callback function that the caller must implement to provide the potentia...
Definition: az_span.h:531
AZ_JSON_TOKEN_STRING
@ AZ_JSON_TOKEN_STRING
The token kind is a JSON string.
Definition: az_json.h:38
az_json_reader::current_depth
int32_t current_depth
Definition: az_json.h:672
az_json_reader::options
az_json_reader_options options
A copy of the options provided by the user.
Definition: az_json.h:706
az_json_reader::number_of_buffers
int32_t number_of_buffers
Definition: az_json.h:685
az_span_slice
AZ_NODISCARD az_span az_span_slice(az_span span, int32_t start_index, int32_t end_index)
Returns a new az_span which is a sub-span of the specified span.
az_json_writer::total_bytes_written
int32_t total_bytes_written
Definition: az_json.h:309
az_json_token_get_uint64
AZ_NODISCARD az_result az_json_token_get_uint64(az_json_token const *json_token, uint64_t *out_value)
Gets the JSON token's number as a 64-bit unsigned integer.
AZ_JSON_TOKEN_PROPERTY_NAME
@ AZ_JSON_TOKEN_PROPERTY_NAME
The token kind is a JSON property name.
Definition: az_json.h:37
az_json_reader_options_default
AZ_NODISCARD AZ_INLINE az_json_reader_options az_json_reader_options_default()
Gets the default json reader options which reads the JSON strictly according to the JSON RFC.
Definition: az_json.h:646
az_json_reader::bit_stack
_az_json_bit_stack bit_stack
A limited stack to track the depth and nested JSON objects or arrays read so far.
Definition: az_json.h:703
az_span.h
An az_span represents a contiguous byte buffer and is used for string manipulations,...
az_json_token::kind
az_json_token_kind kind
Definition: az_json.h:84
AZ_JSON_TOKEN_NULL
@ AZ_JSON_TOKEN_NULL
The token kind is the JSON literal null.
Definition: az_json.h:42
az_json_reader::buffer_index
int32_t buffer_index
Definition: az_json.h:689
az_json_token::start_buffer_offset
int32_t start_buffer_offset
The offset within the particular segment within which this token starts.
Definition: az_json.h:111
az_json_writer::user_context
void * user_context
Definition: az_json.h:324
az_json_writer_append_json_text
AZ_NODISCARD az_result az_json_writer_append_json_text(az_json_writer *ref_json_writer, az_span json_text)
Appends an existing UTF-8 encoded JSON text into the buffer, useful for appending nested JSON.
az_json_reader::json_buffer
az_span json_buffer
The first buffer containing the JSON payload.
Definition: az_json.h:677
az_json_writer_append_begin_array
AZ_NODISCARD az_result az_json_writer_append_begin_array(az_json_writer *ref_json_writer)
Appends the beginning of a JSON array (i.e. [).
az_json_token_get_string
AZ_NODISCARD az_result az_json_token_get_string(az_json_token const *json_token, char *destination, int32_t destination_max_size, int32_t *out_string_length)
Gets the JSON token's string after unescaping it, if required.
AZ_JSON_TOKEN_NUMBER
@ AZ_JSON_TOKEN_NUMBER
The token kind is a JSON number.
Definition: az_json.h:39
az_json_token_kind
az_json_token_kind
Defines symbols for the various kinds of JSON tokens that make up any JSON text.
Definition: az_json.h:31
AZ_JSON_TOKEN_NONE
@ AZ_JSON_TOKEN_NONE
There is no value (as distinct from AZ_JSON_TOKEN_NULL).
Definition: az_json.h:32
az_json_token::string_has_escaped_chars
bool string_has_escaped_chars
Definition: az_json.h:101
az_json_writer_append_bool
AZ_NODISCARD az_result az_json_writer_append_bool(az_json_writer *ref_json_writer, bool value)
Appends a boolean value (as a JSON literal true or false).
az_json_token
Represents a JSON token. The kind field indicates the type of the JSON token and the slice represents...
Definition: az_json.h:69
az_json_writer_append_null
AZ_NODISCARD az_result az_json_writer_append_null(az_json_writer *ref_json_writer)
Appends the JSON literal null.
az_json_writer::options
az_json_writer_options options
A copy of the options provided by the user.
Definition: az_json.h:339
az_json_token::size
int32_t size
Definition: az_json.h:90
az_json_writer::destination_buffer
az_span destination_buffer
The destination to write the JSON into.
Definition: az_json.h:314
az_json_writer::allocator_callback
az_span_allocator_fn allocator_callback
Allocator used to support non-contiguous buffer as a destination.
Definition: az_json.h:320
AZ_JSON_TOKEN_TRUE
@ AZ_JSON_TOKEN_TRUE
The token kind is the JSON literal true.
Definition: az_json.h:40
AZ_JSON_TOKEN_BEGIN_ARRAY
@ AZ_JSON_TOKEN_BEGIN_ARRAY
The token kind is the start of a JSON array.
Definition: az_json.h:35
az_json_token::start_buffer_index
int32_t start_buffer_index
The segment index within the non-contiguous JSON payload where this token starts.
Definition: az_json.h:108
az_json_reader::is_complex_json
bool is_complex_json
Definition: az_json.h:700
az_json_token::is_multisegment
bool is_multisegment
Definition: az_json.h:97
az_json_token_is_text_equal
AZ_NODISCARD bool az_json_token_is_text_equal(az_json_token const *json_token, az_span expected_text)
Determines whether the unescaped JSON token value that the az_json_token points to is equal to the ex...
az_json_token_copy_into_span
az_span az_json_token_copy_into_span(az_json_token const *json_token, az_span destination)
Copies the content of the token az_json_token to the destination az_span.
az_json_reader_skip_children
AZ_NODISCARD az_result az_json_reader_skip_children(az_json_reader *ref_json_reader)
Reads and skips over any nested JSON elements.
az_json_token::slice
az_span slice
Definition: az_json.h:77
az_json_reader_init
AZ_NODISCARD az_result az_json_reader_init(az_json_reader *out_json_reader, az_span json_buffer, az_json_reader_options const *options)
Initializes an az_json_reader to read the JSON payload contained within the provided buffer.
az_json_token_get_int64
AZ_NODISCARD az_result az_json_token_get_int64(az_json_token const *json_token, int64_t *out_value)
Gets the JSON token's number as a 64-bit signed integer.
az_json_writer::bit_stack
_az_json_bit_stack bit_stack
Definition: az_json.h:336
az_json_writer_append_int32
AZ_NODISCARD az_result az_json_writer_append_int32(az_json_writer *ref_json_writer, int32_t value)
Appends an int32_t number value.
az_json_reader_chunked_init
AZ_NODISCARD az_result az_json_reader_chunked_init(az_json_reader *out_json_reader, az_span json_buffers[], int32_t number_of_buffers, az_json_reader_options const *options)
Initializes an az_json_reader to read the JSON payload contained within the provided set of discontig...
az_json_token_get_int32
AZ_NODISCARD az_result az_json_token_get_int32(az_json_token const *json_token, int32_t *out_value)
Gets the JSON token's number as a 32-bit signed integer.
az_json_reader::bytes_consumed
int32_t bytes_consumed
The number of bytes consumed so far in the current buffer segment.
Definition: az_json.h:692
az_json_writer_init
AZ_NODISCARD az_result az_json_writer_init(az_json_writer *out_json_writer, az_span destination_buffer, az_json_writer_options const *options)
Initializes an az_json_writer which writes JSON text into a buffer.
az_span
Represents a "view" over a byte buffer that represents a contiguous region of memory....
Definition: az_span.h:33
az_json_string_unescape
AZ_NODISCARD az_span az_json_string_unescape(az_span json_string, az_span destination)
Unescapes the JSON string within the provided az_span.