|
- //-----------------------------------------------------------------------------
- // Project : SDK Core
- //
- // Category : SDK Core Interfaces
- // Filename : pluginterfaces/base/fvariant.h
- // Created by : Steinberg, 01/2004
- // Description : Basic Interface
- //
- //-----------------------------------------------------------------------------
- // This file is part of a Steinberg SDK. It is subject to the license terms
- // in the LICENSE file found in the top-level directory of this distribution
- // and at www.steinberg.net/sdklicenses.
- // No part of the SDK, including this file, may be copied, modified, propagated,
- // or distributed except according to the terms contained in the LICENSE file.
- //-----------------------------------------------------------------------------
-
- #pragma once
-
- #include "pluginterfaces/base/fstrdefs.h"
- #include "pluginterfaces/base/funknown.h"
-
- //------------------------------------------------------------------------
- namespace Steinberg {
-
- class FUnknown;
-
- //------------------------------------------------------------------------
- // FVariant struct declaration
- //------------------------------------------------------------------------
- /** A Value of variable type.
- \ingroup pluginBase
- */
- class FVariant
- {
- //------------------------------------------------------------------------
- public:
- enum
- {
- kEmpty = 0,
- kInteger = 1 << 0,
- kFloat = 1 << 1,
- kString8 = 1 << 2,
- kObject = 1 << 3,
- kOwner = 1 << 4,
- kString16 = 1 << 5
- };
-
- //------------------------------------------------------------------------
- // ctors
- inline FVariant () { memset (this, 0, sizeof (FVariant)); }
- inline FVariant (const FVariant& variant);
-
- inline FVariant (bool b) : type (kInteger), intValue (b) {}
- inline FVariant (uint32 v) : type (kInteger), intValue (v) {}
- inline FVariant (int64 v) : type (kInteger), intValue (v) {}
- inline FVariant (double v) : type (kFloat), floatValue (v) {}
- inline FVariant (const char8* str) : type (kString8), string8 (str) {}
- inline FVariant (const char16* str) : type (kString16), string16 (str) {}
- inline FVariant (FUnknown* obj, bool owner = false) : type (kObject), object (obj)
- {
- setOwner (owner);
- }
- inline ~FVariant () { empty (); }
-
- //------------------------------------------------------------------------
- inline FVariant& operator= (const FVariant& variant);
-
- inline void set (bool b)
- {
- setInt (b);
- }
-
- inline void set (uint32 v)
- {
- setInt (v);
- }
-
- inline void set (int64 v)
- {
- setInt (v);
- }
-
- inline void set (double v)
- {
- setFloat (v);
- }
-
- inline void set (const char8* c)
- {
- setString8 (c);
- }
-
- inline void set (const char16* c)
- {
- setString16 (c);
- }
-
- inline void setInt (int64 v)
- {
- empty ();
- type = kInteger;
- intValue = v;
- }
-
- inline void setFloat (double v)
- {
- empty ();
- type = kFloat;
- floatValue = v;
- }
- inline void setString8 (const char8* v)
- {
- empty ();
- type = kString8;
- string8 = v;
- }
- inline void setString16 (const char16* v)
- {
- empty ();
- type = kString16;
- string16 = v;
- }
-
- inline void setObject (FUnknown* obj)
- {
- empty ();
- type = kObject;
- object = obj;
- }
-
- template <typename T>
- inline T get () const;
-
- inline int64 getInt () const { return (type & kInteger) ? intValue : 0; }
- inline double getFloat () const { return (type & kFloat) ? floatValue : 0.; }
- inline double getNumber () const
- {
- return (type & kInteger) ? static_cast<double> (intValue) : (type & kFloat) ? floatValue :
- 0.;
- }
- inline const char8* getString8 () const { return (type & kString8) ? string8 : 0; }
- inline const char16* getString16 () const { return (type & kString16) ? string16 : 0; }
-
- inline FUnknown* getObject () const { return (type & kObject) ? object : 0; }
-
- inline uint16 getType () const { return static_cast<uint16> (type & ~(kOwner)); }
- inline bool isEmpty () const { return getType () == kEmpty; }
- inline bool isOwner () const { return (type & kOwner) != 0; }
- inline bool isString () const { return (type & (kString8 | kString16)) != 0; }
- inline void setOwner (bool state)
- {
- if (state)
- type |= kOwner;
- else
- type &= ~kOwner;
- }
-
- void empty ();
- //------------------------------------------------------------------------
- uint16 type;
- union
- {
- int64 intValue;
- double floatValue;
- const char8* string8;
- const char16* string16;
- FUnknown* object;
- };
- };
-
- //------------------------------------------------------------------------
- inline bool operator== (const FVariant& v1, const FVariant& v2)
- {
- #if SMTG_PLATFORM_64
- return v1.type == v2.type && v1.intValue == v2.intValue;
- #else
- if (v1.type != v2.type)
- return false;
- if (v1.type & (FVariant::kString8 | FVariant::kString16 | FVariant::kObject))
- return v1.string8 == v2.string8; // pointer type comparisons
- return v1.intValue == v2.intValue; // intValue & double comparison
-
- #endif
- }
-
- template <>
- inline bool FVariant::get<bool> () const
- {
- return getInt () != 0;
- }
-
- template <>
- inline uint32 FVariant::get<uint32> () const
- {
- return static_cast<uint32> (getInt ());
- }
-
- template <>
- inline int32 FVariant::get<int32> () const
- {
- return static_cast<int32> (getInt ());
- }
-
- template <>
- inline int64 FVariant::get<int64> () const
- {
- return static_cast<int64> (getInt ());
- }
-
- template <>
- inline float FVariant::get<float> () const
- {
- return static_cast<float> (getFloat ());
- }
-
- template <>
- inline double FVariant::get<double> () const
- {
- return getFloat ();
- }
-
- template <>
- inline const char8* FVariant::get<const char8*> () const
- {
- return getString8 ();
- }
-
- template <>
- inline const char16* FVariant::get<const char16*> () const
- {
- return getString16 ();
- }
-
- template <>
- inline FUnknown* FVariant::get<FUnknown*> () const
- {
- return getObject ();
- }
-
- //------------------------------------------------------------------------
- inline bool operator!= (const FVariant& v1, const FVariant& v2) { return !(v1 == v2); }
-
- //------------------------------------------------------------------------
- inline FVariant::FVariant (const FVariant& variant) : type (kEmpty) { *this = variant; }
-
- //------------------------------------------------------------------------
- inline void FVariant::empty ()
- {
- if (type & kOwner)
- {
- if ((type & kString8) && string8)
- delete[] string8;
- else if ((type & kString16) && string16)
- delete[] string16;
-
- else if ((type & kObject) && object)
- object->release ();
- }
- memset (this, 0, sizeof (FVariant));
- }
-
- //------------------------------------------------------------------------
- inline FVariant& FVariant::operator= (const FVariant& variant)
- {
- empty ();
-
- type = variant.type;
-
- if ((type & kString8) && variant.string8)
- {
- string8 = new char8[strlen (variant.string8) + 1];
- strcpy (const_cast<char8*> (string8), variant.string8);
- type |= kOwner;
- }
- else if ((type & kString16) && variant.string16)
- {
- int32 len = strlen16 (variant.string16);
- string16 = new char16[len + 1];
- char16* tmp = const_cast<char16*> (string16);
- memcpy (tmp, variant.string16, len * sizeof (char16));
- tmp[len] = 0;
- type |= kOwner;
- }
- else if ((type & kObject) && variant.object)
- {
- object = variant.object;
- object->addRef ();
- type |= kOwner;
- }
- else
- intValue = variant.intValue; // copy memory
-
- return *this;
- }
-
- //------------------------------------------------------------------------
- } // namespace Steinberg
|