| 131 if (token->allocated) { |
130 if (token->allocated) { |
| 132 cx_strfree(&token->content); |
131 cx_strfree(&token->content); |
| 133 } |
132 } |
| 134 } |
133 } |
| 135 |
134 |
| |
135 static bool json_isdigit(char c) { |
| |
136 // TODO: remove once UCX has public API for this |
| |
137 return c >= '0' && c <= '9'; |
| |
138 } |
| |
139 |
| |
140 static bool json_isspace(char c) { |
| |
141 // TODO: remove once UCX has public API for this |
| |
142 return c == ' ' || c == '\t' || c == '\r' || c == '\n' || c == '\v' || c == '\f'; |
| |
143 } |
| |
144 |
| 136 static int num_isexp(const char *content, size_t length, size_t pos) { |
145 static int num_isexp(const char *content, size_t length, size_t pos) { |
| 137 if (pos >= length) { |
146 if (pos >= length) { |
| 138 return 0; |
147 return 0; |
| 139 } |
148 } |
| 140 |
149 |
| 141 int ok = 0; |
150 int ok = 0; |
| 142 for (size_t i = pos; i < length; i++) { |
151 for (size_t i = pos; i < length; i++) { |
| 143 char c = content[i]; |
152 char c = content[i]; |
| 144 if (isdigit(c)) { |
153 if (json_isdigit(c)) { |
| 145 ok = 1; |
154 ok = 1; |
| 146 } else if (i == pos) { |
155 } else if (i == pos) { |
| 147 if (!(c == '+' || c == '-')) { |
156 if (!(c == '+' || c == '-')) { |
| 148 return 0; |
157 return 0; |
| 149 } |
158 } |
| 156 } |
165 } |
| 157 |
166 |
| 158 static CxJsonTokenType token_numbertype(const char *content, size_t length) { |
167 static CxJsonTokenType token_numbertype(const char *content, size_t length) { |
| 159 if (length == 0) return CX_JSON_TOKEN_ERROR; |
168 if (length == 0) return CX_JSON_TOKEN_ERROR; |
| 160 |
169 |
| 161 if (content[0] != '-' && !isdigit(content[0])) { |
170 if (content[0] != '-' && !json_isdigit(content[0])) { |
| 162 return CX_JSON_TOKEN_ERROR; |
171 return CX_JSON_TOKEN_ERROR; |
| 163 } |
172 } |
| 164 |
173 |
| 165 CxJsonTokenType type = CX_JSON_TOKEN_INTEGER; |
174 CxJsonTokenType type = CX_JSON_TOKEN_INTEGER; |
| 166 for (size_t i = 1; i < length; i++) { |
175 for (size_t i = 1; i < length; i++) { |
| 169 return CX_JSON_TOKEN_ERROR; // more than one decimal separator |
178 return CX_JSON_TOKEN_ERROR; // more than one decimal separator |
| 170 } |
179 } |
| 171 type = CX_JSON_TOKEN_NUMBER; |
180 type = CX_JSON_TOKEN_NUMBER; |
| 172 } else if (content[i] == 'e' || content[i] == 'E') { |
181 } else if (content[i] == 'e' || content[i] == 'E') { |
| 173 return num_isexp(content, length, i + 1) ? CX_JSON_TOKEN_NUMBER : CX_JSON_TOKEN_ERROR; |
182 return num_isexp(content, length, i + 1) ? CX_JSON_TOKEN_NUMBER : CX_JSON_TOKEN_ERROR; |
| 174 } else if (!isdigit(content[i])) { |
183 } else if (!json_isdigit(content[i])) { |
| 175 return CX_JSON_TOKEN_ERROR; // char is not a digit, decimal separator or exponent sep |
184 return CX_JSON_TOKEN_ERROR; // char is not a digit, decimal separator or exponent sep |
| 176 } |
185 } |
| 177 } |
186 } |
| 178 |
187 |
| 179 return type; |
188 return type; |