AkJsonBase.h 10 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427
  1. /*******************************************************************************
  2. The content of this file includes portions of the AUDIOKINETIC Wwise Technology
  3. released in source code form as part of the SDK installer package.
  4. Commercial License Usage
  5. Licensees holding valid commercial licenses to the AUDIOKINETIC Wwise Technology
  6. may use this file in accordance with the end user license agreement provided
  7. with the software or, alternatively, in accordance with the terms contained in a
  8. written agreement between you and Audiokinetic Inc.
  9. Apache License Usage
  10. Alternatively, this file may be used under the Apache License, Version 2.0 (the
  11. "Apache License"); you may not use this file except in compliance with the
  12. Apache License. You may obtain a copy of the Apache License at
  13. http://www.apache.org/licenses/LICENSE-2.0.
  14. Unless required by applicable law or agreed to in writing, software distributed
  15. under the Apache License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES
  16. OR CONDITIONS OF ANY KIND, either express or implied. See the Apache License for
  17. the specific language governing permissions and limitations under the License.
  18. Copyright (c) 2023 Audiokinetic Inc.
  19. *******************************************************************************/
  20. #pragma once
  21. #include <map>
  22. #include <string>
  23. #include <vector>
  24. namespace AK
  25. {
  26. namespace WwiseAuthoringAPI
  27. {
  28. template<typename VariantType, typename StringType, typename StringCompareType> class AkJsonBase
  29. {
  30. public:
  31. typedef std::map<StringType, AkJsonBase, StringCompareType> Map;
  32. typedef std::vector<AkJsonBase> Array;
  33. enum class Type
  34. {
  35. Map,
  36. Array,
  37. Variant,
  38. Empty
  39. };
  40. AkJsonBase()
  41. : m_eType(Type::Empty)
  42. , m_ptr(nullptr)
  43. {
  44. }
  45. AkJsonBase(const VariantType& in_other)
  46. : m_eType(Type::Empty)
  47. , m_ptr(nullptr)
  48. {
  49. SetVariant(in_other);
  50. }
  51. AkJsonBase(const Array& in_other)
  52. : m_eType(Type::Empty)
  53. , m_ptr(nullptr)
  54. {
  55. SetArray(in_other);
  56. }
  57. AkJsonBase(const Map& in_other)
  58. : m_eType(Type::Empty)
  59. , m_ptr(nullptr)
  60. {
  61. SetMap(in_other);
  62. }
  63. AkJsonBase(Type in_eType)
  64. : m_eType(Type::Empty)
  65. , m_ptr(nullptr)
  66. {
  67. SetType(in_eType);
  68. }
  69. AkJsonBase(const AkJsonBase& in_other)
  70. : m_eType(Type::Empty)
  71. , m_ptr(nullptr)
  72. {
  73. Copy(in_other, *this);
  74. }
  75. AkJsonBase(AkJsonBase&& in_other)
  76. {
  77. m_ptr = in_other.m_ptr;
  78. m_eType = in_other.m_eType;
  79. in_other.m_ptr = nullptr;
  80. in_other.m_eType = Type::Empty;
  81. }
  82. virtual ~AkJsonBase()
  83. {
  84. Clear();
  85. }
  86. inline bool IsEmpty() const
  87. {
  88. return (m_eType == Type::Empty);
  89. }
  90. inline AkJsonBase& operator=(const AkJsonBase& in_other)
  91. {
  92. Copy(in_other, *this);
  93. return *this;
  94. }
  95. inline AkJsonBase& operator=(AkJsonBase&& in_other)
  96. {
  97. Type copyType = this->m_eType;
  98. void* copyPtr = this->m_ptr;
  99. m_ptr = in_other.m_ptr;
  100. m_eType = in_other.m_eType;
  101. in_other.m_eType = copyType;
  102. in_other.m_ptr = copyPtr;
  103. return *this;
  104. }
  105. void SetVariant(const VariantType& in_other)
  106. {
  107. SetType(Type::Variant);
  108. *m_pVariant = in_other;
  109. }
  110. void SetArray(const Array& in_other)
  111. {
  112. SetType(Type::Array);
  113. (*m_pArray).assign(in_other.begin(), in_other.end());
  114. }
  115. void SetMap(const Map& in_other)
  116. {
  117. SetType(Type::Map);
  118. (*m_pMap).clear();
  119. (*m_pMap).insert(in_other.begin(), in_other.end());
  120. }
  121. static void Copy(const AkJsonBase& in_rSrc, AkJsonBase& in_rDest)
  122. {
  123. switch (in_rSrc.GetType())
  124. {
  125. case Type::Array:
  126. in_rDest.SetArray(in_rSrc.GetArray());
  127. break;
  128. case Type::Map:
  129. in_rDest.SetMap(in_rSrc.GetMap());
  130. break;
  131. case Type::Variant:
  132. in_rDest.SetVariant(in_rSrc.GetVariant());
  133. break;
  134. default:
  135. in_rDest.Clear();
  136. }
  137. }
  138. void SetType(Type in_eType)
  139. {
  140. if (in_eType != m_eType)
  141. {
  142. Clear();
  143. m_eType = in_eType;
  144. switch (in_eType)
  145. {
  146. case Type::Array:
  147. m_pArray = new Array();
  148. break;
  149. case Type::Map:
  150. m_pMap = new Map();
  151. break;
  152. case Type::Variant:
  153. m_pVariant = new VariantType();
  154. break;
  155. default:
  156. m_eType = Type::Empty;
  157. AKASSERT(!L"Invalid node type");
  158. }
  159. }
  160. }
  161. void Clear()
  162. {
  163. if (!m_ptr)
  164. return;
  165. switch (m_eType)
  166. {
  167. case Type::Array:
  168. delete m_pArray;
  169. break;
  170. case Type::Map:
  171. delete m_pMap;
  172. break;
  173. case Type::Variant:
  174. delete m_pVariant;
  175. break;
  176. default:
  177. break;
  178. }
  179. m_eType = Type::Empty;
  180. m_ptr = nullptr;
  181. }
  182. inline Type GetType() const { return m_eType; }
  183. inline bool IsArray() const
  184. {
  185. return m_eType == Type::Array;
  186. }
  187. inline bool IsMap() const
  188. {
  189. return m_eType == Type::Map;
  190. }
  191. inline bool IsVariant() const
  192. {
  193. return m_eType == Type::Variant;
  194. }
  195. inline Array& GetArray() const
  196. {
  197. AKASSERT(m_eType == Type::Array);
  198. return *m_pArray;
  199. }
  200. inline const Map& GetMap() const
  201. {
  202. AKASSERT(m_eType == Type::Map);
  203. return *m_pMap;
  204. }
  205. inline const VariantType& GetVariant() const
  206. {
  207. AKASSERT(m_eType == Type::Variant);
  208. return *m_pVariant;
  209. }
  210. inline Array& GetArray()
  211. {
  212. AKASSERT(m_eType == Type::Array);
  213. return *m_pArray;
  214. }
  215. inline Map& GetMap()
  216. {
  217. AKASSERT(m_eType == Type::Map);
  218. return *m_pMap;
  219. }
  220. inline VariantType& GetVariant()
  221. {
  222. AKASSERT(m_eType == Type::Variant);
  223. return *m_pVariant;
  224. }
  225. inline bool HasKey(const StringType& in_key) const
  226. {
  227. if (m_eType == Type::Map)
  228. {
  229. return (GetMap().find(in_key) != GetMap().end());
  230. }
  231. else
  232. {
  233. AKASSERT(!"Calling HasKey on AkJsonBase which is NOT a map!");
  234. }
  235. return false;
  236. }
  237. const AkJsonBase& operator[](const StringType& in_key) const
  238. {
  239. if (m_eType == Type::Map)
  240. {
  241. auto it = GetMap().find(in_key);
  242. AKASSERT(it != GetMap().end());
  243. if (it != GetMap().end())
  244. return it->second;
  245. }
  246. else
  247. {
  248. AKASSERT(!"Calling [] operator on AkJsonBase which is NOT a map!");
  249. }
  250. static AkJsonBase empty;
  251. return empty;
  252. }
  253. const AkJsonBase& operator[](const uint32_t in_index) const
  254. {
  255. if (m_eType == Type::Array)
  256. {
  257. AKASSERT(in_index != GetArray().size());
  258. if (in_index < GetArray().size())
  259. return GetArray()[in_index];
  260. }
  261. else
  262. {
  263. AKASSERT(!"Calling [] operator on AkJsonBase which is NOT an array!");
  264. }
  265. static AkJsonBase empty;
  266. return empty;
  267. }
  268. // Implicit interface compatible with rapidjson. Dependency on rapidjson is not required if those functions are not used.
  269. template<typename RapidJsonValue, typename RapidJsonAllocator, typename RapidJsonSizeType, typename StringToValue>
  270. static bool ToRapidJson(const AkJsonBase& in_node, RapidJsonValue& out_rapidJson, RapidJsonAllocator& in_allocator);
  271. template<typename RapidJsonValue>
  272. static bool FromRapidJson(const RapidJsonValue& in_rapidJson, AkJsonBase& out_node);
  273. private:
  274. Type m_eType;
  275. union
  276. {
  277. void* m_ptr;
  278. Map* m_pMap;
  279. Array* m_pArray;
  280. VariantType* m_pVariant;
  281. };
  282. };
  283. //<rapidjson::Value>
  284. template<typename VariantType, typename StringType, typename StringCompareType>
  285. template<typename RapidJsonValue>
  286. bool AkJsonBase<VariantType, StringType, StringCompareType>::FromRapidJson(const RapidJsonValue& in_rapidJson, AkJsonBase& out_node)
  287. {
  288. if (in_rapidJson.IsObject())
  289. {
  290. out_node.SetType(AkJsonBase::Type::Map);
  291. AkJsonBase::Map& map = out_node.GetMap();
  292. for (auto it = in_rapidJson.MemberBegin(); it != in_rapidJson.MemberEnd(); ++it)
  293. {
  294. StringType rosName(it->name.GetString());
  295. map[rosName] = AkJsonBase();
  296. if (!FromRapidJson(it->value, map[rosName]))
  297. return false;
  298. }
  299. }
  300. else if (in_rapidJson.IsArray())
  301. {
  302. out_node.SetType(AkJsonBase::Type::Array);
  303. AkJsonBase::Array& array = out_node.GetArray();
  304. for (auto it = in_rapidJson.Begin(); it != in_rapidJson.End(); ++it)
  305. {
  306. array.push_back(AkJsonBase());
  307. if (!FromRapidJson(*it, array.back()))
  308. return false;
  309. }
  310. }
  311. else
  312. {
  313. out_node.SetType(AkJsonBase::Type::Variant);
  314. out_node.SetVariant(VariantType::template FromRapidJsonValue<decltype(in_rapidJson)>(in_rapidJson));
  315. return (!out_node.GetVariant().IsEmpty());
  316. }
  317. return true;
  318. }
  319. //<rapidjson::Value, rapidjson::MemoryPoolAllocator<>, rapidjson::SizeType>
  320. template<typename VariantType, typename StringType, typename StringCompareType>
  321. template<typename RapidJsonValue, typename RapidJsonAllocator, typename RapidJsonSizeType, typename StringToValue>
  322. bool AkJsonBase<VariantType, StringType, StringCompareType>::ToRapidJson(const AkJsonBase& in_node, RapidJsonValue& out_rapidJson, RapidJsonAllocator& in_allocator)
  323. {
  324. if (in_node.GetType() == AkJsonBase::Type::Map)
  325. {
  326. out_rapidJson.SetObject();
  327. const AkJsonBase::Map& map = in_node.GetMap();
  328. for (auto it = map.begin(); it != map.end(); ++it)
  329. {
  330. RapidJsonValue value;
  331. if (!ToRapidJson<RapidJsonValue, RapidJsonAllocator, RapidJsonSizeType, StringToValue>(it->second, value, in_allocator))
  332. return false;
  333. StringType name(it->first);
  334. RapidJsonValue key = StringToValue::Convert(name, in_allocator);
  335. out_rapidJson.AddMember(key, value, in_allocator);
  336. }
  337. }
  338. else if (in_node.GetType() == AkJsonBase::Type::Array)
  339. {
  340. out_rapidJson.SetArray();
  341. const AkJsonBase::Array& arr = in_node.GetArray();
  342. for (auto it = arr.begin(); it != arr.end(); ++it)
  343. {
  344. RapidJsonValue value;
  345. if (!ToRapidJson<RapidJsonValue, RapidJsonAllocator, RapidJsonSizeType, StringToValue>(*it, value, in_allocator))
  346. return false;
  347. out_rapidJson.PushBack(value, in_allocator);
  348. }
  349. }
  350. else if (in_node.GetType() == AkJsonBase::Type::Empty)
  351. {
  352. out_rapidJson.SetNull();
  353. }
  354. else
  355. {
  356. const VariantType& value = in_node.GetVariant();
  357. return value.template toRapidJsonValue<decltype(out_rapidJson), decltype(in_allocator), RapidJsonSizeType>(out_rapidJson, in_allocator);
  358. }
  359. return true;
  360. }
  361. }
  362. }