diff options
author | John Abd-El-Malek <jabdelmalek@google.com> | 2014-05-23 17:28:10 -0700 |
---|---|---|
committer | John Abd-El-Malek <jabdelmalek@google.com> | 2014-05-23 17:41:56 -0700 |
commit | 3f3b45cc74b0499912409f766a595945dbbfc4c5 (patch) | |
tree | ec400b6965477b88ea7f0d335f7e5c52044c346c /core/src/fxcrt/fx_xml_parser.cpp | |
parent | 6fe4aed948337175f6f7f81bb03c37b9c7f535da (diff) | |
download | pdfium-3f3b45cc74b0499912409f766a595945dbbfc4c5.tar.xz |
Convert all line endings to LF.
Diffstat (limited to 'core/src/fxcrt/fx_xml_parser.cpp')
-rw-r--r-- | core/src/fxcrt/fx_xml_parser.cpp | 2034 |
1 files changed, 1017 insertions, 1017 deletions
diff --git a/core/src/fxcrt/fx_xml_parser.cpp b/core/src/fxcrt/fx_xml_parser.cpp index 85e9544342..c3d4b9c506 100644 --- a/core/src/fxcrt/fx_xml_parser.cpp +++ b/core/src/fxcrt/fx_xml_parser.cpp @@ -1,1017 +1,1017 @@ -// Copyright 2014 PDFium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-// Original code copyright 2014 Foxit Software Inc. http://www.foxitsoftware.com
-
-#include "../../include/fxcrt/fx_xml.h"
-#include "xml_int.h"
-CXML_Parser::~CXML_Parser()
-{
- if (m_bOwnedStream) {
- m_pDataAcc->Release();
- }
-}
-FX_BOOL CXML_Parser::Init(FX_LPBYTE pBuffer, size_t size)
-{
- if (m_pAllocator) {
- m_pDataAcc = FX_NewAtAllocator(m_pAllocator)CXML_DataBufAcc(pBuffer, size, m_pAllocator);
- } else {
- m_pDataAcc = FX_NEW CXML_DataBufAcc(pBuffer, size, NULL);
- }
- if (!m_pDataAcc) {
- return FALSE;
- }
- return Init(TRUE);
-}
-FX_BOOL CXML_Parser::Init(IFX_FileRead *pFileRead)
-{
- if (m_pAllocator) {
- m_pDataAcc = FX_NewAtAllocator(m_pAllocator)CXML_DataStmAcc(pFileRead, m_pAllocator);
- } else {
- m_pDataAcc = FX_NEW CXML_DataStmAcc(pFileRead, NULL);
- }
- if (!m_pDataAcc) {
- return FALSE;
- }
- return Init(TRUE);
-}
-FX_BOOL CXML_Parser::Init(IFX_BufferRead *pBuffer)
-{
- if (!pBuffer) {
- return FALSE;
- }
- m_pDataAcc = pBuffer;
- return Init(FALSE);
-}
-FX_BOOL CXML_Parser::Init(FX_BOOL bOwndedStream)
-{
- m_bOwnedStream = bOwndedStream;
- m_nOffset = 0;
- return ReadNextBlock();
-}
-FX_BOOL CXML_Parser::ReadNextBlock()
-{
- if (!m_pDataAcc->ReadNextBlock()) {
- return FALSE;
- }
- m_pBuffer = m_pDataAcc->GetBlockBuffer();
- m_dwBufferSize = m_pDataAcc->GetBlockSize();
- m_nBufferOffset = m_pDataAcc->GetBlockOffset();
- m_dwIndex = 0;
- return m_dwBufferSize > 0;
-}
-FX_BOOL CXML_Parser::IsEOF()
-{
- if (!m_pDataAcc->IsEOF()) {
- return FALSE;
- }
- return m_dwIndex >= m_dwBufferSize;
-}
-#define FXCRTM_XML_CHARTYPE_Normal 0x00
-#define FXCRTM_XML_CHARTYPE_SpaceChar 0x01
-#define FXCRTM_XML_CHARTYPE_Letter 0x02
-#define FXCRTM_XML_CHARTYPE_Digital 0x04
-#define FXCRTM_XML_CHARTYPE_NameIntro 0x08
-#define FXCRTM_XML_CHARTYPE_NameChar 0x10
-#define FXCRTM_XML_CHARTYPE_HexDigital 0x20
-#define FXCRTM_XML_CHARTYPE_HexLowerLetter 0x40
-#define FXCRTM_XML_CHARTYPE_HexUpperLetter 0x60
-#define FXCRTM_XML_CHARTYPE_HexChar 0x60
-FX_BYTE g_FXCRT_XML_ByteTypes[256] = {
- 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01,
- 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01,
- 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x10, 0x00,
- 0x34, 0x34, 0x34, 0x34, 0x34, 0x34, 0x34, 0x34, 0x34, 0x34, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x7A, 0x7A, 0x7A, 0x7A, 0x7A, 0x7A, 0x1A, 0x1A, 0x1A, 0x1A, 0x1A, 0x1A, 0x1A, 0x1A, 0x1A,
- 0x1A, 0x1A, 0x1A, 0x1A, 0x1A, 0x1A, 0x1A, 0x1A, 0x1A, 0x1A, 0x1A, 0x00, 0x00, 0x00, 0x00, 0x18,
- 0x00, 0x5A, 0x5A, 0x5A, 0x5A, 0x5A, 0x5A, 0x1A, 0x1A, 0x1A, 0x1A, 0x1A, 0x1A, 0x1A, 0x1A, 0x1A,
- 0x1A, 0x1A, 0x1A, 0x1A, 0x1A, 0x1A, 0x1A, 0x1A, 0x1A, 0x1A, 0x1A, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x1A, 0x1A, 0x1A, 0x1A, 0x1A, 0x1A, 0x1A, 0x1A, 0x1A, 0x1A, 0x1A, 0x1A, 0x1A, 0x1A, 0x1A, 0x1A,
- 0x1A, 0x1A, 0x1A, 0x1A, 0x1A, 0x1A, 0x1A, 0x1A, 0x1A, 0x1A, 0x1A, 0x1A, 0x1A, 0x1A, 0x1A, 0x1A,
- 0x1A, 0x1A, 0x1A, 0x1A, 0x1A, 0x1A, 0x1A, 0x1A, 0x1A, 0x1A, 0x1A, 0x1A, 0x1A, 0x1A, 0x1A, 0x1A,
- 0x1A, 0x1A, 0x1A, 0x1A, 0x1A, 0x1A, 0x1A, 0x1A, 0x1A, 0x1A, 0x1A, 0x1A, 0x1A, 0x1A, 0x1A, 0x1A,
- 0x1A, 0x1A, 0x1A, 0x1A, 0x1A, 0x1A, 0x1A, 0x1A, 0x1A, 0x1A, 0x1A, 0x1A, 0x1A, 0x1A, 0x1A, 0x1A,
- 0x1A, 0x1A, 0x1A, 0x1A, 0x1A, 0x1A, 0x1A, 0x1A, 0x1A, 0x1A, 0x1A, 0x1A, 0x1A, 0x1A, 0x1A, 0x1A,
- 0x1A, 0x1A, 0x1A, 0x1A, 0x1A, 0x1A, 0x1A, 0x1A, 0x1A, 0x1A, 0x1A, 0x1A, 0x1A, 0x1A, 0x1A, 0x1A,
- 0x1A, 0x1A, 0x1A, 0x1A, 0x1A, 0x1A, 0x1A, 0x1A, 0x1A, 0x1A, 0x1A, 0x1A, 0x1A, 0x1A, 0x01, 0x01,
-};
-FX_BOOL g_FXCRT_XML_IsWhiteSpace(FX_BYTE ch)
-{
- return (g_FXCRT_XML_ByteTypes[ch] & FXCRTM_XML_CHARTYPE_SpaceChar) != 0;
-}
-FX_BOOL g_FXCRT_XML_IsLetter(FX_BYTE ch)
-{
- return (g_FXCRT_XML_ByteTypes[ch] & FXCRTM_XML_CHARTYPE_Letter) != 0;
-}
-FX_BOOL g_FXCRT_XML_IsDigital(FX_BYTE ch)
-{
- return (g_FXCRT_XML_ByteTypes[ch] & FXCRTM_XML_CHARTYPE_Digital) != 0;
-}
-FX_BOOL g_FXCRT_XML_IsNameIntro(FX_BYTE ch)
-{
- return (g_FXCRT_XML_ByteTypes[ch] & FXCRTM_XML_CHARTYPE_NameIntro) != 0;
-}
-FX_BOOL g_FXCRT_XML_IsNameChar(FX_BYTE ch)
-{
- return (g_FXCRT_XML_ByteTypes[ch] & FXCRTM_XML_CHARTYPE_NameChar) != 0;
-}
-FX_BOOL g_FXCRT_XML_IsHexChar(FX_BYTE ch)
-{
- return (g_FXCRT_XML_ByteTypes[ch] & FXCRTM_XML_CHARTYPE_HexChar) != 0;
-}
-void CXML_Parser::SkipWhiteSpaces()
-{
- m_nOffset = m_nBufferOffset + (FX_FILESIZE)m_dwIndex;
- if (IsEOF()) {
- return;
- }
- do {
- while (m_dwIndex < m_dwBufferSize && g_FXCRT_XML_IsWhiteSpace(m_pBuffer[m_dwIndex])) {
- m_dwIndex ++;
- }
- m_nOffset = m_nBufferOffset + (FX_FILESIZE)m_dwIndex;
- if (m_dwIndex < m_dwBufferSize || IsEOF()) {
- break;
- }
- } while (ReadNextBlock());
-}
-void CXML_Parser::GetName(CFX_ByteStringL &space, CFX_ByteStringL &name)
-{
- m_nOffset = m_nBufferOffset + (FX_FILESIZE)m_dwIndex;
- if (IsEOF()) {
- return;
- }
- CFX_ByteTextBuf buf(m_pAllocator);
- FX_BYTE ch;
- do {
- while (m_dwIndex < m_dwBufferSize) {
- ch = m_pBuffer[m_dwIndex];
- if (ch == ':') {
- buf.GetByteStringL(space);
- buf.Clear();
- } else if (g_FXCRT_XML_IsNameChar(ch)) {
- buf.AppendChar(ch);
- } else {
- break;
- }
- m_dwIndex ++;
- }
- m_nOffset = m_nBufferOffset + (FX_FILESIZE)m_dwIndex;
- if (m_dwIndex < m_dwBufferSize || IsEOF()) {
- break;
- }
- } while (ReadNextBlock());
- buf.GetByteStringL(name);
-}
-void CXML_Parser::SkipLiterals(FX_BSTR str)
-{
- m_nOffset = m_nBufferOffset + (FX_FILESIZE)m_dwIndex;
- if (IsEOF()) {
- return;
- }
- FX_INT32 i = 0, iLen = str.GetLength();
- do {
- while (m_dwIndex < m_dwBufferSize) {
- if (str.GetAt(i) != m_pBuffer[m_dwIndex ++]) {
- i = 0;
- } else {
- i ++;
- if (i == iLen) {
- break;
- }
- }
- }
- m_nOffset = m_nBufferOffset + (FX_FILESIZE)m_dwIndex;
- if (i == iLen) {
- return;
- }
- if (m_dwIndex < m_dwBufferSize || IsEOF()) {
- break;
- }
- } while (ReadNextBlock());
- while (!m_pDataAcc->IsEOF()) {
- ReadNextBlock();
- m_nOffset = m_nBufferOffset + (FX_FILESIZE)m_dwBufferSize;
- }
- m_dwIndex = m_dwBufferSize;
-}
-FX_DWORD CXML_Parser::GetCharRef()
-{
- m_nOffset = m_nBufferOffset + (FX_FILESIZE)m_dwIndex;
- if (IsEOF()) {
- return 0;
- }
- FX_BYTE ch;
- FX_INT32 iState = 0;
- CFX_ByteTextBuf buf(m_pAllocator);
- FX_DWORD code = 0;
- do {
- while (m_dwIndex < m_dwBufferSize) {
- ch = m_pBuffer[m_dwIndex];
- switch (iState) {
- case 0:
- if (ch == '#') {
- m_dwIndex ++;
- iState = 2;
- break;
- }
- iState = 1;
- case 1:
- m_dwIndex ++;
- if (ch == ';') {
- CFX_ByteStringC ref = buf.GetByteString();
- if (ref == FX_BSTRC("gt")) {
- code = '>';
- } else if (ref == FX_BSTRC("lt")) {
- code = '<';
- } else if (ref == FX_BSTRC("amp")) {
- code = '&';
- } else if (ref == FX_BSTRC("apos")) {
- code = '\'';
- } else if (ref == FX_BSTRC("quot")) {
- code = '"';
- }
- iState = 10;
- break;
- }
- buf.AppendByte(ch);
- break;
- case 2:
- if (ch == 'x') {
- m_dwIndex ++;
- iState = 4;
- break;
- }
- iState = 3;
- case 3:
- m_dwIndex ++;
- if (ch == ';') {
- iState = 10;
- break;
- }
- if (g_FXCRT_XML_IsDigital(ch)) {
- code = code * 10 + ch - '0';
- }
- break;
- case 4:
- m_dwIndex ++;
- if (ch == ';') {
- iState = 10;
- break;
- }
- FX_BYTE nHex = g_FXCRT_XML_ByteTypes[ch] & FXCRTM_XML_CHARTYPE_HexChar;
- if (nHex) {
- if (nHex == FXCRTM_XML_CHARTYPE_HexDigital) {
- code = (code << 4) + ch - '0';
- } else if (nHex == FXCRTM_XML_CHARTYPE_HexLowerLetter) {
- code = (code << 4) + ch - 87;
- } else {
- code = (code << 4) + ch - 55;
- }
- }
- break;
- }
- if (iState == 10) {
- break;
- }
- }
- m_nOffset = m_nBufferOffset + (FX_FILESIZE)m_dwIndex;
- if (iState == 10 || m_dwIndex < m_dwBufferSize || IsEOF()) {
- break;
- }
- } while (ReadNextBlock());
- return code;
-}
-void CXML_Parser::GetAttrValue(CFX_WideStringL &value)
-{
- m_nOffset = m_nBufferOffset + (FX_FILESIZE)m_dwIndex;
- if (IsEOF()) {
- return;
- }
- CFX_UTF8Decoder decoder(m_pAllocator);
- FX_BYTE mark = 0, ch;
- do {
- while (m_dwIndex < m_dwBufferSize) {
- ch = m_pBuffer[m_dwIndex];
- if (mark == 0) {
- if (ch != '\'' && ch != '"') {
- return;
- }
- mark = ch;
- m_dwIndex ++;
- ch = 0;
- continue;
- }
- m_dwIndex ++;
- if (ch == mark) {
- break;
- }
- if (ch == '&') {
- decoder.AppendChar(GetCharRef());
- if (IsEOF()) {
- decoder.GetResult(value);
- return;
- }
- } else {
- decoder.Input(ch);
- }
- }
- m_nOffset = m_nBufferOffset + (FX_FILESIZE)m_dwIndex;
- if (ch == mark || m_dwIndex < m_dwBufferSize || IsEOF()) {
- break;
- }
- } while (ReadNextBlock());
- decoder.GetResult(value);
-}
-void CXML_Parser::GetTagName(CFX_ByteStringL &space, CFX_ByteStringL &name, FX_BOOL &bEndTag, FX_BOOL bStartTag)
-{
- m_nOffset = m_nBufferOffset + (FX_FILESIZE)m_dwIndex;
- if (IsEOF()) {
- return;
- }
- bEndTag = FALSE;
- FX_BYTE ch;
- FX_INT32 iState = bStartTag ? 1 : 0;
- do {
- while (m_dwIndex < m_dwBufferSize) {
- ch = m_pBuffer[m_dwIndex];
- switch (iState) {
- case 0:
- m_dwIndex ++;
- if (ch != '<') {
- break;
- }
- iState = 1;
- break;
- case 1:
- if (ch == '?') {
- m_dwIndex ++;
- SkipLiterals(FX_BSTRC("?>"));
- iState = 0;
- break;
- } else if (ch == '!') {
- m_dwIndex ++;
- SkipLiterals(FX_BSTRC("-->"));
- iState = 0;
- break;
- }
- if (ch == '/') {
- m_dwIndex ++;
- GetName(space, name);
- bEndTag = TRUE;
- } else {
- GetName(space, name);
- bEndTag = FALSE;
- }
- return;
- }
- }
- m_nOffset = m_nBufferOffset + (FX_FILESIZE)m_dwIndex;
- if (m_dwIndex < m_dwBufferSize || IsEOF()) {
- break;
- }
- } while (ReadNextBlock());
-}
-CXML_Element* CXML_Parser::ParseElement(CXML_Element* pParent, FX_BOOL bStartTag)
-{
- m_nOffset = m_nBufferOffset + (FX_FILESIZE)m_dwIndex;
- if (IsEOF()) {
- return NULL;
- }
- CFX_ByteStringL tag_name, tag_space;
- FX_BOOL bEndTag;
- GetTagName(tag_space, tag_name, bEndTag, bStartTag);
- if (tag_name.IsEmpty() || bEndTag) {
- tag_space.Empty(m_pAllocator);
- return NULL;
- }
- CXML_Element* pElement;
- if (m_pAllocator) {
- pElement = FX_NewAtAllocator(m_pAllocator)CXML_Element(m_pAllocator);
- } else {
- pElement = FX_NEW CXML_Element;
- }
- if (pElement) {
- pElement->m_pParent = pParent;
- pElement->SetTag(tag_space, tag_name);
- }
- tag_space.Empty(m_pAllocator);
- tag_name.Empty(m_pAllocator);
- if (!pElement) {
- return NULL;
- }
- do {
- CFX_ByteStringL attr_space, attr_name;
- while (m_dwIndex < m_dwBufferSize) {
- SkipWhiteSpaces();
- if (IsEOF()) {
- break;
- }
- if (!g_FXCRT_XML_IsNameIntro(m_pBuffer[m_dwIndex])) {
- break;
- }
- attr_space.Empty(m_pAllocator);
- attr_name.Empty(m_pAllocator);
- GetName(attr_space, attr_name);
- SkipWhiteSpaces();
- if (IsEOF()) {
- break;
- }
- if (m_pBuffer[m_dwIndex] != '=') {
- break;
- }
- m_dwIndex ++;
- SkipWhiteSpaces();
- if (IsEOF()) {
- break;
- }
- CFX_WideStringL attr_value;
- GetAttrValue(attr_value);
- pElement->m_AttrMap.SetAt(attr_space, attr_name, attr_value, m_pAllocator);
- attr_value.Empty(m_pAllocator);
- }
- attr_space.Empty(m_pAllocator);
- attr_name.Empty(m_pAllocator);
- m_nOffset = m_nBufferOffset + (FX_FILESIZE)m_dwIndex;
- if (m_dwIndex < m_dwBufferSize || IsEOF()) {
- break;
- }
- } while (ReadNextBlock());
- SkipWhiteSpaces();
- if (IsEOF()) {
- return pElement;
- }
- FX_BYTE ch = m_pBuffer[m_dwIndex ++];
- if (ch == '/') {
- m_dwIndex ++;
- m_nOffset = m_nBufferOffset + (FX_FILESIZE)m_dwIndex;
- return pElement;
- }
- if (ch != '>') {
- m_nOffset = m_nBufferOffset + (FX_FILESIZE)m_dwIndex;
- if (m_pAllocator) {
- FX_DeleteAtAllocator(pElement, m_pAllocator, CXML_Element);
- } else {
- delete pElement;
- }
- return NULL;
- }
- SkipWhiteSpaces();
- if (IsEOF()) {
- return pElement;
- }
- CFX_UTF8Decoder decoder(m_pAllocator);
- CFX_WideTextBuf content(m_pAllocator);
- FX_BOOL bCDATA = FALSE;
- FX_INT32 iState = 0;
- do {
- while (m_dwIndex < m_dwBufferSize) {
- ch = m_pBuffer[m_dwIndex ++];
- switch (iState) {
- case 0:
- if (ch == '<') {
- iState = 1;
- } else if (ch == '&') {
- decoder.ClearStatus();
- decoder.AppendChar(GetCharRef());
- } else {
- decoder.Input(ch);
- }
- break;
- case 1:
- if (ch == '!') {
- iState = 2;
- } else if (ch == '?') {
- SkipLiterals(FX_BSTRC("?>"));
- SkipWhiteSpaces();
- iState = 0;
- } else if (ch == '/') {
- CFX_ByteStringL space, name;
- GetName(space, name);
- space.Empty(m_pAllocator);
- name.Empty(m_pAllocator);
- SkipWhiteSpaces();
- m_dwIndex ++;
- iState = 10;
- } else {
- content << decoder.GetResult();
- CFX_WideStringL dataStr;
- content.GetWideStringL(dataStr);
- if (!bCDATA && !m_bSaveSpaceChars) {
- dataStr.TrimRight((FX_LPCWSTR)L" \t\r\n");
- }
- InsertContentSegment(bCDATA, dataStr, pElement);
- dataStr.Empty(m_pAllocator);
- content.Clear();
- decoder.Clear();
- bCDATA = FALSE;
- iState = 0;
- m_dwIndex --;
- CXML_Element* pSubElement = ParseElement(pElement, TRUE);
- if (pSubElement == NULL) {
- break;
- }
- pSubElement->m_pParent = pElement;
- pElement->m_Children.Add((FX_LPVOID)CXML_Element::Element);
- pElement->m_Children.Add(pSubElement);
- SkipWhiteSpaces();
- }
- break;
- case 2:
- if (ch == '[') {
- SkipLiterals(FX_BSTRC("]]>"));
- } else if (ch == '-') {
- m_dwIndex ++;
- SkipLiterals(FX_BSTRC("-->"));
- } else {
- SkipLiterals(FX_BSTRC(">"));
- }
- decoder.Clear();
- SkipWhiteSpaces();
- iState = 0;
- break;
- }
- if (iState == 10) {
- break;
- }
- }
- m_nOffset = m_nBufferOffset + (FX_FILESIZE)m_dwIndex;
- if (iState == 10 || m_dwIndex < m_dwBufferSize || IsEOF()) {
- break;
- }
- } while (ReadNextBlock());
- content << decoder.GetResult();
- CFX_WideStringL dataStr;
- content.GetWideStringL(dataStr);
- if (!m_bSaveSpaceChars) {
- dataStr.TrimRight((FX_LPCWSTR)L" \t\r\n");
- }
- InsertContentSegment(bCDATA, dataStr, pElement);
- dataStr.Empty(m_pAllocator);
- content.Clear();
- decoder.Clear();
- bCDATA = FALSE;
- return pElement;
-}
-void CXML_Parser::InsertContentSegment(FX_BOOL bCDATA, FX_WSTR content, CXML_Element* pElement)
-{
- if (content.IsEmpty()) {
- return;
- }
- CXML_Content* pContent;
- if (m_pAllocator) {
- pContent = FX_NewAtAllocator(m_pAllocator)CXML_Content;
- } else {
- pContent = FX_NEW CXML_Content;
- }
- if (!pContent) {
- return;
- }
- pContent->Set(bCDATA, content, m_pAllocator);
- pElement->m_Children.Add((FX_LPVOID)CXML_Element::Content);
- pElement->m_Children.Add(pContent);
-}
-static CXML_Element* XML_ContinueParse(CXML_Parser &parser, FX_BOOL bSaveSpaceChars, FX_FILESIZE* pParsedSize)
-{
- parser.m_bSaveSpaceChars = bSaveSpaceChars;
- CXML_Element* pElement = parser.ParseElement(NULL, FALSE);
- if (pParsedSize) {
- *pParsedSize = parser.m_nOffset;
- }
- return pElement;
-}
-CXML_Element* CXML_Element::Parse(const void* pBuffer, size_t size, FX_BOOL bSaveSpaceChars, FX_FILESIZE* pParsedSize, IFX_Allocator* pAllocator)
-{
- CXML_Parser parser(pAllocator);
- if (!parser.Init((FX_LPBYTE)pBuffer, size)) {
- return NULL;
- }
- return XML_ContinueParse(parser, bSaveSpaceChars, pParsedSize);
-}
-CXML_Element* CXML_Element::Parse(IFX_FileRead *pFile, FX_BOOL bSaveSpaceChars, FX_FILESIZE* pParsedSize, IFX_Allocator* pAllocator)
-{
- CXML_Parser parser(pAllocator);
- if (!parser.Init(pFile)) {
- return NULL;
- }
- return XML_ContinueParse(parser, bSaveSpaceChars, pParsedSize);
-}
-CXML_Element* CXML_Element::Parse(IFX_BufferRead *pBuffer, FX_BOOL bSaveSpaceChars, FX_FILESIZE* pParsedSize, IFX_Allocator* pAllocator)
-{
- CXML_Parser parser(pAllocator);
- if (!parser.Init(pBuffer)) {
- return NULL;
- }
- return XML_ContinueParse(parser, bSaveSpaceChars, pParsedSize);
-}
-CXML_Element::CXML_Element(IFX_Allocator* pAllocator)
- : m_pParent(NULL)
- , m_QSpaceName()
- , m_TagName()
- , m_AttrMap()
- , m_Children(pAllocator)
-{
-}
-CXML_Element::CXML_Element(FX_BSTR qSpace, FX_BSTR tagName, IFX_Allocator* pAllocator)
- : m_pParent(NULL)
- , m_QSpaceName()
- , m_TagName()
- , m_AttrMap()
- , m_Children(pAllocator)
-{
- m_QSpaceName.Set(qSpace, pAllocator);
- m_TagName.Set(tagName, pAllocator);
-}
-CXML_Element::CXML_Element(FX_BSTR qTagName, IFX_Allocator* pAllocator)
- : m_pParent(NULL)
- , m_QSpaceName()
- , m_TagName()
- , m_AttrMap()
- , m_Children(pAllocator)
-{
- SetTag(qTagName);
-}
-CXML_Element::~CXML_Element()
-{
- Empty();
-}
-void CXML_Element::Empty()
-{
- IFX_Allocator* pAllocator = m_Children.m_pAllocator;
- m_QSpaceName.Empty(pAllocator);
- m_TagName.Empty(pAllocator);
- m_AttrMap.RemoveAll(pAllocator);
- RemoveChildren();
-}
-void CXML_Element::RemoveChildren()
-{
- IFX_Allocator* pAllocator = m_Children.m_pAllocator;
- for (int i = 0; i < m_Children.GetSize(); i += 2) {
- ChildType type = (ChildType)(FX_UINTPTR)m_Children.GetAt(i);
- if (type == Content) {
- CXML_Content* content = (CXML_Content*)m_Children.GetAt(i + 1);
- if (pAllocator) {
- FX_DeleteAtAllocator(content, pAllocator, CXML_Content);
- } else {
- delete content;
- }
- } else if (type == Element) {
- CXML_Element* child = (CXML_Element*)m_Children.GetAt(i + 1);
- child->RemoveChildren();
- if (pAllocator) {
- FX_DeleteAtAllocator(child, pAllocator, CXML_Element);
- } else {
- delete child;
- }
- }
- }
- m_Children.RemoveAll();
-}
-CFX_ByteString CXML_Element::GetTagName(FX_BOOL bQualified) const
-{
- if (!bQualified || m_QSpaceName.IsEmpty()) {
- return m_TagName;
- }
- CFX_ByteString bsTag = m_QSpaceName;
- bsTag += ":";
- bsTag += m_TagName;
- return bsTag;
-}
-void CXML_Element::GetTagName(CFX_ByteStringL &tagName, FX_BOOL bQualified) const
-{
- IFX_Allocator* pAllocator = m_Children.m_pAllocator;
- if (!bQualified || m_QSpaceName.IsEmpty()) {
- tagName.Set(m_TagName, pAllocator);
- return;
- }
- FX_LPSTR str = tagName.AllocBuffer(m_QSpaceName.GetLength() + m_TagName.GetLength() + 2, pAllocator);
- if (!str) {
- return;
- }
- FXSYS_memcpy32(str, m_QSpaceName.GetCStr(), m_QSpaceName.GetLength());
- str += m_QSpaceName.GetLength();
- *str = ':';
- str ++;
- FXSYS_memcpy32(str, m_TagName.GetCStr(), m_TagName.GetLength());
- str += m_TagName.GetLength();
- *str = '\0';
-}
-CFX_ByteString CXML_Element::GetNamespace(FX_BOOL bQualified) const
-{
- if (bQualified) {
- return m_QSpaceName;
- }
- return GetNamespaceURI(m_QSpaceName);
-}
-void CXML_Element::GetNamespace(CFX_ByteStringL &nameSpace, FX_BOOL bQualified) const
-{
- IFX_Allocator* pAllocator = m_Children.m_pAllocator;
- if (bQualified) {
- nameSpace.Set(m_QSpaceName, pAllocator);
- return;
- }
- GetNamespaceURI(m_QSpaceName, nameSpace);
-}
-CFX_ByteString CXML_Element::GetNamespaceURI(FX_BSTR qName) const
-{
- const CFX_WideStringL* pwsSpace;
- const CXML_Element *pElement = this;
- do {
- if (qName.IsEmpty()) {
- pwsSpace = pElement->m_AttrMap.Lookup(FX_BSTRC(""), FX_BSTRC("xmlns"));
- } else {
- pwsSpace = pElement->m_AttrMap.Lookup(FX_BSTRC("xmlns"), qName);
- }
- if (pwsSpace) {
- break;
- }
- pElement = pElement->GetParent();
- } while(pElement);
- return pwsSpace ? FX_UTF8Encode(*pwsSpace) : CFX_ByteString();
-}
-void CXML_Element::GetNamespaceURI(FX_BSTR qName, CFX_ByteStringL &uri) const
-{
- IFX_Allocator* pAllocator = m_Children.m_pAllocator;
- const CFX_WideStringL* pwsSpace;
- const CXML_Element *pElement = this;
- do {
- if (qName.IsEmpty()) {
- pwsSpace = pElement->m_AttrMap.Lookup(FX_BSTRC(""), FX_BSTRC("xmlns"));
- } else {
- pwsSpace = pElement->m_AttrMap.Lookup(FX_BSTRC("xmlns"), qName);
- }
- if (pwsSpace) {
- break;
- }
- pElement = pElement->GetParent();
- } while(pElement);
- if (pwsSpace) {
- FX_UTF8Encode(pwsSpace->GetPtr(), pwsSpace->GetLength(), uri, pAllocator);
- }
-}
-void CXML_Element::GetAttrByIndex(int index, CFX_ByteString& space, CFX_ByteString& name, CFX_WideString& value) const
-{
- if (index < 0 || index >= m_AttrMap.GetSize()) {
- return;
- }
- CXML_AttrItem& item = m_AttrMap.GetAt(index);
- space = item.m_QSpaceName;
- name = item.m_AttrName;
- value = item.m_Value;
-}
-void CXML_Element::GetAttrByIndex(int index, CFX_ByteStringL &space, CFX_ByteStringL &name, CFX_WideStringL &value) const
-{
- if (index < 0 || index >= m_AttrMap.GetSize()) {
- return;
- }
- IFX_Allocator* pAllocator = m_Children.m_pAllocator;
- CXML_AttrItem& item = m_AttrMap.GetAt(index);
- space.Set(item.m_QSpaceName, pAllocator);
- name.Set(item.m_AttrName, pAllocator);
- value.Set(item.m_Value, pAllocator);
-}
-FX_BOOL CXML_Element::HasAttr(FX_BSTR name) const
-{
- CFX_ByteStringC bsSpace, bsName;
- FX_XML_SplitQualifiedName(name, bsSpace, bsName);
- return m_AttrMap.Lookup(bsSpace, bsName) != NULL;
-}
-FX_BOOL CXML_Element::GetAttrValue(FX_BSTR name, CFX_WideString& attribute) const
-{
- CFX_ByteStringC bsSpace, bsName;
- FX_XML_SplitQualifiedName(name, bsSpace, bsName);
- const CFX_WideStringL* pValue = m_AttrMap.Lookup(bsSpace, bsName);
- if (pValue) {
- attribute = CFX_WideString(pValue->GetPtr(), pValue->GetLength());
- return TRUE;
- }
- return FALSE;
-}
-const CFX_WideStringL* CXML_Element::GetAttrValuePtr(FX_BSTR name) const
-{
- CFX_ByteStringC bsSpace, bsName;
- FX_XML_SplitQualifiedName(name, bsSpace, bsName);
- return m_AttrMap.Lookup(bsSpace, bsName);
-}
-FX_BOOL CXML_Element::GetAttrValue(FX_BSTR space, FX_BSTR name, CFX_WideString& attribute) const
-{
- const CFX_WideStringL* pValue = m_AttrMap.Lookup(space, name);
- if (pValue) {
- attribute = CFX_WideString(pValue->GetPtr(), pValue->GetLength());
- return TRUE;
- }
- return FALSE;
-}
-const CFX_WideStringL* CXML_Element::GetAttrValuePtr(FX_BSTR space, FX_BSTR name) const
-{
- return m_AttrMap.Lookup(space, name);
-}
-FX_BOOL CXML_Element::GetAttrInteger(FX_BSTR name, int& attribute) const
-{
- CFX_ByteStringC bsSpace, bsName;
- FX_XML_SplitQualifiedName(name, bsSpace, bsName);
- const CFX_WideStringL* pwsValue = m_AttrMap.Lookup(bsSpace, bsName);
- if (pwsValue) {
- attribute = pwsValue->GetInteger();
- return TRUE;
- }
- return FALSE;
-}
-FX_BOOL CXML_Element::GetAttrInteger(FX_BSTR space, FX_BSTR name, int& attribute) const
-{
- const CFX_WideStringL* pwsValue = m_AttrMap.Lookup(space, name);
- if (pwsValue) {
- attribute = pwsValue->GetInteger();
- return TRUE;
- }
- return FALSE;
-}
-FX_BOOL CXML_Element::GetAttrFloat(FX_BSTR name, FX_FLOAT& attribute) const
-{
- CFX_ByteStringC bsSpace, bsName;
- FX_XML_SplitQualifiedName(name, bsSpace, bsName);
- return GetAttrFloat(bsSpace, bsName, attribute);
-}
-FX_BOOL CXML_Element::GetAttrFloat(FX_BSTR space, FX_BSTR name, FX_FLOAT& attribute) const
-{
- CFX_WideString value;
- const CFX_WideStringL* pValue = m_AttrMap.Lookup(space, name);
- if (pValue) {
- attribute = pValue->GetFloat();
- return TRUE;
- }
- return FALSE;
-}
-FX_DWORD CXML_Element::CountChildren() const
-{
- return m_Children.GetSize() / 2;
-}
-CXML_Element::ChildType CXML_Element::GetChildType(FX_DWORD index) const
-{
- index <<= 1;
- if (index >= (FX_DWORD)m_Children.GetSize()) {
- return Invalid;
- }
- return (ChildType)(FX_UINTPTR)m_Children.GetAt(index);
-}
-CFX_WideString CXML_Element::GetContent(FX_DWORD index) const
-{
- index <<= 1;
- if (index >= (FX_DWORD)m_Children.GetSize() ||
- (ChildType)(FX_UINTPTR)m_Children.GetAt(index) != Content) {
- return CFX_WideString();
- }
- CXML_Content* pContent = (CXML_Content*)m_Children.GetAt(index + 1);
- if (pContent) {
- return pContent->m_Content;
- }
- return CFX_WideString();
-}
-const CFX_WideStringL* CXML_Element::GetContentPtr(FX_DWORD index) const
-{
- index <<= 1;
- if (index >= (FX_DWORD)m_Children.GetSize() ||
- (ChildType)(FX_UINTPTR)m_Children.GetAt(index) != Content) {
- return NULL;
- }
- CXML_Content* pContent = (CXML_Content*)m_Children.GetAt(index + 1);
- if (pContent) {
- return &pContent->m_Content;
- }
- return NULL;
-}
-CXML_Element* CXML_Element::GetElement(FX_DWORD index) const
-{
- index <<= 1;
- if (index >= (FX_DWORD)m_Children.GetSize() ||
- (ChildType)(FX_UINTPTR)m_Children.GetAt(index) != Element) {
- return NULL;
- }
- return (CXML_Element*)m_Children.GetAt(index + 1);
-}
-FX_DWORD CXML_Element::CountElements(FX_BSTR space, FX_BSTR tag) const
-{
- int count = 0;
- for (int i = 0; i < m_Children.GetSize(); i += 2) {
- ChildType type = (ChildType)(FX_UINTPTR)m_Children.GetAt(i);
- if (type != Element) {
- continue;
- }
- CXML_Element* pKid = (CXML_Element*)m_Children.GetAt(i + 1);
- if ((space.IsEmpty() || pKid->m_QSpaceName == space) && pKid->m_TagName == tag) {
- count ++;
- }
- }
- return count;
-}
-CXML_Element* CXML_Element::GetElement(FX_BSTR space, FX_BSTR tag, int index) const
-{
- if (index < 0) {
- return NULL;
- }
- for (int i = 0; i < m_Children.GetSize(); i += 2) {
- ChildType type = (ChildType)(FX_UINTPTR)m_Children.GetAt(i);
- if (type != Element) {
- continue;
- }
- CXML_Element* pKid = (CXML_Element*)m_Children.GetAt(i + 1);
- if ((!space.IsEmpty() && pKid->m_QSpaceName != space) || pKid->m_TagName != tag) {
- continue;
- }
- if (index -- == 0) {
- return pKid;
- }
- }
- return NULL;
-}
-FX_DWORD CXML_Element::FindElement(CXML_Element *pChild) const
-{
- for (int i = 0; i < m_Children.GetSize(); i += 2) {
- if ((ChildType)(FX_UINTPTR)m_Children.GetAt(i) == Element &&
- (CXML_Element*)m_Children.GetAt(i + 1) == pChild) {
- return (FX_DWORD)(i >> 1);
- }
- }
- return (FX_DWORD) - 1;
-}
-const CFX_WideStringL* CXML_AttrMap::Lookup(FX_BSTR space, FX_BSTR name) const
-{
- if (m_pMap == NULL) {
- return NULL;
- }
- for (int i = 0; i < m_pMap->GetSize(); i ++) {
- CXML_AttrItem& item = GetAt(i);
- if ((space.IsEmpty() || item.m_QSpaceName == space) && item.m_AttrName == name) {
- return &item.m_Value;
- }
- }
- return NULL;
-}
-void CXML_AttrMap::SetAt(FX_BSTR space, FX_BSTR name, FX_WSTR value, IFX_Allocator* pAllocator)
-{
- for (int i = 0; i < GetSize(); i ++) {
- CXML_AttrItem& item = GetAt(i);
- if ((space.IsEmpty() || item.m_QSpaceName == space) && item.m_AttrName == name) {
- item.m_Value.Set(value, pAllocator);
- return;
- }
- }
- if (!m_pMap) {
- if (pAllocator) {
- m_pMap = FX_NewAtAllocator(pAllocator)CFX_ObjectArray<CXML_AttrItem>(pAllocator);
- } else {
- m_pMap = FX_NEW CFX_ObjectArray<CXML_AttrItem>;
- }
- }
- if (!m_pMap) {
- return;
- }
- CXML_AttrItem* pItem = (CXML_AttrItem*)m_pMap->AddSpace();
- if (!pItem) {
- return;
- }
- pItem->m_QSpaceName.Set(space, pAllocator);
- pItem->m_AttrName.Set(name, pAllocator);
- pItem->m_Value.Set(value, pAllocator);
-}
-void CXML_AttrMap::RemoveAt(FX_BSTR space, FX_BSTR name, IFX_Allocator* pAllocator)
-{
- if (m_pMap == NULL) {
- return;
- }
- for (int i = 0; i < m_pMap->GetSize(); i ++) {
- CXML_AttrItem& item = GetAt(i);
- if ((space.IsEmpty() || item.m_QSpaceName == space) && item.m_AttrName == name) {
- item.Empty(pAllocator);
- m_pMap->RemoveAt(i);
- return;
- }
- }
-}
-int CXML_AttrMap::GetSize() const
-{
- return m_pMap == NULL ? 0 : m_pMap->GetSize();
-}
-CXML_AttrItem& CXML_AttrMap::GetAt(int index) const
-{
- ASSERT(m_pMap != NULL);
- return (*m_pMap)[index];
-}
-void CXML_AttrMap::RemoveAll(IFX_Allocator* pAllocator)
-{
- if (!m_pMap) {
- return;
- }
- for (int i = 0; i < m_pMap->GetSize(); i ++) {
- CXML_AttrItem& item = (*m_pMap)[i];
- item.Empty(pAllocator);
- }
- m_pMap->RemoveAll();
- if (pAllocator) {
- FX_DeleteAtAllocator(m_pMap, pAllocator, CFX_ObjectArray<CXML_AttrItem>);
- } else {
- delete m_pMap;
- }
- m_pMap = NULL;
-}
+// Copyright 2014 PDFium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +// Original code copyright 2014 Foxit Software Inc. http://www.foxitsoftware.com + +#include "../../include/fxcrt/fx_xml.h" +#include "xml_int.h" +CXML_Parser::~CXML_Parser() +{ + if (m_bOwnedStream) { + m_pDataAcc->Release(); + } +} +FX_BOOL CXML_Parser::Init(FX_LPBYTE pBuffer, size_t size) +{ + if (m_pAllocator) { + m_pDataAcc = FX_NewAtAllocator(m_pAllocator)CXML_DataBufAcc(pBuffer, size, m_pAllocator); + } else { + m_pDataAcc = FX_NEW CXML_DataBufAcc(pBuffer, size, NULL); + } + if (!m_pDataAcc) { + return FALSE; + } + return Init(TRUE); +} +FX_BOOL CXML_Parser::Init(IFX_FileRead *pFileRead) +{ + if (m_pAllocator) { + m_pDataAcc = FX_NewAtAllocator(m_pAllocator)CXML_DataStmAcc(pFileRead, m_pAllocator); + } else { + m_pDataAcc = FX_NEW CXML_DataStmAcc(pFileRead, NULL); + } + if (!m_pDataAcc) { + return FALSE; + } + return Init(TRUE); +} +FX_BOOL CXML_Parser::Init(IFX_BufferRead *pBuffer) +{ + if (!pBuffer) { + return FALSE; + } + m_pDataAcc = pBuffer; + return Init(FALSE); +} +FX_BOOL CXML_Parser::Init(FX_BOOL bOwndedStream) +{ + m_bOwnedStream = bOwndedStream; + m_nOffset = 0; + return ReadNextBlock(); +} +FX_BOOL CXML_Parser::ReadNextBlock() +{ + if (!m_pDataAcc->ReadNextBlock()) { + return FALSE; + } + m_pBuffer = m_pDataAcc->GetBlockBuffer(); + m_dwBufferSize = m_pDataAcc->GetBlockSize(); + m_nBufferOffset = m_pDataAcc->GetBlockOffset(); + m_dwIndex = 0; + return m_dwBufferSize > 0; +} +FX_BOOL CXML_Parser::IsEOF() +{ + if (!m_pDataAcc->IsEOF()) { + return FALSE; + } + return m_dwIndex >= m_dwBufferSize; +} +#define FXCRTM_XML_CHARTYPE_Normal 0x00 +#define FXCRTM_XML_CHARTYPE_SpaceChar 0x01 +#define FXCRTM_XML_CHARTYPE_Letter 0x02 +#define FXCRTM_XML_CHARTYPE_Digital 0x04 +#define FXCRTM_XML_CHARTYPE_NameIntro 0x08 +#define FXCRTM_XML_CHARTYPE_NameChar 0x10 +#define FXCRTM_XML_CHARTYPE_HexDigital 0x20 +#define FXCRTM_XML_CHARTYPE_HexLowerLetter 0x40 +#define FXCRTM_XML_CHARTYPE_HexUpperLetter 0x60 +#define FXCRTM_XML_CHARTYPE_HexChar 0x60 +FX_BYTE g_FXCRT_XML_ByteTypes[256] = { + 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, + 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, + 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x10, 0x00, + 0x34, 0x34, 0x34, 0x34, 0x34, 0x34, 0x34, 0x34, 0x34, 0x34, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x7A, 0x7A, 0x7A, 0x7A, 0x7A, 0x7A, 0x1A, 0x1A, 0x1A, 0x1A, 0x1A, 0x1A, 0x1A, 0x1A, 0x1A, + 0x1A, 0x1A, 0x1A, 0x1A, 0x1A, 0x1A, 0x1A, 0x1A, 0x1A, 0x1A, 0x1A, 0x00, 0x00, 0x00, 0x00, 0x18, + 0x00, 0x5A, 0x5A, 0x5A, 0x5A, 0x5A, 0x5A, 0x1A, 0x1A, 0x1A, 0x1A, 0x1A, 0x1A, 0x1A, 0x1A, 0x1A, + 0x1A, 0x1A, 0x1A, 0x1A, 0x1A, 0x1A, 0x1A, 0x1A, 0x1A, 0x1A, 0x1A, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x1A, 0x1A, 0x1A, 0x1A, 0x1A, 0x1A, 0x1A, 0x1A, 0x1A, 0x1A, 0x1A, 0x1A, 0x1A, 0x1A, 0x1A, 0x1A, + 0x1A, 0x1A, 0x1A, 0x1A, 0x1A, 0x1A, 0x1A, 0x1A, 0x1A, 0x1A, 0x1A, 0x1A, 0x1A, 0x1A, 0x1A, 0x1A, + 0x1A, 0x1A, 0x1A, 0x1A, 0x1A, 0x1A, 0x1A, 0x1A, 0x1A, 0x1A, 0x1A, 0x1A, 0x1A, 0x1A, 0x1A, 0x1A, + 0x1A, 0x1A, 0x1A, 0x1A, 0x1A, 0x1A, 0x1A, 0x1A, 0x1A, 0x1A, 0x1A, 0x1A, 0x1A, 0x1A, 0x1A, 0x1A, + 0x1A, 0x1A, 0x1A, 0x1A, 0x1A, 0x1A, 0x1A, 0x1A, 0x1A, 0x1A, 0x1A, 0x1A, 0x1A, 0x1A, 0x1A, 0x1A, + 0x1A, 0x1A, 0x1A, 0x1A, 0x1A, 0x1A, 0x1A, 0x1A, 0x1A, 0x1A, 0x1A, 0x1A, 0x1A, 0x1A, 0x1A, 0x1A, + 0x1A, 0x1A, 0x1A, 0x1A, 0x1A, 0x1A, 0x1A, 0x1A, 0x1A, 0x1A, 0x1A, 0x1A, 0x1A, 0x1A, 0x1A, 0x1A, + 0x1A, 0x1A, 0x1A, 0x1A, 0x1A, 0x1A, 0x1A, 0x1A, 0x1A, 0x1A, 0x1A, 0x1A, 0x1A, 0x1A, 0x01, 0x01, +}; +FX_BOOL g_FXCRT_XML_IsWhiteSpace(FX_BYTE ch) +{ + return (g_FXCRT_XML_ByteTypes[ch] & FXCRTM_XML_CHARTYPE_SpaceChar) != 0; +} +FX_BOOL g_FXCRT_XML_IsLetter(FX_BYTE ch) +{ + return (g_FXCRT_XML_ByteTypes[ch] & FXCRTM_XML_CHARTYPE_Letter) != 0; +} +FX_BOOL g_FXCRT_XML_IsDigital(FX_BYTE ch) +{ + return (g_FXCRT_XML_ByteTypes[ch] & FXCRTM_XML_CHARTYPE_Digital) != 0; +} +FX_BOOL g_FXCRT_XML_IsNameIntro(FX_BYTE ch) +{ + return (g_FXCRT_XML_ByteTypes[ch] & FXCRTM_XML_CHARTYPE_NameIntro) != 0; +} +FX_BOOL g_FXCRT_XML_IsNameChar(FX_BYTE ch) +{ + return (g_FXCRT_XML_ByteTypes[ch] & FXCRTM_XML_CHARTYPE_NameChar) != 0; +} +FX_BOOL g_FXCRT_XML_IsHexChar(FX_BYTE ch) +{ + return (g_FXCRT_XML_ByteTypes[ch] & FXCRTM_XML_CHARTYPE_HexChar) != 0; +} +void CXML_Parser::SkipWhiteSpaces() +{ + m_nOffset = m_nBufferOffset + (FX_FILESIZE)m_dwIndex; + if (IsEOF()) { + return; + } + do { + while (m_dwIndex < m_dwBufferSize && g_FXCRT_XML_IsWhiteSpace(m_pBuffer[m_dwIndex])) { + m_dwIndex ++; + } + m_nOffset = m_nBufferOffset + (FX_FILESIZE)m_dwIndex; + if (m_dwIndex < m_dwBufferSize || IsEOF()) { + break; + } + } while (ReadNextBlock()); +} +void CXML_Parser::GetName(CFX_ByteStringL &space, CFX_ByteStringL &name) +{ + m_nOffset = m_nBufferOffset + (FX_FILESIZE)m_dwIndex; + if (IsEOF()) { + return; + } + CFX_ByteTextBuf buf(m_pAllocator); + FX_BYTE ch; + do { + while (m_dwIndex < m_dwBufferSize) { + ch = m_pBuffer[m_dwIndex]; + if (ch == ':') { + buf.GetByteStringL(space); + buf.Clear(); + } else if (g_FXCRT_XML_IsNameChar(ch)) { + buf.AppendChar(ch); + } else { + break; + } + m_dwIndex ++; + } + m_nOffset = m_nBufferOffset + (FX_FILESIZE)m_dwIndex; + if (m_dwIndex < m_dwBufferSize || IsEOF()) { + break; + } + } while (ReadNextBlock()); + buf.GetByteStringL(name); +} +void CXML_Parser::SkipLiterals(FX_BSTR str) +{ + m_nOffset = m_nBufferOffset + (FX_FILESIZE)m_dwIndex; + if (IsEOF()) { + return; + } + FX_INT32 i = 0, iLen = str.GetLength(); + do { + while (m_dwIndex < m_dwBufferSize) { + if (str.GetAt(i) != m_pBuffer[m_dwIndex ++]) { + i = 0; + } else { + i ++; + if (i == iLen) { + break; + } + } + } + m_nOffset = m_nBufferOffset + (FX_FILESIZE)m_dwIndex; + if (i == iLen) { + return; + } + if (m_dwIndex < m_dwBufferSize || IsEOF()) { + break; + } + } while (ReadNextBlock()); + while (!m_pDataAcc->IsEOF()) { + ReadNextBlock(); + m_nOffset = m_nBufferOffset + (FX_FILESIZE)m_dwBufferSize; + } + m_dwIndex = m_dwBufferSize; +} +FX_DWORD CXML_Parser::GetCharRef() +{ + m_nOffset = m_nBufferOffset + (FX_FILESIZE)m_dwIndex; + if (IsEOF()) { + return 0; + } + FX_BYTE ch; + FX_INT32 iState = 0; + CFX_ByteTextBuf buf(m_pAllocator); + FX_DWORD code = 0; + do { + while (m_dwIndex < m_dwBufferSize) { + ch = m_pBuffer[m_dwIndex]; + switch (iState) { + case 0: + if (ch == '#') { + m_dwIndex ++; + iState = 2; + break; + } + iState = 1; + case 1: + m_dwIndex ++; + if (ch == ';') { + CFX_ByteStringC ref = buf.GetByteString(); + if (ref == FX_BSTRC("gt")) { + code = '>'; + } else if (ref == FX_BSTRC("lt")) { + code = '<'; + } else if (ref == FX_BSTRC("amp")) { + code = '&'; + } else if (ref == FX_BSTRC("apos")) { + code = '\''; + } else if (ref == FX_BSTRC("quot")) { + code = '"'; + } + iState = 10; + break; + } + buf.AppendByte(ch); + break; + case 2: + if (ch == 'x') { + m_dwIndex ++; + iState = 4; + break; + } + iState = 3; + case 3: + m_dwIndex ++; + if (ch == ';') { + iState = 10; + break; + } + if (g_FXCRT_XML_IsDigital(ch)) { + code = code * 10 + ch - '0'; + } + break; + case 4: + m_dwIndex ++; + if (ch == ';') { + iState = 10; + break; + } + FX_BYTE nHex = g_FXCRT_XML_ByteTypes[ch] & FXCRTM_XML_CHARTYPE_HexChar; + if (nHex) { + if (nHex == FXCRTM_XML_CHARTYPE_HexDigital) { + code = (code << 4) + ch - '0'; + } else if (nHex == FXCRTM_XML_CHARTYPE_HexLowerLetter) { + code = (code << 4) + ch - 87; + } else { + code = (code << 4) + ch - 55; + } + } + break; + } + if (iState == 10) { + break; + } + } + m_nOffset = m_nBufferOffset + (FX_FILESIZE)m_dwIndex; + if (iState == 10 || m_dwIndex < m_dwBufferSize || IsEOF()) { + break; + } + } while (ReadNextBlock()); + return code; +} +void CXML_Parser::GetAttrValue(CFX_WideStringL &value) +{ + m_nOffset = m_nBufferOffset + (FX_FILESIZE)m_dwIndex; + if (IsEOF()) { + return; + } + CFX_UTF8Decoder decoder(m_pAllocator); + FX_BYTE mark = 0, ch; + do { + while (m_dwIndex < m_dwBufferSize) { + ch = m_pBuffer[m_dwIndex]; + if (mark == 0) { + if (ch != '\'' && ch != '"') { + return; + } + mark = ch; + m_dwIndex ++; + ch = 0; + continue; + } + m_dwIndex ++; + if (ch == mark) { + break; + } + if (ch == '&') { + decoder.AppendChar(GetCharRef()); + if (IsEOF()) { + decoder.GetResult(value); + return; + } + } else { + decoder.Input(ch); + } + } + m_nOffset = m_nBufferOffset + (FX_FILESIZE)m_dwIndex; + if (ch == mark || m_dwIndex < m_dwBufferSize || IsEOF()) { + break; + } + } while (ReadNextBlock()); + decoder.GetResult(value); +} +void CXML_Parser::GetTagName(CFX_ByteStringL &space, CFX_ByteStringL &name, FX_BOOL &bEndTag, FX_BOOL bStartTag) +{ + m_nOffset = m_nBufferOffset + (FX_FILESIZE)m_dwIndex; + if (IsEOF()) { + return; + } + bEndTag = FALSE; + FX_BYTE ch; + FX_INT32 iState = bStartTag ? 1 : 0; + do { + while (m_dwIndex < m_dwBufferSize) { + ch = m_pBuffer[m_dwIndex]; + switch (iState) { + case 0: + m_dwIndex ++; + if (ch != '<') { + break; + } + iState = 1; + break; + case 1: + if (ch == '?') { + m_dwIndex ++; + SkipLiterals(FX_BSTRC("?>")); + iState = 0; + break; + } else if (ch == '!') { + m_dwIndex ++; + SkipLiterals(FX_BSTRC("-->")); + iState = 0; + break; + } + if (ch == '/') { + m_dwIndex ++; + GetName(space, name); + bEndTag = TRUE; + } else { + GetName(space, name); + bEndTag = FALSE; + } + return; + } + } + m_nOffset = m_nBufferOffset + (FX_FILESIZE)m_dwIndex; + if (m_dwIndex < m_dwBufferSize || IsEOF()) { + break; + } + } while (ReadNextBlock()); +} +CXML_Element* CXML_Parser::ParseElement(CXML_Element* pParent, FX_BOOL bStartTag) +{ + m_nOffset = m_nBufferOffset + (FX_FILESIZE)m_dwIndex; + if (IsEOF()) { + return NULL; + } + CFX_ByteStringL tag_name, tag_space; + FX_BOOL bEndTag; + GetTagName(tag_space, tag_name, bEndTag, bStartTag); + if (tag_name.IsEmpty() || bEndTag) { + tag_space.Empty(m_pAllocator); + return NULL; + } + CXML_Element* pElement; + if (m_pAllocator) { + pElement = FX_NewAtAllocator(m_pAllocator)CXML_Element(m_pAllocator); + } else { + pElement = FX_NEW CXML_Element; + } + if (pElement) { + pElement->m_pParent = pParent; + pElement->SetTag(tag_space, tag_name); + } + tag_space.Empty(m_pAllocator); + tag_name.Empty(m_pAllocator); + if (!pElement) { + return NULL; + } + do { + CFX_ByteStringL attr_space, attr_name; + while (m_dwIndex < m_dwBufferSize) { + SkipWhiteSpaces(); + if (IsEOF()) { + break; + } + if (!g_FXCRT_XML_IsNameIntro(m_pBuffer[m_dwIndex])) { + break; + } + attr_space.Empty(m_pAllocator); + attr_name.Empty(m_pAllocator); + GetName(attr_space, attr_name); + SkipWhiteSpaces(); + if (IsEOF()) { + break; + } + if (m_pBuffer[m_dwIndex] != '=') { + break; + } + m_dwIndex ++; + SkipWhiteSpaces(); + if (IsEOF()) { + break; + } + CFX_WideStringL attr_value; + GetAttrValue(attr_value); + pElement->m_AttrMap.SetAt(attr_space, attr_name, attr_value, m_pAllocator); + attr_value.Empty(m_pAllocator); + } + attr_space.Empty(m_pAllocator); + attr_name.Empty(m_pAllocator); + m_nOffset = m_nBufferOffset + (FX_FILESIZE)m_dwIndex; + if (m_dwIndex < m_dwBufferSize || IsEOF()) { + break; + } + } while (ReadNextBlock()); + SkipWhiteSpaces(); + if (IsEOF()) { + return pElement; + } + FX_BYTE ch = m_pBuffer[m_dwIndex ++]; + if (ch == '/') { + m_dwIndex ++; + m_nOffset = m_nBufferOffset + (FX_FILESIZE)m_dwIndex; + return pElement; + } + if (ch != '>') { + m_nOffset = m_nBufferOffset + (FX_FILESIZE)m_dwIndex; + if (m_pAllocator) { + FX_DeleteAtAllocator(pElement, m_pAllocator, CXML_Element); + } else { + delete pElement; + } + return NULL; + } + SkipWhiteSpaces(); + if (IsEOF()) { + return pElement; + } + CFX_UTF8Decoder decoder(m_pAllocator); + CFX_WideTextBuf content(m_pAllocator); + FX_BOOL bCDATA = FALSE; + FX_INT32 iState = 0; + do { + while (m_dwIndex < m_dwBufferSize) { + ch = m_pBuffer[m_dwIndex ++]; + switch (iState) { + case 0: + if (ch == '<') { + iState = 1; + } else if (ch == '&') { + decoder.ClearStatus(); + decoder.AppendChar(GetCharRef()); + } else { + decoder.Input(ch); + } + break; + case 1: + if (ch == '!') { + iState = 2; + } else if (ch == '?') { + SkipLiterals(FX_BSTRC("?>")); + SkipWhiteSpaces(); + iState = 0; + } else if (ch == '/') { + CFX_ByteStringL space, name; + GetName(space, name); + space.Empty(m_pAllocator); + name.Empty(m_pAllocator); + SkipWhiteSpaces(); + m_dwIndex ++; + iState = 10; + } else { + content << decoder.GetResult(); + CFX_WideStringL dataStr; + content.GetWideStringL(dataStr); + if (!bCDATA && !m_bSaveSpaceChars) { + dataStr.TrimRight((FX_LPCWSTR)L" \t\r\n"); + } + InsertContentSegment(bCDATA, dataStr, pElement); + dataStr.Empty(m_pAllocator); + content.Clear(); + decoder.Clear(); + bCDATA = FALSE; + iState = 0; + m_dwIndex --; + CXML_Element* pSubElement = ParseElement(pElement, TRUE); + if (pSubElement == NULL) { + break; + } + pSubElement->m_pParent = pElement; + pElement->m_Children.Add((FX_LPVOID)CXML_Element::Element); + pElement->m_Children.Add(pSubElement); + SkipWhiteSpaces(); + } + break; + case 2: + if (ch == '[') { + SkipLiterals(FX_BSTRC("]]>")); + } else if (ch == '-') { + m_dwIndex ++; + SkipLiterals(FX_BSTRC("-->")); + } else { + SkipLiterals(FX_BSTRC(">")); + } + decoder.Clear(); + SkipWhiteSpaces(); + iState = 0; + break; + } + if (iState == 10) { + break; + } + } + m_nOffset = m_nBufferOffset + (FX_FILESIZE)m_dwIndex; + if (iState == 10 || m_dwIndex < m_dwBufferSize || IsEOF()) { + break; + } + } while (ReadNextBlock()); + content << decoder.GetResult(); + CFX_WideStringL dataStr; + content.GetWideStringL(dataStr); + if (!m_bSaveSpaceChars) { + dataStr.TrimRight((FX_LPCWSTR)L" \t\r\n"); + } + InsertContentSegment(bCDATA, dataStr, pElement); + dataStr.Empty(m_pAllocator); + content.Clear(); + decoder.Clear(); + bCDATA = FALSE; + return pElement; +} +void CXML_Parser::InsertContentSegment(FX_BOOL bCDATA, FX_WSTR content, CXML_Element* pElement) +{ + if (content.IsEmpty()) { + return; + } + CXML_Content* pContent; + if (m_pAllocator) { + pContent = FX_NewAtAllocator(m_pAllocator)CXML_Content; + } else { + pContent = FX_NEW CXML_Content; + } + if (!pContent) { + return; + } + pContent->Set(bCDATA, content, m_pAllocator); + pElement->m_Children.Add((FX_LPVOID)CXML_Element::Content); + pElement->m_Children.Add(pContent); +} +static CXML_Element* XML_ContinueParse(CXML_Parser &parser, FX_BOOL bSaveSpaceChars, FX_FILESIZE* pParsedSize) +{ + parser.m_bSaveSpaceChars = bSaveSpaceChars; + CXML_Element* pElement = parser.ParseElement(NULL, FALSE); + if (pParsedSize) { + *pParsedSize = parser.m_nOffset; + } + return pElement; +} +CXML_Element* CXML_Element::Parse(const void* pBuffer, size_t size, FX_BOOL bSaveSpaceChars, FX_FILESIZE* pParsedSize, IFX_Allocator* pAllocator) +{ + CXML_Parser parser(pAllocator); + if (!parser.Init((FX_LPBYTE)pBuffer, size)) { + return NULL; + } + return XML_ContinueParse(parser, bSaveSpaceChars, pParsedSize); +} +CXML_Element* CXML_Element::Parse(IFX_FileRead *pFile, FX_BOOL bSaveSpaceChars, FX_FILESIZE* pParsedSize, IFX_Allocator* pAllocator) +{ + CXML_Parser parser(pAllocator); + if (!parser.Init(pFile)) { + return NULL; + } + return XML_ContinueParse(parser, bSaveSpaceChars, pParsedSize); +} +CXML_Element* CXML_Element::Parse(IFX_BufferRead *pBuffer, FX_BOOL bSaveSpaceChars, FX_FILESIZE* pParsedSize, IFX_Allocator* pAllocator) +{ + CXML_Parser parser(pAllocator); + if (!parser.Init(pBuffer)) { + return NULL; + } + return XML_ContinueParse(parser, bSaveSpaceChars, pParsedSize); +} +CXML_Element::CXML_Element(IFX_Allocator* pAllocator) + : m_pParent(NULL) + , m_QSpaceName() + , m_TagName() + , m_AttrMap() + , m_Children(pAllocator) +{ +} +CXML_Element::CXML_Element(FX_BSTR qSpace, FX_BSTR tagName, IFX_Allocator* pAllocator) + : m_pParent(NULL) + , m_QSpaceName() + , m_TagName() + , m_AttrMap() + , m_Children(pAllocator) +{ + m_QSpaceName.Set(qSpace, pAllocator); + m_TagName.Set(tagName, pAllocator); +} +CXML_Element::CXML_Element(FX_BSTR qTagName, IFX_Allocator* pAllocator) + : m_pParent(NULL) + , m_QSpaceName() + , m_TagName() + , m_AttrMap() + , m_Children(pAllocator) +{ + SetTag(qTagName); +} +CXML_Element::~CXML_Element() +{ + Empty(); +} +void CXML_Element::Empty() +{ + IFX_Allocator* pAllocator = m_Children.m_pAllocator; + m_QSpaceName.Empty(pAllocator); + m_TagName.Empty(pAllocator); + m_AttrMap.RemoveAll(pAllocator); + RemoveChildren(); +} +void CXML_Element::RemoveChildren() +{ + IFX_Allocator* pAllocator = m_Children.m_pAllocator; + for (int i = 0; i < m_Children.GetSize(); i += 2) { + ChildType type = (ChildType)(FX_UINTPTR)m_Children.GetAt(i); + if (type == Content) { + CXML_Content* content = (CXML_Content*)m_Children.GetAt(i + 1); + if (pAllocator) { + FX_DeleteAtAllocator(content, pAllocator, CXML_Content); + } else { + delete content; + } + } else if (type == Element) { + CXML_Element* child = (CXML_Element*)m_Children.GetAt(i + 1); + child->RemoveChildren(); + if (pAllocator) { + FX_DeleteAtAllocator(child, pAllocator, CXML_Element); + } else { + delete child; + } + } + } + m_Children.RemoveAll(); +} +CFX_ByteString CXML_Element::GetTagName(FX_BOOL bQualified) const +{ + if (!bQualified || m_QSpaceName.IsEmpty()) { + return m_TagName; + } + CFX_ByteString bsTag = m_QSpaceName; + bsTag += ":"; + bsTag += m_TagName; + return bsTag; +} +void CXML_Element::GetTagName(CFX_ByteStringL &tagName, FX_BOOL bQualified) const +{ + IFX_Allocator* pAllocator = m_Children.m_pAllocator; + if (!bQualified || m_QSpaceName.IsEmpty()) { + tagName.Set(m_TagName, pAllocator); + return; + } + FX_LPSTR str = tagName.AllocBuffer(m_QSpaceName.GetLength() + m_TagName.GetLength() + 2, pAllocator); + if (!str) { + return; + } + FXSYS_memcpy32(str, m_QSpaceName.GetCStr(), m_QSpaceName.GetLength()); + str += m_QSpaceName.GetLength(); + *str = ':'; + str ++; + FXSYS_memcpy32(str, m_TagName.GetCStr(), m_TagName.GetLength()); + str += m_TagName.GetLength(); + *str = '\0'; +} +CFX_ByteString CXML_Element::GetNamespace(FX_BOOL bQualified) const +{ + if (bQualified) { + return m_QSpaceName; + } + return GetNamespaceURI(m_QSpaceName); +} +void CXML_Element::GetNamespace(CFX_ByteStringL &nameSpace, FX_BOOL bQualified) const +{ + IFX_Allocator* pAllocator = m_Children.m_pAllocator; + if (bQualified) { + nameSpace.Set(m_QSpaceName, pAllocator); + return; + } + GetNamespaceURI(m_QSpaceName, nameSpace); +} +CFX_ByteString CXML_Element::GetNamespaceURI(FX_BSTR qName) const +{ + const CFX_WideStringL* pwsSpace; + const CXML_Element *pElement = this; + do { + if (qName.IsEmpty()) { + pwsSpace = pElement->m_AttrMap.Lookup(FX_BSTRC(""), FX_BSTRC("xmlns")); + } else { + pwsSpace = pElement->m_AttrMap.Lookup(FX_BSTRC("xmlns"), qName); + } + if (pwsSpace) { + break; + } + pElement = pElement->GetParent(); + } while(pElement); + return pwsSpace ? FX_UTF8Encode(*pwsSpace) : CFX_ByteString(); +} +void CXML_Element::GetNamespaceURI(FX_BSTR qName, CFX_ByteStringL &uri) const +{ + IFX_Allocator* pAllocator = m_Children.m_pAllocator; + const CFX_WideStringL* pwsSpace; + const CXML_Element *pElement = this; + do { + if (qName.IsEmpty()) { + pwsSpace = pElement->m_AttrMap.Lookup(FX_BSTRC(""), FX_BSTRC("xmlns")); + } else { + pwsSpace = pElement->m_AttrMap.Lookup(FX_BSTRC("xmlns"), qName); + } + if (pwsSpace) { + break; + } + pElement = pElement->GetParent(); + } while(pElement); + if (pwsSpace) { + FX_UTF8Encode(pwsSpace->GetPtr(), pwsSpace->GetLength(), uri, pAllocator); + } +} +void CXML_Element::GetAttrByIndex(int index, CFX_ByteString& space, CFX_ByteString& name, CFX_WideString& value) const +{ + if (index < 0 || index >= m_AttrMap.GetSize()) { + return; + } + CXML_AttrItem& item = m_AttrMap.GetAt(index); + space = item.m_QSpaceName; + name = item.m_AttrName; + value = item.m_Value; +} +void CXML_Element::GetAttrByIndex(int index, CFX_ByteStringL &space, CFX_ByteStringL &name, CFX_WideStringL &value) const +{ + if (index < 0 || index >= m_AttrMap.GetSize()) { + return; + } + IFX_Allocator* pAllocator = m_Children.m_pAllocator; + CXML_AttrItem& item = m_AttrMap.GetAt(index); + space.Set(item.m_QSpaceName, pAllocator); + name.Set(item.m_AttrName, pAllocator); + value.Set(item.m_Value, pAllocator); +} +FX_BOOL CXML_Element::HasAttr(FX_BSTR name) const +{ + CFX_ByteStringC bsSpace, bsName; + FX_XML_SplitQualifiedName(name, bsSpace, bsName); + return m_AttrMap.Lookup(bsSpace, bsName) != NULL; +} +FX_BOOL CXML_Element::GetAttrValue(FX_BSTR name, CFX_WideString& attribute) const +{ + CFX_ByteStringC bsSpace, bsName; + FX_XML_SplitQualifiedName(name, bsSpace, bsName); + const CFX_WideStringL* pValue = m_AttrMap.Lookup(bsSpace, bsName); + if (pValue) { + attribute = CFX_WideString(pValue->GetPtr(), pValue->GetLength()); + return TRUE; + } + return FALSE; +} +const CFX_WideStringL* CXML_Element::GetAttrValuePtr(FX_BSTR name) const +{ + CFX_ByteStringC bsSpace, bsName; + FX_XML_SplitQualifiedName(name, bsSpace, bsName); + return m_AttrMap.Lookup(bsSpace, bsName); +} +FX_BOOL CXML_Element::GetAttrValue(FX_BSTR space, FX_BSTR name, CFX_WideString& attribute) const +{ + const CFX_WideStringL* pValue = m_AttrMap.Lookup(space, name); + if (pValue) { + attribute = CFX_WideString(pValue->GetPtr(), pValue->GetLength()); + return TRUE; + } + return FALSE; +} +const CFX_WideStringL* CXML_Element::GetAttrValuePtr(FX_BSTR space, FX_BSTR name) const +{ + return m_AttrMap.Lookup(space, name); +} +FX_BOOL CXML_Element::GetAttrInteger(FX_BSTR name, int& attribute) const +{ + CFX_ByteStringC bsSpace, bsName; + FX_XML_SplitQualifiedName(name, bsSpace, bsName); + const CFX_WideStringL* pwsValue = m_AttrMap.Lookup(bsSpace, bsName); + if (pwsValue) { + attribute = pwsValue->GetInteger(); + return TRUE; + } + return FALSE; +} +FX_BOOL CXML_Element::GetAttrInteger(FX_BSTR space, FX_BSTR name, int& attribute) const +{ + const CFX_WideStringL* pwsValue = m_AttrMap.Lookup(space, name); + if (pwsValue) { + attribute = pwsValue->GetInteger(); + return TRUE; + } + return FALSE; +} +FX_BOOL CXML_Element::GetAttrFloat(FX_BSTR name, FX_FLOAT& attribute) const +{ + CFX_ByteStringC bsSpace, bsName; + FX_XML_SplitQualifiedName(name, bsSpace, bsName); + return GetAttrFloat(bsSpace, bsName, attribute); +} +FX_BOOL CXML_Element::GetAttrFloat(FX_BSTR space, FX_BSTR name, FX_FLOAT& attribute) const +{ + CFX_WideString value; + const CFX_WideStringL* pValue = m_AttrMap.Lookup(space, name); + if (pValue) { + attribute = pValue->GetFloat(); + return TRUE; + } + return FALSE; +} +FX_DWORD CXML_Element::CountChildren() const +{ + return m_Children.GetSize() / 2; +} +CXML_Element::ChildType CXML_Element::GetChildType(FX_DWORD index) const +{ + index <<= 1; + if (index >= (FX_DWORD)m_Children.GetSize()) { + return Invalid; + } + return (ChildType)(FX_UINTPTR)m_Children.GetAt(index); +} +CFX_WideString CXML_Element::GetContent(FX_DWORD index) const +{ + index <<= 1; + if (index >= (FX_DWORD)m_Children.GetSize() || + (ChildType)(FX_UINTPTR)m_Children.GetAt(index) != Content) { + return CFX_WideString(); + } + CXML_Content* pContent = (CXML_Content*)m_Children.GetAt(index + 1); + if (pContent) { + return pContent->m_Content; + } + return CFX_WideString(); +} +const CFX_WideStringL* CXML_Element::GetContentPtr(FX_DWORD index) const +{ + index <<= 1; + if (index >= (FX_DWORD)m_Children.GetSize() || + (ChildType)(FX_UINTPTR)m_Children.GetAt(index) != Content) { + return NULL; + } + CXML_Content* pContent = (CXML_Content*)m_Children.GetAt(index + 1); + if (pContent) { + return &pContent->m_Content; + } + return NULL; +} +CXML_Element* CXML_Element::GetElement(FX_DWORD index) const +{ + index <<= 1; + if (index >= (FX_DWORD)m_Children.GetSize() || + (ChildType)(FX_UINTPTR)m_Children.GetAt(index) != Element) { + return NULL; + } + return (CXML_Element*)m_Children.GetAt(index + 1); +} +FX_DWORD CXML_Element::CountElements(FX_BSTR space, FX_BSTR tag) const +{ + int count = 0; + for (int i = 0; i < m_Children.GetSize(); i += 2) { + ChildType type = (ChildType)(FX_UINTPTR)m_Children.GetAt(i); + if (type != Element) { + continue; + } + CXML_Element* pKid = (CXML_Element*)m_Children.GetAt(i + 1); + if ((space.IsEmpty() || pKid->m_QSpaceName == space) && pKid->m_TagName == tag) { + count ++; + } + } + return count; +} +CXML_Element* CXML_Element::GetElement(FX_BSTR space, FX_BSTR tag, int index) const +{ + if (index < 0) { + return NULL; + } + for (int i = 0; i < m_Children.GetSize(); i += 2) { + ChildType type = (ChildType)(FX_UINTPTR)m_Children.GetAt(i); + if (type != Element) { + continue; + } + CXML_Element* pKid = (CXML_Element*)m_Children.GetAt(i + 1); + if ((!space.IsEmpty() && pKid->m_QSpaceName != space) || pKid->m_TagName != tag) { + continue; + } + if (index -- == 0) { + return pKid; + } + } + return NULL; +} +FX_DWORD CXML_Element::FindElement(CXML_Element *pChild) const +{ + for (int i = 0; i < m_Children.GetSize(); i += 2) { + if ((ChildType)(FX_UINTPTR)m_Children.GetAt(i) == Element && + (CXML_Element*)m_Children.GetAt(i + 1) == pChild) { + return (FX_DWORD)(i >> 1); + } + } + return (FX_DWORD) - 1; +} +const CFX_WideStringL* CXML_AttrMap::Lookup(FX_BSTR space, FX_BSTR name) const +{ + if (m_pMap == NULL) { + return NULL; + } + for (int i = 0; i < m_pMap->GetSize(); i ++) { + CXML_AttrItem& item = GetAt(i); + if ((space.IsEmpty() || item.m_QSpaceName == space) && item.m_AttrName == name) { + return &item.m_Value; + } + } + return NULL; +} +void CXML_AttrMap::SetAt(FX_BSTR space, FX_BSTR name, FX_WSTR value, IFX_Allocator* pAllocator) +{ + for (int i = 0; i < GetSize(); i ++) { + CXML_AttrItem& item = GetAt(i); + if ((space.IsEmpty() || item.m_QSpaceName == space) && item.m_AttrName == name) { + item.m_Value.Set(value, pAllocator); + return; + } + } + if (!m_pMap) { + if (pAllocator) { + m_pMap = FX_NewAtAllocator(pAllocator)CFX_ObjectArray<CXML_AttrItem>(pAllocator); + } else { + m_pMap = FX_NEW CFX_ObjectArray<CXML_AttrItem>; + } + } + if (!m_pMap) { + return; + } + CXML_AttrItem* pItem = (CXML_AttrItem*)m_pMap->AddSpace(); + if (!pItem) { + return; + } + pItem->m_QSpaceName.Set(space, pAllocator); + pItem->m_AttrName.Set(name, pAllocator); + pItem->m_Value.Set(value, pAllocator); +} +void CXML_AttrMap::RemoveAt(FX_BSTR space, FX_BSTR name, IFX_Allocator* pAllocator) +{ + if (m_pMap == NULL) { + return; + } + for (int i = 0; i < m_pMap->GetSize(); i ++) { + CXML_AttrItem& item = GetAt(i); + if ((space.IsEmpty() || item.m_QSpaceName == space) && item.m_AttrName == name) { + item.Empty(pAllocator); + m_pMap->RemoveAt(i); + return; + } + } +} +int CXML_AttrMap::GetSize() const +{ + return m_pMap == NULL ? 0 : m_pMap->GetSize(); +} +CXML_AttrItem& CXML_AttrMap::GetAt(int index) const +{ + ASSERT(m_pMap != NULL); + return (*m_pMap)[index]; +} +void CXML_AttrMap::RemoveAll(IFX_Allocator* pAllocator) +{ + if (!m_pMap) { + return; + } + for (int i = 0; i < m_pMap->GetSize(); i ++) { + CXML_AttrItem& item = (*m_pMap)[i]; + item.Empty(pAllocator); + } + m_pMap->RemoveAll(); + if (pAllocator) { + FX_DeleteAtAllocator(m_pMap, pAllocator, CFX_ObjectArray<CXML_AttrItem>); + } else { + delete m_pMap; + } + m_pMap = NULL; +} |