DocumentServer/ActiveX/Common/Structures.h
nikolay ivanov a8be6b9e72 init repo
2014-07-05 18:22:49 +00:00

718 lines
13 KiB
C++

/*
* (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<typename E>
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<E>&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<E> &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 nIndex<nNewArrayCount; nIndex++)
m_pData[nIndex] = arNew[nIndex];
}
void RemoveAt(int nIndex)
{
if ((0>nIndex)||(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<E*>(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<E*>(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<nCount; i++)
pData[i].~E();
}
void CallConstructors(E* pData, int nCount)
{
for (int i=0; i<nCount; i++)
::new(pData + i) E;
}
};
template<typename K, typename V>
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; nIndex<nCount; nIndex++)
{
if (NULL==m_arPair[nIndex])
continue;
delete m_arPair[nIndex];
}
m_arPair.RemoveAll();
}
int GetCount() const
{
return m_arPair.GetCount();
}
protected:
int FindByKey(const K &oKey) const
{
int nCount = m_arPair.GetCount();
for (int nIndex = 0; nIndex<nCount; nIndex++)
{
if (NULL==m_arPair[nIndex])
continue;
if (oKey==m_arPair[nIndex]->m_key)
return nIndex;
}
return -1;
}
CArray<CPair *> m_arPair;
};
};
#endif//STRUCTURES