@@ -780,6 +780,10 @@ static bool equivalent_types(enum json_tokens type1, enum json_tokens type2)
780
780
return type2 == JSON_TOK_TRUE || type2 == JSON_TOK_FALSE ;
781
781
}
782
782
783
+ if (type1 == JSON_TOK_ARRAY_START && type2 == JSON_TOK_MIXED_ARRAY ) {
784
+ return true;
785
+ }
786
+
783
787
if (type1 == JSON_TOK_NUMBER && type2 == JSON_TOK_FLOAT ) {
784
788
return true;
785
789
}
@@ -816,6 +820,12 @@ static bool equivalent_types(enum json_tokens type1, enum json_tokens type2)
816
820
return true;
817
821
}
818
822
823
+ if (type2 == JSON_TOK_ENCODED_OBJ ) {
824
+ return (type1 == JSON_TOK_OBJECT_START ||
825
+ type1 == JSON_TOK_ARRAY_START ||
826
+ type1 == JSON_TOK_STRING );
827
+ }
828
+
819
829
if (type1 == JSON_TOK_ARRAY_START && type2 == JSON_TOK_OBJ_ARRAY ) {
820
830
return true;
821
831
}
@@ -1781,3 +1791,366 @@ ssize_t json_calc_encoded_arr_len(const struct json_obj_descr *descr,
1781
1791
1782
1792
return total ;
1783
1793
}
1794
+
1795
+
1796
+ static int mixed_arr_parse (struct json_obj * arr ,
1797
+ const struct json_mixed_arr_descr * descr ,
1798
+ size_t descr_len , void * val );
1799
+ int json_mixed_arr_encode (const struct json_mixed_arr_descr * descr ,
1800
+ size_t descr_len , void * val ,
1801
+ json_append_bytes_t append_bytes ,
1802
+ void * data );
1803
+
1804
+ static int extract_raw_json_data (struct json_obj * obj , struct json_token * value ,
1805
+ char * * field_ptr )
1806
+ {
1807
+ char * start_pos = value -> start ;
1808
+
1809
+ switch (value -> type ) {
1810
+ case JSON_TOK_OBJECT_START :
1811
+ case JSON_TOK_ARRAY_START : {
1812
+ struct json_obj_key_value kv = {
1813
+ .key = NULL ,
1814
+ .key_len = 0 ,
1815
+ .value = * value
1816
+ };
1817
+
1818
+ int ret = skip_field (obj , & kv );
1819
+
1820
+ if (ret < 0 ) {
1821
+ return ret ;
1822
+ }
1823
+
1824
+ char * end_pos = obj -> lex .pos ;
1825
+ * end_pos = '\0' ;
1826
+ * field_ptr = start_pos ;
1827
+
1828
+ return 0 ;
1829
+ }
1830
+
1831
+ case JSON_TOK_STRING :
1832
+ * value -> end = '\0' ;
1833
+ * field_ptr = start_pos ;
1834
+ return 0 ;
1835
+
1836
+ default :
1837
+ return - EINVAL ;
1838
+ }
1839
+ }
1840
+
1841
+ static int64_t decode_mixed_value (struct json_obj * obj ,
1842
+ const struct json_mixed_arr_descr * elem ,
1843
+ struct json_token * value ,
1844
+ void * field , void * val )
1845
+ {
1846
+ if (!equivalent_types (value -> type , elem -> type )) {
1847
+ return - EINVAL ;
1848
+ }
1849
+
1850
+ switch (elem -> type ) {
1851
+ case JSON_TOK_OBJECT_START : {
1852
+ return obj_parse (obj , elem -> object .sub_descr ,
1853
+ elem -> object .sub_descr_len , field );
1854
+ }
1855
+ case JSON_TOK_ARRAY_START : {
1856
+ const struct json_obj_descr * actual_elem_descr = elem -> array .element_descr ;
1857
+ size_t actual_n_elements = elem -> array .n_elements ;
1858
+
1859
+ if (actual_elem_descr -> type == JSON_TOK_ARRAY_START ) {
1860
+ actual_elem_descr = actual_elem_descr -> array .element_descr ;
1861
+ }
1862
+ return arr_parse (obj , actual_elem_descr , actual_n_elements , field , val );
1863
+ }
1864
+ case JSON_TOK_MIXED_ARRAY : {
1865
+ return mixed_arr_parse (obj , elem -> mixed_array .sub_descr ,
1866
+ elem -> mixed_array .sub_descr_len ,
1867
+ field );
1868
+ }
1869
+ case JSON_TOK_FALSE :
1870
+ case JSON_TOK_TRUE : {
1871
+ bool * v = field ;
1872
+
1873
+ * v = (value -> type == JSON_TOK_TRUE );
1874
+ return 0 ;
1875
+ }
1876
+ case JSON_TOK_NUMBER : {
1877
+ int32_t * num32 = field ;
1878
+
1879
+ return decode_int32 (value , num32 );
1880
+ }
1881
+ case JSON_TOK_INT : {
1882
+ return decode_int (value , field , elem -> primitive .size );
1883
+ }
1884
+ case JSON_TOK_UINT : {
1885
+ return decode_uint (value , field , elem -> primitive .size );
1886
+ }
1887
+ case JSON_TOK_INT64 : {
1888
+ int64_t * num64 = field ;
1889
+
1890
+ return decode_int64 (value , num64 );
1891
+ }
1892
+ case JSON_TOK_UINT64 : {
1893
+ uint64_t * unum64 = field ;
1894
+
1895
+ return decode_uint64 (value , unum64 );
1896
+ }
1897
+ case JSON_TOK_FLOAT_FP : {
1898
+ float * f_num = field ;
1899
+
1900
+ return decode_float (value , f_num );
1901
+ }
1902
+ case JSON_TOK_DOUBLE_FP : {
1903
+ double * d_num = field ;
1904
+
1905
+ return decode_double (value , d_num );
1906
+ }
1907
+ case JSON_TOK_STRING : {
1908
+ char * * str_ptr = field ;
1909
+
1910
+ * value -> end = '\0' ;
1911
+ * str_ptr = value -> start ;
1912
+ return 0 ;
1913
+ }
1914
+ case JSON_TOK_STRING_BUF : {
1915
+ char * str_buf = field ;
1916
+
1917
+ return decode_string_buf (value , str_buf , elem -> primitive .size );
1918
+ }
1919
+ case JSON_TOK_OBJ_ARRAY : {
1920
+ struct json_obj_token * obj_token = field ;
1921
+
1922
+ obj_token -> start = value -> start ;
1923
+ return arr_data_parse (obj , obj_token );
1924
+ }
1925
+ case JSON_TOK_OPAQUE :
1926
+ case JSON_TOK_FLOAT : {
1927
+ struct json_obj_token * obj_token = field ;
1928
+
1929
+ obj_token -> start = value -> start ;
1930
+ obj_token -> length = value -> end - value -> start ;
1931
+ return 0 ;
1932
+ }
1933
+ case JSON_TOK_ENCODED_OBJ : {
1934
+ char * * str_ptr = field ;
1935
+
1936
+ return extract_raw_json_data (obj , value , str_ptr );
1937
+ }
1938
+ case JSON_TOK_NULL : {
1939
+ memset (field , 0 , elem -> primitive .size );
1940
+ return 0 ;
1941
+ }
1942
+ default :
1943
+ return - EINVAL ;
1944
+ }
1945
+ }
1946
+
1947
+ static int encode_mixed_value (const struct json_mixed_arr_descr * elem ,
1948
+ void * field , void * val ,
1949
+ json_append_bytes_t append_bytes , void * data )
1950
+ {
1951
+
1952
+ switch (elem -> type ) {
1953
+ case JSON_TOK_OBJECT_START : {
1954
+ return json_obj_encode (elem -> object .sub_descr ,
1955
+ elem -> object .sub_descr_len ,
1956
+ field , append_bytes , data );
1957
+ }
1958
+ case JSON_TOK_ARRAY_START : {
1959
+ const struct json_obj_descr * actual_elem_descr = elem -> array .element_descr ;
1960
+
1961
+ if (actual_elem_descr -> type == JSON_TOK_ARRAY_START ) {
1962
+ actual_elem_descr = actual_elem_descr -> array .element_descr ;
1963
+ }
1964
+ return arr_encode (actual_elem_descr , field , val , append_bytes , data );
1965
+ }
1966
+ case JSON_TOK_MIXED_ARRAY : {
1967
+ return json_mixed_arr_encode (elem -> mixed_array .sub_descr ,
1968
+ elem -> mixed_array .sub_descr_len ,
1969
+ field , append_bytes , data );
1970
+ }
1971
+ case JSON_TOK_FALSE :
1972
+ case JSON_TOK_TRUE : {
1973
+ return bool_encode (field , append_bytes , data );
1974
+ }
1975
+ case JSON_TOK_STRING : {
1976
+ return str_encode (* ((char * * )field ), append_bytes , data );
1977
+ }
1978
+ case JSON_TOK_STRING_BUF : {
1979
+ return str_encode (field , append_bytes , data );
1980
+ }
1981
+ case JSON_TOK_NUMBER : {
1982
+ return int32_encode (field , append_bytes , data );
1983
+ }
1984
+ case JSON_TOK_INT : {
1985
+ return int_encode (field , elem -> primitive .size , append_bytes , data );
1986
+ }
1987
+ case JSON_TOK_UINT : {
1988
+ return uint_encode (field , elem -> primitive .size , append_bytes , data );
1989
+ }
1990
+ case JSON_TOK_INT64 : {
1991
+ return int64_encode (field , append_bytes , data );
1992
+ }
1993
+ case JSON_TOK_UINT64 : {
1994
+ return uint64_encode (field , append_bytes , data );
1995
+ }
1996
+ case JSON_TOK_FLOAT_FP : {
1997
+ return float_encode (field , append_bytes , data );
1998
+ }
1999
+ case JSON_TOK_DOUBLE_FP : {
2000
+ return double_encode (field , append_bytes , data );
2001
+ }
2002
+ case JSON_TOK_FLOAT : {
2003
+ return float_ascii_encode (field , append_bytes , data );
2004
+ }
2005
+ case JSON_TOK_OPAQUE : {
2006
+ return opaque_string_encode (field , append_bytes , data );
2007
+ }
2008
+ case JSON_TOK_ENCODED_OBJ : {
2009
+ return encoded_obj_encode ((const char * * )field , append_bytes , data );
2010
+ }
2011
+ default :
2012
+ return - EINVAL ;
2013
+ }
2014
+ }
2015
+
2016
+ static int mixed_arr_parse (struct json_obj * arr ,
2017
+ const struct json_mixed_arr_descr * descr ,
2018
+ size_t descr_len , void * val )
2019
+ {
2020
+ struct json_token tok ;
2021
+ size_t elem_idx = 0 ;
2022
+ void * field_ptr ;
2023
+ int ret ;
2024
+
2025
+ if (descr_len == 0 ) {
2026
+ if (!arr_next (arr , & tok ) && tok .type == JSON_TOK_ARRAY_END ) {
2027
+ return 0 ;
2028
+ }
2029
+ return - EINVAL ;
2030
+ }
2031
+
2032
+ while (!arr_next (arr , & tok )) {
2033
+ if (tok .type == JSON_TOK_ARRAY_END ) {
2034
+ return elem_idx ;
2035
+ }
2036
+
2037
+ if (elem_idx >= descr_len ) {
2038
+ return - ENOSPC ;
2039
+ }
2040
+
2041
+ switch (descr [elem_idx ].type ) {
2042
+ case JSON_TOK_OBJECT_START :
2043
+ field_ptr = (char * )val + descr [elem_idx ].object .offset ;
2044
+ break ;
2045
+ case JSON_TOK_ARRAY_START :
2046
+ field_ptr = (char * )val + descr [elem_idx ].array .offset ;
2047
+ break ;
2048
+ case JSON_TOK_MIXED_ARRAY :
2049
+ field_ptr = (char * )val + descr [elem_idx ].mixed_array .offset ;
2050
+ break ;
2051
+ default :
2052
+ field_ptr = (char * )val + descr [elem_idx ].primitive .offset ;
2053
+ break ;
2054
+ }
2055
+
2056
+ ret = decode_mixed_value (arr , & descr [elem_idx ], & tok , field_ptr , val );
2057
+ if (ret < 0 ) {
2058
+ return ret ;
2059
+ }
2060
+
2061
+ elem_idx ++ ;
2062
+ }
2063
+
2064
+ return elem_idx ;
2065
+ }
2066
+
2067
+ int json_mixed_arr_parse (char * json , size_t len ,
2068
+ const struct json_mixed_arr_descr * descr ,
2069
+ size_t descr_len , void * val )
2070
+ {
2071
+ struct json_obj arr ;
2072
+ int ret ;
2073
+
2074
+ ret = arr_init (& arr , json , len );
2075
+ if (ret < 0 ) {
2076
+ return ret ;
2077
+ }
2078
+
2079
+ return mixed_arr_parse (& arr , descr , descr_len , val );
2080
+ }
2081
+
2082
+ int json_mixed_arr_encode (const struct json_mixed_arr_descr * descr ,
2083
+ size_t descr_len , void * val ,
2084
+ json_append_bytes_t append_bytes ,
2085
+ void * data )
2086
+ {
2087
+ size_t * element_count ;
2088
+ size_t i ;
2089
+ int ret ;
2090
+ void * field_ptr ;
2091
+
2092
+ if (descr_len == 0 ) {
2093
+ return append_bytes ("[]" , 2 , data );
2094
+ }
2095
+
2096
+ element_count = (size_t * )((char * )val + descr [0 ].count_offset );
2097
+
2098
+ ret = append_bytes ("[" , 1 , data );
2099
+ if (ret < 0 ) {
2100
+ return ret ;
2101
+ }
2102
+
2103
+ for (i = 0 ; i < * element_count && i < descr_len ; i ++ ) {
2104
+ switch (descr [i ].type ) {
2105
+ case JSON_TOK_OBJECT_START :
2106
+ field_ptr = (char * )val + descr [i ].object .offset ;
2107
+ break ;
2108
+ case JSON_TOK_ARRAY_START :
2109
+ field_ptr = (char * )val + descr [i ].array .offset ;
2110
+ break ;
2111
+ case JSON_TOK_MIXED_ARRAY :
2112
+ field_ptr = (char * )val + descr [i ].mixed_array .offset ;
2113
+ break ;
2114
+ default :
2115
+ field_ptr = (char * )val + descr [i ].primitive .offset ;
2116
+ break ;
2117
+ }
2118
+
2119
+ ret = encode_mixed_value (& descr [i ], field_ptr , val , append_bytes , data );
2120
+ if (ret < 0 ) {
2121
+ return ret ;
2122
+ }
2123
+
2124
+ if (i < * element_count - 1 ) {
2125
+ ret = append_bytes ("," , 1 , data );
2126
+ if (ret < 0 ) {
2127
+ return ret ;
2128
+ }
2129
+ }
2130
+ }
2131
+
2132
+ return append_bytes ("]" , 1 , data );
2133
+ }
2134
+
2135
+ int json_mixed_arr_encode_buf (const struct json_mixed_arr_descr * descr ,
2136
+ size_t descr_len , void * val ,
2137
+ char * buffer , size_t buf_size )
2138
+ {
2139
+ struct appender appender = { .buffer = buffer , .size = buf_size };
2140
+
2141
+ return json_mixed_arr_encode (descr , descr_len , val , append_bytes_to_buf , & appender );
2142
+ }
2143
+
2144
+ ssize_t json_calc_mixed_arr_len (const struct json_mixed_arr_descr * descr ,
2145
+ size_t descr_len , void * val )
2146
+ {
2147
+ ssize_t total = 0 ;
2148
+ int ret ;
2149
+
2150
+ ret = json_mixed_arr_encode (descr , descr_len , val , measure_bytes , & total );
2151
+ if (ret < 0 ) {
2152
+ return ret ;
2153
+ }
2154
+
2155
+ return total ;
2156
+ }
0 commit comments