| OLD | NEW |
| 1 // Copyright 2014 PDFium Authors. All rights reserved. | 1 // Copyright 2014 PDFium Authors. All rights reserved. |
| 2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
| 3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
| 4 | 4 |
| 5 // Original code copyright 2014 Foxit Software Inc. http://www.foxitsoftware.com | 5 // Original code copyright 2014 Foxit Software Inc. http://www.foxitsoftware.com |
| 6 | 6 |
| 7 #include <algorithm> | 7 #include <algorithm> |
| 8 | 8 |
| 9 #include "xfa/src/fdp/src/xml/fde_xml_imp.h" | 9 #include "xfa/src/fdp/src/xml/fde_xml_imp.h" |
| 10 #include "xfa/src/foxitlib.h" | 10 #include "xfa/src/foxitlib.h" |
| 11 #ifdef __cplusplus | 11 |
| 12 extern "C" { | |
| 13 #endif | |
| 14 #define FDE_XMLVALIDCHARRANGENUM 5 | 12 #define FDE_XMLVALIDCHARRANGENUM 5 |
| 15 static FX_WCHAR g_XMLValidCharRange[FDE_XMLVALIDCHARRANGENUM][2] = { | 13 static FX_WCHAR g_XMLValidCharRange[FDE_XMLVALIDCHARRANGENUM][2] = { |
| 16 {0x09, 0x09}, | 14 {0x09, 0x09}, |
| 17 {0x0A, 0x0A}, | 15 {0x0A, 0x0A}, |
| 18 {0x0D, 0x0D}, | 16 {0x0D, 0x0D}, |
| 19 {0x20, 0xD7FF}, | 17 {0x20, 0xD7FF}, |
| 20 {0xE000, 0xFFFD}}; | 18 {0xE000, 0xFFFD}}; |
| 21 FX_BOOL FDE_IsXMLValidChar(FX_WCHAR ch) { | 19 FX_BOOL FDE_IsXMLValidChar(FX_WCHAR ch) { |
| 22 int32_t iStart = 0, iEnd = FDE_XMLVALIDCHARRANGENUM - 1, iMid; | 20 int32_t iStart = 0, iEnd = FDE_XMLVALIDCHARRANGENUM - 1, iMid; |
| 23 while (iStart <= iEnd) { | 21 while (iStart <= iEnd) { |
| (...skipping 36 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 60 iStart = iMid + 1; | 58 iStart = iMid + 1; |
| 61 } else { | 59 } else { |
| 62 if (bFirstChar) { | 60 if (bFirstChar) { |
| 63 return g_XMLNameChars[iMid].bStartChar; | 61 return g_XMLNameChars[iMid].bStartChar; |
| 64 } | 62 } |
| 65 return TRUE; | 63 return TRUE; |
| 66 } | 64 } |
| 67 } | 65 } |
| 68 return FALSE; | 66 return FALSE; |
| 69 } | 67 } |
| 70 #ifdef __cplusplus | 68 |
| 71 } | |
| 72 #endif | |
| 73 CFDE_XMLNode::CFDE_XMLNode() | 69 CFDE_XMLNode::CFDE_XMLNode() |
| 74 : m_pParent(NULL), m_pChild(NULL), m_pPrior(NULL), m_pNext(NULL) {} | 70 : m_pParent(NULL), m_pChild(NULL), m_pPrior(NULL), m_pNext(NULL) {} |
| 75 CFDE_XMLNode::~CFDE_XMLNode() { | 71 CFDE_XMLNode::~CFDE_XMLNode() { |
| 76 DeleteChildren(); | 72 DeleteChildren(); |
| 77 } | 73 } |
| 78 void CFDE_XMLNode::DeleteChildren() { | 74 void CFDE_XMLNode::DeleteChildren() { |
| 79 CFDE_XMLNode *pChild = m_pChild, *pTemp; | 75 CFDE_XMLNode *pChild = m_pChild, *pTemp; |
| 80 while (pChild != NULL) { | 76 while (pChild != NULL) { |
| 81 pTemp = pChild->m_pNext; | 77 pTemp = pChild->m_pNext; |
| 82 pChild->Release(); | 78 pChild->Release(); |
| (...skipping 1225 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1308 return m_pParser->GetStatus(); | 1304 return m_pParser->GetStatus(); |
| 1309 } | 1305 } |
| 1310 inline void CFDE_XMLSAXParser::Push(const CFDE_XMLTAG& xmlTag) { | 1306 inline void CFDE_XMLSAXParser::Push(const CFDE_XMLTAG& xmlTag) { |
| 1311 m_TagStack.Push(xmlTag); | 1307 m_TagStack.Push(xmlTag); |
| 1312 m_pTagTop = m_TagStack.GetTopElement(); | 1308 m_pTagTop = m_TagStack.GetTopElement(); |
| 1313 } | 1309 } |
| 1314 inline void CFDE_XMLSAXParser::Pop() { | 1310 inline void CFDE_XMLSAXParser::Pop() { |
| 1315 m_TagStack.Pop(); | 1311 m_TagStack.Pop(); |
| 1316 m_pTagTop = m_TagStack.GetTopElement(); | 1312 m_pTagTop = m_TagStack.GetTopElement(); |
| 1317 } | 1313 } |
| 1318 #ifdef _FDE_BLOCK_BUFFER | 1314 |
| 1319 CFDE_BlockBuffer::CFDE_BlockBuffer(int32_t iAllocStep) | 1315 CFDE_BlockBuffer::CFDE_BlockBuffer(int32_t iAllocStep) |
| 1320 : m_iDataLength(0), | 1316 : m_iDataLength(0), |
| 1321 m_iBufferSize(0), | 1317 m_iBufferSize(0), |
| 1322 m_iAllocStep(iAllocStep), | 1318 m_iAllocStep(iAllocStep), |
| 1323 m_iStartPosition(0) {} | 1319 m_iStartPosition(0) {} |
| 1324 CFDE_BlockBuffer::~CFDE_BlockBuffer() { | 1320 CFDE_BlockBuffer::~CFDE_BlockBuffer() { |
| 1325 ClearBuffer(); | 1321 ClearBuffer(); |
| 1326 } | 1322 } |
| 1327 FX_WCHAR* CFDE_BlockBuffer::GetAvailableBlock(int32_t& iIndexInBlock) { | 1323 FX_WCHAR* CFDE_BlockBuffer::GetAvailableBlock(int32_t& iIndexInBlock) { |
| 1328 iIndexInBlock = 0; | 1324 iIndexInBlock = 0; |
| (...skipping 109 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1438 } | 1434 } |
| 1439 void CFDE_BlockBuffer::ClearBuffer() { | 1435 void CFDE_BlockBuffer::ClearBuffer() { |
| 1440 m_iBufferSize = 0; | 1436 m_iBufferSize = 0; |
| 1441 int32_t iSize = m_BlockArray.GetSize(); | 1437 int32_t iSize = m_BlockArray.GetSize(); |
| 1442 for (int32_t i = 0; i < iSize; i++) { | 1438 for (int32_t i = 0; i < iSize; i++) { |
| 1443 FX_Free(m_BlockArray[i]); | 1439 FX_Free(m_BlockArray[i]); |
| 1444 m_BlockArray[i] = NULL; | 1440 m_BlockArray[i] = NULL; |
| 1445 } | 1441 } |
| 1446 m_BlockArray.RemoveAll(); | 1442 m_BlockArray.RemoveAll(); |
| 1447 } | 1443 } |
| 1448 #endif | 1444 |
| 1449 IFDE_XMLSyntaxParser* IFDE_XMLSyntaxParser::Create() { | 1445 IFDE_XMLSyntaxParser* IFDE_XMLSyntaxParser::Create() { |
| 1450 return new CFDE_XMLSyntaxParser; | 1446 return new CFDE_XMLSyntaxParser; |
| 1451 } | 1447 } |
| 1452 #ifdef _FDE_BLOCK_BUFFER | 1448 |
| 1453 CFDE_XMLSyntaxParser::CFDE_XMLSyntaxParser() | 1449 CFDE_XMLSyntaxParser::CFDE_XMLSyntaxParser() |
| 1454 : m_pStream(nullptr), | 1450 : m_pStream(nullptr), |
| 1455 m_iXMLPlaneSize(-1), | 1451 m_iXMLPlaneSize(-1), |
| 1456 m_iCurrentPos(0), | 1452 m_iCurrentPos(0), |
| 1457 m_iCurrentNodeNum(-1), | 1453 m_iCurrentNodeNum(-1), |
| 1458 m_iLastNodeNum(-1), | 1454 m_iLastNodeNum(-1), |
| 1459 m_iParsedChars(0), | 1455 m_iParsedChars(0), |
| 1460 m_iParsedBytes(0), | 1456 m_iParsedBytes(0), |
| 1461 m_pBuffer(nullptr), | 1457 m_pBuffer(nullptr), |
| 1462 m_iBufferChars(0), | 1458 m_iBufferChars(0), |
| (...skipping 496 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1959 default: | 1955 default: |
| 1960 break; | 1956 break; |
| 1961 } | 1957 } |
| 1962 if (dwStatus != FDE_XMLSYNTAXSTATUS_None) { | 1958 if (dwStatus != FDE_XMLSYNTAXSTATUS_None) { |
| 1963 return dwStatus; | 1959 return dwStatus; |
| 1964 } | 1960 } |
| 1965 } | 1961 } |
| 1966 } | 1962 } |
| 1967 return 0; | 1963 return 0; |
| 1968 } | 1964 } |
| 1969 #else | 1965 |
| 1970 CFDE_XMLSyntaxParser::CFDE_XMLSyntaxParser() | |
| 1971 : m_pStream(NULL), | |
| 1972 m_iXMLPlaneSize(-1), | |
| 1973 m_iTextDataSize(256), | |
| 1974 m_iCurrentPos(0), | |
| 1975 m_iCurrentNodeNum(-1), | |
| 1976 m_iLastNodeNum(-1), | |
| 1977 m_iParsedChars(0), | |
| 1978 m_iParsedBytes(0), | |
| 1979 m_pBuffer(NULL), | |
| 1980 m_iBufferChars(0), | |
| 1981 m_bEOS(FALSE), | |
| 1982 m_pStart(NULL), | |
| 1983 m_pEnd(NULL), | |
| 1984 m_XMLNodeStack(16), | |
| 1985 m_pwsTextData(NULL), | |
| 1986 m_iDataPos(0), | |
| 1987 m_dwStatus(FDE_XMLSYNTAXSTATUS_None), | |
| 1988 m_dwMode(FDE_XMLSYNTAXMODE_Text), | |
| 1989 m_wQuotationMark(0), | |
| 1990 m_iTextDataLength(0), | |
| 1991 m_iEntityStart(-1), | |
| 1992 m_SkipStack(16) { | |
| 1993 m_CurNode.iNodeNum = -1; | |
| 1994 m_CurNode.eNodeType = FDE_XMLNODE_Unknown; | |
| 1995 } | |
| 1996 void CFDE_XMLSyntaxParser::Init(IFX_Stream* pStream, | |
| 1997 int32_t iXMLPlaneSize, | |
| 1998 int32_t iTextDataSize) { | |
| 1999 FXSYS_assert(m_pStream == NULL && m_pBuffer == NULL); | |
| 2000 FXSYS_assert(pStream != NULL && iXMLPlaneSize > 0 && iTextDataSize > 0); | |
| 2001 int32_t iStreamLength = pStream->GetLength(); | |
| 2002 FXSYS_assert(iStreamLength > 0); | |
| 2003 m_pStream = pStream; | |
| 2004 m_iXMLPlaneSize = std::min(iXMLPlaneSize, iStreamLength); | |
| 2005 m_iTextDataSize = iTextDataSize; | |
| 2006 uint8_t bom[4]; | |
| 2007 m_iCurrentPos = m_pStream->GetBOM(bom); | |
| 2008 FXSYS_assert(m_pBuffer == NULL); | |
| 2009 m_pBuffer = FX_Alloc(FX_WCHAR, m_iXMLPlaneSize); | |
| 2010 m_pStart = m_pEnd = m_pBuffer; | |
| 2011 FXSYS_assert(m_pwsTextData == NULL); | |
| 2012 m_pwsTextData = FX_Alloc(FX_WCHAR, m_iTextDataSize); | |
| 2013 m_iParsedBytes = 0; | |
| 2014 m_iParsedChars = 0; | |
| 2015 m_iBufferChars = 0; | |
| 2016 } | |
| 2017 FX_DWORD CFDE_XMLSyntaxParser::DoSyntaxParse() { | |
| 2018 if (m_dwStatus == FDE_XMLSYNTAXSTATUS_Error || | |
| 2019 m_dwStatus == FDE_XMLSYNTAXSTATUS_EOS) { | |
| 2020 return m_dwStatus; | |
| 2021 } | |
| 2022 FXSYS_assert(m_pStream != NULL && m_pBuffer != NULL && m_pwsTextData != NULL); | |
| 2023 int32_t iStreamLength = m_pStream->GetLength(); | |
| 2024 int32_t iPos; | |
| 2025 FX_WCHAR ch; | |
| 2026 FX_DWORD dwStatus = FDE_XMLSYNTAXSTATUS_None; | |
| 2027 while (TRUE) { | |
| 2028 if (m_pStart >= m_pEnd) { | |
| 2029 if (m_bEOS || m_iCurrentPos >= iStreamLength) { | |
| 2030 m_dwStatus = FDE_XMLSYNTAXSTATUS_EOS; | |
| 2031 return m_dwStatus; | |
| 2032 } | |
| 2033 m_iParsedChars += (m_pEnd - m_pBuffer); | |
| 2034 m_iParsedBytes = m_iCurrentPos; | |
| 2035 m_pStream->Lock(); | |
| 2036 if (m_pStream->GetPosition() != m_iCurrentPos) { | |
| 2037 m_pStream->Seek(FX_STREAMSEEK_Begin, m_iCurrentPos); | |
| 2038 } | |
| 2039 m_iBufferChars = | |
| 2040 m_pStream->ReadString(m_pBuffer, m_iXMLPlaneSize, m_bEOS); | |
| 2041 iPos = m_pStream->GetPosition(); | |
| 2042 m_pStream->Unlock(); | |
| 2043 if (m_iBufferChars < 1) { | |
| 2044 m_iCurrentPos = iStreamLength; | |
| 2045 m_dwStatus = FDE_XMLSYNTAXSTATUS_EOS; | |
| 2046 return m_dwStatus; | |
| 2047 } | |
| 2048 m_iCurrentPos = iPos; | |
| 2049 m_pStart = m_pBuffer; | |
| 2050 m_pEnd = m_pBuffer + m_iBufferChars; | |
| 2051 } | |
| 2052 while (m_pStart < m_pEnd) { | |
| 2053 ch = *m_pStart; | |
| 2054 switch (m_dwMode) { | |
| 2055 case FDE_XMLSYNTAXMODE_Text: | |
| 2056 if (ch == L'<') { | |
| 2057 if (m_iDataPos > 0) { | |
| 2058 m_iTextDataLength = m_iDataPos; | |
| 2059 m_iDataPos = 0; | |
| 2060 m_iEntityStart = -1; | |
| 2061 dwStatus = FDE_XMLSYNTAXSTATUS_Text; | |
| 2062 } else { | |
| 2063 m_pStart++; | |
| 2064 m_dwMode = FDE_XMLSYNTAXMODE_Node; | |
| 2065 } | |
| 2066 } else { | |
| 2067 ParseTextChar(ch); | |
| 2068 } | |
| 2069 break; | |
| 2070 case FDE_XMLSYNTAXMODE_Node: | |
| 2071 if (ch == L'!') { | |
| 2072 m_pStart++; | |
| 2073 m_dwMode = FDE_XMLSYNTAXMODE_SkipCommentOrDecl; | |
| 2074 } else if (ch == L'/') { | |
| 2075 m_pStart++; | |
| 2076 m_dwMode = FDE_XMLSYNTAXMODE_CloseElement; | |
| 2077 } else if (ch == L'?') { | |
| 2078 m_iLastNodeNum++; | |
| 2079 m_iCurrentNodeNum = m_iLastNodeNum; | |
| 2080 m_CurNode.iNodeNum = m_iLastNodeNum; | |
| 2081 m_CurNode.eNodeType = FDE_XMLNODE_Instruction; | |
| 2082 m_XMLNodeStack.Push(m_CurNode); | |
| 2083 m_pStart++; | |
| 2084 m_dwMode = FDE_XMLSYNTAXMODE_Target; | |
| 2085 dwStatus = FDE_XMLSYNTAXSTATUS_InstructionOpen; | |
| 2086 } else { | |
| 2087 m_iLastNodeNum++; | |
| 2088 m_iCurrentNodeNum = m_iLastNodeNum; | |
| 2089 m_CurNode.iNodeNum = m_iLastNodeNum; | |
| 2090 m_CurNode.eNodeType = FDE_XMLNODE_Element; | |
| 2091 m_XMLNodeStack.Push(m_CurNode); | |
| 2092 m_dwMode = FDE_XMLSYNTAXMODE_Tag; | |
| 2093 dwStatus = FDE_XMLSYNTAXSTATUS_ElementOpen; | |
| 2094 } | |
| 2095 break; | |
| 2096 case FDE_XMLSYNTAXMODE_Target: | |
| 2097 case FDE_XMLSYNTAXMODE_Tag: | |
| 2098 if (!FDE_IsXMLNameChar(ch, m_iDataPos < 1)) { | |
| 2099 if (m_iDataPos < 1) { | |
| 2100 m_dwStatus = FDE_XMLSYNTAXSTATUS_Error; | |
| 2101 return m_dwStatus; | |
| 2102 } else { | |
| 2103 m_iTextDataLength = m_iDataPos; | |
| 2104 m_iDataPos = 0; | |
| 2105 if (m_dwMode != FDE_XMLSYNTAXMODE_Target) { | |
| 2106 dwStatus = FDE_XMLSYNTAXSTATUS_TagName; | |
| 2107 } else { | |
| 2108 dwStatus = FDE_XMLSYNTAXSTATUS_TargetName; | |
| 2109 } | |
| 2110 m_dwMode = FDE_XMLSYNTAXMODE_AttriName; | |
| 2111 } | |
| 2112 } else { | |
| 2113 if (m_iDataPos >= m_iTextDataSize) { | |
| 2114 ReallocTextDataBuffer(); | |
| 2115 } | |
| 2116 m_pwsTextData[m_iDataPos++] = ch; | |
| 2117 m_pStart++; | |
| 2118 } | |
| 2119 break; | |
| 2120 case FDE_XMLSYNTAXMODE_AttriName: | |
| 2121 if (m_iDataPos < 1 && FDE_IsXMLWhiteSpace(ch)) { | |
| 2122 m_pStart++; | |
| 2123 break; | |
| 2124 } | |
| 2125 if (!FDE_IsXMLNameChar(ch, m_iDataPos < 1)) { | |
| 2126 if (m_iDataPos < 1) { | |
| 2127 if (m_CurNode.eNodeType == FDE_XMLNODE_Element) { | |
| 2128 if (ch == L'>' || ch == L'/') { | |
| 2129 m_dwMode = FDE_XMLSYNTAXMODE_BreakElement; | |
| 2130 break; | |
| 2131 } | |
| 2132 } else if (m_CurNode.eNodeType == FDE_XMLNODE_Instruction) { | |
| 2133 if (ch == L'?') { | |
| 2134 m_dwMode = FDE_XMLSYNTAXMODE_CloseInstruction; | |
| 2135 m_pStart++; | |
| 2136 } else { | |
| 2137 m_dwMode = FDE_XMLSYNTAXMODE_TargetData; | |
| 2138 } | |
| 2139 break; | |
| 2140 } | |
| 2141 m_dwStatus = FDE_XMLSYNTAXSTATUS_Error; | |
| 2142 return m_dwStatus; | |
| 2143 } else { | |
| 2144 if (m_CurNode.eNodeType == FDE_XMLNODE_Instruction) { | |
| 2145 if (ch != '=' && !FDE_IsXMLWhiteSpace(ch)) { | |
| 2146 m_dwMode = FDE_XMLSYNTAXMODE_TargetData; | |
| 2147 break; | |
| 2148 } | |
| 2149 } | |
| 2150 m_iTextDataLength = m_iDataPos; | |
| 2151 m_iDataPos = 0; | |
| 2152 m_dwMode = FDE_XMLSYNTAXMODE_AttriEqualSign; | |
| 2153 dwStatus = FDE_XMLSYNTAXSTATUS_AttriName; | |
| 2154 } | |
| 2155 } else { | |
| 2156 if (m_iDataPos >= m_iTextDataSize) { | |
| 2157 ReallocTextDataBuffer(); | |
| 2158 } | |
| 2159 m_pwsTextData[m_iDataPos++] = ch; | |
| 2160 m_pStart++; | |
| 2161 } | |
| 2162 break; | |
| 2163 case FDE_XMLSYNTAXMODE_AttriEqualSign: | |
| 2164 if (FDE_IsXMLWhiteSpace(ch)) { | |
| 2165 m_pStart++; | |
| 2166 break; | |
| 2167 } | |
| 2168 if (ch != L'=') { | |
| 2169 if (m_CurNode.eNodeType == FDE_XMLNODE_Instruction) { | |
| 2170 m_dwMode = FDE_XMLSYNTAXMODE_TargetData; | |
| 2171 break; | |
| 2172 } | |
| 2173 m_dwStatus = FDE_XMLSYNTAXSTATUS_Error; | |
| 2174 return m_dwStatus; | |
| 2175 } else { | |
| 2176 m_dwMode = FDE_XMLSYNTAXMODE_AttriQuotation; | |
| 2177 m_pStart++; | |
| 2178 } | |
| 2179 break; | |
| 2180 case FDE_XMLSYNTAXMODE_AttriQuotation: | |
| 2181 if (FDE_IsXMLWhiteSpace(ch)) { | |
| 2182 m_pStart++; | |
| 2183 break; | |
| 2184 } | |
| 2185 if (ch != L'\"' && ch != L'\'') { | |
| 2186 m_dwStatus = FDE_XMLSYNTAXSTATUS_Error; | |
| 2187 return m_dwStatus; | |
| 2188 } else { | |
| 2189 m_wQuotationMark = ch; | |
| 2190 m_dwMode = FDE_XMLSYNTAXMODE_AttriValue; | |
| 2191 m_pStart++; | |
| 2192 } | |
| 2193 break; | |
| 2194 case FDE_XMLSYNTAXMODE_AttriValue: | |
| 2195 if (ch == m_wQuotationMark) { | |
| 2196 if (m_iEntityStart > -1) { | |
| 2197 m_dwStatus = FDE_XMLSYNTAXSTATUS_Error; | |
| 2198 return m_dwStatus; | |
| 2199 } | |
| 2200 m_iTextDataLength = m_iDataPos; | |
| 2201 m_wQuotationMark = 0; | |
| 2202 m_iDataPos = 0; | |
| 2203 m_pStart++; | |
| 2204 m_dwMode = FDE_XMLSYNTAXMODE_AttriName; | |
| 2205 dwStatus = FDE_XMLSYNTAXSTATUS_AttriValue; | |
| 2206 } else { | |
| 2207 ParseTextChar(ch); | |
| 2208 } | |
| 2209 break; | |
| 2210 case FDE_XMLSYNTAXMODE_CloseInstruction: | |
| 2211 if (ch != L'>') { | |
| 2212 if (m_iDataPos >= m_iTextDataSize) { | |
| 2213 ReallocTextDataBuffer(); | |
| 2214 } | |
| 2215 m_pwsTextData[m_iDataPos++] = ch; | |
| 2216 m_dwMode = FDE_XMLSYNTAXMODE_TargetData; | |
| 2217 } else if (m_iDataPos > 0) { | |
| 2218 m_iTextDataLength = m_iDataPos; | |
| 2219 m_iDataPos = 0; | |
| 2220 dwStatus = FDE_XMLSYNTAXSTATUS_TargetData; | |
| 2221 } else { | |
| 2222 m_pStart++; | |
| 2223 FDE_LPXMLNODE pXMLNode = m_XMLNodeStack.GetTopElement(); | |
| 2224 if (pXMLNode == NULL) { | |
| 2225 m_dwStatus = FDE_XMLSYNTAXSTATUS_Error; | |
| 2226 return m_dwStatus; | |
| 2227 } | |
| 2228 m_XMLNodeStack.Pop(); | |
| 2229 pXMLNode = m_XMLNodeStack.GetTopElement(); | |
| 2230 if (pXMLNode == NULL) { | |
| 2231 m_CurNode.iNodeNum = -1; | |
| 2232 m_CurNode.eNodeType = FDE_XMLNODE_Unknown; | |
| 2233 } else { | |
| 2234 m_CurNode = *pXMLNode; | |
| 2235 } | |
| 2236 m_iCurrentNodeNum = m_CurNode.iNodeNum; | |
| 2237 m_iDataPos = 0; | |
| 2238 m_dwMode = FDE_XMLSYNTAXMODE_Text; | |
| 2239 dwStatus = FDE_XMLSYNTAXSTATUS_InstructionClose; | |
| 2240 } | |
| 2241 break; | |
| 2242 case FDE_XMLSYNTAXMODE_BreakElement: | |
| 2243 if (ch == L'>') { | |
| 2244 m_dwMode = FDE_XMLSYNTAXMODE_Text; | |
| 2245 dwStatus = FDE_XMLSYNTAXSTATUS_ElementBreak; | |
| 2246 } else if (ch == L'/') { | |
| 2247 m_dwMode = FDE_XMLSYNTAXMODE_CloseElement; | |
| 2248 } else { | |
| 2249 m_dwStatus = FDE_XMLSYNTAXSTATUS_Error; | |
| 2250 return m_dwStatus; | |
| 2251 } | |
| 2252 m_pStart++; | |
| 2253 break; | |
| 2254 case FDE_XMLSYNTAXMODE_CloseElement: | |
| 2255 if (!FDE_IsXMLNameChar(ch, m_iDataPos < 1)) { | |
| 2256 if (ch == L'>') { | |
| 2257 FDE_LPXMLNODE pXMLNode = m_XMLNodeStack.GetTopElement(); | |
| 2258 if (pXMLNode == NULL) { | |
| 2259 m_dwStatus = FDE_XMLSYNTAXSTATUS_Error; | |
| 2260 return m_dwStatus; | |
| 2261 } | |
| 2262 m_XMLNodeStack.Pop(); | |
| 2263 pXMLNode = m_XMLNodeStack.GetTopElement(); | |
| 2264 if (pXMLNode == NULL) { | |
| 2265 m_CurNode.iNodeNum = -1; | |
| 2266 m_CurNode.eNodeType = FDE_XMLNODE_Unknown; | |
| 2267 } else { | |
| 2268 m_CurNode = *pXMLNode; | |
| 2269 } | |
| 2270 m_iCurrentNodeNum = m_CurNode.iNodeNum; | |
| 2271 m_iTextDataLength = m_iDataPos; | |
| 2272 m_iDataPos = 0; | |
| 2273 m_dwMode = FDE_XMLSYNTAXMODE_Text; | |
| 2274 dwStatus = FDE_XMLSYNTAXSTATUS_ElementClose; | |
| 2275 } else if (!FDE_IsXMLWhiteSpace(ch)) { | |
| 2276 m_dwStatus = FDE_XMLSYNTAXSTATUS_Error; | |
| 2277 return m_dwStatus; | |
| 2278 } | |
| 2279 } else { | |
| 2280 if (m_iDataPos >= m_iTextDataSize) { | |
| 2281 ReallocTextDataBuffer(); | |
| 2282 } | |
| 2283 m_pwsTextData[m_iDataPos++] = ch; | |
| 2284 } | |
| 2285 m_pStart++; | |
| 2286 break; | |
| 2287 case FDE_XMLSYNTAXMODE_SkipCommentOrDecl: | |
| 2288 if (ch == '-') { | |
| 2289 m_dwMode = FDE_XMLSYNTAXMODE_SkipComment; | |
| 2290 } else { | |
| 2291 m_dwMode = FDE_XMLSYNTAXMODE_SkipDeclNode; | |
| 2292 m_SkipChar = L'>'; | |
| 2293 m_SkipStack.Push(L'>'); | |
| 2294 } | |
| 2295 break; | |
| 2296 case FDE_XMLSYNTAXMODE_SkipDeclNode: | |
| 2297 if (m_SkipChar == L'\'' || m_SkipChar == L'\"') { | |
| 2298 m_pStart++; | |
| 2299 if (ch != m_SkipChar) { | |
| 2300 break; | |
| 2301 } | |
| 2302 m_SkipStack.Pop(); | |
| 2303 FX_DWORD* pDWord = m_SkipStack.GetTopElement(); | |
| 2304 if (pDWord == NULL) { | |
| 2305 m_dwMode = FDE_XMLSYNTAXMODE_Text; | |
| 2306 } else { | |
| 2307 m_SkipChar = (FX_WCHAR)*pDWord; | |
| 2308 } | |
| 2309 } else { | |
| 2310 switch (ch) { | |
| 2311 case L'<': | |
| 2312 m_SkipChar = L'>'; | |
| 2313 m_SkipStack.Push(L'>'); | |
| 2314 break; | |
| 2315 case L'[': | |
| 2316 m_SkipChar = L']'; | |
| 2317 m_SkipStack.Push(L']'); | |
| 2318 break; | |
| 2319 case L'(': | |
| 2320 m_SkipChar = L')'; | |
| 2321 m_SkipStack.Push(L')'); | |
| 2322 break; | |
| 2323 case L'\'': | |
| 2324 m_SkipChar = L'\''; | |
| 2325 m_SkipStack.Push(L'\''); | |
| 2326 break; | |
| 2327 case L'\"': | |
| 2328 m_SkipChar = L'\"'; | |
| 2329 m_SkipStack.Push(L'\"'); | |
| 2330 break; | |
| 2331 default: | |
| 2332 if (ch == m_SkipChar) { | |
| 2333 m_SkipStack.Pop(); | |
| 2334 FX_DWORD* pDWord = m_SkipStack.GetTopElement(); | |
| 2335 if (pDWord == NULL) { | |
| 2336 m_iTextDataLength = m_iDataPos; | |
| 2337 m_iDataPos = 0; | |
| 2338 if (m_iTextDataLength >= 9 && | |
| 2339 FXSYS_memcmp(m_pwsTextData, L"[CDATA[", | |
| 2340 7 * sizeof(FX_WCHAR)) == 0 && | |
| 2341 FXSYS_memcmp(m_pwsTextData + m_iTextDataLength - 2, | |
| 2342 L"]]", 2 * sizeof(FX_WCHAR)) == 0) { | |
| 2343 m_iTextDataLength -= 9; | |
| 2344 FXSYS_memmove(m_pwsTextData, m_pwsTextData + 7, | |
| 2345 m_iTextDataLength * sizeof(FX_WCHAR)); | |
| 2346 dwStatus = FDE_XMLSYNTAXSTATUS_CData; | |
| 2347 } | |
| 2348 m_dwMode = FDE_XMLSYNTAXMODE_Text; | |
| 2349 } else { | |
| 2350 m_SkipChar = (FX_WCHAR)*pDWord; | |
| 2351 } | |
| 2352 } | |
| 2353 break; | |
| 2354 } | |
| 2355 if (m_SkipStack.GetSize() > 0) { | |
| 2356 if (m_iDataPos >= m_iTextDataSize) { | |
| 2357 ReallocTextDataBuffer(); | |
| 2358 } | |
| 2359 m_pwsTextData[m_iDataPos++] = ch; | |
| 2360 } | |
| 2361 m_pStart++; | |
| 2362 } | |
| 2363 break; | |
| 2364 case FDE_XMLSYNTAXMODE_SkipComment: | |
| 2365 if (ch == L'-') { | |
| 2366 m_iDataPos++; | |
| 2367 } else if (ch == L'>') { | |
| 2368 if (m_iDataPos > 1) { | |
| 2369 m_iDataPos = 0; | |
| 2370 m_dwMode = FDE_XMLSYNTAXMODE_Text; | |
| 2371 } | |
| 2372 } else { | |
| 2373 m_iDataPos = 0; | |
| 2374 } | |
| 2375 m_pStart++; | |
| 2376 break; | |
| 2377 case FDE_XMLSYNTAXMODE_TargetData: | |
| 2378 if (FDE_IsXMLWhiteSpace(ch)) { | |
| 2379 if (m_iDataPos < 1) { | |
| 2380 m_pStart++; | |
| 2381 break; | |
| 2382 } else if (m_wQuotationMark == 0) { | |
| 2383 m_iTextDataLength = m_iDataPos; | |
| 2384 m_wQuotationMark = 0; | |
| 2385 m_iDataPos = 0; | |
| 2386 m_pStart++; | |
| 2387 dwStatus = FDE_XMLSYNTAXSTATUS_TargetData; | |
| 2388 break; | |
| 2389 } | |
| 2390 } | |
| 2391 if (ch == '?') { | |
| 2392 m_dwMode = FDE_XMLSYNTAXMODE_CloseInstruction; | |
| 2393 m_pStart++; | |
| 2394 } else if (ch == '\"') { | |
| 2395 if (m_wQuotationMark == 0) { | |
| 2396 m_wQuotationMark = ch; | |
| 2397 m_pStart++; | |
| 2398 } else if (ch == m_wQuotationMark) { | |
| 2399 m_iTextDataLength = m_iDataPos; | |
| 2400 m_wQuotationMark = 0; | |
| 2401 m_iDataPos = 0; | |
| 2402 m_pStart++; | |
| 2403 dwStatus = FDE_XMLSYNTAXSTATUS_TargetData; | |
| 2404 } else { | |
| 2405 m_dwStatus = FDE_XMLSYNTAXSTATUS_Error; | |
| 2406 return m_dwStatus; | |
| 2407 } | |
| 2408 } else { | |
| 2409 if (m_iDataPos >= m_iTextDataSize) { | |
| 2410 ReallocTextDataBuffer(); | |
| 2411 } | |
| 2412 m_pwsTextData[m_iDataPos++] = ch; | |
| 2413 m_pStart++; | |
| 2414 } | |
| 2415 break; | |
| 2416 default: | |
| 2417 break; | |
| 2418 } | |
| 2419 if (dwStatus != FDE_XMLSYNTAXSTATUS_None) { | |
| 2420 return dwStatus; | |
| 2421 } | |
| 2422 } | |
| 2423 } | |
| 2424 return 0; | |
| 2425 } | |
| 2426 #endif | |
| 2427 CFDE_XMLSyntaxParser::~CFDE_XMLSyntaxParser() { | 1966 CFDE_XMLSyntaxParser::~CFDE_XMLSyntaxParser() { |
| 2428 #ifdef _FDE_BLOCK_BUFFER | |
| 2429 if (m_pCurrentBlock) { | 1967 if (m_pCurrentBlock) { |
| 2430 m_pCurrentBlock = NULL; | 1968 m_pCurrentBlock = NULL; |
| 2431 } | 1969 } |
| 2432 #else | |
| 2433 FX_Free(m_pwsTextData); | |
| 2434 #endif | |
| 2435 FX_Free(m_pBuffer); | 1970 FX_Free(m_pBuffer); |
| 2436 } | 1971 } |
| 1972 |
| 2437 int32_t CFDE_XMLSyntaxParser::GetStatus() const { | 1973 int32_t CFDE_XMLSyntaxParser::GetStatus() const { |
| 2438 if (m_pStream == NULL) { | 1974 if (m_pStream == NULL) { |
| 2439 return -1; | 1975 return -1; |
| 2440 } | 1976 } |
| 2441 int32_t iStreamLength = m_pStream->GetLength(); | 1977 int32_t iStreamLength = m_pStream->GetLength(); |
| 2442 if (iStreamLength < 1) { | 1978 if (iStreamLength < 1) { |
| 2443 return 100; | 1979 return 100; |
| 2444 } | 1980 } |
| 2445 if (m_dwStatus == FDE_XMLSYNTAXSTATUS_Error) { | 1981 if (m_dwStatus == FDE_XMLSYNTAXSTATUS_Error) { |
| 2446 return -1; | 1982 return -1; |
| (...skipping 27 matching lines...) Expand all Loading... |
| 2474 return iDstNum; | 2010 return iDstNum; |
| 2475 } | 2011 } |
| 2476 FX_FILESIZE CFDE_XMLSyntaxParser::GetCurrentBinaryPos() const { | 2012 FX_FILESIZE CFDE_XMLSyntaxParser::GetCurrentBinaryPos() const { |
| 2477 if (m_pStream == NULL) { | 2013 if (m_pStream == NULL) { |
| 2478 return 0; | 2014 return 0; |
| 2479 } | 2015 } |
| 2480 int32_t nSrcLen = m_pStart - m_pBuffer; | 2016 int32_t nSrcLen = m_pStart - m_pBuffer; |
| 2481 int32_t nDstLen = FX_GetUTF8EncodeLength(m_pBuffer, nSrcLen); | 2017 int32_t nDstLen = FX_GetUTF8EncodeLength(m_pBuffer, nSrcLen); |
| 2482 return m_iParsedBytes + nDstLen; | 2018 return m_iParsedBytes + nDstLen; |
| 2483 } | 2019 } |
| 2484 #ifdef _FDE_BLOCK_BUFFER | 2020 |
| 2485 void CFDE_XMLSyntaxParser::ParseTextChar(FX_WCHAR ch) { | 2021 void CFDE_XMLSyntaxParser::ParseTextChar(FX_WCHAR ch) { |
| 2486 if (m_iIndexInBlock == m_iAllocStep) { | 2022 if (m_iIndexInBlock == m_iAllocStep) { |
| 2487 m_pCurrentBlock = m_BlockBuffer.GetAvailableBlock(m_iIndexInBlock); | 2023 m_pCurrentBlock = m_BlockBuffer.GetAvailableBlock(m_iIndexInBlock); |
| 2488 if (!m_pCurrentBlock) { | 2024 if (!m_pCurrentBlock) { |
| 2489 return; | 2025 return; |
| 2490 } | 2026 } |
| 2491 } | 2027 } |
| 2492 m_pCurrentBlock[m_iIndexInBlock++] = ch; | 2028 m_pCurrentBlock[m_iIndexInBlock++] = ch; |
| 2493 m_iDataLength++; | 2029 m_iDataLength++; |
| 2494 if (m_iEntityStart > -1 && ch == L';') { | 2030 if (m_iEntityStart > -1 && ch == L';') { |
| (...skipping 53 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2548 m_BlockBuffer.DeleteTextChars(m_iDataLength - m_iEntityStart, FALSE); | 2084 m_BlockBuffer.DeleteTextChars(m_iDataLength - m_iEntityStart, FALSE); |
| 2549 m_pCurrentBlock = m_BlockBuffer.GetAvailableBlock(m_iIndexInBlock); | 2085 m_pCurrentBlock = m_BlockBuffer.GetAvailableBlock(m_iIndexInBlock); |
| 2550 m_iEntityStart = -1; | 2086 m_iEntityStart = -1; |
| 2551 } else { | 2087 } else { |
| 2552 if (m_iEntityStart < 0 && ch == L'&') { | 2088 if (m_iEntityStart < 0 && ch == L'&') { |
| 2553 m_iEntityStart = m_iDataLength - 1; | 2089 m_iEntityStart = m_iDataLength - 1; |
| 2554 } | 2090 } |
| 2555 } | 2091 } |
| 2556 m_pStart++; | 2092 m_pStart++; |
| 2557 } | 2093 } |
| 2558 #else | |
| 2559 void CFDE_XMLSyntaxParser::ParseTextChar(FX_WCHAR ch) { | |
| 2560 if (m_iDataPos >= m_iTextDataSize) { | |
| 2561 ReallocTextDataBuffer(); | |
| 2562 } | |
| 2563 m_pwsTextData[m_iDataPos] = ch; | |
| 2564 if (m_iEntityStart > -1 && ch == L';') { | |
| 2565 CFX_WideString csEntity(m_pwsTextData + m_iEntityStart + 1, | |
| 2566 m_iDataPos - m_iEntityStart - 1); | |
| 2567 int32_t iLen = csEntity.GetLength(); | |
| 2568 if (iLen > 0) { | |
| 2569 if (csEntity[0] == L'#') { | |
| 2570 ch = 0; | |
| 2571 FX_WCHAR w; | |
| 2572 if (iLen > 1 && csEntity[1] == L'x') { | |
| 2573 for (int32_t i = 2; i < iLen; i++) { | |
| 2574 w = csEntity[i]; | |
| 2575 if (w >= L'0' && w <= L'9') { | |
| 2576 ch = (ch << 4) + w - L'0'; | |
| 2577 } else if (w >= L'A' && w <= L'F') { | |
| 2578 ch = (ch << 4) + w - 55; | |
| 2579 } else if (w >= L'a' && w <= L'f') { | |
| 2580 ch = (ch << 4) + w - 87; | |
| 2581 } else { | |
| 2582 break; | |
| 2583 } | |
| 2584 } | |
| 2585 } else { | |
| 2586 for (int32_t i = 1; i < iLen; i++) { | |
| 2587 w = csEntity[i]; | |
| 2588 if (w < L'0' || w > L'9') { | |
| 2589 break; | |
| 2590 } | |
| 2591 ch = ch * 10 + w - L'0'; | |
| 2592 } | |
| 2593 } | |
| 2594 if (ch != 0) { | |
| 2595 m_pwsTextData[m_iEntityStart++] = ch; | |
| 2596 } | |
| 2597 } else { | |
| 2598 if (csEntity.Compare(L"amp") == 0) { | |
| 2599 m_pwsTextData[m_iEntityStart++] = L'&'; | |
| 2600 } else if (csEntity.Compare(L"lt") == 0) { | |
| 2601 m_pwsTextData[m_iEntityStart++] = L'<'; | |
| 2602 } else if (csEntity.Compare(L"gt") == 0) { | |
| 2603 m_pwsTextData[m_iEntityStart++] = L'>'; | |
| 2604 } else if (csEntity.Compare(L"apos") == 0) { | |
| 2605 m_pwsTextData[m_iEntityStart++] = L'\''; | |
| 2606 } else if (csEntity.Compare(L"quot") == 0) { | |
| 2607 m_pwsTextData[m_iEntityStart++] = L'\"'; | |
| 2608 } | |
| 2609 } | |
| 2610 } | |
| 2611 m_iDataPos = m_iEntityStart; | |
| 2612 m_iEntityStart = -1; | |
| 2613 } else { | |
| 2614 if (m_iEntityStart < 0 && ch == L'&') { | |
| 2615 m_iEntityStart = m_iDataPos; | |
| 2616 } | |
| 2617 m_iDataPos++; | |
| 2618 } | |
| 2619 m_pStart++; | |
| 2620 } | |
| 2621 void CFDE_XMLSyntaxParser::ReallocTextDataBuffer() { | |
| 2622 FXSYS_assert(m_pwsTextData != NULL); | |
| 2623 if (m_iTextDataSize <= 1024 * 1024) { | |
| 2624 m_iTextDataSize *= 2; | |
| 2625 } else { | |
| 2626 m_iTextDataSize += 1024 * 1024; | |
| 2627 } | |
| 2628 m_pwsTextData = FX_Realloc(FX_WCHAR, m_pwsTextData, m_iTextDataSize); | |
| 2629 } | |
| 2630 void CFDE_XMLSyntaxParser::GetData(CFX_WideString& wsData) const { | |
| 2631 FX_WCHAR* pBuf = wsData.GetBuffer(m_iTextDataLength); | |
| 2632 FXSYS_memcpy(pBuf, m_pwsTextData, m_iTextDataLength * sizeof(FX_WCHAR)); | |
| 2633 wsData.ReleaseBuffer(m_iTextDataLength); | |
| 2634 } | |
| 2635 #endif | |
| OLD | NEW |