From cde8f9b84c967d5c8a0c7a761cf2768d5a68658d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=D0=9F=D0=B5=D0=BB=D0=B8=D0=BF=D0=B5=D0=BD=D0=BA=D0=BE=20?= =?UTF-8?q?=D0=98=D0=B2=D0=B0=D0=BD?= Date: Fri, 15 Apr 2016 08:04:44 +0000 Subject: [PATCH] git-svn-id: svn://db.shs.com.ru/pip@189 12ceb7fc-bf1f-11e4-8940-5bc7170c53b5 --- src/core/pibitarray.h | 2 + src/core/pibytearray.h | 4 + src/core/pivariant.cpp | 460 +++++++++++++++++++--------------------- src/core/pivariant.h | 370 ++++++++++++++++++++------------ src/thread/pithread.cpp | 8 +- 5 files changed, 471 insertions(+), 373 deletions(-) diff --git a/src/core/pibitarray.h b/src/core/pibitarray.h index 6e44222b..e6d1c2cb 100755 --- a/src/core/pibitarray.h +++ b/src/core/pibitarray.h @@ -23,6 +23,8 @@ #include "picontainers.h" class PIP_EXPORT PIBitArray { + friend PIByteArray & operator <<(PIByteArray & s, const PIBitArray & v); + friend PIByteArray & operator >>(PIByteArray & s, PIBitArray & v); public: PIBitArray(const int & size = 0) {resize(size);} PIBitArray(uchar val) {resize(sizeof(val) * 8); data_[0] = val;} diff --git a/src/core/pibytearray.h b/src/core/pibytearray.h index 71baf05b..d76221db 100755 --- a/src/core/pibytearray.h +++ b/src/core/pibytearray.h @@ -180,6 +180,8 @@ inline PIByteArray & operator <<(PIByteArray & s, const PIVector & v) {s << i template inline PIByteArray & operator <<(PIByteArray & s, const PIList & v) {s << int(v.size_s()); for (uint i = 0; i < v.size(); ++i) s << v[i]; return s;} //! \relatesalso PIByteArray \brief Store operator +inline PIByteArray & operator <<(PIByteArray & s, const PIBitArray & v) {s << v.size_ << v.data_; return s;} +//! \relatesalso PIByteArray \brief Store operator template inline PIByteArray & operator <<(PIByteArray & s, const PIDeque & v) {s << int(v.size_s()); for (uint i = 0; i < v.size(); ++i) s << v[i]; return s;} #ifdef PIP_BYTEARRAY_STREAM_ANY_TYPE @@ -234,6 +236,8 @@ inline PIByteArray & operator >>(PIByteArray & s, PIList & v) {assert(s.size_ //! \relatesalso PIByteArray \brief Restore operator template inline PIByteArray & operator >>(PIByteArray & s, PIDeque & v) {assert(s.size_s() >= 4); int sz; s >> sz; v.resize(sz); for (int i = 0; i < sz; ++i) s >> v[i]; return s;} +//! \relatesalso PIByteArray \brief Restore operator +inline PIByteArray & operator >>(PIByteArray & s, PIBitArray & v) {assert(s.size_s() >= 8); s >> v.size_ >> v.data_; return s;} // //! \relatesalso PIByteArray \brief Restore operator //template //inline PIByteArray & operator >>(PIByteArray & s, PIMap & v) {assert(s.size_s() >= 4); int sz; s >> sz; v.resize(sz); for (int i = 0; i < sz; ++i) s >> v[i]; return s;} diff --git a/src/core/pivariant.cpp b/src/core/pivariant.cpp index 8df7ac70..aa0f150b 100755 --- a/src/core/pivariant.cpp +++ b/src/core/pivariant.cpp @@ -48,55 +48,24 @@ * \endcode * */ +PIMap * __PIVariantInfoStorage__::map = 0; + PIVariant::PIVariant() { - type_ = PIVariant::Invalid; - memset(_vraw, 0, __PIVARIANT_UNION_SIZE__); + _type = PIVariant::Invalid; } PIVariant & PIVariant::operator =(const PIVariant & v) { - type_ = v.type_; - memcpy(_vraw, v._vraw, __PIVARIANT_UNION_SIZE__); - _vbytearray = v._vbytearray; - _vbitarray = v._vbitarray; - _vstring = v._vstring; - _vstringlist = v._vstringlist; - _vcustom = v._vcustom; + _type = v._type; + _content = v._content; + _info = v._info; return *this; } bool PIVariant::operator ==(const PIVariant & v) const { - if (type_ != v.type_) return false; - switch (type_) { - case PIVariant::Bool: - case PIVariant::Char: - case PIVariant::UChar: - case PIVariant::Short: - case PIVariant::UShort: - case PIVariant::Int: - case PIVariant::UInt: - case PIVariant::Long: - case PIVariant::ULong: return _vint == v._vint; - case PIVariant::LLong: - case PIVariant::ULLong: return _vllong == v._vllong; - case PIVariant::Float: return _vfloat == v._vfloat; - case PIVariant::Double: return _vdouble == v._vdouble; - case PIVariant::LDouble: return _vldouble == v._vldouble; - case PIVariant::Complexd: return _vcomplexd == _vvcomplexd(v); - case PIVariant::Complexld: return _vcomplexld == _vvcomplexld(v); - case PIVariant::BitArray: return _vbitarray == v._vbitarray; - case PIVariant::ByteArray: return _vbytearray == v._vbytearray; - case PIVariant::String: return _vstring == v._vstring; - case PIVariant::StringList: return _vstringlist == v._vstringlist; - case PIVariant::Time: return _vtime == _vvtime(v); - case PIVariant::Date: return _vdate == _vvdate(v); - case PIVariant::DateTime: return _vdatetime == _vvdatetime(v); - case PIVariant::SystemTime: return _vsystime == _vvsystime(v); - default: break; - }; - return false; + return (_type == v._type) && (_content == v._content); } @@ -106,12 +75,12 @@ PIVariant::Type PIVariant::typeFromName(const PIString & tname) { if (s == "char" || s == "sbyte") return PIVariant::Char; if (s == "short" || s == "shortint" || s == "signedshort" || s == "signedshortint" || s == "sword") return PIVariant::Short; if (s == "int" || s == "signed" || s == "signedint") return PIVariant::Int; - if (s == "long" || s == "longint" || s == "signedlong" || s == "signedlongint" || s == "sdword") return PIVariant::Long; + if (s == "long" || s == "longint" || s == "signedlong" || s == "signedlongint" || s == "sdword") return PIVariant::Int; if (s == "llong" || s == "longlong" || s == "longlongint" || s == "signedlonglong" || s == "signedlonglongint" || s == "sqword") return PIVariant::LLong; if (s == "uchar" || s == "byte") return PIVariant::UChar; if (s == "ushort" || s == "unsignedshort" || s == "unsignedshortint" || s == "word") return PIVariant::UShort; if (s == "uint" || s == "unsigned" || s == "unsignedint") return PIVariant::UInt; - if (s == "ulong" || s == "unsignedlong" || s == "unsignedlongint" || s == "dword") return PIVariant::ULong; + if (s == "ulong" || s == "unsignedlong" || s == "unsignedlongint" || s == "dword") return PIVariant::UInt; if (s == "ullong" || s == "unsignedlonglong" || s == "unsignedlonglongint" || s == "qword") return PIVariant::ULLong; if (s == "float") return PIVariant::Float; if (s == "double" || s == "real") return PIVariant::Double; @@ -131,6 +100,13 @@ PIVariant::Type PIVariant::typeFromName(const PIString & tname) { } +PIString PIVariant::typeName() const { + if ((_type == Custom) && _info) + return _info->typeName; + return typeName(_type); +} + + PIString PIVariant::typeName(PIVariant::Type type) { switch (type) { case PIVariant::Bool: return "Bool"; @@ -140,8 +116,6 @@ PIString PIVariant::typeName(PIVariant::Type type) { case PIVariant::UShort: return "UShort"; case PIVariant::Int: return "Int"; case PIVariant::UInt: return "UInt"; - case PIVariant::Long: return "Long"; - case PIVariant::ULong: return "ULong"; case PIVariant::LLong: return "LLong"; case PIVariant::ULLong: return "ULLong"; case PIVariant::Float: return "Float"; @@ -171,25 +145,26 @@ PIString PIVariant::typeName(PIVariant::Type type) { * otherwise returns \a PIString::toBool() of first string. \n * In case of other types returns \b false. */ bool PIVariant::toBool() const { - switch (type_) { - case PIVariant::Bool: - case PIVariant::Char: - case PIVariant::UChar: - case PIVariant::Short: - case PIVariant::UShort: - case PIVariant::Int: - case PIVariant::UInt: - case PIVariant::Long: - case PIVariant::ULong: return _vint != 0; - case PIVariant::LLong: - case PIVariant::ULLong: return _vllong != 0; - case PIVariant::Float: return _vfloat != 0; - case PIVariant::Double: return _vdouble != 0; - case PIVariant::LDouble: return _vldouble != 0; - case PIVariant::Complexd: return _vcomplexd.real() != 0; - case PIVariant::Complexld: return _vcomplexld.real() != 0; - case PIVariant::String: return _vstring.toBool(); - case PIVariant::StringList: if (_vstringlist.isEmpty()) return false; return _vstringlist.front().toBool(); + PIByteArray ba(_content); + switch (_type) { + case PIVariant::Bool: {bool r; ba >> r; return r;} + case PIVariant::Char: {char r; ba >> r; return r != 0;} + case PIVariant::UChar: {uchar r; ba >> r; return r != 0;} + case PIVariant::Short: {short r; ba >> r; return r != 0;} + case PIVariant::UShort: {ushort r; ba >> r; return r != 0;} + case PIVariant::Int: {int r; ba >> r; return r != 0;} + case PIVariant::UInt: {uint r; ba >> r; return r != 0;} + case PIVariant::LLong: {llong r; ba >> r; return r != 0;} + case PIVariant::ULLong: {ullong r; ba >> r; return r != 0;} + case PIVariant::Float: {float r; ba >> r; return r > 0.f;} + case PIVariant::Double: {double r; ba >> r; return r > 0.;} + case PIVariant::LDouble: {ldouble r; ba >> r; return r > 0.;} + case PIVariant::Complexd: {complexd r; ba >> r; return r.real() != 0;} + case PIVariant::Complexld: {complexld r; ba >> r; return r.real() != 0;} + case PIVariant::String: {PIString r; ba >> r; return r.toBool();} + case PIVariant::StringList: {PIStringList r; ba >> r; if (r.isEmpty()) return false; return r.front().toBool();} + case PIVariant::Custom: + return getAsValue(*this); default: break; } return false; @@ -204,25 +179,26 @@ bool PIVariant::toBool() const { * otherwise returns \a PIString::toInt() of first string. \n * In case of other types returns \b 0. */ int PIVariant::toInt() const { - switch (type_) { - case PIVariant::Bool: - case PIVariant::Char: - case PIVariant::UChar: - case PIVariant::Short: - case PIVariant::UShort: - case PIVariant::Int: - case PIVariant::UInt: - case PIVariant::Long: - case PIVariant::ULong: return _vint; - case PIVariant::LLong: - case PIVariant::ULLong: return _vllong; - case PIVariant::Float: return _vfloat; - case PIVariant::Double: return _vdouble; - case PIVariant::LDouble: return _vldouble; - case PIVariant::Complexd: return _vcomplexd.real(); - case PIVariant::Complexld: return _vcomplexld.real(); - case PIVariant::String: return _vstring.toInt(); - case PIVariant::StringList: if (_vstringlist.isEmpty()) return 0; return _vstringlist.front().toInt(); + PIByteArray ba(_content); + switch (_type) { + case PIVariant::Bool: {bool r; ba >> r; return r;} + case PIVariant::Char: {char r; ba >> r; return r;} + case PIVariant::UChar: {uchar r; ba >> r; return r;} + case PIVariant::Short: {short r; ba >> r; return r;} + case PIVariant::UShort: {ushort r; ba >> r; return r;} + case PIVariant::Int: {int r; ba >> r; return r;} + case PIVariant::UInt: {uint r; ba >> r; return r;} + case PIVariant::LLong: {llong r; ba >> r; return r;} + case PIVariant::ULLong: {ullong r; ba >> r; return r;} + case PIVariant::Float: {float r; ba >> r; return r;} + case PIVariant::Double: {double r; ba >> r; return r;} + case PIVariant::LDouble: {ldouble r; ba >> r; return r;} + case PIVariant::Complexd: {complexd r; ba >> r; return r.real();} + case PIVariant::Complexld: {complexld r; ba >> r; return r.real();} + case PIVariant::String: {PIString r; ba >> r; return r.toInt();} + case PIVariant::StringList: {PIStringList r; ba >> r; if (r.isEmpty()) return 0; return r.front().toInt();} + case PIVariant::Custom: + return getAsValue(*this); default: break; } return 0; @@ -236,26 +212,26 @@ int PIVariant::toInt() const { * otherwise returns \a PIString::toLLong() of first string. \n * In case of other types returns \b 0L. */ llong PIVariant::toLLong() const { - switch (type_) { - case PIVariant::Bool: - case PIVariant::Char: - case PIVariant::UChar: - case PIVariant::Short: - case PIVariant::UShort: - case PIVariant::Int: - case PIVariant::UInt: - case PIVariant::Long: - case PIVariant::ULong: return _vint; - case PIVariant::LLong: - case PIVariant::ULLong: return _vllong; - case PIVariant::Float: return _vfloat; - case PIVariant::Double: return _vdouble; - case PIVariant::LDouble: return _vldouble; - case PIVariant::Complexd: return _vcomplexd.real(); - case PIVariant::Complexld: return _vcomplexld.real(); - case PIVariant::String: return _vstring.toLLong(); - case PIVariant::StringList: if (_vstringlist.isEmpty()) return 0L; return _vstringlist.front().toLLong(); - default: break; + PIByteArray ba(_content); + switch (_type) { + case PIVariant::Bool: {bool r; ba >> r; return r;} + case PIVariant::Char: {char r; ba >> r; return r;} + case PIVariant::UChar: {uchar r; ba >> r; return r;} + case PIVariant::Short: {short r; ba >> r; return r;} + case PIVariant::UShort: {ushort r; ba >> r; return r;} + case PIVariant::Int: {int r; ba >> r; return r;} + case PIVariant::UInt: {uint r; ba >> r; return r;} + case PIVariant::LLong: {llong r; ba >> r; return r;} + case PIVariant::ULLong: {ullong r; ba >> r; return r;} + case PIVariant::Float: {float r; ba >> r; return r;} + case PIVariant::Double: {double r; ba >> r; return r;} + case PIVariant::LDouble: {ldouble r; ba >> r; return r;} + case PIVariant::Complexd: {complexd r; ba >> r; return r.real();} + case PIVariant::Complexld: {complexld r; ba >> r; return r.real();} + case PIVariant::String: {PIString r; ba >> r; return r.toLLong();} + case PIVariant::StringList: {PIStringList r; ba >> r; if (r.isEmpty()) return 0L; return r.front().toLLong();} + case PIVariant::Custom: + return getAsValue(*this); } return 0L; } @@ -268,26 +244,26 @@ llong PIVariant::toLLong() const { * otherwise returns \a PIString::toFloat() of first string. \n * In case of other types returns \b 0.f. */ float PIVariant::toFloat() const { - switch (type_) { - case PIVariant::Bool: - case PIVariant::Char: - case PIVariant::UChar: - case PIVariant::Short: - case PIVariant::UShort: - case PIVariant::Int: - case PIVariant::UInt: - case PIVariant::Long: - case PIVariant::ULong: return _vint; - case PIVariant::LLong: - case PIVariant::ULLong: return _vllong; - case PIVariant::Float: return _vfloat; - case PIVariant::Double: return _vdouble; - case PIVariant::LDouble: return _vldouble; - case PIVariant::Complexd: return _vcomplexd.real(); - case PIVariant::Complexld: return _vcomplexld.real(); - case PIVariant::String: return _vstring.toFloat(); - case PIVariant::StringList: if (_vstringlist.isEmpty()) return 0.f; return _vstringlist.front().toFloat(); - default: break; + PIByteArray ba(_content); + switch (_type) { + case PIVariant::Bool: {bool r; ba >> r; return r;} + case PIVariant::Char: {char r; ba >> r; return r;} + case PIVariant::UChar: {uchar r; ba >> r; return r;} + case PIVariant::Short: {short r; ba >> r; return r;} + case PIVariant::UShort: {ushort r; ba >> r; return r;} + case PIVariant::Int: {int r; ba >> r; return r;} + case PIVariant::UInt: {uint r; ba >> r; return r;} + case PIVariant::LLong: {llong r; ba >> r; return r;} + case PIVariant::ULLong: {ullong r; ba >> r; return r;} + case PIVariant::Float: {float r; ba >> r; return r;} + case PIVariant::Double: {double r; ba >> r; return r;} + case PIVariant::LDouble: {ldouble r; ba >> r; return r;} + case PIVariant::Complexd: {complexd r; ba >> r; return r.real();} + case PIVariant::Complexld: {complexld r; ba >> r; return r.real();} + case PIVariant::String: {PIString r; ba >> r; return r.toFloat();} + case PIVariant::StringList: {PIStringList r; ba >> r; if (r.isEmpty()) return 0.f; return r.front().toFloat();} + case PIVariant::Custom: + return getAsValue(*this); } return 0.f; } @@ -300,26 +276,26 @@ float PIVariant::toFloat() const { * otherwise returns \a PIString::toDouble() of first string. \n * In case of other types returns \b 0.. */ double PIVariant::toDouble() const { - switch (type_) { - case PIVariant::Bool: - case PIVariant::Char: - case PIVariant::UChar: - case PIVariant::Short: - case PIVariant::UShort: - case PIVariant::Int: - case PIVariant::UInt: - case PIVariant::Long: - case PIVariant::ULong: return _vint; - case PIVariant::LLong: - case PIVariant::ULLong: return _vllong; - case PIVariant::Float: return _vfloat; - case PIVariant::Double: return _vdouble; - case PIVariant::LDouble: return _vldouble; - case PIVariant::Complexd: return _vcomplexd.real(); - case PIVariant::Complexld: return _vcomplexld.real(); - case PIVariant::String: return _vstring.toDouble(); - case PIVariant::StringList: if (_vstringlist.isEmpty()) return 0.; return _vstringlist.front().toDouble(); - default: break; + PIByteArray ba(_content); + switch (_type) { + case PIVariant::Bool: {bool r; ba >> r; return r;} + case PIVariant::Char: {char r; ba >> r; return r;} + case PIVariant::UChar: {uchar r; ba >> r; return r;} + case PIVariant::Short: {short r; ba >> r; return r;} + case PIVariant::UShort: {ushort r; ba >> r; return r;} + case PIVariant::Int: {int r; ba >> r; return r;} + case PIVariant::UInt: {uint r; ba >> r; return r;} + case PIVariant::LLong: {llong r; ba >> r; return r;} + case PIVariant::ULLong: {ullong r; ba >> r; return r;} + case PIVariant::Float: {float r; ba >> r; return r;} + case PIVariant::Double: {double r; ba >> r; return r;} + case PIVariant::LDouble: {ldouble r; ba >> r; return r;} + case PIVariant::Complexd: {complexd r; ba >> r; return r.real();} + case PIVariant::Complexld: {complexld r; ba >> r; return r.real();} + case PIVariant::String: {PIString r; ba >> r; return r.toDouble();} + case PIVariant::StringList: {PIStringList r; ba >> r; if (r.isEmpty()) return 0.; return r.front().toDouble();} + case PIVariant::Custom: + return getAsValue(*this); } return 0.; } @@ -332,26 +308,26 @@ double PIVariant::toDouble() const { * otherwise returns \a PIString::toLDouble() of first string. \n * In case of other types returns \b 0.. */ ldouble PIVariant::toLDouble() const { - switch (type_) { - case PIVariant::Bool: - case PIVariant::Char: - case PIVariant::UChar: - case PIVariant::Short: - case PIVariant::UShort: - case PIVariant::Int: - case PIVariant::UInt: - case PIVariant::Long: - case PIVariant::ULong: return _vint; - case PIVariant::LLong: - case PIVariant::ULLong: return _vllong; - case PIVariant::Float: return _vfloat; - case PIVariant::Double: return _vdouble; - case PIVariant::LDouble: return _vldouble; - case PIVariant::Complexd: return _vcomplexd.real(); - case PIVariant::Complexld: return _vcomplexld.real(); - case PIVariant::String: return _vstring.toLDouble(); - case PIVariant::StringList: if (_vstringlist.isEmpty()) return 0.; return _vstringlist.front().toLDouble(); - default: break; + PIByteArray ba(_content); + switch (_type) { + case PIVariant::Bool: {bool r; ba >> r; return r;} + case PIVariant::Char: {char r; ba >> r; return r;} + case PIVariant::UChar: {uchar r; ba >> r; return r;} + case PIVariant::Short: {short r; ba >> r; return r;} + case PIVariant::UShort: {ushort r; ba >> r; return r;} + case PIVariant::Int: {int r; ba >> r; return r;} + case PIVariant::UInt: {uint r; ba >> r; return r;} + case PIVariant::LLong: {llong r; ba >> r; return r;} + case PIVariant::ULLong: {ullong r; ba >> r; return r;} + case PIVariant::Float: {float r; ba >> r; return r;} + case PIVariant::Double: {double r; ba >> r; return r;} + case PIVariant::LDouble: {ldouble r; ba >> r; return r;} + case PIVariant::Complexd: {complexd r; ba >> r; return r.real();} + case PIVariant::Complexld: {complexld r; ba >> r; return r.real();} + case PIVariant::String: {PIString r; ba >> r; return r.toLDouble();} + case PIVariant::StringList: {PIStringList r; ba >> r; if (r.isEmpty()) return 0.; return r.front().toLDouble();} + case PIVariant::Custom: + return getAsValue(*this); } return 0.; } @@ -364,26 +340,26 @@ ldouble PIVariant::toLDouble() const { * otherwise returns \a PIString::toDouble() of first string. \n * In case of other types returns \b 0.. */ complexd PIVariant::toComplexd() const { - switch (type_) { - case PIVariant::Bool: - case PIVariant::Char: - case PIVariant::UChar: - case PIVariant::Short: - case PIVariant::UShort: - case PIVariant::Int: - case PIVariant::UInt: - case PIVariant::Long: - case PIVariant::ULong: return _vint; - case PIVariant::LLong: - case PIVariant::ULLong: return _vllong; - case PIVariant::Float: return _vfloat; - case PIVariant::Double: return _vdouble; - case PIVariant::LDouble: return _vldouble; - case PIVariant::Complexd: return _vcomplexd.real(); - case PIVariant::Complexld: return _vcomplexld.real(); - case PIVariant::String: return _vstring.toDouble(); - case PIVariant::StringList: if (_vstringlist.isEmpty()) return complexd_0; return _vstringlist.front().toDouble(); - default: break; + PIByteArray ba(_content); + switch (_type) { + case PIVariant::Bool: {bool r; ba >> r; return r;} + case PIVariant::Char: {char r; ba >> r; return r;} + case PIVariant::UChar: {uchar r; ba >> r; return r;} + case PIVariant::Short: {short r; ba >> r; return r;} + case PIVariant::UShort: {ushort r; ba >> r; return r;} + case PIVariant::Int: {int r; ba >> r; return r;} + case PIVariant::UInt: {uint r; ba >> r; return r;} + case PIVariant::LLong: {llong r; ba >> r; return r;} + case PIVariant::ULLong: {ullong r; ba >> r; return r;} + case PIVariant::Float: {float r; ba >> r; return r;} + case PIVariant::Double: {double r; ba >> r; return r;} + case PIVariant::LDouble: {ldouble r; ba >> r; return r;} + case PIVariant::Complexd: {complexd r; ba >> r; return r.real();} + case PIVariant::Complexld: {complexld r; ba >> r; return r.real();} + case PIVariant::String: {PIString r; ba >> r; return r.toDouble();} + case PIVariant::StringList: {PIStringList r; ba >> r; if (r.isEmpty()) return complexd_0; return r.front().toDouble();} + case PIVariant::Custom: + return getAsValue(*this); } return complexd_0; } @@ -396,26 +372,26 @@ complexd PIVariant::toComplexd() const { * otherwise returns \a PIString::toLDouble() of first string. \n * In case of other types returns \b 0.. */ complexld PIVariant::toComplexld() const { - switch (type_) { - case PIVariant::Bool: - case PIVariant::Char: - case PIVariant::UChar: - case PIVariant::Short: - case PIVariant::UShort: - case PIVariant::Int: - case PIVariant::UInt: - case PIVariant::Long: - case PIVariant::ULong: return _vint; - case PIVariant::LLong: - case PIVariant::ULLong: return _vllong; - case PIVariant::Float: return _vfloat; - case PIVariant::Double: return _vdouble; - case PIVariant::LDouble: return _vldouble; - case PIVariant::Complexd: return _vcomplexd.real(); - case PIVariant::Complexld: return _vcomplexld.real(); - case PIVariant::String: return _vstring.toLDouble(); - case PIVariant::StringList: if (_vstringlist.isEmpty()) return complexld_0; return _vstringlist.front().toLDouble(); - default: break; + PIByteArray ba(_content); + switch (_type) { + case PIVariant::Bool: {bool r; ba >> r; return r;} + case PIVariant::Char: {char r; ba >> r; return r;} + case PIVariant::UChar: {uchar r; ba >> r; return r;} + case PIVariant::Short: {short r; ba >> r; return r;} + case PIVariant::UShort: {ushort r; ba >> r; return r;} + case PIVariant::Int: {int r; ba >> r; return r;} + case PIVariant::UInt: {uint r; ba >> r; return r;} + case PIVariant::LLong: {llong r; ba >> r; return r;} + case PIVariant::ULLong: {ullong r; ba >> r; return r;} + case PIVariant::Float: {float r; ba >> r; return r;} + case PIVariant::Double: {double r; ba >> r; return r;} + case PIVariant::LDouble: {ldouble r; ba >> r; return r;} + case PIVariant::Complexd: {complexd r; ba >> r; return r.real();} + case PIVariant::Complexld: {complexld r; ba >> r; return r.real();} + case PIVariant::String: {PIString r; ba >> r; return r.toLDouble();} + case PIVariant::StringList: {PIStringList r; ba >> r; if (r.isEmpty()) return complexld_0; return r.front().toLDouble();} + case PIVariant::Custom: + return getAsValue(*this); } return complexld_0; } @@ -426,8 +402,10 @@ complexld PIVariant::toComplexld() const { * In case of DateTime type returns time part of value. \n * In case of other types returns \a PITime(). */ PITime PIVariant::toTime() const { - if (type_ == PIVariant::Time) return _vtime; - if (type_ == PIVariant::DateTime) return _vtime; + PIByteArray ba(_content); + if (_type == PIVariant::Time) {PITime r; ba >> r; return r;} + if (_type == PIVariant::DateTime) {PIDateTime r; ba >> r; return r.time();} + if (_type == PIVariant::Custom) {return getAsValue(*this);} return PITime(); } @@ -437,8 +415,10 @@ PITime PIVariant::toTime() const { * In case of DateTime type returns date part of value. \n * In case of other types returns \a PIDate(). */ PIDate PIVariant::toDate() const { - if (type_ == PIVariant::Date) return _vdate; - if (type_ == PIVariant::DateTime) return *((PIDate*)(&(_vdatetime.day))); + PIByteArray ba(_content); + if (_type == PIVariant::Date) {PIDate r; ba >> r; return r;} + if (_type == PIVariant::DateTime) {PIDateTime r; ba >> r; return r.date();} + if (_type == PIVariant::Custom) {return getAsValue(*this);} return PIDate(); } @@ -449,9 +429,11 @@ PIDate PIVariant::toDate() const { * In case of DateTime type returns date and time. \n * In case of other types returns \a PIDateTime(). */ PIDateTime PIVariant::toDateTime() const { - if (type_ == PIVariant::DateTime) return _vdatetime; - if (type_ == PIVariant::Time) return PIDateTime(_vtime); - if (type_ == PIVariant::Date) return PIDateTime(_vdate); + PIByteArray ba(_content); + if (_type == PIVariant::Time) {PITime r; ba >> r; return PIDateTime(r);} + if (_type == PIVariant::Date) {PIDate r; ba >> r; return PIDateTime(r);} + if (_type == PIVariant::DateTime) {PIDateTime r; ba >> r; return r;} + if (_type == PIVariant::Custom) {return getAsValue(*this);} return PIDateTime(); } @@ -461,7 +443,9 @@ PIDateTime PIVariant::toDateTime() const { * In case of other types returns \a PISystemTime::fromSeconds() from * double value of variant content. */ PISystemTime PIVariant::toSystemTime() const { - if (type_ == PIVariant::SystemTime) return _vsystime; + PIByteArray ba(_content); + if (_type == PIVariant::SystemTime) {PISystemTime r; ba >> r; return r;} + if (_type == PIVariant::Custom) {return getAsValue(*this);} return PISystemTime::fromSeconds(toDouble()); } @@ -476,34 +460,28 @@ PISystemTime PIVariant::toSystemTime() const { * ("(PISystemTime::seconds s, PISystemTime::nanoseconds ns)"). \n * In case of other types returns \b "". */ PIString PIVariant::toString() const { - switch (type_) { - case PIVariant::Bool: return _vint == 0 ? "false" : "true"; - case PIVariant::Char: - case PIVariant::UChar: - case PIVariant::Short: - case PIVariant::UShort: - case PIVariant::Int: - case PIVariant::UInt: - case PIVariant::Long: - case PIVariant::ULong: return PIString::fromNumber(_vint); - case PIVariant::LLong: - case PIVariant::ULLong: return PIString::fromNumber(_vllong); - case PIVariant::Float: return PIString::fromNumber(_vfloat); - case PIVariant::Double: return PIString::fromNumber(_vdouble); - case PIVariant::LDouble: return PIString::fromNumber(_vldouble); - case PIVariant::Complexd: return "(" + PIString::fromNumber(_vcomplexd.real()) + "; " + PIString::fromNumber(_vcomplexd.imag()) + ")"; - case PIVariant::Complexld: return "(" + PIString::fromNumber(_vcomplexld.real()) + "; " + PIString::fromNumber(_vcomplexld.imag()) + ")"; - case PIVariant::BitArray: return PIString::fromNumber(_vbitarray.bitSize()) + " bits"; - case PIVariant::ByteArray: return _vbytearray.toString(); - case PIVariant::String: return _vstring; - case PIVariant::StringList: return "(" + _vstringlist.join("; ") + ")"; - case PIVariant::Time: return _vtime.toString(); - case PIVariant::Date: return _vdate.toString(); - case PIVariant::DateTime: return _vdatetime.toString(); - case PIVariant::SystemTime: return "(" + PIString::fromNumber(_vsystime.seconds) + " s, " + PIString::fromNumber(_vsystime.nanoseconds) + " ns)"; - default: break; + PIByteArray ba(_content); + switch (_type) { + case PIVariant::Bool: {bool r; ba >> r; return PIString::fromNumber(r);} + case PIVariant::Char: {char r; ba >> r; return PIString::fromNumber(r);} + case PIVariant::UChar: {uchar r; ba >> r; return PIString::fromNumber(r);} + case PIVariant::Short: {short r; ba >> r; return PIString::fromNumber(r);} + case PIVariant::UShort: {ushort r; ba >> r; return PIString::fromNumber(r);} + case PIVariant::Int: {int r; ba >> r; return PIString::fromNumber(r);} + case PIVariant::UInt: {uint r; ba >> r; return PIString::fromNumber(r);} + case PIVariant::LLong: {llong r; ba >> r; return PIString::fromNumber(r);} + case PIVariant::ULLong: {ullong r; ba >> r; return PIString::fromNumber(r);} + case PIVariant::Float: {float r; ba >> r; return PIString::fromNumber(r);} + case PIVariant::Double: {double r; ba >> r; return PIString::fromNumber(r);} + case PIVariant::LDouble: {ldouble r; ba >> r; return PIString::fromNumber(r);} + case PIVariant::Complexd: {complexd r; ba >> r; return PIString::fromNumber(r.real());} + case PIVariant::Complexld: {complexld r; ba >> r; return PIString::fromNumber(r.real());} + case PIVariant::String: {PIString r; ba >> r; return r;} + case PIVariant::StringList: {PIStringList r; ba >> r; if (r.isEmpty()) return PIString(); return r.front();} + case PIVariant::Custom: + return getAsValue(*this); } - return ""; + return PIString(); } @@ -511,7 +489,9 @@ PIString PIVariant::toString() const { * \details In case of StringList type returns strings list value. \n * In case of other types returns \a PIStringList with one string value of variant content. */ PIStringList PIVariant::toStringList() const { - if (type_ == PIVariant::StringList) return _vstringlist; + PIByteArray ba(_content); + if (_type == PIVariant::StringList) {PIStringList r; ba >> r; return r;} + if (_type == PIVariant::Custom) {return getAsValue(*this);} return PIStringList(toString()); } @@ -520,7 +500,9 @@ PIStringList PIVariant::toStringList() const { * \details In case of BitArray type returns bit array value. \n * In case of other types returns \a PIBitArray from \a toLLong() value. */ PIBitArray PIVariant::toBitArray() const { - if (type_ == PIVariant::BitArray) return _vbitarray; + PIByteArray ba(_content); + if (_type == PIVariant::BitArray) {PIBitArray r; ba >> r; return r;} + if (_type == PIVariant::Custom) {return getAsValue(*this);} return PIBitArray(ullong(toLLong())); } @@ -529,6 +511,8 @@ PIBitArray PIVariant::toBitArray() const { * \details In case of ByteArray type returns byte array value. \n * In case of other types returns empty \a PIByteArray. */ PIByteArray PIVariant::toByteArray() const { - if (type_ == PIVariant::ByteArray) return _vbytearray; + PIByteArray ba(_content); + if (_type == PIVariant::ByteArray) {PIByteArray r; ba >> r; return r;} + if (_type == PIVariant::Custom) {return getAsValue(*this);} return PIByteArray(); } diff --git a/src/core/pivariant.h b/src/core/pivariant.h index effb2d63..7e86a0c5 100755 --- a/src/core/pivariant.h +++ b/src/core/pivariant.h @@ -30,21 +30,96 @@ #include "pitime.h" #include "pimathbase.h" -#define __PIVARIANT_UNION_SIZE__ 32 -#define _vcomplexd (*((complexd*)_vraw)) -#define _vcomplexld (*((complexld*)_vraw)) -#define _vtime (*((PITime*)_vraw)) -#define _vdate (*((PIDate*)_vraw)) -#define _vdatetime (*((PIDateTime*)_vraw)) -#define _vsystime (*((PISystemTime*)_vraw)) +template +class __PIVariantFunctions__ { +public: + static PIString typeNameHelper() {return PIStringAscii("");} + + static bool isSimpleHelper() {return false;} + template static PIByteArray castHelper(PIByteArray ba) {return PIByteArray();} + template static C castVariant(const T & v) {return C();} +}; + +struct __PIVariantInfo__ { + __PIVariantInfo__() { + simple = false; + } + typedef PIByteArray(*castHelperFunc)(PIByteArray); + PIMap cast; + PIString typeName; + bool simple; +}; + +class __PIVariantInfoStorage__ { +public: + __PIVariantInfoStorage__() {if (!map) map = new PIMap();} + static __PIVariantInfoStorage__ * get() {static __PIVariantInfoStorage__ * r = new __PIVariantInfoStorage__(); return r;} + static PIMap * map; +}; + + +#define REGISTER_VARIANT_H(classname) \ +template<> inline PIString __PIVariantFunctions__< classname >::typeNameHelper() {static PIString tn = PIStringAscii(#classname); return tn;} + +#define REGISTER_VARIANT_CPP(classname) \ +template \ +class __##classname##_PIVariantInitializer__ { \ +public: \ + __##classname##_PIVariantInitializer__(const PIString & name) { \ + if (__PIVariantInfoStorage__::get()->map->contains(name)) \ + return; \ + __PIVariantInfo__ * vi = new __PIVariantInfo__(); \ + vi->typeName = name; \ + (*(__PIVariantInfoStorage__::get()->map))[name] = vi; \ + } \ +}; + +#define INIT_VARIANT(classname) \ + __##classname##_PIVariantInitializer__< classname > __##classname##_pivariant_initializer__(#classname); + +#define REGISTER_VARIANT(classname) \ + REGISTER_VARIANT_H(classname) \ + REGISTER_VARIANT_CPP(classname) \ + static INIT_VARIANT(classname) + + +#define REGISTER_VARIANT_CAST_H(classname_from, classname_to) \ +template<> template<> inline \ +classname_to __PIVariantFunctions__::castVariant(const classname_from & v); + +#define REGISTER_VARIANT_CAST_CPP(classname_from, classname_to) \ +template<> template<> inline \ +PIByteArray __PIVariantFunctions__::castHelper(PIByteArray v) { \ + classname_from f; v >> f; \ + classname_to t = __PIVariantFunctions__::castVariant(f); \ + PIByteArray ret; ret << t; \ + return ret;} \ +template \ +class __##classname_from##_##classname_to##_PIVariantCastInitializer__ { \ +public: \ + __##classname_from##_##classname_to##_PIVariantCastInitializer__(const PIString & name, const PIString & cname) { \ + __PIVariantInfo__ * vi(__PIVariantInfoStorage__::get()->map->value(name, 0)); \ + if (!vi) { \ + piCout << "Warning! Using REGISTER_VARIANT_CAST("#classname_from", "#classname_to") before REGISTER_VARIANT("#classname_from"), ignore."; \ + return; \ + } \ + vi->cast[cname] = __PIVariantFunctions__::castHelper; \ + } \ +}; \ +static __##classname_from##_##classname_to##_PIVariantCastInitializer__< classname_from, classname_to > __##classname_from##_##classname_to##_pivariant_cast_initializer__(#classname_from, #classname_to); \ +template<> template<> \ +classname_to __PIVariantFunctions__::castVariant(const classname_from & v) + +#define REGISTER_VARIANT_CAST(classname_from, classname_to) \ + REGISTER_VARIANT_CAST_H(classname_from, classname_to) \ + REGISTER_VARIANT_CAST_CPP(classname_from, classname_to) + + +#define REGISTER_VARIANT_CAST_SIMPLE(classname_from, classname_to) REGISTER_VARIANT_CAST(classname_from, classname_to) {return classname_to(v);} +#define REGISTER_VARIANT_CAST_SIMPLE_H(classname_from, classname_to) REGISTER_VARIANT_CAST_H(classname_from, classname_to) +#define REGISTER_VARIANT_CAST_SIMPLE_CPP(classname_from, classname_to) REGISTER_VARIANT_CAST_CPP(classname_from, classname_to) {return classname_to(v);} -#define _vvcomplexd(v) (*((complexd*)v._vraw)) -#define _vvcomplexld(v) (*((complexld*)v._vraw)) -#define _vvtime(v) (*((PITime*)v._vraw)) -#define _vvdate(v) (*((PIDate*)v._vraw)) -#define _vvdatetime(v) (*((PIDateTime*)v._vraw)) -#define _vvsystime(v) (*((PISystemTime*)v._vraw)) class PIP_EXPORT PIVariant { friend PICout operator <<(PICout s, const PIVariant & v); @@ -60,8 +135,6 @@ public: UShort /** ushort */ , Int /** int */ , UInt /** uint */ , - Long /** long */ , - ULong /** ulong */ , LLong /** llong */ , ULLong /** ullong */ , Float /** float */ , @@ -84,155 +157,143 @@ public: PIVariant(); //! Constructs variant from string - PIVariant(const char * v) {setValue(PIString(v));} + PIVariant(const char * v) {initType(PIString(v));} //! Constructs variant from boolean - PIVariant(const bool v) {setValue(v);} + PIVariant(const bool v) {initType(v);} //! Constructs variant from char - PIVariant(const char v) {setValue(v);} + PIVariant(const char v) {initType(v);} //! Constructs variant from integer - PIVariant(const uchar v) {setValue(v);} + PIVariant(const uchar v) {initType(v);} //! Constructs variant from integer - PIVariant(const short v) {setValue(v);} + PIVariant(const short v) {initType(v);} //! Constructs variant from integer - PIVariant(const ushort v) {setValue(v);} + PIVariant(const ushort v) {initType(v);} //! Constructs variant from integer - PIVariant(const int & v) {setValue(v);} + PIVariant(const int & v) {initType(v);} //! Constructs variant from integer - PIVariant(const uint & v) {setValue(v);} + PIVariant(const uint & v) {initType(v);} //! Constructs variant from integer - PIVariant(const long & v) {setValue(v);} + PIVariant(const llong & v) {initType(v);} //! Constructs variant from integer - PIVariant(const ulong & v) {setValue(v);} - - //! Constructs variant from integer - PIVariant(const llong & v) {setValue(v);} - - //! Constructs variant from integer - PIVariant(const ullong & v) {setValue(v);} + PIVariant(const ullong & v) {initType(v);} //! Constructs variant from float - PIVariant(const float & v) {setValue(v);} + PIVariant(const float & v) {initType(v);} //! Constructs variant from double - PIVariant(const double & v) {setValue(v);} + PIVariant(const double & v) {initType(v);} //! Constructs variant from long double - PIVariant(const ldouble & v) {setValue(v);} + PIVariant(const ldouble & v) {initType(v);} //! Constructs variant from complex - PIVariant(const complexd & v) {setValue(v);} + PIVariant(const complexd & v) {initType(v);} //! Constructs variant from complex - PIVariant(const complexld & v) {setValue(v);} + PIVariant(const complexld & v) {initType(v);} //! Constructs variant from bit array - PIVariant(const PIBitArray & v) {setValue(v);} + PIVariant(const PIBitArray & v) {initType(v);} //! Constructs variant from byte array - PIVariant(const PIByteArray & v) {setValue(v);} + PIVariant(const PIByteArray & v) {initType(v);} //! Constructs variant from string - PIVariant(const PIString & v) {setValue(v);} + PIVariant(const PIString & v) {initType(v);} //! Constructs variant from strings list - PIVariant(const PIStringList & v) {setValue(v);} + PIVariant(const PIStringList & v) {initType(v);} //! Constructs variant from time - PIVariant(const PITime & v) {setValue(v);} + PIVariant(const PITime & v) {initType(v);} //! Constructs variant from date - PIVariant(const PIDate & v) {setValue(v);} + PIVariant(const PIDate & v) {initType(v);} //! Constructs variant from date and time - PIVariant(const PIDateTime & v) {setValue(v);} + PIVariant(const PIDateTime & v) {initType(v);} //! Constructs variant from system time - PIVariant(const PISystemTime & v) {setValue(v);} + PIVariant(const PISystemTime & v) {initType(v);} //! Set variant content and type to string void setValue(const char * v) {setValue(PIString(v));} //! Set variant content and type to boolean - void setValue(const bool v) {type_ = PIVariant::Bool; _vint = (v ? 1 : 0);} + void setValue(const bool v) {initType(v);} //! Set variant content and type to char - void setValue(const char v) {type_ = PIVariant::Char; _vint = v;} + void setValue(const char v) {initType(v);} //! Set variant content and type to integer - void setValue(const uchar v) {type_ = PIVariant::UChar; _vint = v;} + void setValue(const uchar v) {initType(v);} //! Set variant content and type to integer - void setValue(const short v) {type_ = PIVariant::Short; _vint = v;} + void setValue(const short v) {initType(v);} //! Set variant content and type to integer - void setValue(const ushort v) {type_ = PIVariant::UShort; _vint = v;} + void setValue(const ushort v) {initType(v);} //! Set variant content and type to integer - void setValue(const int & v) {type_ = PIVariant::Int; _vint = v;} + void setValue(const int & v) {initType(v);} //! Set variant content and type to integer - void setValue(const uint & v) {type_ = PIVariant::UInt; _vint = v;} + void setValue(const uint & v) {initType(v);} //! Set variant content and type to integer - void setValue(const long & v) {type_ = PIVariant::Long; _vint = v;} + void setValue(const llong & v) {initType(v);} //! Set variant content and type to integer - void setValue(const ulong & v) {type_ = PIVariant::ULong; _vint = v;} - - //! Set variant content and type to integer - void setValue(const llong & v) {type_ = PIVariant::LLong; _vllong = v;} - - //! Set variant content and type to integer - void setValue(const ullong & v) {type_ = PIVariant::ULLong; _vllong = v;} + void setValue(const ullong & v) {initType(v);} //! Set variant content and type to float - void setValue(const float & v) {type_ = PIVariant::Float; _vfloat = v;} + void setValue(const float & v) {initType(v);} //! Set variant content and type to double - void setValue(const double & v) {type_ = PIVariant::Double; _vdouble = v;} + void setValue(const double & v) {initType(v);} //! Set variant content and type to long double - void setValue(const ldouble & v) {type_ = PIVariant::LDouble; _vldouble = v;} + void setValue(const ldouble & v) {initType(v);} //! Set variant content and type to complex - void setValue(const complexd & v) {type_ = PIVariant::Complexd; _vcomplexd = v;} + void setValue(const complexd & v) {initType(v);} //! Set variant content and type to complex - void setValue(const complexld & v) {type_ = PIVariant::Complexld; _vcomplexld = v;} + void setValue(const complexld & v) {initType(v);} //! Set variant content and type to bit array - void setValue(const PIBitArray & v) {type_ = PIVariant::BitArray; _vbitarray = v;} + void setValue(const PIBitArray & v) {initType(v);} //! Set variant content and type to byte array - void setValue(const PIByteArray & v) {type_ = PIVariant::ByteArray; _vbytearray = v;} + void setValue(const PIByteArray & v) {initType(v);} //! Set variant content and type to string - void setValue(const PIString & v) {type_ = PIVariant::String; _vstring = v;} + void setValue(const PIString & v) {initType(v);} //! Set variant content and type to strings list - void setValue(const PIStringList & v) {type_ = PIVariant::StringList; _vstringlist = v;} + void setValue(const PIStringList & v) {initType(v);} //! Set variant content and type to time - void setValue(const PITime & v) {type_ = PIVariant::Time; _vtime = v;} + void setValue(const PITime & v) {initType(v);} //! Set variant content and type to date - void setValue(const PIDate & v) {type_ = PIVariant::Date; _vdate = v;} + void setValue(const PIDate & v) {initType(v);} //! Set variant content and type to date and time - void setValue(const PIDateTime & v) {type_ = PIVariant::DateTime; _vdatetime = v;} + void setValue(const PIDateTime & v) {initType(v);} //! Set variant content and type to system time - void setValue(const PISystemTime & v) {type_ = PIVariant::SystemTime; _vsystime = v;} + void setValue(const PISystemTime & v) {initType(v);} bool toBool() const; @@ -257,7 +318,7 @@ public: * \details In case of known types this function equivalent \a to function. \n * Otherwise returns content as type T. */ template - T toValue() const {if (_vcustom.size() != sizeof(T)) return T(); return *((T*)_vcustom.data());} + T value() const {return getAsValue(*this);} /* operator bool() const {return toBool();} operator char() const {return toInt();} @@ -305,10 +366,6 @@ public: //! Assign operator PIVariant & operator =(const uint & v) {setValue(v); return *this;} //! Assign operator - PIVariant & operator =(const long & v) {setValue(v); return *this;} - //! Assign operator - PIVariant & operator =(const ulong & v) {setValue(v); return *this;} - //! Assign operator PIVariant & operator =(const llong & v) {setValue(v); return *this;} //! Assign operator PIVariant & operator =(const ullong & v) {setValue(v); return *this;} @@ -347,21 +404,41 @@ public: //! Returns type of variant content - PIVariant::Type type() const {return type_;} + PIVariant::Type type() const {return _type;} //! Returns type name of variant content - PIString typeName() const {return typeName(type_);} + PIString typeName() const; //! Returns \b true if type is not Invalid - bool isValid() const {return type_ != PIVariant::Invalid;} + bool isValid() const {return _type != PIVariant::Invalid;} /** \brief Returns new variant from custom type * \details In case of known types this function equivalent \a PIVariant(T) constructors. \n * Otherwise returns variant with content \a v and type Custom. */ template - static PIVariant fromValue(const T & v) {PIVariant ret; ret._vcustom.resize(sizeof(T)); new((T*)(ret._vcustom.data()))T(v); ret.type_ = PIVariant::Custom; return ret;} + static PIVariant fromValue(const T & v) { + PIVariant ret; + ret.initType(v); + return ret; + } + + static PIVariant fromValue(const PIByteArray & c, const PIString & type) { + PIVariant ret; + ret._info = __PIVariantInfoStorage__::get()->map->value(type, 0); + if (!ret._info) { + PIVariant::Type t = typeFromName(type); + if (t == Invalid) { + piCout << "Can`t initialize PIVariant from unregistered type \"" << type << "\"!"; + return ret; + } + ret._type = t; + } else + ret._type = Custom; + ret._content = c; + return ret; + } //! Returns type from name @@ -371,56 +448,65 @@ public: static PIString typeName(PIVariant::Type type); private: - void destroy() {_vcustom.clear();} + void destroy() {_content.clear();} + template static Type getType() {return Custom;} + template void initType(const T & v) { + _content.clear(); + _content << v; + _type = getType(); + if (_type == Custom) { + _info = __PIVariantInfoStorage__::get()->map->value(__PIVariantFunctions__::typeNameHelper(), 0); + if (!_info) + piCout << "Can`t initialize PIVariant from unregistered type!"; + } else + _info = 0; + } + template static T getAsValue(const PIVariant & v) { + if (v._content.isEmpty() || !v._info) return T(); + PIString cn = __PIVariantFunctions__::typeNameHelper(); + piCout << "gav" << cn; + PIByteArray ba; + if (cn == v._info->typeName) { + ba = v._content; + } else { + __PIVariantInfo__::castHelperFunc cf = v._info->cast.value(cn); + piCout << "gav cast" << cf; + if (!cf) return T(); + ba = cf(v._content); + } + T ret; ba >> ret; + return ret; + } - union { - int _vint; - llong _vllong; - float _vfloat; - double _vdouble; - ldouble _vldouble; - uchar _vraw[__PIVARIANT_UNION_SIZE__]; - /*complexd _vcomplexd; - complexld _vcomplexld; - PITime _vtime; - PIDate _vdate; - PIDateTime _vdatetime; - PISystemTime _vsystime;*/ - }; - PIBitArray _vbitarray; - PIByteArray _vbytearray; - PIString _vstring; - PIStringList _vstringlist; - PIByteArray _vcustom; - PIVariant::Type type_; + PIByteArray _content; + PIVariant::Type _type; + __PIVariantInfo__ * _info; }; -template<> inline bool PIVariant::toValue() const {return toBool();} -template<> inline char PIVariant::toValue() const {return (char)toInt();} -template<> inline uchar PIVariant::toValue() const {return (uchar)toInt();} -template<> inline short PIVariant::toValue() const {return (short)toInt();} -template<> inline ushort PIVariant::toValue() const {return (ushort)toInt();} -template<> inline int PIVariant::toValue() const {return toInt();} -template<> inline uint PIVariant::toValue() const {return (uint)toInt();} -template<> inline long PIVariant::toValue() const {return (long)toInt();} -template<> inline ulong PIVariant::toValue() const {return (ulong)toInt();} -template<> inline llong PIVariant::toValue() const {return toLLong();} -template<> inline ullong PIVariant::toValue() const {return (ullong)toLLong();} -template<> inline float PIVariant::toValue() const {return toFloat();} -template<> inline double PIVariant::toValue() const {return toDouble();} -template<> inline ldouble PIVariant::toValue() const {return toLDouble();} -template<> inline complexd PIVariant::toValue() const {return toComplexd();} -template<> inline complexld PIVariant::toValue() const {return toComplexld();} -template<> inline void* PIVariant::toValue() const {return (void*)toLLong();} -template<> inline const char* PIVariant::toValue() const {return toString().data();} -template<> inline PITime PIVariant::toValue() const {return toTime();} -template<> inline PIDate PIVariant::toValue() const {return toDate();} -template<> inline PIDateTime PIVariant::toValue() const {return toDateTime();} -template<> inline PIString PIVariant::toValue() const {return toString();} -template<> inline PIStringList PIVariant::toValue() const {return toStringList();} -template<> inline PIBitArray PIVariant::toValue() const {return toBitArray();} -template<> inline PIByteArray PIVariant::toValue() const {return toByteArray();} +template<> inline bool PIVariant::value() const {return toBool();} +template<> inline char PIVariant::value() const {return (char)toInt();} +template<> inline uchar PIVariant::value() const {return (uchar)toInt();} +template<> inline short PIVariant::value() const {return (short)toInt();} +template<> inline ushort PIVariant::value() const {return (ushort)toInt();} +template<> inline int PIVariant::value() const {return toInt();} +template<> inline uint PIVariant::value() const {return (uint)toInt();} +template<> inline llong PIVariant::value() const {return toLLong();} +template<> inline ullong PIVariant::value() const {return (ullong)toLLong();} +template<> inline float PIVariant::value() const {return toFloat();} +template<> inline double PIVariant::value() const {return toDouble();} +template<> inline ldouble PIVariant::value() const {return toLDouble();} +template<> inline complexd PIVariant::value() const {return toComplexd();} +template<> inline complexld PIVariant::value() const {return toComplexld();} +template<> inline void* PIVariant::value() const {return (void*)toLLong();} +template<> inline const char* PIVariant::value() const {return toString().data();} +template<> inline PITime PIVariant::value() const {return toTime();} +template<> inline PIDate PIVariant::value() const {return toDate();} +template<> inline PIDateTime PIVariant::value() const {return toDateTime();} +template<> inline PIString PIVariant::value() const {return toString();} +template<> inline PIStringList PIVariant::value() const {return toStringList();} +template<> inline PIBitArray PIVariant::value() const {return toBitArray();} +template<> inline PIByteArray PIVariant::value() const {return toByteArray();} //template<> inline PIVariant PIVariant::fromValue(const char * v) {return PIVariant(PIString(v));} template<> inline PIVariant PIVariant::fromValue(const bool & v) {return PIVariant(v);} @@ -430,8 +516,6 @@ template<> inline PIVariant PIVariant::fromValue(const short & v) {return PIVari template<> inline PIVariant PIVariant::fromValue(const ushort & v) {return PIVariant(v);} template<> inline PIVariant PIVariant::fromValue(const int & v) {return PIVariant(v);} template<> inline PIVariant PIVariant::fromValue(const uint & v) {return PIVariant(v);} -template<> inline PIVariant PIVariant::fromValue(const long & v) {return PIVariant(v);} -template<> inline PIVariant PIVariant::fromValue(const ulong & v) {return PIVariant(v);} template<> inline PIVariant PIVariant::fromValue(const llong & v) {return PIVariant(v);} template<> inline PIVariant PIVariant::fromValue(const ullong & v) {return PIVariant(v);} template<> inline PIVariant PIVariant::fromValue(const float & v) {return PIVariant(v);} @@ -448,12 +532,32 @@ template<> inline PIVariant PIVariant::fromValue(const PIDate & v) {return PIVar template<> inline PIVariant PIVariant::fromValue(const PIDateTime & v) {return PIVariant(v);} template<> inline PIVariant PIVariant::fromValue(const PISystemTime & v) {return PIVariant(v);} +template<> inline PIVariant::Type PIVariant::getType() {return PIVariant::Bool;} +template<> inline PIVariant::Type PIVariant::getType() {return PIVariant::Char;} +template<> inline PIVariant::Type PIVariant::getType() {return PIVariant::UChar;} +template<> inline PIVariant::Type PIVariant::getType() {return PIVariant::Short;} +template<> inline PIVariant::Type PIVariant::getType() {return PIVariant::UShort;} +template<> inline PIVariant::Type PIVariant::getType() {return PIVariant::Int;} +template<> inline PIVariant::Type PIVariant::getType() {return PIVariant::UInt;} +template<> inline PIVariant::Type PIVariant::getType() {return PIVariant::LLong;} +template<> inline PIVariant::Type PIVariant::getType() {return PIVariant::ULLong;} +template<> inline PIVariant::Type PIVariant::getType() {return PIVariant::Float;} +template<> inline PIVariant::Type PIVariant::getType() {return PIVariant::Double;} +template<> inline PIVariant::Type PIVariant::getType() {return PIVariant::LDouble;} +template<> inline PIVariant::Type PIVariant::getType() {return PIVariant::Complexd;} +template<> inline PIVariant::Type PIVariant::getType() {return PIVariant::Complexld;} +template<> inline PIVariant::Type PIVariant::getType() {return PIVariant::BitArray;} +template<> inline PIVariant::Type PIVariant::getType() {return PIVariant::ByteArray;} +template<> inline PIVariant::Type PIVariant::getType() {return PIVariant::String;} +template<> inline PIVariant::Type PIVariant::getType() {return PIVariant::StringList;} +template<> inline PIVariant::Type PIVariant::getType() {return PIVariant::Time;} +template<> inline PIVariant::Type PIVariant::getType() {return PIVariant::Date;} +template<> inline PIVariant::Type PIVariant::getType() {return PIVariant::DateTime;} +template<> inline PIVariant::Type PIVariant::getType() {return PIVariant::SystemTime;} + inline PICout operator <<(PICout s, const PIVariant & v) { s.space(); s.setControl(0, true); - s << "PIVariant(" << PIVariant::typeName(v.type()) << ", "; - if (v.type() == PIVariant::Custom) s << v._vcustom.size() << " bytes"; - else s << v.toString(); - s << ")"; + s << "PIVariant(" << v.typeName() << ", " << v.toString() << ")"; s.restoreControl(); return s; } diff --git a/src/thread/pithread.cpp b/src/thread/pithread.cpp index eeb5d509..21e0789f 100755 --- a/src/thread/pithread.cpp +++ b/src/thread/pithread.cpp @@ -139,7 +139,6 @@ bool PIThread::start(int timer_delay) { thread = (void *)_beginthreadex(0, 0, thread_function, this, 0, 0); // thread = CreateThread(0, 0, (LPTHREAD_START_ROUTINE)thread_function, this, 0, 0); if (thread != 0) { - tid_ = GetThreadId(thread); #endif setPriority(priority_); running_ = true; @@ -172,7 +171,6 @@ bool PIThread::startOnce() { thread = (void *)_beginthreadex(0, 0, thread_function_once, this, 0, 0); // thread = CreateThread(0, 0, (LPTHREAD_START_ROUTINE)thread_function_once, this, 0, 0); if (thread != 0) { - tid_ = GetThreadId(thread); #endif setPriority(priority_); running_ = true; @@ -219,6 +217,9 @@ __THREAD_FUNC__ PIThread::thread_function(void * t) { __PISetTimerResolution(); #endif PIThread & ct = *((PIThread * )t); +#ifdef WINDOWS + ct.tid_ = GetCurrentThreadId(); +#endif PIINTROSPECTION_REGISTER_THREAD(ct.tid(), ct.priority(), ct.name()); ct.running_ = true; if (ct.lockRun) ct.mutex_.lock(); @@ -276,6 +277,9 @@ __THREAD_FUNC__ PIThread::thread_function_once(void * t) { __PISetTimerResolution(); #endif PIThread & ct = *((PIThread * )t); +#ifdef WINDOWS + ct.tid_ = GetCurrentThreadId(); +#endif PIINTROSPECTION_REGISTER_THREAD(ct.tid(), ct.priority(), ct.name()); ct.running_ = true; ct.begin();