JsonObjectHandler.cpp 17 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583
  1. /*
  2. * Copyright (c) Contributors to the Open 3D Engine Project.
  3. * For complete copyright and license terms please see the LICENSE at the root of this distribution.
  4. *
  5. * SPDX-License-Identifier: Apache-2.0 OR MIT
  6. *
  7. */
  8. #include <AzCore/Casting/numeric_cast.h>
  9. #include <AzCore/JSON/error/error.h>
  10. #include <Framework/JsonObjectHandler.h>
  11. namespace AWSCore
  12. {
  13. class JsonReaderHandler
  14. : public JsonReader
  15. {
  16. public:
  17. virtual ~JsonReaderHandler() = default;
  18. using Ch = char;
  19. using SizeType = rapidjson::SizeType;
  20. bool StartObject()
  21. {
  22. if (!CallArrayHandler())
  23. {
  24. return false;
  25. }
  26. if (m_expecting != Expecting::OBJECT)
  27. {
  28. return UnexpectedContent(Expecting::OBJECT);
  29. }
  30. else
  31. {
  32. m_jsonKeyHandlerStack.push_back(m_targetKeyHandler);
  33. m_jsonArrayHandlerStack.push_back(nullptr);
  34. return true;
  35. }
  36. }
  37. bool EndObject(rapidjson::SizeType memberCount)
  38. {
  39. AZ_UNUSED(memberCount);
  40. m_jsonKeyHandlerStack.pop_back();
  41. m_jsonArrayHandlerStack.pop_back();
  42. return true;
  43. }
  44. bool StartArray()
  45. {
  46. if (!CallArrayHandler())
  47. {
  48. return false;
  49. }
  50. if (m_expecting != Expecting::ARRAY)
  51. {
  52. return UnexpectedContent(Expecting::ARRAY);
  53. }
  54. else
  55. {
  56. m_jsonArrayHandlerStack.push_back(m_targetArrayHandler);
  57. m_jsonKeyHandlerStack.push_back(nullptr);
  58. return true;
  59. }
  60. }
  61. bool EndArray(rapidjson::SizeType elementCount)
  62. {
  63. AZ_UNUSED(elementCount);
  64. m_jsonKeyHandlerStack.pop_back();
  65. m_jsonArrayHandlerStack.pop_back();
  66. return true;
  67. }
  68. bool Key(const Ch* str, rapidjson::SizeType length, bool copy)
  69. {
  70. AZ_UNUSED(str);
  71. AZ_UNUSED(length);
  72. AZ_UNUSED(copy);
  73. if (m_jsonKeyHandlerStack.empty() || !m_jsonKeyHandlerStack.back())
  74. {
  75. return UnexpectedContent("key");
  76. }
  77. else
  78. {
  79. m_expecting = Expecting::NOTHING; // default to ignoring
  80. bool ok = m_jsonKeyHandlerStack.back()(str, *this);
  81. if (!ok)
  82. {
  83. return UnexpectedObjectKey(str);
  84. }
  85. return true;
  86. }
  87. }
  88. inline bool CallArrayHandler()
  89. {
  90. if (!m_jsonArrayHandlerStack.empty() && m_jsonArrayHandlerStack.back())
  91. {
  92. bool ok = m_jsonArrayHandlerStack.back()(*this);
  93. if (!ok)
  94. {
  95. return UnexpectedArrayElement();
  96. }
  97. }
  98. return true;
  99. }
  100. bool String(const Ch* str, rapidjson::SizeType length, bool copy)
  101. {
  102. AZ_UNUSED(str);
  103. AZ_UNUSED(length);
  104. AZ_UNUSED(copy);
  105. if (!CallArrayHandler())
  106. {
  107. return false;
  108. }
  109. if (m_expecting != Expecting::STRING)
  110. {
  111. return UnexpectedContent(Expecting::STRING);
  112. }
  113. else
  114. {
  115. // Doesn't support embedded \0, which rapidjson allows.
  116. *m_targetString = AZStd::string::format("%.*s", aznumeric_cast<int>(length), str);
  117. return true;
  118. }
  119. }
  120. bool RawNumber(const Ch* str, rapidjson::SizeType length, bool copy)
  121. {
  122. return String(str, length, copy);
  123. }
  124. bool Null()
  125. {
  126. if (!CallArrayHandler())
  127. {
  128. return false;
  129. }
  130. return UnexpectedContent("null");
  131. }
  132. bool Bool(bool b)
  133. {
  134. if (!CallArrayHandler())
  135. {
  136. return false;
  137. }
  138. if (m_expecting != Expecting::BOOL)
  139. {
  140. return UnexpectedContent(Expecting::BOOL);
  141. }
  142. else
  143. {
  144. *m_targetBool = b;
  145. return true;
  146. }
  147. }
  148. bool Int(int i)
  149. {
  150. if (!CallArrayHandler())
  151. {
  152. return false;
  153. }
  154. if (m_expecting == Expecting::INT)
  155. {
  156. *m_targetInt = i;
  157. return true;
  158. }
  159. if (m_expecting == Expecting::INT64)
  160. {
  161. *m_targetInt64 = i;
  162. return true;
  163. }
  164. if (m_expecting == Expecting::DOUBLE)
  165. {
  166. *m_targetDouble = i;
  167. return true;
  168. }
  169. return UnexpectedContent(Expecting::INT);
  170. }
  171. bool Uint(unsigned i)
  172. {
  173. if (!CallArrayHandler())
  174. {
  175. return false;
  176. }
  177. if (m_expecting == Expecting::INT && i <= INT_MAX)
  178. {
  179. *m_targetInt = i;
  180. return true;
  181. }
  182. if (m_expecting == Expecting::UINT)
  183. {
  184. *m_targetUInt = i;
  185. return true;
  186. }
  187. if (m_expecting == Expecting::INT64)
  188. {
  189. *m_targetInt64 = i;
  190. return true;
  191. }
  192. if (m_expecting == Expecting::UINT64)
  193. {
  194. *m_targetUInt64 = i;
  195. return true;
  196. }
  197. if (m_expecting == Expecting::DOUBLE)
  198. {
  199. *m_targetDouble = i;
  200. return true;
  201. }
  202. return UnexpectedContent("unsigned");
  203. }
  204. bool Int64(int64_t i)
  205. {
  206. if (!CallArrayHandler())
  207. {
  208. return false;
  209. }
  210. if (m_expecting == Expecting::INT64)
  211. {
  212. *m_targetInt64 = i;
  213. return true;
  214. }
  215. if (m_expecting == Expecting::DOUBLE)
  216. {
  217. *m_targetDouble = aznumeric_caster(i);
  218. return true;
  219. }
  220. return UnexpectedContent(Expecting::INT64);
  221. }
  222. bool Uint64(uint64_t i)
  223. {
  224. if (!CallArrayHandler())
  225. {
  226. return false;
  227. }
  228. if (m_expecting == Expecting::INT64 && i < INT64_MAX)
  229. {
  230. *m_targetInt64 = i;
  231. return true;
  232. }
  233. if (m_expecting == Expecting::UINT64)
  234. {
  235. *m_targetUInt64 = i;
  236. return true;
  237. }
  238. if (m_expecting == Expecting::DOUBLE)
  239. {
  240. *m_targetDouble = aznumeric_caster(i);
  241. return true;
  242. }
  243. return UnexpectedContent(Expecting::UINT64);
  244. }
  245. bool Double(double d)
  246. {
  247. if (!CallArrayHandler())
  248. {
  249. return false;
  250. }
  251. if (m_expecting == Expecting::DOUBLE)
  252. {
  253. *m_targetDouble = d;
  254. return true;
  255. }
  256. return UnexpectedContent(Expecting::DOUBLE);
  257. }
  258. bool Ignore() override
  259. {
  260. m_expecting = JsonReaderHandler::Expecting::NOTHING;
  261. return true;
  262. }
  263. /// Tell the JsonReaderHandler that a boolean value is expected and provide
  264. /// a location where the value can be stored.
  265. bool Accept(bool& target) override
  266. {
  267. m_targetBool = &target;
  268. m_expecting = JsonReaderHandler::Expecting::BOOL;
  269. return true;
  270. }
  271. /// Tell the JsonReaderHandler that a string value is expected and provide
  272. /// a location where the value can be stored.
  273. bool Accept(AZStd::string& target) override
  274. {
  275. m_targetString = &target;
  276. m_expecting = JsonReaderHandler::Expecting::STRING;
  277. return true;
  278. }
  279. /// Tell the JsonReaderHandler that an int value is expected and provide
  280. /// a location where the value can be stored.
  281. bool Accept(int& target) override
  282. {
  283. m_targetInt = &target;
  284. m_expecting = JsonReaderHandler::Expecting::INT;
  285. return true;
  286. }
  287. /// Tell the JsonReaderHandler that an unsigned value is expected and provide
  288. /// a location where the value can be stored.
  289. bool Accept(unsigned& target) override
  290. {
  291. m_targetUInt = &target;
  292. m_expecting = JsonReaderHandler::Expecting::UINT;
  293. return true;
  294. }
  295. /// Tell the JsonReaderHandler that a int64_t value is expected and provide
  296. /// a location where the value can be stored.
  297. bool Accept(int64_t& target) override
  298. {
  299. m_targetInt64 = &target;
  300. m_expecting = JsonReaderHandler::Expecting::INT64;
  301. return true;
  302. }
  303. /// Tell the JsonReaderHandler that a uint64_t value is expected and provide
  304. /// a location where the value can be stored.
  305. bool Accept(uint64_t& target) override
  306. {
  307. m_targetUInt64 = &target;
  308. m_expecting = JsonReaderHandler::Expecting::UINT64;
  309. return true;
  310. }
  311. /// Tell the JsonReaderHandler that a double value is expected and provide
  312. /// a location where the value can be stored.
  313. bool Accept(double& target) override
  314. {
  315. m_targetDouble = &target;
  316. m_expecting = JsonReaderHandler::Expecting::DOUBLE;
  317. return true;
  318. }
  319. /// Tell the JsonReaderHandler that an object is expected and provide
  320. /// a JsonKeyHandler function for that object.
  321. bool Accept(JsonKeyHandler keyHandler) override
  322. {
  323. m_targetKeyHandler = keyHandler;
  324. m_expecting = JsonReaderHandler::Expecting::OBJECT;
  325. return true;
  326. }
  327. bool Accept(JsonArrayHandler arrayHandler) override
  328. {
  329. m_expecting = JsonReaderHandler::Expecting::ARRAY;
  330. m_targetArrayHandler = arrayHandler;
  331. return true;
  332. }
  333. AZStd::string GetParseErrorMessage(const rapidjson::ParseResult& result, JsonInputStream& stream)
  334. {
  335. AZStd::string msg;
  336. switch (result.Code())
  337. {
  338. case rapidjson::kParseErrorNone:
  339. msg = "No error";
  340. break;
  341. case rapidjson::kParseErrorDocumentEmpty:
  342. msg = "The document is empty";
  343. break;
  344. case rapidjson::kParseErrorDocumentRootNotSingular:
  345. msg = "The document root must not follow by other values";
  346. break;
  347. case rapidjson::kParseErrorValueInvalid:
  348. msg = "Invalid value";
  349. break;
  350. case rapidjson::kParseErrorObjectMissName:
  351. msg = "Missing a name for object member";
  352. break;
  353. case rapidjson::kParseErrorObjectMissColon:
  354. msg = "Missing a colon after a name of object member";
  355. break;
  356. case rapidjson::kParseErrorObjectMissCommaOrCurlyBracket:
  357. msg = "Missing a comma or '}' after an object member";
  358. break;
  359. case rapidjson::kParseErrorArrayMissCommaOrSquareBracket:
  360. msg = "Missing a comma or ']' after an array element";
  361. break;
  362. case rapidjson::kParseErrorStringUnicodeEscapeInvalidHex:
  363. msg = "Incorrect hex digit after \\u escape in string";
  364. break;
  365. case rapidjson::kParseErrorStringUnicodeSurrogateInvalid:
  366. msg = "The surrogate pair in string is invalid";
  367. break;
  368. case rapidjson::kParseErrorStringEscapeInvalid:
  369. msg = "Invalid escape character in string";
  370. break;
  371. case rapidjson::kParseErrorStringMissQuotationMark:
  372. msg = "Missing a closing quotation mark in string";
  373. break;
  374. case rapidjson::kParseErrorStringInvalidEncoding:
  375. msg = "Invalid encoding in string";
  376. break;
  377. case rapidjson::kParseErrorNumberTooBig:
  378. msg = "Number too big to be stored in double";
  379. break;
  380. case rapidjson::kParseErrorNumberMissFraction:
  381. msg = "Miss fraction part in number";
  382. break;
  383. case rapidjson::kParseErrorNumberMissExponent:
  384. msg = "Miss exponent in number";
  385. break;
  386. case rapidjson::kParseErrorTermination:
  387. if (m_errorMessage.empty())
  388. {
  389. msg = "Parsing terminated";
  390. }
  391. else
  392. {
  393. msg = m_errorMessage;
  394. }
  395. break;
  396. case rapidjson::kParseErrorUnspecificSyntaxError:
  397. msg = "Unspecific syntax error";
  398. break;
  399. default:
  400. msg = AZStd::string::format("Unexpected error code %i", result.Code());
  401. break;
  402. }
  403. msg += AZStd::string::format(" at character %zu: ", result.Offset());
  404. const int snippet_size = 40;
  405. int start = static_cast<int>(result.Offset() - snippet_size / 2);
  406. int length = snippet_size;
  407. int offset = snippet_size / 2;
  408. if (start < 0) {
  409. length -= -start;
  410. offset -= -start;
  411. start = 0;
  412. }
  413. AZStd::string snippet = stream.GetContent().substr(start, length);
  414. if (offset >= 0 && offset <= snippet.size())
  415. {
  416. snippet.insert(offset, " <--- ");
  417. }
  418. msg += snippet;
  419. return msg;
  420. }
  421. protected:
  422. friend class JsonReader;
  423. enum class Expecting
  424. {
  425. ARRAY,
  426. BOOL,
  427. DOUBLE,
  428. INT,
  429. INT64,
  430. NOTHING,
  431. OBJECT,
  432. STRING,
  433. UINT,
  434. UINT64
  435. };
  436. Expecting m_expecting{ Expecting::NOTHING };
  437. bool* m_targetBool{ nullptr };
  438. AZStd::string* m_targetString{ nullptr };
  439. int* m_targetInt{ nullptr };
  440. unsigned* m_targetUInt{ nullptr };
  441. int64_t* m_targetInt64{ nullptr };
  442. uint64_t* m_targetUInt64{ nullptr };
  443. double* m_targetDouble{ nullptr };
  444. JsonKeyHandler m_targetKeyHandler{};
  445. JsonArrayHandler m_targetArrayHandler{};
  446. AZStd::vector<JsonKeyHandler> m_jsonKeyHandlerStack;
  447. AZStd::vector<JsonArrayHandler> m_jsonArrayHandlerStack;
  448. AZStd::string m_errorMessage;
  449. bool UnexpectedObjectKey(const char* key)
  450. {
  451. m_errorMessage = AZStd::string::format("Found unexpected object key %s",
  452. key
  453. );
  454. return false;
  455. }
  456. bool UnexpectedArrayElement()
  457. {
  458. m_errorMessage = "Found unexpected array element";
  459. return false;
  460. }
  461. bool UnexpectedContent(Expecting actual)
  462. {
  463. return UnexpectedContent(ExpectingToString(actual));
  464. }
  465. bool UnexpectedContent(const char* actual)
  466. {
  467. bool result = false;
  468. if (m_expecting == Expecting::NOTHING)
  469. {
  470. result = true;
  471. }
  472. else if (m_expecting == Expecting::STRING && !strcmp(actual, "null"))
  473. {
  474. // We are allowing null values to parse as empty strings as a workaround for optional fields not always being handled correctly.
  475. result = true;
  476. }
  477. else
  478. {
  479. m_errorMessage = AZStd::string::format("Found %s when expecting %s",
  480. actual,
  481. ExpectingToString(m_expecting)
  482. );
  483. }
  484. return result;
  485. }
  486. static const char* ExpectingToString(Expecting expecting)
  487. {
  488. switch (expecting)
  489. {
  490. case Expecting::ARRAY: return "an array";
  491. case Expecting::BOOL: return "a boolean";
  492. case Expecting::DOUBLE: return "a double";
  493. case Expecting::INT: return "an int";
  494. case Expecting::INT64: return "an int64";
  495. case Expecting::NOTHING: return "nothing";
  496. case Expecting::OBJECT: return "an object";
  497. case Expecting::STRING: return "a string";
  498. case Expecting::UINT: return "an unsigned";
  499. case Expecting::UINT64: return "an uint64";
  500. default: return "unknown";
  501. }
  502. }
  503. };
  504. bool JsonReader::ReadObject(JsonInputStream& stream, JsonKeyHandler keyHandler, AZStd::string& errorMessage)
  505. {
  506. JsonReaderHandler handler;
  507. handler.Accept(keyHandler);
  508. rapidjson::Reader reader;
  509. rapidjson::ParseResult result = reader.Parse(stream, handler);
  510. if (result.IsError())
  511. {
  512. errorMessage = handler.GetParseErrorMessage(result, stream);
  513. return false;
  514. }
  515. else
  516. {
  517. return true;
  518. }
  519. }
  520. } // namespace AWSCore