#ifndef _KVI_KVS_VARIANT_H_ #define _KVI_KVS_VARIANT_H_ //============================================================================= // // File : kvi_kvs_variant.h // Created on Tue 07 Oct 2003 04:01:19 by Szymon Stefanek // // This file is part of the KVIrc IRC client distribution // Copyright (C) 2003 Szymon Stefanek // // 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 2 // of the License, or (at your opinion) 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, write to the Free Software Foundation, // Inc. ,51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. // //============================================================================= #include "kvi_settings.h" #include "kvi_qstring.h" #include "kvi_heapobject.h" #include "kvi_kvs_types.h" class KviKvsVariant; class KviKvsArrayCast; class KVIRC_API KviKvsNumber { friend class KviKvsVariant; public: enum DataType { Real, Integer }; protected: union { kvs_int_t iInteger; kvs_real_t dReal; } m_u; DataType m_type; public: DataType type() const { return m_type; }; bool isReal() const { return m_type == Real; }; bool isInteger() const { return m_type == Integer; }; kvs_real_t real() const { return m_u.dReal; }; kvs_int_t integer() const { return m_u.iInteger; }; }; // pre-declare.. the real declarations are included below class KviKvsHash; class KviKvsArray; class KviKvsVariantData { public: enum Type { Nothing = 0, // m_pData not initialized String = 1, // TQString (scalar) Integer = 2, // long int (scalar) Real = 4, // double (scalar) Array = 8, // KviKvsArray Hash = 16, // KviKvsHash Boolean = 32, // bool (scalar) HObject = 64 // object, shallow! (scalar) }; public: unsigned int m_uRefs; Type m_eType; union { kvs_int_t iInteger; kvs_real_t * pReal; TQString * pString; KviKvsArray * pArray; KviKvsHash * pHash; bool bBoolean; kvs_hobject_t hObject; } m_u; }; // This class must not have virtual funcitons nor destructor // Otherwise it will happily crash on windows when it is // allocated in modules and destroyed anywhere else around... class KVIRC_API KviKvsVariant : public KviHeapObject { friend class KviKvsVariantComparison; public: KviKvsVariant(); KviKvsVariant(kvs_int_t iInteger); KviKvsVariant(kvs_real_t dReal); KviKvsVariant(kvs_real_t * pReal); KviKvsVariant(bool bBoolean); KviKvsVariant(const TQString &szString); KviKvsVariant(const char * szString); // without this gcc chooses the conversion (const char *)->(void *) instead of (const char *)->(TQString) and obviously calls the wrong constructor KviKvsVariant(TQString * pString); KviKvsVariant(KviKvsArray * pArray); KviKvsVariant(KviKvsHash * pHash); KviKvsVariant(kvs_hobject_t hObject); KviKvsVariant(const KviKvsVariant &v); ~KviKvsVariant(); protected: KviKvsVariantData * m_pData; public: KviKvsVariantData::Type type(){ return m_pData ? m_pData->m_eType : KviKvsVariantData::Nothing; }; void setReal(kvs_real_t dReal); void setReal(kvs_real_t * pReal); void setInteger(kvs_int_t iInteger); void setString(const TQString &szString); void setString(TQString * pString); void setArray(KviKvsArray * pArray); void setHash(KviKvsHash * pHash); void setBoolean(bool bBoolean); void setHObject(kvs_hobject_t hObject); void setNothing(); //void unset(){ setNothing(); }; void getTypeName(TQString &szBuffer) const; bool isNothing() const { return !m_pData; }; bool isInteger() const { return m_pData ? (m_pData->m_eType == KviKvsVariantData::Integer) : false; }; bool isReal() const { return m_pData ? (m_pData->m_eType == KviKvsVariantData::Real) : false; }; bool isNumeric() const { return m_pData ? (m_pData->m_eType & (KviKvsVariantData::Integer | KviKvsVariantData::Real)) : false; }; bool isString() const { return m_pData ? (m_pData->m_eType == KviKvsVariantData::String) : false; }; bool isScalar() const { return m_pData ? (m_pData->m_eType & (KviKvsVariantData::String | KviKvsVariantData::Integer | KviKvsVariantData::Real)) : false; }; bool isArray() const { return m_pData ? (m_pData->m_eType == KviKvsVariantData::Array) : false; }; bool isHash() const { return m_pData ? (m_pData->m_eType == KviKvsVariantData::Hash) : false; }; bool isBoolean() const { return m_pData ? (m_pData->m_eType == KviKvsVariantData::Boolean) : false; }; bool isHObject() const { return m_pData ? (m_pData->m_eType == KviKvsVariantData::HObject) : false; }; bool isEmpty() const; // returns true if this variant is nothing, false, null, 0 or an empty string bool isEqualToNothing() const; // evaluates Integer, Real and String rappresenting an Integer bool asInteger(kvs_int_t &iVal) const; // evaluates Real, Integer and String rappresenting a Real bool asReal(kvs_real_t &dVal) const; // evaluates Real, Integer and String rappresenting a Real or integer bool asNumber(KviKvsNumber &n) const; // always evaluates to a boolean value bool asBoolean() const; // evaluates to an object handle bool asHObject(kvs_hobject_t &hObject) const; // evaluates anything to a string void asString(TQString &szBuffer) const; void appendAsString(TQString &szBuffer) const; // always evaluates to some number... void castToNumber(KviKvsNumber &n) const; // always evaluates to an integer void castToInteger(kvs_int_t &iVal) const; // always evaluates to an array void castToArray(KviKvsArrayCast *c) const; // converts this variant to an array void convertToArray(); kvs_int_t integer() const { return m_pData ? m_pData->m_u.iInteger : 0; }; kvs_real_t real() const { return m_pData ? *(m_pData->m_u.pReal) : 0.0; }; const TQString & string() const { return m_pData ? *(m_pData->m_u.pString) : KviTQString::empty; }; KviKvsArray * array() const { return m_pData ? m_pData->m_u.pArray : 0; }; KviKvsHash * hash() const { return m_pData ? m_pData->m_u.pHash : 0; }; bool boolean() const { return m_pData ? m_pData->m_u.bBoolean : false; }; kvs_hobject_t hobject() const { return m_pData ? m_pData->m_u.hObject : (kvs_hobject_t)0; }; void copyFrom(const KviKvsVariant * v); void copyFrom(const KviKvsVariant & v); void takeFrom(KviKvsVariant * v); void takeFrom(KviKvsVariant &v); void dump(const char * prefix) const; // returns -1 if this variant is greater than the other, 0 if are equal, 1 if the other is greater // if bPreferNumeric is true then when comparing strings a conversion to a numeric format // is first attempted. int compare(const KviKvsVariant * pOther,bool bPreferNumeric = false) const; void operator = (const KviKvsVariant &v){ copyFrom(v); }; //JSON serialization void serialize(TQString& result); static void serializeString(TQString& buffer); static KviKvsVariant* unserialize(const TQString& buffer); private: static KviKvsVariant* unserialize(const TQChar** aux); static KviKvsVariant* unserializeTrue(const TQChar** aux); static KviKvsVariant* unserializeFalse(const TQChar** aux); static KviKvsVariant* unserializeNull(const TQChar** aux); static KviKvsVariant* unserializeArray(const TQChar** aux); static KviKvsVariant* unserializeHash(const TQChar** aux); static void unserializeString(const TQChar** aux,TQString& buffer); static KviKvsVariant* unserializeString(const TQChar** aux); static KviKvsVariant* unserializeRealOrInteger(const TQChar** aux); static KviKvsVariant* unserializeReal(const TQChar** aux,TQString& data); static KviKvsVariant* unserializeInteger(const TQChar** aux,TQString& data); }; #include "kvi_kvs_array.h" #include "kvi_kvs_hash.h" #endif //!_KVI_KVS_VARIANT_H_