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