297 lines
7.1 KiB
C++
297 lines
7.1 KiB
C++
//-----------------------------------------------------------------------------
|
|
// 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
|