sjson.cpp 9.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485
  1. /*
  2. * Copyright (c) 2012-2016 Daniele Bartolini and individual contributors.
  3. * License: https://github.com/taylor001/crown/blob/master/LICENSE
  4. */
  5. #include "dynamic_string.h"
  6. #include "map.h"
  7. #include "sjson.h"
  8. #include "string_utils.h"
  9. #include "temp_allocator.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)
  28. {
  29. if (*json == '"' && !escaped)
  30. {
  31. ++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;
  57. if (*json == '/')
  58. {
  59. json = next(json, '/');
  60. while (*json && *json != '\n')
  61. ++json;
  62. }
  63. else if (*json == '*')
  64. {
  65. ++json;
  66. while (*json && *json != '*')
  67. ++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. static const char* parse_key(const char* json, DynamicString& key)
  100. {
  101. CE_ASSERT_NOT_NULL(json);
  102. if (*json == '"')
  103. {
  104. parse_string(json, key);
  105. return skip_string(json);
  106. }
  107. while (true)
  108. {
  109. if (isspace(*json) || *json == '=' || *json == ':')
  110. return json;
  111. key += *json++;
  112. }
  113. CE_FATAL("Bad key");
  114. return NULL;
  115. }
  116. static f64 parse_number(const char* json)
  117. {
  118. CE_ASSERT_NOT_NULL(json);
  119. TempAllocator512 alloc;
  120. Array<char> number(alloc);
  121. if (*json == '-')
  122. {
  123. array::push_back(number, '-');
  124. ++json;
  125. }
  126. while (isdigit(*json))
  127. {
  128. array::push_back(number, *json);
  129. ++json;
  130. }
  131. if (*json == '.')
  132. {
  133. array::push_back(number, '.');
  134. while (*++json && isdigit(*json))
  135. {
  136. array::push_back(number, *json);
  137. }
  138. }
  139. if (*json == 'e' || *json == 'E')
  140. {
  141. array::push_back(number, *json);
  142. ++json;
  143. if (*json == '-' || *json == '+')
  144. {
  145. array::push_back(number, *json);
  146. ++json;
  147. }
  148. while (isdigit(*json))
  149. {
  150. array::push_back(number, *json);
  151. ++json;
  152. }
  153. }
  154. array::push_back(number, '\0');
  155. f64 val;
  156. int ok = sscanf(array::begin(number), "%lf", &val);
  157. CE_ASSERT(ok == 1, "Failed to parse f64: %s", array::begin(number));
  158. CE_UNUSED(ok);
  159. return val;
  160. }
  161. s32 parse_int(const char* json)
  162. {
  163. return (s32)parse_number(json);
  164. }
  165. f32 parse_float(const char* json)
  166. {
  167. return (f32)parse_number(json);
  168. }
  169. bool parse_bool(const char* json)
  170. {
  171. CE_ASSERT_NOT_NULL(json);
  172. switch (*json)
  173. {
  174. case 't':
  175. json = next(json, 't');
  176. json = next(json, 'r');
  177. json = next(json, 'u');
  178. json = next(json, 'e');
  179. return true;
  180. case 'f':
  181. json = next(json, 'f');
  182. json = next(json, 'a');
  183. json = next(json, 'l');
  184. json = next(json, 's');
  185. json = next(json, 'e');
  186. return false;
  187. default:
  188. CE_FATAL("Bad boolean");
  189. return false;
  190. }
  191. }
  192. void parse_string(const char* json, DynamicString& string)
  193. {
  194. CE_ASSERT_NOT_NULL(json);
  195. if (*json == '"')
  196. {
  197. while (*++json)
  198. {
  199. // Empty string
  200. if (*json == '"')
  201. {
  202. ++json;
  203. return;
  204. }
  205. else if (*json == '\\')
  206. {
  207. ++json;
  208. switch (*json)
  209. {
  210. case '"': string += '"'; break;
  211. case '\\': string += '\\'; break;
  212. case '/': string += '/'; break;
  213. case 'b': string += '\b'; break;
  214. case 'f': string += '\f'; break;
  215. case 'n': string += '\n'; break;
  216. case 'r': string += '\r'; break;
  217. case 't': string += '\t'; break;
  218. default: CE_FATAL("Bad escape character"); break;
  219. }
  220. }
  221. else
  222. {
  223. string += *json;
  224. }
  225. }
  226. }
  227. CE_FATAL("Bad string");
  228. }
  229. void parse_array(const char* json, JsonArray& array)
  230. {
  231. CE_ASSERT_NOT_NULL(json);
  232. if (*json == '[')
  233. {
  234. json = skip_spaces(++json);
  235. if (*json == ']')
  236. return;
  237. while (*json)
  238. {
  239. array::push_back(array, json);
  240. json = skip_value(json);
  241. json = skip_spaces(json);
  242. if (*json == ']')
  243. return;
  244. json = skip_spaces(json);
  245. }
  246. }
  247. CE_FATAL("Bad array");
  248. }
  249. static void parse_root_object(const char* json, JsonObject& object)
  250. {
  251. CE_ASSERT_NOT_NULL(json);
  252. while (*json)
  253. {
  254. const char* key_begin = *json == '"' ? (json + 1) : json;
  255. TempAllocator256 ta;
  256. DynamicString key(ta);
  257. json = parse_key(json, key);
  258. FixedString fs_key(key_begin, key.length());
  259. json = skip_spaces(json);
  260. json = next(json, (*json == '=') ? '=' : ':');
  261. json = skip_spaces(json);
  262. map::set(object._map, fs_key, json);
  263. json = skip_value(json);
  264. json = skip_spaces(json);
  265. }
  266. }
  267. void parse_object(const char* json, JsonObject& object)
  268. {
  269. CE_ASSERT_NOT_NULL(json);
  270. if (*json == '{')
  271. {
  272. json = skip_spaces(++json);
  273. if (*json == '}')
  274. return;
  275. while (*json)
  276. {
  277. const char* key_begin = *json == '"' ? (json + 1) : json;
  278. TempAllocator256 ta;
  279. DynamicString key(ta);
  280. json = parse_key(json, key);
  281. FixedString fs_key(key_begin, key.length());
  282. json = skip_spaces(json);
  283. json = next(json, (*json == '=') ? '=' : ':');
  284. json = skip_spaces(json);
  285. map::set(object._map, fs_key, json);
  286. json = skip_value(json);
  287. json = skip_spaces(json);
  288. if (*json == '}')
  289. return;
  290. json = skip_spaces(json);
  291. }
  292. }
  293. CE_FATAL("Bad object");
  294. }
  295. void parse(const char* json, JsonObject& object)
  296. {
  297. CE_ASSERT_NOT_NULL(json);
  298. json = skip_spaces(json);
  299. if (*json == '{')
  300. parse_object(json, object);
  301. else
  302. parse_root_object(json, object);
  303. }
  304. void parse(Buffer& json, JsonObject& object)
  305. {
  306. array::push_back(json, '\0');
  307. array::pop_back(json);
  308. parse(array::begin(json), object);
  309. }
  310. } // namespace sjson
  311. namespace sjson
  312. {
  313. Vector2 parse_vector2(const char* json)
  314. {
  315. TempAllocator64 ta;
  316. JsonArray array(ta);
  317. sjson::parse_array(json, array);
  318. Vector2 v;
  319. v.x = sjson::parse_float(array[0]);
  320. v.y = sjson::parse_float(array[1]);
  321. return v;
  322. }
  323. Vector3 parse_vector3(const char* json)
  324. {
  325. TempAllocator64 ta;
  326. JsonArray array(ta);
  327. sjson::parse_array(json, array);
  328. Vector3 v;
  329. v.x = sjson::parse_float(array[0]);
  330. v.y = sjson::parse_float(array[1]);
  331. v.z = sjson::parse_float(array[2]);
  332. return v;
  333. }
  334. Vector4 parse_vector4(const char* json)
  335. {
  336. TempAllocator64 ta;
  337. JsonArray array(ta);
  338. sjson::parse_array(json, array);
  339. Vector4 v;
  340. v.x = sjson::parse_float(array[0]);
  341. v.y = sjson::parse_float(array[1]);
  342. v.z = sjson::parse_float(array[2]);
  343. v.w = sjson::parse_float(array[3]);
  344. return v;
  345. }
  346. Quaternion parse_quaternion(const char* json)
  347. {
  348. TempAllocator64 ta;
  349. JsonArray array(ta);
  350. sjson::parse_array(json, array);
  351. Quaternion q;
  352. q.x = sjson::parse_float(array[0]);
  353. q.y = sjson::parse_float(array[1]);
  354. q.z = sjson::parse_float(array[2]);
  355. q.w = sjson::parse_float(array[3]);
  356. return q;
  357. }
  358. Matrix4x4 parse_matrix4x4(const char* json)
  359. {
  360. TempAllocator128 ta;
  361. JsonArray array(ta);
  362. sjson::parse_array(json, array);
  363. Matrix4x4 m;
  364. m.x.x = sjson::parse_float(array[ 0]);
  365. m.x.y = sjson::parse_float(array[ 1]);
  366. m.x.z = sjson::parse_float(array[ 2]);
  367. m.x.w = sjson::parse_float(array[ 3]);
  368. m.y.x = sjson::parse_float(array[ 4]);
  369. m.y.y = sjson::parse_float(array[ 5]);
  370. m.y.z = sjson::parse_float(array[ 6]);
  371. m.y.w = sjson::parse_float(array[ 7]);
  372. m.z.x = sjson::parse_float(array[ 8]);
  373. m.z.y = sjson::parse_float(array[ 9]);
  374. m.z.z = sjson::parse_float(array[10]);
  375. m.z.w = sjson::parse_float(array[11]);
  376. m.t.x = sjson::parse_float(array[12]);
  377. m.t.y = sjson::parse_float(array[13]);
  378. m.t.z = sjson::parse_float(array[14]);
  379. m.t.w = sjson::parse_float(array[15]);
  380. return m;
  381. }
  382. StringId32 parse_string_id(const char* json)
  383. {
  384. TempAllocator1024 ta;
  385. DynamicString str(ta);
  386. sjson::parse_string(json, str);
  387. return str.to_string_id();
  388. }
  389. ResourceId parse_resource_id(const char* json)
  390. {
  391. TempAllocator1024 ta;
  392. DynamicString str(ta);
  393. sjson::parse_string(json, str);
  394. return ResourceId(str.c_str());
  395. }
  396. } // namespace json
  397. } // namespace crown