| 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 "../../include/fxcrt/fx_xml.h" | 7 #include "../../include/fxcrt/fx_xml.h" |
| 8 #include "xml_int.h" | 8 #include "xml_int.h" |
| 9 CXML_Parser::~CXML_Parser() | 9 CXML_Parser::~CXML_Parser() { |
| 10 { | 10 if (m_bOwnedStream) { |
| 11 if (m_bOwnedStream) { | 11 m_pDataAcc->Release(); |
| 12 m_pDataAcc->Release(); | 12 } |
| 13 } | 13 } |
| 14 } | 14 FX_BOOL CXML_Parser::Init(uint8_t* pBuffer, size_t size) { |
| 15 FX_BOOL CXML_Parser::Init(uint8_t* pBuffer, size_t size) | 15 m_pDataAcc = new CXML_DataBufAcc(pBuffer, size); |
| 16 { | 16 return Init(TRUE); |
| 17 m_pDataAcc = new CXML_DataBufAcc(pBuffer, size); | 17 } |
| 18 return Init(TRUE); | 18 FX_BOOL CXML_Parser::Init(IFX_FileRead* pFileRead) { |
| 19 } | 19 m_pDataAcc = new CXML_DataStmAcc(pFileRead); |
| 20 FX_BOOL CXML_Parser::Init(IFX_FileRead *pFileRead) | 20 return Init(TRUE); |
| 21 { | 21 } |
| 22 m_pDataAcc = new CXML_DataStmAcc(pFileRead); | 22 FX_BOOL CXML_Parser::Init(IFX_BufferRead* pBuffer) { |
| 23 return Init(TRUE); | 23 if (!pBuffer) { |
| 24 } | 24 return FALSE; |
| 25 FX_BOOL CXML_Parser::Init(IFX_BufferRead *pBuffer) | 25 } |
| 26 { | 26 m_pDataAcc = pBuffer; |
| 27 if (!pBuffer) { | 27 return Init(FALSE); |
| 28 return FALSE; | 28 } |
| 29 } | 29 FX_BOOL CXML_Parser::Init(FX_BOOL bOwndedStream) { |
| 30 m_pDataAcc = pBuffer; | 30 m_bOwnedStream = bOwndedStream; |
| 31 return Init(FALSE); | 31 m_nOffset = 0; |
| 32 } | 32 return ReadNextBlock(); |
| 33 FX_BOOL CXML_Parser::Init(FX_BOOL bOwndedStream) | 33 } |
| 34 { | 34 FX_BOOL CXML_Parser::ReadNextBlock() { |
| 35 m_bOwnedStream = bOwndedStream; | 35 if (!m_pDataAcc->ReadNextBlock()) { |
| 36 m_nOffset = 0; | 36 return FALSE; |
| 37 return ReadNextBlock(); | 37 } |
| 38 } | 38 m_pBuffer = m_pDataAcc->GetBlockBuffer(); |
| 39 FX_BOOL CXML_Parser::ReadNextBlock() | 39 m_dwBufferSize = m_pDataAcc->GetBlockSize(); |
| 40 { | 40 m_nBufferOffset = m_pDataAcc->GetBlockOffset(); |
| 41 if (!m_pDataAcc->ReadNextBlock()) { | 41 m_dwIndex = 0; |
| 42 return FALSE; | 42 return m_dwBufferSize > 0; |
| 43 } | 43 } |
| 44 m_pBuffer = m_pDataAcc->GetBlockBuffer(); | 44 FX_BOOL CXML_Parser::IsEOF() { |
| 45 m_dwBufferSize = m_pDataAcc->GetBlockSize(); | 45 if (!m_pDataAcc->IsEOF()) { |
| 46 m_nBufferOffset = m_pDataAcc->GetBlockOffset(); | 46 return FALSE; |
| 47 m_dwIndex = 0; | 47 } |
| 48 return m_dwBufferSize > 0; | 48 return m_dwIndex >= m_dwBufferSize; |
| 49 } | 49 } |
| 50 FX_BOOL CXML_Parser::IsEOF() | 50 #define FXCRTM_XML_CHARTYPE_Normal 0x00 |
| 51 { | 51 #define FXCRTM_XML_CHARTYPE_SpaceChar 0x01 |
| 52 if (!m_pDataAcc->IsEOF()) { | 52 #define FXCRTM_XML_CHARTYPE_Letter 0x02 |
| 53 return FALSE; | 53 #define FXCRTM_XML_CHARTYPE_Digital 0x04 |
| 54 } | 54 #define FXCRTM_XML_CHARTYPE_NameIntro 0x08 |
| 55 return m_dwIndex >= m_dwBufferSize; | 55 #define FXCRTM_XML_CHARTYPE_NameChar 0x10 |
| 56 } | 56 #define FXCRTM_XML_CHARTYPE_HexDigital 0x20 |
| 57 #define FXCRTM_XML_CHARTYPE_Normal» » » 0x00 | 57 #define FXCRTM_XML_CHARTYPE_HexLowerLetter 0x40 |
| 58 #define FXCRTM_XML_CHARTYPE_SpaceChar» » 0x01 | 58 #define FXCRTM_XML_CHARTYPE_HexUpperLetter 0x60 |
| 59 #define FXCRTM_XML_CHARTYPE_Letter» » » 0x02 | 59 #define FXCRTM_XML_CHARTYPE_HexChar 0x60 |
| 60 #define FXCRTM_XML_CHARTYPE_Digital» » » 0x04 | |
| 61 #define FXCRTM_XML_CHARTYPE_NameIntro» » 0x08 | |
| 62 #define FXCRTM_XML_CHARTYPE_NameChar» » 0x10 | |
| 63 #define FXCRTM_XML_CHARTYPE_HexDigital» » 0x20 | |
| 64 #define FXCRTM_XML_CHARTYPE_HexLowerLetter» 0x40 | |
| 65 #define FXCRTM_XML_CHARTYPE_HexUpperLetter» 0x60 | |
| 66 #define FXCRTM_XML_CHARTYPE_HexChar» » » 0x60 | |
| 67 uint8_t g_FXCRT_XML_ByteTypes[256] = { | 60 uint8_t g_FXCRT_XML_ByteTypes[256] = { |
| 68 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01
, 0x01, 0x01, 0x01, | 61 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, |
| 69 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01
, 0x01, 0x01, 0x01, | 62 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, |
| 70 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
, 0x10, 0x10, 0x00, | 63 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x00, 0x00, 0x00, |
| 71 0x34, 0x34, 0x34, 0x34, 0x34, 0x34, 0x34, 0x34, 0x34, 0x34, 0x08, 0x00, 0x00
, 0x00, 0x00, 0x00, | 64 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x10, 0x00, |
| 72 0x00, 0x7A, 0x7A, 0x7A, 0x7A, 0x7A, 0x7A, 0x1A, 0x1A, 0x1A, 0x1A, 0x1A, 0x1A
, 0x1A, 0x1A, 0x1A, | 65 0x34, 0x34, 0x34, 0x34, 0x34, 0x34, 0x34, 0x34, 0x34, 0x34, 0x08, 0x00, |
| 73 0x1A, 0x1A, 0x1A, 0x1A, 0x1A, 0x1A, 0x1A, 0x1A, 0x1A, 0x1A, 0x1A, 0x00, 0x00
, 0x00, 0x00, 0x18, | 66 0x00, 0x00, 0x00, 0x00, 0x00, 0x7A, 0x7A, 0x7A, 0x7A, 0x7A, 0x7A, 0x1A, |
| 74 0x00, 0x5A, 0x5A, 0x5A, 0x5A, 0x5A, 0x5A, 0x1A, 0x1A, 0x1A, 0x1A, 0x1A, 0x1A
, 0x1A, 0x1A, 0x1A, | 67 0x1A, 0x1A, 0x1A, 0x1A, 0x1A, 0x1A, 0x1A, 0x1A, 0x1A, 0x1A, 0x1A, 0x1A, |
| 75 0x1A, 0x1A, 0x1A, 0x1A, 0x1A, 0x1A, 0x1A, 0x1A, 0x1A, 0x1A, 0x1A, 0x00, 0x00
, 0x00, 0x00, 0x00, | 68 0x1A, 0x1A, 0x1A, 0x1A, 0x1A, 0x1A, 0x1A, 0x00, 0x00, 0x00, 0x00, 0x18, |
| 76 0x1A, 0x1A, 0x1A, 0x1A, 0x1A, 0x1A, 0x1A, 0x1A, 0x1A, 0x1A, 0x1A, 0x1A, 0x1A
, 0x1A, 0x1A, 0x1A, | 69 0x00, 0x5A, 0x5A, 0x5A, 0x5A, 0x5A, 0x5A, 0x1A, 0x1A, 0x1A, 0x1A, 0x1A, |
| 77 0x1A, 0x1A, 0x1A, 0x1A, 0x1A, 0x1A, 0x1A, 0x1A, 0x1A, 0x1A, 0x1A, 0x1A, 0x1A
, 0x1A, 0x1A, 0x1A, | 70 0x1A, 0x1A, 0x1A, 0x1A, 0x1A, 0x1A, 0x1A, 0x1A, 0x1A, 0x1A, 0x1A, 0x1A, |
| 78 0x1A, 0x1A, 0x1A, 0x1A, 0x1A, 0x1A, 0x1A, 0x1A, 0x1A, 0x1A, 0x1A, 0x1A, 0x1A
, 0x1A, 0x1A, 0x1A, | 71 0x1A, 0x1A, 0x1A, 0x00, 0x00, 0x00, 0x00, 0x00, 0x1A, 0x1A, 0x1A, 0x1A, |
| 79 0x1A, 0x1A, 0x1A, 0x1A, 0x1A, 0x1A, 0x1A, 0x1A, 0x1A, 0x1A, 0x1A, 0x1A, 0x1A
, 0x1A, 0x1A, 0x1A, | 72 0x1A, 0x1A, 0x1A, 0x1A, 0x1A, 0x1A, 0x1A, 0x1A, 0x1A, 0x1A, 0x1A, 0x1A, |
| 80 0x1A, 0x1A, 0x1A, 0x1A, 0x1A, 0x1A, 0x1A, 0x1A, 0x1A, 0x1A, 0x1A, 0x1A, 0x1A
, 0x1A, 0x1A, 0x1A, | 73 0x1A, 0x1A, 0x1A, 0x1A, 0x1A, 0x1A, 0x1A, 0x1A, 0x1A, 0x1A, 0x1A, 0x1A, |
| 81 0x1A, 0x1A, 0x1A, 0x1A, 0x1A, 0x1A, 0x1A, 0x1A, 0x1A, 0x1A, 0x1A, 0x1A, 0x1A
, 0x1A, 0x1A, 0x1A, | 74 0x1A, 0x1A, 0x1A, 0x1A, 0x1A, 0x1A, 0x1A, 0x1A, 0x1A, 0x1A, 0x1A, 0x1A, |
| 82 0x1A, 0x1A, 0x1A, 0x1A, 0x1A, 0x1A, 0x1A, 0x1A, 0x1A, 0x1A, 0x1A, 0x1A, 0x1A
, 0x1A, 0x1A, 0x1A, | 75 0x1A, 0x1A, 0x1A, 0x1A, 0x1A, 0x1A, 0x1A, 0x1A, 0x1A, 0x1A, 0x1A, 0x1A, |
| 83 0x1A, 0x1A, 0x1A, 0x1A, 0x1A, 0x1A, 0x1A, 0x1A, 0x1A, 0x1A, 0x1A, 0x1A, 0x1A
, 0x1A, 0x01, 0x01, | 76 0x1A, 0x1A, 0x1A, 0x1A, 0x1A, 0x1A, 0x1A, 0x1A, 0x1A, 0x1A, 0x1A, 0x1A, |
| 77 0x1A, 0x1A, 0x1A, 0x1A, 0x1A, 0x1A, 0x1A, 0x1A, 0x1A, 0x1A, 0x1A, 0x1A, |
| 78 0x1A, 0x1A, 0x1A, 0x1A, 0x1A, 0x1A, 0x1A, 0x1A, 0x1A, 0x1A, 0x1A, 0x1A, |
| 79 0x1A, 0x1A, 0x1A, 0x1A, 0x1A, 0x1A, 0x1A, 0x1A, 0x1A, 0x1A, 0x1A, 0x1A, |
| 80 0x1A, 0x1A, 0x1A, 0x1A, 0x1A, 0x1A, 0x1A, 0x1A, 0x1A, 0x1A, 0x1A, 0x1A, |
| 81 0x1A, 0x1A, 0x1A, 0x1A, 0x1A, 0x1A, 0x1A, 0x1A, 0x1A, 0x1A, 0x1A, 0x1A, |
| 82 0x1A, 0x1A, 0x01, 0x01, |
| 84 }; | 83 }; |
| 85 FX_BOOL g_FXCRT_XML_IsWhiteSpace(uint8_t ch) | 84 FX_BOOL g_FXCRT_XML_IsWhiteSpace(uint8_t ch) { |
| 86 { | 85 return (g_FXCRT_XML_ByteTypes[ch] & FXCRTM_XML_CHARTYPE_SpaceChar) != 0; |
| 87 return (g_FXCRT_XML_ByteTypes[ch] & FXCRTM_XML_CHARTYPE_SpaceChar) != 0; | 86 } |
| 88 } | 87 FX_BOOL g_FXCRT_XML_IsLetter(uint8_t ch) { |
| 89 FX_BOOL g_FXCRT_XML_IsLetter(uint8_t ch) | 88 return (g_FXCRT_XML_ByteTypes[ch] & FXCRTM_XML_CHARTYPE_Letter) != 0; |
| 90 { | 89 } |
| 91 return (g_FXCRT_XML_ByteTypes[ch] & FXCRTM_XML_CHARTYPE_Letter) != 0; | 90 FX_BOOL g_FXCRT_XML_IsDigital(uint8_t ch) { |
| 92 } | 91 return (g_FXCRT_XML_ByteTypes[ch] & FXCRTM_XML_CHARTYPE_Digital) != 0; |
| 93 FX_BOOL g_FXCRT_XML_IsDigital(uint8_t ch) | 92 } |
| 94 { | 93 FX_BOOL g_FXCRT_XML_IsNameIntro(uint8_t ch) { |
| 95 return (g_FXCRT_XML_ByteTypes[ch] & FXCRTM_XML_CHARTYPE_Digital) != 0; | 94 return (g_FXCRT_XML_ByteTypes[ch] & FXCRTM_XML_CHARTYPE_NameIntro) != 0; |
| 96 } | 95 } |
| 97 FX_BOOL g_FXCRT_XML_IsNameIntro(uint8_t ch) | 96 FX_BOOL g_FXCRT_XML_IsNameChar(uint8_t ch) { |
| 98 { | 97 return (g_FXCRT_XML_ByteTypes[ch] & FXCRTM_XML_CHARTYPE_NameChar) != 0; |
| 99 return (g_FXCRT_XML_ByteTypes[ch] & FXCRTM_XML_CHARTYPE_NameIntro) != 0; | 98 } |
| 100 } | 99 FX_BOOL g_FXCRT_XML_IsHexChar(uint8_t ch) { |
| 101 FX_BOOL g_FXCRT_XML_IsNameChar(uint8_t ch) | 100 return (g_FXCRT_XML_ByteTypes[ch] & FXCRTM_XML_CHARTYPE_HexChar) != 0; |
| 102 { | 101 } |
| 103 return (g_FXCRT_XML_ByteTypes[ch] & FXCRTM_XML_CHARTYPE_NameChar) != 0; | 102 void CXML_Parser::SkipWhiteSpaces() { |
| 104 } | 103 m_nOffset = m_nBufferOffset + (FX_FILESIZE)m_dwIndex; |
| 105 FX_BOOL g_FXCRT_XML_IsHexChar(uint8_t ch) | 104 if (IsEOF()) { |
| 106 { | 105 return; |
| 107 return (g_FXCRT_XML_ByteTypes[ch] & FXCRTM_XML_CHARTYPE_HexChar) != 0; | 106 } |
| 108 } | 107 do { |
| 109 void CXML_Parser::SkipWhiteSpaces() | 108 while (m_dwIndex < m_dwBufferSize && |
| 110 { | 109 g_FXCRT_XML_IsWhiteSpace(m_pBuffer[m_dwIndex])) { |
| 111 m_nOffset = m_nBufferOffset + (FX_FILESIZE)m_dwIndex; | 110 m_dwIndex++; |
| 112 if (IsEOF()) { | 111 } |
| 113 return; | 112 m_nOffset = m_nBufferOffset + (FX_FILESIZE)m_dwIndex; |
| 114 } | 113 if (m_dwIndex < m_dwBufferSize || IsEOF()) { |
| 115 do { | 114 break; |
| 116 while (m_dwIndex < m_dwBufferSize && g_FXCRT_XML_IsWhiteSpace(m_pBuffer[
m_dwIndex])) { | 115 } |
| 117 m_dwIndex ++; | 116 } while (ReadNextBlock()); |
| 117 } |
| 118 void CXML_Parser::GetName(CFX_ByteString& space, CFX_ByteString& name) { |
| 119 m_nOffset = m_nBufferOffset + (FX_FILESIZE)m_dwIndex; |
| 120 if (IsEOF()) { |
| 121 return; |
| 122 } |
| 123 CFX_ByteTextBuf buf; |
| 124 uint8_t ch; |
| 125 do { |
| 126 while (m_dwIndex < m_dwBufferSize) { |
| 127 ch = m_pBuffer[m_dwIndex]; |
| 128 if (ch == ':') { |
| 129 space = buf.GetByteString(); |
| 130 buf.Clear(); |
| 131 } else if (g_FXCRT_XML_IsNameChar(ch)) { |
| 132 buf.AppendChar(ch); |
| 133 } else { |
| 134 break; |
| 135 } |
| 136 m_dwIndex++; |
| 137 } |
| 138 m_nOffset = m_nBufferOffset + (FX_FILESIZE)m_dwIndex; |
| 139 if (m_dwIndex < m_dwBufferSize || IsEOF()) { |
| 140 break; |
| 141 } |
| 142 } while (ReadNextBlock()); |
| 143 name = buf.GetByteString(); |
| 144 } |
| 145 void CXML_Parser::SkipLiterals(const CFX_ByteStringC& str) { |
| 146 m_nOffset = m_nBufferOffset + (FX_FILESIZE)m_dwIndex; |
| 147 if (IsEOF()) { |
| 148 return; |
| 149 } |
| 150 int32_t i = 0, iLen = str.GetLength(); |
| 151 do { |
| 152 while (m_dwIndex < m_dwBufferSize) { |
| 153 if (str.GetAt(i) != m_pBuffer[m_dwIndex++]) { |
| 154 i = 0; |
| 155 } else { |
| 156 i++; |
| 157 if (i == iLen) { |
| 158 break; |
| 118 } | 159 } |
| 119 m_nOffset = m_nBufferOffset + (FX_FILESIZE)m_dwIndex; | 160 } |
| 120 if (m_dwIndex < m_dwBufferSize || IsEOF()) { | 161 } |
| 162 m_nOffset = m_nBufferOffset + (FX_FILESIZE)m_dwIndex; |
| 163 if (i == iLen) { |
| 164 return; |
| 165 } |
| 166 if (m_dwIndex < m_dwBufferSize || IsEOF()) { |
| 167 break; |
| 168 } |
| 169 } while (ReadNextBlock()); |
| 170 while (!m_pDataAcc->IsEOF()) { |
| 171 ReadNextBlock(); |
| 172 m_nOffset = m_nBufferOffset + (FX_FILESIZE)m_dwBufferSize; |
| 173 } |
| 174 m_dwIndex = m_dwBufferSize; |
| 175 } |
| 176 FX_DWORD CXML_Parser::GetCharRef() { |
| 177 m_nOffset = m_nBufferOffset + (FX_FILESIZE)m_dwIndex; |
| 178 if (IsEOF()) { |
| 179 return 0; |
| 180 } |
| 181 uint8_t ch; |
| 182 int32_t iState = 0; |
| 183 CFX_ByteTextBuf buf; |
| 184 FX_DWORD code = 0; |
| 185 do { |
| 186 while (m_dwIndex < m_dwBufferSize) { |
| 187 ch = m_pBuffer[m_dwIndex]; |
| 188 switch (iState) { |
| 189 case 0: |
| 190 if (ch == '#') { |
| 191 m_dwIndex++; |
| 192 iState = 2; |
| 121 break; | 193 break; |
| 194 } |
| 195 iState = 1; |
| 196 case 1: |
| 197 m_dwIndex++; |
| 198 if (ch == ';') { |
| 199 CFX_ByteStringC ref = buf.GetByteString(); |
| 200 if (ref == FX_BSTRC("gt")) { |
| 201 code = '>'; |
| 202 } else if (ref == FX_BSTRC("lt")) { |
| 203 code = '<'; |
| 204 } else if (ref == FX_BSTRC("amp")) { |
| 205 code = '&'; |
| 206 } else if (ref == FX_BSTRC("apos")) { |
| 207 code = '\''; |
| 208 } else if (ref == FX_BSTRC("quot")) { |
| 209 code = '"'; |
| 210 } |
| 211 iState = 10; |
| 212 break; |
| 213 } |
| 214 buf.AppendByte(ch); |
| 215 break; |
| 216 case 2: |
| 217 if (ch == 'x') { |
| 218 m_dwIndex++; |
| 219 iState = 4; |
| 220 break; |
| 221 } |
| 222 iState = 3; |
| 223 case 3: |
| 224 m_dwIndex++; |
| 225 if (ch == ';') { |
| 226 iState = 10; |
| 227 break; |
| 228 } |
| 229 if (g_FXCRT_XML_IsDigital(ch)) { |
| 230 code = code * 10 + ch - '0'; |
| 231 } |
| 232 break; |
| 233 case 4: |
| 234 m_dwIndex++; |
| 235 if (ch == ';') { |
| 236 iState = 10; |
| 237 break; |
| 238 } |
| 239 uint8_t nHex = |
| 240 g_FXCRT_XML_ByteTypes[ch] & FXCRTM_XML_CHARTYPE_HexChar; |
| 241 if (nHex) { |
| 242 if (nHex == FXCRTM_XML_CHARTYPE_HexDigital) { |
| 243 code = (code << 4) + ch - '0'; |
| 244 } else if (nHex == FXCRTM_XML_CHARTYPE_HexLowerLetter) { |
| 245 code = (code << 4) + ch - 87; |
| 246 } else { |
| 247 code = (code << 4) + ch - 55; |
| 248 } |
| 249 } |
| 250 break; |
| 251 } |
| 252 if (iState == 10) { |
| 253 break; |
| 254 } |
| 255 } |
| 256 m_nOffset = m_nBufferOffset + (FX_FILESIZE)m_dwIndex; |
| 257 if (iState == 10 || m_dwIndex < m_dwBufferSize || IsEOF()) { |
| 258 break; |
| 259 } |
| 260 } while (ReadNextBlock()); |
| 261 return code; |
| 262 } |
| 263 void CXML_Parser::GetAttrValue(CFX_WideString& value) { |
| 264 m_nOffset = m_nBufferOffset + (FX_FILESIZE)m_dwIndex; |
| 265 if (IsEOF()) { |
| 266 return; |
| 267 } |
| 268 CFX_UTF8Decoder decoder; |
| 269 uint8_t mark = 0, ch = 0; |
| 270 do { |
| 271 while (m_dwIndex < m_dwBufferSize) { |
| 272 ch = m_pBuffer[m_dwIndex]; |
| 273 if (mark == 0) { |
| 274 if (ch != '\'' && ch != '"') { |
| 275 return; |
| 122 } | 276 } |
| 123 } while (ReadNextBlock()); | 277 mark = ch; |
| 124 } | 278 m_dwIndex++; |
| 125 void CXML_Parser::GetName(CFX_ByteString &space, CFX_ByteString &name) | 279 ch = 0; |
| 126 { | 280 continue; |
| 127 m_nOffset = m_nBufferOffset + (FX_FILESIZE)m_dwIndex; | 281 } |
| 128 if (IsEOF()) { | 282 m_dwIndex++; |
| 129 return; | 283 if (ch == mark) { |
| 130 } | 284 break; |
| 131 CFX_ByteTextBuf buf; | 285 } |
| 132 uint8_t ch; | 286 if (ch == '&') { |
| 133 do { | 287 decoder.AppendChar(GetCharRef()); |
| 134 while (m_dwIndex < m_dwBufferSize) { | 288 if (IsEOF()) { |
| 135 ch = m_pBuffer[m_dwIndex]; | 289 value = decoder.GetResult(); |
| 136 if (ch == ':') { | 290 return; |
| 137 space = buf.GetByteString(); | 291 } |
| 138 buf.Clear(); | 292 } else { |
| 139 } else if (g_FXCRT_XML_IsNameChar(ch)) { | 293 decoder.Input(ch); |
| 140 buf.AppendChar(ch); | 294 } |
| 141 } else { | 295 } |
| 142 break; | 296 m_nOffset = m_nBufferOffset + (FX_FILESIZE)m_dwIndex; |
| 297 if (ch == mark || m_dwIndex < m_dwBufferSize || IsEOF()) { |
| 298 break; |
| 299 } |
| 300 } while (ReadNextBlock()); |
| 301 value = decoder.GetResult(); |
| 302 } |
| 303 void CXML_Parser::GetTagName(CFX_ByteString& space, |
| 304 CFX_ByteString& name, |
| 305 FX_BOOL& bEndTag, |
| 306 FX_BOOL bStartTag) { |
| 307 m_nOffset = m_nBufferOffset + (FX_FILESIZE)m_dwIndex; |
| 308 if (IsEOF()) { |
| 309 return; |
| 310 } |
| 311 bEndTag = FALSE; |
| 312 uint8_t ch; |
| 313 int32_t iState = bStartTag ? 1 : 0; |
| 314 do { |
| 315 while (m_dwIndex < m_dwBufferSize) { |
| 316 ch = m_pBuffer[m_dwIndex]; |
| 317 switch (iState) { |
| 318 case 0: |
| 319 m_dwIndex++; |
| 320 if (ch != '<') { |
| 321 break; |
| 322 } |
| 323 iState = 1; |
| 324 break; |
| 325 case 1: |
| 326 if (ch == '?') { |
| 327 m_dwIndex++; |
| 328 SkipLiterals(FX_BSTRC("?>")); |
| 329 iState = 0; |
| 330 break; |
| 331 } else if (ch == '!') { |
| 332 m_dwIndex++; |
| 333 SkipLiterals(FX_BSTRC("-->")); |
| 334 iState = 0; |
| 335 break; |
| 336 } |
| 337 if (ch == '/') { |
| 338 m_dwIndex++; |
| 339 GetName(space, name); |
| 340 bEndTag = TRUE; |
| 341 } else { |
| 342 GetName(space, name); |
| 343 bEndTag = FALSE; |
| 344 } |
| 345 return; |
| 346 } |
| 347 } |
| 348 m_nOffset = m_nBufferOffset + (FX_FILESIZE)m_dwIndex; |
| 349 if (m_dwIndex < m_dwBufferSize || IsEOF()) { |
| 350 break; |
| 351 } |
| 352 } while (ReadNextBlock()); |
| 353 } |
| 354 CXML_Element* CXML_Parser::ParseElement(CXML_Element* pParent, |
| 355 FX_BOOL bStartTag) { |
| 356 m_nOffset = m_nBufferOffset + (FX_FILESIZE)m_dwIndex; |
| 357 if (IsEOF()) { |
| 358 return NULL; |
| 359 } |
| 360 CFX_ByteString tag_name, tag_space; |
| 361 FX_BOOL bEndTag; |
| 362 GetTagName(tag_space, tag_name, bEndTag, bStartTag); |
| 363 if (tag_name.IsEmpty() || bEndTag) { |
| 364 return NULL; |
| 365 } |
| 366 CXML_Element* pElement = new CXML_Element; |
| 367 pElement->m_pParent = pParent; |
| 368 pElement->SetTag(tag_space, tag_name); |
| 369 do { |
| 370 CFX_ByteString attr_space, attr_name; |
| 371 while (m_dwIndex < m_dwBufferSize) { |
| 372 SkipWhiteSpaces(); |
| 373 if (IsEOF()) { |
| 374 break; |
| 375 } |
| 376 if (!g_FXCRT_XML_IsNameIntro(m_pBuffer[m_dwIndex])) { |
| 377 break; |
| 378 } |
| 379 GetName(attr_space, attr_name); |
| 380 SkipWhiteSpaces(); |
| 381 if (IsEOF()) { |
| 382 break; |
| 383 } |
| 384 if (m_pBuffer[m_dwIndex] != '=') { |
| 385 break; |
| 386 } |
| 387 m_dwIndex++; |
| 388 SkipWhiteSpaces(); |
| 389 if (IsEOF()) { |
| 390 break; |
| 391 } |
| 392 CFX_WideString attr_value; |
| 393 GetAttrValue(attr_value); |
| 394 pElement->m_AttrMap.SetAt(attr_space, attr_name, attr_value); |
| 395 } |
| 396 m_nOffset = m_nBufferOffset + (FX_FILESIZE)m_dwIndex; |
| 397 if (m_dwIndex < m_dwBufferSize || IsEOF()) { |
| 398 break; |
| 399 } |
| 400 } while (ReadNextBlock()); |
| 401 SkipWhiteSpaces(); |
| 402 if (IsEOF()) { |
| 403 return pElement; |
| 404 } |
| 405 uint8_t ch = m_pBuffer[m_dwIndex++]; |
| 406 if (ch == '/') { |
| 407 m_dwIndex++; |
| 408 m_nOffset = m_nBufferOffset + (FX_FILESIZE)m_dwIndex; |
| 409 return pElement; |
| 410 } |
| 411 if (ch != '>') { |
| 412 m_nOffset = m_nBufferOffset + (FX_FILESIZE)m_dwIndex; |
| 413 delete pElement; |
| 414 return NULL; |
| 415 } |
| 416 SkipWhiteSpaces(); |
| 417 if (IsEOF()) { |
| 418 return pElement; |
| 419 } |
| 420 CFX_UTF8Decoder decoder; |
| 421 CFX_WideTextBuf content; |
| 422 FX_BOOL bCDATA = FALSE; |
| 423 int32_t iState = 0; |
| 424 do { |
| 425 while (m_dwIndex < m_dwBufferSize) { |
| 426 ch = m_pBuffer[m_dwIndex++]; |
| 427 switch (iState) { |
| 428 case 0: |
| 429 if (ch == '<') { |
| 430 iState = 1; |
| 431 } else if (ch == '&') { |
| 432 decoder.ClearStatus(); |
| 433 decoder.AppendChar(GetCharRef()); |
| 434 } else { |
| 435 decoder.Input(ch); |
| 436 } |
| 437 break; |
| 438 case 1: |
| 439 if (ch == '!') { |
| 440 iState = 2; |
| 441 } else if (ch == '?') { |
| 442 SkipLiterals(FX_BSTRC("?>")); |
| 443 SkipWhiteSpaces(); |
| 444 iState = 0; |
| 445 } else if (ch == '/') { |
| 446 CFX_ByteString space, name; |
| 447 GetName(space, name); |
| 448 SkipWhiteSpaces(); |
| 449 m_dwIndex++; |
| 450 iState = 10; |
| 451 } else { |
| 452 content << decoder.GetResult(); |
| 453 CFX_WideString dataStr = content.GetWideString(); |
| 454 if (!bCDATA && !m_bSaveSpaceChars) { |
| 455 dataStr.TrimRight(L" \t\r\n"); |
| 143 } | 456 } |
| 144 m_dwIndex ++; | 457 InsertContentSegment(bCDATA, dataStr, pElement); |
| 145 } | 458 content.Clear(); |
| 146 m_nOffset = m_nBufferOffset + (FX_FILESIZE)m_dwIndex; | 459 decoder.Clear(); |
| 147 if (m_dwIndex < m_dwBufferSize || IsEOF()) { | 460 bCDATA = FALSE; |
| 148 break; | 461 iState = 0; |
| 149 } | 462 m_dwIndex--; |
| 150 } while (ReadNextBlock()); | 463 CXML_Element* pSubElement = ParseElement(pElement, TRUE); |
| 151 name = buf.GetByteString(); | 464 if (pSubElement == NULL) { |
| 152 } | 465 break; |
| 153 void CXML_Parser::SkipLiterals(const CFX_ByteStringC& str) | |
| 154 { | |
| 155 m_nOffset = m_nBufferOffset + (FX_FILESIZE)m_dwIndex; | |
| 156 if (IsEOF()) { | |
| 157 return; | |
| 158 } | |
| 159 int32_t i = 0, iLen = str.GetLength(); | |
| 160 do { | |
| 161 while (m_dwIndex < m_dwBufferSize) { | |
| 162 if (str.GetAt(i) != m_pBuffer[m_dwIndex ++]) { | |
| 163 i = 0; | |
| 164 } else { | |
| 165 i ++; | |
| 166 if (i == iLen) { | |
| 167 break; | |
| 168 } | |
| 169 } | 466 } |
| 170 } | 467 pSubElement->m_pParent = pElement; |
| 171 m_nOffset = m_nBufferOffset + (FX_FILESIZE)m_dwIndex; | 468 pElement->m_Children.Add((void*)CXML_Element::Element); |
| 172 if (i == iLen) { | 469 pElement->m_Children.Add(pSubElement); |
| 173 return; | |
| 174 } | |
| 175 if (m_dwIndex < m_dwBufferSize || IsEOF()) { | |
| 176 break; | |
| 177 } | |
| 178 } while (ReadNextBlock()); | |
| 179 while (!m_pDataAcc->IsEOF()) { | |
| 180 ReadNextBlock(); | |
| 181 m_nOffset = m_nBufferOffset + (FX_FILESIZE)m_dwBufferSize; | |
| 182 } | |
| 183 m_dwIndex = m_dwBufferSize; | |
| 184 } | |
| 185 FX_DWORD CXML_Parser::GetCharRef() | |
| 186 { | |
| 187 m_nOffset = m_nBufferOffset + (FX_FILESIZE)m_dwIndex; | |
| 188 if (IsEOF()) { | |
| 189 return 0; | |
| 190 } | |
| 191 uint8_t ch; | |
| 192 int32_t iState = 0; | |
| 193 CFX_ByteTextBuf buf; | |
| 194 FX_DWORD code = 0; | |
| 195 do { | |
| 196 while (m_dwIndex < m_dwBufferSize) { | |
| 197 ch = m_pBuffer[m_dwIndex]; | |
| 198 switch (iState) { | |
| 199 case 0: | |
| 200 if (ch == '#') { | |
| 201 m_dwIndex ++; | |
| 202 iState = 2; | |
| 203 break; | |
| 204 } | |
| 205 iState = 1; | |
| 206 case 1: | |
| 207 m_dwIndex ++; | |
| 208 if (ch == ';') { | |
| 209 CFX_ByteStringC ref = buf.GetByteString(); | |
| 210 if (ref == FX_BSTRC("gt")) { | |
| 211 code = '>'; | |
| 212 } else if (ref == FX_BSTRC("lt")) { | |
| 213 code = '<'; | |
| 214 } else if (ref == FX_BSTRC("amp")) { | |
| 215 code = '&'; | |
| 216 } else if (ref == FX_BSTRC("apos")) { | |
| 217 code = '\''; | |
| 218 } else if (ref == FX_BSTRC("quot")) { | |
| 219 code = '"'; | |
| 220 } | |
| 221 iState = 10; | |
| 222 break; | |
| 223 } | |
| 224 buf.AppendByte(ch); | |
| 225 break; | |
| 226 case 2: | |
| 227 if (ch == 'x') { | |
| 228 m_dwIndex ++; | |
| 229 iState = 4; | |
| 230 break; | |
| 231 } | |
| 232 iState = 3; | |
| 233 case 3: | |
| 234 m_dwIndex ++; | |
| 235 if (ch == ';') { | |
| 236 iState = 10; | |
| 237 break; | |
| 238 } | |
| 239 if (g_FXCRT_XML_IsDigital(ch)) { | |
| 240 code = code * 10 + ch - '0'; | |
| 241 } | |
| 242 break; | |
| 243 case 4: | |
| 244 m_dwIndex ++; | |
| 245 if (ch == ';') { | |
| 246 iState = 10; | |
| 247 break; | |
| 248 } | |
| 249 uint8_t nHex = g_FXCRT_XML_ByteTypes[ch] & FXCRTM_XML_CHARTY
PE_HexChar; | |
| 250 if (nHex) { | |
| 251 if (nHex == FXCRTM_XML_CHARTYPE_HexDigital) { | |
| 252 code = (code << 4) + ch - '0'; | |
| 253 } else if (nHex == FXCRTM_XML_CHARTYPE_HexLowerLetter) { | |
| 254 code = (code << 4) + ch - 87; | |
| 255 } else { | |
| 256 code = (code << 4) + ch - 55; | |
| 257 } | |
| 258 } | |
| 259 break; | |
| 260 } | |
| 261 if (iState == 10) { | |
| 262 break; | |
| 263 } | |
| 264 } | |
| 265 m_nOffset = m_nBufferOffset + (FX_FILESIZE)m_dwIndex; | |
| 266 if (iState == 10 || m_dwIndex < m_dwBufferSize || IsEOF()) { | |
| 267 break; | |
| 268 } | |
| 269 } while (ReadNextBlock()); | |
| 270 return code; | |
| 271 } | |
| 272 void CXML_Parser::GetAttrValue(CFX_WideString &value) | |
| 273 { | |
| 274 m_nOffset = m_nBufferOffset + (FX_FILESIZE)m_dwIndex; | |
| 275 if (IsEOF()) { | |
| 276 return; | |
| 277 } | |
| 278 CFX_UTF8Decoder decoder; | |
| 279 uint8_t mark = 0, ch = 0; | |
| 280 do { | |
| 281 while (m_dwIndex < m_dwBufferSize) { | |
| 282 ch = m_pBuffer[m_dwIndex]; | |
| 283 if (mark == 0) { | |
| 284 if (ch != '\'' && ch != '"') { | |
| 285 return; | |
| 286 } | |
| 287 mark = ch; | |
| 288 m_dwIndex ++; | |
| 289 ch = 0; | |
| 290 continue; | |
| 291 } | |
| 292 m_dwIndex ++; | |
| 293 if (ch == mark) { | |
| 294 break; | |
| 295 } | |
| 296 if (ch == '&') { | |
| 297 decoder.AppendChar(GetCharRef()); | |
| 298 if (IsEOF()) { | |
| 299 value = decoder.GetResult(); | |
| 300 return; | |
| 301 } | |
| 302 } else { | |
| 303 decoder.Input(ch); | |
| 304 } | |
| 305 } | |
| 306 m_nOffset = m_nBufferOffset + (FX_FILESIZE)m_dwIndex; | |
| 307 if (ch == mark || m_dwIndex < m_dwBufferSize || IsEOF()) { | |
| 308 break; | |
| 309 } | |
| 310 } while (ReadNextBlock()); | |
| 311 value = decoder.GetResult(); | |
| 312 } | |
| 313 void CXML_Parser::GetTagName(CFX_ByteString &space, CFX_ByteString &name, FX_BOO
L &bEndTag, FX_BOOL bStartTag) | |
| 314 { | |
| 315 m_nOffset = m_nBufferOffset + (FX_FILESIZE)m_dwIndex; | |
| 316 if (IsEOF()) { | |
| 317 return; | |
| 318 } | |
| 319 bEndTag = FALSE; | |
| 320 uint8_t ch; | |
| 321 int32_t iState = bStartTag ? 1 : 0; | |
| 322 do { | |
| 323 while (m_dwIndex < m_dwBufferSize) { | |
| 324 ch = m_pBuffer[m_dwIndex]; | |
| 325 switch (iState) { | |
| 326 case 0: | |
| 327 m_dwIndex ++; | |
| 328 if (ch != '<') { | |
| 329 break; | |
| 330 } | |
| 331 iState = 1; | |
| 332 break; | |
| 333 case 1: | |
| 334 if (ch == '?') { | |
| 335 m_dwIndex ++; | |
| 336 SkipLiterals(FX_BSTRC("?>")); | |
| 337 iState = 0; | |
| 338 break; | |
| 339 } else if (ch == '!') { | |
| 340 m_dwIndex ++; | |
| 341 SkipLiterals(FX_BSTRC("-->")); | |
| 342 iState = 0; | |
| 343 break; | |
| 344 } | |
| 345 if (ch == '/') { | |
| 346 m_dwIndex ++; | |
| 347 GetName(space, name); | |
| 348 bEndTag = TRUE; | |
| 349 } else { | |
| 350 GetName(space, name); | |
| 351 bEndTag = FALSE; | |
| 352 } | |
| 353 return; | |
| 354 } | |
| 355 } | |
| 356 m_nOffset = m_nBufferOffset + (FX_FILESIZE)m_dwIndex; | |
| 357 if (m_dwIndex < m_dwBufferSize || IsEOF()) { | |
| 358 break; | |
| 359 } | |
| 360 } while (ReadNextBlock()); | |
| 361 } | |
| 362 CXML_Element* CXML_Parser::ParseElement(CXML_Element* pParent, FX_BOOL bStartTag
) | |
| 363 { | |
| 364 m_nOffset = m_nBufferOffset + (FX_FILESIZE)m_dwIndex; | |
| 365 if (IsEOF()) { | |
| 366 return NULL; | |
| 367 } | |
| 368 CFX_ByteString tag_name, tag_space; | |
| 369 FX_BOOL bEndTag; | |
| 370 GetTagName(tag_space, tag_name, bEndTag, bStartTag); | |
| 371 if (tag_name.IsEmpty() || bEndTag) { | |
| 372 return NULL; | |
| 373 } | |
| 374 CXML_Element* pElement = new CXML_Element; | |
| 375 pElement->m_pParent = pParent; | |
| 376 pElement->SetTag(tag_space, tag_name); | |
| 377 do { | |
| 378 CFX_ByteString attr_space, attr_name; | |
| 379 while (m_dwIndex < m_dwBufferSize) { | |
| 380 SkipWhiteSpaces(); | 470 SkipWhiteSpaces(); |
| 381 if (IsEOF()) { | 471 } |
| 382 break; | 472 break; |
| 383 } | 473 case 2: |
| 384 if (!g_FXCRT_XML_IsNameIntro(m_pBuffer[m_dwIndex])) { | 474 if (ch == '[') { |
| 385 break; | 475 SkipLiterals(FX_BSTRC("]]>")); |
| 386 } | 476 } else if (ch == '-') { |
| 387 GetName(attr_space, attr_name); | 477 m_dwIndex++; |
| 388 SkipWhiteSpaces(); | 478 SkipLiterals(FX_BSTRC("-->")); |
| 389 if (IsEOF()) { | 479 } else { |
| 390 break; | 480 SkipLiterals(FX_BSTRC(">")); |
| 391 } | 481 } |
| 392 if (m_pBuffer[m_dwIndex] != '=') { | 482 decoder.Clear(); |
| 393 break; | 483 SkipWhiteSpaces(); |
| 394 } | 484 iState = 0; |
| 395 m_dwIndex ++; | 485 break; |
| 396 SkipWhiteSpaces(); | 486 } |
| 397 if (IsEOF()) { | 487 if (iState == 10) { |
| 398 break; | 488 break; |
| 399 } | 489 } |
| 400 CFX_WideString attr_value; | 490 } |
| 401 GetAttrValue(attr_value); | 491 m_nOffset = m_nBufferOffset + (FX_FILESIZE)m_dwIndex; |
| 402 pElement->m_AttrMap.SetAt(attr_space, attr_name, attr_value); | 492 if (iState == 10 || m_dwIndex < m_dwBufferSize || IsEOF()) { |
| 403 } | 493 break; |
| 404 m_nOffset = m_nBufferOffset + (FX_FILESIZE)m_dwIndex; | 494 } |
| 405 if (m_dwIndex < m_dwBufferSize || IsEOF()) { | 495 } while (ReadNextBlock()); |
| 406 break; | 496 content << decoder.GetResult(); |
| 407 } | 497 CFX_WideString dataStr = content.GetWideString(); |
| 408 } while (ReadNextBlock()); | 498 if (!m_bSaveSpaceChars) { |
| 409 SkipWhiteSpaces(); | 499 dataStr.TrimRight(L" \t\r\n"); |
| 410 if (IsEOF()) { | 500 } |
| 411 return pElement; | 501 InsertContentSegment(bCDATA, dataStr, pElement); |
| 412 } | 502 content.Clear(); |
| 413 uint8_t ch = m_pBuffer[m_dwIndex ++]; | 503 decoder.Clear(); |
| 414 if (ch == '/') { | 504 bCDATA = FALSE; |
| 415 m_dwIndex ++; | 505 return pElement; |
| 416 m_nOffset = m_nBufferOffset + (FX_FILESIZE)m_dwIndex; | 506 } |
| 417 return pElement; | 507 void CXML_Parser::InsertContentSegment(FX_BOOL bCDATA, |
| 418 } | 508 const CFX_WideStringC& content, |
| 419 if (ch != '>') { | 509 CXML_Element* pElement) { |
| 420 m_nOffset = m_nBufferOffset + (FX_FILESIZE)m_dwIndex; | 510 if (content.IsEmpty()) { |
| 421 delete pElement; | 511 return; |
| 422 return NULL; | 512 } |
| 423 } | 513 CXML_Content* pContent = new CXML_Content; |
| 424 SkipWhiteSpaces(); | 514 pContent->Set(bCDATA, content); |
| 425 if (IsEOF()) { | 515 pElement->m_Children.Add((void*)CXML_Element::Content); |
| 426 return pElement; | 516 pElement->m_Children.Add(pContent); |
| 427 } | 517 } |
| 428 CFX_UTF8Decoder decoder; | 518 static CXML_Element* XML_ContinueParse(CXML_Parser& parser, |
| 429 CFX_WideTextBuf content; | 519 FX_BOOL bSaveSpaceChars, |
| 430 FX_BOOL bCDATA = FALSE; | 520 FX_FILESIZE* pParsedSize) { |
| 431 int32_t iState = 0; | 521 parser.m_bSaveSpaceChars = bSaveSpaceChars; |
| 432 do { | 522 CXML_Element* pElement = parser.ParseElement(NULL, FALSE); |
| 433 while (m_dwIndex < m_dwBufferSize) { | 523 if (pParsedSize) { |
| 434 ch = m_pBuffer[m_dwIndex ++]; | 524 *pParsedSize = parser.m_nOffset; |
| 435 switch (iState) { | 525 } |
| 436 case 0: | 526 return pElement; |
| 437 if (ch == '<') { | 527 } |
| 438 iState = 1; | 528 CXML_Element* CXML_Element::Parse(const void* pBuffer, |
| 439 } else if (ch == '&') { | 529 size_t size, |
| 440 decoder.ClearStatus(); | 530 FX_BOOL bSaveSpaceChars, |
| 441 decoder.AppendChar(GetCharRef()); | 531 FX_FILESIZE* pParsedSize) { |
| 442 } else { | 532 CXML_Parser parser; |
| 443 decoder.Input(ch); | 533 if (!parser.Init((uint8_t*)pBuffer, size)) { |
| 444 } | 534 return NULL; |
| 445 break; | 535 } |
| 446 case 1: | 536 return XML_ContinueParse(parser, bSaveSpaceChars, pParsedSize); |
| 447 if (ch == '!') { | 537 } |
| 448 iState = 2; | 538 CXML_Element* CXML_Element::Parse(IFX_FileRead* pFile, |
| 449 } else if (ch == '?') { | 539 FX_BOOL bSaveSpaceChars, |
| 450 SkipLiterals(FX_BSTRC("?>")); | 540 FX_FILESIZE* pParsedSize) { |
| 451 SkipWhiteSpaces(); | 541 CXML_Parser parser; |
| 452 iState = 0; | 542 if (!parser.Init(pFile)) { |
| 453 } else if (ch == '/') { | 543 return NULL; |
| 454 CFX_ByteString space, name; | 544 } |
| 455 GetName(space, name); | 545 return XML_ContinueParse(parser, bSaveSpaceChars, pParsedSize); |
| 456 SkipWhiteSpaces(); | 546 } |
| 457 m_dwIndex ++; | 547 CXML_Element* CXML_Element::Parse(IFX_BufferRead* pBuffer, |
| 458 iState = 10; | 548 FX_BOOL bSaveSpaceChars, |
| 459 } else { | 549 FX_FILESIZE* pParsedSize) { |
| 460 content << decoder.GetResult(); | 550 CXML_Parser parser; |
| 461 CFX_WideString dataStr = content.GetWideString(); | 551 if (!parser.Init(pBuffer)) { |
| 462 if (!bCDATA && !m_bSaveSpaceChars) { | 552 return NULL; |
| 463 dataStr.TrimRight(L" \t\r\n"); | 553 } |
| 464 } | 554 return XML_ContinueParse(parser, bSaveSpaceChars, pParsedSize); |
| 465 InsertContentSegment(bCDATA, dataStr, pElement); | 555 } |
| 466 content.Clear(); | 556 CXML_Element::CXML_Element() : m_QSpaceName(), m_TagName(), m_AttrMap() {} |
| 467 decoder.Clear(); | 557 CXML_Element::CXML_Element(const CFX_ByteStringC& qSpace, |
| 468 bCDATA = FALSE; | 558 const CFX_ByteStringC& tagName) |
| 469 iState = 0; | 559 : m_QSpaceName(), m_TagName(), m_AttrMap() { |
| 470 m_dwIndex --; | 560 m_QSpaceName = qSpace; |
| 471 CXML_Element* pSubElement = ParseElement(pElement, TRUE)
; | 561 m_TagName = tagName; |
| 472 if (pSubElement == NULL) { | |
| 473 break; | |
| 474 } | |
| 475 pSubElement->m_pParent = pElement; | |
| 476 pElement->m_Children.Add((void*)CXML_Element::Element); | |
| 477 pElement->m_Children.Add(pSubElement); | |
| 478 SkipWhiteSpaces(); | |
| 479 } | |
| 480 break; | |
| 481 case 2: | |
| 482 if (ch == '[') { | |
| 483 SkipLiterals(FX_BSTRC("]]>")); | |
| 484 } else if (ch == '-') { | |
| 485 m_dwIndex ++; | |
| 486 SkipLiterals(FX_BSTRC("-->")); | |
| 487 } else { | |
| 488 SkipLiterals(FX_BSTRC(">")); | |
| 489 } | |
| 490 decoder.Clear(); | |
| 491 SkipWhiteSpaces(); | |
| 492 iState = 0; | |
| 493 break; | |
| 494 } | |
| 495 if (iState == 10) { | |
| 496 break; | |
| 497 } | |
| 498 } | |
| 499 m_nOffset = m_nBufferOffset + (FX_FILESIZE)m_dwIndex; | |
| 500 if (iState == 10 || m_dwIndex < m_dwBufferSize || IsEOF()) { | |
| 501 break; | |
| 502 } | |
| 503 } while (ReadNextBlock()); | |
| 504 content << decoder.GetResult(); | |
| 505 CFX_WideString dataStr = content.GetWideString(); | |
| 506 if (!m_bSaveSpaceChars) { | |
| 507 dataStr.TrimRight(L" \t\r\n"); | |
| 508 } | |
| 509 InsertContentSegment(bCDATA, dataStr, pElement); | |
| 510 content.Clear(); | |
| 511 decoder.Clear(); | |
| 512 bCDATA = FALSE; | |
| 513 return pElement; | |
| 514 } | |
| 515 void CXML_Parser::InsertContentSegment(FX_BOOL bCDATA, const CFX_WideStringC& co
ntent, CXML_Element* pElement) | |
| 516 { | |
| 517 if (content.IsEmpty()) { | |
| 518 return; | |
| 519 } | |
| 520 CXML_Content* pContent = new CXML_Content; | |
| 521 pContent->Set(bCDATA, content); | |
| 522 pElement->m_Children.Add((void*)CXML_Element::Content); | |
| 523 pElement->m_Children.Add(pContent); | |
| 524 } | |
| 525 static CXML_Element* XML_ContinueParse(CXML_Parser &parser, FX_BOOL bSaveSpaceCh
ars, FX_FILESIZE* pParsedSize) | |
| 526 { | |
| 527 parser.m_bSaveSpaceChars = bSaveSpaceChars; | |
| 528 CXML_Element* pElement = parser.ParseElement(NULL, FALSE); | |
| 529 if (pParsedSize) { | |
| 530 *pParsedSize = parser.m_nOffset; | |
| 531 } | |
| 532 return pElement; | |
| 533 } | |
| 534 CXML_Element* CXML_Element::Parse(const void* pBuffer, size_t size, FX_BOOL bSav
eSpaceChars, FX_FILESIZE* pParsedSize) | |
| 535 { | |
| 536 CXML_Parser parser; | |
| 537 if (!parser.Init((uint8_t*)pBuffer, size)) { | |
| 538 return NULL; | |
| 539 } | |
| 540 return XML_ContinueParse(parser, bSaveSpaceChars, pParsedSize); | |
| 541 } | |
| 542 CXML_Element* CXML_Element::Parse(IFX_FileRead *pFile, FX_BOOL bSaveSpaceChars,
FX_FILESIZE* pParsedSize) | |
| 543 { | |
| 544 CXML_Parser parser; | |
| 545 if (!parser.Init(pFile)) { | |
| 546 return NULL; | |
| 547 } | |
| 548 return XML_ContinueParse(parser, bSaveSpaceChars, pParsedSize); | |
| 549 } | |
| 550 CXML_Element* CXML_Element::Parse(IFX_BufferRead *pBuffer, FX_BOOL bSaveSpaceCha
rs, FX_FILESIZE* pParsedSize) | |
| 551 { | |
| 552 CXML_Parser parser; | |
| 553 if (!parser.Init(pBuffer)) { | |
| 554 return NULL; | |
| 555 } | |
| 556 return XML_ContinueParse(parser, bSaveSpaceChars, pParsedSize); | |
| 557 } | |
| 558 CXML_Element::CXML_Element() | |
| 559 : m_QSpaceName() | |
| 560 , m_TagName() | |
| 561 , m_AttrMap() | |
| 562 { | |
| 563 } | |
| 564 CXML_Element::CXML_Element(const CFX_ByteStringC& qSpace, const CFX_ByteStringC&
tagName) | |
| 565 : m_QSpaceName() | |
| 566 , m_TagName() | |
| 567 , m_AttrMap() | |
| 568 { | |
| 569 m_QSpaceName = qSpace; | |
| 570 m_TagName = tagName; | |
| 571 } | 562 } |
| 572 CXML_Element::CXML_Element(const CFX_ByteStringC& qTagName) | 563 CXML_Element::CXML_Element(const CFX_ByteStringC& qTagName) |
| 573 : m_pParent(NULL) | 564 : m_pParent(NULL), m_QSpaceName(), m_TagName(), m_AttrMap() { |
| 574 , m_QSpaceName() | 565 SetTag(qTagName); |
| 575 , m_TagName() | 566 } |
| 576 , m_AttrMap() | 567 CXML_Element::~CXML_Element() { |
| 577 { | 568 Empty(); |
| 578 SetTag(qTagName); | 569 } |
| 579 } | 570 void CXML_Element::Empty() { |
| 580 CXML_Element::~CXML_Element() | 571 RemoveChildren(); |
| 581 { | 572 } |
| 582 Empty(); | 573 void CXML_Element::RemoveChildren() { |
| 583 } | 574 for (int i = 0; i < m_Children.GetSize(); i += 2) { |
| 584 void CXML_Element::Empty() | 575 ChildType type = (ChildType)(uintptr_t)m_Children.GetAt(i); |
| 585 { | 576 if (type == Content) { |
| 586 RemoveChildren(); | 577 CXML_Content* content = (CXML_Content*)m_Children.GetAt(i + 1); |
| 587 } | 578 delete content; |
| 588 void CXML_Element::RemoveChildren() | 579 } else if (type == Element) { |
| 589 { | 580 CXML_Element* child = (CXML_Element*)m_Children.GetAt(i + 1); |
| 590 for (int i = 0; i < m_Children.GetSize(); i += 2) { | 581 child->RemoveChildren(); |
| 591 ChildType type = (ChildType)(uintptr_t)m_Children.GetAt(i); | 582 delete child; |
| 592 if (type == Content) { | 583 } |
| 593 CXML_Content* content = (CXML_Content*)m_Children.GetAt(i + 1); | 584 } |
| 594 delete content; | 585 m_Children.RemoveAll(); |
| 595 } else if (type == Element) { | 586 } |
| 596 CXML_Element* child = (CXML_Element*)m_Children.GetAt(i + 1); | 587 CFX_ByteString CXML_Element::GetTagName(FX_BOOL bQualified) const { |
| 597 child->RemoveChildren(); | 588 if (!bQualified || m_QSpaceName.IsEmpty()) { |
| 598 delete child; | 589 return m_TagName; |
| 599 } | 590 } |
| 600 } | 591 CFX_ByteString bsTag = m_QSpaceName; |
| 601 m_Children.RemoveAll(); | 592 bsTag += ":"; |
| 602 } | 593 bsTag += m_TagName; |
| 603 CFX_ByteString CXML_Element::GetTagName(FX_BOOL bQualified) const | 594 return bsTag; |
| 604 { | 595 } |
| 605 if (!bQualified || m_QSpaceName.IsEmpty()) { | 596 CFX_ByteString CXML_Element::GetNamespace(FX_BOOL bQualified) const { |
| 606 return m_TagName; | 597 if (bQualified) { |
| 607 } | 598 return m_QSpaceName; |
| 608 CFX_ByteString bsTag = m_QSpaceName; | 599 } |
| 609 bsTag += ":"; | 600 return GetNamespaceURI(m_QSpaceName); |
| 610 bsTag += m_TagName; | 601 } |
| 611 return bsTag; | 602 CFX_ByteString CXML_Element::GetNamespaceURI( |
| 612 } | 603 const CFX_ByteStringC& qName) const { |
| 613 CFX_ByteString CXML_Element::GetNamespace(FX_BOOL bQualified) const | 604 const CFX_WideString* pwsSpace; |
| 614 { | 605 const CXML_Element* pElement = this; |
| 615 if (bQualified) { | 606 do { |
| 616 return m_QSpaceName; | 607 if (qName.IsEmpty()) { |
| 617 } | 608 pwsSpace = pElement->m_AttrMap.Lookup(FX_BSTRC(""), FX_BSTRC("xmlns")); |
| 618 return GetNamespaceURI(m_QSpaceName); | 609 } else { |
| 619 } | 610 pwsSpace = pElement->m_AttrMap.Lookup(FX_BSTRC("xmlns"), qName); |
| 620 CFX_ByteString CXML_Element::GetNamespaceURI(const CFX_ByteStringC& qName) const | 611 } |
| 621 { | 612 if (pwsSpace) { |
| 622 const CFX_WideString* pwsSpace; | 613 break; |
| 623 const CXML_Element *pElement = this; | 614 } |
| 624 do { | 615 pElement = pElement->GetParent(); |
| 625 if (qName.IsEmpty()) { | 616 } while (pElement); |
| 626 pwsSpace = pElement->m_AttrMap.Lookup(FX_BSTRC(""), FX_BSTRC("xmlns"
)); | 617 return pwsSpace ? FX_UTF8Encode(*pwsSpace) : CFX_ByteString(); |
| 627 } else { | 618 } |
| 628 pwsSpace = pElement->m_AttrMap.Lookup(FX_BSTRC("xmlns"), qName); | 619 void CXML_Element::GetAttrByIndex(int index, |
| 629 } | 620 CFX_ByteString& space, |
| 630 if (pwsSpace) { | 621 CFX_ByteString& name, |
| 631 break; | 622 CFX_WideString& value) const { |
| 632 } | 623 if (index < 0 || index >= m_AttrMap.GetSize()) { |
| 633 pElement = pElement->GetParent(); | 624 return; |
| 634 } while(pElement); | 625 } |
| 635 return pwsSpace ? FX_UTF8Encode(*pwsSpace) : CFX_ByteString(); | 626 CXML_AttrItem& item = m_AttrMap.GetAt(index); |
| 636 } | 627 space = item.m_QSpaceName; |
| 637 void CXML_Element::GetAttrByIndex(int index, CFX_ByteString& space, CFX_ByteStri
ng& name, CFX_WideString& value) const | 628 name = item.m_AttrName; |
| 638 { | 629 value = item.m_Value; |
| 639 if (index < 0 || index >= m_AttrMap.GetSize()) { | 630 } |
| 640 return; | 631 FX_BOOL CXML_Element::HasAttr(const CFX_ByteStringC& name) const { |
| 641 } | 632 CFX_ByteStringC bsSpace, bsName; |
| 642 CXML_AttrItem& item = m_AttrMap.GetAt(index); | 633 FX_XML_SplitQualifiedName(name, bsSpace, bsName); |
| 643 space = item.m_QSpaceName; | 634 return m_AttrMap.Lookup(bsSpace, bsName) != NULL; |
| 644 name = item.m_AttrName; | 635 } |
| 645 value = item.m_Value; | 636 FX_BOOL CXML_Element::GetAttrValue(const CFX_ByteStringC& name, |
| 646 } | 637 CFX_WideString& attribute) const { |
| 647 FX_BOOL CXML_Element::HasAttr(const CFX_ByteStringC& name) const | 638 CFX_ByteStringC bsSpace, bsName; |
| 648 { | 639 FX_XML_SplitQualifiedName(name, bsSpace, bsName); |
| 649 CFX_ByteStringC bsSpace, bsName; | 640 return GetAttrValue(bsSpace, bsName, attribute); |
| 650 FX_XML_SplitQualifiedName(name, bsSpace, bsName); | 641 } |
| 651 return m_AttrMap.Lookup(bsSpace, bsName) != NULL; | 642 FX_BOOL CXML_Element::GetAttrValue(const CFX_ByteStringC& space, |
| 652 } | 643 const CFX_ByteStringC& name, |
| 653 FX_BOOL CXML_Element::GetAttrValue(const CFX_ByteStringC& name, CFX_WideString&
attribute) const | 644 CFX_WideString& attribute) const { |
| 654 { | 645 const CFX_WideString* pValue = m_AttrMap.Lookup(space, name); |
| 655 CFX_ByteStringC bsSpace, bsName; | 646 if (pValue) { |
| 656 FX_XML_SplitQualifiedName(name, bsSpace, bsName); | 647 attribute = *pValue; |
| 657 return GetAttrValue(bsSpace, bsName, attribute); | 648 return TRUE; |
| 658 } | 649 } |
| 659 FX_BOOL CXML_Element::GetAttrValue(const CFX_ByteStringC& space, const CFX_ByteS
tringC& name, CFX_WideString& attribute) const | 650 return FALSE; |
| 660 { | 651 } |
| 661 const CFX_WideString* pValue = m_AttrMap.Lookup(space, name); | 652 FX_BOOL CXML_Element::GetAttrInteger(const CFX_ByteStringC& name, |
| 662 if (pValue) { | 653 int& attribute) const { |
| 663 attribute = *pValue; | 654 CFX_ByteStringC bsSpace, bsName; |
| 664 return TRUE; | 655 FX_XML_SplitQualifiedName(name, bsSpace, bsName); |
| 665 } | 656 const CFX_WideString* pwsValue = m_AttrMap.Lookup(bsSpace, bsName); |
| 666 return FALSE; | 657 if (pwsValue) { |
| 667 } | 658 attribute = pwsValue->GetInteger(); |
| 668 FX_BOOL CXML_Element::GetAttrInteger(const CFX_ByteStringC& name, int& attribute
) const | 659 return TRUE; |
| 669 { | 660 } |
| 670 CFX_ByteStringC bsSpace, bsName; | 661 return FALSE; |
| 671 FX_XML_SplitQualifiedName(name, bsSpace, bsName); | 662 } |
| 672 const CFX_WideString* pwsValue = m_AttrMap.Lookup(bsSpace, bsName); | 663 FX_BOOL CXML_Element::GetAttrInteger(const CFX_ByteStringC& space, |
| 673 if (pwsValue) { | 664 const CFX_ByteStringC& name, |
| 674 attribute = pwsValue->GetInteger(); | 665 int& attribute) const { |
| 675 return TRUE; | 666 const CFX_WideString* pwsValue = m_AttrMap.Lookup(space, name); |
| 676 } | 667 if (pwsValue) { |
| 677 return FALSE; | 668 attribute = pwsValue->GetInteger(); |
| 678 } | 669 return TRUE; |
| 679 FX_BOOL»CXML_Element::GetAttrInteger(const CFX_ByteStringC& space, const CFX_Byt
eStringC& name, int& attribute) const | 670 } |
| 680 { | 671 return FALSE; |
| 681 const CFX_WideString* pwsValue = m_AttrMap.Lookup(space, name); | 672 } |
| 682 if (pwsValue) { | 673 FX_BOOL CXML_Element::GetAttrFloat(const CFX_ByteStringC& name, |
| 683 attribute = pwsValue->GetInteger(); | 674 FX_FLOAT& attribute) const { |
| 684 return TRUE; | 675 CFX_ByteStringC bsSpace, bsName; |
| 685 } | 676 FX_XML_SplitQualifiedName(name, bsSpace, bsName); |
| 686 return FALSE; | 677 return GetAttrFloat(bsSpace, bsName, attribute); |
| 687 } | 678 } |
| 688 FX_BOOL CXML_Element::GetAttrFloat(const CFX_ByteStringC& name, FX_FLOAT& attrib
ute) const | 679 FX_BOOL CXML_Element::GetAttrFloat(const CFX_ByteStringC& space, |
| 689 { | 680 const CFX_ByteStringC& name, |
| 690 CFX_ByteStringC bsSpace, bsName; | 681 FX_FLOAT& attribute) const { |
| 691 FX_XML_SplitQualifiedName(name, bsSpace, bsName); | 682 const CFX_WideString* pValue = m_AttrMap.Lookup(space, name); |
| 692 return GetAttrFloat(bsSpace, bsName, attribute); | 683 if (pValue) { |
| 693 } | 684 attribute = pValue->GetFloat(); |
| 694 FX_BOOL CXML_Element::GetAttrFloat(const CFX_ByteStringC& space, const CFX_ByteS
tringC& name, FX_FLOAT& attribute) const | 685 return TRUE; |
| 695 { | 686 } |
| 696 const CFX_WideString* pValue = m_AttrMap.Lookup(space, name); | 687 return FALSE; |
| 697 if (pValue) { | 688 } |
| 698 attribute = pValue->GetFloat(); | 689 FX_DWORD CXML_Element::CountChildren() const { |
| 699 return TRUE; | 690 return m_Children.GetSize() / 2; |
| 700 } | 691 } |
| 701 return FALSE; | 692 CXML_Element::ChildType CXML_Element::GetChildType(FX_DWORD index) const { |
| 702 } | 693 index <<= 1; |
| 703 FX_DWORD CXML_Element::CountChildren() const | 694 if (index >= (FX_DWORD)m_Children.GetSize()) { |
| 704 { | 695 return Invalid; |
| 705 return m_Children.GetSize() / 2; | 696 } |
| 706 } | 697 return (ChildType)(uintptr_t)m_Children.GetAt(index); |
| 707 CXML_Element::ChildType CXML_Element::GetChildType(FX_DWORD index) const | 698 } |
| 708 { | 699 CFX_WideString CXML_Element::GetContent(FX_DWORD index) const { |
| 709 index <<= 1; | 700 index <<= 1; |
| 710 if (index >= (FX_DWORD)m_Children.GetSize()) { | 701 if (index >= (FX_DWORD)m_Children.GetSize() || |
| 711 return Invalid; | 702 (ChildType)(uintptr_t)m_Children.GetAt(index) != Content) { |
| 712 } | |
| 713 return (ChildType)(uintptr_t)m_Children.GetAt(index); | |
| 714 } | |
| 715 CFX_WideString CXML_Element::GetContent(FX_DWORD index) const | |
| 716 { | |
| 717 index <<= 1; | |
| 718 if (index >= (FX_DWORD)m_Children.GetSize() || | |
| 719 (ChildType)(uintptr_t)m_Children.GetAt(index) != Content) { | |
| 720 return CFX_WideString(); | |
| 721 } | |
| 722 CXML_Content* pContent = (CXML_Content*)m_Children.GetAt(index + 1); | |
| 723 if (pContent) { | |
| 724 return pContent->m_Content; | |
| 725 } | |
| 726 return CFX_WideString(); | 703 return CFX_WideString(); |
| 727 } | 704 } |
| 728 CXML_Element* CXML_Element::GetElement(FX_DWORD index) const | 705 CXML_Content* pContent = (CXML_Content*)m_Children.GetAt(index + 1); |
| 729 { | 706 if (pContent) { |
| 730 index <<= 1; | 707 return pContent->m_Content; |
| 731 if (index >= (FX_DWORD)m_Children.GetSize() || | 708 } |
| 732 (ChildType)(uintptr_t)m_Children.GetAt(index) != Element) { | 709 return CFX_WideString(); |
| 733 return NULL; | 710 } |
| 734 } | 711 CXML_Element* CXML_Element::GetElement(FX_DWORD index) const { |
| 735 return (CXML_Element*)m_Children.GetAt(index + 1); | 712 index <<= 1; |
| 736 } | 713 if (index >= (FX_DWORD)m_Children.GetSize() || |
| 737 FX_DWORD CXML_Element::CountElements(const CFX_ByteStringC& space, const CFX_Byt
eStringC& tag) const | 714 (ChildType)(uintptr_t)m_Children.GetAt(index) != Element) { |
| 738 { | |
| 739 int count = 0; | |
| 740 for (int i = 0; i < m_Children.GetSize(); i += 2) { | |
| 741 ChildType type = (ChildType)(uintptr_t)m_Children.GetAt(i); | |
| 742 if (type != Element) { | |
| 743 continue; | |
| 744 } | |
| 745 CXML_Element* pKid = (CXML_Element*)m_Children.GetAt(i + 1); | |
| 746 if ((space.IsEmpty() || pKid->m_QSpaceName == space) && pKid->m_TagName
== tag) { | |
| 747 count ++; | |
| 748 } | |
| 749 } | |
| 750 return count; | |
| 751 } | |
| 752 CXML_Element* CXML_Element::GetElement(const CFX_ByteStringC& space, const CFX_B
yteStringC& tag, int index) const | |
| 753 { | |
| 754 if (index < 0) { | |
| 755 return NULL; | |
| 756 } | |
| 757 for (int i = 0; i < m_Children.GetSize(); i += 2) { | |
| 758 ChildType type = (ChildType)(uintptr_t)m_Children.GetAt(i); | |
| 759 if (type != Element) { | |
| 760 continue; | |
| 761 } | |
| 762 CXML_Element* pKid = (CXML_Element*)m_Children.GetAt(i + 1); | |
| 763 if ((!space.IsEmpty() && pKid->m_QSpaceName != space) || pKid->m_TagName
!= tag) { | |
| 764 continue; | |
| 765 } | |
| 766 if (index -- == 0) { | |
| 767 return pKid; | |
| 768 } | |
| 769 } | |
| 770 return NULL; | 715 return NULL; |
| 771 } | 716 } |
| 772 FX_DWORD CXML_Element::FindElement(CXML_Element *pChild) const | 717 return (CXML_Element*)m_Children.GetAt(index + 1); |
| 773 { | 718 } |
| 774 for (int i = 0; i < m_Children.GetSize(); i += 2) { | 719 FX_DWORD CXML_Element::CountElements(const CFX_ByteStringC& space, |
| 775 if ((ChildType)(uintptr_t)m_Children.GetAt(i) == Element && | 720 const CFX_ByteStringC& tag) const { |
| 776 (CXML_Element*)m_Children.GetAt(i + 1) == pChild) { | 721 int count = 0; |
| 777 return (FX_DWORD)(i >> 1); | 722 for (int i = 0; i < m_Children.GetSize(); i += 2) { |
| 778 } | 723 ChildType type = (ChildType)(uintptr_t)m_Children.GetAt(i); |
| 779 } | 724 if (type != Element) { |
| 780 return (FX_DWORD) - 1; | 725 continue; |
| 781 } | 726 } |
| 782 const CFX_WideString* CXML_AttrMap::Lookup(const CFX_ByteStringC& space, const C
FX_ByteStringC& name) const | 727 CXML_Element* pKid = (CXML_Element*)m_Children.GetAt(i + 1); |
| 783 { | 728 if ((space.IsEmpty() || pKid->m_QSpaceName == space) && |
| 784 if (m_pMap == NULL) { | 729 pKid->m_TagName == tag) { |
| 785 return NULL; | 730 count++; |
| 786 } | 731 } |
| 787 for (int i = 0; i < m_pMap->GetSize(); i ++) { | 732 } |
| 788 CXML_AttrItem& item = GetAt(i); | 733 return count; |
| 789 if ((space.IsEmpty() || item.m_QSpaceName == space) && item.m_AttrName =
= name) { | 734 } |
| 790 return &item.m_Value; | 735 CXML_Element* CXML_Element::GetElement(const CFX_ByteStringC& space, |
| 791 } | 736 const CFX_ByteStringC& tag, |
| 792 } | 737 int index) const { |
| 738 if (index < 0) { |
| 793 return NULL; | 739 return NULL; |
| 794 } | 740 } |
| 795 void CXML_AttrMap::SetAt(const CFX_ByteStringC& space, const CFX_ByteStringC& na
me, const CFX_WideStringC& value) | 741 for (int i = 0; i < m_Children.GetSize(); i += 2) { |
| 796 { | 742 ChildType type = (ChildType)(uintptr_t)m_Children.GetAt(i); |
| 797 for (int i = 0; i < GetSize(); i++) { | 743 if (type != Element) { |
| 798 CXML_AttrItem& item = GetAt(i); | 744 continue; |
| 799 if ((space.IsEmpty() || item.m_QSpaceName == space) && item.m_AttrName =
= name) { | 745 } |
| 800 item.m_Value = value; | 746 CXML_Element* pKid = (CXML_Element*)m_Children.GetAt(i + 1); |
| 801 return; | 747 if ((!space.IsEmpty() && pKid->m_QSpaceName != space) || |
| 802 } | 748 pKid->m_TagName != tag) { |
| 803 } | 749 continue; |
| 804 if (!m_pMap) { | 750 } |
| 805 m_pMap = new CFX_ObjectArray<CXML_AttrItem>; | 751 if (index-- == 0) { |
| 806 } | 752 return pKid; |
| 807 CXML_AttrItem* pItem = (CXML_AttrItem*)m_pMap->AddSpace(); | 753 } |
| 808 if (!pItem) { | 754 } |
| 809 return; | 755 return NULL; |
| 810 } | 756 } |
| 811 pItem->m_QSpaceName = space; | 757 FX_DWORD CXML_Element::FindElement(CXML_Element* pChild) const { |
| 812 pItem->m_AttrName = name; | 758 for (int i = 0; i < m_Children.GetSize(); i += 2) { |
| 813 pItem->m_Value = value; | 759 if ((ChildType)(uintptr_t)m_Children.GetAt(i) == Element && |
| 814 } | 760 (CXML_Element*)m_Children.GetAt(i + 1) == pChild) { |
| 815 void CXML_AttrMap::RemoveAt(const CFX_ByteStringC& space, const CFX_ByteStringC&
name) | 761 return (FX_DWORD)(i >> 1); |
| 816 { | 762 } |
| 817 if (m_pMap == NULL) { | 763 } |
| 818 return; | 764 return (FX_DWORD)-1; |
| 819 } | 765 } |
| 820 for (int i = 0; i < m_pMap->GetSize(); i ++) { | 766 const CFX_WideString* CXML_AttrMap::Lookup(const CFX_ByteStringC& space, |
| 821 CXML_AttrItem& item = GetAt(i); | 767 const CFX_ByteStringC& name) const { |
| 822 if ((space.IsEmpty() || item.m_QSpaceName == space) && item.m_AttrName =
= name) { | 768 if (m_pMap == NULL) { |
| 823 m_pMap->RemoveAt(i); | 769 return NULL; |
| 824 return; | 770 } |
| 825 } | 771 for (int i = 0; i < m_pMap->GetSize(); i++) { |
| 826 } | 772 CXML_AttrItem& item = GetAt(i); |
| 827 } | 773 if ((space.IsEmpty() || item.m_QSpaceName == space) && |
| 828 int CXML_AttrMap::GetSize() const | 774 item.m_AttrName == name) { |
| 829 { | 775 return &item.m_Value; |
| 830 return m_pMap == NULL ? 0 : m_pMap->GetSize(); | 776 } |
| 831 } | 777 } |
| 832 CXML_AttrItem& CXML_AttrMap::GetAt(int index) const | 778 return NULL; |
| 833 { | 779 } |
| 834 ASSERT(m_pMap != NULL); | 780 void CXML_AttrMap::SetAt(const CFX_ByteStringC& space, |
| 835 return (*m_pMap)[index]; | 781 const CFX_ByteStringC& name, |
| 836 } | 782 const CFX_WideStringC& value) { |
| 837 void CXML_AttrMap::RemoveAll() | 783 for (int i = 0; i < GetSize(); i++) { |
| 838 { | 784 CXML_AttrItem& item = GetAt(i); |
| 839 if (!m_pMap) { | 785 if ((space.IsEmpty() || item.m_QSpaceName == space) && |
| 840 return; | 786 item.m_AttrName == name) { |
| 841 } | 787 item.m_Value = value; |
| 842 m_pMap->RemoveAll(); | 788 return; |
| 843 delete m_pMap; | 789 } |
| 844 m_pMap = NULL; | 790 } |
| 845 } | 791 if (!m_pMap) { |
| 792 m_pMap = new CFX_ObjectArray<CXML_AttrItem>; |
| 793 } |
| 794 CXML_AttrItem* pItem = (CXML_AttrItem*)m_pMap->AddSpace(); |
| 795 if (!pItem) { |
| 796 return; |
| 797 } |
| 798 pItem->m_QSpaceName = space; |
| 799 pItem->m_AttrName = name; |
| 800 pItem->m_Value = value; |
| 801 } |
| 802 void CXML_AttrMap::RemoveAt(const CFX_ByteStringC& space, |
| 803 const CFX_ByteStringC& name) { |
| 804 if (m_pMap == NULL) { |
| 805 return; |
| 806 } |
| 807 for (int i = 0; i < m_pMap->GetSize(); i++) { |
| 808 CXML_AttrItem& item = GetAt(i); |
| 809 if ((space.IsEmpty() || item.m_QSpaceName == space) && |
| 810 item.m_AttrName == name) { |
| 811 m_pMap->RemoveAt(i); |
| 812 return; |
| 813 } |
| 814 } |
| 815 } |
| 816 int CXML_AttrMap::GetSize() const { |
| 817 return m_pMap == NULL ? 0 : m_pMap->GetSize(); |
| 818 } |
| 819 CXML_AttrItem& CXML_AttrMap::GetAt(int index) const { |
| 820 ASSERT(m_pMap != NULL); |
| 821 return (*m_pMap)[index]; |
| 822 } |
| 823 void CXML_AttrMap::RemoveAll() { |
| 824 if (!m_pMap) { |
| 825 return; |
| 826 } |
| 827 m_pMap->RemoveAll(); |
| 828 delete m_pMap; |
| 829 m_pMap = NULL; |
| 830 } |
| OLD | NEW |