/* * variant.cpp * Copyright (C) 2017 Belledonne Communications SARL * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY {} without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program. If not, see . */ #include "linphone/utils/utils.h" #include "variant.h" // ============================================================================= using namespace std; LINPHONE_BEGIN_NAMESPACE class VariantPrivate { public: union Value { int i; unsigned int ui; short s; unsigned short us; long l; unsigned long ul; long long ll; unsigned long long ull; char c; bool b; double d; float f; string *str; void *g; }; // Integer, because type can be a custom type. int type = Variant::Invalid; Value value = {}; }; Variant::Variant () { // Nothing. Construct an invalid invariant. } Variant::Variant (Type type) { // TODO. } Variant::Variant (const Variant &src) { // TODO. } Variant::Variant (Variant &&src) { // TODO. } Variant::Variant (int value) : Variant(Int) { L_D(Variant); d->value.i = value; } Variant::Variant (unsigned int value) : Variant(UnsignedInt) { L_D(Variant); d->value.ui = value; } Variant::Variant (short value) : Variant(Short) { L_D(Variant); d->value.s = value; } Variant::Variant (unsigned short value) : Variant(UnsignedShort) { L_D(Variant); d->value.us = value; } Variant::Variant (long value) : Variant(Long) { L_D(Variant); d->value.l = value; } Variant::Variant (unsigned long value) : Variant(UnsignedLong) { L_D(Variant); d->value.ul = value; } Variant::Variant (long long value) : Variant(LongLong) { L_D(Variant); d->value.ll = value; } Variant::Variant (unsigned long long value) : Variant(UnsignedLongLong) { L_D(Variant); d->value.ull = value; } Variant::Variant (char value) : Variant(Char) { L_D(Variant); d->value.c = value; } Variant::Variant (bool value) : Variant(Bool) { L_D(Variant); d->value.b = value; } Variant::Variant (double value) : Variant(Double) { L_D(Variant); d->value.d = value; } Variant::Variant (float value) : Variant(Float) { L_D(Variant); d->value.f = value; } Variant::Variant (const std::string &value) { // TODO. } Variant::~Variant () { // TODO. } bool Variant::operator!= (const Variant &variant) const { // TODO. return false; } bool Variant::operator< (const Variant &variant) const { // TODO. return false; } bool Variant::operator<= (const Variant &variant) const { // TODO. return false; } Variant &Variant::operator= (const Variant &variant) { // TODO. return *this; } Variant &Variant::operator= (Variant &&variant) { // TODO. return *this; } bool Variant::operator== (const Variant &variant) const { // TODO. return false; } bool Variant::operator> (const Variant &variant) const { // TODO. return false; } bool Variant::operator>= (const Variant &variant) const { // TODO. return false; } bool Variant::isValid () const { // TODO. return false; } void Variant::clear () { // TODO. } void Variant::swap (const Variant &variant) { // TODO. } // ----------------------------------------------------------------------------- // Number helpers. // ----------------------------------------------------------------------------- static inline long long getAssumedNumber (const VariantPrivate &p) { L_ASSERT(p.type > Variant::Invalid && p.type < Variant::MaxDefaultTypes); switch (static_cast(p.type)) { case Variant::Int: return p.value.i; case Variant::Short: return p.value.s; case Variant::Long: return p.value.l; case Variant::LongLong: return p.value.ll; case Variant::Char: return p.value.c; case Variant::Double: return p.value.d; case Variant::Float: return p.value.f; default: L_ASSERT(false); } return 0; } static inline unsigned long long getAssumedUnsignedNumber (const VariantPrivate &p) { L_ASSERT(p.type > Variant::Invalid && p.type < Variant::MaxDefaultTypes); switch (static_cast(p.type)) { case Variant::UnsignedInt: return p.value.ui; case Variant::UnsignedShort: return p.value.us; case Variant::UnsignedLong: return p.value.ul; case Variant::UnsignedLongLong: return p.value.ull; default: L_ASSERT(false); } return 0; } // ----------------------------------------------------------------------------- // Number conversions. // ----------------------------------------------------------------------------- static inline long long getValueAsNumber (const VariantPrivate &p, bool *soFarSoGood) { // TODO. return 0; } static inline unsigned long long getValueAsUnsignedNumber (const VariantPrivate &p, bool *soFarSoGood) { // TODO. return 0; } // ----------------------------------------------------------------------------- // Specific conversions. // ----------------------------------------------------------------------------- static inline bool getValueAsBool (const VariantPrivate &p, bool *soFarSoGood) { L_ASSERT(p.type > Variant::Invalid && p.type < Variant::MaxDefaultTypes); *soFarSoGood = true; switch (static_cast(p.type)) { case Variant::Int: case Variant::Short: case Variant::Long: case Variant::LongLong: case Variant::Char: case Variant::Double: case Variant::Float: return static_cast(getAssumedNumber(p)); case Variant::UnsignedInt: case Variant::UnsignedShort: case Variant::UnsignedLong: case Variant::UnsignedLongLong: return static_cast(getAssumedUnsignedNumber(p)); case Variant::Bool: return p.value.b; case Variant::String: return Utils::stringToBool(*p.value.str); case Variant::Generic: return static_cast(p.value.g); default: *soFarSoGood = false; break; } return false; } static inline double getValueAsDouble (const VariantPrivate &p, bool *soFarSoGood) { // TODO. return 0.0; } static inline float getValueAsFloat (const VariantPrivate &p, bool *soFarSoGood) { // TODO. return 0.f; } static inline float getValueAsString (const VariantPrivate &p, bool *soFarSoGood) { // TODO. return 0.f; } static inline void *getValueAsGeneric (const VariantPrivate &p, bool *soFarSoGood) { // TODO. return nullptr; } // ----------------------------------------------------------------------------- void Variant::getValue (int type, void *value, bool *soFarSoGood) const { L_D(const Variant); if (type <= Invalid || type >= MaxDefaultTypes) { *soFarSoGood = false; // Unable to get value. It will be great to support custom types. return; } switch (static_cast(type)) { // Cast as Number. case Int: *static_cast(value) = static_cast(getValueAsNumber(*d, soFarSoGood)); break; case Short: *static_cast(value) = static_cast(getValueAsNumber(*d, soFarSoGood)); break; case Long: *static_cast(value) = static_cast(getValueAsNumber(*d, soFarSoGood)); break; case LongLong: *static_cast(value) = getValueAsNumber(*d, soFarSoGood); break; case Char: *static_cast(value) = static_cast(getValueAsNumber(*d, soFarSoGood)); break; // Cast as Unsigned number. case UnsignedInt: *static_cast(value) = static_cast(getValueAsNumber(*d, soFarSoGood)); break; case UnsignedShort: *static_cast(value) = static_cast(getValueAsNumber(*d, soFarSoGood)); break; case UnsignedLong: *static_cast(value) = static_cast(getValueAsNumber(*d, soFarSoGood)); break; case UnsignedLongLong: *static_cast(value) = getValueAsNumber(*d, soFarSoGood); break; // Cast as specific value. case Bool: *static_cast(value) = getValueAsBool(*d, soFarSoGood); break; case Double: *static_cast(value) = getValueAsDouble(*d, soFarSoGood); break; case Float: *static_cast(value) = getValueAsFloat(*d, soFarSoGood); break; case String: *static_cast(value) = getValueAsString(*d, soFarSoGood); break; case Generic: *static_cast(value) = getValueAsGeneric(*d, soFarSoGood); break; case Invalid: case MaxDefaultTypes: *soFarSoGood = false; break; } } LINPHONE_END_NAMESPACE