/* * (c) Copyright Ascensio System SIA 2010-2014 * * 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 Lubanas st. 125a-25, Riga, Latvia, * EU, LV-1021. * * 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 * */ #ifndef STRUCTURES #define STRUCTURES #if _MSC_VER >= 1000 #pragma once #endif #ifndef max #define max(a,b) (((a) > (b)) ? (a) : (b)) #endif #ifndef min #define min(a,b) (((a) < (b)) ? (a) : (b)) #endif namespace Structures { struct POINTI { int x; int y; POINTI() { x = y = 0; } POINTI(int _x, int _y) { x = _x; y = _y; } POINTI(const POINTI& point) { operator= (point); } POINTI(const POINT& point) { operator= (point); } POINTI& operator= (const POINTI& point) { x = point.x; y = point.y; return *this; } POINTI& operator= (const POINT& point) { x = point.x; y = point.y; return *this; } operator POINT() const { POINT point; point.x = x; point.y = y; return point; } friend BOOL operator== (const POINTI& point1, const POINTI& point2) { return (point1.x == point2.x && point1.y == point2.y); } friend BOOL operator!= (const POINTI& point1, const POINTI& point2) { return (point1.x != point2.x || point1.y != point2.y); } void Create(int _x, int _y) { x = _x; y = _y; } }; struct POINTD { double x; double y; POINTD() { x = y = 0.0; } POINTD(double _x, double _y) { x = _x; y = _y; } POINTD(const POINTD& point) { operator= (point); } POINTD& operator= (const POINTD& point) { x = point.x; y = point.y; return *this; } void Create(double _x, double _y) { x = _x; y = _y; } }; struct RECTI { int left; int top; int right; int bottom; RECTI() { left = top = right = bottom = 0; } RECTI(int x, int y) { left = right = x; top = bottom = y; } RECTI(int _left, int _top, int _right, int _bottom) { left = _left; top = _top; right = _right; bottom = _bottom; } RECTI(const RECTI& rect) { operator= (rect); } RECTI(const RECT& rect) { operator= (rect); } RECTI& operator= (const RECT& rect) { left = rect.left; top = rect.top; right = rect.right; bottom = rect.bottom; return *this; } RECTI& operator= (const RECTI& rect) { left = rect.left; top = rect.top; right = rect.right; bottom = rect.bottom; return *this; } friend BOOL operator== (const RECTI& rect1, const RECTI& rect2) { return (rect1.left == rect2.left && rect1.top == rect2.top && rect1.right == rect2.right && rect1.bottom == rect2.bottom); } friend BOOL operator!= (const RECTI& rect1, const RECTI& rect2) { return (rect1.left != rect2.left || rect1.top != rect2.top || rect1.right != rect2.right || rect1.bottom != rect2.bottom); } void Normalize() { RECTI rect = *this; if (left > right) { right = rect.left; left = rect.right; } if (top > bottom) { bottom = rect.top; top = rect.bottom; } } int GetWidth() { return right - left; } int GetHeight() { return bottom - top; } BOOL IsPointInside(const POINTI& point) { Normalize(); if (point.x >= left && point.x <= right && point.y >= top && point.y <= bottom) return TRUE; return FALSE; } POINTI GetCenter() { return POINTI((left + right)/2, (top + bottom)/2); } void SetCener(int x, int y) { int cx = (left + right)/2; int cy = (top + bottom)/2; left = x + (left - cx); top = y + (top - cy); right = x + (right - cx); bottom = y + (bottom - cy); } void Offset(int x, int y) { left += x; top += y; right += x; bottom += y; } }; struct RECTD { double left; double top; double right; double bottom; RECTD() { left = top = right = bottom = 0.0; } RECTD(double x, double y) { left = right = x; top = bottom = y; } RECTD(double _left, double _top, double _right, double _bottom) { left = _left; top = _top; right = _right; bottom = _bottom; } RECTD(const RECTD& rect) { operator= (rect); } RECTD(const RECTI& rect) { operator= (rect); } RECTD(const RECT& rect) { operator= (rect); } RECTD& operator= (const RECTI& rect) { left = rect.left; top = rect.top; right = rect.right; bottom = rect.bottom; return *this; } RECTD& operator= (const RECTD& rect) { left = rect.left; top = rect.top; right = rect.right; bottom = rect.bottom; return *this; } RECTD& operator= (const RECT& rect) { left = rect.left; top = rect.top; right = rect.right; bottom = rect.bottom; return *this; } void Normalize() { RECTD rect = *this; if (left > right) { right = rect.left; left = rect.right; } if (top > bottom) { bottom = rect.top; top = rect.bottom; } } double GetWidth() { return right - left; } double GetHeight() { return bottom - top; } BOOL IsPointInside(const POINTD& point) { Normalize(); if (point.x >= left && point.x <= right && point.y >= top && point.y <= bottom) return TRUE; return FALSE; } POINTD GetCenter() { return POINTD(0.5*(left + right), 0.5*(top + bottom)); } void SetCenter(double x, double y) { double cx = 0.5*(left + right); double cy = 0.5*(top + bottom); left = x + (left - cx); top = y + (top - cy); right = x + (right - cx); bottom = y + (bottom - cy); } void Offset(double x, double y) { left += x; top += y; right += x; bottom += y; } }; } namespace Templates { template class CArray { public: CArray() : m_pData(NULL) , m_nSize(0) , m_nMaxSize(0) , m_nGrowBy(0) { } ~CArray() { RemoveAll(); } int GetCount() const { return m_nSize; } BOOL IsEmpty() const { return (0>=m_nSize); } BOOL SetCount( int nNewSize, int nGrowBy = -1 ) { if (-1!=nGrowBy) { m_nGrowBy = nGrowBy; } if (0==nNewSize) { if(NULL!=m_pData) { CallDestructors(m_pData, m_nSize); free(m_pData); m_pData = NULL; } m_nSize = 0; m_nMaxSize = 0; } else if (nNewSize <= m_nMaxSize) { if( nNewSize > m_nSize ) { CallConstructors(m_pData+m_nSize, nNewSize - m_nSize); } else if (m_nSize > nNewSize) { CallDestructors(m_pData+nNewSize, m_nSize - nNewSize); } m_nSize = nNewSize; } else { if (!GrowBuffer(nNewSize)) return FALSE; CallConstructors(m_pData+m_nSize, nNewSize - m_nSize); m_nSize = nNewSize; } return TRUE; } void RemoveAll() { SetCount(0, -1); } const E& GetAt(int nIndex) const { if (0>nIndex) nIndex = 0; else if (nIndex>=m_nSize) nIndex = m_nSize; return m_pData[nIndex]; } void SetAt(int nIndex, const E &oElement) { if ((0>nIndex)||(nIndex>=m_nSize)) return; m_pData[nIndex] = oElement; } E& GetAt(int nIndex) { if (0>nIndex) nIndex = 0; else if (nIndex>=m_nSize) nIndex = m_nSize; return m_pData[nIndex]; } int Add(const E& oElement) { int nIndex = m_nSize; if (nIndex >= m_nMaxSize) { if (!GrowBuffer(nIndex+1)) return -1; } ::new(m_pData+nIndex)E(oElement); m_nSize++; return(nIndex); } int Append(const CArray&arSrc) { int nOldSize = m_nSize; if(!SetCount(m_nSize + arSrc.m_nSize)) return -1; memcpy(m_pData+nOldSize, arSrc.m_pData, arSrc.m_nSize*sizeof(E)); return( nOldSize ); } const E& operator[](int nIndex) const { return GetAt(nIndex); } E& operator[](int nIndex) { return GetAt(nIndex); } void InsertAt(int nIndex, const E& oElement) { if (nIndex>=m_nSize) { Add(oElement); return; } int nOldSize = m_nSize; if(!SetCount(m_nSize + 1, -1)) return; memcpy(m_pData + (nIndex + 1), m_pData + nIndex, sizeof(E)*(nOldSize-nIndex)); m_pData[nIndex] = oElement; } void InsertArrayAt(int nStart, const CArray &arNew) { if (nStart>=m_nSize) { Append(arNew); return; } int nNewArrayCount = arNew.GetCount(); int nOldSize = m_nSize; if(!SetCount(m_nSize + nNewArrayCount, -1)) return; memcpy(m_pData + (nStart + nNewArrayCount), m_pData + nStart, sizeof(E)*(nOldSize-nStart)); for (int nIndex = nStartl nIndexnIndex)||(nIndex>=m_nSize)) return; m_pData[nIndex].~E(); memcpy(m_pData + nIndex, m_pData + nIndex + 1, (m_nSize - nIndex)*sizeof(E)); m_nSize--; } private: BOOL GrowBuffer(int nNewSize) { if (nNewSize > m_nMaxSize) { if (NULL==m_pData) { int nAllocSize = (m_nGrowBy>nNewSize) ? m_nGrowBy : nNewSize; m_pData = static_cast(calloc(nAllocSize, sizeof(E))); if (NULL==m_pData) return FALSE; m_nMaxSize = nAllocSize; } else { int nGrowBy = m_nGrowBy; if (0==nGrowBy) { nGrowBy = m_nSize/8; nGrowBy = (nGrowBy < 4) ? 4 : ((nGrowBy > 1024) ? 1024 : nGrowBy); } int nNewMax = max(nNewSize, (m_nMaxSize+nGrowBy)); E* pNewData = static_cast(calloc(nNewMax, sizeof(E))); if (NULL==pNewData) { return FALSE; } memcpy(pNewData, m_pData, m_nSize*sizeof(E)); free(m_pData); m_pData = pNewData; m_nMaxSize = nNewMax; } } return TRUE; } private: E* m_pData; int m_nSize; int m_nMaxSize; int m_nGrowBy; void CallDestructors(E* pData, int nCount) { for (int i=0; i class CMap { public: class CPair { public: CPair(const K &oKey, const V &oValue) : m_key(oKey) , m_value(oValue) { } const K m_key; V m_value; }; public: CMap() { } ~CMap() { RemoveAll(); } void SetAt(const K &oKey, const V &oValue) { int nIndex = FindByKey(oKey); if (-1==nIndex) { CPair *pPair = new CPair(oKey, oValue); if (NULL==pPair) return; m_arPair.Add(pPair); } else { m_arPair[nIndex]->m_value = oValue; } } CPair *Lookup(const K &oKey) { int nIndex = FindByKey(oKey); if (-1==nIndex) return NULL; return m_arPair[nIndex]; } const CPair *Lookup(const K &oKey) const { int nIndex = FindByKey(oKey); if (-1==nIndex) return NULL; return m_arPair[nIndex]; } CPair *GetAt(int nIndex) { if ((nIndex<0)||(nIndex>=m_arPair.GetCount())) return NULL; return m_arPair[nIndex]; } const CPair *GetAt(int nIndex) const { if ((nIndex<0)||(nIndex>=m_arPair.GetCount())) return NULL; return m_arPair[nIndex]; } void RemoveKey(const K &oKey) { int nIndex = FindByKey(oKey); if (-1==nIndex) return; if (NULL!=m_arPair[nIndex]) delete m_arPair[nIndex]; m_arPair.RemoveAt(nIndex); } void RemoveAll() { int nCount = m_arPair.GetCount(); for (int nIndex = 0; nIndexm_key) return nIndex; } return -1; } CArray m_arPair; }; }; #endif//STRUCTURES