@@ -51,6 +51,7 @@ enum json_tokens {
51
51
JSON_TOK_UINT = 'u' ,
52
52
JSON_TOK_TRUE = 't' ,
53
53
JSON_TOK_FALSE = 'f' ,
54
+ JSON_TOK_MIXED_ARRAY = 'm' ,
54
55
JSON_TOK_NULL = 'n' ,
55
56
JSON_TOK_ERROR = '!' ,
56
57
JSON_TOK_EOF = '\0' ,
@@ -811,6 +812,232 @@ int json_obj_encode(const struct json_obj_descr *descr, size_t descr_len,
811
812
int json_arr_encode (const struct json_obj_descr * descr , const void * val ,
812
813
json_append_bytes_t append_bytes , void * data );
813
814
815
+ /**
816
+ * @brief Descriptor for a mixed-type JSON array.
817
+ *
818
+ * This structure describes a top-level JSON array whose elements may be
819
+ * of different types (primitives, objects, arrays, or nested mixed arrays).
820
+ * Each element in the array is described by an entry in a descriptor array.
821
+ *
822
+ * Mixed arrays are useful for parsing and encoding JSON arrays that do not
823
+ * have a homogeneous element type, such as:
824
+ *
825
+ * [ "string", 42, { "foo": 1 }, [1,2,3], true ]
826
+ *
827
+ * @note This structure and its associated macros are intended for use with
828
+ * the mixed array parsing and encoding APIs (see json_mixed_arr_parse()).
829
+ */
830
+ struct json_mixed_arr_descr {
831
+ uint32_t type : 7 ;
832
+ size_t count_offset ;
833
+
834
+ union {
835
+ struct {
836
+ size_t offset ;
837
+ size_t size ;
838
+ } primitive ;
839
+
840
+ struct {
841
+ const struct json_obj_descr * sub_descr ;
842
+ size_t sub_descr_len ;
843
+ size_t offset ;
844
+ } object ;
845
+
846
+ struct {
847
+ const struct json_obj_descr * element_descr ;
848
+ size_t n_elements ;
849
+ size_t offset ;
850
+ } array ;
851
+
852
+ struct {
853
+ const struct json_mixed_arr_descr * sub_descr ;
854
+ size_t sub_descr_len ;
855
+ size_t offset ;
856
+ } mixed_array ;
857
+ };
858
+ };
859
+
860
+ /**
861
+ * @brief Helper macro to declare a mixed array primitive element descriptor.
862
+ *
863
+ * @param struct_ Struct containing the value.
864
+ * @param field_name_ Field name in the struct.
865
+ * @param type_ Token type for the JSON value (see enum json_tokens).
866
+ * @param count_field_ Field name in the struct for the number of elements.
867
+ *
868
+ * Example:
869
+ * struct foo { int x; size_t x_count; };
870
+ * const struct json_mixed_arr_descr foo_descr[] = {
871
+ * JSON_MIXED_ARR_DESCR_PRIM(struct foo, x, JSON_TOK_NUMBER, x_count),
872
+ * };
873
+ */
874
+ #define JSON_MIXED_ARR_DESCR_PRIM (struct_ , field_name_ , type_ , count_field_ ) \
875
+ { \
876
+ .type = type_, \
877
+ .count_offset = offsetof(struct_, count_field_), \
878
+ .primitive = { \
879
+ .offset = offsetof(struct_, field_name_), \
880
+ .size = SIZEOF_FIELD(struct_, field_name_) \
881
+ } \
882
+ }
883
+
884
+ /**
885
+ * @brief Helper macro to declare a mixed array object element descriptor.
886
+ *
887
+ * @param struct_ Struct containing the object.
888
+ * @param field_name_ Field name in the struct.
889
+ * @param sub_descr_ Array of json_obj_descr describing the object fields.
890
+ * @param count_field_ Field name in the struct for the number of elements.
891
+ *
892
+ * Example:
893
+ * struct bar { int y; };
894
+ * struct foo { struct bar b; size_t b_count; };
895
+ * const struct json_obj_descr bar_descr[] = { ... };
896
+ * const struct json_mixed_arr_descr foo_descr[] = {
897
+ * JSON_MIXED_ARR_DESCR_OBJECT(struct foo, b, bar_descr, b_count),
898
+ * };
899
+ */
900
+ #define JSON_MIXED_ARR_DESCR_OBJECT (struct_ , field_name_ , sub_descr_ , count_field_ ) \
901
+ { \
902
+ .type = JSON_TOK_OBJECT_START, \
903
+ .count_offset = offsetof(struct_, count_field_), \
904
+ .object = { \
905
+ .sub_descr = sub_descr_, \
906
+ .sub_descr_len = ARRAY_SIZE(sub_descr_), \
907
+ .offset = offsetof(struct_, field_name_) \
908
+ } \
909
+ }
910
+
911
+ /**
912
+ * @brief Helper macro to declare a mixed array homogeneous array element descriptor.
913
+ *
914
+ * @param struct_ Struct containing the array.
915
+ * @param field_name_ Field name in the struct.
916
+ * @param max_len_ Maximum number of elements in the array.
917
+ * @param elem_descr_ Element descriptor (pointer to json_obj_descr array).
918
+ * @param count_field_ Field name in the struct for the number of elements.
919
+ *
920
+ * Example:
921
+ * struct foo {
922
+ * int arr[4];
923
+ * size_t arr_count;
924
+ * };
925
+ * const struct json_obj_descr arr_elem_descr[] = {
926
+ * JSON_OBJ_DESCR_ARRAY(struct foo, arr, 4, arr_count, JSON_TOK_NUMBER),
927
+ * };
928
+ * const struct json_mixed_arr_descr foo_descr[] = {
929
+ * JSON_MIXED_ARR_DESCR_ARRAY(struct foo, arr, 4, arr_elem_descr, arr_count),
930
+ * };
931
+ */
932
+ #define JSON_MIXED_ARR_DESCR_ARRAY (struct_ , field_name_ , max_len_ , elem_descr_ , count_field_ ) \
933
+ { \
934
+ .type = JSON_TOK_ARRAY_START, \
935
+ .count_offset = offsetof(struct_, count_field_), \
936
+ .array = { \
937
+ .element_descr = elem_descr_, \
938
+ .n_elements = (max_len_), \
939
+ .offset = offsetof(struct_, field_name_) \
940
+ } \
941
+ }
942
+
943
+ /**
944
+ * @brief Helper macro to declare a nested mixed array element descriptor.
945
+ *
946
+ * @param struct_ Struct containing the nested mixed array.
947
+ * @param field_name_ Field name in the struct.
948
+ * @param sub_descr_ Mixed array descriptor for the nested array.
949
+ * @param count_field_ Field name in the struct for the number of elements.
950
+ *
951
+ * Example:
952
+ * struct foo { ...; size_t nested_count; };
953
+ * const struct json_mixed_arr_descr nested_descr[] = { ... };
954
+ * const struct json_mixed_arr_descr foo_descr[] = {
955
+ * JSON_MIXED_ARR_DESCR_MIXED_ARRAY(struct foo, nested, nested_descr, nested_count),
956
+ * };
957
+ */
958
+ #define JSON_MIXED_ARR_DESCR_MIXED_ARRAY (struct_ , field_name_ , sub_descr_ , count_field_ ) \
959
+ { \
960
+ .type = JSON_TOK_MIXED_ARRAY, \
961
+ .count_offset = offsetof(struct_, count_field_), \
962
+ .mixed_array = { \
963
+ .sub_descr = sub_descr_, \
964
+ .sub_descr_len = ARRAY_SIZE(sub_descr_), \
965
+ .offset = offsetof(struct_, field_name_) \
966
+ } \
967
+ }
968
+
969
+ /**
970
+ * @brief Parse a JSON mixed array into a C structure.
971
+ *
972
+ * This function parses a JSON array (which may contain elements of varying types)
973
+ * according to the provided mixed array descriptor and stores the result in the
974
+ * user-supplied structure.
975
+ *
976
+ * @param json Pointer to the input JSON string.
977
+ * @param len Length of the input JSON string.
978
+ * @param descr Descriptor array describing the structure of the mixed array.
979
+ * @param descr_len Number of elements in the descriptor array.
980
+ * @param val Pointer to the structure to populate with parsed data.
981
+ *
982
+ * @return < 0 if error, number of elements parsed on success.
983
+ */
984
+ int json_mixed_arr_parse (char * json , size_t len ,
985
+ const struct json_mixed_arr_descr * descr ,
986
+ size_t descr_len , void * val );
987
+
988
+ /**
989
+ * @brief Encode a C structure as a JSON mixed array.
990
+ *
991
+ * This function encodes a C structure, described by the mixed array descriptor,
992
+ * as a JSON array.
993
+ *
994
+ * @param descr Descriptor array describing the structure of the mixed array.
995
+ * @param descr_len Number of elements in the descriptor array.
996
+ * @param val Pointer to the structure to encode.
997
+ * @param append_bytes Function to append bytes to the output
998
+ * @param data Data pointer to be passed to the append_bytes callback
999
+ * function.
1000
+ *
1001
+ * @return 0 if mixed array has been successfully encoded. Negative error code on failure.
1002
+ */
1003
+ int json_mixed_arr_encode (const struct json_mixed_arr_descr * descr ,
1004
+ size_t descr_len , void * val ,
1005
+ json_append_bytes_t append_bytes ,
1006
+ void * data );
1007
+
1008
+ /**
1009
+ * @brief Encode a C structure as a JSON mixed array into a buffer.
1010
+ *
1011
+ * This function encodes a C structure, described by the mixed array descriptor,
1012
+ * as a JSON array and writes the result into the provided buffer.
1013
+ *
1014
+ * @param descr Descriptor array describing the structure of the mixed array.
1015
+ * @param descr_len Number of elements in the descriptor array.
1016
+ * @param val Pointer to the structure to encode.
1017
+ * @param buffer Output buffer to write the JSON string.
1018
+ * @param buf_size Size of the output buffer.
1019
+ *
1020
+ * @return 0 if mixed array has been successfully encoded. Negative error code on failure.
1021
+ */
1022
+ int json_mixed_arr_encode_buf (const struct json_mixed_arr_descr * descr ,
1023
+ size_t descr_len , void * val ,
1024
+ char * buffer , size_t buf_size );
1025
+
1026
+ /**
1027
+ * @brief Calculate the length of the encoded JSON mixed array.
1028
+ *
1029
+ * This function calculates the number of bytes required to encode the given
1030
+ * structure as a JSON mixed array, according to the provided descriptor.
1031
+ *
1032
+ * @param descr Descriptor array describing the structure of the mixed array.
1033
+ * @param descr_len Number of elements in the descriptor array.
1034
+ * @param val Pointer to the structure to encode.
1035
+ *
1036
+ * @return Number of bytes required for encoding, or negative error code.
1037
+ */
1038
+ ssize_t json_calc_mixed_arr_len (const struct json_mixed_arr_descr * descr ,
1039
+ size_t descr_len , void * val );
1040
+
814
1041
#ifdef __cplusplus
815
1042
}
816
1043
#endif
0 commit comments