1 /*
2  * Copyright (C) 2015-2018 Alibaba Group Holding Limited
3  */
4 
5 #ifndef _INFRA_JSON_PARSER_H_
6 #define _INFRA_JSON_PARSER_H_
7 
8 /* #include "iotx_utils_internal.h" */
9 
10 typedef struct JSON_NV {
11     int nLen;
12     int vLen;
13     int vType;
14     char *pN;
15     char *pV;
16 } JSON_NV;
17 
18 /**
19 The descriptions of the json value node type
20 **/
21 enum JSONTYPE {
22     JNONE = -1,
23     JSTRING = 0,
24     JOBJECT,
25     JARRAY,
26     JNUMBER,
27     JBOOLEAN,
28     JTYPEMAX
29 };
30 
31 /**
32 The error codes produced by the JSON parsers
33 **/
34 enum JSON_PARSE_CODE {
35     JSON_PARSE_ERR,
36     JSON_PARSE_OK,
37     JSON_PARSE_FINISH
38 };
39 
40 /**
41 The return codes produced by the JSON parsers
42 **/
43 enum JSON_PARSE_RESULT {
44     JSON_RESULT_ERR = -1,
45     JSON_RESULT_OK
46 };
47 
48 typedef int (*json_parse_cb)(char *p_cName, int iNameLen, char *p_cValue,
49                              int iValueLen, int iValueType, void *p_Result);
50 
51 /**
52  * @brief Parse the JSON string, and iterate through all keys and values,
53  * then handle the keys and values by callback function.
54  *
55  * @param[in]  p_cJsonStr @n  The JSON string
56  * @param[in]  iStrLen    @n  The JSON string length
57  * @param[in]  pfnCB      @n  Callback function
58  * @param[out] p_CBData   @n  User data
59  * @return JSON_RESULT_OK success, JSON_RESULT_ERR failed
60  * @see None.
61  * @note None.
62  **/
63 int json_parse_name_value(char *p_cJsonStr, int iStrLen, json_parse_cb pfnCB,
64                           void *p_CBData);
65 
66 /**
67  * @brief Get the value by a specified key from a json string
68  *
69  * @param[in]  p_cJsonStr   @n the JSON string
70  * @param[in]  iStrLen      @n the JSON string length
71  * @param[in]  p_cName      @n the specified key string
72  * @param[out] p_iValueLen  @n the value length
73  * @param[out] p_iValueType @n the value type
74  * @return A pointer to the value
75  * @see None.
76  * @note None.
77  **/
78 char *json_get_value_by_name(char *p_cJsonStr, int iStrLen, char *p_cName,
79                              int *p_iValueLen, int *p_iValueType);
80 
81 /**
82  * @brief Get the value by a specified key from a json string
83  *
84  * @param[in]  p_cJsonStr   @n the JSON string
85  * @param[in]  iStrLen      @n the JSON string length
86  * @param[in]  p_cName      @n the specified key string
87  * @param[in]  p_cNameLen   @n the specified key string length
88  * @param[out] p_iValueLen  @n the value length
89  * @param[out] p_iValueType @n the value type
90  * @return A pointer to the value
91  * @see None.
92  * @note None.
93  **/
94 char *json_get_value_by_name_len(char *p_cJsonStr, int iStrLen, char *p_cName,
95                                  int p_cNameLen, int *p_iValueLen,
96                                  int *p_iValueType);
97 
98 /**
99  * @brief Get the JSON object point associate with a given type.
100  *
101  * @param[in] type      @n The object type
102  * @param[in] str       @n The JSON string
103  * @param[in] str_end   @n The end point of Json string
104  * @returns The json object point with the given field type.
105  * @see None.
106  * @note None.
107  */
108 char *json_get_object(int type, char *str, char *str_end);
109 char *json_get_next_object(int type, char *str, char *str_end, char **key,
110                            int *key_len, char **val, int *val_len,
111                            int *val_type);
112 
113 /**
114  * @brief retrieve each key&value pair from the json string
115  *
116  * @param[in]  str   @n Json string to revolve
117  * @param[in]  slen  @n The length of json string
118  * @param[in]  pos   @n cursor
119  * @param[out] key   @n pointer to the next Key object
120  * @param[out] klen  @n Key object length
121  * @param[out] val   @n pointer to the next Value object
122  * @param[out] vlen  @n Value object length
123  * @param[out] vtype @n Value object type(digital, string, object, array)
124  * @see None.
125  * @note None.
126  */
127 #define json_object_for_each_kv(str, slen, pos, key, klen, val, vlen, vtype) \
128     for (pos = json_get_object(JOBJECT, str, str + slen);                    \
129          pos != NULL && *pos != 0 &&                                         \
130          (pos = json_get_next_object(JOBJECT, pos, str + slen, &key, &klen,  \
131                                      &val, &vlen, &vtype)) != 0;)
132 
133 /**
134  * @brief retrieve each entry from the json array
135  *
136  * @param[in]  str   @n Json array to revolve
137  * @param[in]  slen  @n the length of Json array
138  * @param[in]  pos   @n cursor
139  * @param[out] entry @n pointer to the next entry from the array
140  * @param[out] len   @n entry length
141  * @param[out] type  @n entry type(digital, string, object, array)
142  * @see None.
143  * @note None.
144  */
145 #define json_array_for_each_entry(str, slen, pos, entry, len, type)           \
146     for (pos = json_get_object(JARRAY, str, str + slen);                      \
147          pos != NULL && *pos != 0 &&                                          \
148          (pos = json_get_next_object(JARRAY, ++pos, str + slen, 0, 0, &entry, \
149                                      &len, &type)) != 0;)
150 
151 /**
152  * @brief backup the last character to register parameters,
153  *          and set the end character with '\0'
154  *
155  * @param[in]  json_str @n json string
156  * @param[in]  str_len  @n json string lenth
157  * @param[out] register @n used to backup the last character
158  * @see None.
159  * @note None.
160  */
161 #define backup_json_str_last_char(json_str, str_len, register) \
162     {                                                          \
163         register = *((char *)json_str + str_len);              \
164         *((char *)json_str + str_len) = '\0';                  \
165     }
166 
167 /**
168  * @brief restore the last character from register parameters
169  *
170  * @param[in]  json_str @n json string
171  * @param[in]  str_len  @n json string lenth
172  * @param[in] register  @n used to restore the last character
173  * @see None.
174  * @note None.
175  */
176 #define restore_json_str_last_char(json_str, str_len, register) \
177     {                                                           \
178         *((char *)json_str + str_len) = register;               \
179     }
180 
181 char *LITE_json_value_of(char *key, char *src, ...);
182 
183 #endif /* __JSON_PARSER_H__ */
184