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; |