26enum VariantStreamMarkers
29 varMarker_BoolTrue = 2,
30 varMarker_BoolFalse = 3,
36 varMarker_Undefined = 9
46 virtual int toInt (
const ValueUnion&)
const noexcept {
return 0; }
47 virtual int64 toInt64 (
const ValueUnion&)
const noexcept {
return 0; }
48 virtual double toDouble (
const ValueUnion&)
const noexcept {
return 0; }
49 virtual String toString (
const ValueUnion&)
const {
return {}; }
50 virtual bool toBool (
const ValueUnion&)
const noexcept {
return false; }
52 virtual Array<var>* toArray (
const ValueUnion&)
const noexcept {
return nullptr; }
53 virtual MemoryBlock* toBinary (
const ValueUnion&)
const noexcept {
return nullptr; }
56 virtual bool isVoid()
const noexcept {
return false; }
57 virtual bool isUndefined()
const noexcept {
return false; }
58 virtual bool isInt()
const noexcept {
return false; }
59 virtual bool isInt64()
const noexcept {
return false; }
60 virtual bool isBool()
const noexcept {
return false; }
61 virtual bool isDouble()
const noexcept {
return false; }
62 virtual bool isString()
const noexcept {
return false; }
63 virtual bool isObject()
const noexcept {
return false; }
64 virtual bool isArray()
const noexcept {
return false; }
65 virtual bool isBinary()
const noexcept {
return false; }
66 virtual bool isMethod()
const noexcept {
return false; }
67 virtual bool isComparable()
const noexcept {
return false; }
69 virtual void cleanUp (ValueUnion&)
const noexcept {}
70 virtual void createCopy (ValueUnion& dest,
const ValueUnion& source)
const { dest = source; }
72 virtual void writeToStream (
const ValueUnion& data,
OutputStream& output)
const = 0;
82 bool isVoid()
const noexcept override {
return true; }
83 bool isComparable()
const noexcept override {
return true; }
95 bool isUndefined()
const noexcept override {
return true; }
96 String toString (
const ValueUnion&)
const override {
return "undefined"; }
99 void writeToStream (
const ValueUnion&,
OutputStream& output)
const override
113 int toInt (
const ValueUnion& data)
const noexcept override {
return data.intValue; }
114 int64 toInt64 (
const ValueUnion& data)
const noexcept override {
return (
int64) data.intValue; }
115 double toDouble (
const ValueUnion& data)
const noexcept override {
return (
double) data.intValue; }
116 String toString (
const ValueUnion& data)
const override {
return String (data.intValue); }
117 bool toBool (
const ValueUnion& data)
const noexcept override {
return data.intValue != 0; }
118 bool isInt()
const noexcept override {
return true; }
119 bool isComparable()
const noexcept override {
return true; }
129 void writeToStream (
const ValueUnion& data,
OutputStream& output)
const override
144 int toInt (
const ValueUnion& data)
const noexcept override {
return (
int) data.int64Value; }
145 int64 toInt64 (
const ValueUnion& data)
const noexcept override {
return data.int64Value; }
146 double toDouble (
const ValueUnion& data)
const noexcept override {
return (
double) data.int64Value; }
147 String toString (
const ValueUnion& data)
const override {
return String (data.int64Value); }
148 bool toBool (
const ValueUnion& data)
const noexcept override {
return data.int64Value != 0; }
149 bool isInt64()
const noexcept override {
return true; }
150 bool isComparable()
const noexcept override {
return true; }
160 void writeToStream (
const ValueUnion& data,
OutputStream& output)
const override
175 int toInt (
const ValueUnion& data)
const noexcept override {
return (
int) data.doubleValue; }
176 int64 toInt64 (
const ValueUnion& data)
const noexcept override {
return (
int64) data.doubleValue; }
177 double toDouble (
const ValueUnion& data)
const noexcept override {
return data.doubleValue; }
178 String toString (
const ValueUnion& data)
const override {
return serialiseDouble (data.doubleValue); }
179 bool toBool (
const ValueUnion& data)
const noexcept override {
return data.doubleValue != 0.0; }
180 bool isDouble()
const noexcept override {
return true; }
181 bool isComparable()
const noexcept override {
return true; }
185 return std::abs (
otherType.toDouble (
otherData) - data.doubleValue) < std::numeric_limits<double>::epsilon();
188 void writeToStream (
const ValueUnion& data,
OutputStream& output)
const override
203 int toInt (
const ValueUnion& data)
const noexcept override {
return data.boolValue ? 1 : 0; }
204 int64 toInt64 (
const ValueUnion& data)
const noexcept override {
return data.boolValue ? 1 : 0; }
205 double toDouble (
const ValueUnion& data)
const noexcept override {
return data.boolValue ? 1.0 : 0.0; }
207 bool toBool (
const ValueUnion& data)
const noexcept override {
return data.boolValue; }
208 bool isBool()
const noexcept override {
return true; }
209 bool isComparable()
const noexcept override {
return true; }
216 void writeToStream (
const ValueUnion& data,
OutputStream& output)
const override
219 output.
writeByte (data.boolValue ? (
char) varMarker_BoolTrue : (
char) varMarker_BoolFalse);
230 void cleanUp (ValueUnion& data)
const noexcept override { getString (data)->
~String(); }
231 void createCopy (ValueUnion& dest,
const ValueUnion& source)
const override {
new (dest.stringValue)
String (*getString (source)); }
233 bool isString()
const noexcept override {
return true; }
234 int toInt (
const ValueUnion& data)
const noexcept override {
return getString (data)->getIntValue(); }
235 int64 toInt64 (
const ValueUnion& data)
const noexcept override {
return getString (data)->getLargeIntValue(); }
236 double toDouble (
const ValueUnion& data)
const noexcept override {
return getString (data)->getDoubleValue(); }
237 String toString (
const ValueUnion& data)
const override {
return *getString (data); }
238 bool toBool (
const ValueUnion& data)
const noexcept override {
return getString (data)->getIntValue() != 0
239 || getString (data)->trim().equalsIgnoreCase (
"true")
240 || getString (data)->trim().equalsIgnoreCase (
"yes"); }
241 bool isComparable()
const noexcept override {
return true; }
248 void writeToStream (
const ValueUnion& data,
OutputStream& output)
const override
250 auto*
s = getString (data);
251 const size_t len =
s->getNumBytesAsUTF8() + 1;
260 static inline const String* getString (
const ValueUnion& data)
noexcept {
return reinterpret_cast<const String*
> (data.stringValue); }
261 static inline String* getString (ValueUnion& data)
noexcept {
return reinterpret_cast<String*
> (data.stringValue); }
271 void cleanUp (ValueUnion& data)
const noexcept override {
if (data.objectValue !=
nullptr) data.objectValue->decReferenceCount(); }
273 void createCopy (ValueUnion& dest,
const ValueUnion& source)
const override
275 dest.objectValue = source.objectValue;
276 if (dest.objectValue !=
nullptr)
277 dest.objectValue->incReferenceCount();
281 bool toBool (
const ValueUnion& data)
const noexcept override {
return data.objectValue !=
nullptr; }
282 ReferenceCountedObject* toObject (
const ValueUnion& data)
const noexcept override {
return data.objectValue; }
283 bool isObject()
const noexcept override {
return true; }
292 if (
auto* d =
original.getDynamicObject())
293 return d->
clone().get();
299 void writeToStream (
const ValueUnion&,
OutputStream& output)
const override
313 String toString (
const ValueUnion&)
const override {
return "[Array]"; }
315 bool isArray()
const noexcept override {
return true; }
317 Array<var>* toArray (
const ValueUnion& data)
const noexcept override
336 if (
auto* array = toArray (
original.value))
340 for (
auto& i : *array)
347 void writeToStream (
const ValueUnion& data,
OutputStream& output)
const override
349 if (
auto* array = toArray (data))
354 for (
auto& i : *array)
355 i.writeToStream (buffer);
379 void cleanUp (ValueUnion& data)
const noexcept override {
delete data.binaryValue; }
380 void createCopy (ValueUnion& dest,
const ValueUnion& source)
const override { dest.binaryValue =
new MemoryBlock (*source.binaryValue); }
382 String toString (
const ValueUnion& data)
const override {
return data.binaryValue->toBase64Encoding(); }
383 bool isBinary()
const noexcept override {
return true; }
384 MemoryBlock* toBinary (
const ValueUnion& data)
const noexcept override {
return data.binaryValue; }
392 void writeToStream (
const ValueUnion& data,
OutputStream& output)
const override
396 output << *data.binaryValue;
407 void cleanUp (ValueUnion& data)
const noexcept override {
if (data.methodValue !=
nullptr )
delete data.methodValue; }
408 void createCopy (ValueUnion& dest,
const ValueUnion& source)
const override { dest.methodValue =
new NativeFunction (*source.methodValue); }
410 String toString (
const ValueUnion&)
const override {
return "Method"; }
411 bool toBool (
const ValueUnion& data)
const noexcept override {
return data.methodValue !=
nullptr; }
412 bool isMethod()
const noexcept override {
return true; }
419 void writeToStream (
const ValueUnion&,
OutputStream& output)
const override
445JUCE_DECLARE_DEPRECATED_STATIC (
const var var::null;)
453var::var (
const int v) noexcept : type (&VariantType_Int::instance) { value.intValue = v; }
454var::var (
const int64 v) noexcept : type (&VariantType_Int64::instance) { value.int64Value = v; }
455var::var (
const bool v) noexcept : type (&VariantType_Bool::instance) { value.boolValue = v; }
456var::var (
const double v) noexcept : type (&VariantType_Double::instance) { value.doubleValue = v; }
457var::var (NativeFunction m) noexcept : type (&VariantType_Method::instance) { value.methodValue =
new NativeFunction (m); }
458var::var (
const Array<var>& v) : type (&VariantType_Array::instance) { value.objectValue =
new VariantType_Array::RefCountedArray(v); }
459var::var (
const String& v) : type (&VariantType_String::instance) {
new (value.stringValue) String (v); }
460var::var (
const char*
const v) : type (&VariantType_String::instance) {
new (value.stringValue) String (v); }
461var::var (
const wchar_t*
const v) : type (&VariantType_String::instance) {
new (value.stringValue) String (v); }
462var::var (
const void* v,
size_t sz) : type (&VariantType_Binary::instance) { value.binaryValue =
new MemoryBlock (v, sz); }
463var::var (
const MemoryBlock& v) : type (&VariantType_Binary::instance) { value.binaryValue =
new MemoryBlock (v); }
465var::var (
const StringArray& v) : type (&VariantType_Array::instance)
468 strings.ensureStorageAllocated (v.size());
471 strings.add (
var (i));
473 value.objectValue =
new VariantType_Array::RefCountedArray (strings);
476var::var (ReferenceCountedObject*
const object) : type (&VariantType_Object::instance)
478 value.objectValue = object;
480 if (
object !=
nullptr)
481 object->incReferenceCount();
488bool var::isUndefined() const noexcept {
return type->isUndefined(); }
489bool var::isInt() const noexcept {
return type->isInt(); }
490bool var::isInt64() const noexcept {
return type->isInt64(); }
491bool var::isBool() const noexcept {
return type->isBool(); }
492bool var::isDouble() const noexcept {
return type->isDouble(); }
493bool var::isString() const noexcept {
return type->isString(); }
494bool var::isObject() const noexcept {
return type->isObject(); }
495bool var::isArray() const noexcept {
return type->isArray(); }
496bool var::isBinaryData() const noexcept {
return type->isBinary(); }
497bool var::isMethod() const noexcept {
return type->isMethod(); }
499var::operator int() const noexcept {
return type->toInt (value); }
500var::operator int64() const noexcept {
return type->toInt64 (value); }
501var::operator bool() const noexcept {
return type->toBool (value); }
502var::operator float() const noexcept {
return (
float) type->toDouble (value); }
503var::operator double() const noexcept {
return type->toDouble (value); }
504String var::toString()
const {
return type->toString (value); }
505var::operator String()
const {
return type->toString (value); }
506ReferenceCountedObject* var::getObject() const noexcept {
return type->toObject (value); }
512void var::swapWith (var& other)
noexcept
514 std::swap (type, other.type);
515 std::swap (value, other.value);
518var& var::operator= (
const var& v) { type->cleanUp (value); type = v.type; type->createCopy (value, v.value);
return *
this; }
519var& var::operator= (
const int v) { type->cleanUp (value); type = &VariantType_Int::instance; value.intValue = v;
return *
this; }
520var& var::operator= (
const int64 v) { type->cleanUp (value); type = &VariantType_Int64::instance; value.int64Value = v;
return *
this; }
521var& var::operator= (
const bool v) { type->cleanUp (value); type = &VariantType_Bool::instance; value.boolValue = v;
return *
this; }
522var& var::operator= (
const double v) { type->cleanUp (value); type = &VariantType_Double::instance; value.doubleValue = v;
return *
this; }
523var& var::operator= (
const char*
const v) { type->cleanUp (value); type = &VariantType_String::instance;
new (value.stringValue) String (v);
return *
this; }
524var& var::operator= (
const wchar_t*
const v) { type->cleanUp (value); type = &VariantType_String::instance;
new (value.stringValue) String (v);
return *
this; }
525var& var::operator= (
const String& v) { type->cleanUp (value); type = &VariantType_String::instance;
new (value.stringValue) String (v);
return *
this; }
526var& var::operator= (
const MemoryBlock& v) { type->cleanUp (value); type = &VariantType_Binary::instance; value.binaryValue =
new MemoryBlock (v);
return *
this; }
527var& var::operator= (
const Array<var>& v) {
var v2 (v); swapWith (v2);
return *
this; }
528var& var::operator= (ReferenceCountedObject* v) {
var v2 (v); swapWith (v2);
return *
this; }
529var& var::operator= (NativeFunction v) {
var v2 (v); swapWith (v2);
return *
this; }
535 other.type = &VariantType_Void::instance;
538var& var::operator= (var&& other)
noexcept
544var::var (String&& v) : type (&VariantType_String::instance)
546 new (value.stringValue) String (std::move (v));
549var::var (MemoryBlock&& v) : type (&VariantType_Binary::instance)
551 value.binaryValue =
new MemoryBlock (std::move (v));
554var::var (Array<var>&& v) : type (&VariantType_Array::instance)
556 value.objectValue =
new VariantType_Array::RefCountedArray (std::move (v));
559var& var::operator= (String&& v)
561 type->cleanUp (value);
562 type = &VariantType_String::instance;
563 new (value.stringValue) String (std::move (v));
570 return type->equals (value,
other.value, *
other.type);
575 return hasSameTypeAs (
other) && equals (
other);
580 return type ==
other.type;
583bool canCompare (
const var& v1,
const var& v2)
585 return v1.type->isComparable() && v2.type->isComparable();
588static int compare (
const var& v1,
const var& v2)
590 if (v1.isString() && v2.isString())
591 return v1.toString().compare (v2.toString());
593 auto diff =
static_cast<double> (v1) -
static_cast<double> (v2);
594 return diff == 0 ? 0 : (diff < 0 ? -1 : 1);
597bool operator== (
const var& v1,
const var& v2) {
return v1.equals (v2); }
598bool operator!= (
const var& v1,
const var& v2) {
return ! v1.equals (v2); }
599bool operator< (
const var& v1,
const var& v2) {
return canCompare (v1, v2) && compare (v1, v2) < 0; }
600bool operator> (
const var& v1,
const var& v2) {
return canCompare (v1, v2) && compare (v1, v2) > 0; }
601bool operator<= (
const var& v1,
const var& v2) {
return canCompare (v1, v2) && compare (v1, v2) <= 0; }
602bool operator>= (
const var& v1,
const var& v2) {
return canCompare (v1, v2) && compare (v1, v2) >= 0; }
604bool operator== (
const var& v1,
const String& v2) {
return v1.toString() == v2; }
605bool operator!= (
const var& v1,
const String& v2) {
return v1.toString() != v2; }
606bool operator== (
const var& v1,
const char* v2) {
return v1.toString() == v2; }
607bool operator!= (
const var& v1,
const char* v2) {
return v1.toString() != v2; }
612 return type->clone (*
this);
618 if (
auto*
o = getDynamicObject())
621 return getNullVarRef();
631 if (
auto*
o = getDynamicObject())
639 if (
auto*
o = getDynamicObject())
647 return isMethod() && (value.methodValue !=
nullptr) ? *value.methodValue :
nullptr;
652 if (
auto*
o = getDynamicObject())
696 return array->
size();
707 jassert (array !=
nullptr && isPositiveAndBelow (
arrayIndex, array->
size()));
718 jassert (array !=
nullptr && isPositiveAndBelow (
arrayIndex, array->
size()));
739 convertToArray()->
add (
n);
750 convertToArray()->
insert (index,
n);
769 type->writeToStream (value, output);
780 case varMarker_Int:
return var (input.
readInt());
782 case varMarker_BoolTrue:
return var (
true);
783 case varMarker_BoolFalse:
return var (
false);
786 case varMarker_String:
789 mo.writeFromInputStream (input, numBytes - 1);
790 return var (
mo.toUTF8());
793 case varMarker_Binary:
806 case varMarker_Array:
826 : thisObject (
t), arguments (
args), numArguments (
numArgs)
Holds a resizable array of primitive or copy-by-value objects.
void ensureStorageAllocated(int minNumElements)
Increases the array's internal storage to hold a minimum number of elements.
int size() const noexcept
Returns the current number of elements in the array.
void remove(int indexToRemove)
Removes an element from the array.
void insert(int indexToInsertAt, ParameterType newElement)
Inserts a new element into the array at a given position.
int indexOf(ParameterType elementToLookFor) const
Finds the index of the first element which matches the value passed in.
void add(const ElementType &newElement)
Appends a new element at the end of the array.
void resize(int targetNumItems)
This will enlarge or shrink the array to the given number of elements, by adding or removing items fr...
Represents a dynamically implemented object.
Represents a string identifier, designed for accessing properties by name.
A class to hold a resizable block of raw data.
Writes data to an internal memory buffer, which grows as required.
size_t getDataSize() const noexcept
Returns the number of bytes of data that have been written to the stream.
The base class for streams that write data to some kind of destination.
virtual bool writeDouble(double value)
Writes a 64-bit floating point value to the stream in a binary format.
virtual bool write(const void *dataToWrite, size_t numberOfBytes)=0
Writes a block of data to the stream.
virtual bool writeCompressedInt(int value)
Writes a condensed binary encoding of a 32-bit integer.
virtual bool writeByte(char byte)
Writes a single byte to the stream.
virtual bool writeInt64(int64 value)
Writes a 64-bit integer to the stream in a little-endian byte order.
virtual bool writeInt(int value)
Writes a 32-bit integer to the stream in a little-endian byte order.
A base class which provides methods for reference-counting.
void incReferenceCount() noexcept
Increments the object's reference count.
static String toHexString(IntegerType number)
Returns a string representing this numeric value in hexadecimal.
static String charToString(juce_wchar character)
Creates a string from a single character.
A variant class, that can be used to hold a range of primitive values.
static var undefined() noexcept
Returns a var object that can be used where you need the javascript "undefined" value.
void insert(int index, const var &value)
Inserts an element to the var, converting it to an array if it isn't already one.
int size() const
If the var is an array, this returns the number of elements.
var invoke(const Identifier &method, const var *arguments, int numArguments) const
Invokes a named method call with a list of arguments.
void writeToStream(OutputStream &output) const
Writes a binary representation of this value to a stream.
var() noexcept
Creates a void variant.
~var() noexcept
Destructor.
Array< var > * getArray() const noexcept
If this variant holds an array, this provides access to it.
int indexOf(const var &value) const
If the var is an array, this searches it for the first occurrence of the specified value,...
const var & operator[](int arrayIndex) const
If the var is an array, this can be used to return one of its elements.
NativeFunction getNativeFunction() const
If this object is a method, this returns the function pointer.
bool hasProperty(const Identifier &propertyName) const noexcept
Returns true if this variant is an object and if it has the given property.
static var readFromStream(InputStream &input)
Reads back a stored binary representation of a value.
void append(const var &valueToAppend)
Appends an element to the var, converting it to an array if it isn't already one.
bool equals(const var &other) const noexcept
Returns true if this var has the same value as the one supplied.
bool equalsWithSameType(const var &other) const noexcept
Returns true if this var has the same value and type as the one supplied.
void resize(int numArrayElementsWanted)
Treating the var as an array, this resizes it to contain the specified number of elements.
var getProperty(const Identifier &propertyName, const var &defaultReturnValue) const
If this variant is an object, this returns one of its properties, or a default fallback value if the ...
void remove(int index)
If the var is an array, this removes one of its elements.
var call(const Identifier &method) const
Invokes a named method call with no arguments.
bool hasSameTypeAs(const var &other) const noexcept
Returns true if this var has the same type as the one supplied.
var clone() const noexcept
Returns a deep copy of this object.
MemoryBlock * getBinaryData() const noexcept
If this variant holds a memory block, this provides access to it.
This structure is passed to a NativeFunction callback, and contains invocation details about the func...