/* Copyright(C) 2007-2017 VoIP objects (voipobjects.com) * This Source Code Form is subject to the terms of the Mozilla Public * License, v. 2.0. If a copy of the MPL was not distributed with this * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ #include "HL_VariantMap.h" #include "HL_Exception.h" #include #if defined(TARGET_ANDROID) #define __STDC_FORMAT_MACROS #endif #include #include Variant::Variant() { mType = VTYPE_INT; mInt = 0; mInt64 = 0; mBool = 0; mFloat = 0; mPointer = nullptr; } Variant::~Variant() {} Variant::Variant(bool value) : mType(VTYPE_BOOL), mBool(value) {} Variant::Variant(int value) : mType(VTYPE_INT), mInt(value) {} Variant::Variant(int64_t value) : mType(VTYPE_INT64), mInt64(value) {} Variant::Variant(float value) : mType(VTYPE_FLOAT), mFloat(value) {} Variant::Variant(double value) : mType(VTYPE_FLOAT), mFloat((float)value) {} Variant::Variant(const std::string& value) : mType(VTYPE_STRING), mString(value) {} Variant& Variant::operator=(bool value) { mType = VTYPE_BOOL; mBool = value; return *this; } Variant& Variant::operator=(int value) { mType = VTYPE_INT; mInt = value; return *this; } Variant& Variant::operator=(int64_t value) { mType = VTYPE_INT64; mInt64 = value; return *this; } Variant& Variant::operator=(float value) { mType = VTYPE_FLOAT; mFloat = value; return *this; } Variant& Variant::operator=(const std::string& value) { mType = VTYPE_STRING; mString = value; return *this; } Variant& Variant::operator=(const char* value) { mType = VTYPE_STRING; mString = value; return *this; } Variant& Variant::operator=(void* value) { mType = VTYPE_POINTER; mPointer = value; return *this; } Variant& Variant::operator=(PVariantMap map) { mType = VTYPE_VMAP; mVMap = map; return *this; } Variant Variant::operator+(const Variant& rhs) { switch (type()) { case VTYPE_BOOL: case VTYPE_INT: return asInt() + rhs.asInt(); case VTYPE_INT64: return asInt64() + rhs.asInt64(); case VTYPE_FLOAT: return asFloat() + rhs.asFloat(); case VTYPE_STRING: return asStdString() + rhs.asStdString(); default: return false; } } Variant Variant::operator-(const Variant& rhs) { switch (type()) { case VTYPE_BOOL: case VTYPE_STRING: case VTYPE_INT: return asInt() - rhs.asInt(); case VTYPE_INT64: return asInt64() - rhs.asInt64(); case VTYPE_FLOAT: return asFloat() - rhs.asFloat(); default: return false; } } Variant Variant::operator*(const Variant& rhs) { switch (type()) { case VTYPE_BOOL: case VTYPE_STRING: case VTYPE_INT: return asInt() * rhs.asInt(); case VTYPE_INT64: return asInt64() * rhs.asInt64(); case VTYPE_FLOAT: return asFloat() * rhs.asFloat(); default: return false; } } Variant Variant::operator/(const Variant& rhs) { switch (type()) { case VTYPE_BOOL: case VTYPE_STRING: case VTYPE_INT: return asInt() / rhs.asInt(); case VTYPE_INT64: return asInt64() / rhs.asInt64(); case VTYPE_FLOAT: return asFloat() / rhs.asFloat(); default: return false; } } bool Variant::operator<(const Variant& rhs) const { switch (type()) { case VTYPE_STRING: return asStdString() < rhs.asStdString(); case VTYPE_BOOL: case VTYPE_INT: return asInt() < rhs.asInt(); case VTYPE_INT64: return asInt64() < rhs.asInt64(); case VTYPE_FLOAT: return asFloat() < rhs.asFloat(); default: return false; } } bool Variant::operator>(const Variant& rhs) const { return !(*this == rhs) && !(*this < rhs); } bool Variant::operator==(const Variant& rhs) const { switch (type()) { case VTYPE_STRING: return asStdString() == rhs.asStdString(); case VTYPE_BOOL: return asBool() == rhs.asBool(); case VTYPE_INT: return asInt() == rhs.asInt(); case VTYPE_INT64: return asInt64() == rhs.asInt64(); case VTYPE_FLOAT: return asFloat() == rhs.asFloat(); case VTYPE_POINTER: return asPointer() == rhs.asPointer(); case VTYPE_VMAP: assert(0); break; default: return false; } return false; } bool Variant::operator!=(const Variant& rhs) const { return !(*this == rhs); } bool Variant::operator<=(const Variant& rhs) const { return (*this < rhs) || (*this == rhs); } bool Variant::operator>=(const Variant& rhs) const { return (*this > rhs) || (*this == rhs); } int Variant::asInt() const { if (mType != VTYPE_INT) throw Exception(ERR_BAD_VARIANT_TYPE); return mInt; } int64_t Variant::asInt64() const { if (mType != VTYPE_INT64) throw Exception(ERR_BAD_VARIANT_TYPE); return mInt64; } bool Variant::asBool() const { switch (mType) { case VTYPE_INT: return mInt != 0; case VTYPE_INT64: return mInt64 != 0; case VTYPE_BOOL: return mBool; case VTYPE_FLOAT: return mFloat != 0; case VTYPE_STRING: return mString.length() != 0; default: throw Exception(ERR_BAD_VARIANT_TYPE); } } float Variant::asFloat() const { switch (mType) { case VTYPE_INT: return (float)mInt; case VTYPE_INT64: return (float)mInt64; case VTYPE_FLOAT: return mFloat; default: throw Exception(ERR_BAD_VARIANT_TYPE); } } double Variant::asDouble() const { return static_cast(asFloat()); } std::string Variant::asStdString() const { char buffer[32]; switch (mType) { case VTYPE_STRING: return mString; case VTYPE_INT: std::snprintf(buffer, sizeof(buffer), "%d", mInt); return buffer; case VTYPE_INT64: std::snprintf(buffer, sizeof(buffer), "%lli", static_cast(mInt64)); return buffer; case VTYPE_BOOL: return mBool ? "true" : "false"; case VTYPE_FLOAT: std::snprintf(buffer, sizeof(buffer), "%f", mFloat); return buffer; default: throw Exception(ERR_BAD_VARIANT_TYPE); } } void* Variant::asPointer() const { switch (mType) { case VTYPE_POINTER: return mPointer; default: throw Exception(ERR_BAD_VARIANT_TYPE); } } PVariantMap Variant::asVMap() { switch (mType) { case VTYPE_VMAP: return mVMap; default: throw Exception(ERR_BAD_VARIANT_TYPE); } } VariantType Variant::type() const { return mType; } VariantMap::VariantMap() {} VariantMap::~VariantMap() {} bool VariantMap::empty() const { return mData.empty(); } void VariantMap::clear() { mData.clear(); } bool VariantMap::exists(int itemId) const { return mData.find(itemId) != mData.end(); } Variant& VariantMap::operator[](int itemId) { return mData[itemId]; } Variant& VariantMap::at(int itemId) { return mData[itemId]; }