/* * (c) Copyright Ascensio System SIA 2010-2023 * * This program is a free software product. You can redistribute it and/or * modify it under the terms of the GNU Affero General Public License (AGPL) * version 3 as published by the Free Software Foundation. In accordance with * Section 7(a) of the GNU AGPL its Section 15 shall be amended to the effect * that Ascensio System SIA expressly excludes the warranty of non-infringement * of any third-party rights. * * This program is distributed WITHOUT ANY WARRANTY; without even the implied * warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. For * details, see the GNU AGPL at: http://www.gnu.org/licenses/agpl-3.0.html * * You can contact Ascensio System SIA at 20A-6 Ernesta Birznieka-Upish * street, Riga, Latvia, EU, LV-1050. * * The interactive user interfaces in modified source and object code versions * of the Program must display Appropriate Legal Notices, as required under * Section 5 of the GNU AGPL version 3. * * Pursuant to Section 7(b) of the License you must retain the original Product * logo when distributing the program. Pursuant to Section 7(e) we decline to * grant you any rights under trademark law for use of our trademarks. * * All the Product's GUI elements, including illustrations and icon sets, as * well as technical writing content are licensed under the terms of the * Creative Commons Attribution-ShareAlike 4.0 International. See the License * terms at http://creativecommons.org/licenses/by-sa/4.0/legalcode * */ #pragma once #include "Base.h" #include "Unit.h" #include "SmartPtr.h" #include "../../DesktopEditor/xml/include/xmlutils.h" #include "../../MsBinaryFile/XlsFile/Format/Logic/BaseObject.h" namespace NSCommon { template class nullable_base { protected: Type* m_pPointer; public: nullable_base() { m_pPointer = NULL; } nullable_base(const nullable_base& oOther) { m_pPointer = NULL; if ( NULL != oOther.m_pPointer ) m_pPointer = new Type( (const Type&)*(oOther.m_pPointer) ); } virtual ~nullable_base() { RELEASEOBJECT(m_pPointer); } Type& operator*() { return *m_pPointer; } Type* operator->() { return m_pPointer; } Type& operator*() const { return *m_pPointer; } Type* operator->() const { return m_pPointer; } const Type& get()const { return *m_pPointer; } Type& get() { return *m_pPointer; } nullable_base& operator=(const nullable_base &oOther) { RELEASEOBJECT(m_pPointer); if ( NULL != oOther.m_pPointer ) m_pPointer = new Type( (const Type&)*(oOther.m_pPointer) ); return *this; } nullable_base& operator=(Type* pType) { RELEASEOBJECT(m_pPointer); m_pPointer = pType; return *this; } nullable_base& operator=(const Type& oSrc) { RELEASEOBJECT(m_pPointer); m_pPointer = new Type(oSrc); return *this; } bool IsInit() const { return (NULL != m_pPointer); } bool is_init() const { return IsInit(); } void reset(Type* pType = NULL) { RELEASEOBJECT(m_pPointer); m_pPointer = pType; } }; template class nullable : public nullable_base { public: nullable() : nullable_base() { } nullable(const nullable& oOther) { if ( NULL == oOther.m_pPointer ) this->m_pPointer = NULL; else this->m_pPointer = new Type( (const Type&)*(oOther.m_pPointer) ); } nullable(const XmlUtils::CXmlNode& oNode) // const modifier is important for gcc compiler in our case { if (oNode.IsValid()) { Type* pType = new Type(); *pType = const_cast (oNode); this->m_pPointer = pType; } else this->m_pPointer = NULL; } nullable(XmlUtils::CXmlNode& oNode) { if (oNode.IsValid()) { Type* pType = new Type(); *pType = oNode; this->m_pPointer = pType; } else this->m_pPointer = NULL; } nullable(XmlUtils::CXmlLiteReader& oReader) { if (oReader.IsValid()) { Type* pType = new Type(); *pType = oReader; this->m_pPointer = pType; } else this->m_pPointer = NULL; } nullable(XLS::BaseObjectPtr& obj) { if (obj != nullptr) this->m_pPointer = new Type(obj); else this->m_pPointer = NULL; } nullable(std::vector& obj) { if (!obj.empty()) this->m_pPointer = new Type(obj); else this->m_pPointer = NULL; } nullable& operator=(XLS::BaseObjectPtr& obj) { RELEASEOBJECT(this->m_pPointer); if (obj != nullptr) this->m_pPointer = new Type(obj); return *this; } nullable& operator=(std::vector& obj) { RELEASEOBJECT(this->m_pPointer); if (!obj.empty()) this->m_pPointer = new Type(obj); return *this; } nullable& operator=(XmlUtils::CXmlNode& oNode) { RELEASEOBJECT(this->m_pPointer); if (oNode.IsValid()) { Type* pType = new Type(); *pType = oNode; this->m_pPointer = pType; } return *this; } nullable& operator=(XmlUtils::CXmlLiteReader& oReader) { RELEASEOBJECT(this->m_pPointer); if (oReader.IsValid()) { Type* pType = new Type(); *pType = oReader; this->m_pPointer = pType; } return *this; } nullable& operator=(const wchar_t* cwsValue) { RELEASEOBJECT(this->m_pPointer); if (NULL != cwsValue) this->m_pPointer = new Type( cwsValue ); return *this; } nullable& operator=(const nullable &oOther) { RELEASEOBJECT(this->m_pPointer); if ( NULL != oOther.m_pPointer ) this->m_pPointer = new Type( (const Type&)*(oOther.m_pPointer) ); return *this; } nullable& operator=(Type* pType) { RELEASEOBJECT(this->m_pPointer); this->m_pPointer = pType; return *this; } nullable& operator=(Type& oSrc) { RELEASEOBJECT(this->m_pPointer); this->m_pPointer = new Type(oSrc); return *this; } nullable& operator=(const Type& oSrc) { RELEASEOBJECT(this->m_pPointer); this->m_pPointer = new Type(oSrc); return *this; } const bool operator==(const nullable& oOther) const { if ( !this->m_pPointer && !oOther.m_pPointer ) return true; else if ( !this->m_pPointer || !oOther.m_pPointer ) return false; return (*this->m_pPointer) == (*(oOther.m_pPointer)); } const bool operator==(const Type& oOther) const { if ( !this->m_pPointer ) return false; return (*this->m_pPointer) == oOther; } Type& operator*() { return *this->m_pPointer; } Type* operator->() { return this->m_pPointer; } Type& operator*() const { return *this->m_pPointer; } Type* operator->() const { return this->m_pPointer; } const Type& get()const { return *this->m_pPointer; } Type& get2()const { return *this->m_pPointer; } template const bool is()const { if (NULL == this->m_pPointer) return false; T* pResult = dynamic_cast(const_cast(this->m_pPointer)); return (NULL != pResult); } template const T& as()const { T* pResult = dynamic_cast(const_cast(this->m_pPointer)); return *pResult; } template T& as() { T* pResult = dynamic_cast(const_cast(this->m_pPointer)); return *pResult; } bool Init() { RELEASEOBJECT(this->m_pPointer); this->m_pPointer = new Type; return this->IsInit(); } Type* GetPointer() const { return this->m_pPointer; } //GetPointerEmptyNullable - небезопасная операция, использовать при крайней необходимости //Передает указатель и очищает nullable, в дальнейшем память надо удалять самостоятельно Type* GetPointerEmptyNullable() { Type* pOldPointer = this->m_pPointer; this->m_pPointer = NULL; return pOldPointer; } }; template class nullable_limit : public nullable_base { public: nullable_limit() : nullable_base() { } void operator=(const std::wstring& value) { RELEASEOBJECT(this->m_pPointer); this->m_pPointer = new Type(); this->m_pPointer->set(value); } void operator=(Type* pType) { RELEASEOBJECT(this->m_pPointer); this->m_pPointer = pType; } void operator=(const BYTE& value) { RELEASEOBJECT(this->m_pPointer); this->m_pPointer = new Type(); this->m_pPointer->SetBYTECode(value); } void operator=(const Type& value) { *this = value.get(); } nullable_limit& operator=(const nullable_limit& oSrc) { RELEASEOBJECT(this->m_pPointer); if ( NULL != oSrc.m_pPointer ) { this->m_pPointer = new Type(); this->m_pPointer->set(oSrc->get()); } return *this; } const std::wstring& get_value_or(const std::wstring& value) const { if (NULL == this->m_pPointer) return value; return this->m_pPointer->get(); } const std::wstring& get_value() const { return this->m_pPointer->get(); } Type& operator*() { return *this->m_pPointer; } Type* operator->() { return this->m_pPointer; } Type& operator*() const { return *this->m_pPointer; } Type* operator->() const { return this->m_pPointer; } const Type& get()const { return *this->m_pPointer; } }; class nullable_int : public nullable_base { public: nullable_int() : nullable_base() { } void normalize(const int& min, const int& max) { if (IsInit()) { if (*m_pPointer < min) *m_pPointer = min; else if (*m_pPointer > max) *m_pPointer = max; } } void normalize_positive() { if (IsInit()) { if (*m_pPointer < 0) *m_pPointer = 0; } } nullable_int& operator=(const wchar_t* cwsValue) { RELEASEOBJECT(m_pPointer); if ( NULL != cwsValue ) m_pPointer = new int(XmlUtils::GetInteger(cwsValue)); return *this; } void operator=(const std::wstring& value) { RELEASEOBJECT(this->m_pPointer); this->m_pPointer = new int(XmlUtils::GetInteger(value)); } void operator=(const int& value) { RELEASEOBJECT(this->m_pPointer); this->m_pPointer = new int(value); } std::wstring ToString() const { return std::to_wstring(*m_pPointer); } nullable_int& operator=(const nullable_int& oSrc) { RELEASEOBJECT(m_pPointer); if (NULL != oSrc.m_pPointer ) m_pPointer = new int(*oSrc); return *this; } const bool operator==(const nullable_int& oOther) const { if ( !this->m_pPointer ) return false; return (*this->m_pPointer) == *oOther; } const bool operator==(const int& oOther) const { if ( !this->m_pPointer ) return false; return (*this->m_pPointer) == oOther; } int get_value_or(const int& value) const { if (NULL == m_pPointer) { int ret = value; return ret; } return *m_pPointer; } std::wstring ToAttribute(const std::wstring & name) const { if (m_pPointer) { return name + L"=\"" + std::to_wstring(*m_pPointer) + L"\" "; } return L""; } int& operator*() { return *m_pPointer; } int* operator->() { return m_pPointer; } int& operator*() const { return *m_pPointer; } int* operator->() const { return m_pPointer; } const int& get()const { return *m_pPointer; } }; class nullable_uint : public nullable_base { public: nullable_uint() : nullable_base() { } void normalize(const unsigned int& min, const unsigned int& max) { if (IsInit()) { if (*m_pPointer < min) *m_pPointer = min; else if (*m_pPointer > max) *m_pPointer = max; } } void normalize_positive() { if (IsInit()) { if ((int)(*m_pPointer) < 0) *m_pPointer = 0; } } nullable_uint& operator=(const wchar_t* cwsValue) { RELEASEOBJECT(m_pPointer); if ( NULL != cwsValue ) m_pPointer = new unsigned int(XmlUtils::GetUInteger(cwsValue)); return *this; } void operator=(const std::wstring& value) { RELEASEOBJECT(this->m_pPointer); this->m_pPointer = new unsigned int(XmlUtils::GetUInteger(value)); } void operator=(const unsigned int& value) { RELEASEOBJECT(this->m_pPointer); this->m_pPointer = new unsigned int(value); } nullable_uint& operator=(const nullable_uint& oSrc) { RELEASEOBJECT(m_pPointer); if (NULL != oSrc.m_pPointer ) m_pPointer = new unsigned int(*oSrc); return *this; } unsigned int* GetPointerEmptyNullable() { unsigned int* pOldPointer = this->m_pPointer; this->m_pPointer = NULL; return pOldPointer; } unsigned int get_value_or(const unsigned int& value) const { if (NULL == m_pPointer) { unsigned int ret = value; return ret; } return *m_pPointer; } unsigned int& operator*() { return *m_pPointer; } unsigned int* operator->() { return m_pPointer; } unsigned int& operator*() const { return *m_pPointer; } unsigned int* operator->() const { return m_pPointer; } const unsigned int& get()const { return *m_pPointer; } }; class nullable_int64 : public nullable_base<_INT64> { public: nullable_int64() : nullable_base<_INT64>() { } void normalize(const _INT64& min, const _INT64& max) { if (IsInit()) { if (*m_pPointer < min) *m_pPointer = min; else if (*m_pPointer > max) *m_pPointer = max; } } void normalize_positive() { if (IsInit()) { if (*m_pPointer < 0) *m_pPointer = 0; } } nullable_int64& operator=(const wchar_t* cwsValue) { RELEASEOBJECT(m_pPointer); if ( NULL != cwsValue ) m_pPointer = new _INT64(XmlUtils::GetInteger64(cwsValue)); return *this; } void operator=(const std::wstring& value) { RELEASEOBJECT(this->m_pPointer); this->m_pPointer = new _INT64(XmlUtils::GetInteger64(value)); } void operator=(const _INT64& value) { RELEASEOBJECT(this->m_pPointer); this->m_pPointer = new _INT64(value); } nullable_int64& operator=(const nullable_int64& oSrc) { RELEASEOBJECT(m_pPointer); if (NULL != oSrc.m_pPointer ) m_pPointer = new _INT64(*oSrc); return *this; } std::wstring ToAttribute(const std::wstring & name) const { if (m_pPointer) { return name + L"=\"" + std::to_wstring(*m_pPointer) + L"\" "; } return L""; } _INT64 get_value_or(const _INT64& value) const { if (NULL == m_pPointer) { int ret = (int)value; return ret; } return *m_pPointer; } _INT64& operator*() { return *m_pPointer; } _INT64* operator->() { return m_pPointer; } _INT64& operator*() const { return *m_pPointer; } _INT64* operator->() const { return m_pPointer; } const _INT64& get()const { return *m_pPointer; } }; class nullable_sizet : public nullable_base { public: nullable_sizet() : nullable_base() { } void normalize(const size_t& max) { if (IsInit()) { if (*m_pPointer > max) *m_pPointer = max; } } nullable_sizet& operator=(const std::wstring & sValue) { RELEASEOBJECT(m_pPointer); if ( !sValue.empty() ) m_pPointer = new size_t((size_t)XmlUtils::GetUInteger(sValue)); return *this; } void operator=(const size_t& value) { RELEASEOBJECT(m_pPointer); m_pPointer = new size_t(value); } nullable_sizet& operator=(const nullable_sizet& oSrc) { RELEASEOBJECT(m_pPointer); if ( NULL != oSrc.m_pPointer ) m_pPointer = new size_t(*oSrc); return *this; } size_t get_value_or(const size_t& value) const { if (NULL == m_pPointer) { size_t ret = value; return ret; } return *m_pPointer; } std::wstring ToAttribute(const std::wstring & name) const { if (m_pPointer) { return name + L"=\"" + std::to_wstring(*m_pPointer) + L"\" "; } return L""; } size_t& operator*() { return *m_pPointer; } size_t* operator->() { return m_pPointer; } size_t& operator*() const { return *m_pPointer; } size_t* operator->() const { return m_pPointer; } const size_t& get()const { return *m_pPointer; } }; class nullable_double : public nullable_base { public: nullable_double() : nullable_base() { } void normalize(const double& min, const double& max) { if (IsInit()) { if (*m_pPointer < min) *m_pPointer = min; else if (*m_pPointer > max) *m_pPointer = max; } } nullable_double& operator=(const std::wstring & sValue) { RELEASEOBJECT(m_pPointer); if ( !sValue.empty() ) m_pPointer = new double(XmlUtils::GetDouble(sValue)); return *this; } void operator=(const double& value) { RELEASEOBJECT(m_pPointer); m_pPointer = new double(value); } std::wstring ToAttribute(const std::wstring & name) const { if (m_pPointer) { return name + L"=\"" + std::to_wstring(*m_pPointer) + L"\" "; } return L""; } nullable_double& operator=(const nullable_double& oSrc) { RELEASEOBJECT(m_pPointer); if ( NULL != oSrc.m_pPointer ) m_pPointer = new double(*oSrc); return *this; } double get_value_or(const double& value) const { if (NULL == m_pPointer) { double ret = value; return ret; } return *m_pPointer; } double* GetPointerEmptyNullable() { double* pOldPointer = this->m_pPointer; this->m_pPointer = NULL; return pOldPointer; } double& operator*() { return *m_pPointer; } double* operator->() { return m_pPointer; } double& operator*() const { return *m_pPointer; } double* operator->() const { return m_pPointer; } const double& get()const { return *m_pPointer; } }; class nullable_bool : public nullable_base { public: nullable_bool() : nullable_base() { } protected: bool set(const std::wstring& value) { if ((L"true" == value) || (L"1" == value)) return true; return false; } public: nullable_bool& operator=(const std::wstring &sValue) { RELEASEOBJECT(m_pPointer); if (!sValue.empty() ) m_pPointer = new bool(XmlUtils::GetBoolean2(sValue)); return *this; } nullable_bool& operator=(const wchar_t* cwsValue) { RELEASEOBJECT(m_pPointer); if ( NULL != cwsValue ) m_pPointer = new bool(XmlUtils::GetBoolean2(cwsValue)); return *this; } void operator=(const bool& value) { RELEASEOBJECT(m_pPointer); m_pPointer = new bool(value); } nullable_bool& operator=(const nullable_bool& oSrc) { RELEASEOBJECT(m_pPointer); if ( NULL != oSrc.m_pPointer ) m_pPointer = new bool(*oSrc); return *this; } std::wstring ToAttribute(const std::wstring & name) const { if (m_pPointer) { return name + L"=\"" + (*m_pPointer ? L"1" : L"0") + L"\" "; } return L""; } bool get_value_or(const bool& value) const { if (NULL == m_pPointer) { bool ret = value; return ret; } return *m_pPointer; } bool* GetPointerEmptyNullable() { bool* pOldPointer = this->m_pPointer; this->m_pPointer = NULL; return pOldPointer; } bool& operator*() { return *m_pPointer; } bool* operator->() { return m_pPointer; } bool& operator*() const { return *m_pPointer; } bool* operator->() const { return m_pPointer; } const bool& get()const { return *m_pPointer; } }; class nullable_string : public nullable_base { public: nullable_string() : nullable_base() { } nullable_string(const nullable_string& oOther) { if (NULL == oOther.m_pPointer) m_pPointer = NULL; else m_pPointer = new std::wstring(*oOther.m_pPointer); } void operator=(const std::wstring& value) { RELEASEOBJECT(m_pPointer); m_pPointer = new std::wstring(value); } void operator+=(const std::wstring& value) { if (NULL == m_pPointer) m_pPointer = new std::wstring(value); else *m_pPointer += value; } void operator=(std::wstring* value) { RELEASEOBJECT(m_pPointer); m_pPointer = value; } nullable_string& operator=(const nullable_string& oSrc) { RELEASEOBJECT(m_pPointer); if (NULL != oSrc.m_pPointer) m_pPointer = new std::wstring(*oSrc); return *this; } const bool operator==(const nullable_string& oOther) const { if (!this->m_pPointer) return false; return (*this->m_pPointer) == *oOther; } const bool operator==(const std::wstring& oOther) const { if (!this->m_pPointer) return false; return (*this->m_pPointer) == oOther; } std::wstring get_value_or(const std::wstring& value) const { if (NULL == m_pPointer) { std::wstring ret = value; return ret; } return *m_pPointer; } std::wstring ToAttribute(const std::wstring & name) const { if (m_pPointer) { return name + L"=\"" + (*m_pPointer) + L"\" "; } return L""; } std::wstring* GetPointerEmptyNullable() { std::wstring* pOldPointer = this->m_pPointer; this->m_pPointer = NULL; return pOldPointer; } std::wstring& operator*() { return *m_pPointer; } std::wstring* operator->() { return m_pPointer; } std::wstring& operator*() const { return *m_pPointer; } std::wstring* operator->() const { return m_pPointer; } std::wstring& get()const { return *m_pPointer; } }; class nullable_astring : public nullable_base { public: nullable_astring() : nullable_base() { } nullable_astring(const nullable_astring& oOther) { if (NULL == oOther.m_pPointer) m_pPointer = NULL; else m_pPointer = new std::string(*oOther.m_pPointer); } void operator=(const std::string& value) { RELEASEOBJECT(m_pPointer); m_pPointer = new std::string(value); } void operator+=(const std::string& value) { if (NULL == m_pPointer) m_pPointer = new std::string(value); else *m_pPointer += value; } void operator=(std::string* value) { RELEASEOBJECT(m_pPointer); m_pPointer = value; } nullable_astring& operator=(const nullable_astring& oSrc) { RELEASEOBJECT(m_pPointer); if (NULL != oSrc.m_pPointer) m_pPointer = new std::string(*oSrc); return *this; } const bool operator==(const nullable_astring& oOther) const { if (!this->m_pPointer) return false; return (*this->m_pPointer) == *oOther; } const bool operator==(const std::string& oOther) const { if (!this->m_pPointer) return false; return (*this->m_pPointer) == oOther; } std::string get_value_or(const std::string& value) const { if (NULL == m_pPointer) { std::string ret = value; return ret; } return *m_pPointer; } std::string ToAttribute(const std::string& name) const { if (m_pPointer) { return name + "=\"" + (*m_pPointer) + "\" "; } return ""; } std::string* GetPointerEmptyNullable() { std::string* pOldPointer = this->m_pPointer; this->m_pPointer = NULL; return pOldPointer; } std::string& operator*() { return *m_pPointer; } std::string* operator->() { return m_pPointer; } std::string& operator*() const { return *m_pPointer; } std::string* operator->() const { return m_pPointer; } std::string& get()const { return *m_pPointer; } }; }