JsonObjectHandler.h 7.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213
  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. #pragma once
  9. #include <AzCore/std/string/string.h>
  10. #include <AzCore/std/containers/vector.h>
  11. #include <AzCore/std/functional.h>
  12. #include <AzCore/JSON/reader.h>
  13. #include <aws/core/utils/memory/stl/AWSStreamFwd.h>
  14. namespace AWSCore
  15. {
  16. class JsonInputStream
  17. {
  18. public:
  19. typedef char Ch;
  20. JsonInputStream(std::istream& is) : m_is(is)
  21. {
  22. }
  23. Ch Peek() const
  24. {
  25. int c = m_is.peek();
  26. return c == std::char_traits<char>::eof() ? '\0' : static_cast<Ch>(c);
  27. }
  28. Ch Take()
  29. {
  30. int c = m_is.get();
  31. return c == std::char_traits<char>::eof() ? '\0' : static_cast<Ch>(c);
  32. }
  33. size_t Tell() const
  34. {
  35. return static_cast<size_t>(m_is.tellg());
  36. }
  37. Ch* PutBegin()
  38. {
  39. AZ_Assert(false, "Not Implemented");
  40. return nullptr;
  41. }
  42. void Put(Ch)
  43. {
  44. AZ_Assert(false, "Not Implemented");
  45. }
  46. void Flush()
  47. {
  48. AZ_Assert(false, "Not Implemented");
  49. }
  50. size_t PutEnd(Ch*)
  51. {
  52. AZ_Assert(false, "Not Implemented");
  53. return 0;
  54. }
  55. AZStd::string GetContent()
  56. {
  57. m_is.seekg(0);
  58. std::istreambuf_iterator<AZStd::string::value_type> eos;
  59. AZStd::string content{ std::istreambuf_iterator<AZStd::string::value_type>(m_is),eos };
  60. return content;
  61. }
  62. private:
  63. JsonInputStream(const JsonInputStream&) = delete;
  64. JsonInputStream& operator=(const JsonInputStream&) = delete;
  65. std::istream& m_is;
  66. };
  67. class JsonReader;
  68. /// Type of function called to update a JsonReaderHandler's state when reading
  69. /// a JSON object.
  70. typedef AZStd::function<bool(const char* key, JsonReader& reader)> JsonKeyHandler;
  71. /// Type of function called to update a JsonReaderHandler's state when reading
  72. /// a JSON array.
  73. typedef AZStd::function<bool(JsonReader& reader)> JsonArrayHandler;
  74. /// Default GlobalGetJsonKeyHandler template function implementation. Returns a
  75. /// lambda that calls the following function on the object:
  76. ///
  77. /// bool OnJsonKey(const char* key, ServiceApi::JsonReader& reader)
  78. /// {
  79. /// if(strcmp(key, "foo") == 0) return handler.ExpectObject(m_foo)
  80. /// if(strcmp(key, "bar") == 0) return handler.ExpectString(m_bar)
  81. /// return true; // ignore other keys, return false to fail
  82. /// }
  83. ///
  84. template<class ObjectType>
  85. JsonKeyHandler GlobalGetJsonKeyHandler(ObjectType& object)
  86. {
  87. return [&object](const char* key, JsonReader& reader) {
  88. return object.OnJsonKey(key, reader);
  89. };
  90. }
  91. /// Handles the reading of JSON data.
  92. class JsonReader
  93. {
  94. public:
  95. template<class ObjectType>
  96. static JsonKeyHandler GetJsonKeyHandler(ObjectType& object)
  97. {
  98. return GlobalGetJsonKeyHandler(object);
  99. }
  100. /// Read a JSON format object from a stream into an object. ObjectType should
  101. /// implement the following function:
  102. ///
  103. /// static void OnJsonKey(const char* key, JsonReader& reader)
  104. ///
  105. /// This function will be called for each of the object's properties. It should
  106. /// call one of the Expect methods on the state object to identify the expected
  107. /// property type and provide a location where the property value can be stored.
  108. template<class ObjectType>
  109. static bool ReadObject(JsonInputStream& stream, ObjectType& object, AZStd::string& errorMessage)
  110. {
  111. return ReadObject(stream, GetJsonKeyHandler(object), errorMessage);
  112. }
  113. /// Read a JSON format object from a stream. The specified JsonKeyHandler will
  114. /// be called for each of the object's properties. It should call one of the Expect
  115. /// methods on the state object to identify the expected property type and provide
  116. /// a location where the property value can be stored.
  117. static bool ReadObject(JsonInputStream& stream, JsonKeyHandler keyHandler, AZStd::string&);
  118. virtual bool Ignore() = 0;
  119. /// Tell the JsonReaderHandler that a boolean value is expected and provide
  120. /// a location where the value can be stored.
  121. virtual bool Accept(bool& target) = 0;
  122. /// Tell the JsonReaderHandler that a string value is expected and provide
  123. /// a location where the value can be stored.
  124. virtual bool Accept(AZStd::string& target) = 0;
  125. /// Tell the JsonReaderHandler that an int value is expected and provide
  126. /// a location where the value can be stored.
  127. virtual bool Accept(int& target) = 0;
  128. /// Tell the JsonReaderHandler that an unsigned value is expected and provide
  129. /// a location where the value can be stored.
  130. virtual bool Accept(unsigned& target) = 0;
  131. /// Tell the JsonReaderHandler that a int64_t value is expected and provide
  132. /// a location where the value can be stored.
  133. virtual bool Accept(int64_t& target) = 0;
  134. /// Tell the JsonReaderHandler that a uint64_t value is expected and provide
  135. /// a location where the value can be stored.
  136. virtual bool Accept(uint64_t& target) = 0;
  137. /// Tell the JsonReaderHandler that a double value is expected and provide
  138. /// a location where the value can be stored.
  139. virtual bool Accept(double& target) = 0;
  140. /// Tell the JsonReaderHandler that an object is expected and provide
  141. /// a JsonKeyHandler function for that object.
  142. virtual bool Accept(JsonKeyHandler keyHandler) = 0;
  143. /// Tell the JsonReaderHandler that an object is expected and provide
  144. /// a location where the value can be stored. ObjectType should
  145. /// implement the following function:
  146. ///
  147. /// static void OnJsonKey(const char* key, JsonReader& reader)
  148. ///
  149. /// This function will be called for each of the object's properties. It should
  150. /// call one of the Expect methods on the state object to identify the expected
  151. /// property type and provide a location where the property value can be stored.
  152. template<class ObjectType>
  153. bool Accept(ObjectType& object)
  154. {
  155. return Accept(GlobalGetJsonKeyHandler(object));
  156. }
  157. virtual bool Accept(JsonArrayHandler arrayHandler) = 0;
  158. template<class ElementType>
  159. bool Accept(AZStd::vector<ElementType>& target)
  160. {
  161. target.clear();
  162. JsonArrayHandler arrayHandler =
  163. [&target](JsonReader& reader)
  164. {
  165. target.resize(target.size() + 1);
  166. return reader.Accept(target[target.size() - 1]);
  167. };
  168. return Accept(arrayHandler);
  169. }
  170. };
  171. } // namespace AWSCore