Audio plugin host https://kx.studio/carla
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

207 lines
5.8KB

  1. //-----------------------------------------------------------------------------
  2. // Project : SDK Core
  3. //
  4. // Category : SDK Core Interfaces
  5. // Filename : pluginterfaces/base/fvariant.h
  6. // Created by : Steinberg, 01/2004
  7. // Description : Basic Interface
  8. //
  9. //-----------------------------------------------------------------------------
  10. // This file is part of a Steinberg SDK. It is subject to the license terms
  11. // in the LICENSE file found in the top-level directory of this distribution
  12. // and at www.steinberg.net/sdklicenses.
  13. // No part of the SDK, including this file, may be copied, modified, propagated,
  14. // or distributed except according to the terms contained in the LICENSE file.
  15. //-----------------------------------------------------------------------------
  16. #pragma once
  17. #include "pluginterfaces/base/fstrdefs.h"
  18. //------------------------------------------------------------------------
  19. namespace Steinberg {
  20. class FUnknown;
  21. //------------------------------------------------------------------------
  22. // FVariant struct declaration
  23. //------------------------------------------------------------------------
  24. /** A Value of variable type.
  25. \ingroup pluginBase
  26. */
  27. class FVariant
  28. {
  29. //------------------------------------------------------------------------
  30. public:
  31. enum
  32. {
  33. kEmpty = 0,
  34. kInteger = 1 << 0,
  35. kFloat = 1 << 1,
  36. kString8 = 1 << 2,
  37. kObject = 1 << 3,
  38. kOwner = 1 << 4,
  39. kString16 = 1 << 5
  40. };
  41. //------------------------------------------------------------------------
  42. // ctors
  43. inline FVariant () { memset (this, 0, sizeof (FVariant)); }
  44. inline FVariant (const FVariant& variant);
  45. inline FVariant (int64 v) : type (kInteger), intValue (v) {}
  46. inline FVariant (double v) : type (kFloat), floatValue (v) {}
  47. inline FVariant (const char8* str) : type (kString8), string8 (str) {}
  48. inline FVariant (const char16* str) : type (kString16), string16 (str) {}
  49. inline FVariant (FUnknown* obj, bool owner = false) : type (kObject), object (obj)
  50. {
  51. setOwner (owner);
  52. }
  53. inline ~FVariant () { empty (); }
  54. //------------------------------------------------------------------------
  55. inline FVariant& operator= (const FVariant& variant);
  56. inline void setInt (int64 v)
  57. {
  58. empty ();
  59. type = kInteger;
  60. intValue = v;
  61. }
  62. inline void setFloat (double v)
  63. {
  64. empty ();
  65. type = kFloat;
  66. floatValue = v;
  67. }
  68. inline void setString8 (const char8* v)
  69. {
  70. empty ();
  71. type = kString8;
  72. string8 = v;
  73. }
  74. inline void setString16 (const char16* v)
  75. {
  76. empty ();
  77. type = kString16;
  78. string16 = v;
  79. }
  80. inline void setObject (FUnknown* obj)
  81. {
  82. empty ();
  83. type = kObject;
  84. object = obj;
  85. }
  86. inline int64 getInt () const { return (type & kInteger) ? intValue : 0; }
  87. inline double getFloat () const { return (type & kFloat) ? floatValue : 0.; }
  88. inline double getNumber () const
  89. {
  90. return (type & kInteger) ? static_cast<double> (intValue) : (type & kFloat) ? floatValue :
  91. 0.;
  92. }
  93. inline const char8* getString8 () const { return (type & kString8) ? string8 : 0; }
  94. inline const char16* getString16 () const { return (type & kString16) ? string16 : 0; }
  95. inline FUnknown* getObject () const { return (type & kObject) ? object : 0; }
  96. inline uint16 getType () const { return static_cast<uint16> (type & ~(kOwner)); }
  97. inline bool isEmpty () const { return getType () == kEmpty; }
  98. inline bool isOwner () const { return (type & kOwner) != 0; }
  99. inline bool isString () const { return (type & (kString8 | kString16)) != 0; }
  100. inline void setOwner (bool state)
  101. {
  102. if (state)
  103. type |= kOwner;
  104. else
  105. type &= ~kOwner;
  106. }
  107. void empty ();
  108. //------------------------------------------------------------------------
  109. uint16 type;
  110. union
  111. {
  112. int64 intValue;
  113. double floatValue;
  114. const char8* string8;
  115. const char16* string16;
  116. FUnknown* object;
  117. };
  118. };
  119. //------------------------------------------------------------------------
  120. inline bool operator== (const FVariant& v1, const FVariant& v2)
  121. {
  122. #if PLATFORM_64
  123. return v1.type == v2.type && v1.intValue == v2.intValue;
  124. #else
  125. if (v1.type != v2.type)
  126. return false;
  127. if (v1.type & (FVariant::kString8 | FVariant::kString16 | FVariant::kObject))
  128. return v1.string8 == v2.string8; // pointer type comparisons
  129. return v1.intValue == v2.intValue; // intValue & double comparison
  130. #endif
  131. }
  132. //------------------------------------------------------------------------
  133. inline bool operator!= (const FVariant& v1, const FVariant& v2) { return !(v1 == v2); }
  134. //------------------------------------------------------------------------
  135. inline FVariant::FVariant (const FVariant& variant) : type (kEmpty) { *this = variant; }
  136. //------------------------------------------------------------------------
  137. inline void FVariant::empty ()
  138. {
  139. if (type & kOwner)
  140. {
  141. if ((type & kString8) && string8)
  142. delete[] string8;
  143. else if ((type & kString16) && string16)
  144. delete[] string16;
  145. else if ((type & kObject) && object)
  146. object->release ();
  147. }
  148. memset (this, 0, sizeof (FVariant));
  149. }
  150. //------------------------------------------------------------------------
  151. inline FVariant& FVariant::operator= (const FVariant& variant)
  152. {
  153. empty ();
  154. type = variant.type;
  155. if ((type & kString8) && variant.string8)
  156. {
  157. string8 = new char8[strlen (variant.string8) + 1];
  158. strcpy (const_cast<char8*> (string8), variant.string8);
  159. type |= kOwner;
  160. }
  161. else if ((type & kString16) && variant.string16)
  162. {
  163. int32 len = strlen16 (variant.string16);
  164. string16 = new char16[len + 1];
  165. char16* tmp = const_cast<char16*> (string16);
  166. memcpy (tmp, variant.string16, len * sizeof (char16));
  167. tmp[len] = 0;
  168. type |= kOwner;
  169. }
  170. else if ((type & kObject) && variant.object)
  171. {
  172. object = variant.object;
  173. object->addRef ();
  174. type |= kOwner;
  175. }
  176. else
  177. intValue = variant.intValue; // copy memory
  178. return *this;
  179. }
  180. //------------------------------------------------------------------------
  181. } // namespace Steinberg