sjson.cpp 9.6 KB

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