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

691 lines
15 KiB
C++
Raw Blame History

#pragma once
#pragma comment(lib, "libxml2.lib")
#include "win_build/Config.h"
#include "XML/include/libxml/xmlreader.h"
#include <windows.h>
#include "../Utils.h"
namespace XmlUtils
{
namespace NSFile
{
class CFile
{
public:
CFile()
{
m_hFileHandle = NULL;
m_lFileSize = 0;
m_lFilePosition = 0;
}
virtual ~CFile()
{
CloseFile();
}
virtual HRESULT OpenFile(CString FileName)
{
CloseFile();
HRESULT hRes = S_OK;
DWORD AccessMode = GENERIC_READ;
DWORD ShareMode = FILE_SHARE_READ;
DWORD Disposition = OPEN_EXISTING;
m_hFileHandle = ::CreateFile(FileName, AccessMode, ShareMode, NULL, Disposition, FILE_ATTRIBUTE_NORMAL, NULL);
if (NULL == m_hFileHandle || INVALID_HANDLE_VALUE == m_hFileHandle)
hRes = S_FALSE;
else
{
ULARGE_INTEGER nTempSize;
nTempSize.LowPart = ::GetFileSize(m_hFileHandle, &nTempSize.HighPart);
m_lFileSize = nTempSize.QuadPart;
SetPosition(0);
}
return hRes;
}
virtual HRESULT OpenFileRW(CString FileName)
{
CloseFile();
HRESULT hRes = S_OK;
DWORD AccessMode = GENERIC_READ | GENERIC_WRITE;
DWORD ShareMode = FILE_SHARE_READ;
DWORD Disposition = OPEN_EXISTING;
m_hFileHandle = ::CreateFile(FileName, AccessMode, ShareMode, NULL, Disposition, 0, 0);
if (NULL == m_hFileHandle || INVALID_HANDLE_VALUE == m_hFileHandle)
{
hRes = S_FALSE;
}
else
{
ULARGE_INTEGER nTempSize;
nTempSize.LowPart = ::GetFileSize(m_hFileHandle, &nTempSize.HighPart);
m_lFileSize = nTempSize.QuadPart;
SetPosition(0);
}
return hRes;
}
HRESULT ReadFile(BYTE* pData, DWORD nBytesToRead)
{
DWORD nBytesRead = 0;
if(NULL == pData)
return S_FALSE;
if(m_hFileHandle && (pData))
{
SetPosition(m_lFilePosition);
::ReadFile(m_hFileHandle, pData, nBytesToRead, &nBytesRead, NULL);
m_lFilePosition += nBytesRead;
}
return S_OK;
}
HRESULT ReadFile2(BYTE* pData, DWORD nBytesToRead)
{
DWORD nBytesRead = 0;
if(NULL == pData)
return S_FALSE;
if(m_hFileHandle && (pData))
{
SetPosition(m_lFilePosition);
::ReadFile(m_hFileHandle, pData, nBytesToRead, &nBytesRead, NULL);
m_lFilePosition += nBytesRead;
for (size_t index = 0; index < nBytesToRead / 2; ++index)
{
BYTE temp = pData[index];
pData[index] = pData[nBytesToRead - index - 1];
pData[nBytesToRead - index - 1] = temp;
}
}
return S_OK;
}
HRESULT ReadFile3(void* pData, DWORD nBytesToRead)
{
DWORD nBytesRead = 0;
if(NULL == pData)
return S_FALSE;
if(m_hFileHandle && (pData))
{
SetPosition(m_lFilePosition);
::ReadFile(m_hFileHandle, pData, nBytesToRead, &nBytesRead, NULL);
m_lFilePosition += nBytesRead;
}
return S_OK;
}
HRESULT WriteFile(void* pData, DWORD nBytesToWrite)
{
if(m_hFileHandle)
{
DWORD dwWritten = 0;
::WriteFile(m_hFileHandle, pData, nBytesToWrite, &dwWritten, NULL);
m_lFilePosition += nBytesToWrite;
}
return S_OK;
}
HRESULT WriteFile2(void* pData, DWORD nBytesToWrite)
{
if(m_hFileHandle)
{
BYTE* mem = new BYTE[nBytesToWrite];
memcpy(mem, pData, nBytesToWrite);
for (size_t index = 0; index < nBytesToWrite / 2; ++index)
{
BYTE temp = mem[index];
mem[index] = mem[nBytesToWrite - index - 1];
mem[nBytesToWrite - index - 1] = temp;
}
DWORD dwWritten = 0;
::WriteFile(m_hFileHandle, (void*)mem, nBytesToWrite, &dwWritten, NULL);
m_lFilePosition += nBytesToWrite;
RELEASEARRAYOBJECTS(mem);
}
return S_OK;
}
HRESULT CreateFile(CString strFileName)
{
CloseFile();
DWORD AccessMode = GENERIC_WRITE;
DWORD ShareMode = FILE_SHARE_WRITE;
DWORD Disposition = CREATE_ALWAYS;
m_hFileHandle = ::CreateFile(strFileName, AccessMode, ShareMode, NULL, Disposition, FILE_ATTRIBUTE_NORMAL, NULL);
return SetPosition(0);
}
HRESULT SetPosition( ULONG64 nPos )
{
if (m_hFileHandle && nPos < (ULONG)m_lFileSize)
{
LARGE_INTEGER nTempPos;
nTempPos.QuadPart = nPos;
::SetFilePointer(m_hFileHandle, nTempPos.LowPart, &nTempPos.HighPart, FILE_BEGIN);
m_lFilePosition = nPos;
return S_OK;
}
else
{
return (INVALID_HANDLE_VALUE == m_hFileHandle) ? S_FALSE : S_OK;
}
}
LONG64 GetPosition()
{
return m_lFilePosition;
}
HRESULT SkipBytes(ULONG64 nCount)
{
return SetPosition(m_lFilePosition + nCount);
}
HRESULT CloseFile()
{
m_lFileSize = 0;
m_lFilePosition = 0;
RELEASEHANDLE(m_hFileHandle);
return S_OK;
}
ULONG64 GetFileSize()
{
return m_lFileSize;
}
HRESULT WriteReserved(DWORD dwCount)
{
BYTE* buf = new BYTE[dwCount];
memset(buf, 0, (size_t)dwCount);
HRESULT hr = WriteFile(buf, dwCount);
RELEASEARRAYOBJECTS(buf);
return hr;
}
HRESULT WriteReserved2(DWORD dwCount)
{
BYTE* buf = new BYTE[dwCount];
memset(buf, 0xFF, (size_t)dwCount);
HRESULT hr = WriteFile(buf, dwCount);
RELEASEARRAYOBJECTS(buf);
return hr;
}
HRESULT WriteReservedTo(DWORD dwPoint)
{
if (m_lFilePosition >= dwPoint)
return S_OK;
DWORD dwCount = dwPoint - (DWORD)m_lFilePosition;
BYTE* buf = new BYTE[dwCount];
memset(buf, 0, (size_t)dwCount);
HRESULT hr = WriteFile(buf, dwCount);
RELEASEARRAYOBJECTS(buf);
return hr;
}
HRESULT SkipReservedTo(DWORD dwPoint)
{
if (m_lFilePosition >= dwPoint)
return S_OK;
DWORD dwCount = dwPoint - (DWORD)m_lFilePosition;
return SkipBytes(dwCount);
}
LONG GetProgress()
{
if (0 >= m_lFileSize)
return -1;
double dVal = (double)(100 * m_lFilePosition);
LONG lProgress = (LONG)(dVal / m_lFileSize);
return lProgress;
}
void WriteStringUTF8(CString& strXml)
{
int nLength = strXml.GetLength();
CStringA saStr;
#ifdef UNICODE
// Encoding Unicode to UTF-8
WideCharToMultiByte(CP_UTF8, 0, strXml.GetBuffer(), nLength + 1, saStr.GetBuffer(nLength*3 + 1), nLength*3, NULL, NULL);
saStr.ReleaseBuffer();
#else
wchar_t* pWStr = new wchar_t[nLength + 1];
if (!pWStr)
return;
// set end string
pWStr[nLength] = 0;
// Encoding ASCII to Unicode
MultiByteToWideChar(CP_ACP, 0, strXml, nLength, pWStr, nLength);
int nLengthW = (int)wcslen(pWStr);
// Encoding Unicode to UTF-8
WideCharToMultiByte(CP_UTF8, 0, pWStr, nLengthW + 1, saStr.GetBuffer(nLengthW*3 + 1), nLengthW*3, NULL, NULL);
saStr.ReleaseBuffer();
delete[] pWStr;
#endif
WriteFile((void*)saStr.GetBuffer(), saStr.GetLength());
}
protected:
HANDLE m_hFileHandle;
LONG64 m_lFileSize;
LONG64 m_lFilePosition;
};
}
typedef
enum XmlNodeType
{
XmlNodeType_None = 0,
XmlNodeType_Element = 1,
XmlNodeType_Attribute = 2,
XmlNodeType_Text = 3,
XmlNodeType_CDATA = 4,
XmlNodeType_ENTITY_REFERENCE = 5,
XmlNodeType_ENTITY = 6,
XmlNodeType_ProcessingInstruction = 7,
XmlNodeType_Comment = 8,
XmlNodeType_Document = 9,
XmlNodeType_DocumentType = 10,
XmlNodeType_DOCUMENT_FRAGMENT = 11,
XmlNodeType_NOTATION = 12,
XmlNodeType_Whitespace = 13,
XmlNodeType_SIGNIFICANT_WHITESPACE = 14,
XmlNodeType_EndElement = 15,
XmlNodeType_TYPE_END_ENTITY = 16,
XmlNodeType_XmlDeclaration = 17,
_XmlNodeType_Last = 17
} XmlNodeType;
class CXmlLiteReader
{
xmlTextReaderPtr reader;
BYTE* m_pStream;
LONG m_lStreamLen;
public:
CXmlLiteReader()
{
reader = NULL;
m_pStream = NULL;
}
~CXmlLiteReader()
{
if (NULL != m_pStream)
delete []m_pStream;
}
public:
inline void Clear()
{
}
inline BOOL IsValid()
{
return ( NULL != reader );
}
inline BOOL FromFile(CString& sFilePath)
{
Clear();
NSFile::CFile oFile;
oFile.OpenFile(sFilePath);
m_lStreamLen = (int)oFile.GetFileSize();
m_pStream = new BYTE[m_lStreamLen];
oFile.ReadFile(m_pStream, (DWORD)m_lStreamLen);
oFile.CloseFile();
reader = xmlReaderForMemory((char*)m_pStream, m_lStreamLen, NULL, NULL, 0);
return TRUE;
}
inline BOOL FromString(CString& sXml)
{
Clear();
UnicodeToUtf8(sXml, m_pStream, m_lStreamLen);
reader = xmlReaderForMemory((char*)m_pStream, m_lStreamLen, NULL, NULL, 0);
return TRUE;
}
inline BOOL Read(XmlNodeType &oNodeType)
{
if ( !IsValid() )
return FALSE;
if ( 0 == xmlTextReaderRead(reader) )
return FALSE;
oNodeType = (XmlNodeType)xmlTextReaderNodeType(reader);
return TRUE;
}
inline BOOL ReadNextNode()
{
if ( !IsValid() )
return FALSE;
XmlNodeType oNodeType = XmlNodeType_None;
while ( XmlNodeType_Element != oNodeType )
{
if (!xmlTextReaderRead(reader))
break;
oNodeType = (XmlNodeType)xmlTextReaderNodeType(reader);
}
if ( XmlNodeType_Element == oNodeType )
return TRUE;
return FALSE;
}
inline BOOL ReadNextSiblingNode(int nDepth)
{
// <20><><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>,
// <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD>.
if ( !IsValid() )
return FALSE;
XmlNodeType eNodeType = XmlNodeType_None;
int nCurDepth = -1;
while ( xmlTextReaderRead(reader) )
{
eNodeType = (XmlNodeType)xmlTextReaderNodeType(reader);
nCurDepth = xmlTextReaderDepth(reader);
if (nCurDepth <= nDepth)
break;
if ( XmlNodeType_Element == eNodeType && nCurDepth == nDepth + 1 )
return TRUE;
else if ( XmlNodeType_EndElement == eNodeType && nCurDepth == nDepth + 1 )
return FALSE;
}
return FALSE;
}
inline BOOL ReadTillEnd(int nDepth = -2)
{
if ( !IsValid() )
return FALSE;
if ( -2 == nDepth )
nDepth = GetDepth();
else if ( nDepth == GetDepth() && xmlTextReaderIsEmptyElement(reader) )
return TRUE;
XmlNodeType eNodeType = XmlNodeType_None;
int nCurDepth = -1;
// <20> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><> 1 <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD>, <20><><EFBFBD> <20> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
while( TRUE )
{
if ( 0 == xmlTextReaderRead(reader) )
break;
eNodeType = (XmlNodeType)xmlTextReaderNodeType(reader);
nCurDepth = GetDepth();
if ( nCurDepth <= nDepth )
break;
if ( XmlNodeType_EndElement == eNodeType && nCurDepth == nDepth + 1 )
break;
}
return TRUE;
}
inline const wchar_t* GetName()
{
if ( !IsValid() )
return NULL;
xmlChar* pName = xmlTextReaderName(reader);
return UnicodeFromUtf8(pName);
}
inline int GetDepth()
{
if ( !IsValid() )
return -1;
return xmlTextReaderDepth(reader);
}
inline BOOL IsEmptyNode()
{
if ( !IsValid() )
return FALSE;
return xmlTextReaderIsEmptyElement(reader);
}
inline const WCHAR *GetText()
{
if ( !IsValid() )
return NULL;
xmlChar* pValue = xmlTextReaderValue(reader);
return UnicodeFromUtf8(pValue);
}
inline CString GetText2()
{
if ( !IsValid() )
return _T("");
// TO DO: <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> (<28><><EFBFBD><EFBFBD><EFBFBD><EFBFBD> CString)
CString sResult;
if ( xmlTextReaderIsEmptyElement(reader) )
return sResult;
int nDepth = GetDepth();
XmlNodeType eNodeType = XmlNodeType_EndElement;
while ( Read( eNodeType ) && GetDepth() >= nDepth && XmlNodeType_EndElement != eNodeType )
{
if ( eNodeType == XmlNodeType_Text || eNodeType == XmlNodeType_Whitespace || eNodeType == XmlNodeType_SIGNIFICANT_WHITESPACE )
sResult += GetText();
}
return sResult;
}
inline CString GetOuterXml()
{
return GetXml(false);
}
inline CString GetInnerXml()
{
return GetXml(true);
}
inline int GetAttributesCount()
{
if ( !IsValid() )
return -1;
return xmlTextReaderAttributeCount(reader);
}
inline BOOL MoveToFirstAttribute()
{
if ( !IsValid() )
return FALSE;
return (BOOL)xmlTextReaderMoveToFirstAttribute(reader);
}
inline BOOL MoveToNextAttribute()
{
if ( !IsValid() )
return FALSE;
return (BOOL)xmlTextReaderMoveToNextAttribute(reader);;
}
inline BOOL MoveToElement()
{
if ( !IsValid() )
return FALSE;
return (BOOL)xmlTextReaderMoveToElement(reader);
}
private:
inline CString GetXml(bool bInner)
{
if ( !IsValid() )
return _T("");
CStringWriter oResult;
if(false == bInner)
WriteElement(oResult);
int nDepth = GetDepth();
if ( 0 == xmlTextReaderIsEmptyElement(reader) )
{
XmlNodeType eNodeType = XmlNodeType_None;
int nCurDepth = -1;
// <20> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><> 1 <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD>, <20><><EFBFBD> <20> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
while( TRUE )
{
if ( 0 == xmlTextReaderRead(reader) )
break;
eNodeType = (XmlNodeType)xmlTextReaderNodeType(reader);
nCurDepth = GetDepth();
if ( eNodeType == XmlNodeType_Text || eNodeType == XmlNodeType_Whitespace )
oResult.WriteEncodeXmlString(GetText());
else if(eNodeType == XmlNodeType_Element)
WriteElement(oResult);
else if(eNodeType == XmlNodeType_EndElement)
{
if(false == bInner || nCurDepth != nDepth + 1)
{
oResult.AddChar2Safe(TCHAR('<'), TCHAR('/'));
oResult.WriteEncodeXmlString(GetName());
oResult.AddCharSafe(TCHAR('>'));
}
}
nCurDepth = GetDepth();
if ( nCurDepth <= nDepth )
break;
if ( XmlNodeType_EndElement == eNodeType && nCurDepth == nDepth )
break;
}
}
return oResult.GetData();
}
void WriteElement(CStringWriter& oResult)
{
oResult.AddCharSafe((TCHAR)'<');
oResult.WriteEncodeXmlString(GetName());
if(GetAttributesCount() > 0)
{
MoveToFirstAttribute();
CString sName = GetName();
while( !sName.IsEmpty() )
{
oResult.AddCharSafe(TCHAR(' '));
oResult.WriteEncodeXmlString(GetName());
oResult.AddChar2Safe(TCHAR('='), TCHAR('\"'));
oResult.WriteEncodeXmlString(GetText());
oResult.AddCharSafe(TCHAR('\"'));
if ( !MoveToNextAttribute() )
break;
sName = GetName();
}
MoveToElement();
}
if (IsEmptyNode())
oResult.AddChar2Safe(TCHAR('/'), TCHAR('>'));
else
oResult.AddCharSafe(TCHAR('>'));
}
WCHAR* UnicodeFromUtf8(xmlChar* pValue)
{
BYTE* pBuffer = (BYTE*)pValue;
LONG lCount = strlen((char*)pValue);
LONG lLenght = 0;
WCHAR* pUnicodeString = new WCHAR[lCount + 1];
LONG lIndexUnicode = 0;
for (LONG lIndex = 0; lIndex < lCount; ++lIndex)
{
if (0x00 == (0x80 & pBuffer[lIndex]))
{
//strRes += (WCHAR)pBuffer[lIndex];
pUnicodeString[lIndexUnicode++] = (WCHAR)pBuffer[lIndex];
continue;
}
else if (0x00 == (0x20 & pBuffer[lIndex]))
{
WCHAR mem = (WCHAR)(((pBuffer[lIndex] & 0x1F) << 6) + (pBuffer[lIndex + 1] & 0x3F));
//strRes += mem;
pUnicodeString[lIndexUnicode++] = mem;
lIndex += 1;
}
else if (0x00 == (0x10 & pBuffer[lIndex]))
{
WCHAR mem = (WCHAR)(((pBuffer[lIndex] & 0x0F) << 12) + ((pBuffer[lIndex + 1] & 0x3F) << 6) + (pBuffer[lIndex + 2] & 0x3F));
//strRes += mem;
pUnicodeString[lIndexUnicode++] = mem;
lIndex += 2;
}
else
{
BYTE mem = pBuffer[lIndex];
//pUnicodeString[lIndexUnicode++] = mem;
}
}
pUnicodeString[lIndexUnicode] = 0;
return pUnicodeString;
}
void UnicodeToUtf8(CString& strXml, BYTE*& pBuffer, LONG& lLen)
{
int nLength = strXml.GetLength();
pBuffer = new BYTE[nLength*3 + 1];
// Encoding Unicode to UTF-8
WideCharToMultiByte(CP_UTF8, 0, strXml.GetBuffer(), nLength + 1, (LPSTR)pBuffer, nLength*3, NULL, NULL);
lLen = strlen((LPSTR)pBuffer);
}
};
}