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.

371 lines
18KB

  1. /*
  2. ==============================================================================
  3. This file is part of the JUCE library.
  4. Copyright (c) 2016 - ROLI Ltd.
  5. Permission is granted to use this software under the terms of the ISC license
  6. http://www.isc.org/downloads/software-support-policy/isc-license/
  7. Permission to use, copy, modify, and/or distribute this software for any
  8. purpose with or without fee is hereby granted, provided that the above
  9. copyright notice and this permission notice appear in all copies.
  10. THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH REGARD
  11. TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND
  12. FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT,
  13. OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF
  14. USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER
  15. TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE
  16. OF THIS SOFTWARE.
  17. -----------------------------------------------------------------------------
  18. To release a closed-source product which uses other parts of JUCE not
  19. licensed under the ISC terms, commercial licenses are available: visit
  20. www.juce.com for more information.
  21. ==============================================================================
  22. */
  23. enum VariantStreamMarkers
  24. {
  25. varMarker_Int = 1,
  26. varMarker_BoolTrue = 2,
  27. varMarker_BoolFalse = 3,
  28. varMarker_Double = 4,
  29. varMarker_String = 5,
  30. varMarker_Int64 = 6,
  31. varMarker_Undefined = 9
  32. };
  33. //==============================================================================
  34. class var::VariantType
  35. {
  36. public:
  37. VariantType() noexcept {}
  38. virtual ~VariantType() noexcept {}
  39. virtual int toInt (const ValueUnion&) const noexcept { return 0; }
  40. virtual int64 toInt64 (const ValueUnion&) const noexcept { return 0; }
  41. virtual double toDouble (const ValueUnion&) const noexcept { return 0; }
  42. virtual String toString (const ValueUnion&) const { return String(); }
  43. virtual bool toBool (const ValueUnion&) const noexcept { return false; }
  44. virtual var clone (const var& original) const { return original; }
  45. virtual bool isVoid() const noexcept { return false; }
  46. virtual bool isUndefined() const noexcept { return false; }
  47. virtual bool isInt() const noexcept { return false; }
  48. virtual bool isInt64() const noexcept { return false; }
  49. virtual bool isBool() const noexcept { return false; }
  50. virtual bool isDouble() const noexcept { return false; }
  51. virtual bool isString() const noexcept { return false; }
  52. virtual void cleanUp (ValueUnion&) const noexcept {}
  53. virtual void createCopy (ValueUnion& dest, const ValueUnion& source) const { dest = source; }
  54. virtual bool equals (const ValueUnion& data, const ValueUnion& otherData, const VariantType& otherType) const noexcept = 0;
  55. virtual void writeToStream (const ValueUnion& data, OutputStream& output) const = 0;
  56. };
  57. //==============================================================================
  58. class var::VariantType_Void : public var::VariantType
  59. {
  60. public:
  61. VariantType_Void() noexcept {}
  62. static const VariantType_Void instance;
  63. bool isVoid() const noexcept override { return true; }
  64. bool equals (const ValueUnion&, const ValueUnion&, const VariantType& otherType) const noexcept override { return otherType.isVoid() || otherType.isUndefined(); }
  65. void writeToStream (const ValueUnion&, OutputStream& output) const override { output.writeCompressedInt (0); }
  66. };
  67. //==============================================================================
  68. class var::VariantType_Undefined : public var::VariantType
  69. {
  70. public:
  71. VariantType_Undefined() noexcept {}
  72. static const VariantType_Undefined instance;
  73. bool isUndefined() const noexcept override { return true; }
  74. String toString (const ValueUnion&) const override { return "undefined"; }
  75. bool equals (const ValueUnion&, const ValueUnion&, const VariantType& otherType) const noexcept override { return otherType.isVoid() || otherType.isUndefined(); }
  76. void writeToStream (const ValueUnion&, OutputStream& output) const override
  77. {
  78. output.writeCompressedInt (1);
  79. output.writeByte (varMarker_Undefined);
  80. }
  81. };
  82. //==============================================================================
  83. class var::VariantType_Int : public var::VariantType
  84. {
  85. public:
  86. VariantType_Int() noexcept {}
  87. static const VariantType_Int instance;
  88. int toInt (const ValueUnion& data) const noexcept override { return data.intValue; };
  89. int64 toInt64 (const ValueUnion& data) const noexcept override { return (int64) data.intValue; };
  90. double toDouble (const ValueUnion& data) const noexcept override { return (double) data.intValue; }
  91. String toString (const ValueUnion& data) const override { return String (data.intValue); }
  92. bool toBool (const ValueUnion& data) const noexcept override { return data.intValue != 0; }
  93. bool isInt() const noexcept override { return true; }
  94. bool equals (const ValueUnion& data, const ValueUnion& otherData, const VariantType& otherType) const noexcept override
  95. {
  96. if (otherType.isDouble() || otherType.isInt64() || otherType.isString())
  97. return otherType.equals (otherData, data, *this);
  98. return otherType.toInt (otherData) == data.intValue;
  99. }
  100. void writeToStream (const ValueUnion& data, OutputStream& output) const override
  101. {
  102. output.writeCompressedInt (5);
  103. output.writeByte (varMarker_Int);
  104. output.writeInt (data.intValue);
  105. }
  106. };
  107. //==============================================================================
  108. class var::VariantType_Int64 : public var::VariantType
  109. {
  110. public:
  111. VariantType_Int64() noexcept {}
  112. static const VariantType_Int64 instance;
  113. int toInt (const ValueUnion& data) const noexcept override { return (int) data.int64Value; };
  114. int64 toInt64 (const ValueUnion& data) const noexcept override { return data.int64Value; };
  115. double toDouble (const ValueUnion& data) const noexcept override { return (double) data.int64Value; }
  116. String toString (const ValueUnion& data) const override { return String (data.int64Value); }
  117. bool toBool (const ValueUnion& data) const noexcept override { return data.int64Value != 0; }
  118. bool isInt64() const noexcept override { return true; }
  119. bool equals (const ValueUnion& data, const ValueUnion& otherData, const VariantType& otherType) const noexcept override
  120. {
  121. if (otherType.isDouble() || otherType.isString())
  122. return otherType.equals (otherData, data, *this);
  123. return otherType.toInt64 (otherData) == data.int64Value;
  124. }
  125. void writeToStream (const ValueUnion& data, OutputStream& output) const override
  126. {
  127. output.writeCompressedInt (9);
  128. output.writeByte (varMarker_Int64);
  129. output.writeInt64 (data.int64Value);
  130. }
  131. };
  132. //==============================================================================
  133. class var::VariantType_Double : public var::VariantType
  134. {
  135. public:
  136. VariantType_Double() noexcept {}
  137. static const VariantType_Double instance;
  138. int toInt (const ValueUnion& data) const noexcept override { return (int) data.doubleValue; };
  139. int64 toInt64 (const ValueUnion& data) const noexcept override { return (int64) data.doubleValue; };
  140. double toDouble (const ValueUnion& data) const noexcept override { return data.doubleValue; }
  141. String toString (const ValueUnion& data) const override { return String (data.doubleValue, 20); }
  142. bool toBool (const ValueUnion& data) const noexcept override { return data.doubleValue != 0; }
  143. bool isDouble() const noexcept override { return true; }
  144. bool equals (const ValueUnion& data, const ValueUnion& otherData, const VariantType& otherType) const noexcept override
  145. {
  146. return std::abs (otherType.toDouble (otherData) - data.doubleValue) < std::numeric_limits<double>::epsilon();
  147. }
  148. void writeToStream (const ValueUnion& data, OutputStream& output) const override
  149. {
  150. output.writeCompressedInt (9);
  151. output.writeByte (varMarker_Double);
  152. output.writeDouble (data.doubleValue);
  153. }
  154. };
  155. //==============================================================================
  156. class var::VariantType_Bool : public var::VariantType
  157. {
  158. public:
  159. VariantType_Bool() noexcept {}
  160. static const VariantType_Bool instance;
  161. int toInt (const ValueUnion& data) const noexcept override { return data.boolValue ? 1 : 0; };
  162. int64 toInt64 (const ValueUnion& data) const noexcept override { return data.boolValue ? 1 : 0; };
  163. double toDouble (const ValueUnion& data) const noexcept override { return data.boolValue ? 1.0 : 0.0; }
  164. String toString (const ValueUnion& data) const override { return String::charToString (data.boolValue ? (juce_wchar) '1' : (juce_wchar) '0'); }
  165. bool toBool (const ValueUnion& data) const noexcept override { return data.boolValue; }
  166. bool isBool() const noexcept override { return true; }
  167. bool equals (const ValueUnion& data, const ValueUnion& otherData, const VariantType& otherType) const noexcept override
  168. {
  169. return otherType.toBool (otherData) == data.boolValue;
  170. }
  171. void writeToStream (const ValueUnion& data, OutputStream& output) const override
  172. {
  173. output.writeCompressedInt (1);
  174. output.writeByte (data.boolValue ? (char) varMarker_BoolTrue : (char) varMarker_BoolFalse);
  175. }
  176. };
  177. //==============================================================================
  178. class var::VariantType_String : public var::VariantType
  179. {
  180. public:
  181. VariantType_String() noexcept {}
  182. static const VariantType_String instance;
  183. void cleanUp (ValueUnion& data) const noexcept override { getString (data)-> ~String(); }
  184. void createCopy (ValueUnion& dest, const ValueUnion& source) const override { new (dest.stringValue) String (*getString (source)); }
  185. bool isString() const noexcept override { return true; }
  186. int toInt (const ValueUnion& data) const noexcept override { return getString (data)->getIntValue(); };
  187. int64 toInt64 (const ValueUnion& data) const noexcept override { return getString (data)->getLargeIntValue(); };
  188. double toDouble (const ValueUnion& data) const noexcept override { return getString (data)->getDoubleValue(); }
  189. String toString (const ValueUnion& data) const override { return *getString (data); }
  190. bool toBool (const ValueUnion& data) const noexcept override { return getString (data)->getIntValue() != 0
  191. || getString (data)->trim().equalsIgnoreCase ("true")
  192. || getString (data)->trim().equalsIgnoreCase ("yes"); }
  193. bool equals (const ValueUnion& data, const ValueUnion& otherData, const VariantType& otherType) const noexcept override
  194. {
  195. return otherType.toString (otherData) == *getString (data);
  196. }
  197. void writeToStream (const ValueUnion& data, OutputStream& output) const override
  198. {
  199. const String* const s = getString (data);
  200. const size_t len = s->getNumBytesAsUTF8() + 1;
  201. HeapBlock<char> temp (len);
  202. s->copyToUTF8 (temp, len);
  203. output.writeCompressedInt ((int) (len + 1));
  204. output.writeByte (varMarker_String);
  205. output.write (temp, len);
  206. }
  207. private:
  208. static inline const String* getString (const ValueUnion& data) noexcept { return reinterpret_cast<const String*> (data.stringValue); }
  209. static inline String* getString (ValueUnion& data) noexcept { return reinterpret_cast<String*> (data.stringValue); }
  210. };
  211. //==============================================================================
  212. const var::VariantType_Void var::VariantType_Void::instance;
  213. const var::VariantType_Undefined var::VariantType_Undefined::instance;
  214. const var::VariantType_Int var::VariantType_Int::instance;
  215. const var::VariantType_Int64 var::VariantType_Int64::instance;
  216. const var::VariantType_Bool var::VariantType_Bool::instance;
  217. const var::VariantType_Double var::VariantType_Double::instance;
  218. const var::VariantType_String var::VariantType_String::instance;
  219. //==============================================================================
  220. var::var() noexcept : type (&VariantType_Void::instance) {}
  221. var::var (const VariantType& t) noexcept : type (&t) {}
  222. var::~var() noexcept { type->cleanUp (value); }
  223. //==============================================================================
  224. var::var (const var& valueToCopy) : type (valueToCopy.type)
  225. {
  226. type->createCopy (value, valueToCopy.value);
  227. }
  228. var::var (const int v) noexcept : type (&VariantType_Int::instance) { value.intValue = v; }
  229. var::var (const int64 v) noexcept : type (&VariantType_Int64::instance) { value.int64Value = v; }
  230. var::var (const bool v) noexcept : type (&VariantType_Bool::instance) { value.boolValue = v; }
  231. var::var (const double v) noexcept : type (&VariantType_Double::instance) { value.doubleValue = v; }
  232. var::var (const String& v) : type (&VariantType_String::instance) { new (value.stringValue) String (v); }
  233. var::var (const char* const v) : type (&VariantType_String::instance) { new (value.stringValue) String (v); }
  234. var var::undefined() noexcept { return var (VariantType_Undefined::instance); }
  235. //==============================================================================
  236. bool var::isVoid() const noexcept { return type->isVoid(); }
  237. bool var::isUndefined() const noexcept { return type->isUndefined(); }
  238. bool var::isInt() const noexcept { return type->isInt(); }
  239. bool var::isInt64() const noexcept { return type->isInt64(); }
  240. bool var::isBool() const noexcept { return type->isBool(); }
  241. bool var::isDouble() const noexcept { return type->isDouble(); }
  242. bool var::isString() const noexcept { return type->isString(); }
  243. var::operator int() const noexcept { return type->toInt (value); }
  244. var::operator int64() const noexcept { return type->toInt64 (value); }
  245. var::operator bool() const noexcept { return type->toBool (value); }
  246. var::operator float() const noexcept { return (float) type->toDouble (value); }
  247. var::operator double() const noexcept { return type->toDouble (value); }
  248. String var::toString() const { return type->toString (value); }
  249. var::operator String() const { return type->toString (value); }
  250. //==============================================================================
  251. void var::swapWith (var& other) noexcept
  252. {
  253. std::swap (type, other.type);
  254. std::swap (value, other.value);
  255. }
  256. var& var::operator= (const var& v) { type->cleanUp (value); type = v.type; type->createCopy (value, v.value); return *this; }
  257. var& var::operator= (const int v) { type->cleanUp (value); type = &VariantType_Int::instance; value.intValue = v; return *this; }
  258. var& var::operator= (const int64 v) { type->cleanUp (value); type = &VariantType_Int64::instance; value.int64Value = v; return *this; }
  259. var& var::operator= (const bool v) { type->cleanUp (value); type = &VariantType_Bool::instance; value.boolValue = v; return *this; }
  260. var& var::operator= (const double v) { type->cleanUp (value); type = &VariantType_Double::instance; value.doubleValue = v; return *this; }
  261. var& var::operator= (const char* const v) { type->cleanUp (value); type = &VariantType_String::instance; new (value.stringValue) String (v); return *this; }
  262. var& var::operator= (const String& v) { type->cleanUp (value); type = &VariantType_String::instance; new (value.stringValue) String (v); return *this; }
  263. #if JUCE_COMPILER_SUPPORTS_MOVE_SEMANTICS
  264. var::var (var&& other) noexcept
  265. : type (other.type),
  266. value (other.value)
  267. {
  268. other.type = &VariantType_Void::instance;
  269. }
  270. var& var::operator= (var&& other) noexcept
  271. {
  272. swapWith (other);
  273. return *this;
  274. }
  275. var::var (String&& v) : type (&VariantType_String::instance)
  276. {
  277. new (value.stringValue) String (static_cast<String&&> (v));
  278. }
  279. var& var::operator= (String&& v)
  280. {
  281. type->cleanUp (value);
  282. type = &VariantType_String::instance;
  283. new (value.stringValue) String (static_cast<String&&> (v));
  284. return *this;
  285. }
  286. #endif
  287. //==============================================================================
  288. bool var::equals (const var& other) const noexcept
  289. {
  290. return type->equals (value, other.value, *other.type);
  291. }
  292. bool var::equalsWithSameType (const var& other) const noexcept
  293. {
  294. return type == other.type && equals (other);
  295. }
  296. bool var::hasSameTypeAs (const var& other) const noexcept
  297. {
  298. return type == other.type;
  299. }
  300. bool operator== (const var& v1, const var& v2) noexcept { return v1.equals (v2); }
  301. bool operator!= (const var& v1, const var& v2) noexcept { return ! v1.equals (v2); }
  302. bool operator== (const var& v1, const String& v2) { return v1.toString() == v2; }
  303. bool operator!= (const var& v1, const String& v2) { return v1.toString() != v2; }
  304. bool operator== (const var& v1, const char* const v2) { return v1.toString() == v2; }
  305. bool operator!= (const var& v1, const char* const v2) { return v1.toString() != v2; }
  306. //==============================================================================
  307. var var::clone() const noexcept
  308. {
  309. return type->clone (*this);
  310. }