AkVariantBase.h 23 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860
  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 <stdint.h>
  22. #include <string>
  23. #if (defined(_HAS_CXX17) && _HAS_CXX17)
  24. #include <string_view>
  25. #endif
  26. #include "AkGuid.h"
  27. #include <AK/SoundEngine/Common/AkTypes.h>
  28. namespace AK
  29. {
  30. namespace WwiseAuthoringAPI
  31. {
  32. enum AkVariantTypeBase
  33. {
  34. AkVariantType_none = 0,
  35. AkVariantType_uint8,
  36. AkVariantType_uint16,
  37. AkVariantType_uint32,
  38. AkVariantType_uint64,
  39. AkVariantType_int8,
  40. AkVariantType_int16,
  41. AkVariantType_int32,
  42. AkVariantType_int64,
  43. AkVariantType_real32,
  44. AkVariantType_real64,
  45. AkVariantType_bool,
  46. AkVariantType_string,
  47. AkVariantType_guid
  48. };
  49. // Do not use AkVariantBase directly, you must inherit from it.
  50. class AkVariantBase
  51. {
  52. private:
  53. static const int k_iExampleGuidLen = 38;
  54. // Constructors and destructor are protected to prevent accidental leak when deleting the class with the wrong type.
  55. // The class is not using a virtual destructor on purpose to avoid having a vtable.
  56. protected:
  57. inline ~AkVariantBase()
  58. {
  59. Clear();
  60. }
  61. inline AkVariantBase()
  62. {
  63. Nullify();
  64. }
  65. inline AkVariantBase(const AkVariantBase& other)
  66. {
  67. Nullify();
  68. CopyFrom(other);
  69. }
  70. inline AkVariantBase(AkVariantBase&& other) noexcept
  71. {
  72. Nullify();
  73. CopyFrom(other);
  74. }
  75. inline AkVariantBase(uint8_t in_val) { m_uint8 = in_val; m_eType = AkVariantType_uint8; }
  76. inline AkVariantBase(uint16_t in_val) { m_uint16 = in_val; m_eType = AkVariantType_uint16; }
  77. inline AkVariantBase(uint32_t in_val) { m_uint32 = in_val; m_eType = AkVariantType_uint32; }
  78. inline AkVariantBase(uint64_t in_val) { m_uint64 = in_val; m_eType = AkVariantType_uint64; }
  79. inline AkVariantBase(int8_t in_val) { m_uint8 = in_val; m_eType = AkVariantType_int8; }
  80. inline AkVariantBase(int16_t in_val) { m_uint16 = in_val; m_eType = AkVariantType_int16; }
  81. inline AkVariantBase(int32_t in_val) { m_uint32 = in_val; m_eType = AkVariantType_int32; }
  82. inline AkVariantBase(int64_t in_val) { m_uint64 = in_val; m_eType = AkVariantType_int64; }
  83. inline AkVariantBase(float in_val) { m_real32 = in_val; m_eType = AkVariantType_real32; }
  84. inline AkVariantBase(double in_val) { m_real64 = in_val; m_eType = AkVariantType_real64; }
  85. inline AkVariantBase(bool in_val) { m_boolean = in_val; m_eType = AkVariantType_bool; }
  86. inline AkVariantBase(const AkGuid& in_val)
  87. {
  88. m_data = new AkGuid();
  89. memcpy(m_data, &in_val, sizeof(AkGuid));
  90. m_eType = AkVariantType_guid;
  91. }
  92. #ifdef GUID_DEFINED
  93. inline AkVariantBase(const GUID& in_val)
  94. {
  95. m_data = new AkGuid();
  96. memcpy(m_data, &in_val, sizeof(AkGuid));
  97. m_eType = AkVariantType_guid;
  98. }
  99. #endif
  100. inline AkVariantBase(const char* in_val)
  101. {
  102. m_data = new std::string(in_val);
  103. m_eType = AkVariantType_string;
  104. }
  105. inline AkVariantBase(const std::string& in_val)
  106. : AkVariantBase(in_val.c_str())
  107. {
  108. }
  109. #if (defined(_HAS_CXX17) && _HAS_CXX17) || defined(AK_APPLE) || defined(AK_LINUX)
  110. inline AkVariantBase(const std::string_view& in_val)
  111. {
  112. m_data = new std::string(in_val);
  113. m_eType = AkVariantType_string;
  114. }
  115. #endif
  116. void Nullify()
  117. {
  118. m_uint64 = 0;
  119. m_eType = AkVariantType_none;
  120. }
  121. public:
  122. // Assignment ----------------------------------------------------------------------------
  123. inline AkVariantBase& operator=(const AkVariantBase& in_val)
  124. {
  125. Clear();
  126. CopyFrom(in_val);
  127. return *this;
  128. }
  129. inline AkVariantBase& operator=(const AkGuid& in_val)
  130. {
  131. Clear();
  132. AkGuid*guid = new AkGuid();
  133. memcpy(guid, &in_val, sizeof(AkGuid));
  134. m_eType = AkVariantType_guid;
  135. return *this;
  136. }
  137. inline AkVariantBase& operator=(const char* in_val)
  138. {
  139. Clear();
  140. m_data = new std::string(in_val);
  141. m_eType = AkVariantType_string;
  142. return *this;
  143. }
  144. inline AkVariantBase& operator=(const std::string& in_val)
  145. {
  146. Clear();
  147. m_data = new std::string(in_val);
  148. m_eType = AkVariantType_string;
  149. return *this;
  150. }
  151. // Helpers ----------------------------------------------------------------------------
  152. inline bool IsString() const
  153. {
  154. return (m_eType == AkVariantType_string);
  155. }
  156. inline bool IsGuid() const
  157. {
  158. return (m_eType == AkVariantType_guid);
  159. }
  160. const std::string& GetString() const
  161. {
  162. if (m_eType == AkVariantType_guid)
  163. {
  164. // Safeguard to prevent a crash in case a guid (and nothing else) is provided as a string to a
  165. // function that does not support guids (which would pass schema validation and crash here).
  166. static const std::string empty;
  167. return empty;
  168. }
  169. AKASSERT(m_eType == AkVariantType_string && "AkVariant: illegal typecast");
  170. return *static_cast<const std::string*>(m_data);
  171. }
  172. inline const AkGuid& GetGuid() const
  173. {
  174. AKASSERT(m_eType == AkVariantType_guid && "AkVariant: illegal typecast");
  175. return *static_cast<const AkGuid*>(m_data);
  176. }
  177. #define _SET_VALUE( _member_, _value_, _type_ ) { \
  178. Clear(); \
  179. (_member_) = (_value_); \
  180. m_eType = _type_; \
  181. return *this; \
  182. }
  183. inline AkVariantBase& operator=(int64_t in_val)
  184. {
  185. _SET_VALUE(m_int64, in_val, AkVariantType_int64)
  186. }
  187. inline AkVariantBase& operator=(int32_t in_val)
  188. {
  189. _SET_VALUE(m_int32, in_val, AkVariantType_int32)
  190. }
  191. inline AkVariantBase& operator=(int16_t in_val)
  192. {
  193. _SET_VALUE(m_int16, in_val, AkVariantType_int16)
  194. }
  195. inline AkVariantBase& operator=(int8_t in_val)
  196. {
  197. _SET_VALUE(m_int8, in_val, AkVariantType_int8)
  198. }
  199. inline AkVariantBase& operator=(uint64_t in_val)
  200. {
  201. _SET_VALUE(m_uint64, in_val, AkVariantType_uint64)
  202. }
  203. inline AkVariantBase& operator=(uint32_t in_val)
  204. {
  205. _SET_VALUE(m_uint32, in_val, AkVariantType_uint32)
  206. }
  207. inline AkVariantBase& operator=(uint16_t in_val)
  208. {
  209. _SET_VALUE(m_uint16, in_val, AkVariantType_uint16)
  210. }
  211. inline AkVariantBase& operator=(uint8_t in_val)
  212. {
  213. _SET_VALUE(m_uint8, in_val, AkVariantType_uint8)
  214. }
  215. inline AkVariantBase& operator=(double in_val)
  216. {
  217. _SET_VALUE(m_real64, in_val, AkVariantType_real64)
  218. }
  219. inline AkVariantBase& operator=(float in_val)
  220. {
  221. _SET_VALUE(m_real32, in_val, AkVariantType_real32)
  222. }
  223. inline AkVariantBase& operator=(bool in_val)
  224. {
  225. _SET_VALUE(m_boolean, in_val, AkVariantType_bool)
  226. }
  227. inline bool operator==(const AkVariantBase& rhs) const
  228. {
  229. if (m_eType != rhs.m_eType)
  230. return false;
  231. switch (m_eType)
  232. {
  233. case AkVariantType_uint8: return m_uint8 == rhs.m_uint8;
  234. case AkVariantType_uint16: return m_uint16 == rhs.m_uint16;
  235. case AkVariantType_uint32: return m_uint32 == rhs.m_uint32;
  236. case AkVariantType_uint64: return m_uint64 == rhs.m_uint64;
  237. case AkVariantType_int8: return m_int8 == rhs.m_int8;
  238. case AkVariantType_int16: return m_int16 == rhs.m_int16;
  239. case AkVariantType_int32: return m_int32 == rhs.m_int32;
  240. case AkVariantType_int64: return m_int64 == rhs.m_int64;
  241. case AkVariantType_real32: return m_real32 == rhs.m_real32;
  242. case AkVariantType_real64: return m_real64 == rhs.m_real64;
  243. case AkVariantType_bool: return m_boolean == rhs.m_boolean;
  244. case AkVariantType_string: return GetString().compare(rhs.GetString()) == 0;
  245. case AkVariantType_guid: return GetGuid() == rhs.GetGuid();
  246. case AkVariantType_none: return true; // Both variants are empty
  247. default: return false; // Unknown type
  248. }
  249. return false;
  250. }
  251. inline bool operator!=(const AkVariantBase& rhs) const
  252. {
  253. return !(*this == rhs);
  254. }
  255. // Typecast ----------------------------------------------------------------------------
  256. inline operator bool() const
  257. {
  258. switch (m_eType)
  259. {
  260. case AkVariantType_bool: return m_boolean;
  261. default: break;
  262. }
  263. AKASSERT(false && "AkVariantBase: illegal typecast");
  264. return 0;
  265. }
  266. inline operator int64_t() const
  267. {
  268. switch (m_eType)
  269. {
  270. case AkVariantType_int8: return static_cast<int64_t>(m_int8);
  271. case AkVariantType_int16: return static_cast<int64_t>(m_int16);
  272. case AkVariantType_int32: return static_cast<int64_t>(m_int32);
  273. case AkVariantType_int64: return m_int64;
  274. default: break;
  275. }
  276. AKASSERT(false && "AkVariantBase: illegal typecast");
  277. return 0;
  278. }
  279. #ifdef AK_LINUX
  280. inline operator long long() const
  281. {
  282. // Prevents conversion ambiguity when using an AkVariant parameter with GMock on Linux
  283. return static_cast<int64_t>(*this);
  284. }
  285. #endif
  286. template<typename T> T ToEnum() const
  287. {
  288. return static_cast<T>(static_cast<int32_t>(*this));
  289. }
  290. inline operator int32_t() const
  291. {
  292. switch (m_eType)
  293. {
  294. case AkVariantType_int8: return static_cast<int32_t>(m_int8);
  295. case AkVariantType_int16: return static_cast<int32_t>(m_int16);
  296. case AkVariantType_int32: return m_int32;
  297. case AkVariantType_uint8: return static_cast<int32_t>(m_uint8);
  298. case AkVariantType_uint16: return static_cast<int32_t>(m_uint16);
  299. default: break;
  300. }
  301. AKASSERT(false && "AkVariantBase: illegal typecast");
  302. return 0;
  303. }
  304. inline operator uint32_t() const
  305. {
  306. switch (m_eType)
  307. {
  308. case AkVariantType_int8: return static_cast<uint32_t>(m_int8);
  309. case AkVariantType_int16: return static_cast<uint32_t>(m_int16);
  310. case AkVariantType_int32: return static_cast<uint32_t>(m_int32);
  311. case AkVariantType_uint8: return static_cast<uint32_t>(m_uint8);
  312. case AkVariantType_uint16: return static_cast<uint32_t>(m_uint16);
  313. case AkVariantType_uint32: return m_uint32;
  314. default: break;
  315. }
  316. AKASSERT(false && "AkVariantBase: illegal typecast");
  317. return 0;
  318. }
  319. inline operator uint64_t() const
  320. {
  321. switch (m_eType)
  322. {
  323. case AkVariantType_int8: return static_cast<uint64_t>(m_int8);
  324. case AkVariantType_int16: return static_cast<uint64_t>(m_int16);
  325. case AkVariantType_int32: return static_cast<uint64_t>(m_int32);
  326. case AkVariantType_int64: return static_cast<uint64_t>(m_int64);
  327. case AkVariantType_uint8: return static_cast<uint64_t>(m_uint8);
  328. case AkVariantType_uint16: return static_cast<uint64_t>(m_uint16);
  329. case AkVariantType_uint32: return static_cast<uint64_t>(m_uint32);
  330. case AkVariantType_uint64: return m_uint64;
  331. default: break;
  332. }
  333. AKASSERT(false && "AkVariantBase: illegal typecast");
  334. return 0;
  335. }
  336. inline operator double() const
  337. {
  338. switch (m_eType)
  339. {
  340. case AkVariantType_int8: return static_cast<double>(m_int8);
  341. case AkVariantType_int16: return static_cast<double>(m_int16);
  342. case AkVariantType_int32: return static_cast<double>(m_int32);
  343. case AkVariantType_int64: return static_cast<double>(m_int64);
  344. case AkVariantType_uint8: return static_cast<double>(m_uint8);
  345. case AkVariantType_uint16: return static_cast<double>(m_uint16);
  346. case AkVariantType_uint32: return static_cast<double>(m_uint32);
  347. case AkVariantType_uint64: return static_cast<double>(m_uint64);
  348. case AkVariantType_real32: return static_cast<double>(m_real32);
  349. case AkVariantType_real64: return m_real64;
  350. default: break;
  351. }
  352. AKASSERT(false && "AkVariantBase: illegal typecast");
  353. return 0;
  354. }
  355. inline operator AkGuid() const
  356. {
  357. if (m_eType == AkVariantType_guid)
  358. return *static_cast<const AkGuid*>(m_data);
  359. AKASSERT(false && "AkVariantBase: illegal typecast");
  360. return AkGuid();
  361. }
  362. inline operator std::string() const
  363. {
  364. if (m_eType == AkVariantType_string)
  365. return *static_cast<const std::string*>(m_data);
  366. AKASSERT(false && "AkVariantBase: illegal typecast");
  367. return std::string();
  368. }
  369. // Helpers ----------------------------------------------------------------------------
  370. inline bool IsNumber() const
  371. {
  372. return (m_eType >= AkVariantType_int8 && m_eType <= AkVariantType_int64)
  373. || (m_eType >= AkVariantType_uint8 && m_eType <= AkVariantType_uint64)
  374. || (m_eType >= AkVariantType_real32 && m_eType <= AkVariantType_real64);
  375. }
  376. inline bool IsEmpty() const
  377. {
  378. return (m_eType == AkVariantType_none);
  379. }
  380. inline bool IsBool() const
  381. {
  382. return (m_eType == AkVariantType_bool);
  383. }
  384. private:
  385. static inline uint8_t CharToUInt(char c)
  386. {
  387. if (c >= '0' && c <= '9')
  388. return (uint8_t)(c - '0');
  389. else if (c >= 'a' && c <= 'f')
  390. return (uint8_t)(c - 'a') + 10;
  391. else if (c >= 'A' && c <= 'F')
  392. return (uint8_t)(c - 'A') + 10;
  393. else
  394. return (uint8_t)-1;
  395. }
  396. static inline char UIntToChar(uint8_t by)
  397. {
  398. if (by < 0xa)
  399. return '0' + by;
  400. else
  401. return 'A' + (by - 10);
  402. }
  403. public:
  404. static bool StrToAkGuid(const std::string& in_str, AkGuid& out_guid)
  405. {
  406. const char* psz = in_str.c_str();
  407. const size_t len = strlen(psz);
  408. // GUID must have format: 01234567-ABCD-0123-abcd-01234567ABCD, with MANDATORY brackets around
  409. if (len != k_iExampleGuidLen)
  410. return false;
  411. const bool brackets = psz[0] == '{' && psz[len - 1] == '}';
  412. if (!brackets)
  413. return false;
  414. psz += 1;
  415. // Note: we must convert the string into this struct
  416. // uint32_t data1;
  417. // uint16_t data2;
  418. // uint16_t data3;
  419. // uint8_t data4[8];
  420. // We only support little endian for now!
  421. uint8_t* pby = (uint8_t*)&out_guid;
  422. // Convert into uint32
  423. for (int i = 0; i < 4; i++) // 01234567
  424. {
  425. uint8_t u1 = CharToUInt(*psz++);
  426. uint8_t u2 = CharToUInt(*psz++);
  427. if (u1 == (uint8_t)-1 || u2 == (uint8_t)-1)
  428. return false;
  429. pby[3 - i] = (u1 << 4) | u2; // store backward as little endian
  430. }
  431. if (*psz != '-')
  432. return false;
  433. ++psz; // -
  434. pby += 4;
  435. // Convert into uint16
  436. for (int i = 0; i < 2; i++) // ABCD
  437. {
  438. uint8_t u1 = CharToUInt(*psz++);
  439. uint8_t u2 = CharToUInt(*psz++);
  440. if (u1 == (uint8_t)-1 || u2 == (uint8_t)-1)
  441. return false;
  442. pby[1 - i] = (u1 << 4) | u2;
  443. }
  444. if (*psz != '-')
  445. return false;
  446. ++psz; // -
  447. pby += 2;
  448. // Convert into uint16
  449. for (int i = 0; i < 2; i++) // 0123
  450. {
  451. uint8_t u1 = CharToUInt(*psz++);
  452. uint8_t u2 = CharToUInt(*psz++);
  453. if (u1 == (uint8_t)-1 || u2 == (uint8_t)-1)
  454. return false;
  455. pby[1 - i] = (u1 << 4) | u2;
  456. }
  457. if (*psz != '-')
  458. return false;
  459. ++psz; // -
  460. pby += 2;
  461. // Convert into uint8[2]
  462. for (int i = 0; i < 2; i++) // abcd
  463. {
  464. uint8_t u1 = CharToUInt(*psz++);
  465. uint8_t u2 = CharToUInt(*psz++);
  466. if (u1 == (uint8_t)-1 || u2 == (uint8_t)-1)
  467. return false;
  468. *pby++ = (u1 << 4) | u2;
  469. }
  470. if (*psz != '-')
  471. return false;
  472. ++psz; // -
  473. // Convert into uint8[6]
  474. for (int i = 0; i < 6; i++) // 01234567ABCD
  475. {
  476. uint8_t u1 = CharToUInt(*psz++);
  477. uint8_t u2 = CharToUInt(*psz++);
  478. if (u1 == (uint8_t)-1 || u2 == (uint8_t)-1)
  479. return false;
  480. *pby++ = (u1 << 4) | u2;
  481. }
  482. return true;
  483. }
  484. static void AkGuidToStr(const AkGuid& in_guid, std::string& out_str)
  485. {
  486. uint8_t* pby = (uint8_t*)&in_guid;
  487. if (out_str.size() < (k_iExampleGuidLen))
  488. out_str.resize(k_iExampleGuidLen);
  489. char* psz = (char*)&out_str[0];
  490. *psz++ = '{';
  491. // Note: we must convert the string into this struct
  492. // uint32_t data1;
  493. // uint16_t data2;
  494. // uint16_t data3;
  495. // uint8_t data4[8];
  496. // We only support little endian for now!
  497. // Convert uint32
  498. for (int i = 0; i < 4; ++i)
  499. {
  500. *psz++ = UIntToChar(pby[3 - i] >> 4);
  501. *psz++ = UIntToChar(pby[3 - i] & 0xf);
  502. }
  503. pby += 4;
  504. *psz++ = '-';
  505. // Convert uint16
  506. for (int i = 0; i < 2; ++i)
  507. {
  508. *psz++ = UIntToChar(pby[1 - i] >> 4);
  509. *psz++ = UIntToChar(pby[1 - i] & 0xf);
  510. }
  511. pby += 2;
  512. *psz++ = '-';
  513. // Convert uint16
  514. for (int i = 0; i < 2; ++i)
  515. {
  516. *psz++ = UIntToChar(pby[1 - i] >> 4);
  517. *psz++ = UIntToChar(pby[1 - i] & 0xf);
  518. }
  519. pby += 2;
  520. *psz++ = '-';
  521. // Convert uint8[2]
  522. for (int i = 0; i < 2; ++i)
  523. {
  524. *psz++ = UIntToChar(pby[i] >> 4);
  525. *psz++ = UIntToChar(pby[i] & 0xf);
  526. }
  527. pby += 2;
  528. *psz++ = '-';
  529. // Convert uint8[6]
  530. for (int i = 0; i < 6; ++i)
  531. {
  532. *psz++ = UIntToChar(pby[i] >> 4);
  533. *psz++ = UIntToChar(pby[i] & 0xf);
  534. }
  535. *psz++ = '}';
  536. }
  537. private:
  538. void Clear()
  539. {
  540. switch (m_eType)
  541. {
  542. case AkVariantType_string:
  543. delete static_cast<std::string*>(m_data);
  544. break;
  545. case AkVariantType_guid:
  546. delete static_cast<AkGuid*>(m_data);
  547. break;
  548. }
  549. }
  550. void CopyFrom(const AkVariantBase& in_var)
  551. {
  552. m_eType = in_var.m_eType;
  553. switch (in_var.m_eType)
  554. {
  555. case AkVariantType_uint8:
  556. m_uint8 = in_var.m_uint8;
  557. break;
  558. case AkVariantType_uint16:
  559. m_uint16 = in_var.m_uint16;
  560. break;
  561. case AkVariantType_uint32:
  562. m_uint32 = in_var.m_uint32;
  563. break;
  564. case AkVariantType_uint64:
  565. m_uint64 = in_var.m_uint64;
  566. break;
  567. case AkVariantType_int8:
  568. m_int8 = in_var.m_int8;
  569. break;
  570. case AkVariantType_int16:
  571. m_int16 = in_var.m_int16;
  572. break;
  573. case AkVariantType_int32:
  574. m_int32 = in_var.m_int32;
  575. break;
  576. case AkVariantType_int64:
  577. m_int64 = in_var.m_int64;
  578. break;
  579. case AkVariantType_real32:
  580. m_real32 = in_var.m_real32;
  581. break;
  582. case AkVariantType_real64:
  583. m_real64 = in_var.m_real64;
  584. break;
  585. case AkVariantType_bool:
  586. m_boolean = in_var.m_boolean;
  587. break;
  588. case AkVariantType_string:
  589. m_data = new std::string(*static_cast<const std::string*>(in_var.m_data));
  590. break;
  591. case AkVariantType_guid:
  592. m_data = new AkGuid();
  593. memcpy(m_data, in_var.m_data, sizeof(AkGuid));
  594. break;
  595. default:
  596. break;
  597. }
  598. }
  599. public:
  600. int GetType() const
  601. {
  602. return m_eType;
  603. }
  604. bool GetBoolean() const
  605. {
  606. AKASSERT(m_eType == AkVariantType_bool && "AkVariant: illegal typecast");
  607. return m_boolean;
  608. }
  609. int8_t GetInt8() const
  610. {
  611. AKASSERT(m_eType == AkVariantType_int8 && "AkVariant: illegal typecast");
  612. return m_int8;
  613. }
  614. int16_t GetInt16() const
  615. {
  616. AKASSERT(m_eType == AkVariantType_int16 && "AkVariant: illegal typecast");
  617. return m_int16;
  618. }
  619. int32_t GetInt32() const
  620. {
  621. AKASSERT(m_eType == AkVariantType_int32 && "AkVariant: illegal typecast");
  622. return m_int32;
  623. }
  624. int64_t GetInt64() const
  625. {
  626. AKASSERT(m_eType == AkVariantType_int64 && "AkVariant: illegal typecast");
  627. return m_int64;
  628. }
  629. uint8_t GetUInt8() const
  630. {
  631. AKASSERT(m_eType == AkVariantType_uint8 && "AkVariant: illegal typecast");
  632. return m_uint8;
  633. }
  634. uint16_t GetUInt16() const
  635. {
  636. AKASSERT(m_eType == AkVariantType_uint16 && "AkVariant: illegal typecast");
  637. return m_uint16;
  638. }
  639. uint32_t GetUInt32() const
  640. {
  641. AKASSERT(m_eType == AkVariantType_uint32 && "AkVariant: illegal typecast");
  642. return m_uint32;
  643. }
  644. uint64_t GetUInt64() const
  645. {
  646. AKASSERT(m_eType == AkVariantType_uint64 && "AkVariant: illegal typecast");
  647. return m_uint64;
  648. }
  649. float GetReal32() const
  650. {
  651. AKASSERT(m_eType == AkVariantType_real32 && "AkVariant: illegal typecast");
  652. return m_real32;
  653. }
  654. double GetReal64() const
  655. {
  656. AKASSERT(m_eType == AkVariantType_real64 && "AkVariant: illegal typecast");
  657. return m_real64;
  658. }
  659. // Implicit interface supporting conversion to rapidjson. Does not require rapidjson dependencies
  660. // if the function is not called.
  661. template<typename RapidJsonValueType, typename RapidJsonAllocator, typename RapidJsonSizeType>
  662. bool toRapidJsonValue(RapidJsonValueType& out_rapidJson, RapidJsonAllocator& in_allocator) const
  663. {
  664. switch (m_eType)
  665. {
  666. case AkVariantType_none: out_rapidJson.SetNull(); break;
  667. case AkVariantType_bool: out_rapidJson.SetBool(m_boolean); break;
  668. case AkVariantType_int8: out_rapidJson.SetInt(m_int8); break;
  669. case AkVariantType_int16: out_rapidJson.SetInt(m_int16); break;
  670. case AkVariantType_int32: out_rapidJson.SetInt(m_int32); break;
  671. case AkVariantType_int64: out_rapidJson.SetInt64(m_int64); break;
  672. case AkVariantType_uint8: out_rapidJson.SetUint(m_uint8); break;
  673. case AkVariantType_uint16: out_rapidJson.SetUint(m_uint16); break;
  674. case AkVariantType_uint32: out_rapidJson.SetUint(m_uint32); break;
  675. case AkVariantType_uint64: out_rapidJson.SetUint64(m_uint64); break;
  676. case AkVariantType_real32: out_rapidJson.SetDouble(m_real32); break;
  677. case AkVariantType_real64: out_rapidJson.SetDouble(m_real64); break;
  678. case AkVariantType_guid:
  679. {
  680. std::string str;
  681. AkVariantBase::AkGuidToStr(*static_cast<const AkGuid*>(m_data), str);
  682. out_rapidJson.SetString(str.c_str(), static_cast<RapidJsonSizeType>(str.length()), in_allocator);
  683. }
  684. break;
  685. default:
  686. return false;
  687. }
  688. return true;
  689. }
  690. protected:
  691. int m_eType;
  692. union
  693. {
  694. uint8_t m_uint8;
  695. uint16_t m_uint16;
  696. uint32_t m_uint32;
  697. uint64_t m_uint64;
  698. int8_t m_int8;
  699. int16_t m_int16;
  700. int32_t m_int32;
  701. int64_t m_int64;
  702. float m_real32;
  703. double m_real64;
  704. bool m_boolean;
  705. void* m_data;
  706. };
  707. };
  708. }
  709. }