| Index: xfa/src/fgas/src/xml/fx_sax_imp.cpp
|
| diff --git a/xfa/src/fgas/src/xml/fx_sax_imp.cpp b/xfa/src/fgas/src/xml/fx_sax_imp.cpp
|
| index 6b3cc778ab0af7842888a1b850b0a95c117bd670..bb1602ca7264b11d5f0dbeb1e2729ed0a719f70c 100644
|
| --- a/xfa/src/fgas/src/xml/fx_sax_imp.cpp
|
| +++ b/xfa/src/fgas/src/xml/fx_sax_imp.cpp
|
| @@ -1,689 +1,689 @@
|
| -// 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 <algorithm>
|
| -
|
| -#include "xfa/src/fgas/src/fgas_base.h"
|
| -#include "fx_sax_imp.h"
|
| -
|
| -namespace {
|
| -
|
| -const FX_DWORD kSaxFileBufSize = 32768;
|
| -
|
| -} // namespace
|
| -
|
| -IFX_SAXReader* FX_SAXReader_Create() {
|
| - return new CFX_SAXReader;
|
| -}
|
| -CFX_SAXFile::CFX_SAXFile()
|
| - : m_pFile(NULL),
|
| - m_dwStart(0),
|
| - m_dwEnd(0),
|
| - m_dwCur(0),
|
| - m_pBuf(NULL),
|
| - m_dwBufSize(0),
|
| - m_dwBufIndex(0) {}
|
| -FX_BOOL CFX_SAXFile::StartFile(IFX_FileRead* pFile,
|
| - FX_DWORD dwStart,
|
| - FX_DWORD dwLen) {
|
| - FXSYS_assert(m_pFile == NULL && pFile != NULL);
|
| - FX_DWORD dwSize = pFile->GetSize();
|
| - if (dwStart >= dwSize) {
|
| - return FALSE;
|
| - }
|
| - if (dwLen == -1 || dwStart + dwLen > dwSize) {
|
| - dwLen = dwSize - dwStart;
|
| - }
|
| - if (dwLen == 0) {
|
| - return FALSE;
|
| - }
|
| - m_dwBufSize = std::min(dwLen, kSaxFileBufSize);
|
| - m_pBuf = FX_Alloc(uint8_t, m_dwBufSize);
|
| - if (!pFile->ReadBlock(m_pBuf, dwStart, m_dwBufSize)) {
|
| - return FALSE;
|
| - }
|
| - m_dwStart = dwStart;
|
| - m_dwEnd = dwStart + dwLen;
|
| - m_dwCur = dwStart;
|
| - m_pFile = pFile;
|
| - m_dwBufIndex = 0;
|
| - return TRUE;
|
| -}
|
| -FX_BOOL CFX_SAXFile::ReadNextBlock() {
|
| - FXSYS_assert(m_pFile != NULL);
|
| - FX_DWORD dwSize = m_dwEnd - m_dwCur;
|
| - if (dwSize == 0) {
|
| - return FALSE;
|
| - }
|
| - m_dwBufSize = std::min(dwSize, kSaxFileBufSize);
|
| - if (!m_pFile->ReadBlock(m_pBuf, m_dwCur, m_dwBufSize)) {
|
| - return FALSE;
|
| - }
|
| - m_dwBufIndex = 0;
|
| - return TRUE;
|
| -}
|
| -void CFX_SAXFile::Reset() {
|
| - if (m_pBuf) {
|
| - FX_Free(m_pBuf);
|
| - m_pBuf = NULL;
|
| - }
|
| - m_pFile = NULL;
|
| -}
|
| -CFX_SAXReader::CFX_SAXReader()
|
| - : m_File(),
|
| - m_pHandler(nullptr),
|
| - m_iState(-1),
|
| - m_pRoot(nullptr),
|
| - m_pCurItem(nullptr),
|
| - m_dwItemID(0),
|
| - m_iDataSize(256),
|
| - m_iNameSize(256),
|
| - m_dwParseMode(0),
|
| - m_pCommentContext(nullptr) {
|
| - m_pszData = FX_Alloc(uint8_t, m_iDataSize);
|
| - m_pszName = FX_Alloc(uint8_t, m_iNameSize);
|
| -}
|
| -CFX_SAXReader::~CFX_SAXReader() {
|
| - Reset();
|
| - if (m_pszData) {
|
| - FX_Free(m_pszData);
|
| - m_pszData = NULL;
|
| - }
|
| - if (m_pszName) {
|
| - FX_Free(m_pszName);
|
| - m_pszName = NULL;
|
| - }
|
| -}
|
| -void CFX_SAXReader::Reset() {
|
| - m_File.Reset();
|
| - CFX_SAXItem* pItem = m_pRoot;
|
| - while (pItem) {
|
| - CFX_SAXItem* pNext = pItem->m_pNext;
|
| - delete pItem;
|
| - pItem = pNext;
|
| - }
|
| - m_pRoot = NULL;
|
| - m_pCurItem = NULL;
|
| - m_dwItemID = 0;
|
| - m_SkipStack.RemoveAll();
|
| - m_SkipChar = 0;
|
| - m_iDataLength = 0;
|
| - m_iEntityStart = -1;
|
| - m_iNameLength = 0;
|
| - m_iDataPos = 0;
|
| - if (m_pCommentContext) {
|
| - delete m_pCommentContext;
|
| - m_pCommentContext = NULL;
|
| - }
|
| -}
|
| -inline void CFX_SAXReader::Push() {
|
| - CFX_SAXItem* pNew = new CFX_SAXItem;
|
| - pNew->m_dwID = ++m_dwItemID;
|
| - pNew->m_bSkip = m_pCurItem->m_bSkip;
|
| - pNew->m_pPrev = m_pCurItem;
|
| - m_pCurItem->m_pNext = pNew;
|
| - m_pCurItem = pNew;
|
| -}
|
| -inline void CFX_SAXReader::Pop() {
|
| - if (!m_pCurItem) {
|
| - return;
|
| - }
|
| - CFX_SAXItem* pPrev = m_pCurItem->m_pPrev;
|
| - pPrev->m_pNext = NULL;
|
| - delete m_pCurItem;
|
| - m_pCurItem = pPrev;
|
| -}
|
| -inline void CFX_SAXReader::AppendData(uint8_t ch) {
|
| - ReallocDataBuffer();
|
| - m_pszData[m_iDataPos++] = ch;
|
| -}
|
| -inline void CFX_SAXReader::AppendName(uint8_t ch) {
|
| - ReallocNameBuffer();
|
| - m_pszName[m_iDataPos++] = ch;
|
| -}
|
| -void CFX_SAXReader::ReallocDataBuffer() {
|
| - if (m_iDataPos < m_iDataSize) {
|
| - return;
|
| - }
|
| - if (m_iDataSize <= 1024 * 1024) {
|
| - m_iDataSize *= 2;
|
| - } else {
|
| - m_iDataSize += 1024 * 1024;
|
| - }
|
| - m_pszData = (uint8_t*)FX_Realloc(uint8_t, m_pszData, m_iDataSize);
|
| -}
|
| -void CFX_SAXReader::ReallocNameBuffer() {
|
| - if (m_iDataPos < m_iNameSize) {
|
| - return;
|
| - }
|
| - if (m_iNameSize <= 1024 * 1024) {
|
| - m_iNameSize *= 2;
|
| - } else {
|
| - m_iNameSize += 1024 * 1024;
|
| - }
|
| - m_pszName = (uint8_t*)FX_Realloc(uint8_t, m_pszName, m_iNameSize);
|
| -}
|
| -inline FX_BOOL CFX_SAXReader::SkipSpace(uint8_t ch) {
|
| - return (m_dwParseMode & FX_SAXPARSEMODE_NotSkipSpace) == 0 && ch < 0x21;
|
| -}
|
| -int32_t CFX_SAXReader::StartParse(IFX_FileRead* pFile,
|
| - FX_DWORD dwStart,
|
| - FX_DWORD dwLen,
|
| - FX_DWORD dwParseMode) {
|
| - m_iState = -1;
|
| - Reset();
|
| - if (!m_File.StartFile(pFile, dwStart, dwLen)) {
|
| - return -1;
|
| - }
|
| - m_iState = 0;
|
| - m_eMode = FX_SAXMODE_Text;
|
| - m_ePrevMode = FX_SAXMODE_Text;
|
| - m_bCharData = FALSE;
|
| - m_dwDataOffset = 0;
|
| - m_pRoot = m_pCurItem = new CFX_SAXItem;
|
| - m_pCurItem->m_dwID = ++m_dwItemID;
|
| - m_dwParseMode = dwParseMode;
|
| - return 0;
|
| -}
|
| -typedef void (CFX_SAXReader::*FX_SAXReader_LPFParse)();
|
| -static const FX_SAXReader_LPFParse g_FX_SAXReader_LPFParse[FX_SAXMODE_MAX] = {
|
| - &CFX_SAXReader::ParseText,
|
| - &CFX_SAXReader::ParseNodeStart,
|
| - &CFX_SAXReader::ParseDeclOrComment,
|
| - &CFX_SAXReader::ParseDeclNode,
|
| - &CFX_SAXReader::ParseComment,
|
| - &CFX_SAXReader::ParseCommentContent,
|
| - &CFX_SAXReader::ParseTagName,
|
| - &CFX_SAXReader::ParseTagAttributeName,
|
| - &CFX_SAXReader::ParseTagAttributeEqual,
|
| - &CFX_SAXReader::ParseTagAttributeValue,
|
| - &CFX_SAXReader::ParseMaybeClose,
|
| - &CFX_SAXReader::ParseTagClose,
|
| - &CFX_SAXReader::ParseTagEnd,
|
| - &CFX_SAXReader::ParseTargetData,
|
| -};
|
| -int32_t CFX_SAXReader::ContinueParse(IFX_Pause* pPause) {
|
| - if (m_iState < 0 || m_iState > 99) {
|
| - return m_iState;
|
| - }
|
| - while (m_File.m_dwCur < m_File.m_dwEnd) {
|
| - FX_DWORD& index = m_File.m_dwBufIndex;
|
| - FX_DWORD size = m_File.m_dwBufSize;
|
| - const uint8_t* pBuf = m_File.m_pBuf;
|
| - while (index < size) {
|
| - m_CurByte = pBuf[index];
|
| - (this->*g_FX_SAXReader_LPFParse[m_eMode])();
|
| - index++;
|
| - }
|
| - m_File.m_dwCur += index;
|
| - m_iState = (m_File.m_dwCur - m_File.m_dwStart) * 100 /
|
| - (m_File.m_dwEnd - m_File.m_dwStart);
|
| - if (m_File.m_dwCur >= m_File.m_dwEnd) {
|
| - break;
|
| - }
|
| - if (!m_File.ReadNextBlock()) {
|
| - m_iState = -2;
|
| - break;
|
| - }
|
| - m_dwDataOffset = 0;
|
| - if (pPause && pPause->NeedToPauseNow()) {
|
| - break;
|
| - }
|
| - }
|
| - return m_iState;
|
| -}
|
| -void CFX_SAXReader::ParseChar(uint8_t ch) {
|
| - ReallocDataBuffer();
|
| - m_pszData[m_iDataPos] = ch;
|
| - if (m_iEntityStart > -1 && ch == ';') {
|
| - int32_t iSaveEntityStart = m_iEntityStart;
|
| - CFX_ByteString csEntity(m_pszData + m_iEntityStart + 1,
|
| - m_iDataPos - m_iEntityStart - 1);
|
| - int32_t iLen = csEntity.GetLength();
|
| - if (iLen > 0) {
|
| - if (csEntity[0] == '#') {
|
| - if ((m_dwParseMode & FX_SAXPARSEMODE_NotConvert_sharp) == 0) {
|
| - ch = 0;
|
| - uint8_t w;
|
| - if (iLen > 1 && csEntity[1] == 'x') {
|
| - for (int32_t i = 2; i < iLen; i++) {
|
| - w = csEntity[i];
|
| - if (w >= '0' && w <= '9') {
|
| - ch = (ch << 4) + w - '0';
|
| - } else if (w >= 'A' && w <= 'F') {
|
| - ch = (ch << 4) + w - 55;
|
| - } else if (w >= 'a' && w <= 'f') {
|
| - ch = (ch << 4) + w - 87;
|
| - } else {
|
| - break;
|
| - }
|
| - }
|
| - } else {
|
| - for (int32_t i = 1; i < iLen; i++) {
|
| - w = csEntity[i];
|
| - if (w < '0' || w > '9') {
|
| - break;
|
| - }
|
| - ch = ch * 10 + w - '0';
|
| - }
|
| - }
|
| - if (ch != 0) {
|
| - m_pszData[m_iEntityStart++] = ch;
|
| - }
|
| - }
|
| - } else {
|
| - if (csEntity.Compare("amp") == 0) {
|
| - if ((m_dwParseMode & FX_SAXPARSEMODE_NotConvert_amp) == 0) {
|
| - m_pszData[m_iEntityStart++] = '&';
|
| - }
|
| - } else if (csEntity.Compare("lt") == 0) {
|
| - if ((m_dwParseMode & FX_SAXPARSEMODE_NotConvert_lt) == 0) {
|
| - m_pszData[m_iEntityStart++] = '<';
|
| - }
|
| - } else if (csEntity.Compare("gt") == 0) {
|
| - if ((m_dwParseMode & FX_SAXPARSEMODE_NotConvert_gt) == 0) {
|
| - m_pszData[m_iEntityStart++] = '>';
|
| - }
|
| - } else if (csEntity.Compare("apos") == 0) {
|
| - if ((m_dwParseMode & FX_SAXPARSEMODE_NotConvert_apos) == 0) {
|
| - m_pszData[m_iEntityStart++] = '\'';
|
| - }
|
| - } else if (csEntity.Compare("quot") == 0) {
|
| - if ((m_dwParseMode & FX_SAXPARSEMODE_NotConvert_quot) == 0) {
|
| - m_pszData[m_iEntityStart++] = '\"';
|
| - }
|
| - }
|
| - }
|
| - }
|
| - if (iSaveEntityStart != m_iEntityStart) {
|
| - m_iDataPos = m_iEntityStart;
|
| - m_iEntityStart = -1;
|
| - } else {
|
| - m_iDataPos++;
|
| - m_iEntityStart = -1;
|
| - }
|
| - } else {
|
| - if (m_iEntityStart < 0 && ch == '&') {
|
| - m_iEntityStart = m_iDataPos;
|
| - }
|
| - m_iDataPos++;
|
| - }
|
| -}
|
| -void CFX_SAXReader::ParseText() {
|
| - if (m_CurByte == '<') {
|
| - if (m_iDataPos > 0) {
|
| - m_iDataLength = m_iDataPos;
|
| - m_iDataPos = 0;
|
| - if (m_pHandler) {
|
| - NotifyData();
|
| - }
|
| - }
|
| - Push();
|
| - m_dwNodePos = m_File.m_dwCur + m_File.m_dwBufIndex;
|
| - m_eMode = FX_SAXMODE_NodeStart;
|
| - return;
|
| - }
|
| - if (m_iDataPos < 1 && SkipSpace(m_CurByte)) {
|
| - return;
|
| - }
|
| - ParseChar(m_CurByte);
|
| -}
|
| -void CFX_SAXReader::ParseNodeStart() {
|
| - if (m_CurByte == '?') {
|
| - m_pCurItem->m_eNode = FX_SAXNODE_Instruction;
|
| - m_eMode = FX_SAXMODE_TagName;
|
| - return;
|
| - }
|
| - if (m_CurByte == '!') {
|
| - m_eMode = FX_SAXMODE_DeclOrComment;
|
| - return;
|
| - }
|
| - if (m_CurByte == '/') {
|
| - m_eMode = FX_SAXMODE_TagEnd;
|
| - return;
|
| - }
|
| - if (m_CurByte == '>') {
|
| - Pop();
|
| - m_eMode = FX_SAXMODE_Text;
|
| - return;
|
| - }
|
| - if (m_CurByte > 0x20) {
|
| - m_dwDataOffset = m_File.m_dwBufIndex;
|
| - m_pCurItem->m_eNode = FX_SAXNODE_Tag;
|
| - m_eMode = FX_SAXMODE_TagName;
|
| - AppendData(m_CurByte);
|
| - }
|
| -}
|
| -void CFX_SAXReader::ParseDeclOrComment() {
|
| - if (m_CurByte == '-') {
|
| - m_eMode = FX_SAXMODE_Comment;
|
| - m_pCurItem->m_eNode = FX_SAXNODE_Comment;
|
| - if (m_pCommentContext == NULL) {
|
| - m_pCommentContext = new CFX_SAXCommentContext;
|
| - }
|
| - m_pCommentContext->m_iHeaderCount = 1;
|
| - m_pCommentContext->m_iTailCount = 0;
|
| - } else {
|
| - m_eMode = FX_SAXMODE_DeclNode;
|
| - m_dwDataOffset = m_File.m_dwBufIndex;
|
| - m_SkipChar = '>';
|
| - m_SkipStack.Add('>');
|
| - SkipNode();
|
| - }
|
| -}
|
| -void CFX_SAXReader::ParseComment() {
|
| - m_pCommentContext->m_iHeaderCount = 2;
|
| - m_dwNodePos = m_File.m_dwCur + m_File.m_dwBufIndex;
|
| - m_eMode = FX_SAXMODE_CommentContent;
|
| -}
|
| -void CFX_SAXReader::ParseCommentContent() {
|
| - if (m_CurByte == '-') {
|
| - m_pCommentContext->m_iTailCount++;
|
| - } else if (m_CurByte == '>' && m_pCommentContext->m_iTailCount == 2) {
|
| - m_iDataLength = m_iDataPos;
|
| - m_iDataPos = 0;
|
| - if (m_pHandler) {
|
| - NotifyTargetData();
|
| - }
|
| - Pop();
|
| - m_eMode = FX_SAXMODE_Text;
|
| - } else {
|
| - while (m_pCommentContext->m_iTailCount > 0) {
|
| - AppendData('-');
|
| - m_pCommentContext->m_iTailCount--;
|
| - }
|
| - AppendData(m_CurByte);
|
| - }
|
| -}
|
| -void CFX_SAXReader::ParseDeclNode() {
|
| - SkipNode();
|
| -}
|
| -void CFX_SAXReader::ParseTagName() {
|
| - if (m_CurByte < 0x21 || m_CurByte == '/' || m_CurByte == '>' ||
|
| - m_CurByte == '?') {
|
| - m_iDataLength = m_iDataPos;
|
| - m_iDataPos = 0;
|
| - if (m_pHandler) {
|
| - NotifyEnter();
|
| - }
|
| - if (m_CurByte < 0x21) {
|
| - m_eMode = FX_SAXMODE_TagAttributeName;
|
| - } else if (m_CurByte == '/' || m_CurByte == '?') {
|
| - m_ePrevMode = m_eMode;
|
| - m_eMode = FX_SAXMODE_TagMaybeClose;
|
| - } else {
|
| - if (m_pHandler) {
|
| - NotifyBreak();
|
| - }
|
| - m_eMode = FX_SAXMODE_Text;
|
| - }
|
| - } else {
|
| - AppendData(m_CurByte);
|
| - }
|
| -}
|
| -void CFX_SAXReader::ParseTagAttributeName() {
|
| - if (m_CurByte < 0x21 || m_CurByte == '=') {
|
| - if (m_iDataPos < 1 && m_CurByte < 0x21) {
|
| - return;
|
| - }
|
| - m_iNameLength = m_iDataPos;
|
| - m_iDataPos = 0;
|
| - m_SkipChar = 0;
|
| - m_eMode = m_CurByte == '=' ? FX_SAXMODE_TagAttributeValue
|
| - : FX_SAXMODE_TagAttributeEqual;
|
| - return;
|
| - }
|
| - if (m_CurByte == '/' || m_CurByte == '>' || m_CurByte == '?') {
|
| - if (m_CurByte == '/' || m_CurByte == '?') {
|
| - m_ePrevMode = m_eMode;
|
| - m_eMode = FX_SAXMODE_TagMaybeClose;
|
| - } else {
|
| - if (m_pHandler) {
|
| - NotifyBreak();
|
| - }
|
| - m_eMode = FX_SAXMODE_Text;
|
| - }
|
| - return;
|
| - }
|
| - if (m_iDataPos < 1) {
|
| - m_dwDataOffset = m_File.m_dwBufIndex;
|
| - }
|
| - AppendName(m_CurByte);
|
| -}
|
| -void CFX_SAXReader::ParseTagAttributeEqual() {
|
| - if (m_CurByte == '=') {
|
| - m_SkipChar = 0;
|
| - m_eMode = FX_SAXMODE_TagAttributeValue;
|
| - return;
|
| - } else if (m_pCurItem->m_eNode == FX_SAXNODE_Instruction) {
|
| - m_iDataPos = m_iNameLength;
|
| - AppendName(0x20);
|
| - m_eMode = FX_SAXMODE_TargetData;
|
| - ParseTargetData();
|
| - }
|
| -}
|
| -void CFX_SAXReader::ParseTagAttributeValue() {
|
| - if (m_SkipChar) {
|
| - if (m_SkipChar == m_CurByte) {
|
| - {
|
| - m_iDataLength = m_iDataPos;
|
| - m_iDataPos = 0;
|
| - if (m_pHandler) {
|
| - NotifyAttribute();
|
| - }
|
| - }
|
| - m_SkipChar = 0;
|
| - m_eMode = FX_SAXMODE_TagAttributeName;
|
| - return;
|
| - }
|
| - ParseChar(m_CurByte);
|
| - return;
|
| - }
|
| - if (m_CurByte < 0x21) {
|
| - return;
|
| - }
|
| - if (m_iDataPos < 1) {
|
| - if (m_CurByte == '\'' || m_CurByte == '\"') {
|
| - m_SkipChar = m_CurByte;
|
| - }
|
| - }
|
| -}
|
| -void CFX_SAXReader::ParseMaybeClose() {
|
| - if (m_CurByte == '>') {
|
| - if (m_pCurItem->m_eNode == FX_SAXNODE_Instruction) {
|
| - m_iNameLength = m_iDataPos;
|
| - m_iDataPos = 0;
|
| - if (m_pHandler) {
|
| - NotifyTargetData();
|
| - }
|
| - }
|
| - ParseTagClose();
|
| - m_eMode = FX_SAXMODE_Text;
|
| - } else if (m_ePrevMode == FX_SAXMODE_TagName) {
|
| - AppendData('/');
|
| - m_eMode = FX_SAXMODE_TagName;
|
| - m_ePrevMode = FX_SAXMODE_Text;
|
| - ParseTagName();
|
| - } else if (m_ePrevMode == FX_SAXMODE_TagAttributeName) {
|
| - AppendName('/');
|
| - m_eMode = FX_SAXMODE_TagAttributeName;
|
| - m_ePrevMode = FX_SAXMODE_Text;
|
| - ParseTagAttributeName();
|
| - } else if (m_ePrevMode == FX_SAXMODE_TargetData) {
|
| - AppendName('?');
|
| - m_eMode = FX_SAXMODE_TargetData;
|
| - m_ePrevMode = FX_SAXMODE_Text;
|
| - ParseTargetData();
|
| - }
|
| -}
|
| -void CFX_SAXReader::ParseTagClose() {
|
| - m_dwNodePos = m_File.m_dwCur + m_File.m_dwBufIndex;
|
| - if (m_pHandler) {
|
| - NotifyClose();
|
| - }
|
| - Pop();
|
| -}
|
| -void CFX_SAXReader::ParseTagEnd() {
|
| - if (m_CurByte < 0x21) {
|
| - return;
|
| - }
|
| - if (m_CurByte == '>') {
|
| - Pop();
|
| - m_dwNodePos = m_File.m_dwCur + m_File.m_dwBufIndex;
|
| - m_iDataLength = m_iDataPos;
|
| - m_iDataPos = 0;
|
| - if (m_pHandler) {
|
| - NotifyEnd();
|
| - }
|
| - Pop();
|
| - m_eMode = FX_SAXMODE_Text;
|
| - } else {
|
| - ParseChar(m_CurByte);
|
| - }
|
| -}
|
| -void CFX_SAXReader::ParseTargetData() {
|
| - if (m_CurByte == '?') {
|
| - m_ePrevMode = m_eMode;
|
| - m_eMode = FX_SAXMODE_TagMaybeClose;
|
| - } else {
|
| - AppendName(m_CurByte);
|
| - }
|
| -}
|
| -void CFX_SAXReader::SkipNode() {
|
| - int32_t iLen = m_SkipStack.GetSize();
|
| - if (m_SkipChar == '\'' || m_SkipChar == '\"') {
|
| - if (m_CurByte != m_SkipChar) {
|
| - return;
|
| - }
|
| - iLen--;
|
| - FXSYS_assert(iLen > -1);
|
| - m_SkipStack.RemoveAt(iLen, 1);
|
| - m_SkipChar = iLen ? m_SkipStack[iLen - 1] : 0;
|
| - return;
|
| - }
|
| - switch (m_CurByte) {
|
| - case '<':
|
| - m_SkipChar = '>';
|
| - m_SkipStack.Add('>');
|
| - break;
|
| - case '[':
|
| - m_SkipChar = ']';
|
| - m_SkipStack.Add(']');
|
| - break;
|
| - case '(':
|
| - m_SkipChar = ')';
|
| - m_SkipStack.Add(')');
|
| - break;
|
| - case '\'':
|
| - m_SkipChar = '\'';
|
| - m_SkipStack.Add('\'');
|
| - break;
|
| - case '\"':
|
| - m_SkipChar = '\"';
|
| - m_SkipStack.Add('\"');
|
| - break;
|
| - default:
|
| - if (m_CurByte == m_SkipChar) {
|
| - iLen--;
|
| - m_SkipStack.RemoveAt(iLen, 1);
|
| - m_SkipChar = iLen ? m_SkipStack[iLen - 1] : 0;
|
| - if (iLen == 0 && m_CurByte == '>') {
|
| - m_iDataLength = m_iDataPos;
|
| - m_iDataPos = 0;
|
| - if (m_iDataLength >= 9 &&
|
| - FXSYS_memcmp(m_pszData, "[CDATA[", 7 * sizeof(uint8_t)) == 0 &&
|
| - FXSYS_memcmp(m_pszData + m_iDataLength - 2, "]]",
|
| - 2 * sizeof(uint8_t)) == 0) {
|
| - Pop();
|
| - m_iDataLength -= 9;
|
| - m_dwDataOffset += 7;
|
| - FXSYS_memmove(m_pszData, m_pszData + 7,
|
| - m_iDataLength * sizeof(uint8_t));
|
| - m_bCharData = TRUE;
|
| - if (m_pHandler) {
|
| - NotifyData();
|
| - }
|
| - m_bCharData = FALSE;
|
| - } else {
|
| - Pop();
|
| - }
|
| - m_eMode = FX_SAXMODE_Text;
|
| - }
|
| - }
|
| - break;
|
| - }
|
| - if (iLen > 0) {
|
| - ParseChar(m_CurByte);
|
| - }
|
| -}
|
| -void CFX_SAXReader::NotifyData() {
|
| - FXSYS_assert(m_pHandler != NULL);
|
| - if (m_pCurItem->m_eNode == FX_SAXNODE_Tag)
|
| - m_pHandler->OnTagData(m_pCurItem->m_pNode,
|
| - m_bCharData ? FX_SAXNODE_CharData : FX_SAXNODE_Text,
|
| - CFX_ByteStringC(m_pszData, m_iDataLength),
|
| - m_File.m_dwCur + m_dwDataOffset);
|
| -}
|
| -void CFX_SAXReader::NotifyEnter() {
|
| - FXSYS_assert(m_pHandler != NULL);
|
| - if (m_pCurItem->m_eNode == FX_SAXNODE_Tag ||
|
| - m_pCurItem->m_eNode == FX_SAXNODE_Instruction) {
|
| - m_pCurItem->m_pNode =
|
| - m_pHandler->OnTagEnter(CFX_ByteStringC(m_pszData, m_iDataLength),
|
| - m_pCurItem->m_eNode, m_dwNodePos);
|
| - }
|
| -}
|
| -void CFX_SAXReader::NotifyAttribute() {
|
| - FXSYS_assert(m_pHandler != NULL);
|
| - if (m_pCurItem->m_eNode == FX_SAXNODE_Tag ||
|
| - m_pCurItem->m_eNode == FX_SAXNODE_Instruction) {
|
| - m_pHandler->OnTagAttribute(m_pCurItem->m_pNode,
|
| - CFX_ByteStringC(m_pszName, m_iNameLength),
|
| - CFX_ByteStringC(m_pszData, m_iDataLength));
|
| - }
|
| -}
|
| -void CFX_SAXReader::NotifyBreak() {
|
| - FXSYS_assert(m_pHandler != NULL);
|
| - if (m_pCurItem->m_eNode == FX_SAXNODE_Tag) {
|
| - m_pHandler->OnTagBreak(m_pCurItem->m_pNode);
|
| - }
|
| -}
|
| -void CFX_SAXReader::NotifyClose() {
|
| - FXSYS_assert(m_pHandler != NULL);
|
| - if (m_pCurItem->m_eNode == FX_SAXNODE_Tag ||
|
| - m_pCurItem->m_eNode == FX_SAXNODE_Instruction) {
|
| - m_pHandler->OnTagClose(m_pCurItem->m_pNode, m_dwNodePos);
|
| - }
|
| -}
|
| -void CFX_SAXReader::NotifyEnd() {
|
| - FXSYS_assert(m_pHandler != NULL);
|
| - if (m_pCurItem->m_eNode == FX_SAXNODE_Tag) {
|
| - m_pHandler->OnTagEnd(m_pCurItem->m_pNode,
|
| - CFX_ByteStringC(m_pszData, m_iDataLength),
|
| - m_dwNodePos);
|
| - }
|
| -}
|
| -void CFX_SAXReader::NotifyTargetData() {
|
| - FXSYS_assert(m_pHandler != NULL);
|
| - if (m_pCurItem->m_eNode == FX_SAXNODE_Instruction) {
|
| - m_pHandler->OnTargetData(m_pCurItem->m_pNode, m_pCurItem->m_eNode,
|
| - CFX_ByteStringC(m_pszName, m_iNameLength),
|
| - m_dwNodePos);
|
| - } else if (m_pCurItem->m_eNode == FX_SAXNODE_Comment) {
|
| - m_pHandler->OnTargetData(m_pCurItem->m_pNode, m_pCurItem->m_eNode,
|
| - CFX_ByteStringC(m_pszData, m_iDataLength),
|
| - m_dwNodePos);
|
| - }
|
| -}
|
| -void CFX_SAXReader::SkipCurrentNode() {
|
| - if (!m_pCurItem) {
|
| - return;
|
| - }
|
| - m_pCurItem->m_bSkip = TRUE;
|
| -}
|
| -void CFX_SAXReader::SetHandler(IFX_SAXReaderHandler* pHandler) {
|
| - m_pHandler = pHandler;
|
| -}
|
| +// 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 <algorithm>
|
| +
|
| +#include "xfa/src/fgas/src/fgas_base.h"
|
| +#include "fx_sax_imp.h"
|
| +
|
| +namespace {
|
| +
|
| +const FX_DWORD kSaxFileBufSize = 32768;
|
| +
|
| +} // namespace
|
| +
|
| +IFX_SAXReader* FX_SAXReader_Create() {
|
| + return new CFX_SAXReader;
|
| +}
|
| +CFX_SAXFile::CFX_SAXFile()
|
| + : m_pFile(NULL),
|
| + m_dwStart(0),
|
| + m_dwEnd(0),
|
| + m_dwCur(0),
|
| + m_pBuf(NULL),
|
| + m_dwBufSize(0),
|
| + m_dwBufIndex(0) {}
|
| +FX_BOOL CFX_SAXFile::StartFile(IFX_FileRead* pFile,
|
| + FX_DWORD dwStart,
|
| + FX_DWORD dwLen) {
|
| + FXSYS_assert(m_pFile == NULL && pFile != NULL);
|
| + FX_DWORD dwSize = pFile->GetSize();
|
| + if (dwStart >= dwSize) {
|
| + return FALSE;
|
| + }
|
| + if (dwLen == -1 || dwStart + dwLen > dwSize) {
|
| + dwLen = dwSize - dwStart;
|
| + }
|
| + if (dwLen == 0) {
|
| + return FALSE;
|
| + }
|
| + m_dwBufSize = std::min(dwLen, kSaxFileBufSize);
|
| + m_pBuf = FX_Alloc(uint8_t, m_dwBufSize);
|
| + if (!pFile->ReadBlock(m_pBuf, dwStart, m_dwBufSize)) {
|
| + return FALSE;
|
| + }
|
| + m_dwStart = dwStart;
|
| + m_dwEnd = dwStart + dwLen;
|
| + m_dwCur = dwStart;
|
| + m_pFile = pFile;
|
| + m_dwBufIndex = 0;
|
| + return TRUE;
|
| +}
|
| +FX_BOOL CFX_SAXFile::ReadNextBlock() {
|
| + FXSYS_assert(m_pFile != NULL);
|
| + FX_DWORD dwSize = m_dwEnd - m_dwCur;
|
| + if (dwSize == 0) {
|
| + return FALSE;
|
| + }
|
| + m_dwBufSize = std::min(dwSize, kSaxFileBufSize);
|
| + if (!m_pFile->ReadBlock(m_pBuf, m_dwCur, m_dwBufSize)) {
|
| + return FALSE;
|
| + }
|
| + m_dwBufIndex = 0;
|
| + return TRUE;
|
| +}
|
| +void CFX_SAXFile::Reset() {
|
| + if (m_pBuf) {
|
| + FX_Free(m_pBuf);
|
| + m_pBuf = NULL;
|
| + }
|
| + m_pFile = NULL;
|
| +}
|
| +CFX_SAXReader::CFX_SAXReader()
|
| + : m_File(),
|
| + m_pHandler(nullptr),
|
| + m_iState(-1),
|
| + m_pRoot(nullptr),
|
| + m_pCurItem(nullptr),
|
| + m_dwItemID(0),
|
| + m_iDataSize(256),
|
| + m_iNameSize(256),
|
| + m_dwParseMode(0),
|
| + m_pCommentContext(nullptr) {
|
| + m_pszData = FX_Alloc(uint8_t, m_iDataSize);
|
| + m_pszName = FX_Alloc(uint8_t, m_iNameSize);
|
| +}
|
| +CFX_SAXReader::~CFX_SAXReader() {
|
| + Reset();
|
| + if (m_pszData) {
|
| + FX_Free(m_pszData);
|
| + m_pszData = NULL;
|
| + }
|
| + if (m_pszName) {
|
| + FX_Free(m_pszName);
|
| + m_pszName = NULL;
|
| + }
|
| +}
|
| +void CFX_SAXReader::Reset() {
|
| + m_File.Reset();
|
| + CFX_SAXItem* pItem = m_pRoot;
|
| + while (pItem) {
|
| + CFX_SAXItem* pNext = pItem->m_pNext;
|
| + delete pItem;
|
| + pItem = pNext;
|
| + }
|
| + m_pRoot = NULL;
|
| + m_pCurItem = NULL;
|
| + m_dwItemID = 0;
|
| + m_SkipStack.RemoveAll();
|
| + m_SkipChar = 0;
|
| + m_iDataLength = 0;
|
| + m_iEntityStart = -1;
|
| + m_iNameLength = 0;
|
| + m_iDataPos = 0;
|
| + if (m_pCommentContext) {
|
| + delete m_pCommentContext;
|
| + m_pCommentContext = NULL;
|
| + }
|
| +}
|
| +inline void CFX_SAXReader::Push() {
|
| + CFX_SAXItem* pNew = new CFX_SAXItem;
|
| + pNew->m_dwID = ++m_dwItemID;
|
| + pNew->m_bSkip = m_pCurItem->m_bSkip;
|
| + pNew->m_pPrev = m_pCurItem;
|
| + m_pCurItem->m_pNext = pNew;
|
| + m_pCurItem = pNew;
|
| +}
|
| +inline void CFX_SAXReader::Pop() {
|
| + if (!m_pCurItem) {
|
| + return;
|
| + }
|
| + CFX_SAXItem* pPrev = m_pCurItem->m_pPrev;
|
| + pPrev->m_pNext = NULL;
|
| + delete m_pCurItem;
|
| + m_pCurItem = pPrev;
|
| +}
|
| +inline void CFX_SAXReader::AppendData(uint8_t ch) {
|
| + ReallocDataBuffer();
|
| + m_pszData[m_iDataPos++] = ch;
|
| +}
|
| +inline void CFX_SAXReader::AppendName(uint8_t ch) {
|
| + ReallocNameBuffer();
|
| + m_pszName[m_iDataPos++] = ch;
|
| +}
|
| +void CFX_SAXReader::ReallocDataBuffer() {
|
| + if (m_iDataPos < m_iDataSize) {
|
| + return;
|
| + }
|
| + if (m_iDataSize <= 1024 * 1024) {
|
| + m_iDataSize *= 2;
|
| + } else {
|
| + m_iDataSize += 1024 * 1024;
|
| + }
|
| + m_pszData = (uint8_t*)FX_Realloc(uint8_t, m_pszData, m_iDataSize);
|
| +}
|
| +void CFX_SAXReader::ReallocNameBuffer() {
|
| + if (m_iDataPos < m_iNameSize) {
|
| + return;
|
| + }
|
| + if (m_iNameSize <= 1024 * 1024) {
|
| + m_iNameSize *= 2;
|
| + } else {
|
| + m_iNameSize += 1024 * 1024;
|
| + }
|
| + m_pszName = (uint8_t*)FX_Realloc(uint8_t, m_pszName, m_iNameSize);
|
| +}
|
| +inline FX_BOOL CFX_SAXReader::SkipSpace(uint8_t ch) {
|
| + return (m_dwParseMode & FX_SAXPARSEMODE_NotSkipSpace) == 0 && ch < 0x21;
|
| +}
|
| +int32_t CFX_SAXReader::StartParse(IFX_FileRead* pFile,
|
| + FX_DWORD dwStart,
|
| + FX_DWORD dwLen,
|
| + FX_DWORD dwParseMode) {
|
| + m_iState = -1;
|
| + Reset();
|
| + if (!m_File.StartFile(pFile, dwStart, dwLen)) {
|
| + return -1;
|
| + }
|
| + m_iState = 0;
|
| + m_eMode = FX_SAXMODE_Text;
|
| + m_ePrevMode = FX_SAXMODE_Text;
|
| + m_bCharData = FALSE;
|
| + m_dwDataOffset = 0;
|
| + m_pRoot = m_pCurItem = new CFX_SAXItem;
|
| + m_pCurItem->m_dwID = ++m_dwItemID;
|
| + m_dwParseMode = dwParseMode;
|
| + return 0;
|
| +}
|
| +typedef void (CFX_SAXReader::*FX_SAXReader_LPFParse)();
|
| +static const FX_SAXReader_LPFParse g_FX_SAXReader_LPFParse[FX_SAXMODE_MAX] = {
|
| + &CFX_SAXReader::ParseText,
|
| + &CFX_SAXReader::ParseNodeStart,
|
| + &CFX_SAXReader::ParseDeclOrComment,
|
| + &CFX_SAXReader::ParseDeclNode,
|
| + &CFX_SAXReader::ParseComment,
|
| + &CFX_SAXReader::ParseCommentContent,
|
| + &CFX_SAXReader::ParseTagName,
|
| + &CFX_SAXReader::ParseTagAttributeName,
|
| + &CFX_SAXReader::ParseTagAttributeEqual,
|
| + &CFX_SAXReader::ParseTagAttributeValue,
|
| + &CFX_SAXReader::ParseMaybeClose,
|
| + &CFX_SAXReader::ParseTagClose,
|
| + &CFX_SAXReader::ParseTagEnd,
|
| + &CFX_SAXReader::ParseTargetData,
|
| +};
|
| +int32_t CFX_SAXReader::ContinueParse(IFX_Pause* pPause) {
|
| + if (m_iState < 0 || m_iState > 99) {
|
| + return m_iState;
|
| + }
|
| + while (m_File.m_dwCur < m_File.m_dwEnd) {
|
| + FX_DWORD& index = m_File.m_dwBufIndex;
|
| + FX_DWORD size = m_File.m_dwBufSize;
|
| + const uint8_t* pBuf = m_File.m_pBuf;
|
| + while (index < size) {
|
| + m_CurByte = pBuf[index];
|
| + (this->*g_FX_SAXReader_LPFParse[m_eMode])();
|
| + index++;
|
| + }
|
| + m_File.m_dwCur += index;
|
| + m_iState = (m_File.m_dwCur - m_File.m_dwStart) * 100 /
|
| + (m_File.m_dwEnd - m_File.m_dwStart);
|
| + if (m_File.m_dwCur >= m_File.m_dwEnd) {
|
| + break;
|
| + }
|
| + if (!m_File.ReadNextBlock()) {
|
| + m_iState = -2;
|
| + break;
|
| + }
|
| + m_dwDataOffset = 0;
|
| + if (pPause && pPause->NeedToPauseNow()) {
|
| + break;
|
| + }
|
| + }
|
| + return m_iState;
|
| +}
|
| +void CFX_SAXReader::ParseChar(uint8_t ch) {
|
| + ReallocDataBuffer();
|
| + m_pszData[m_iDataPos] = ch;
|
| + if (m_iEntityStart > -1 && ch == ';') {
|
| + int32_t iSaveEntityStart = m_iEntityStart;
|
| + CFX_ByteString csEntity(m_pszData + m_iEntityStart + 1,
|
| + m_iDataPos - m_iEntityStart - 1);
|
| + int32_t iLen = csEntity.GetLength();
|
| + if (iLen > 0) {
|
| + if (csEntity[0] == '#') {
|
| + if ((m_dwParseMode & FX_SAXPARSEMODE_NotConvert_sharp) == 0) {
|
| + ch = 0;
|
| + uint8_t w;
|
| + if (iLen > 1 && csEntity[1] == 'x') {
|
| + for (int32_t i = 2; i < iLen; i++) {
|
| + w = csEntity[i];
|
| + if (w >= '0' && w <= '9') {
|
| + ch = (ch << 4) + w - '0';
|
| + } else if (w >= 'A' && w <= 'F') {
|
| + ch = (ch << 4) + w - 55;
|
| + } else if (w >= 'a' && w <= 'f') {
|
| + ch = (ch << 4) + w - 87;
|
| + } else {
|
| + break;
|
| + }
|
| + }
|
| + } else {
|
| + for (int32_t i = 1; i < iLen; i++) {
|
| + w = csEntity[i];
|
| + if (w < '0' || w > '9') {
|
| + break;
|
| + }
|
| + ch = ch * 10 + w - '0';
|
| + }
|
| + }
|
| + if (ch != 0) {
|
| + m_pszData[m_iEntityStart++] = ch;
|
| + }
|
| + }
|
| + } else {
|
| + if (csEntity.Compare("amp") == 0) {
|
| + if ((m_dwParseMode & FX_SAXPARSEMODE_NotConvert_amp) == 0) {
|
| + m_pszData[m_iEntityStart++] = '&';
|
| + }
|
| + } else if (csEntity.Compare("lt") == 0) {
|
| + if ((m_dwParseMode & FX_SAXPARSEMODE_NotConvert_lt) == 0) {
|
| + m_pszData[m_iEntityStart++] = '<';
|
| + }
|
| + } else if (csEntity.Compare("gt") == 0) {
|
| + if ((m_dwParseMode & FX_SAXPARSEMODE_NotConvert_gt) == 0) {
|
| + m_pszData[m_iEntityStart++] = '>';
|
| + }
|
| + } else if (csEntity.Compare("apos") == 0) {
|
| + if ((m_dwParseMode & FX_SAXPARSEMODE_NotConvert_apos) == 0) {
|
| + m_pszData[m_iEntityStart++] = '\'';
|
| + }
|
| + } else if (csEntity.Compare("quot") == 0) {
|
| + if ((m_dwParseMode & FX_SAXPARSEMODE_NotConvert_quot) == 0) {
|
| + m_pszData[m_iEntityStart++] = '\"';
|
| + }
|
| + }
|
| + }
|
| + }
|
| + if (iSaveEntityStart != m_iEntityStart) {
|
| + m_iDataPos = m_iEntityStart;
|
| + m_iEntityStart = -1;
|
| + } else {
|
| + m_iDataPos++;
|
| + m_iEntityStart = -1;
|
| + }
|
| + } else {
|
| + if (m_iEntityStart < 0 && ch == '&') {
|
| + m_iEntityStart = m_iDataPos;
|
| + }
|
| + m_iDataPos++;
|
| + }
|
| +}
|
| +void CFX_SAXReader::ParseText() {
|
| + if (m_CurByte == '<') {
|
| + if (m_iDataPos > 0) {
|
| + m_iDataLength = m_iDataPos;
|
| + m_iDataPos = 0;
|
| + if (m_pHandler) {
|
| + NotifyData();
|
| + }
|
| + }
|
| + Push();
|
| + m_dwNodePos = m_File.m_dwCur + m_File.m_dwBufIndex;
|
| + m_eMode = FX_SAXMODE_NodeStart;
|
| + return;
|
| + }
|
| + if (m_iDataPos < 1 && SkipSpace(m_CurByte)) {
|
| + return;
|
| + }
|
| + ParseChar(m_CurByte);
|
| +}
|
| +void CFX_SAXReader::ParseNodeStart() {
|
| + if (m_CurByte == '?') {
|
| + m_pCurItem->m_eNode = FX_SAXNODE_Instruction;
|
| + m_eMode = FX_SAXMODE_TagName;
|
| + return;
|
| + }
|
| + if (m_CurByte == '!') {
|
| + m_eMode = FX_SAXMODE_DeclOrComment;
|
| + return;
|
| + }
|
| + if (m_CurByte == '/') {
|
| + m_eMode = FX_SAXMODE_TagEnd;
|
| + return;
|
| + }
|
| + if (m_CurByte == '>') {
|
| + Pop();
|
| + m_eMode = FX_SAXMODE_Text;
|
| + return;
|
| + }
|
| + if (m_CurByte > 0x20) {
|
| + m_dwDataOffset = m_File.m_dwBufIndex;
|
| + m_pCurItem->m_eNode = FX_SAXNODE_Tag;
|
| + m_eMode = FX_SAXMODE_TagName;
|
| + AppendData(m_CurByte);
|
| + }
|
| +}
|
| +void CFX_SAXReader::ParseDeclOrComment() {
|
| + if (m_CurByte == '-') {
|
| + m_eMode = FX_SAXMODE_Comment;
|
| + m_pCurItem->m_eNode = FX_SAXNODE_Comment;
|
| + if (m_pCommentContext == NULL) {
|
| + m_pCommentContext = new CFX_SAXCommentContext;
|
| + }
|
| + m_pCommentContext->m_iHeaderCount = 1;
|
| + m_pCommentContext->m_iTailCount = 0;
|
| + } else {
|
| + m_eMode = FX_SAXMODE_DeclNode;
|
| + m_dwDataOffset = m_File.m_dwBufIndex;
|
| + m_SkipChar = '>';
|
| + m_SkipStack.Add('>');
|
| + SkipNode();
|
| + }
|
| +}
|
| +void CFX_SAXReader::ParseComment() {
|
| + m_pCommentContext->m_iHeaderCount = 2;
|
| + m_dwNodePos = m_File.m_dwCur + m_File.m_dwBufIndex;
|
| + m_eMode = FX_SAXMODE_CommentContent;
|
| +}
|
| +void CFX_SAXReader::ParseCommentContent() {
|
| + if (m_CurByte == '-') {
|
| + m_pCommentContext->m_iTailCount++;
|
| + } else if (m_CurByte == '>' && m_pCommentContext->m_iTailCount == 2) {
|
| + m_iDataLength = m_iDataPos;
|
| + m_iDataPos = 0;
|
| + if (m_pHandler) {
|
| + NotifyTargetData();
|
| + }
|
| + Pop();
|
| + m_eMode = FX_SAXMODE_Text;
|
| + } else {
|
| + while (m_pCommentContext->m_iTailCount > 0) {
|
| + AppendData('-');
|
| + m_pCommentContext->m_iTailCount--;
|
| + }
|
| + AppendData(m_CurByte);
|
| + }
|
| +}
|
| +void CFX_SAXReader::ParseDeclNode() {
|
| + SkipNode();
|
| +}
|
| +void CFX_SAXReader::ParseTagName() {
|
| + if (m_CurByte < 0x21 || m_CurByte == '/' || m_CurByte == '>' ||
|
| + m_CurByte == '?') {
|
| + m_iDataLength = m_iDataPos;
|
| + m_iDataPos = 0;
|
| + if (m_pHandler) {
|
| + NotifyEnter();
|
| + }
|
| + if (m_CurByte < 0x21) {
|
| + m_eMode = FX_SAXMODE_TagAttributeName;
|
| + } else if (m_CurByte == '/' || m_CurByte == '?') {
|
| + m_ePrevMode = m_eMode;
|
| + m_eMode = FX_SAXMODE_TagMaybeClose;
|
| + } else {
|
| + if (m_pHandler) {
|
| + NotifyBreak();
|
| + }
|
| + m_eMode = FX_SAXMODE_Text;
|
| + }
|
| + } else {
|
| + AppendData(m_CurByte);
|
| + }
|
| +}
|
| +void CFX_SAXReader::ParseTagAttributeName() {
|
| + if (m_CurByte < 0x21 || m_CurByte == '=') {
|
| + if (m_iDataPos < 1 && m_CurByte < 0x21) {
|
| + return;
|
| + }
|
| + m_iNameLength = m_iDataPos;
|
| + m_iDataPos = 0;
|
| + m_SkipChar = 0;
|
| + m_eMode = m_CurByte == '=' ? FX_SAXMODE_TagAttributeValue
|
| + : FX_SAXMODE_TagAttributeEqual;
|
| + return;
|
| + }
|
| + if (m_CurByte == '/' || m_CurByte == '>' || m_CurByte == '?') {
|
| + if (m_CurByte == '/' || m_CurByte == '?') {
|
| + m_ePrevMode = m_eMode;
|
| + m_eMode = FX_SAXMODE_TagMaybeClose;
|
| + } else {
|
| + if (m_pHandler) {
|
| + NotifyBreak();
|
| + }
|
| + m_eMode = FX_SAXMODE_Text;
|
| + }
|
| + return;
|
| + }
|
| + if (m_iDataPos < 1) {
|
| + m_dwDataOffset = m_File.m_dwBufIndex;
|
| + }
|
| + AppendName(m_CurByte);
|
| +}
|
| +void CFX_SAXReader::ParseTagAttributeEqual() {
|
| + if (m_CurByte == '=') {
|
| + m_SkipChar = 0;
|
| + m_eMode = FX_SAXMODE_TagAttributeValue;
|
| + return;
|
| + } else if (m_pCurItem->m_eNode == FX_SAXNODE_Instruction) {
|
| + m_iDataPos = m_iNameLength;
|
| + AppendName(0x20);
|
| + m_eMode = FX_SAXMODE_TargetData;
|
| + ParseTargetData();
|
| + }
|
| +}
|
| +void CFX_SAXReader::ParseTagAttributeValue() {
|
| + if (m_SkipChar) {
|
| + if (m_SkipChar == m_CurByte) {
|
| + {
|
| + m_iDataLength = m_iDataPos;
|
| + m_iDataPos = 0;
|
| + if (m_pHandler) {
|
| + NotifyAttribute();
|
| + }
|
| + }
|
| + m_SkipChar = 0;
|
| + m_eMode = FX_SAXMODE_TagAttributeName;
|
| + return;
|
| + }
|
| + ParseChar(m_CurByte);
|
| + return;
|
| + }
|
| + if (m_CurByte < 0x21) {
|
| + return;
|
| + }
|
| + if (m_iDataPos < 1) {
|
| + if (m_CurByte == '\'' || m_CurByte == '\"') {
|
| + m_SkipChar = m_CurByte;
|
| + }
|
| + }
|
| +}
|
| +void CFX_SAXReader::ParseMaybeClose() {
|
| + if (m_CurByte == '>') {
|
| + if (m_pCurItem->m_eNode == FX_SAXNODE_Instruction) {
|
| + m_iNameLength = m_iDataPos;
|
| + m_iDataPos = 0;
|
| + if (m_pHandler) {
|
| + NotifyTargetData();
|
| + }
|
| + }
|
| + ParseTagClose();
|
| + m_eMode = FX_SAXMODE_Text;
|
| + } else if (m_ePrevMode == FX_SAXMODE_TagName) {
|
| + AppendData('/');
|
| + m_eMode = FX_SAXMODE_TagName;
|
| + m_ePrevMode = FX_SAXMODE_Text;
|
| + ParseTagName();
|
| + } else if (m_ePrevMode == FX_SAXMODE_TagAttributeName) {
|
| + AppendName('/');
|
| + m_eMode = FX_SAXMODE_TagAttributeName;
|
| + m_ePrevMode = FX_SAXMODE_Text;
|
| + ParseTagAttributeName();
|
| + } else if (m_ePrevMode == FX_SAXMODE_TargetData) {
|
| + AppendName('?');
|
| + m_eMode = FX_SAXMODE_TargetData;
|
| + m_ePrevMode = FX_SAXMODE_Text;
|
| + ParseTargetData();
|
| + }
|
| +}
|
| +void CFX_SAXReader::ParseTagClose() {
|
| + m_dwNodePos = m_File.m_dwCur + m_File.m_dwBufIndex;
|
| + if (m_pHandler) {
|
| + NotifyClose();
|
| + }
|
| + Pop();
|
| +}
|
| +void CFX_SAXReader::ParseTagEnd() {
|
| + if (m_CurByte < 0x21) {
|
| + return;
|
| + }
|
| + if (m_CurByte == '>') {
|
| + Pop();
|
| + m_dwNodePos = m_File.m_dwCur + m_File.m_dwBufIndex;
|
| + m_iDataLength = m_iDataPos;
|
| + m_iDataPos = 0;
|
| + if (m_pHandler) {
|
| + NotifyEnd();
|
| + }
|
| + Pop();
|
| + m_eMode = FX_SAXMODE_Text;
|
| + } else {
|
| + ParseChar(m_CurByte);
|
| + }
|
| +}
|
| +void CFX_SAXReader::ParseTargetData() {
|
| + if (m_CurByte == '?') {
|
| + m_ePrevMode = m_eMode;
|
| + m_eMode = FX_SAXMODE_TagMaybeClose;
|
| + } else {
|
| + AppendName(m_CurByte);
|
| + }
|
| +}
|
| +void CFX_SAXReader::SkipNode() {
|
| + int32_t iLen = m_SkipStack.GetSize();
|
| + if (m_SkipChar == '\'' || m_SkipChar == '\"') {
|
| + if (m_CurByte != m_SkipChar) {
|
| + return;
|
| + }
|
| + iLen--;
|
| + FXSYS_assert(iLen > -1);
|
| + m_SkipStack.RemoveAt(iLen, 1);
|
| + m_SkipChar = iLen ? m_SkipStack[iLen - 1] : 0;
|
| + return;
|
| + }
|
| + switch (m_CurByte) {
|
| + case '<':
|
| + m_SkipChar = '>';
|
| + m_SkipStack.Add('>');
|
| + break;
|
| + case '[':
|
| + m_SkipChar = ']';
|
| + m_SkipStack.Add(']');
|
| + break;
|
| + case '(':
|
| + m_SkipChar = ')';
|
| + m_SkipStack.Add(')');
|
| + break;
|
| + case '\'':
|
| + m_SkipChar = '\'';
|
| + m_SkipStack.Add('\'');
|
| + break;
|
| + case '\"':
|
| + m_SkipChar = '\"';
|
| + m_SkipStack.Add('\"');
|
| + break;
|
| + default:
|
| + if (m_CurByte == m_SkipChar) {
|
| + iLen--;
|
| + m_SkipStack.RemoveAt(iLen, 1);
|
| + m_SkipChar = iLen ? m_SkipStack[iLen - 1] : 0;
|
| + if (iLen == 0 && m_CurByte == '>') {
|
| + m_iDataLength = m_iDataPos;
|
| + m_iDataPos = 0;
|
| + if (m_iDataLength >= 9 &&
|
| + FXSYS_memcmp(m_pszData, "[CDATA[", 7 * sizeof(uint8_t)) == 0 &&
|
| + FXSYS_memcmp(m_pszData + m_iDataLength - 2, "]]",
|
| + 2 * sizeof(uint8_t)) == 0) {
|
| + Pop();
|
| + m_iDataLength -= 9;
|
| + m_dwDataOffset += 7;
|
| + FXSYS_memmove(m_pszData, m_pszData + 7,
|
| + m_iDataLength * sizeof(uint8_t));
|
| + m_bCharData = TRUE;
|
| + if (m_pHandler) {
|
| + NotifyData();
|
| + }
|
| + m_bCharData = FALSE;
|
| + } else {
|
| + Pop();
|
| + }
|
| + m_eMode = FX_SAXMODE_Text;
|
| + }
|
| + }
|
| + break;
|
| + }
|
| + if (iLen > 0) {
|
| + ParseChar(m_CurByte);
|
| + }
|
| +}
|
| +void CFX_SAXReader::NotifyData() {
|
| + FXSYS_assert(m_pHandler != NULL);
|
| + if (m_pCurItem->m_eNode == FX_SAXNODE_Tag)
|
| + m_pHandler->OnTagData(m_pCurItem->m_pNode,
|
| + m_bCharData ? FX_SAXNODE_CharData : FX_SAXNODE_Text,
|
| + CFX_ByteStringC(m_pszData, m_iDataLength),
|
| + m_File.m_dwCur + m_dwDataOffset);
|
| +}
|
| +void CFX_SAXReader::NotifyEnter() {
|
| + FXSYS_assert(m_pHandler != NULL);
|
| + if (m_pCurItem->m_eNode == FX_SAXNODE_Tag ||
|
| + m_pCurItem->m_eNode == FX_SAXNODE_Instruction) {
|
| + m_pCurItem->m_pNode =
|
| + m_pHandler->OnTagEnter(CFX_ByteStringC(m_pszData, m_iDataLength),
|
| + m_pCurItem->m_eNode, m_dwNodePos);
|
| + }
|
| +}
|
| +void CFX_SAXReader::NotifyAttribute() {
|
| + FXSYS_assert(m_pHandler != NULL);
|
| + if (m_pCurItem->m_eNode == FX_SAXNODE_Tag ||
|
| + m_pCurItem->m_eNode == FX_SAXNODE_Instruction) {
|
| + m_pHandler->OnTagAttribute(m_pCurItem->m_pNode,
|
| + CFX_ByteStringC(m_pszName, m_iNameLength),
|
| + CFX_ByteStringC(m_pszData, m_iDataLength));
|
| + }
|
| +}
|
| +void CFX_SAXReader::NotifyBreak() {
|
| + FXSYS_assert(m_pHandler != NULL);
|
| + if (m_pCurItem->m_eNode == FX_SAXNODE_Tag) {
|
| + m_pHandler->OnTagBreak(m_pCurItem->m_pNode);
|
| + }
|
| +}
|
| +void CFX_SAXReader::NotifyClose() {
|
| + FXSYS_assert(m_pHandler != NULL);
|
| + if (m_pCurItem->m_eNode == FX_SAXNODE_Tag ||
|
| + m_pCurItem->m_eNode == FX_SAXNODE_Instruction) {
|
| + m_pHandler->OnTagClose(m_pCurItem->m_pNode, m_dwNodePos);
|
| + }
|
| +}
|
| +void CFX_SAXReader::NotifyEnd() {
|
| + FXSYS_assert(m_pHandler != NULL);
|
| + if (m_pCurItem->m_eNode == FX_SAXNODE_Tag) {
|
| + m_pHandler->OnTagEnd(m_pCurItem->m_pNode,
|
| + CFX_ByteStringC(m_pszData, m_iDataLength),
|
| + m_dwNodePos);
|
| + }
|
| +}
|
| +void CFX_SAXReader::NotifyTargetData() {
|
| + FXSYS_assert(m_pHandler != NULL);
|
| + if (m_pCurItem->m_eNode == FX_SAXNODE_Instruction) {
|
| + m_pHandler->OnTargetData(m_pCurItem->m_pNode, m_pCurItem->m_eNode,
|
| + CFX_ByteStringC(m_pszName, m_iNameLength),
|
| + m_dwNodePos);
|
| + } else if (m_pCurItem->m_eNode == FX_SAXNODE_Comment) {
|
| + m_pHandler->OnTargetData(m_pCurItem->m_pNode, m_pCurItem->m_eNode,
|
| + CFX_ByteStringC(m_pszData, m_iDataLength),
|
| + m_dwNodePos);
|
| + }
|
| +}
|
| +void CFX_SAXReader::SkipCurrentNode() {
|
| + if (!m_pCurItem) {
|
| + return;
|
| + }
|
| + m_pCurItem->m_bSkip = TRUE;
|
| +}
|
| +void CFX_SAXReader::SetHandler(IFX_SAXReaderHandler* pHandler) {
|
| + m_pHandler = pHandler;
|
| +}
|
|
|