sjson.cpp 9.5 KB

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