sjson.cpp 11 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591
  1. /*
  2. * Copyright (c) 2012-2016 Daniele Bartolini and individual contributors.
  3. * License: https://github.com/taylor001/crown/blob/master/LICENSE
  4. */
  5. #include "sjson.h"
  6. #include "string_utils.h"
  7. #include "temp_allocator.h"
  8. #include "map.h"
  9. #include "quaternion.h"
  10. namespace crown
  11. {
  12. namespace sjson
  13. {
  14. static const char* next(const char* json, const char c = 0)
  15. {
  16. CE_ASSERT_NOT_NULL(json);
  17. if (c && c != *json)
  18. {
  19. CE_ASSERT(false, "Expected '%c' got '%c'", c, *json);
  20. }
  21. return ++json;
  22. }
  23. static const char* skip_string(const char* json)
  24. {
  25. CE_ASSERT_NOT_NULL(json);
  26. bool escaped = false;
  27. while ((*(json = next(json))) != 0)
  28. {
  29. if (*json == '"' && !escaped)
  30. {
  31. json = next(json);
  32. return json;
  33. }
  34. else if (*json == '\\') escaped = true;
  35. else escaped = false;
  36. }
  37. return json;
  38. }
  39. static const char* skip_value(const char* json)
  40. {
  41. CE_ASSERT_NOT_NULL(json);
  42. switch (*json)
  43. {
  44. case '"': json = skip_string(json); break;
  45. case '[': json = skip_block(json, '[', ']'); break;
  46. case '{': json = skip_block(json, '{', '}'); break;
  47. default: for (; *json != '\0' && *json != ',' && *json != '\n' && *json != ' ' && *json != '}' && *json != ']'; ++json) ; break;
  48. }
  49. return json;
  50. }
  51. static const char* skip_comments(const char* json)
  52. {
  53. CE_ASSERT_NOT_NULL(json);
  54. if (*json == '/')
  55. {
  56. json = next(json);
  57. if (*json == '/')
  58. {
  59. json = next(json, '/');
  60. while (*json && *json != '\n')
  61. json = next(json);
  62. }
  63. else if (*json == '*')
  64. {
  65. json = next(json);
  66. while (*json && *json != '*')
  67. json = next(json);
  68. json = next(json, '*');
  69. json = next(json, '/');
  70. }
  71. else
  72. CE_FATAL("Bad comment");
  73. }
  74. return json;
  75. }
  76. static const char* skip_spaces(const char* json)
  77. {
  78. CE_ASSERT_NOT_NULL(json);
  79. while (*json)
  80. {
  81. if (*json == '/') json = skip_comments(json);
  82. else if (isspace(*json) || *json == ',') ++json;
  83. else break;
  84. }
  85. return json;
  86. }
  87. JsonValueType::Enum type(const char* json)
  88. {
  89. CE_ASSERT_NOT_NULL(json);
  90. switch (*json)
  91. {
  92. case '"': return JsonValueType::STRING;
  93. case '{': return JsonValueType::OBJECT;
  94. case '[': return JsonValueType::ARRAY;
  95. case '-': return JsonValueType::NUMBER;
  96. default: return (isdigit(*json)) ? JsonValueType::NUMBER : (*json == 'n' ? JsonValueType::NIL : JsonValueType::BOOL);
  97. }
  98. }
  99. void parse_string(const char* json, DynamicString& string)
  100. {
  101. CE_ASSERT_NOT_NULL(json);
  102. if (*json == '"')
  103. {
  104. while (*(json = next(json)))
  105. {
  106. // Empty string
  107. if (*json == '"')
  108. {
  109. json = next(json);
  110. return;
  111. }
  112. else if (*json == '\\')
  113. {
  114. json = next(json);
  115. switch (*json)
  116. {
  117. case '"': string += '"'; break;
  118. case '\\': string += '\\'; break;
  119. case '/': string += '/'; break;
  120. case 'b': string += '\b'; break;
  121. case 'f': string += '\f'; break;
  122. case 'n': string += '\n'; break;
  123. case 'r': string += '\r'; break;
  124. case 't': string += '\t'; break;
  125. default:
  126. {
  127. CE_FATAL("Bad escape character");
  128. break;
  129. }
  130. }
  131. }
  132. else
  133. {
  134. string += *json;
  135. }
  136. }
  137. }
  138. CE_FATAL("Bad string");
  139. }
  140. static const char* parse_key(const char* json, DynamicString& key)
  141. {
  142. CE_ASSERT_NOT_NULL(json);
  143. if (*json == '"')
  144. {
  145. parse_string(json, key);
  146. return skip_string(json);
  147. }
  148. else if (isalpha(*json))
  149. {
  150. while (true)
  151. {
  152. if (isspace(*json) || *json == '=')
  153. return json;
  154. key += *json;
  155. ++json;
  156. }
  157. }
  158. CE_FATAL("Bad key");
  159. return NULL;
  160. }
  161. f64 parse_number(const char* json)
  162. {
  163. CE_ASSERT_NOT_NULL(json);
  164. TempAllocator512 alloc;
  165. Array<char> number(alloc);
  166. if (*json == '-')
  167. {
  168. array::push_back(number, '-');
  169. json = next(json, '-');
  170. }
  171. while (isdigit(*json))
  172. {
  173. array::push_back(number, *json);
  174. json = next(json);
  175. }
  176. if (*json == '.')
  177. {
  178. array::push_back(number, '.');
  179. while ((*(json = next(json))) && isdigit(*json))
  180. {
  181. array::push_back(number, *json);
  182. }
  183. }
  184. if (*json == 'e' || *json == 'E')
  185. {
  186. array::push_back(number, *json);
  187. json = next(json);
  188. if (*json == '-' || *json == '+')
  189. {
  190. array::push_back(number, *json);
  191. json = next(json);
  192. }
  193. while (isdigit(*json))
  194. {
  195. array::push_back(number, *json);
  196. json = next(json);
  197. }
  198. }
  199. // Ensure null terminated
  200. array::push_back(number, '\0');
  201. f64 val;
  202. int ok = sscanf(array::begin(number), "%lf", &val);
  203. CE_ASSERT(ok == 1, "Failed to parse f64: %s", array::begin(number));
  204. CE_UNUSED(ok);
  205. return val;
  206. }
  207. bool parse_bool(const char* json)
  208. {
  209. CE_ASSERT_NOT_NULL(json);
  210. switch (*json)
  211. {
  212. case 't':
  213. {
  214. json = next(json, 't');
  215. json = next(json, 'r');
  216. json = next(json, 'u');
  217. json = next(json, 'e');
  218. return true;
  219. }
  220. case 'f':
  221. {
  222. json = next(json, 'f');
  223. json = next(json, 'a');
  224. json = next(json, 'l');
  225. json = next(json, 's');
  226. json = next(json, 'e');
  227. return false;
  228. }
  229. default:
  230. {
  231. CE_FATAL("Bad boolean");
  232. return false;
  233. }
  234. }
  235. }
  236. s32 parse_int(const char* json)
  237. {
  238. return (s32) parse_number(json);
  239. }
  240. f32 parse_float(const char* json)
  241. {
  242. return (f32) parse_number(json);
  243. }
  244. void parse_array(const char* json, JsonArray& array)
  245. {
  246. CE_ASSERT_NOT_NULL(json);
  247. if (*json == '[')
  248. {
  249. json = next(json, '[');
  250. json = skip_spaces(json);
  251. if (*json == ']')
  252. {
  253. json = next(json, ']');
  254. return;
  255. }
  256. while (*json)
  257. {
  258. array::push_back(array, json);
  259. json = skip_value(json);
  260. json = skip_spaces(json);
  261. if (*json == ']')
  262. {
  263. json = next(json, ']');
  264. return;
  265. }
  266. json = skip_spaces(json);
  267. }
  268. }
  269. CE_FATAL("Bad array");
  270. }
  271. static void parse_root_object(const char* json, Map<DynamicString, const char*>& object)
  272. {
  273. CE_ASSERT_NOT_NULL(json);
  274. while (*json)
  275. {
  276. TempAllocator256 ta;
  277. DynamicString key(ta);
  278. json = parse_key(json, key);
  279. json = skip_spaces(json);
  280. json = next(json, '=');
  281. json = skip_spaces(json);
  282. map::set(object, key, json);
  283. json = skip_value(json);
  284. json = skip_spaces(json);
  285. }
  286. }
  287. void parse_object(const char* json, Map<DynamicString, const char*>& object)
  288. {
  289. CE_ASSERT_NOT_NULL(json);
  290. if (*json == '{')
  291. {
  292. json = next(json, '{');
  293. json = skip_spaces(json);
  294. if (*json == '}')
  295. {
  296. next(json, '}');
  297. return;
  298. }
  299. while (*json)
  300. {
  301. TempAllocator256 ta;
  302. DynamicString key(ta);
  303. json = parse_key(json, key);
  304. json = skip_spaces(json);
  305. json = next(json, '=');
  306. json = skip_spaces(json);
  307. map::set(object, key, json);
  308. json = skip_value(json);
  309. json = skip_spaces(json);
  310. if (*json == '}')
  311. {
  312. next(json, '}');
  313. return;
  314. }
  315. json = skip_spaces(json);
  316. }
  317. }
  318. CE_FATAL("Bad object");
  319. }
  320. void parse(const char* json, Map<DynamicString, const char*>& object)
  321. {
  322. CE_ASSERT_NOT_NULL(json);
  323. json = skip_spaces(json);
  324. if (*json == '{')
  325. parse_object(json, object);
  326. else
  327. parse_root_object(json, object);
  328. }
  329. static void parse_root_object(const char* json, JsonObject& object)
  330. {
  331. CE_ASSERT_NOT_NULL(json);
  332. while (*json)
  333. {
  334. const char* key_begin = *json == '"' ? (json + 1) : json;
  335. TempAllocator256 ta;
  336. DynamicString key(ta);
  337. json = parse_key(json, key);
  338. FixedString fs_key(key_begin, key.length());
  339. json = skip_spaces(json);
  340. json = next(json, '=');
  341. json = skip_spaces(json);
  342. map::set(object, fs_key, json);
  343. json = skip_value(json);
  344. json = skip_spaces(json);
  345. }
  346. }
  347. void parse_object(const char* json, JsonObject& object)
  348. {
  349. CE_ASSERT_NOT_NULL(json);
  350. if (*json == '{')
  351. {
  352. json = next(json, '{');
  353. json = skip_spaces(json);
  354. if (*json == '}')
  355. {
  356. next(json, '}');
  357. return;
  358. }
  359. while (*json)
  360. {
  361. const char* key_begin = *json == '"' ? (json + 1) : json;
  362. TempAllocator256 ta;
  363. DynamicString key(ta);
  364. json = parse_key(json, key);
  365. FixedString fs_key(key_begin, key.length());
  366. json = skip_spaces(json);
  367. json = next(json, '=');
  368. json = skip_spaces(json);
  369. map::set(object, fs_key, json);
  370. json = skip_value(json);
  371. json = skip_spaces(json);
  372. if (*json == '}')
  373. {
  374. next(json, '}');
  375. return;
  376. }
  377. json = skip_spaces(json);
  378. }
  379. }
  380. CE_FATAL("Bad object");
  381. }
  382. void parse(const char* json, JsonObject& object)
  383. {
  384. CE_ASSERT_NOT_NULL(json);
  385. json = skip_spaces(json);
  386. if (*json == '{')
  387. parse_object(json, object);
  388. else
  389. parse_root_object(json, object);
  390. }
  391. void parse(Buffer& json, JsonObject& object)
  392. {
  393. array::push_back(json, '\0');
  394. array::pop_back(json);
  395. parse(array::begin(json), object);
  396. }
  397. } // namespace sjson
  398. namespace sjson
  399. {
  400. Vector2 parse_vector2(const char* json)
  401. {
  402. TempAllocator64 ta;
  403. JsonArray array(ta);
  404. sjson::parse_array(json, array);
  405. Vector2 v;
  406. v.x = sjson::parse_float(array[0]);
  407. v.y = sjson::parse_float(array[1]);
  408. return v;
  409. }
  410. Vector3 parse_vector3(const char* json)
  411. {
  412. TempAllocator64 ta;
  413. JsonArray array(ta);
  414. sjson::parse_array(json, array);
  415. Vector3 v;
  416. v.x = sjson::parse_float(array[0]);
  417. v.y = sjson::parse_float(array[1]);
  418. v.z = sjson::parse_float(array[2]);
  419. return v;
  420. }
  421. Vector4 parse_vector4(const char* json)
  422. {
  423. TempAllocator64 ta;
  424. JsonArray array(ta);
  425. sjson::parse_array(json, array);
  426. Vector4 v;
  427. v.x = sjson::parse_float(array[0]);
  428. v.y = sjson::parse_float(array[1]);
  429. v.z = sjson::parse_float(array[2]);
  430. v.w = sjson::parse_float(array[3]);
  431. return v;
  432. }
  433. Quaternion parse_quaternion(const char* json)
  434. {
  435. TempAllocator64 ta;
  436. JsonArray array(ta);
  437. sjson::parse_array(json, array);
  438. Vector3 axis;
  439. axis.x = sjson::parse_float(array[0]);
  440. axis.y = sjson::parse_float(array[1]);
  441. axis.z = sjson::parse_float(array[2]);
  442. f32 angle = sjson::parse_float(array[3]);
  443. return quaternion(axis, angle);
  444. }
  445. Matrix4x4 parse_matrix4x4(const char* json)
  446. {
  447. TempAllocator128 ta;
  448. JsonArray array(ta);
  449. sjson::parse_array(json, array);
  450. Matrix4x4 m;
  451. m.x.x = sjson::parse_float(array[ 0]);
  452. m.x.y = sjson::parse_float(array[ 1]);
  453. m.x.z = sjson::parse_float(array[ 2]);
  454. m.x.w = sjson::parse_float(array[ 3]);
  455. m.y.x = sjson::parse_float(array[ 4]);
  456. m.y.y = sjson::parse_float(array[ 5]);
  457. m.y.z = sjson::parse_float(array[ 6]);
  458. m.y.w = sjson::parse_float(array[ 7]);
  459. m.z.x = sjson::parse_float(array[ 8]);
  460. m.z.y = sjson::parse_float(array[ 9]);
  461. m.z.z = sjson::parse_float(array[10]);
  462. m.z.w = sjson::parse_float(array[11]);
  463. m.t.x = sjson::parse_float(array[12]);
  464. m.t.y = sjson::parse_float(array[13]);
  465. m.t.z = sjson::parse_float(array[14]);
  466. m.t.w = sjson::parse_float(array[15]);
  467. return m;
  468. }
  469. StringId32 parse_string_id(const char* json)
  470. {
  471. TempAllocator1024 ta;
  472. DynamicString str(ta);
  473. sjson::parse_string(json, str);
  474. return str.to_string_id();
  475. }
  476. ResourceId parse_resource_id(const char* json)
  477. {
  478. TempAllocator1024 ta;
  479. DynamicString str(ta);
  480. sjson::parse_string(json, str);
  481. return ResourceId(str.c_str());
  482. }
  483. } // namespace json
  484. } // namespace crown