2
0

JSONParser.cpp 14 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624
  1. #include "JSONParser.h"
  2. #include "DiskFile.h"
  3. #include "OS.h"
  4. #include "StringUtils.h"
  5. #include "Assert.h"
  6. #include <stdlib.h>
  7. namespace crown
  8. {
  9. //--------------------------------------------------------------------------
  10. JSONParser::JSONParser(Allocator& allocator, File* file, size_t size) :
  11. m_allocator(allocator),
  12. m_file(file),
  13. m_next_token(0),
  14. m_prev_token(-1),
  15. m_nodes_count(0)
  16. {
  17. if (size > 1024)
  18. {
  19. m_tokens = CE_NEW(m_allocator, JSONToken[1024]);
  20. }
  21. else
  22. {
  23. m_tokens = m_tokens_list;
  24. }
  25. m_tokens_number = size;
  26. parse();
  27. m_nodes = CE_NEW(m_allocator, JSONNode[16]);
  28. }
  29. //--------------------------------------------------------------------------
  30. JSONParser::~JSONParser()
  31. {
  32. if (m_tokens_number > 1024 && m_tokens != NULL)
  33. {
  34. CE_DELETE(m_allocator, m_tokens);
  35. }
  36. if (m_nodes != NULL)
  37. {
  38. CE_DELETE(m_allocator, m_nodes);
  39. }
  40. }
  41. //--------------------------------------------------------------------------
  42. void JSONParser::parse()
  43. {
  44. JSONToken* token;
  45. char c;
  46. while(!m_file->end_of_file())
  47. {
  48. JSONType type;
  49. m_file->read(&c, 1);
  50. switch(c)
  51. {
  52. case '{':
  53. case '[':
  54. {
  55. token = allocate_token();
  56. CE_ASSERT(token != NULL, "Cannot allocate a new token for parsing.\n");
  57. if (m_prev_token != -1)
  58. {
  59. m_tokens[m_prev_token].m_size++;
  60. token->m_parent = m_prev_token;
  61. }
  62. token->m_type = c == '{' ? JSON_OBJECT : JSON_ARRAY;
  63. token->m_start = m_file->position() - 1;
  64. m_prev_token = m_next_token - 1;
  65. break;
  66. }
  67. case '}':
  68. case ']':
  69. {
  70. type = c == '}' ? JSON_OBJECT : JSON_ARRAY;
  71. CE_ASSERT(m_next_token > 0, "");
  72. token = &m_tokens[m_next_token - 1];
  73. while (true)
  74. {
  75. // If token does not have a parent
  76. if (token->m_parent == -1)
  77. {
  78. token->m_end = m_file->position();
  79. break;
  80. }
  81. // If token is started but not finished
  82. if (token->m_start != -1 && token->m_end == -1)
  83. {
  84. CE_ASSERT(token->m_type == type, "Token %d does not have type %d.\n", token->m_id, type);
  85. token->m_end = m_file->position();
  86. m_prev_token = token->m_parent;
  87. break;
  88. }
  89. token = &m_tokens[token->m_parent];
  90. }
  91. fill_token(token, type, token->m_start, token->m_end);
  92. break;
  93. }
  94. case '\"':
  95. {
  96. parse_string();
  97. if (m_prev_token != -1)
  98. {
  99. m_tokens[m_prev_token].m_size++;
  100. }
  101. break;
  102. }
  103. case ':':
  104. {
  105. break;
  106. }
  107. case '\t':
  108. case '\r':
  109. case '\n':
  110. case ',':
  111. case ' ':
  112. {
  113. break;
  114. }
  115. case '-':
  116. case '0':
  117. case '1':
  118. case '2':
  119. case '3':
  120. case '4':
  121. case '5':
  122. case '6':
  123. case '7':
  124. case '8':
  125. case '9':
  126. {
  127. parse_number();
  128. if (m_prev_token != -1)
  129. {
  130. m_tokens[m_prev_token].m_size++;
  131. }
  132. break;
  133. }
  134. case 't': // true
  135. case 'f': // false
  136. {
  137. parse_bool();
  138. if (m_prev_token != -1)
  139. {
  140. m_tokens[m_prev_token].m_size++;
  141. }
  142. break;
  143. }
  144. case 'n': // null
  145. {
  146. break;
  147. }
  148. }
  149. }
  150. for (int i = m_next_token - 1; i >= 0; i--)
  151. {
  152. if (m_tokens[i].m_start != -1 && m_tokens[i].m_end == -1)
  153. {
  154. CE_ASSERT(false, "There is an error in JSON syntax.");
  155. }
  156. }
  157. }
  158. //--------------------------------------------------------------------------
  159. void JSONParser::parse_string()
  160. {
  161. JSONToken* token;
  162. int start = m_file->position();
  163. char c;
  164. while(!m_file->end_of_file())
  165. {
  166. m_file->read(&c, 1);
  167. if (c == '\"' || c == '\'')
  168. {
  169. token = allocate_token();
  170. CE_ASSERT(token != NULL, "Cannot allocate a new token for parsing.\n");
  171. fill_token(token, JSON_STRING, start, m_file->position() - 1);
  172. token->m_parent = m_prev_token;
  173. return;
  174. }
  175. if (c == '\\')
  176. {
  177. m_file->read(&c, 1);
  178. switch(c)
  179. {
  180. case '\"':
  181. case '/' :
  182. case '\\':
  183. case 'b':
  184. case 'f':
  185. case 'r':
  186. case 'n':
  187. case 't':
  188. case 'u':
  189. {
  190. break;
  191. }
  192. default:
  193. {
  194. CE_ASSERT(false, "Wrong character.\n");
  195. }
  196. }
  197. }
  198. }
  199. }
  200. //--------------------------------------------------------------------------
  201. void JSONParser::parse_number()
  202. {
  203. JSONToken* token;
  204. int start = m_file->position() - 1;
  205. char c;
  206. while (!m_file->end_of_file())
  207. {
  208. m_file->read(&c, 1);
  209. switch (c)
  210. {
  211. case '\t':
  212. case '\r':
  213. case '\n':
  214. case ' ':
  215. case ',':
  216. case '}':
  217. case ']':
  218. {
  219. token = allocate_token();
  220. CE_ASSERT(token != NULL, "Cannot allocate a new token for parsing.\n");
  221. fill_token(token, JSON_NUMBER, start, m_file->position() - 1);
  222. token->m_parent = m_prev_token;
  223. m_file->seek(m_file->position() - 1);
  224. return;
  225. }
  226. }
  227. CE_ASSERT(c >= 32 || c < 127, "Wrong character.\n");
  228. }
  229. }
  230. //--------------------------------------------------------------------------
  231. void JSONParser::parse_bool()
  232. {
  233. JSONToken* token;
  234. int start = m_file->position() - 1;
  235. char c;
  236. while (!m_file->end_of_file())
  237. {
  238. m_file->read(&c, 1);
  239. switch (c)
  240. {
  241. case '\t':
  242. case '\r':
  243. case '\n':
  244. case ' ':
  245. case ',':
  246. case '}':
  247. case ']':
  248. {
  249. token = allocate_token();
  250. CE_ASSERT(token != NULL, "Cannot allocate a new token.\n");
  251. fill_token(token, JSON_BOOL, start, m_file->position() - 1);
  252. token->m_parent = m_prev_token;
  253. m_file->seek(m_file->position() - 1);
  254. return;
  255. }
  256. }
  257. CE_ASSERT(c >= 32 || c < 127, "Wrong character.\n");
  258. }
  259. }
  260. //--------------------------------------------------------------------------
  261. JSONToken* JSONParser::allocate_token()
  262. {
  263. JSONToken* token;
  264. if (m_next_token >= m_tokens_number)
  265. {
  266. return NULL;
  267. }
  268. int32_t id = m_next_token;
  269. token = &m_tokens[id];
  270. token->m_id = id;
  271. token->m_start = -1;
  272. token->m_end = -1;
  273. token->m_size = 0;
  274. token->m_parent = -1;
  275. m_next_token++;
  276. return token;
  277. }
  278. //--------------------------------------------------------------------------
  279. void JSONParser::fill_token(JSONToken* token, JSONType type, int32_t start, int32_t end)
  280. {
  281. uint32_t cur_pos = m_file->position();
  282. token->m_type = type;
  283. token->m_start = start;
  284. token->m_end = end;
  285. token->m_size = token->m_end - token->m_start;
  286. char tmp[1024];
  287. m_file->seek(token->m_start);
  288. m_file->read(tmp, token->m_size);
  289. tmp[token->m_size] = '\0';
  290. string::strncpy(token->m_value, tmp, 1024);
  291. m_file->seek(cur_pos);
  292. }
  293. //--------------------------------------------------------------------------
  294. void JSONParser::reset_nodes()
  295. {
  296. CE_DELETE(m_allocator, m_nodes);
  297. m_nodes = CE_NEW(m_allocator, JSONNode[16]);
  298. // reset nodes counter
  299. m_nodes_count = 0;
  300. }
  301. //--------------------------------------------------------------------------
  302. JSONParser& JSONParser::get_root()
  303. {
  304. // Check if root node is an object and if it's the first
  305. CE_ASSERT(m_tokens[0].m_type == JSON_OBJECT && m_nodes_count == 0, "JSON root element '{'' must be first.\n");
  306. m_nodes[m_nodes_count].m_id = m_tokens[0].m_id;
  307. m_nodes[m_nodes_count].m_type = JSON_OBJECT;
  308. m_nodes_count++;
  309. return *this;
  310. }
  311. //--------------------------------------------------------------------------
  312. JSONParser& JSONParser::get_object(const char* key)
  313. {
  314. bool found = false;
  315. int32_t begin = m_nodes_count != 0 ? m_nodes[m_nodes_count-1].m_id : 0;
  316. // For each token
  317. for (int i = begin; i < m_next_token; i++)
  318. {
  319. // Check key and type
  320. if ((string::strcmp(m_tokens[i].m_value, key) == 0) && m_tokens[i].m_type == JSON_STRING)
  321. {
  322. // Check if the successive token is an array
  323. CE_ASSERT(m_tokens[i+1].m_type == JSON_OBJECT, "Token %d is not an Object.\n", m_tokens[i+1].m_id);
  324. found = true;
  325. // Store token's id in a json node
  326. m_nodes[m_nodes_count].m_id = m_tokens[i+1].m_id;
  327. m_nodes[m_nodes_count].m_type = JSON_OBJECT;
  328. // If token stored has parent
  329. if (m_tokens[i+1].has_parent())
  330. {
  331. // Check if precedent token stored is the parent of current token
  332. CE_ASSERT(m_nodes_count && m_nodes[m_nodes_count-1].m_id == m_tokens[i+1].m_parent, "The precedent node is not parent of current.\n");
  333. }
  334. break;
  335. }
  336. }
  337. CE_ASSERT(found, "Node '%s' not found!\n", key);
  338. // Incremente nodes count for the next token
  339. m_nodes_count++;
  340. return *this;
  341. }
  342. //--------------------------------------------------------------------------
  343. JSONParser& JSONParser::get_array(const char* key, uint32_t element)
  344. {
  345. bool found = false;
  346. int32_t begin = m_nodes_count != 0 ? m_nodes[m_nodes_count-1].m_id : 0;
  347. element++;
  348. // For each token
  349. for (int i = begin; i < m_next_token; i++)
  350. {
  351. // Check key and type
  352. if ((string::strcmp(m_tokens[i].m_value, key) == 0) && m_tokens[i].m_type == JSON_STRING)
  353. {
  354. // Check if the successive token is an array
  355. CE_ASSERT(m_tokens[i + 1].m_type == JSON_ARRAY, "Token %d is not an Array.\n", m_tokens[i+1].m_id);
  356. found = true;
  357. // Store array-token's id in a json node
  358. m_nodes[m_nodes_count].m_id = m_tokens[i + 1].m_id;
  359. m_nodes[m_nodes_count].m_type = JSON_ARRAY;
  360. // If token stored has parent
  361. if (m_tokens[i + 1].has_parent())
  362. {
  363. // Check if precedent token stored is the parent of current token
  364. CE_ASSERT(m_nodes_count && m_nodes[m_nodes_count-1].m_id == m_tokens[i + 1].m_parent,
  365. "The precedent node is not parent of current.\n");
  366. }
  367. m_nodes_count++;
  368. // Store element-token's id in a json node
  369. m_nodes[m_nodes_count].m_id = m_tokens[i + 1 + element].m_id;
  370. m_nodes[m_nodes_count].m_type = JSON_ARRAY;
  371. if (m_tokens[i + 1 + element].has_parent())
  372. {
  373. // Check if precedent token stored is the parent of current token
  374. CE_ASSERT(m_nodes[m_nodes_count-1].m_id == m_tokens[i + 1 + element].m_parent,
  375. "The precedent node is not parent of current.\n");
  376. }
  377. break;
  378. }
  379. }
  380. CE_ASSERT(found, "Node '%s' not found!\n", key);
  381. m_nodes_count++;
  382. return *this;
  383. }
  384. //--------------------------------------------------------------------------
  385. JSONParser& JSONParser::get_string(const char* key)
  386. {
  387. bool found = false;
  388. int32_t begin = m_nodes_count != 0 ? m_nodes[m_nodes_count-1].m_id : 0;
  389. for (int i = begin; i < m_next_token; i++)
  390. {
  391. if ((string::strcmp(m_tokens[i].m_value, key) == 0) && m_tokens[i].m_type == JSON_STRING)
  392. {
  393. CE_ASSERT(m_tokens[i+1].m_type == JSON_STRING, "Token %d is not a String.\n", m_tokens[i+1].m_id);
  394. found = true;
  395. m_nodes[m_nodes_count].m_id = m_tokens[i+1].m_id;
  396. m_nodes[m_nodes_count].m_type = JSON_STRING;
  397. if (m_tokens[i+1].has_parent())
  398. {
  399. CE_ASSERT(m_nodes_count && m_nodes[m_nodes_count-1].m_id == m_tokens[i+1].m_parent,
  400. "The precedent node is not parent of current.\n");
  401. }
  402. break;
  403. }
  404. }
  405. CE_ASSERT(found, "Node '%s' not found!\n", key);
  406. m_nodes_count++;
  407. return *this;
  408. }
  409. //--------------------------------------------------------------------------
  410. JSONParser& JSONParser::get_number(const char* key)
  411. {
  412. bool found = false;
  413. int32_t begin = m_nodes_count != 0 ? m_nodes[m_nodes_count-1].m_id : 0;
  414. for (int i = begin; i < m_next_token; i++)
  415. {
  416. if ((string::strcmp(m_tokens[i].m_value, key) == 0) && m_tokens[i].m_type == JSON_STRING)
  417. {
  418. CE_ASSERT(m_tokens[i+1].m_type == JSON_NUMBER, "Token %d is not a Number.\n", m_tokens[i+1].m_id);
  419. found = true;
  420. m_nodes[m_nodes_count].m_id = m_tokens[i+1].m_id;
  421. m_nodes[m_nodes_count].m_type = JSON_NUMBER;
  422. if (m_tokens[i+1].has_parent())
  423. {
  424. CE_ASSERT(m_nodes_count && m_nodes[m_nodes_count-1].m_id == m_tokens[i+1].m_parent,
  425. "The precedent node is not parent of current.\n");
  426. }
  427. break;
  428. }
  429. }
  430. CE_ASSERT(found, "Node '%s' not found!\n", key);
  431. m_nodes_count++;
  432. return *this;
  433. }
  434. //--------------------------------------------------------------------------
  435. JSONParser& JSONParser::get_bool(const char* key)
  436. {
  437. bool found = false;
  438. int32_t begin = m_nodes_count != 0 ? m_nodes[m_nodes_count-1].m_id : 0;
  439. for (int i = begin; i < m_next_token; i++)
  440. {
  441. if ((string::strcmp(m_tokens[i].m_value, key) == 0) && m_tokens[i].m_type == JSON_STRING)
  442. {
  443. CE_ASSERT(m_tokens[i+1].m_type == JSON_BOOL, "Token %d is not a Boolean.\n", m_tokens[i+1].m_id);
  444. found = true;
  445. m_nodes[m_nodes_count].m_id = m_tokens[i+1].m_id;
  446. m_nodes[m_nodes_count].m_type = JSON_BOOL;
  447. if (m_tokens[i+1].has_parent())
  448. {
  449. CE_ASSERT(m_nodes_count && m_nodes[m_nodes_count-1].m_id == m_tokens[i+1].m_parent,
  450. "The precedent node is not parent of current.\n");
  451. }
  452. break;
  453. }
  454. }
  455. CE_ASSERT(found, "Node '%s' not found!\n", key);
  456. m_nodes_count++;
  457. return *this;
  458. }
  459. //--------------------------------------------------------------------------
  460. void JSONParser::to_string(char* value)
  461. {
  462. string::strncpy(value, m_tokens[m_nodes[m_nodes_count-1].m_id].m_value, JSONToken::MAX_TOKEN_LEN);
  463. reset_nodes();
  464. }
  465. //--------------------------------------------------------------------------
  466. void JSONParser::to_float(float& value)
  467. {
  468. value = atof(m_tokens[m_nodes[m_nodes_count-1].m_id].m_value);
  469. reset_nodes();
  470. }
  471. //--------------------------------------------------------------------------
  472. void JSONParser::to_int(int& value)
  473. {
  474. value = atoi(m_tokens[m_nodes[m_nodes_count-1].m_id].m_value);
  475. reset_nodes();
  476. }
  477. //--------------------------------------------------------------------------
  478. void JSONParser::to_bool(bool& value)
  479. {
  480. if (string::strcmp(m_tokens[m_nodes[m_nodes_count-1].m_id].m_value, "true") == 0)
  481. {
  482. value = true;
  483. }
  484. else
  485. {
  486. value = false;
  487. }
  488. reset_nodes();
  489. }
  490. } //namespace crown