AkJsonBase.h 12 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477
  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. #include <utility>
  25. namespace AK
  26. {
  27. namespace WwiseAuthoringAPI
  28. {
  29. template<typename VariantType, typename StringType, typename StringCompareType> class AkJsonBase final
  30. {
  31. public:
  32. typedef std::map<StringType, AkJsonBase, StringCompareType> Map;
  33. typedef std::vector<AkJsonBase> Array;
  34. enum class Type
  35. {
  36. Map,
  37. Array,
  38. Variant,
  39. Empty
  40. };
  41. AkJsonBase() {}
  42. AkJsonBase(const VariantType& in_other)
  43. {
  44. SetVariant(in_other);
  45. }
  46. AkJsonBase(const Array& in_other)
  47. {
  48. SetArray(in_other);
  49. }
  50. AkJsonBase(const Map& in_other)
  51. {
  52. SetMap(in_other);
  53. }
  54. AkJsonBase(Type in_eType)
  55. {
  56. SetType(in_eType);
  57. }
  58. AkJsonBase(const AkJsonBase& in_other)
  59. {
  60. Copy(in_other, *this);
  61. }
  62. AkJsonBase(AkJsonBase&& in_other) noexcept
  63. {
  64. m_ptr = in_other.m_ptr;
  65. m_eType = in_other.m_eType;
  66. in_other.m_ptr = nullptr;
  67. in_other.m_eType = Type::Empty;
  68. }
  69. ~AkJsonBase()
  70. {
  71. Clear();
  72. }
  73. inline bool IsEmpty() const
  74. {
  75. return (m_eType == Type::Empty);
  76. }
  77. inline AkJsonBase& operator=(const AkJsonBase& in_other)
  78. {
  79. Copy(in_other, *this);
  80. return *this;
  81. }
  82. inline AkJsonBase& operator=(AkJsonBase&& in_other) noexcept
  83. {
  84. std::swap(this->m_eType, in_other.m_eType);
  85. std::swap(this->m_ptr, in_other.m_ptr);
  86. return *this;
  87. }
  88. void SetVariant(const VariantType& in_other)
  89. {
  90. SetType(Type::Variant);
  91. *m_pVariant = in_other;
  92. AKASSERT(*m_pVariant == in_other);
  93. AKASSERT(m_pVariant->GetType() == in_other.GetType());
  94. }
  95. void SetArray(const Array& in_other)
  96. {
  97. #ifdef _DEBUG
  98. for (const auto& element : in_other)
  99. {
  100. AKASSERT(!element.IsEmpty());
  101. }
  102. #endif
  103. SetType(Type::Array);
  104. (*m_pArray).assign(in_other.begin(), in_other.end());
  105. AKASSERT(m_pArray->size() == in_other.size());
  106. }
  107. void SetMap(const Map& in_other)
  108. {
  109. #ifdef _DEBUG
  110. for (const auto& element : in_other)
  111. {
  112. AKASSERT(!element.second.IsEmpty());
  113. }
  114. #endif
  115. SetType(Type::Map);
  116. (*m_pMap).clear();
  117. (*m_pMap).insert(in_other.begin(), in_other.end());
  118. AKASSERT(m_pMap->size() == in_other.size());
  119. }
  120. static void Copy(const AkJsonBase& in_rSrc, AkJsonBase& in_rDest)
  121. {
  122. switch (in_rSrc.GetType())
  123. {
  124. case Type::Array:
  125. {
  126. in_rDest.SetArray(in_rSrc.GetArray());
  127. AKASSERT(in_rDest.GetType() == Type::Array);
  128. break;
  129. }
  130. case Type::Map:
  131. {
  132. in_rDest.SetMap(in_rSrc.GetMap());
  133. AKASSERT(in_rDest.GetType() == Type::Map);
  134. break;
  135. }
  136. case Type::Variant:
  137. {
  138. in_rDest.SetVariant(in_rSrc.GetVariant());
  139. AKASSERT(in_rDest.GetType() == Type::Variant);
  140. break;
  141. }
  142. case Type::Empty:
  143. {
  144. in_rDest.Clear();
  145. AKASSERT(in_rDest.GetType() == Type::Empty);
  146. break;
  147. }
  148. default:
  149. {
  150. AKASSERT(!"Invalid type copied");
  151. in_rDest.Clear();
  152. AKASSERT(in_rDest.GetType() == Type::Empty);
  153. break;
  154. }
  155. }
  156. }
  157. void SetType(Type in_eType)
  158. {
  159. if (in_eType != m_eType)
  160. {
  161. Clear();
  162. AKASSERT(m_ptr == nullptr);
  163. m_eType = in_eType;
  164. switch (in_eType)
  165. {
  166. case Type::Array:
  167. m_pArray = new Array();
  168. break;
  169. case Type::Map:
  170. m_pMap = new Map();
  171. break;
  172. case Type::Variant:
  173. m_pVariant = new VariantType();
  174. break;
  175. case Type::Empty:
  176. m_eType = Type::Empty;
  177. AKASSERT(!L"Cannot assign type empty");
  178. break;
  179. default:
  180. m_eType = Type::Empty;
  181. AKASSERT(!L"Unknown type assigned");
  182. break;
  183. }
  184. }
  185. AKASSERT(m_eType == in_eType);
  186. AKASSERT(m_ptr != nullptr);
  187. }
  188. void Clear()
  189. {
  190. if (m_ptr == nullptr)
  191. {
  192. AKASSERT(m_eType == Type::Empty);
  193. return;
  194. }
  195. switch (m_eType)
  196. {
  197. case Type::Array:
  198. delete m_pArray;
  199. break;
  200. case Type::Map:
  201. delete m_pMap;
  202. break;
  203. case Type::Variant:
  204. delete m_pVariant;
  205. break;
  206. case Type::Empty:
  207. default:
  208. // Leak any value pointed to by m_ptr: unknown type
  209. AKASSERT(!"Empty-typed variant with non-null value");
  210. break;
  211. }
  212. m_eType = Type::Empty;
  213. m_ptr = nullptr;
  214. }
  215. inline Type GetType() const
  216. {
  217. AKASSERT(
  218. m_eType == Type::Map ||
  219. m_eType == Type::Array ||
  220. m_eType == Type::Variant ||
  221. m_eType == Type::Empty
  222. );
  223. return m_eType;
  224. }
  225. inline bool IsArray() const
  226. {
  227. return m_eType == Type::Array;
  228. }
  229. inline bool IsMap() const
  230. {
  231. return m_eType == Type::Map;
  232. }
  233. inline bool IsVariant() const
  234. {
  235. return m_eType == Type::Variant;
  236. }
  237. inline Array& GetArray() const
  238. {
  239. AKASSERT(m_eType == Type::Array);
  240. AKASSERT(m_pArray != nullptr);
  241. return *m_pArray;
  242. }
  243. inline const Map& GetMap() const
  244. {
  245. AKASSERT(m_eType == Type::Map);
  246. AKASSERT(m_pMap != nullptr);
  247. return *m_pMap;
  248. }
  249. inline const VariantType& GetVariant() const
  250. {
  251. AKASSERT(m_eType == Type::Variant);
  252. AKASSERT(m_pVariant != nullptr);
  253. return *m_pVariant;
  254. }
  255. inline Array& GetArray()
  256. {
  257. AKASSERT(m_eType == Type::Array);
  258. AKASSERT(m_pArray != nullptr);
  259. return *m_pArray;
  260. }
  261. inline Map& GetMap()
  262. {
  263. AKASSERT(m_eType == Type::Map);
  264. AKASSERT(m_pMap != nullptr);
  265. return *m_pMap;
  266. }
  267. inline VariantType& GetVariant()
  268. {
  269. AKASSERT(m_eType == Type::Variant);
  270. AKASSERT(m_pVariant != nullptr);
  271. return *m_pVariant;
  272. }
  273. inline bool HasKey(const StringType& in_key) const
  274. {
  275. if (m_eType == Type::Map)
  276. {
  277. return (GetMap().find(in_key) != GetMap().end());
  278. }
  279. else
  280. {
  281. AKASSERT(!"Calling HasKey on AkJsonBase which is NOT a map!");
  282. }
  283. return false;
  284. }
  285. const AkJsonBase& operator[](const StringType& in_key) const
  286. {
  287. if (m_eType == Type::Map)
  288. {
  289. auto it = GetMap().find(in_key);
  290. AKASSERT(it != GetMap().end());
  291. if (it != GetMap().end())
  292. return it->second;
  293. }
  294. else
  295. {
  296. AKASSERT(!"Calling [] operator on AkJsonBase which is NOT a map!");
  297. }
  298. static const AkJsonBase empty;
  299. return empty;
  300. }
  301. const AkJsonBase& operator[](const uint32_t in_index) const
  302. {
  303. if (m_eType == Type::Array)
  304. {
  305. AKASSERT(in_index < GetArray().size());
  306. if (in_index < GetArray().size())
  307. return GetArray()[in_index];
  308. }
  309. else
  310. {
  311. AKASSERT(!"Calling [] operator on AkJsonBase which is NOT an array!");
  312. }
  313. static const AkJsonBase empty;
  314. return empty;
  315. }
  316. // Implicit interface compatible with rapidjson. Dependency on rapidjson is not required if those functions are not used.
  317. template<typename RapidJsonValue, typename RapidJsonAllocator, typename RapidJsonSizeType, typename StringToValue>
  318. static bool ToRapidJson(const AkJsonBase& in_node, RapidJsonValue& out_rapidJson, RapidJsonAllocator& in_allocator);
  319. template<typename RapidJsonValue>
  320. static bool FromRapidJson(const RapidJsonValue& in_rapidJson, AkJsonBase& out_node);
  321. private:
  322. Type m_eType = Type::Empty;
  323. union
  324. {
  325. void* m_ptr{nullptr};
  326. Map* m_pMap;
  327. Array* m_pArray;
  328. VariantType* m_pVariant;
  329. };
  330. };
  331. //<rapidjson::Value>
  332. template<typename VariantType, typename StringType, typename StringCompareType>
  333. template<typename RapidJsonValue>
  334. bool AkJsonBase<VariantType, StringType, StringCompareType>::FromRapidJson(const RapidJsonValue& in_rapidJson, AkJsonBase& out_node)
  335. {
  336. if (in_rapidJson.IsObject())
  337. {
  338. out_node.SetType(AkJsonBase::Type::Map);
  339. AkJsonBase::Map& map = out_node.GetMap();
  340. for (auto it = in_rapidJson.MemberBegin(); it != in_rapidJson.MemberEnd(); ++it)
  341. {
  342. StringType rosName(it->name.GetString());
  343. map[rosName] = AkJsonBase();
  344. if (!FromRapidJson(it->value, map[rosName]))
  345. return false;
  346. }
  347. }
  348. else if (in_rapidJson.IsArray())
  349. {
  350. out_node.SetType(AkJsonBase::Type::Array);
  351. AkJsonBase::Array& array = out_node.GetArray();
  352. for (auto it = in_rapidJson.Begin(); it != in_rapidJson.End(); ++it)
  353. {
  354. array.push_back(AkJsonBase());
  355. if (!FromRapidJson(*it, array.back()))
  356. return false;
  357. }
  358. }
  359. else if (in_rapidJson.IsNull())
  360. {
  361. out_node = VariantType();
  362. return true;
  363. }
  364. else
  365. {
  366. out_node.SetType(AkJsonBase::Type::Variant);
  367. out_node.SetVariant(VariantType::template FromRapidJsonValue<decltype(in_rapidJson)>(in_rapidJson));
  368. return (!out_node.GetVariant().IsEmpty());
  369. }
  370. return true;
  371. }
  372. //<rapidjson::Value, rapidjson::MemoryPoolAllocator<>, rapidjson::SizeType>
  373. template<typename VariantType, typename StringType, typename StringCompareType>
  374. template<typename RapidJsonValue, typename RapidJsonAllocator, typename RapidJsonSizeType, typename StringToValue>
  375. bool AkJsonBase<VariantType, StringType, StringCompareType>::ToRapidJson(const AkJsonBase& in_node, RapidJsonValue& out_rapidJson, RapidJsonAllocator& in_allocator)
  376. {
  377. if (in_node.GetType() == AkJsonBase::Type::Map)
  378. {
  379. out_rapidJson.SetObject();
  380. const AkJsonBase::Map& map = in_node.GetMap();
  381. for (auto it = map.begin(); it != map.end(); ++it)
  382. {
  383. RapidJsonValue value;
  384. if (!ToRapidJson<RapidJsonValue, RapidJsonAllocator, RapidJsonSizeType, StringToValue>(it->second, value, in_allocator))
  385. return false;
  386. StringType name(it->first);
  387. RapidJsonValue key = StringToValue::Convert(name, in_allocator);
  388. out_rapidJson.AddMember(key, value, in_allocator);
  389. }
  390. }
  391. else if (in_node.GetType() == AkJsonBase::Type::Array)
  392. {
  393. out_rapidJson.SetArray();
  394. const AkJsonBase::Array& arr = in_node.GetArray();
  395. for (auto it = arr.begin(); it != arr.end(); ++it)
  396. {
  397. RapidJsonValue value;
  398. if (!ToRapidJson<RapidJsonValue, RapidJsonAllocator, RapidJsonSizeType, StringToValue>(*it, value, in_allocator))
  399. return false;
  400. out_rapidJson.PushBack(value, in_allocator);
  401. }
  402. }
  403. else if (in_node.GetType() == AkJsonBase::Type::Empty)
  404. {
  405. out_rapidJson.SetNull();
  406. }
  407. else
  408. {
  409. const VariantType& value = in_node.GetVariant();
  410. return value.template toRapidJsonValue<decltype(out_rapidJson), decltype(in_allocator), RapidJsonSizeType>(out_rapidJson, in_allocator);
  411. }
  412. return true;
  413. }
  414. }
  415. }