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 |