src/json.c

changeset 1132
b7fea9b2874c
parent 1130
5bcb725119b6
equal deleted inserted replaced
1131:644f77f903b1 1132:b7fea9b2874c
27 */ 27 */
28 28
29 #include "cx/json.h" 29 #include "cx/json.h"
30 30
31 #include <string.h> 31 #include <string.h>
32 #include <ctype.h>
33 #include <assert.h> 32 #include <assert.h>
34 #include <stdio.h> 33 #include <stdio.h>
35 #include <inttypes.h> 34 #include <inttypes.h>
36 35
37 /* 36 /*
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;
233 } 242 }
234 case '"': { 243 case '"': {
235 return CX_JSON_TOKEN_STRING; 244 return CX_JSON_TOKEN_STRING;
236 } 245 }
237 default: { 246 default: {
238 if (isspace(c)) { 247 if (json_isspace(c)) {
239 return CX_JSON_TOKEN_SPACE; 248 return CX_JSON_TOKEN_SPACE;
240 } 249 }
241 } 250 }
242 } 251 }
243 return CX_JSON_NO_TOKEN; 252 return CX_JSON_NO_TOKEN;

mercurial