mirror of
https://github.com/ONLYOFFICE/core.git
synced 2026-07-11 14:00:32 +08:00
git-svn-id: svn://fileserver/activex/AVS/Sources/TeamlabOffice/trunk/ServerComponents@62078 954022d7-b5bf-4e40-9824-e11837661b57
557 lines
13 KiB
C++
557 lines
13 KiB
C++
#pragma once
|
||
|
||
#include "../Base/Base.h"
|
||
#include "../Base/SmartPtr.h"
|
||
|
||
#if defined(_WIN32) || defined (_WIN64)
|
||
#include <atlenc.h>
|
||
#include <comutil.h>
|
||
#endif
|
||
|
||
#include <algorithm>
|
||
|
||
#ifndef _USE_NULLABLE_PROPERTY_
|
||
using namespace NSCommon;
|
||
#endif
|
||
namespace XmlUtils
|
||
{
|
||
static CString strInvalidValue = _T("x(-Jdl%^8sFGs@gkp14jJU(90dyjhjnb*EcfFf%#2124sf98hc");
|
||
//static _bstr_t g_cpszXML_TextExt = L"./text()";
|
||
|
||
// common
|
||
AVSINLINE static int GetDigit (TCHAR c)
|
||
{
|
||
if (c >= '0' && c <= '9')
|
||
return (int)(c - '0');
|
||
if (c >= 'a' && c <= 'f')
|
||
return 10 + (int)(c - 'a');
|
||
if (c >= 'A' && c <= 'F')
|
||
return 10 + (int)(c - 'A');
|
||
|
||
return 0;
|
||
}
|
||
AVSINLINE static bool IsDigit (TCHAR c)
|
||
{
|
||
if (c >= '0' && c <= '9')
|
||
return true;
|
||
return false;
|
||
}
|
||
AVSINLINE static __int64 GetHex (const CString& string)
|
||
{
|
||
__int64 nResult = 0;
|
||
int nLen = string.GetLength();
|
||
for ( int nIndex = 0; nIndex < nLen; ++nIndex )
|
||
{
|
||
nResult += GetDigit( string[nIndex] ) << ( 4 * ( nLen - 1 - nIndex ) );
|
||
}
|
||
|
||
return nResult;
|
||
}
|
||
AVSINLINE static int GetColor (const CString& string)
|
||
{
|
||
// variables
|
||
int blue = 0;
|
||
int green = 0;
|
||
int red = 0;
|
||
|
||
CString color = string; color = color.Trim();
|
||
|
||
if (color.Find(_T("0x"))!=-1)
|
||
color.Delete(0,2);
|
||
if (color.Find(_T("#"))!=-1)
|
||
color.Delete(0,1);
|
||
|
||
while (color.GetLength() < 6)
|
||
color = _T("0") + color;
|
||
|
||
red = 16*GetDigit(color[0]) + GetDigit(color[1]);
|
||
green = 16*GetDigit(color[2]) + GetDigit(color[3]);
|
||
blue = 16*GetDigit(color[4]) + GetDigit(color[5]);
|
||
|
||
return RGB(red, green, blue);
|
||
}
|
||
AVSINLINE static bool GetBoolean (const CString& string)
|
||
{
|
||
CString s = string; s.MakeLower();
|
||
|
||
return (s == _T("true"));
|
||
}
|
||
AVSINLINE static bool GetBoolean2(const CString& string)
|
||
{
|
||
CString sTemp = string; sTemp.MakeLower();
|
||
|
||
return ( _T("true") == sTemp || _T("1") == sTemp || _T("t") == sTemp || _T("on") == sTemp );
|
||
}
|
||
AVSINLINE static int GetInteger (const CString& string)
|
||
{
|
||
if (string.GetLength() <1) return 0;
|
||
|
||
try
|
||
{
|
||
return _ttoi(string);
|
||
}
|
||
catch(...)
|
||
{
|
||
}
|
||
|
||
try
|
||
{
|
||
return static_cast<int>(_wtoi64(string));
|
||
}
|
||
catch(...)
|
||
{
|
||
return 0;
|
||
}
|
||
}
|
||
AVSINLINE static size_t GetUInteger(const CString& string)
|
||
{
|
||
if (string.GetLength() <1) return 0;
|
||
try
|
||
{
|
||
return (size_t) _ttoi(string);
|
||
}
|
||
catch(...)
|
||
{
|
||
}
|
||
|
||
try
|
||
{
|
||
return (size_t) _wtoi64(string);
|
||
}
|
||
catch(...)
|
||
{
|
||
return 0;
|
||
}
|
||
}
|
||
AVSINLINE static double GetDouble (const CString& string)
|
||
{
|
||
if (string.GetLength() <1) return 0;
|
||
|
||
double d = 0;
|
||
_stscanf(string, _T("%lf"), &d);
|
||
return d;
|
||
}
|
||
AVSINLINE static float GetFloat (const CString& string)
|
||
{
|
||
if (string.GetLength() <1) return 0;
|
||
|
||
float f = 0;
|
||
_stscanf(string, _T("%f"), &f);
|
||
return f;
|
||
}
|
||
#if defined(_WIN32) || defined (_WIN64)
|
||
AVSINLINE static int GetInteger (BSTR string)
|
||
{
|
||
return _wtoi(string);
|
||
}
|
||
AVSINLINE static size_t GetUInteger(BSTR string)
|
||
{
|
||
return (size_t)_wtoi(string);
|
||
}
|
||
AVSINLINE static double GetDouble (BSTR string)
|
||
{
|
||
double d = 0;
|
||
swscanf(string, _T("%lf"), &d);
|
||
return d;
|
||
}
|
||
AVSINLINE static float GetFloat (BSTR string)
|
||
{
|
||
float f = 0;
|
||
swscanf(string, _T("%f"), &f);
|
||
return f;
|
||
}
|
||
AVSINLINE static void GetDouble (BSTR string, double* p)
|
||
{
|
||
*p = 0;
|
||
swscanf(string, _T("%lf"), *p);
|
||
}
|
||
AVSINLINE static void GetFloat (BSTR string, float* p)
|
||
{
|
||
*p = 0;
|
||
swscanf(string, _T("%f"), *p);
|
||
}
|
||
AVSINLINE static void GetInteger (BSTR string, int* p)
|
||
{
|
||
*p = 0;
|
||
swscanf(string, _T("%d"), *p);
|
||
}
|
||
#endif
|
||
|
||
AVSINLINE CString BoolToString (const bool & value)
|
||
{
|
||
CString sResult = ( value ? _T("true") : _T("false") );
|
||
return sResult;
|
||
}
|
||
AVSINLINE CString IntToString (const int & value)
|
||
{
|
||
CString str = _T("");
|
||
str.Format(_T("%d"), value);
|
||
return str;
|
||
}
|
||
AVSINLINE CString UIntToString (const size_t & value)
|
||
{
|
||
CString str = _T("");
|
||
str.Format(_T("%u"), value);
|
||
return str;
|
||
}
|
||
AVSINLINE CString FloatToString (const float & value)
|
||
{
|
||
CString str = _T("");
|
||
str.Format(_T("%f"), value);
|
||
return str;
|
||
}
|
||
AVSINLINE CString DoubleToString(const double& value)
|
||
{
|
||
CString str = _T("");
|
||
str.Format(_T("%lf"), value);
|
||
return str;
|
||
}
|
||
AVSINLINE static CString GetLower(const CString& string)
|
||
{
|
||
//CString s = string; s.MakeLower();
|
||
//return s;
|
||
CString sResult;
|
||
|
||
for( int nIndex = 0; nIndex < string.GetLength(); nIndex++)
|
||
sResult += wchar_t( towlower(string[nIndex]) );
|
||
|
||
return sResult;
|
||
}
|
||
AVSINLINE static CString GetUpper(const CString& string)
|
||
{
|
||
CString sResult;
|
||
|
||
for( int nIndex = 0; nIndex < string.GetLength(); nIndex++)
|
||
sResult += wchar_t( towupper(string[nIndex]) );
|
||
|
||
return sResult;
|
||
}
|
||
AVSINLINE static bool IsUnicodeSymbol( WCHAR symbol )
|
||
{
|
||
bool result = false;
|
||
|
||
if ( ( 0x0009 == symbol ) || ( 0x000A == symbol ) || ( 0x000D == symbol ) ||
|
||
( ( 0x0020 <= symbol ) && ( 0xD7FF >= symbol ) ) || ( ( 0xE000 <= symbol ) && ( symbol <= 0xFFFD ) ) ||
|
||
( ( 0x10000 <= symbol ) && symbol ) )
|
||
{
|
||
result = true;
|
||
}
|
||
|
||
return result;
|
||
}
|
||
AVSINLINE static CString EncodeXmlString(const CString& string, bool bDeleteNoUnicode = false)
|
||
{
|
||
CString sResult;
|
||
if(bDeleteNoUnicode)
|
||
{
|
||
sResult = _T("");
|
||
for (unsigned int i = 0, length = string.GetLength(); i < length; ++i )
|
||
{
|
||
WCHAR symbol = string.GetAt(i);
|
||
if ( false == IsUnicodeSymbol( symbol ) )
|
||
{
|
||
if(0xD800 <= symbol && symbol <= 0xDFFF && i + 1 < length)
|
||
{
|
||
i++;
|
||
WCHAR symbol2 = string.GetAt(i);
|
||
if (symbol < 0xDC00 && symbol2 >= 0xDC00 && symbol2 <= 0xDFFF)
|
||
{
|
||
sResult.AppendChar(symbol);
|
||
sResult.AppendChar(symbol2);
|
||
}
|
||
}
|
||
}
|
||
else
|
||
sResult.AppendChar(symbol);
|
||
}
|
||
}
|
||
else
|
||
{
|
||
sResult = string;
|
||
for (unsigned int i = 0, length = string.GetLength(); i < length; ++i )
|
||
{
|
||
WCHAR symbol = string.GetAt(i);
|
||
if ( false == IsUnicodeSymbol( symbol ) )
|
||
{
|
||
if(0xD800 <= symbol && symbol <= 0xDFFF && i + 1 < length)
|
||
{
|
||
i++;
|
||
WCHAR symbol2 = string.GetAt(i);
|
||
if (!(symbol < 0xDC00 && symbol2 >= 0xDC00 && symbol2 <= 0xDFFF))
|
||
{
|
||
sResult.SetAt(i - 1, ' ');
|
||
sResult.SetAt(i, ' ');
|
||
}
|
||
}
|
||
else
|
||
sResult.SetAt(i, ' ');
|
||
}
|
||
}
|
||
}
|
||
sResult.Replace(_T("&"), _T("&"));
|
||
sResult.Replace(_T("'"), _T("'"));
|
||
sResult.Replace(_T("<"), _T("<"));
|
||
sResult.Replace(_T(">"), _T(">"));
|
||
sResult.Replace(_T("\""), _T("""));
|
||
return sResult;
|
||
}
|
||
//#ifndef _USE_LIBXML2_READER_
|
||
class CStringWriter
|
||
{
|
||
private:
|
||
wchar_t* m_pData;
|
||
size_t m_lSize;
|
||
|
||
wchar_t* m_pDataCur;
|
||
size_t m_lSizeCur;
|
||
|
||
public:
|
||
CStringWriter()
|
||
{
|
||
m_pData = NULL;
|
||
m_lSize = 0;
|
||
|
||
m_pDataCur = m_pData;
|
||
m_lSizeCur = m_lSize;
|
||
|
||
m_bInitTable = false;
|
||
}
|
||
~CStringWriter()
|
||
{
|
||
RELEASEMEM(m_pData);
|
||
}
|
||
|
||
AVSINLINE void AddSize(size_t nSize)
|
||
{
|
||
if (NULL == m_pData)
|
||
{
|
||
m_lSize = (std::max)((int) nSize, 1000);
|
||
m_pData = (wchar_t*)malloc(m_lSize * sizeof(wchar_t));
|
||
|
||
m_lSizeCur = 0;
|
||
m_pDataCur = m_pData;
|
||
return;
|
||
}
|
||
|
||
if ((m_lSizeCur + nSize) > m_lSize)
|
||
{
|
||
while ((m_lSizeCur + nSize) > m_lSize)
|
||
{
|
||
m_lSize *= 2;
|
||
}
|
||
|
||
wchar_t* pRealloc = (wchar_t*)realloc(m_pData, m_lSize * sizeof(wchar_t));
|
||
if (NULL != pRealloc)
|
||
{
|
||
// <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
|
||
m_pData = pRealloc;
|
||
m_pDataCur = m_pData + m_lSizeCur;
|
||
}
|
||
else
|
||
{
|
||
wchar_t* pMalloc = (wchar_t*)malloc(m_lSize * sizeof(wchar_t));
|
||
memcpy(pMalloc, m_pData, m_lSizeCur * sizeof(wchar_t));
|
||
|
||
free(m_pData);
|
||
m_pData = pMalloc;
|
||
m_pDataCur = m_pData + m_lSizeCur;
|
||
}
|
||
}
|
||
}
|
||
|
||
public:
|
||
|
||
AVSINLINE void WriteString(const wchar_t* pString, size_t nLen)
|
||
{
|
||
AddSize(nLen);
|
||
|
||
memcpy(m_pDataCur, pString, nLen * sizeof(wchar_t));
|
||
|
||
m_pDataCur += nLen;
|
||
m_lSizeCur += nLen;
|
||
}
|
||
#if defined(_WIN32) || defined (_WIN64)
|
||
AVSINLINE void WriteString(_bstr_t& bsString)
|
||
{
|
||
size_t nLen = bsString.length();
|
||
WriteString(bsString.GetBSTR(), nLen);
|
||
}
|
||
#endif
|
||
AVSINLINE void WriteString(const CString& sString)
|
||
{
|
||
size_t nLen = (size_t)sString.GetLength();
|
||
|
||
#ifdef _UNICODE
|
||
CString str = sString;
|
||
WriteString(str.GetBuffer(), nLen);
|
||
#else
|
||
CStringW str = (CStringW)sString;
|
||
WriteString(str.GetBuffer(), nLen);
|
||
#endif
|
||
}
|
||
|
||
AVSINLINE void AddCharSafe(const TCHAR& _c)
|
||
{
|
||
AddSize(1);
|
||
*m_pDataCur++ = _c;
|
||
++m_lSizeCur;
|
||
}
|
||
AVSINLINE void AddChar2Safe(const TCHAR _c1, const TCHAR& _c2)
|
||
{
|
||
AddSize(2);
|
||
*m_pDataCur++ = _c1;
|
||
*m_pDataCur++ = _c2;
|
||
m_lSizeCur += 2;
|
||
}
|
||
|
||
inline void WriteEncodeXmlString(const wchar_t* pString)
|
||
{
|
||
const wchar_t* pData = pString;
|
||
while (*pData != 0)
|
||
{
|
||
BYTE _code = CheckCode(*pData);
|
||
|
||
switch (_code)
|
||
{
|
||
case 1:
|
||
AddCharSafe(*pData);
|
||
break;
|
||
case 0:
|
||
AddCharSafe((WCHAR)' ');
|
||
break;
|
||
case 2:
|
||
AddSize(5);
|
||
*m_pDataCur++ = (WCHAR)('&');
|
||
*m_pDataCur++ = (WCHAR)('a');
|
||
*m_pDataCur++ = (WCHAR)('m');
|
||
*m_pDataCur++ = (WCHAR)('p');
|
||
*m_pDataCur++ = (WCHAR)(';');
|
||
m_lSizeCur += 5;
|
||
break;
|
||
case 3:
|
||
AddSize(6);
|
||
*m_pDataCur++ = (WCHAR)('&');
|
||
*m_pDataCur++ = (WCHAR)('a');
|
||
*m_pDataCur++ = (WCHAR)('p');
|
||
*m_pDataCur++ = (WCHAR)('o');
|
||
*m_pDataCur++ = (WCHAR)('s');
|
||
*m_pDataCur++ = (WCHAR)(';');
|
||
m_lSizeCur += 6;
|
||
break;
|
||
case 4:
|
||
AddSize(4);
|
||
*m_pDataCur++ = (WCHAR)('&');
|
||
*m_pDataCur++ = (WCHAR)('l');
|
||
*m_pDataCur++ = (WCHAR)('t');
|
||
*m_pDataCur++ = (WCHAR)(';');
|
||
m_lSizeCur += 4;
|
||
break;
|
||
case 5:
|
||
AddSize(4);
|
||
*m_pDataCur++ = (WCHAR)('&');
|
||
*m_pDataCur++ = (WCHAR)('g');
|
||
*m_pDataCur++ = (WCHAR)('t');
|
||
*m_pDataCur++ = (WCHAR)(';');
|
||
m_lSizeCur += 4;
|
||
break;
|
||
case 6:
|
||
AddSize(6);
|
||
*m_pDataCur++ = (WCHAR)('&');
|
||
*m_pDataCur++ = (WCHAR)('q');
|
||
*m_pDataCur++ = (WCHAR)('u');
|
||
*m_pDataCur++ = (WCHAR)('o');
|
||
*m_pDataCur++ = (WCHAR)('t');
|
||
*m_pDataCur++ = (WCHAR)(';');
|
||
m_lSizeCur += 6;
|
||
break;
|
||
default:
|
||
break;
|
||
}
|
||
|
||
++pData;
|
||
}
|
||
|
||
}
|
||
|
||
AVSINLINE size_t GetCurSize()
|
||
{
|
||
return m_lSizeCur;
|
||
}
|
||
|
||
AVSINLINE void Write(CStringWriter& oWriter)
|
||
{
|
||
WriteString(oWriter.m_pData, oWriter.m_lSizeCur);
|
||
}
|
||
|
||
inline void Clear()
|
||
{
|
||
RELEASEMEM(m_pData);
|
||
|
||
m_pData = NULL;
|
||
m_lSize = 0;
|
||
|
||
m_pDataCur = m_pData;
|
||
m_lSizeCur = 0;
|
||
}
|
||
inline void ClearNoAttack()
|
||
{
|
||
m_pDataCur = m_pData;
|
||
m_lSizeCur = 0;
|
||
}
|
||
|
||
CString GetData()
|
||
{
|
||
CString str(m_pData, (int)m_lSizeCur);
|
||
return str;
|
||
}
|
||
|
||
protected:
|
||
BYTE m_arTableUnicodes[65536];
|
||
bool m_bInitTable;
|
||
|
||
protected:
|
||
BYTE CheckCode(const WCHAR& c)
|
||
{
|
||
if (!m_bInitTable)
|
||
{
|
||
memset(m_arTableUnicodes, 0, 65536);
|
||
m_arTableUnicodes[0x0009] = 1;
|
||
m_arTableUnicodes[0x000A] = 1;
|
||
m_arTableUnicodes[0x000D] = 1;
|
||
|
||
memset(m_arTableUnicodes + 0x0020, 1, 0xD7FF - 0x0020 + 1);
|
||
memset(m_arTableUnicodes + 0xE000, 1, 0xFFFD - 0xE000 + 1);
|
||
|
||
m_arTableUnicodes['&'] = 2;
|
||
m_arTableUnicodes['\''] = 3;
|
||
m_arTableUnicodes['<'] = 4;
|
||
m_arTableUnicodes['>'] = 5;
|
||
m_arTableUnicodes['\"'] = 6;
|
||
|
||
m_bInitTable = true;
|
||
}
|
||
#if !defined(_WIN32) && !defined (_WIN64)
|
||
if (sizeof (wchar_t) == 4)
|
||
{
|
||
UTF16 c1=0;
|
||
|
||
const UTF32 *pStr32 = (UTF32 *)&c;
|
||
UTF16 *pStr16 = (UTF16 *)&c1;
|
||
|
||
ConversionResult eUnicodeConversionResult =
|
||
ConvertUTF32toUTF16(&pStr32,&pStr32[1], &pStr16, &pStr16[1],strictConversion);
|
||
|
||
if (conversionOK != eUnicodeConversionResult)
|
||
{
|
||
return 1; //??
|
||
}
|
||
return m_arTableUnicodes[c1];
|
||
}
|
||
else
|
||
#endif
|
||
return m_arTableUnicodes[c];
|
||
}
|
||
};
|
||
//#endif // ifndef _USE_LIBXML2_READER_
|
||
}
|