Commit 1a7f397c authored by Ilya.Kirillov's avatar Ilya.Kirillov Committed by Alexander Trofimov

Реализовано чтение чисел с мантиссой. Реализованы градиенты. Реализован...

Реализовано чтение чисел с мантиссой. Реализованы градиенты. Реализован нормальный механизм работы с "брашами", теперь браш читается и из ресурсов. 

git-svn-id: svn://fileserver/activex/AVS/Sources/TeamlabOffice/trunk/ServerComponents@63537 954022d7-b5bf-4e40-9824-e11837661b57
parent a1c8d4d0
......@@ -21,12 +21,12 @@ namespace XPS
while (m_vResourcesStack.size())
PopResource();
}
void CContextState::PushOpacity(const double& dOpacity)
void CContextState::PushOpacity(const double& dOpacity)
{
m_dCurOpacity *= dOpacity;
m_vOpacity.push_back(m_dCurOpacity);
}
void CContextState::PopOpacity()
void CContextState::PopOpacity()
{
m_vOpacity.pop_back();
if (m_vOpacity.size())
......@@ -34,24 +34,24 @@ namespace XPS
else
m_dCurOpacity = 1;
}
double CContextState::GetCurrentOpacity()
double CContextState::GetCurrentOpacity()
{
return m_dCurOpacity;
}
void CContextState::PushTransform(const double arrTransform[6])
void CContextState::PushTransform(const double arrTransform[6])
{
Aggplus::CMatrix oTransform(arrTransform[0], arrTransform[1], arrTransform[2], arrTransform[3], arrTransform[4], arrTransform[5]);
m_oCurrentTransform.Multiply(&oTransform);
m_lTransformStack.push_back(m_oCurrentTransform);
SetTransformToRenderer();
}
void CContextState::PopTransform()
void CContextState::PopTransform()
{
m_lTransformStack.pop_back();
m_oCurrentTransform = m_lTransformStack.back();
SetTransformToRenderer();
}
double CContextState::NormalizeTransform()
double CContextState::NormalizeTransform()
{
agg::trans_affine& oMatrix = m_oCurrentTransform.m_agg_mtx;
double dDet = sqrt(oMatrix.sx * oMatrix.sy - oMatrix.shx * oMatrix.shy);
......@@ -65,12 +65,12 @@ namespace XPS
return dDet;
}
void CContextState::PushClip(const CWString& wsClip)
void CContextState::PushClip(const CWString& wsClip)
{
m_vClipStack.push_back(wsClip);
SetClipToRenderer(wsClip);
}
void CContextState::PopClip()
void CContextState::PopClip()
{
m_vClipStack.pop_back();
if (m_pRenderer)
......@@ -85,7 +85,7 @@ namespace XPS
}
}
}
void CContextState::SetTransformToRenderer()
void CContextState::SetTransformToRenderer()
{
if (m_pRenderer)
{
......@@ -94,7 +94,7 @@ namespace XPS
xpsUnitToMM(m_oCurrentTransform.m_agg_mtx.tx), xpsUnitToMM(m_oCurrentTransform.m_agg_mtx.ty));
}
}
void CContextState::SetClipToRenderer(const CWString& wsClip)
void CContextState::SetClipToRenderer(const CWString& wsClip)
{
if (!wsClip.empty() && m_pRenderer)
{
......@@ -108,11 +108,11 @@ namespace XPS
m_pRenderer->PathCommandEnd();
}
}
void CContextState::PushResource(CStaticResource* pResource, bool bOwn)
void CContextState::PushResource(CStaticResource* pResource, bool bOwn)
{
m_vResourcesStack.push_back(TStaticRecource(pResource, bOwn));
}
void CContextState::PopResource()
void CContextState::PopResource()
{
if (m_vResourcesStack.size())
{
......@@ -123,7 +123,7 @@ namespace XPS
m_vResourcesStack.pop_back();
}
}
void CContextState::GetPathGeometry(const CWString& _wsKey, CWString& wsPathData, CWString& wsPathTransform)
void CContextState::GetPathGeometry(const CWString& _wsKey, CWString& wsPathData, CWString& wsPathTransform)
{
if (_wsKey.size() < 17)
return;
......@@ -135,7 +135,7 @@ namespace XPS
for (int nIndex = m_vResourcesStack.size() - 1; nIndex >= 0; nIndex--)
{
pResource = m_vResourcesStack.at(nIndex).pResource;
wsPath = pResource->Get(wsKey);
wsPath = pResource->GetFigure(wsKey);
if (NULL != wsPath)
{
wsPathData.create(wsPath, true);
......@@ -143,4 +143,23 @@ namespace XPS
}
}
}
CBrush* CContextState::GetBrush(const CWString& _wsKey)
{
if (_wsKey.size() < 17)
return NULL;
CWString wsKey((wchar_t*)(_wsKey.c_str() + 16), false, _wsKey.size() - 17);
CBrush* pBrush = NULL;
CStaticResource* pResource;
for (int nIndex = m_vResourcesStack.size() - 1; nIndex >= 0; nIndex--)
{
pResource = m_vResourcesStack.at(nIndex).pResource;
pBrush = pResource->GetBrush(wsKey);
if (pBrush)
return pBrush;
}
return NULL;
}
}
\ No newline at end of file
......@@ -11,6 +11,7 @@
namespace XPS
{
class CBrush;
class CStaticResource;
class CContextState
......@@ -34,18 +35,23 @@ namespace XPS
CContextState(IRenderer* pRenderer);
~CContextState();
void PushOpacity(const double& dOpacity);
void PopOpacity();
double GetCurrentOpacity();
void PushClip(const CWString& wsClip);
void PopClip();
void PushTransform(const double arrTransform[6]);
void PopTransform();
double NormalizeTransform();
void PushResource(CStaticResource* pResource, bool bOwn);
void PopResource();
void GetPathGeometry(const CWString& wsKey, CWString& wsPathData, CWString& wsPathTransform);
void PushOpacity(const double& dOpacity);
void PopOpacity();
double GetCurrentOpacity();
void PushClip(const CWString& wsClip);
void PopClip();
void PushTransform(const double arrTransform[6]);
void PopTransform();
double NormalizeTransform();
void PushResource(CStaticResource* pResource, bool bOwn);
void PopResource();
void GetPathGeometry(const CWString& wsKey, CWString& wsPathData, CWString& wsPathTransform);
CBrush* GetBrush(const CWString& wsKey);
Aggplus::CMatrix GetCurrentTransform()
{
return m_oCurrentTransform;
}
private:
......
......@@ -132,99 +132,7 @@ namespace XPS
}
return true;
//Close();
//m_wsPath = wsPath;
//XmlUtils::CXmlNode oNode;
//XmlUtils::CXmlNodes arrNodes;
//XmlUtils::CXmlNode oSubnode;
//
//std::wstring wsRelsPath = NormalizePath(wsPath + L"_rels/.rels");
//clock_t oBeginTime = clock();
//if (!oNode.FromXmlFile(wsRelsPath.c_str()))
// return false;
//clock_t oEndTime = clock();
//double dElapsedSecs = double(oEndTime - oBeginTime) / CLOCKS_PER_SEC;
//printf("%S %fseconds\n", wsRelsPath.c_str(), dElapsedSecs);
//// Checking root node
//if (L"Relationships" != oNode.GetName())
// return false;
//if (!oNode.GetNodes(L"Relationship", arrNodes))
// return false;
//std::wstring wsFile;
//for (int nIndex = 0, nCount = arrNodes.GetCount(); nIndex < nCount; nIndex++)
//{
// arrNodes.GetAt(nIndex, oNode);
// if (L"http://schemas.microsoft.com/xps/2005/06/fixedrepresentation" == oNode.GetAttribute(L"Type"))
// {
// wsFile = oNode.GetAttribute(L"Target");
// break;
// }
// if (nIndex == nCount - 1)
// return false;
//}
//oBeginTime = clock();
//if (!oNode.FromXmlFile((wsPath + wsFile).c_str()))
// return false;
//oEndTime = clock();
//dElapsedSecs = double(oEndTime - oBeginTime) / CLOCKS_PER_SEC;
//printf("%S %fseconds\n", (wsPath + wsFile).c_str(), dElapsedSecs);
//// Checking root node
//if (L"FixedDocumentSequence" != oNode.GetName())
// return false;
//if (!oNode.GetNode(L"DocumentReference", oSubnode))
// return false;
//wsFile = oSubnode.GetAttribute(L"Source");
//oBeginTime = clock();
//if (!oNode.FromXmlFile((m_wsPath + wsFile).c_str()))
// return false;
//oEndTime = clock();
//dElapsedSecs = double(oEndTime - oBeginTime) / CLOCKS_PER_SEC;
//printf("%S %fseconds\n", (m_wsPath + wsFile).c_str(), dElapsedSecs);
//if (L"FixedDocument" != oNode.GetName())
// return false;
//if (!oNode.GetNodes(L"PageContent", arrNodes))
// return false;
//std::wstring wsFilePath = GetPath(m_wsPath + wsFile);
//std::wstring wsPagePath;
//std::wstring wsSource;
//for (int nIndex = 0, nCount = arrNodes.GetCount(); nIndex < nCount; nIndex++)
//{
// arrNodes.GetAt(nIndex, oNode);
// wsSource = oNode.GetAttribute(L"Source");
// if('/' == wsSource[0])
// wsPagePath = m_wsPath + wsSource;
// else
// wsPagePath = wsFilePath + wsSource;
// m_mPages.insert(std::pair<int, XPS::Page*>(nIndex, new XPS::Page(wsPagePath, wsPath, &m_oFontList, m_pFontManager)));
//}
//return true;
return true;
}
int CDocument::GetPageCount()const
{
......
This diff is collapsed.
......@@ -29,7 +29,6 @@ namespace XPS
bool ReadResource (XmlUtils::CXmlLiteReader& oReader, IRenderer* pRenderer, CContextState* pState);
void DrawGlyph (XmlUtils::CXmlLiteReader& oReader, IRenderer* pRenderer, CContextState* pState);
void DrawPath (XmlUtils::CXmlLiteReader& oReader, IRenderer* pRenderer, CContextState* pState);
bool FillToRenderer (XmlUtils::CXmlLiteReader& oReader, IRenderer* pRenderer, CContextState* pState);
bool StrokeToRenderer(XmlUtils::CXmlLiteReader& oReader, IRenderer* pRenderer, CContextState* pState);
void ReadPathData (XmlUtils::CXmlLiteReader& oReader, CWString& wsData, CWString& wsTranform);
......
This diff is collapsed.
#ifndef _XPS_XPSLIB_STATICRESOURCES_H
#define _XPS_XPSLIB_STATICRESOURCES_H
#include "Utils.h"
#include <map>
class XmlUtils::CXmlLiteReader;
class XPS::CWString;
class IRenderer;
namespace XPS
{
class CBrush;
class CStaticResource
{
public:
CStaticResource(const wchar_t* wsPath);
CStaticResource(XmlUtils::CXmlLiteReader& oReader);
~CStaticResource();
const wchar_t* GetFigure(CWString& wsKey);
CBrush* GetBrush(CWString& wsKey);
private:
void Parse(XmlUtils::CXmlLiteReader& oReader);
void AddFigure(const CWString& wsKey, const CWString& wsValue);
void AddBrush(const CWString& wsKey, CBrush* pBrush);
private:
std::map<CWString, CWString> m_mFigures;
std::map<CWString, CBrush*> m_mBrushes;
};
class CBrush
{
public:
CBrush(){}
virtual ~CBrush(){}
virtual bool SetToRenderer(IRenderer* pRenderer) { return false; }
virtual bool IsImageBrush() { return false; }
};
class CSolidBrush : public CBrush
{
public:
CSolidBrush(int nBgr, int nAlpha) : m_nBgr(nBgr), m_nAlpha(nAlpha){}
bool SetToRenderer(IRenderer* pRenderer);
private:
int m_nBgr;
int m_nAlpha;
};
class CImageBrush : public CBrush
{
public:
CImageBrush(const wchar_t* wsPath)
{
m_wsPath.create(wsPath, true);
}
bool SetToRenderer(IRenderer* pRenderer);
bool IsImageBrush() { return true; }
void SetPaths(const wchar_t* wsRoot, const wchar_t* wsPage);
private:
CWString m_wsPath;
CWString m_wsRoot;
CWString m_wsPage;
};
class CGradientBrush : public CBrush
{
public:
CGradientBrush()
{
m_pColors = NULL;
m_pPositions = NULL;
m_lCount = 0;
}
virtual ~CGradientBrush()
{
RELEASEARRAYOBJECTS(m_pColors);
RELEASEARRAYOBJECTS(m_pPositions);
}
void SetGradientStops(LONG* pColors, double* pPositions, LONG lCount)
{
m_pColors = pColors;
m_pPositions = pPositions;
m_lCount = lCount;
}
protected:
LONG* m_pColors;
double* m_pPositions;
LONG m_lCount;
};
class CLinearGradientBrush : public CGradientBrush
{
public:
CLinearGradientBrush(const double& dX0, const double& dY0, const double& dX1, const double& dY1) : m_dX0(dX0), m_dY0(dY0), m_dX1(dX1), m_dY1(dY1)
{
}
bool SetToRenderer(IRenderer* pRenderer);
private:
double m_dX0;
double m_dY0;
double m_dX1;
double m_dY1;
};
class CRadialGradientBrush : public CGradientBrush
{
public:
CRadialGradientBrush(const double& dXcenter, const double& dYcenter, const double& dXorigin, const double& dYorigin, const double& dRadX, const double& dRadY) :
m_dXc(dXcenter), m_dYc(dYcenter), m_dXo(dXorigin), m_dYo(dYorigin), m_dRadX(dRadX), m_dRadY(dRadY)
{
}
bool SetToRenderer(IRenderer* pRenderer);
private:
double m_dXc;
double m_dYc;
double m_dXo;
double m_dYo;
double m_dRadX;
double m_dRadY;
};
CBrush* ReadBrushNode(XmlUtils::CXmlLiteReader& oReader, const double& dOpacity = 1.0, CWString* pwsKey = NULL);
CBrush* ReadBrush(XmlUtils::CXmlLiteReader& oReader, const double& dOpacity = 1.0, CWString* pwsKey = NULL);
CBrush* ReadBrush(const wchar_t* wsString, const double& dOpacity = 1.0);
}
#endif //_XPS_XPSLIB_STATICRESOURCES_H
\ No newline at end of file
......@@ -24,7 +24,9 @@
|| '8' == (X)\
|| '9' == (X)\
|| '-' == (X)\
|| '.' == (X))
|| '.' == (X)\
|| 'e' == (X)\
|| 'E' == (X))
#define GetChar(STRING, POS) STRING[POS++]
#define LookChar(STRING, POS) STRING[POS]
......@@ -106,6 +108,12 @@ namespace XPS
dFloat = (double)nInt;
goto doReal;
}
else if ('e' == wChar || 'E' == wChar)
{
nPos++;
dFloat = (double)nInt;
goto doExponent;
}
else
{
break;
......@@ -119,7 +127,13 @@ namespace XPS
while (1)
{
wChar = LookChar(wsString, nPos);
if (!isdigit(wChar))
if ('e' == wChar || 'E' == wChar)
{
nPos++;
goto doExponent;
}
else if (!isdigit(wChar))
break;
nPos++;
......@@ -128,6 +142,49 @@ namespace XPS
}
return (bNegative ? (double)(-dFloat) : (double)dFloat);
doExponent:
wChar = GetChar(wsString, nPos);
bool bNegativeExponent = false;
int nExp = 0;
if ('-' == wChar)
{
bNegativeExponent = true;
}
else if ('+' == wChar)
{
bNegativeExponent = false;
}
else
{
nExp = wChar - '0';
}
while (1)
{
wChar = LookChar(wsString, nPos);
if (!isdigit(wChar))
break;
nPos++;
nExp = nExp * 10 + (wChar - '0');
}
dFloat = (bNegative ? (double)(-dFloat) : (double)dFloat);
nExp = max(20, min(0, nExp));
while (nExp)
{
if (bNegativeExponent)
dFloat /= 10;
else
dFloat *= 10;
nExp--;
}
return dFloat;
}
return 0.0;
......@@ -312,6 +369,10 @@ namespace XPS
{
return (((wChar >= 'A') && (wChar <= 'Z')) || ((wChar >= 'a') && (wChar <= 'z')));
}
double GetDouble(const CWString& wsString)
{
return _wtof(wsString.c_str());
}
double GetDouble(const std::wstring& wsString)
{
return _wtof(wsString.c_str());
......@@ -984,7 +1045,7 @@ namespace XPS
else
return false; //
}
void ReadTransform (XmlUtils::CXmlLiteReader& oReader, CWString& wsTransform, CWString* pwsKey)
void ReadTransform (XmlUtils::CXmlLiteReader& oReader, CWString& wsTransform, CWString* pwsKey)
{
CWString wsNodeName;
int nCurDepth = oReader.GetDepth();
......@@ -1006,13 +1067,18 @@ namespace XPS
wsTransform.create(oReader.GetText(), true);
else if (wsAttrName == L"x:Key" && pwsKey)
pwsKey->create(oReader.GetText(), true);
if (!oReader.MoveToNextAttribute())
break;
wsAttrName = oReader.GetName();
}
oReader.MoveToElement();
}
}
}
void ReadPathGeometry(XmlUtils::CXmlLiteReader& oReader, CWString& wsData, CWString& wsTransform, CWString* pwsKey)
void ReadPathGeometry (XmlUtils::CXmlLiteReader& oReader, CWString& wsData, CWString& wsTransform, CWString* pwsKey)
{
bool bEvenOdd = true;
CWString wsAttrName;
......@@ -1056,7 +1122,7 @@ namespace XPS
ReadPathFigure(oReader, wsData, bEvenOdd);
}
}
void ReadPathFigure (XmlUtils::CXmlLiteReader& oReader, CWString& _wsData, bool bEvenOdd)
void ReadPathFigure (XmlUtils::CXmlLiteReader& oReader, CWString& _wsData, bool bEvenOdd)
{
// TODO:
std::wstring wsData;
......@@ -1142,4 +1208,145 @@ namespace XPS
_wsData.create(wsData.c_str(), true);
}
void ReadGradientStops(XmlUtils::CXmlLiteReader& oReader, std::vector<LONG>& vColors, std::vector<double>& vPositions, const double& dOpacity)
{
if (oReader.IsEmptyNode())
return;
CWString wsNodeName, wsAttrName;
int nCurDepth = oReader.GetDepth();
while (oReader.ReadNextSiblingNode(nCurDepth))
{
wsNodeName = oReader.GetName();
if (wsNodeName == L"GradientStop")
{
double dPos = 0;
LONG lColor = 0;
if (oReader.MoveToFirstAttribute())
{
wsAttrName = oReader.GetName();
while (!wsAttrName.empty())
{
if (wsAttrName == L"Color")
{
int nBgr, nAlpha;
ReadSTColor(oReader.GetText(), nBgr, nAlpha);
nAlpha *= dOpacity;
lColor = (nAlpha << 24 & 0xFF000000) | (nBgr & 0xFFFFFF);
}
else if (wsAttrName == L"Offset")
{
ReadSTDouble(oReader.GetText(), dPos);
}
if (!oReader.MoveToNextAttribute())
break;
wsAttrName = oReader.GetName();
}
oReader.MoveToElement();
}
vColors.push_back(lColor);
vPositions.push_back(dPos);
}
}
}
void ReadSTPoint(const CWString& wsString, double& dX, double& dY)
{
int nCommaPos = 0;
while (nCommaPos < wsString.size())
{
if (wsString[nCommaPos] == ',')
break;
nCommaPos++;
}
if (nCommaPos >= wsString.size())
{
CWString wsX = wsString.c_str();
dX = GetDouble(wsX);
dY = 0;
}
else
{
CWString wsX((wchar_t*)wsString.c_str(), false, nCommaPos);
CWString wsY((wchar_t*)(wsString.c_str() + nCommaPos + 1), false, wsString.size() - nCommaPos - 1);
dX = GetDouble(wsX);
dY = GetDouble(wsY);
}
}
void ReadSTColor(const CWString& wsString, int& nBgr, int& nAlpha)
{
int nLen = wsString.size();
if (nLen <= 0)
return;
const wchar_t* pBuffer = wsString.c_str();
if (L'#' == pBuffer[0])
{
nLen--;
pBuffer++;
if (6 != nLen && 8 != nLen)
return;
if (8 == nLen)
{
nAlpha = GetDigit(*pBuffer++);
nAlpha <<= 4;
nAlpha += GetDigit(*pBuffer++);
}
else
{
nAlpha = 255;
}
nBgr = GetDigit(pBuffer[4]);
nBgr <<= 4;
nBgr += GetDigit(pBuffer[5]);
nBgr <<= 4;
nBgr += GetDigit(pBuffer[2]);
nBgr <<= 4;
nBgr += GetDigit(pBuffer[3]);
nBgr <<= 4;
nBgr += GetDigit(pBuffer[0]);
nBgr <<= 4;
nBgr += GetDigit(pBuffer[1]);
}
else if (nLen >= 3 && L's' == pBuffer[0] && L'c' == pBuffer[1] && L'#' == pBuffer[2])
{
int nPos = 3;
if (nPos >= nLen)
return;
CWString wsString2;
wsString2.create(pBuffer + 3, false);
std::vector<CWString> vElements = wsString2.split(',');
if (3 == vElements.size())
{
nAlpha = 255;
nBgr = (((int)(min(GetDouble(vElements[2]), 1.0) * 255)) << 16) + (((int)(min(GetDouble(vElements[1]), 1.0) * 255)) << 8) + ((int)(min(GetDouble(vElements[0]), 1.0) * 255));
}
else if (4 == vElements.size())
{
nAlpha = (int)(min(GetDouble(vElements[0]), 1.0) * 255);
nBgr = (((int)(min(GetDouble(vElements[3]), 1.0) * 255)) << 16) + (((int)(min(GetDouble(vElements[2]), 1.0) * 255)) << 8) + ((int)(min(GetDouble(vElements[1]), 1.0) * 255));
}
}
}
void ReadSTColor(const CWString& wsString, LONG& lColor)
{
int nBgr, nAlpha;
ReadSTColor(wsString, nBgr, nAlpha);
lColor = (nAlpha << 24 & 0xFF000000) | (nBgr & 0xFFFFFF);
}
void ReadSTDouble(const CWString& wsString, double& dValue)
{
int nPos = 0;
dValue = GetDouble(wsString.c_str(), nPos, wsString.size());
}
}
\ No newline at end of file
......@@ -5,6 +5,8 @@
#include <vector>
#include "WString.h"
#include "../../DesktopEditor/common/Types.h"
namespace XmlUtils
{
class CXmlLiteReader;
......@@ -76,9 +78,16 @@ namespace XPS
bool VmlToRenderer(const wchar_t* wsString, IRenderer* pRenderer);
bool GetNextGlyph(const wchar_t* wsIndices, int& nIndicesPos, const int& nIndicesLen, unsigned short* pUtf16, int& nUtf16Pos, const int& nUtf16Len, TIndicesEntry& oEntry);
void ReadSTPoint(const CWString& wsString, double& dX, double& dY);
void ReadSTColor(const CWString& wsString, int& nBgr, int& nAlpha);
void ReadSTColor(const CWString& wsString, LONG& lColor);
void ReadSTDouble(const CWString& wsString, double& dValue);
void ReadTransform (XmlUtils::CXmlLiteReader& oReader, CWString& wsTransform, CWString* pwsKey = NULL);
void ReadPathGeometry(XmlUtils::CXmlLiteReader& oReader, CWString& wsData, CWString& wsTransform, CWString* pwsKey = NULL);
void ReadPathFigure (XmlUtils::CXmlLiteReader& oReader, CWString& _wsData, bool bEvenOdd);
void ReadGradientStops(XmlUtils::CXmlLiteReader& oReader, std::vector<LONG>& vColors, std::vector<double>& vPositions, const double& dOpacity);
}
#endif // _XPS_XPSLIB_UTILS_H
\ No newline at end of file
#include "WString.h"
#include "Utils.h"
#include "../../DesktopEditor/common/String.h"
#include "../../DesktopEditor/common/Types.h"
#define MAX_STRING_LEN 2147483648
namespace XPS
{
class CWStringBuffer
{
public:
CWStringBuffer(const wchar_t* wsString, unsigned int unLen)
{
if (unLen)
{
m_pBuffer = new wchar_t[unLen + 1];
m_pBuffer[unLen] = 0x00;
memcpy(m_pBuffer, wsString, sizeof(wchar_t) * unLen);
}
else
{
m_pBuffer = NULL;
}
m_nRefCount = 1;
}
void AddRef()
{
m_nRefCount++;
}
int Release()
{
return --m_nRefCount;
}
void Free()
{
RELEASEARRAYOBJECTS(m_pBuffer);
}
wchar_t operator[](const unsigned int& unIndex) const
{
return m_pBuffer[unIndex];
}
private:
wchar_t* m_pBuffer;
int m_nRefCount;
friend class CWString;
};
CWString::CWString()
{
m_bOwnBuffer = false;
m_pBuffer = NULL;
m_unLen = 0;
}
CWString::CWString(const wchar_t* wsString)
{
m_bOwnBuffer = false;
m_pBuffer = NULL;
m_unLen = 0;
create(wsString, false);
}
CWString::CWString(wchar_t* wsString, bool bCopy, int nLen)
{
m_bOwnBuffer = false;
m_pBuffer = NULL;
m_unLen = 0;
create(wsString, bCopy, nLen);
}
CWString::CWString(const CWString& wsString)
{
m_unLen = wsString.m_unLen;
m_bOwnBuffer = wsString.m_bOwnBuffer;
m_pBuffer = wsString.m_pBuffer;
if (m_bOwnBuffer && m_pBuffer)
((CWStringBuffer*)m_pBuffer)->AddRef();
}
CWString::~CWString()
{
clear();
}
void CWString::create(const wchar_t* wsString, bool bCopy, int nLen)
{
clear();
unsigned int unLen = -1 == nLen ? min(wcslen(wsString), MAX_STRING_LEN) : (unsigned int)nLen;
m_unLen = unLen;
if (bCopy)
{
if (unLen)
{
m_pBuffer = (void*)(new CWStringBuffer(wsString, m_unLen));
m_bOwnBuffer = true;
}
}
else
{
m_pBuffer = (void*)wsString;
m_bOwnBuffer = false;
}
}
void CWString::clear()
{
if (m_bOwnBuffer)
{
CWStringBuffer* pWStringBuffer = (CWStringBuffer*)m_pBuffer;
if (pWStringBuffer && !pWStringBuffer->Release())
delete pWStringBuffer;
}
m_bOwnBuffer = false;
m_pBuffer = NULL;
m_unLen = 0;
}
void CWString::operator=(const wchar_t* wsString)
{
clear();
create(wsString, false);
}
void CWString::operator=(const CWString& wsString)
{
clear();
m_unLen = wsString.m_unLen;
m_bOwnBuffer = wsString.m_bOwnBuffer;
m_pBuffer = wsString.m_pBuffer;
if (m_bOwnBuffer && m_pBuffer)
((CWStringBuffer*)m_pBuffer)->AddRef();
}
const wchar_t* CWString::c_str() const
{
if (m_bOwnBuffer)
{
CWStringBuffer* pWStringBuffer = (CWStringBuffer*)m_pBuffer;
if (pWStringBuffer)
return pWStringBuffer->m_pBuffer;
return NULL;
}
return (const wchar_t*)m_pBuffer;
}
bool CWString::operator<(const CWString& wsString) const
{
const wchar_t* wsLeft = this->c_str();
const wchar_t* wsRight = wsString.c_str();
unsigned int unLen = min(m_unLen, wsString.m_unLen);
for (unsigned int unPos = 0; unPos < unLen; unPos++)
{
if (wsLeft[unPos] < wsRight[unPos])
return true;
else if (wsLeft[unPos] > wsRight[unPos])
return false;
}
return (m_unLen > wsString.m_unLen);
}
bool CWString::operator>(const CWString& wsString) const
{
return !operator<(wsString);
}
bool CWString::operator==(const CWString& wsString) const
{
const wchar_t* wsLeft = this->c_str();
const wchar_t* wsRight = wsString.c_str();
if (m_unLen != wsString.m_unLen)
return false;
for (unsigned int unPos = 0; unPos < m_unLen; unPos++)
{
if (wsLeft[unPos] != wsRight[unPos])
return false;
}
return true;
}
bool CWString::operator==(const wchar_t* wsString) const
{
const wchar_t* wsLeft = this->c_str();
unsigned unLen = min(wcslen(wsString), MAX_STRING_LEN);
if (m_unLen != unLen)
return false;
for (unsigned int unPos = 0; unPos < m_unLen; unPos++)
{
if (wsLeft[unPos] != wsString[unPos])
return false;
}
return true;
}
unsigned int CWString::size() const
{
return m_unLen;
}
wchar_t CWString::operator[](const unsigned int& unIndex) const
{
return this->c_str()[unIndex];
}
bool CWString::empty() const
{
return 0 == m_unLen;
}
std::vector<CWString> CWString::split(wchar_t wChar, bool bCopy)
{
std::vector<CWString> vResult;
int nPos = 0;
int nLen = size();
int nCharPos = nPos;
while (nPos < nLen)
{
int nCharPos = nPos;
while (nCharPos < nLen && operator[](nCharPos) != wChar)
nCharPos++;
CWString wsElement;
wsElement.create(this->c_str() + nPos, bCopy, nCharPos - nPos);
vResult.push_back(wsElement);
nPos = nCharPos + 1;
}
return vResult;
}
}
\ No newline at end of file
#ifndef _XPS_XPSLIB_WSTRING_H
#define _XPS_XPSLIB_WSTRING_H
#include <vector>
namespace XPS
{
class CWStringBuffer;
class CWString
{
public:
CWString();
CWString(const wchar_t* wsString);
CWString(const CWString& wsString);
CWString(wchar_t* wsString, bool bCopy, int nLen = -1);
~CWString();
void create(const wchar_t*, bool bCopy, int nLen = -1);
void operator=(const wchar_t* wsString);
void operator=(const CWString& wsString);
bool operator<(const CWString& wsString) const;
bool operator>(const CWString& wsString) const;
bool operator==(const CWString& wsString) const;
bool operator==(const wchar_t* wsString) const;
unsigned int size() const;
bool empty() const;
wchar_t operator[](const unsigned int& unIndex) const;
const wchar_t* c_str() const;
void clear();
std::vector<CWString> split(wchar_t wChar, bool bCopy = false);
private:
void* m_pBuffer;
unsigned int m_unLen;
bool m_bOwnBuffer;
};
}
#endif //_XPS_XPSLIB_WSTRING_H
\ No newline at end of file
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment