json.cpp 5.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298
  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/json.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 json
  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 '"': json = skip_string(json); break;
  46. case '[': json = skip_block(json, '[', ']'); break;
  47. case '{': json = skip_block(json, '{', '}'); break;
  48. default: for (; *json != ',' && *json != '}' && *json != ']'; ++json) ; break;
  49. }
  50. return json;
  51. }
  52. JsonValueType::Enum type(const char* json)
  53. {
  54. CE_ENSURE(NULL != json);
  55. switch (*json)
  56. {
  57. case '"': return JsonValueType::STRING;
  58. case '{': return JsonValueType::OBJECT;
  59. case '[': return JsonValueType::ARRAY;
  60. case '-': return JsonValueType::NUMBER;
  61. default: return (isdigit(*json)) ? JsonValueType::NUMBER : (*json == 'n' ? JsonValueType::NIL : JsonValueType::BOOL);
  62. }
  63. }
  64. static f64 parse_number(const char* json)
  65. {
  66. CE_ENSURE(NULL != json);
  67. TempAllocator512 alloc;
  68. Array<char> number(alloc);
  69. if (*json == '-')
  70. {
  71. array::push_back(number, '-');
  72. ++json;
  73. }
  74. while (isdigit(*json))
  75. {
  76. array::push_back(number, *json);
  77. ++json;
  78. }
  79. if (*json == '.')
  80. {
  81. array::push_back(number, '.');
  82. while (*++json && isdigit(*json))
  83. {
  84. array::push_back(number, *json);
  85. }
  86. }
  87. if (*json == 'e' || *json == 'E')
  88. {
  89. array::push_back(number, *json);
  90. ++json;
  91. if (*json == '-' || *json == '+')
  92. {
  93. array::push_back(number, *json);
  94. ++json;
  95. }
  96. while (isdigit(*json))
  97. {
  98. array::push_back(number, *json);
  99. ++json;
  100. }
  101. }
  102. array::push_back(number, '\0');
  103. f64 val;
  104. int ok = sscanf(array::begin(number), "%lf", &val);
  105. CE_ASSERT(ok == 1, "Failed to parse f64: %s", array::begin(number));
  106. CE_UNUSED(ok);
  107. return val;
  108. }
  109. s32 parse_int(const char* json)
  110. {
  111. return (s32)parse_number(json);
  112. }
  113. f32 parse_float(const char* json)
  114. {
  115. return (f32)parse_number(json);
  116. }
  117. bool parse_bool(const char* json)
  118. {
  119. CE_ENSURE(NULL != json);
  120. switch (*json)
  121. {
  122. case 't':
  123. json = next(json, 't');
  124. json = next(json, 'r');
  125. json = next(json, 'u');
  126. next(json, 'e');
  127. return true;
  128. case 'f':
  129. json = next(json, 'f');
  130. json = next(json, 'a');
  131. json = next(json, 'l');
  132. json = next(json, 's');
  133. next(json, 'e');
  134. return false;
  135. default:
  136. CE_FATAL("Bad boolean");
  137. return false;
  138. }
  139. }
  140. void parse_string(const char* json, DynamicString& string)
  141. {
  142. CE_ENSURE(NULL != json);
  143. if (*json == '"')
  144. {
  145. while (*++json)
  146. {
  147. // Empty string
  148. if (*json == '"')
  149. {
  150. ++json;
  151. return;
  152. }
  153. else if (*json == '\\')
  154. {
  155. ++json;
  156. switch (*json)
  157. {
  158. case '"': string += '"'; break;
  159. case '\\': string += '\\'; break;
  160. case '/': string += '/'; break;
  161. case 'b': string += '\b'; break;
  162. case 'f': string += '\f'; break;
  163. case 'n': string += '\n'; break;
  164. case 'r': string += '\r'; break;
  165. case 't': string += '\t'; break;
  166. default:
  167. {
  168. CE_FATAL("Bad escape character");
  169. break;
  170. }
  171. }
  172. }
  173. else
  174. {
  175. string += *json;
  176. }
  177. }
  178. }
  179. CE_FATAL("Bad string");
  180. }
  181. void parse_array(const char* json, JsonArray& array)
  182. {
  183. CE_ENSURE(NULL != json);
  184. if (*json == '[')
  185. {
  186. json = skip_spaces(++json);
  187. if (*json == ']')
  188. return;
  189. while (*json)
  190. {
  191. array::push_back(array, json);
  192. json = skip_value(json);
  193. json = skip_spaces(json);
  194. if (*json == ']')
  195. return;
  196. json = next(json, ',');
  197. json = skip_spaces(json);
  198. }
  199. }
  200. CE_FATAL("Bad array");
  201. }
  202. void parse_object(const char* json, JsonObject& object)
  203. {
  204. CE_ENSURE(NULL != json);
  205. if (*json == '{')
  206. {
  207. json = skip_spaces(++json);
  208. if (*json == '}')
  209. return;
  210. while (*json)
  211. {
  212. const char* key_begin = *json == '"' ? (json + 1) : json;
  213. TempAllocator256 ta;
  214. DynamicString key(ta);
  215. parse_string(json, key);
  216. FixedString fs_key(key_begin, key.length());
  217. json = skip_string(json);
  218. json = skip_spaces(json);
  219. json = next(json, ':');
  220. json = skip_spaces(json);
  221. map::set(object._map, fs_key, json);
  222. json = skip_value(json);
  223. json = skip_spaces(json);
  224. if (*json == '}')
  225. return;
  226. json = next(json, ',');
  227. json = skip_spaces(json);
  228. }
  229. }
  230. CE_FATAL("Bad object");
  231. }
  232. void parse(const char* json, JsonObject& object)
  233. {
  234. CE_ENSURE(NULL != json);
  235. parse_object(json, object);
  236. }
  237. void parse(Buffer& json, JsonObject& object)
  238. {
  239. array::push_back(json, '\0');
  240. array::pop_back(json);
  241. parse(array::begin(json), object);
  242. }
  243. } // namespace json
  244. } // namespace crown