Files
wxWidgets/src/common/variant.cpp
Vadim Zeitlin f4b80e5337 Remove MSVC6 support.
Don't support this compiler any more, this allows to get rid of tons of
MSVC6-specific workarounds, in particular we can now use Bind() and natural
template functions calls in the library code.

Also remove MSVC6 project and solution files and don't generate them when
bakefile_gen is ran any more (removing the remaining occurrences of msvc6prj
from the bakefiles results in weird bake-time errors, so it's simpler to just
leave them there).

git-svn-id: https://svn.wxwidgets.org/svn/wx/wxWidgets/trunk@76532 c3d73ce0-8a6f-49c7-b76d-6d57e0e08775
2014-05-15 22:32:17 +00:00

2511 lines
58 KiB
C++

/////////////////////////////////////////////////////////////////////////////
// Name: src/common/variant.cpp
// Purpose: wxVariant class, container for any type
// Author: Julian Smart
// Modified by:
// Created: 10/09/98
// Copyright: (c)
// Licence: wxWindows licence
/////////////////////////////////////////////////////////////////////////////
// For compilers that support precompilation, includes "wx/wx.h".
#include "wx/wxprec.h"
#ifdef __BORLANDC__
#pragma hdrstop
#endif
#include "wx/variant.h"
#if wxUSE_VARIANT
#ifndef WX_PRECOMP
#include "wx/string.h"
#include "wx/math.h"
#include "wx/crt.h"
#if wxUSE_STREAMS
#include "wx/stream.h"
#endif
#endif
#if wxUSE_STD_IOSTREAM
#if wxUSE_IOSTREAMH
#include <fstream.h>
#else
#include <fstream>
#endif
#endif
#if wxUSE_STREAMS
#include "wx/txtstrm.h"
#endif
#include "wx/string.h"
#include "wx/tokenzr.h"
wxVariant WXDLLIMPEXP_BASE wxNullVariant;
#include "wx/listimpl.cpp"
WX_DEFINE_LIST(wxVariantList)
/*
* wxVariant
*/
IMPLEMENT_DYNAMIC_CLASS(wxVariant, wxObject)
wxVariant::wxVariant()
: wxObject()
{
}
bool wxVariant::IsNull() const
{
return (m_refData == NULL);
}
void wxVariant::MakeNull()
{
UnRef();
}
void wxVariant::Clear()
{
m_name = wxEmptyString;
}
wxVariant::wxVariant(const wxVariant& variant)
: wxObject()
{
if (!variant.IsNull())
Ref(variant);
m_name = variant.m_name;
}
wxVariant::wxVariant(wxVariantData* data, const wxString& name) // User-defined data
: wxObject()
{
m_refData = data;
m_name = name;
}
wxVariant::~wxVariant()
{
}
wxObjectRefData *wxVariant::CreateRefData() const
{
// We cannot create any particular wxVariantData.
wxFAIL_MSG("wxVariant::CreateRefData() cannot be implemented");
return NULL;
}
wxObjectRefData *wxVariant::CloneRefData(const wxObjectRefData *data) const
{
return ((wxVariantData*) data)->Clone();
}
// Assignment
void wxVariant::operator= (const wxVariant& variant)
{
Ref(variant);
m_name = variant.m_name;
}
// myVariant = new wxStringVariantData("hello")
void wxVariant::operator= (wxVariantData* variantData)
{
UnRef();
m_refData = variantData;
}
bool wxVariant::operator== (const wxVariant& variant) const
{
if (IsNull() || variant.IsNull())
return (IsNull() == variant.IsNull());
if (GetType() != variant.GetType())
return false;
return (GetData()->Eq(* variant.GetData()));
}
bool wxVariant::operator!= (const wxVariant& variant) const
{
return (!(*this == variant));
}
wxString wxVariant::MakeString() const
{
if (!IsNull())
{
wxString str;
if (GetData()->Write(str))
return str;
}
return wxEmptyString;
}
void wxVariant::SetData(wxVariantData* data)
{
UnRef();
m_refData = data;
}
bool wxVariant::Unshare()
{
if ( !m_refData || m_refData->GetRefCount() == 1 )
return true;
wxObject::UnShare();
return (m_refData && m_refData->GetRefCount() == 1);
}
// Returns a string representing the type of the variant,
// e.g. "string", "bool", "list", "double", "long"
wxString wxVariant::GetType() const
{
if (IsNull())
return wxString(wxT("null"));
else
return GetData()->GetType();
}
bool wxVariant::IsType(const wxString& type) const
{
return (GetType() == type);
}
bool wxVariant::IsValueKindOf(const wxClassInfo* type) const
{
wxClassInfo* info=GetData()->GetValueClassInfo();
return info ? info->IsKindOf(type) : false ;
}
// -----------------------------------------------------------------
// wxVariant <-> wxAny conversion code
// -----------------------------------------------------------------
#if wxUSE_ANY
wxAnyToVariantRegistration::
wxAnyToVariantRegistration(wxVariantDataFactory factory)
: m_factory(factory)
{
wxPreRegisterAnyToVariant(this);
}
wxAnyToVariantRegistration::~wxAnyToVariantRegistration()
{
}
wxVariant::wxVariant(const wxAny& any)
: wxObject()
{
wxVariant variant;
if ( !any.GetAs(&variant) )
{
wxFAIL_MSG("wxAny of this type cannot be converted to wxVariant");
return;
}
*this = variant;
}
wxAny wxVariant::GetAny() const
{
if ( IsNull() )
return wxAny();
wxAny any;
wxVariantData* data = GetData();
if ( data->GetAsAny(&any) )
return any;
// If everything else fails, wrap the whole wxVariantData
return wxAny(data);
}
#endif // wxUSE_ANY
// -----------------------------------------------------------------
// wxVariantDataLong
// -----------------------------------------------------------------
class WXDLLIMPEXP_BASE wxVariantDataLong: public wxVariantData
{
public:
wxVariantDataLong() { m_value = 0; }
wxVariantDataLong(long value) { m_value = value; }
inline long GetValue() const { return m_value; }
inline void SetValue(long value) { m_value = value; }
virtual bool Eq(wxVariantData& data) const wxOVERRIDE;
virtual bool Read(wxString& str) wxOVERRIDE;
virtual bool Write(wxString& str) const wxOVERRIDE;
#if wxUSE_STD_IOSTREAM
virtual bool Read(wxSTD istream& str) wxOVERRIDE;
virtual bool Write(wxSTD ostream& str) const wxOVERRIDE;
#endif
#if wxUSE_STREAMS
virtual bool Read(wxInputStream& str);
virtual bool Write(wxOutputStream &str) const;
#endif // wxUSE_STREAMS
wxVariantData* Clone() const wxOVERRIDE { return new wxVariantDataLong(m_value); }
virtual wxString GetType() const wxOVERRIDE { return wxT("long"); }
#if wxUSE_ANY
// Since wxAny does not have separate type for integers shorter than
// longlong, we do not usually implement wxVariant->wxAny conversion
// here (but in wxVariantDataLongLong instead).
#ifndef wxLongLong_t
DECLARE_WXANY_CONVERSION()
#else
bool GetAsAny(wxAny* any) const wxOVERRIDE
{
*any = m_value;
return true;
}
#endif
#endif // wxUSE_ANY
protected:
long m_value;
};
#ifndef wxLongLong_t
IMPLEMENT_TRIVIAL_WXANY_CONVERSION(long, wxVariantDataLong)
#endif
bool wxVariantDataLong::Eq(wxVariantData& data) const
{
wxASSERT_MSG( (data.GetType() == wxT("long")), wxT("wxVariantDataLong::Eq: argument mismatch") );
wxVariantDataLong& otherData = (wxVariantDataLong&) data;
return (otherData.m_value == m_value);
}
#if wxUSE_STD_IOSTREAM
bool wxVariantDataLong::Write(wxSTD ostream& str) const
{
wxString s;
Write(s);
str << (const char*) s.mb_str();
return true;
}
#endif
bool wxVariantDataLong::Write(wxString& str) const
{
str.Printf(wxT("%ld"), m_value);
return true;
}
#if wxUSE_STD_IOSTREAM
bool wxVariantDataLong::Read(wxSTD istream& str)
{
str >> m_value;
return true;
}
#endif
#if wxUSE_STREAMS
bool wxVariantDataLong::Write(wxOutputStream& str) const
{
wxTextOutputStream s(str);
s.Write32((size_t)m_value);
return true;
}
bool wxVariantDataLong::Read(wxInputStream& str)
{
wxTextInputStream s(str);
m_value = s.Read32();
return true;
}
#endif // wxUSE_STREAMS
bool wxVariantDataLong::Read(wxString& str)
{
m_value = wxAtol(str);
return true;
}
// wxVariant
wxVariant::wxVariant(long val, const wxString& name)
{
m_refData = new wxVariantDataLong(val);
m_name = name;
}
wxVariant::wxVariant(int val, const wxString& name)
{
m_refData = new wxVariantDataLong((long)val);
m_name = name;
}
wxVariant::wxVariant(short val, const wxString& name)
{
m_refData = new wxVariantDataLong((long)val);
m_name = name;
}
bool wxVariant::operator== (long value) const
{
long thisValue;
if (!Convert(&thisValue))
return false;
else
return (value == thisValue);
}
bool wxVariant::operator!= (long value) const
{
return (!((*this) == value));
}
void wxVariant::operator= (long value)
{
if (GetType() == wxT("long") &&
m_refData->GetRefCount() == 1)
{
((wxVariantDataLong*)GetData())->SetValue(value);
}
else
{
UnRef();
m_refData = new wxVariantDataLong(value);
}
}
long wxVariant::GetLong() const
{
long value;
if (Convert(& value))
return value;
else
{
wxFAIL_MSG(wxT("Could not convert to a long"));
return 0;
}
}
// -----------------------------------------------------------------
// wxVariantDoubleData
// -----------------------------------------------------------------
class WXDLLIMPEXP_BASE wxVariantDoubleData: public wxVariantData
{
public:
wxVariantDoubleData() { m_value = 0.0; }
wxVariantDoubleData(double value) { m_value = value; }
inline double GetValue() const { return m_value; }
inline void SetValue(double value) { m_value = value; }
virtual bool Eq(wxVariantData& data) const wxOVERRIDE;
virtual bool Read(wxString& str) wxOVERRIDE;
#if wxUSE_STD_IOSTREAM
virtual bool Write(wxSTD ostream& str) const wxOVERRIDE;
#endif
virtual bool Write(wxString& str) const wxOVERRIDE;
#if wxUSE_STD_IOSTREAM
virtual bool Read(wxSTD istream& str) wxOVERRIDE;
#endif
#if wxUSE_STREAMS
virtual bool Read(wxInputStream& str);
virtual bool Write(wxOutputStream &str) const;
#endif // wxUSE_STREAMS
virtual wxString GetType() const wxOVERRIDE { return wxT("double"); }
wxVariantData* Clone() const wxOVERRIDE { return new wxVariantDoubleData(m_value); }
DECLARE_WXANY_CONVERSION()
protected:
double m_value;
};
IMPLEMENT_TRIVIAL_WXANY_CONVERSION(double, wxVariantDoubleData)
bool wxVariantDoubleData::Eq(wxVariantData& data) const
{
wxASSERT_MSG( (data.GetType() == wxT("double")), wxT("wxVariantDoubleData::Eq: argument mismatch") );
wxVariantDoubleData& otherData = (wxVariantDoubleData&) data;
return wxIsSameDouble(otherData.m_value, m_value);
}
#if wxUSE_STD_IOSTREAM
bool wxVariantDoubleData::Write(wxSTD ostream& str) const
{
wxString s;
Write(s);
str << (const char*) s.mb_str();
return true;
}
#endif
bool wxVariantDoubleData::Write(wxString& str) const
{
str.Printf(wxT("%.14g"), m_value);
return true;
}
#if wxUSE_STD_IOSTREAM
bool wxVariantDoubleData::Read(wxSTD istream& str)
{
str >> m_value;
return true;
}
#endif
#if wxUSE_STREAMS
bool wxVariantDoubleData::Write(wxOutputStream& str) const
{
wxTextOutputStream s(str);
s.WriteDouble((double)m_value);
return true;
}
bool wxVariantDoubleData::Read(wxInputStream& str)
{
wxTextInputStream s(str);
m_value = (float)s.ReadDouble();
return true;
}
#endif // wxUSE_STREAMS
bool wxVariantDoubleData::Read(wxString& str)
{
m_value = wxAtof(str);
return true;
}
// wxVariant double code
wxVariant::wxVariant(double val, const wxString& name)
{
m_refData = new wxVariantDoubleData(val);
m_name = name;
}
bool wxVariant::operator== (double value) const
{
double thisValue;
if (!Convert(&thisValue))
return false;
return wxIsSameDouble(value, thisValue);
}
bool wxVariant::operator!= (double value) const
{
return (!((*this) == value));
}
void wxVariant::operator= (double value)
{
if (GetType() == wxT("double") &&
m_refData->GetRefCount() == 1)
{
((wxVariantDoubleData*)GetData())->SetValue(value);
}
else
{
UnRef();
m_refData = new wxVariantDoubleData(value);
}
}
double wxVariant::GetDouble() const
{
double value;
if (Convert(& value))
return value;
else
{
wxFAIL_MSG(wxT("Could not convert to a double number"));
return 0.0;
}
}
// -----------------------------------------------------------------
// wxVariantBoolData
// -----------------------------------------------------------------
class WXDLLIMPEXP_BASE wxVariantDataBool: public wxVariantData
{
public:
wxVariantDataBool() { m_value = 0; }
wxVariantDataBool(bool value) { m_value = value; }
inline bool GetValue() const { return m_value; }
inline void SetValue(bool value) { m_value = value; }
virtual bool Eq(wxVariantData& data) const wxOVERRIDE;
#if wxUSE_STD_IOSTREAM
virtual bool Write(wxSTD ostream& str) const wxOVERRIDE;
#endif
virtual bool Write(wxString& str) const wxOVERRIDE;
virtual bool Read(wxString& str) wxOVERRIDE;
#if wxUSE_STD_IOSTREAM
virtual bool Read(wxSTD istream& str) wxOVERRIDE;
#endif
#if wxUSE_STREAMS
virtual bool Read(wxInputStream& str);
virtual bool Write(wxOutputStream& str) const;
#endif // wxUSE_STREAMS
virtual wxString GetType() const wxOVERRIDE { return wxT("bool"); }
wxVariantData* Clone() const wxOVERRIDE { return new wxVariantDataBool(m_value); }
DECLARE_WXANY_CONVERSION()
protected:
bool m_value;
};
IMPLEMENT_TRIVIAL_WXANY_CONVERSION(bool, wxVariantDataBool)
bool wxVariantDataBool::Eq(wxVariantData& data) const
{
wxASSERT_MSG( (data.GetType() == wxT("bool")), wxT("wxVariantDataBool::Eq: argument mismatch") );
wxVariantDataBool& otherData = (wxVariantDataBool&) data;
return (otherData.m_value == m_value);
}
#if wxUSE_STD_IOSTREAM
bool wxVariantDataBool::Write(wxSTD ostream& str) const
{
wxString s;
Write(s);
str << (const char*) s.mb_str();
return true;
}
#endif
bool wxVariantDataBool::Write(wxString& str) const
{
str.Printf(wxT("%d"), (int) m_value);
return true;
}
#if wxUSE_STD_IOSTREAM
bool wxVariantDataBool::Read(wxSTD istream& WXUNUSED(str))
{
wxFAIL_MSG(wxT("Unimplemented"));
// str >> (long) m_value;
return false;
}
#endif
#if wxUSE_STREAMS
bool wxVariantDataBool::Write(wxOutputStream& str) const
{
wxTextOutputStream s(str);
s.Write8(m_value);
return true;
}
bool wxVariantDataBool::Read(wxInputStream& str)
{
wxTextInputStream s(str);
m_value = s.Read8() != 0;
return true;
}
#endif // wxUSE_STREAMS
bool wxVariantDataBool::Read(wxString& str)
{
m_value = (wxAtol(str) != 0);
return true;
}
// wxVariant ****
wxVariant::wxVariant(bool val, const wxString& name)
{
m_refData = new wxVariantDataBool(val);
m_name = name;
}
bool wxVariant::operator== (bool value) const
{
bool thisValue;
if (!Convert(&thisValue))
return false;
else
return (value == thisValue);
}
bool wxVariant::operator!= (bool value) const
{
return (!((*this) == value));
}
void wxVariant::operator= (bool value)
{
if (GetType() == wxT("bool") &&
m_refData->GetRefCount() == 1)
{
((wxVariantDataBool*)GetData())->SetValue(value);
}
else
{
UnRef();
m_refData = new wxVariantDataBool(value);
}
}
bool wxVariant::GetBool() const
{
bool value;
if (Convert(& value))
return value;
else
{
wxFAIL_MSG(wxT("Could not convert to a bool"));
return 0;
}
}
// -----------------------------------------------------------------
// wxVariantDataChar
// -----------------------------------------------------------------
class WXDLLIMPEXP_BASE wxVariantDataChar: public wxVariantData
{
public:
wxVariantDataChar() { m_value = 0; }
wxVariantDataChar(const wxUniChar& value) { m_value = value; }
inline wxUniChar GetValue() const { return m_value; }
inline void SetValue(const wxUniChar& value) { m_value = value; }
virtual bool Eq(wxVariantData& data) const wxOVERRIDE;
#if wxUSE_STD_IOSTREAM
virtual bool Read(wxSTD istream& str) wxOVERRIDE;
virtual bool Write(wxSTD ostream& str) const wxOVERRIDE;
#endif
virtual bool Read(wxString& str) wxOVERRIDE;
virtual bool Write(wxString& str) const wxOVERRIDE;
#if wxUSE_STREAMS
virtual bool Read(wxInputStream& str);
virtual bool Write(wxOutputStream& str) const;
#endif // wxUSE_STREAMS
virtual wxString GetType() const wxOVERRIDE { return wxT("char"); }
wxVariantData* Clone() const wxOVERRIDE { return new wxVariantDataChar(m_value); }
DECLARE_WXANY_CONVERSION()
protected:
wxUniChar m_value;
};
IMPLEMENT_TRIVIAL_WXANY_CONVERSION(wxUniChar, wxVariantDataChar)
bool wxVariantDataChar::Eq(wxVariantData& data) const
{
wxASSERT_MSG( (data.GetType() == wxT("char")), wxT("wxVariantDataChar::Eq: argument mismatch") );
wxVariantDataChar& otherData = (wxVariantDataChar&) data;
return (otherData.m_value == m_value);
}
#if wxUSE_STD_IOSTREAM
bool wxVariantDataChar::Write(wxSTD ostream& str) const
{
str << wxString(m_value);
return true;
}
#endif
bool wxVariantDataChar::Write(wxString& str) const
{
str = m_value;
return true;
}
#if wxUSE_STD_IOSTREAM
bool wxVariantDataChar::Read(wxSTD istream& WXUNUSED(str))
{
wxFAIL_MSG(wxT("Unimplemented"));
return false;
}
#endif
#if wxUSE_STREAMS
bool wxVariantDataChar::Write(wxOutputStream& str) const
{
wxTextOutputStream s(str);
// FIXME-UTF8: this should be just "s << m_value;" after removal of
// ANSI build and addition of wxUniChar to wxTextOutputStream:
s << (wxChar)m_value;
return true;
}
bool wxVariantDataChar::Read(wxInputStream& str)
{
wxTextInputStream s(str);
// FIXME-UTF8: this should be just "s >> m_value;" after removal of
// ANSI build and addition of wxUniChar to wxTextInputStream:
wxChar ch;
s >> ch;
m_value = ch;
return true;
}
#endif // wxUSE_STREAMS
bool wxVariantDataChar::Read(wxString& str)
{
m_value = str[0u];
return true;
}
wxVariant::wxVariant(const wxUniChar& val, const wxString& name)
{
m_refData = new wxVariantDataChar(val);
m_name = name;
}
wxVariant::wxVariant(char val, const wxString& name)
{
m_refData = new wxVariantDataChar(val);
m_name = name;
}
wxVariant::wxVariant(wchar_t val, const wxString& name)
{
m_refData = new wxVariantDataChar(val);
m_name = name;
}
bool wxVariant::operator==(const wxUniChar& value) const
{
wxUniChar thisValue;
if (!Convert(&thisValue))
return false;
else
return (value == thisValue);
}
wxVariant& wxVariant::operator=(const wxUniChar& value)
{
if (GetType() == wxT("char") &&
m_refData->GetRefCount() == 1)
{
((wxVariantDataChar*)GetData())->SetValue(value);
}
else
{
UnRef();
m_refData = new wxVariantDataChar(value);
}
return *this;
}
wxUniChar wxVariant::GetChar() const
{
wxUniChar value;
if (Convert(& value))
return value;
else
{
wxFAIL_MSG(wxT("Could not convert to a char"));
return wxUniChar(0);
}
}
// ----------------------------------------------------------------------------
// wxVariantDataString
// ----------------------------------------------------------------------------
class WXDLLIMPEXP_BASE wxVariantDataString: public wxVariantData
{
public:
wxVariantDataString() { }
wxVariantDataString(const wxString& value) { m_value = value; }
inline wxString GetValue() const { return m_value; }
inline void SetValue(const wxString& value) { m_value = value; }
virtual bool Eq(wxVariantData& data) const wxOVERRIDE;
#if wxUSE_STD_IOSTREAM
virtual bool Write(wxSTD ostream& str) const wxOVERRIDE;
#endif
virtual bool Read(wxString& str) wxOVERRIDE;
virtual bool Write(wxString& str) const wxOVERRIDE;
#if wxUSE_STD_IOSTREAM
virtual bool Read(wxSTD istream& WXUNUSED(str)) wxOVERRIDE { return false; }
#endif
#if wxUSE_STREAMS
virtual bool Read(wxInputStream& str);
virtual bool Write(wxOutputStream& str) const;
#endif // wxUSE_STREAMS
virtual wxString GetType() const wxOVERRIDE { return wxT("string"); }
wxVariantData* Clone() const wxOVERRIDE { return new wxVariantDataString(m_value); }
DECLARE_WXANY_CONVERSION()
protected:
wxString m_value;
};
IMPLEMENT_TRIVIAL_WXANY_CONVERSION(wxString, wxVariantDataString)
#if wxUSE_ANY
// This allows converting string literal wxAnys to string variants
wxVariantData* wxVariantDataFromConstCharPAny(const wxAny& any)
{
return new wxVariantDataString(any.As<const char*>());
}
wxVariantData* wxVariantDataFromConstWchar_tPAny(const wxAny& any)
{
return new wxVariantDataString(any.As<const wchar_t*>());
}
_REGISTER_WXANY_CONVERSION(const char*,
ConstCharP,
wxVariantDataFromConstCharPAny)
_REGISTER_WXANY_CONVERSION(const wchar_t*,
ConstWchar_tP,
wxVariantDataFromConstWchar_tPAny)
#endif
bool wxVariantDataString::Eq(wxVariantData& data) const
{
wxASSERT_MSG( (data.GetType() == wxT("string")), wxT("wxVariantDataString::Eq: argument mismatch") );
wxVariantDataString& otherData = (wxVariantDataString&) data;
return (otherData.m_value == m_value);
}
#if wxUSE_STD_IOSTREAM
bool wxVariantDataString::Write(wxSTD ostream& str) const
{
str << (const char*) m_value.mb_str();
return true;
}
#endif
bool wxVariantDataString::Write(wxString& str) const
{
str = m_value;
return true;
}
#if wxUSE_STREAMS
bool wxVariantDataString::Write(wxOutputStream& str) const
{
// why doesn't wxOutputStream::operator<< take "const wxString&"
wxTextOutputStream s(str);
s.WriteString(m_value);
return true;
}
bool wxVariantDataString::Read(wxInputStream& str)
{
wxTextInputStream s(str);
m_value = s.ReadLine();
return true;
}
#endif // wxUSE_STREAMS
bool wxVariantDataString::Read(wxString& str)
{
m_value = str;
return true;
}
// wxVariant ****
wxVariant::wxVariant(const wxString& val, const wxString& name)
{
m_refData = new wxVariantDataString(val);
m_name = name;
}
wxVariant::wxVariant(const char* val, const wxString& name)
{
m_refData = new wxVariantDataString(wxString(val));
m_name = name;
}
wxVariant::wxVariant(const wchar_t* val, const wxString& name)
{
m_refData = new wxVariantDataString(wxString(val));
m_name = name;
}
wxVariant::wxVariant(const wxCStrData& val, const wxString& name)
{
m_refData = new wxVariantDataString(val.AsString());
m_name = name;
}
wxVariant::wxVariant(const wxScopedCharBuffer& val, const wxString& name)
{
m_refData = new wxVariantDataString(wxString(val));
m_name = name;
}
wxVariant::wxVariant(const wxScopedWCharBuffer& val, const wxString& name)
{
m_refData = new wxVariantDataString(wxString(val));
m_name = name;
}
#if wxUSE_STD_STRING
wxVariant::wxVariant(const std::string& val, const wxString& name)
{
m_refData = new wxVariantDataString(wxString(val));
m_name = name;
}
wxVariant::wxVariant(const wxStdWideString& val, const wxString& name)
{
m_refData = new wxVariantDataString(wxString(val));
m_name = name;
}
#endif // wxUSE_STD_STRING
bool wxVariant::operator== (const wxString& value) const
{
wxString thisValue;
if (!Convert(&thisValue))
return false;
return value == thisValue;
}
bool wxVariant::operator!= (const wxString& value) const
{
return (!((*this) == value));
}
wxVariant& wxVariant::operator= (const wxString& value)
{
if (GetType() == wxT("string") &&
m_refData->GetRefCount() == 1)
{
((wxVariantDataString*)GetData())->SetValue(value);
}
else
{
UnRef();
m_refData = new wxVariantDataString(value);
}
return *this;
}
wxString wxVariant::GetString() const
{
wxString value;
if (!Convert(& value))
{
wxFAIL_MSG(wxT("Could not convert to a string"));
}
return value;
}
// ----------------------------------------------------------------------------
// wxVariantDataWxObjectPtr
// ----------------------------------------------------------------------------
class wxVariantDataWxObjectPtr: public wxVariantData
{
public:
wxVariantDataWxObjectPtr() { }
wxVariantDataWxObjectPtr(wxObject* value) { m_value = value; }
inline wxObject* GetValue() const { return m_value; }
inline void SetValue(wxObject* value) { m_value = value; }
virtual bool Eq(wxVariantData& data) const wxOVERRIDE;
#if wxUSE_STD_IOSTREAM
virtual bool Write(wxSTD ostream& str) const wxOVERRIDE;
#endif
virtual bool Write(wxString& str) const wxOVERRIDE;
#if wxUSE_STD_IOSTREAM
virtual bool Read(wxSTD istream& str) wxOVERRIDE;
#endif
virtual bool Read(wxString& str) wxOVERRIDE;
virtual wxString GetType() const wxOVERRIDE ;
virtual wxVariantData* Clone() const wxOVERRIDE { return new wxVariantDataWxObjectPtr(m_value); }
virtual wxClassInfo* GetValueClassInfo() wxOVERRIDE;
DECLARE_WXANY_CONVERSION()
protected:
wxObject* m_value;
};
IMPLEMENT_TRIVIAL_WXANY_CONVERSION(wxObject*, wxVariantDataWxObjectPtr)
bool wxVariantDataWxObjectPtr::Eq(wxVariantData& data) const
{
wxASSERT_MSG( data.GetType() == GetType(), wxT("wxVariantDataWxObjectPtr::Eq: argument mismatch") );
wxVariantDataWxObjectPtr& otherData = (wxVariantDataWxObjectPtr&) data;
return (otherData.m_value == m_value);
}
wxString wxVariantDataWxObjectPtr::GetType() const
{
wxString returnVal(wxT("wxObject*"));
if (m_value)
{
returnVal = m_value->GetClassInfo()->GetClassName();
returnVal += wxT("*");
}
return returnVal;
}
wxClassInfo* wxVariantDataWxObjectPtr::GetValueClassInfo()
{
wxClassInfo* returnVal=NULL;
if (m_value) returnVal = m_value->GetClassInfo();
return returnVal;
}
#if wxUSE_STD_IOSTREAM
bool wxVariantDataWxObjectPtr::Write(wxSTD ostream& str) const
{
wxString s;
Write(s);
str << (const char*) s.mb_str();
return true;
}
#endif
bool wxVariantDataWxObjectPtr::Write(wxString& str) const
{
str.Printf(wxT("%s(%p)"), GetType().c_str(), static_cast<void*>(m_value));
return true;
}
#if wxUSE_STD_IOSTREAM
bool wxVariantDataWxObjectPtr::Read(wxSTD istream& WXUNUSED(str))
{
// Not implemented
return false;
}
#endif
bool wxVariantDataWxObjectPtr::Read(wxString& WXUNUSED(str))
{
// Not implemented
return false;
}
// wxVariant
wxVariant::wxVariant( wxObject* val, const wxString& name)
{
m_refData = new wxVariantDataWxObjectPtr(val);
m_name = name;
}
bool wxVariant::operator== (wxObject* value) const
{
return (value == ((wxVariantDataWxObjectPtr*)GetData())->GetValue());
}
bool wxVariant::operator!= (wxObject* value) const
{
return (!((*this) == (wxObject*) value));
}
void wxVariant::operator= (wxObject* value)
{
UnRef();
m_refData = new wxVariantDataWxObjectPtr(value);
}
wxObject* wxVariant::GetWxObjectPtr() const
{
return (wxObject*) ((wxVariantDataWxObjectPtr*) m_refData)->GetValue();
}
// ----------------------------------------------------------------------------
// wxVariantDataVoidPtr
// ----------------------------------------------------------------------------
class wxVariantDataVoidPtr: public wxVariantData
{
public:
wxVariantDataVoidPtr() { }
wxVariantDataVoidPtr(void* value) { m_value = value; }
inline void* GetValue() const { return m_value; }
inline void SetValue(void* value) { m_value = value; }
virtual bool Eq(wxVariantData& data) const wxOVERRIDE;
#if wxUSE_STD_IOSTREAM
virtual bool Write(wxSTD ostream& str) const wxOVERRIDE;
#endif
virtual bool Write(wxString& str) const wxOVERRIDE;
#if wxUSE_STD_IOSTREAM
virtual bool Read(wxSTD istream& str) wxOVERRIDE;
#endif
virtual bool Read(wxString& str) wxOVERRIDE;
virtual wxString GetType() const wxOVERRIDE { return wxT("void*"); }
virtual wxVariantData* Clone() const wxOVERRIDE { return new wxVariantDataVoidPtr(m_value); }
DECLARE_WXANY_CONVERSION()
protected:
void* m_value;
};
IMPLEMENT_TRIVIAL_WXANY_CONVERSION(void*, wxVariantDataVoidPtr)
bool wxVariantDataVoidPtr::Eq(wxVariantData& data) const
{
wxASSERT_MSG( data.GetType() == wxT("void*"), wxT("wxVariantDataVoidPtr::Eq: argument mismatch") );
wxVariantDataVoidPtr& otherData = (wxVariantDataVoidPtr&) data;
return (otherData.m_value == m_value);
}
#if wxUSE_STD_IOSTREAM
bool wxVariantDataVoidPtr::Write(wxSTD ostream& str) const
{
wxString s;
Write(s);
str << (const char*) s.mb_str();
return true;
}
#endif
bool wxVariantDataVoidPtr::Write(wxString& str) const
{
str.Printf(wxT("%p"), m_value);
return true;
}
#if wxUSE_STD_IOSTREAM
bool wxVariantDataVoidPtr::Read(wxSTD istream& WXUNUSED(str))
{
// Not implemented
return false;
}
#endif
bool wxVariantDataVoidPtr::Read(wxString& WXUNUSED(str))
{
// Not implemented
return false;
}
// wxVariant
wxVariant::wxVariant( void* val, const wxString& name)
{
m_refData = new wxVariantDataVoidPtr(val);
m_name = name;
}
bool wxVariant::operator== (void* value) const
{
return (value == ((wxVariantDataVoidPtr*)GetData())->GetValue());
}
bool wxVariant::operator!= (void* value) const
{
return (!((*this) == (void*) value));
}
void wxVariant::operator= (void* value)
{
if (GetType() == wxT("void*") && (m_refData->GetRefCount() == 1))
{
((wxVariantDataVoidPtr*)GetData())->SetValue(value);
}
else
{
UnRef();
m_refData = new wxVariantDataVoidPtr(value);
}
}
void* wxVariant::GetVoidPtr() const
{
// handling this specially is convenient when working with COM, see #9873
if ( IsNull() )
return NULL;
wxASSERT( GetType() == wxT("void*") );
return (void*) ((wxVariantDataVoidPtr*) m_refData)->GetValue();
}
// ----------------------------------------------------------------------------
// wxVariantDataDateTime
// ----------------------------------------------------------------------------
#if wxUSE_DATETIME
class wxVariantDataDateTime: public wxVariantData
{
public:
wxVariantDataDateTime() { }
wxVariantDataDateTime(const wxDateTime& value) { m_value = value; }
inline wxDateTime GetValue() const { return m_value; }
inline void SetValue(const wxDateTime& value) { m_value = value; }
virtual bool Eq(wxVariantData& data) const wxOVERRIDE;
#if wxUSE_STD_IOSTREAM
virtual bool Write(wxSTD ostream& str) const wxOVERRIDE;
#endif
virtual bool Write(wxString& str) const wxOVERRIDE;
#if wxUSE_STD_IOSTREAM
virtual bool Read(wxSTD istream& str) wxOVERRIDE;
#endif
virtual bool Read(wxString& str) wxOVERRIDE;
virtual wxString GetType() const wxOVERRIDE { return wxT("datetime"); }
virtual wxVariantData* Clone() const wxOVERRIDE { return new wxVariantDataDateTime(m_value); }
DECLARE_WXANY_CONVERSION()
protected:
wxDateTime m_value;
};
IMPLEMENT_TRIVIAL_WXANY_CONVERSION(wxDateTime, wxVariantDataDateTime)
bool wxVariantDataDateTime::Eq(wxVariantData& data) const
{
wxASSERT_MSG( (data.GetType() == wxT("datetime")), wxT("wxVariantDataDateTime::Eq: argument mismatch") );
wxVariantDataDateTime& otherData = (wxVariantDataDateTime&) data;
return (otherData.m_value == m_value);
}
#if wxUSE_STD_IOSTREAM
bool wxVariantDataDateTime::Write(wxSTD ostream& str) const
{
wxString value;
Write( value );
str << value.c_str();
return true;
}
#endif
bool wxVariantDataDateTime::Write(wxString& str) const
{
if ( m_value.IsValid() )
str = m_value.Format();
else
str = wxS("Invalid");
return true;
}
#if wxUSE_STD_IOSTREAM
bool wxVariantDataDateTime::Read(wxSTD istream& WXUNUSED(str))
{
// Not implemented
return false;
}
#endif
bool wxVariantDataDateTime::Read(wxString& str)
{
if ( str == wxS("Invalid") )
{
m_value = wxInvalidDateTime;
return true;
}
wxString::const_iterator end;
return m_value.ParseDateTime(str, &end) && end == str.end();
}
// wxVariant
wxVariant::wxVariant(const wxDateTime& val, const wxString& name) // Date
{
m_refData = new wxVariantDataDateTime(val);
m_name = name;
}
bool wxVariant::operator== (const wxDateTime& value) const
{
wxDateTime thisValue;
if (!Convert(&thisValue))
return false;
return value.IsEqualTo(thisValue);
}
bool wxVariant::operator!= (const wxDateTime& value) const
{
return (!((*this) == value));
}
void wxVariant::operator= (const wxDateTime& value)
{
if (GetType() == wxT("datetime") &&
m_refData->GetRefCount() == 1)
{
((wxVariantDataDateTime*)GetData())->SetValue(value);
}
else
{
UnRef();
m_refData = new wxVariantDataDateTime(value);
}
}
wxDateTime wxVariant::GetDateTime() const
{
wxDateTime value;
if (!Convert(& value))
{
wxFAIL_MSG(wxT("Could not convert to a datetime"));
}
return value;
}
#endif // wxUSE_DATETIME
// ----------------------------------------------------------------------------
// wxVariantDataArrayString
// ----------------------------------------------------------------------------
class wxVariantDataArrayString: public wxVariantData
{
public:
wxVariantDataArrayString() { }
wxVariantDataArrayString(const wxArrayString& value) { m_value = value; }
wxArrayString GetValue() const { return m_value; }
void SetValue(const wxArrayString& value) { m_value = value; }
virtual bool Eq(wxVariantData& data) const wxOVERRIDE;
#if wxUSE_STD_IOSTREAM
virtual bool Write(wxSTD ostream& str) const wxOVERRIDE;
#endif
virtual bool Write(wxString& str) const wxOVERRIDE;
#if wxUSE_STD_IOSTREAM
virtual bool Read(wxSTD istream& str) wxOVERRIDE;
#endif
virtual bool Read(wxString& str) wxOVERRIDE;
virtual wxString GetType() const wxOVERRIDE { return wxT("arrstring"); }
virtual wxVariantData* Clone() const wxOVERRIDE { return new wxVariantDataArrayString(m_value); }
DECLARE_WXANY_CONVERSION()
protected:
wxArrayString m_value;
};
IMPLEMENT_TRIVIAL_WXANY_CONVERSION(wxArrayString, wxVariantDataArrayString)
bool wxVariantDataArrayString::Eq(wxVariantData& data) const
{
wxASSERT_MSG( data.GetType() == GetType(), wxT("wxVariantDataArrayString::Eq: argument mismatch") );
wxVariantDataArrayString& otherData = (wxVariantDataArrayString&) data;
return otherData.m_value == m_value;
}
#if wxUSE_STD_IOSTREAM
bool wxVariantDataArrayString::Write(wxSTD ostream& WXUNUSED(str)) const
{
// Not implemented
return false;
}
#endif
bool wxVariantDataArrayString::Write(wxString& str) const
{
size_t count = m_value.GetCount();
for ( size_t n = 0; n < count; n++ )
{
if ( n )
str += wxT(';');
str += m_value[n];
}
return true;
}
#if wxUSE_STD_IOSTREAM
bool wxVariantDataArrayString::Read(wxSTD istream& WXUNUSED(str))
{
// Not implemented
return false;
}
#endif
bool wxVariantDataArrayString::Read(wxString& str)
{
wxStringTokenizer tk(str, wxT(";"));
while ( tk.HasMoreTokens() )
{
m_value.Add(tk.GetNextToken());
}
return true;
}
// wxVariant
wxVariant::wxVariant(const wxArrayString& val, const wxString& name) // Strings
{
m_refData = new wxVariantDataArrayString(val);
m_name = name;
}
bool wxVariant::operator==(const wxArrayString& WXUNUSED(value)) const
{
wxFAIL_MSG( wxT("TODO") );
return false;
}
bool wxVariant::operator!=(const wxArrayString& value) const
{
return !(*this == value);
}
void wxVariant::operator=(const wxArrayString& value)
{
if (GetType() == wxT("arrstring") &&
m_refData->GetRefCount() == 1)
{
((wxVariantDataArrayString *)GetData())->SetValue(value);
}
else
{
UnRef();
m_refData = new wxVariantDataArrayString(value);
}
}
wxArrayString wxVariant::GetArrayString() const
{
if ( GetType() == wxT("arrstring") )
return ((wxVariantDataArrayString *)GetData())->GetValue();
return wxArrayString();
}
// ----------------------------------------------------------------------------
// wxVariantDataLongLong
// ----------------------------------------------------------------------------
#if wxUSE_LONGLONG
class WXDLLIMPEXP_BASE wxVariantDataLongLong : public wxVariantData
{
public:
wxVariantDataLongLong() { m_value = 0; }
wxVariantDataLongLong(wxLongLong value) { m_value = value; }
wxLongLong GetValue() const { return m_value; }
void SetValue(wxLongLong value) { m_value = value; }
virtual bool Eq(wxVariantData& data) const wxOVERRIDE;
virtual bool Read(wxString& str) wxOVERRIDE;
virtual bool Write(wxString& str) const wxOVERRIDE;
#if wxUSE_STD_IOSTREAM
virtual bool Read(wxSTD istream& str) wxOVERRIDE;
virtual bool Write(wxSTD ostream& str) const wxOVERRIDE;
#endif
#if wxUSE_STREAMS
virtual bool Read(wxInputStream& str);
virtual bool Write(wxOutputStream &str) const;
#endif // wxUSE_STREAMS
wxVariantData* Clone() const wxOVERRIDE
{
return new wxVariantDataLongLong(m_value);
}
virtual wxString GetType() const wxOVERRIDE { return wxS("longlong"); }
DECLARE_WXANY_CONVERSION()
protected:
wxLongLong m_value;
};
//
// wxLongLong type requires customized wxAny conversion code
//
#if wxUSE_ANY
#ifdef wxLongLong_t
bool wxVariantDataLongLong::GetAsAny(wxAny* any) const
{
*any = m_value.GetValue();
return true;
}
wxVariantData* wxVariantDataLongLong::VariantDataFactory(const wxAny& any)
{
return new wxVariantDataLongLong(any.As<wxLongLong_t>());
}
REGISTER_WXANY_CONVERSION(wxLongLong_t, wxVariantDataLongLong)
#else // if !defined(wxLongLong_t)
bool wxVariantDataLongLong::GetAsAny(wxAny* any) const
{
*any = m_value;
return true;
}
wxVariantData* wxVariantDataLongLong::VariantDataFactory(const wxAny& any)
{
return new wxVariantDataLongLong(any.As<wxLongLong>());
}
REGISTER_WXANY_CONVERSION(wxLongLong, wxVariantDataLongLong)
#endif // defined(wxLongLong_t)/!defined(wxLongLong_t)
#endif // wxUSE_ANY
bool wxVariantDataLongLong::Eq(wxVariantData& data) const
{
wxASSERT_MSG( (data.GetType() == wxS("longlong")),
"wxVariantDataLongLong::Eq: argument mismatch" );
wxVariantDataLongLong& otherData = (wxVariantDataLongLong&) data;
return (otherData.m_value == m_value);
}
#if wxUSE_STD_IOSTREAM
bool wxVariantDataLongLong::Write(wxSTD ostream& str) const
{
wxString s;
Write(s);
str << (const char*) s.mb_str();
return true;
}
#endif
bool wxVariantDataLongLong::Write(wxString& str) const
{
#ifdef wxLongLong_t
str.Printf(wxS("%lld"), m_value.GetValue());
return true;
#else
return false;
#endif
}
#if wxUSE_STD_IOSTREAM
bool wxVariantDataLongLong::Read(wxSTD istream& WXUNUSED(str))
{
wxFAIL_MSG(wxS("Unimplemented"));
return false;
}
#endif
#if wxUSE_STREAMS
bool wxVariantDataLongLong::Write(wxOutputStream& str) const
{
wxTextOutputStream s(str);
s.Write32(m_value.GetLo());
s.Write32(m_value.GetHi());
return true;
}
bool wxVariantDataLongLong::Read(wxInputStream& str)
{
wxTextInputStream s(str);
unsigned long lo = s.Read32();
long hi = s.Read32();
m_value = wxLongLong(hi, lo);
return true;
}
#endif // wxUSE_STREAMS
bool wxVariantDataLongLong::Read(wxString& str)
{
#ifdef wxLongLong_t
wxLongLong_t value_t;
if ( !str.ToLongLong(&value_t) )
return false;
m_value = value_t;
return true;
#else
return false;
#endif
}
// wxVariant
wxVariant::wxVariant(wxLongLong val, const wxString& name)
{
m_refData = new wxVariantDataLongLong(val);
m_name = name;
}
bool wxVariant::operator==(wxLongLong value) const
{
wxLongLong thisValue;
if ( !Convert(&thisValue) )
return false;
else
return (value == thisValue);
}
bool wxVariant::operator!=(wxLongLong value) const
{
return (!((*this) == value));
}
void wxVariant::operator=(wxLongLong value)
{
if ( GetType() == wxS("longlong") &&
m_refData->GetRefCount() == 1 )
{
((wxVariantDataLongLong*)GetData())->SetValue(value);
}
else
{
UnRef();
m_refData = new wxVariantDataLongLong(value);
}
}
wxLongLong wxVariant::GetLongLong() const
{
wxLongLong value;
if ( Convert(&value) )
{
return value;
}
else
{
wxFAIL_MSG(wxT("Could not convert to a long long"));
return 0;
}
}
#endif // wxUSE_LONGLONG
// ----------------------------------------------------------------------------
// wxVariantDataULongLong
// ----------------------------------------------------------------------------
#if wxUSE_LONGLONG
class WXDLLIMPEXP_BASE wxVariantDataULongLong : public wxVariantData
{
public:
wxVariantDataULongLong() { m_value = 0; }
wxVariantDataULongLong(wxULongLong value) { m_value = value; }
wxULongLong GetValue() const { return m_value; }
void SetValue(wxULongLong value) { m_value = value; }
virtual bool Eq(wxVariantData& data) const wxOVERRIDE;
virtual bool Read(wxString& str) wxOVERRIDE;
virtual bool Write(wxString& str) const wxOVERRIDE;
#if wxUSE_STD_IOSTREAM
virtual bool Read(wxSTD istream& str) wxOVERRIDE;
virtual bool Write(wxSTD ostream& str) const wxOVERRIDE;
#endif
#if wxUSE_STREAMS
virtual bool Read(wxInputStream& str);
virtual bool Write(wxOutputStream &str) const;
#endif // wxUSE_STREAMS
wxVariantData* Clone() const wxOVERRIDE
{
return new wxVariantDataULongLong(m_value);
}
virtual wxString GetType() const wxOVERRIDE { return wxS("ulonglong"); }
DECLARE_WXANY_CONVERSION()
protected:
wxULongLong m_value;
};
//
// wxULongLong type requires customized wxAny conversion code
//
#if wxUSE_ANY
#ifdef wxLongLong_t
bool wxVariantDataULongLong::GetAsAny(wxAny* any) const
{
*any = m_value.GetValue();
return true;
}
wxVariantData* wxVariantDataULongLong::VariantDataFactory(const wxAny& any)
{
return new wxVariantDataULongLong(any.As<wxULongLong_t>());
}
REGISTER_WXANY_CONVERSION(wxULongLong_t, wxVariantDataULongLong)
#else // if !defined(wxLongLong_t)
bool wxVariantDataULongLong::GetAsAny(wxAny* any) const
{
*any = m_value;
return true;
}
wxVariantData* wxVariantDataULongLong::VariantDataFactory(const wxAny& any)
{
return new wxVariantDataULongLong(any.As<wxULongLong>());
}
REGISTER_WXANY_CONVERSION(wxULongLong, wxVariantDataULongLong)
#endif // defined(wxLongLong_t)/!defined(wxLongLong_t)
#endif // wxUSE_ANY
bool wxVariantDataULongLong::Eq(wxVariantData& data) const
{
wxASSERT_MSG( (data.GetType() == wxS("ulonglong")),
"wxVariantDataULongLong::Eq: argument mismatch" );
wxVariantDataULongLong& otherData = (wxVariantDataULongLong&) data;
return (otherData.m_value == m_value);
}
#if wxUSE_STD_IOSTREAM
bool wxVariantDataULongLong::Write(wxSTD ostream& str) const
{
wxString s;
Write(s);
str << (const char*) s.mb_str();
return true;
}
#endif
bool wxVariantDataULongLong::Write(wxString& str) const
{
#ifdef wxLongLong_t
str.Printf(wxS("%llu"), m_value.GetValue());
return true;
#else
return false;
#endif
}
#if wxUSE_STD_IOSTREAM
bool wxVariantDataULongLong::Read(wxSTD istream& WXUNUSED(str))
{
wxFAIL_MSG(wxS("Unimplemented"));
return false;
}
#endif
#if wxUSE_STREAMS
bool wxVariantDataULongLong::Write(wxOutputStream& str) const
{
wxTextOutputStream s(str);
s.Write32(m_value.GetLo());
s.Write32(m_value.GetHi());
return true;
}
bool wxVariantDataULongLong::Read(wxInputStream& str)
{
wxTextInputStream s(str);
unsigned long lo = s.Read32();
long hi = s.Read32();
m_value = wxULongLong(hi, lo);
return true;
}
#endif // wxUSE_STREAMS
bool wxVariantDataULongLong::Read(wxString& str)
{
#ifdef wxLongLong_t
wxULongLong_t value_t;
if ( !str.ToULongLong(&value_t) )
return false;
m_value = value_t;
return true;
#else
return false;
#endif
}
// wxVariant
wxVariant::wxVariant(wxULongLong val, const wxString& name)
{
m_refData = new wxVariantDataULongLong(val);
m_name = name;
}
bool wxVariant::operator==(wxULongLong value) const
{
wxULongLong thisValue;
if ( !Convert(&thisValue) )
return false;
else
return (value == thisValue);
}
bool wxVariant::operator!=(wxULongLong value) const
{
return (!((*this) == value));
}
void wxVariant::operator=(wxULongLong value)
{
if ( GetType() == wxS("ulonglong") &&
m_refData->GetRefCount() == 1 )
{
((wxVariantDataULongLong*)GetData())->SetValue(value);
}
else
{
UnRef();
m_refData = new wxVariantDataULongLong(value);
}
}
wxULongLong wxVariant::GetULongLong() const
{
wxULongLong value;
if ( Convert(&value) )
{
return value;
}
else
{
wxFAIL_MSG(wxT("Could not convert to a long long"));
return 0;
}
}
#endif // wxUSE_LONGLONG
// ----------------------------------------------------------------------------
// wxVariantDataList
// ----------------------------------------------------------------------------
class WXDLLIMPEXP_BASE wxVariantDataList: public wxVariantData
{
public:
wxVariantDataList() {}
wxVariantDataList(const wxVariantList& list);
virtual ~wxVariantDataList();
wxVariantList& GetValue() { return m_value; }
void SetValue(const wxVariantList& value) ;
virtual bool Eq(wxVariantData& data) const wxOVERRIDE;
#if wxUSE_STD_IOSTREAM
virtual bool Write(wxSTD ostream& str) const wxOVERRIDE;
#endif
virtual bool Write(wxString& str) const wxOVERRIDE;
#if wxUSE_STD_IOSTREAM
virtual bool Read(wxSTD istream& str) wxOVERRIDE;
#endif
virtual bool Read(wxString& str) wxOVERRIDE;
virtual wxString GetType() const wxOVERRIDE { return wxT("list"); }
void Clear();
wxVariantData* Clone() const wxOVERRIDE { return new wxVariantDataList(m_value); }
DECLARE_WXANY_CONVERSION()
protected:
wxVariantList m_value;
};
#if wxUSE_ANY
//
// Convert to/from list of wxAnys
//
bool wxVariantDataList::GetAsAny(wxAny* any) const
{
wxAnyList dst;
wxVariantList::compatibility_iterator node = m_value.GetFirst();
while (node)
{
wxVariant* pVar = node->GetData();
dst.push_back(new wxAny(((const wxVariant&)*pVar)));
node = node->GetNext();
}
*any = dst;
return true;
}
wxVariantData* wxVariantDataList::VariantDataFactory(const wxAny& any)
{
wxAnyList src = any.As<wxAnyList>();
wxVariantList dst;
wxAnyList::compatibility_iterator node = src.GetFirst();
while (node)
{
wxAny* pAny = node->GetData();
dst.push_back(new wxVariant(*pAny));
node = node->GetNext();
}
return new wxVariantDataList(dst);
}
REGISTER_WXANY_CONVERSION(wxAnyList, wxVariantDataList)
#endif // wxUSE_ANY
wxVariantDataList::wxVariantDataList(const wxVariantList& list)
{
SetValue(list);
}
wxVariantDataList::~wxVariantDataList()
{
Clear();
}
void wxVariantDataList::SetValue(const wxVariantList& value)
{
Clear();
wxVariantList::compatibility_iterator node = value.GetFirst();
while (node)
{
wxVariant* var = node->GetData();
m_value.Append(new wxVariant(*var));
node = node->GetNext();
}
}
void wxVariantDataList::Clear()
{
wxVariantList::compatibility_iterator node = m_value.GetFirst();
while (node)
{
wxVariant* var = node->GetData();
delete var;
node = node->GetNext();
}
m_value.Clear();
}
bool wxVariantDataList::Eq(wxVariantData& data) const
{
wxASSERT_MSG( (data.GetType() == wxT("list")), wxT("wxVariantDataList::Eq: argument mismatch") );
wxVariantDataList& listData = (wxVariantDataList&) data;
wxVariantList::compatibility_iterator node1 = m_value.GetFirst();
wxVariantList::compatibility_iterator node2 = listData.GetValue().GetFirst();
while (node1 && node2)
{
wxVariant* var1 = node1->GetData();
wxVariant* var2 = node2->GetData();
if ((*var1) != (*var2))
return false;
node1 = node1->GetNext();
node2 = node2->GetNext();
}
if (node1 || node2) return false;
return true;
}
#if wxUSE_STD_IOSTREAM
bool wxVariantDataList::Write(wxSTD ostream& str) const
{
wxString s;
Write(s);
str << (const char*) s.mb_str();
return true;
}
#endif
bool wxVariantDataList::Write(wxString& str) const
{
str = wxEmptyString;
wxVariantList::compatibility_iterator node = m_value.GetFirst();
while (node)
{
wxVariant* var = node->GetData();
if (node != m_value.GetFirst())
str += wxT(" ");
wxString str1;
str += var->MakeString();
node = node->GetNext();
}
return true;
}
#if wxUSE_STD_IOSTREAM
bool wxVariantDataList::Read(wxSTD istream& WXUNUSED(str))
{
wxFAIL_MSG(wxT("Unimplemented"));
// TODO
return false;
}
#endif
bool wxVariantDataList::Read(wxString& WXUNUSED(str))
{
wxFAIL_MSG(wxT("Unimplemented"));
// TODO
return false;
}
// wxVariant
wxVariant::wxVariant(const wxVariantList& val, const wxString& name) // List of variants
{
m_refData = new wxVariantDataList(val);
m_name = name;
}
bool wxVariant::operator== (const wxVariantList& value) const
{
wxASSERT_MSG( (GetType() == wxT("list")), wxT("Invalid type for == operator") );
wxVariantDataList other(value);
return (GetData()->Eq(other));
}
bool wxVariant::operator!= (const wxVariantList& value) const
{
return (!((*this) == value));
}
void wxVariant::operator= (const wxVariantList& value)
{
if (GetType() == wxT("list") &&
m_refData->GetRefCount() == 1)
{
((wxVariantDataList*)GetData())->SetValue(value);
}
else
{
UnRef();
m_refData = new wxVariantDataList(value);
}
}
wxVariantList& wxVariant::GetList() const
{
wxASSERT( (GetType() == wxT("list")) );
return (wxVariantList&) ((wxVariantDataList*) m_refData)->GetValue();
}
// Make empty list
void wxVariant::NullList()
{
SetData(new wxVariantDataList());
}
// Append to list
void wxVariant::Append(const wxVariant& value)
{
wxVariantList& list = GetList();
list.Append(new wxVariant(value));
}
// Insert at front of list
void wxVariant::Insert(const wxVariant& value)
{
wxVariantList& list = GetList();
list.Insert(new wxVariant(value));
}
// Returns true if the variant is a member of the list
bool wxVariant::Member(const wxVariant& value) const
{
wxVariantList& list = GetList();
wxVariantList::compatibility_iterator node = list.GetFirst();
while (node)
{
wxVariant* other = node->GetData();
if (value == *other)
return true;
node = node->GetNext();
}
return false;
}
// Deletes the nth element of the list
bool wxVariant::Delete(size_t item)
{
wxVariantList& list = GetList();
wxASSERT_MSG( (item < list.GetCount()), wxT("Invalid index to Delete") );
wxVariantList::compatibility_iterator node = list.Item(item);
wxVariant* variant = node->GetData();
delete variant;
list.Erase(node);
return true;
}
// Clear list
void wxVariant::ClearList()
{
if (!IsNull() && (GetType() == wxT("list")))
{
((wxVariantDataList*) m_refData)->Clear();
}
else
{
if (!GetType().IsSameAs(wxT("list")))
UnRef();
m_refData = new wxVariantDataList;
}
}
// Treat a list variant as an array
wxVariant wxVariant::operator[] (size_t idx) const
{
wxASSERT_MSG( GetType() == wxT("list"), wxT("Invalid type for array operator") );
if (GetType() == wxT("list"))
{
wxVariantDataList* data = (wxVariantDataList*) m_refData;
wxASSERT_MSG( (idx < data->GetValue().GetCount()), wxT("Invalid index for array") );
return *(data->GetValue().Item(idx)->GetData());
}
return wxNullVariant;
}
wxVariant& wxVariant::operator[] (size_t idx)
{
// We can't return a reference to a variant for a string list, since the string
// is actually stored as a char*, not a variant.
wxASSERT_MSG( (GetType() == wxT("list")), wxT("Invalid type for array operator") );
wxVariantDataList* data = (wxVariantDataList*) m_refData;
wxASSERT_MSG( (idx < data->GetValue().GetCount()), wxT("Invalid index for array") );
return * (data->GetValue().Item(idx)->GetData());
}
// Return the number of elements in a list
size_t wxVariant::GetCount() const
{
wxASSERT_MSG( GetType() == wxT("list"), wxT("Invalid type for GetCount()") );
if (GetType() == wxT("list"))
{
wxVariantDataList* data = (wxVariantDataList*) m_refData;
return data->GetValue().GetCount();
}
return 0;
}
// ----------------------------------------------------------------------------
// Type conversion
// ----------------------------------------------------------------------------
bool wxVariant::Convert(long* value) const
{
wxString type(GetType());
if (type == wxS("double"))
*value = (long) (((wxVariantDoubleData*)GetData())->GetValue());
else if (type == wxS("long"))
*value = ((wxVariantDataLong*)GetData())->GetValue();
else if (type == wxS("bool"))
*value = (long) (((wxVariantDataBool*)GetData())->GetValue());
else if (type == wxS("string"))
*value = wxAtol(((wxVariantDataString*)GetData())->GetValue());
#if wxUSE_LONGLONG
else if (type == wxS("longlong"))
{
wxLongLong v = ((wxVariantDataLongLong*)GetData())->GetValue();
// Don't convert if return value would be vague
if ( v < LONG_MIN || v > LONG_MAX )
return false;
*value = v.ToLong();
}
else if (type == wxS("ulonglong"))
{
wxULongLong v = ((wxVariantDataULongLong*)GetData())->GetValue();
// Don't convert if return value would be vague
if ( v.GetHi() )
return false;
*value = (long) v.ToULong();
}
#endif
else
return false;
return true;
}
bool wxVariant::Convert(bool* value) const
{
wxString type(GetType());
if (type == wxT("double"))
*value = ((int) (((wxVariantDoubleData*)GetData())->GetValue()) != 0);
else if (type == wxT("long"))
*value = (((wxVariantDataLong*)GetData())->GetValue() != 0);
else if (type == wxT("bool"))
*value = ((wxVariantDataBool*)GetData())->GetValue();
else if (type == wxT("string"))
{
wxString val(((wxVariantDataString*)GetData())->GetValue());
val.MakeLower();
if (val == wxT("true") || val == wxT("yes") || val == wxT('1') )
*value = true;
else if (val == wxT("false") || val == wxT("no") || val == wxT('0') )
*value = false;
else
return false;
}
else
return false;
return true;
}
bool wxVariant::Convert(double* value) const
{
wxString type(GetType());
if (type == wxT("double"))
*value = ((wxVariantDoubleData*)GetData())->GetValue();
else if (type == wxT("long"))
*value = (double) (((wxVariantDataLong*)GetData())->GetValue());
else if (type == wxT("bool"))
*value = (double) (((wxVariantDataBool*)GetData())->GetValue());
else if (type == wxT("string"))
*value = (double) wxAtof(((wxVariantDataString*)GetData())->GetValue());
#if wxUSE_LONGLONG
else if (type == wxS("longlong"))
{
*value = ((wxVariantDataLongLong*)GetData())->GetValue().ToDouble();
}
else if (type == wxS("ulonglong"))
{
*value = ((wxVariantDataULongLong*)GetData())->GetValue().ToDouble();
}
#endif
else
return false;
return true;
}
bool wxVariant::Convert(wxUniChar* value) const
{
wxString type(GetType());
if (type == wxT("char"))
*value = ((wxVariantDataChar*)GetData())->GetValue();
else if (type == wxT("long"))
*value = (char) (((wxVariantDataLong*)GetData())->GetValue());
else if (type == wxT("bool"))
*value = (char) (((wxVariantDataBool*)GetData())->GetValue());
else if (type == wxS("string"))
{
// Also accept strings of length 1
const wxString& str = (((wxVariantDataString*)GetData())->GetValue());
if ( str.length() == 1 )
*value = str[0];
else
return false;
}
else
return false;
return true;
}
bool wxVariant::Convert(char* value) const
{
wxUniChar ch;
if ( !Convert(&ch) )
return false;
*value = ch;
return true;
}
bool wxVariant::Convert(wchar_t* value) const
{
wxUniChar ch;
if ( !Convert(&ch) )
return false;
*value = ch;
return true;
}
bool wxVariant::Convert(wxString* value) const
{
*value = MakeString();
return true;
}
#if wxUSE_LONGLONG
bool wxVariant::Convert(wxLongLong* value) const
{
wxString type(GetType());
if (type == wxS("longlong"))
*value = ((wxVariantDataLongLong*)GetData())->GetValue();
else if (type == wxS("long"))
*value = ((wxVariantDataLong*)GetData())->GetValue();
else if (type == wxS("string"))
{
wxString s = ((wxVariantDataString*)GetData())->GetValue();
#ifdef wxLongLong_t
wxLongLong_t value_t;
if ( !s.ToLongLong(&value_t) )
return false;
*value = value_t;
#else
long l_value;
if ( !s.ToLong(&l_value) )
return false;
*value = l_value;
#endif
}
else if (type == wxS("bool"))
*value = (long) (((wxVariantDataBool*)GetData())->GetValue());
else if (type == wxS("double"))
{
value->Assign(((wxVariantDoubleData*)GetData())->GetValue());
}
else if (type == wxS("ulonglong"))
*value = ((wxVariantDataULongLong*)GetData())->GetValue();
else
return false;
return true;
}
bool wxVariant::Convert(wxULongLong* value) const
{
wxString type(GetType());
if (type == wxS("ulonglong"))
*value = ((wxVariantDataULongLong*)GetData())->GetValue();
else if (type == wxS("long"))
*value = ((wxVariantDataLong*)GetData())->GetValue();
else if (type == wxS("string"))
{
wxString s = ((wxVariantDataString*)GetData())->GetValue();
#ifdef wxLongLong_t
wxULongLong_t value_t;
if ( !s.ToULongLong(&value_t) )
return false;
*value = value_t;
#else
unsigned long l_value;
if ( !s.ToULong(&l_value) )
return false;
*value = l_value;
#endif
}
else if (type == wxS("bool"))
*value = (long) (((wxVariantDataBool*)GetData())->GetValue());
else if (type == wxS("double"))
{
double value_d = ((wxVariantDoubleData*)GetData())->GetValue();
if ( value_d < 0.0 )
return false;
#ifdef wxLongLong_t
*value = (wxULongLong_t) value_d;
#else
wxLongLong temp;
temp.Assign(value_d);
*value = temp;
#endif
}
else if (type == wxS("longlong"))
*value = ((wxVariantDataLongLong*)GetData())->GetValue();
else
return false;
return true;
}
#endif // wxUSE_LONGLONG
#if wxUSE_DATETIME
bool wxVariant::Convert(wxDateTime* value) const
{
wxString type(GetType());
if (type == wxT("datetime"))
{
*value = ((wxVariantDataDateTime*)GetData())->GetValue();
return true;
}
// Fallback to string conversion
wxString val;
if ( !Convert(&val) )
return false;
// Try to parse this as either date and time, only date or only time
// checking that the entire string was parsed
wxString::const_iterator end;
if ( value->ParseDateTime(val, &end) && end == val.end() )
return true;
if ( value->ParseDate(val, &end) && end == val.end() )
return true;
if ( value->ParseTime(val, &end) && end == val.end() )
return true;
return false;
}
#endif // wxUSE_DATETIME
#endif // wxUSE_VARIANT