OLD | NEW |
| (Empty) |
1 // Copyright 2014 PDFium Authors. All rights reserved. | |
2 // Use of this source code is governed by a BSD-style license that can be | |
3 // found in the LICENSE file. | |
4 | |
5 // Original code copyright 2014 Foxit Software Inc. http://www.foxitsoftware.com | |
6 | |
7 #include "xfa/src/fde/xml/fde_xml_imp.h" | |
8 | |
9 #include <algorithm> | |
10 | |
11 #include "xfa/src/fgas/crt/fgas_system.h" | |
12 #include "xfa/src/fgas/crt/fgas_codepage.h" | |
13 | |
14 #define FDE_XMLVALIDCHARRANGENUM 5 | |
15 | |
16 static const FX_WCHAR g_XMLValidCharRange[FDE_XMLVALIDCHARRANGENUM][2] = { | |
17 {0x09, 0x09}, | |
18 {0x0A, 0x0A}, | |
19 {0x0D, 0x0D}, | |
20 {0x20, 0xD7FF}, | |
21 {0xE000, 0xFFFD}}; | |
22 | |
23 FX_BOOL FDE_IsXMLValidChar(FX_WCHAR ch) { | |
24 int32_t iStart = 0, iEnd = FDE_XMLVALIDCHARRANGENUM - 1, iMid; | |
25 while (iStart <= iEnd) { | |
26 iMid = (iStart + iEnd) / 2; | |
27 if (ch < g_XMLValidCharRange[iMid][0]) { | |
28 iEnd = iMid - 1; | |
29 } else if (ch > g_XMLValidCharRange[iMid][1]) { | |
30 iStart = iMid + 1; | |
31 } else { | |
32 return TRUE; | |
33 } | |
34 } | |
35 return FALSE; | |
36 } | |
37 FX_BOOL FDE_IsXMLWhiteSpace(FX_WCHAR ch) { | |
38 return ch == L' ' || ch == 0x0A || ch == 0x0D || ch == 0x09; | |
39 } | |
40 | |
41 struct FDE_XMLNAMECHAR { | |
42 FX_WCHAR wStart; | |
43 FX_WCHAR wEnd; | |
44 FX_BOOL bStartChar; | |
45 }; | |
46 | |
47 #define FDE_XMLNAMECHARSNUM 20 | |
48 static FDE_XMLNAMECHAR g_XMLNameChars[FDE_XMLNAMECHARSNUM] = { | |
49 {L'-', L'.', FALSE}, {L'0', L'9', FALSE}, {L':', L':', FALSE}, | |
50 {L'A', L'Z', TRUE}, {L'_', L'_', TRUE}, {L'a', L'z', TRUE}, | |
51 {0xB7, 0xB7, FALSE}, {0xC0, 0xD6, TRUE}, {0xD8, 0xF6, TRUE}, | |
52 {0xF8, 0x02FF, TRUE}, {0x0300, 0x036F, FALSE}, {0x0370, 0x037D, TRUE}, | |
53 {0x037F, 0x1FFF, TRUE}, {0x200C, 0x200D, TRUE}, {0x203F, 0x2040, FALSE}, | |
54 {0x2070, 0x218F, TRUE}, {0x2C00, 0x2FEF, TRUE}, {0x3001, 0xD7FF, TRUE}, | |
55 {0xF900, 0xFDCF, TRUE}, {0xFDF0, 0xFFFD, TRUE}, | |
56 }; | |
57 | |
58 FX_BOOL FDE_IsXMLNameChar(FX_WCHAR ch, FX_BOOL bFirstChar) { | |
59 int32_t iStart = 0, iEnd = FDE_XMLNAMECHARSNUM - 1, iMid; | |
60 while (iStart <= iEnd) { | |
61 iMid = (iStart + iEnd) / 2; | |
62 if (ch < g_XMLNameChars[iMid].wStart) { | |
63 iEnd = iMid - 1; | |
64 } else if (ch > g_XMLNameChars[iMid].wEnd) { | |
65 iStart = iMid + 1; | |
66 } else { | |
67 if (bFirstChar) { | |
68 return g_XMLNameChars[iMid].bStartChar; | |
69 } | |
70 return TRUE; | |
71 } | |
72 } | |
73 return FALSE; | |
74 } | |
75 | |
76 CFDE_XMLNode::CFDE_XMLNode() | |
77 : m_pParent(NULL), m_pChild(NULL), m_pPrior(NULL), m_pNext(NULL) {} | |
78 CFDE_XMLNode::~CFDE_XMLNode() { | |
79 DeleteChildren(); | |
80 } | |
81 void CFDE_XMLNode::DeleteChildren() { | |
82 CFDE_XMLNode *pChild = m_pChild, *pTemp; | |
83 while (pChild != NULL) { | |
84 pTemp = pChild->m_pNext; | |
85 pChild->Release(); | |
86 pChild = pTemp; | |
87 } | |
88 m_pChild = NULL; | |
89 } | |
90 int32_t CFDE_XMLNode::CountChildNodes() const { | |
91 int32_t iCount = 0; | |
92 CFDE_XMLNode* pChild = m_pChild; | |
93 while (pChild != NULL) { | |
94 iCount++; | |
95 pChild = pChild->m_pNext; | |
96 } | |
97 return iCount; | |
98 } | |
99 CFDE_XMLNode* CFDE_XMLNode::GetChildNode(int32_t index) const { | |
100 CFDE_XMLNode* pChild = m_pChild; | |
101 while (pChild != NULL) { | |
102 if (index == 0) { | |
103 return pChild; | |
104 } | |
105 index--; | |
106 pChild = pChild->m_pNext; | |
107 } | |
108 return NULL; | |
109 } | |
110 int32_t CFDE_XMLNode::GetChildNodeIndex(CFDE_XMLNode* pNode) const { | |
111 int32_t index = 0; | |
112 CFDE_XMLNode* pChild = m_pChild; | |
113 while (pChild != NULL) { | |
114 if (pChild == pNode) { | |
115 return index; | |
116 } | |
117 index++; | |
118 pChild = pChild->m_pNext; | |
119 } | |
120 return -1; | |
121 } | |
122 CFDE_XMLNode* CFDE_XMLNode::GetPath(const FX_WCHAR* pPath, | |
123 int32_t iLength, | |
124 FX_BOOL bQualifiedName) const { | |
125 FXSYS_assert(pPath != NULL); | |
126 if (iLength < 0) { | |
127 iLength = FXSYS_wcslen(pPath); | |
128 } | |
129 if (iLength == 0) { | |
130 return NULL; | |
131 } | |
132 CFX_WideString csPath; | |
133 const FX_WCHAR* pStart = pPath; | |
134 const FX_WCHAR* pEnd = pPath + iLength; | |
135 FX_WCHAR ch; | |
136 while (pStart < pEnd) { | |
137 ch = *pStart++; | |
138 if (ch == L'/') { | |
139 break; | |
140 } else { | |
141 csPath += ch; | |
142 } | |
143 } | |
144 iLength -= pStart - pPath; | |
145 CFDE_XMLNode* pFind = NULL; | |
146 if (csPath.GetLength() < 1) { | |
147 pFind = GetNodeItem(IFDE_XMLNode::Root); | |
148 } else if (csPath.Compare(L"..") == 0) { | |
149 pFind = m_pParent; | |
150 } else if (csPath.Compare(L".") == 0) { | |
151 pFind = (CFDE_XMLNode*)this; | |
152 } else { | |
153 CFX_WideString wsTag; | |
154 CFDE_XMLNode* pNode = m_pChild; | |
155 while (pNode != NULL) { | |
156 if (pNode->GetType() == FDE_XMLNODE_Element) { | |
157 if (bQualifiedName) { | |
158 ((CFDE_XMLElement*)pNode)->GetTagName(wsTag); | |
159 } else { | |
160 ((CFDE_XMLElement*)pNode)->GetLocalTagName(wsTag); | |
161 } | |
162 if (wsTag.Compare(csPath) == 0) { | |
163 if (iLength < 1) { | |
164 pFind = pNode; | |
165 } else { | |
166 pFind = pNode->GetPath(pStart, iLength, bQualifiedName); | |
167 } | |
168 if (pFind != NULL) { | |
169 return pFind; | |
170 } | |
171 } | |
172 } | |
173 pNode = pNode->m_pNext; | |
174 } | |
175 } | |
176 if (pFind == NULL || iLength < 1) { | |
177 return pFind; | |
178 } | |
179 return pFind->GetPath(pStart, iLength, bQualifiedName); | |
180 } | |
181 int32_t CFDE_XMLNode::InsertChildNode(CFDE_XMLNode* pNode, int32_t index) { | |
182 FXSYS_assert(pNode != NULL); | |
183 pNode->m_pParent = this; | |
184 if (m_pChild == NULL) { | |
185 m_pChild = pNode; | |
186 pNode->m_pPrior = NULL; | |
187 pNode->m_pNext = NULL; | |
188 return 0; | |
189 } else if (index == 0) { | |
190 pNode->m_pNext = m_pChild; | |
191 pNode->m_pPrior = NULL; | |
192 m_pChild->m_pPrior = pNode; | |
193 m_pChild = pNode; | |
194 return 0; | |
195 } | |
196 int32_t iCount = 0; | |
197 CFDE_XMLNode* pFind = m_pChild; | |
198 while (++iCount != index && pFind->m_pNext != NULL) { | |
199 pFind = pFind->m_pNext; | |
200 } | |
201 pNode->m_pPrior = pFind; | |
202 pNode->m_pNext = pFind->m_pNext; | |
203 if (pFind->m_pNext != NULL) { | |
204 pFind->m_pNext->m_pPrior = pNode; | |
205 } | |
206 pFind->m_pNext = pNode; | |
207 return iCount; | |
208 } | |
209 void CFDE_XMLNode::RemoveChildNode(CFDE_XMLNode* pNode) { | |
210 FXSYS_assert(m_pChild != NULL && pNode != NULL); | |
211 if (m_pChild == pNode) { | |
212 m_pChild = pNode->m_pNext; | |
213 } else { | |
214 pNode->m_pPrior->m_pNext = pNode->m_pNext; | |
215 } | |
216 if (pNode->m_pNext != NULL) { | |
217 pNode->m_pNext->m_pPrior = pNode->m_pPrior; | |
218 } | |
219 pNode->m_pParent = NULL; | |
220 pNode->m_pNext = NULL; | |
221 pNode->m_pPrior = NULL; | |
222 } | |
223 CFDE_XMLNode* CFDE_XMLNode::GetNodeItem(IFDE_XMLNode::NodeItem eItem) const { | |
224 switch (eItem) { | |
225 case IFDE_XMLNode::Root: { | |
226 CFDE_XMLNode* pParent = (CFDE_XMLNode*)this; | |
227 while (pParent->m_pParent != NULL) { | |
228 pParent = pParent->m_pParent; | |
229 } | |
230 return pParent; | |
231 } | |
232 case IFDE_XMLNode::Parent: | |
233 return m_pParent; | |
234 case IFDE_XMLNode::FirstSibling: { | |
235 CFDE_XMLNode* pItem = (CFDE_XMLNode*)this; | |
236 while (pItem->m_pPrior != NULL) { | |
237 pItem = pItem->m_pPrior; | |
238 } | |
239 return pItem == (CFDE_XMLNode*)this ? NULL : pItem; | |
240 } | |
241 case IFDE_XMLNode::PriorSibling: | |
242 return m_pPrior; | |
243 case IFDE_XMLNode::NextSibling: | |
244 return m_pNext; | |
245 case IFDE_XMLNode::LastSibling: { | |
246 CFDE_XMLNode* pItem = (CFDE_XMLNode*)this; | |
247 while (pItem->m_pNext != NULL) { | |
248 pItem = pItem->m_pNext; | |
249 } | |
250 return pItem == (CFDE_XMLNode*)this ? NULL : pItem; | |
251 } | |
252 case IFDE_XMLNode::FirstNeighbor: { | |
253 CFDE_XMLNode* pParent = (CFDE_XMLNode*)this; | |
254 while (pParent->m_pParent != NULL) { | |
255 pParent = pParent->m_pParent; | |
256 } | |
257 return pParent == (CFDE_XMLNode*)this ? NULL : pParent; | |
258 } | |
259 case IFDE_XMLNode::PriorNeighbor: { | |
260 if (m_pPrior == NULL) { | |
261 return m_pParent; | |
262 } | |
263 CFDE_XMLNode* pItem = m_pPrior; | |
264 while (CFDE_XMLNode* pTemp = pItem->m_pChild) { | |
265 pItem = pTemp; | |
266 while ((pTemp = pItem->m_pNext) != NULL) { | |
267 pItem = pTemp; | |
268 } | |
269 } | |
270 return pItem; | |
271 } | |
272 case IFDE_XMLNode::NextNeighbor: { | |
273 if (m_pChild != NULL) { | |
274 return m_pChild; | |
275 } | |
276 if (m_pNext != NULL) { | |
277 return m_pNext; | |
278 } | |
279 CFDE_XMLNode* pItem = m_pParent; | |
280 while (pItem != NULL) { | |
281 if (pItem->m_pNext != NULL) { | |
282 return pItem->m_pNext; | |
283 } | |
284 pItem = pItem->m_pParent; | |
285 } | |
286 return NULL; | |
287 } | |
288 case IFDE_XMLNode::LastNeighbor: { | |
289 CFDE_XMLNode* pItem = (CFDE_XMLNode*)this; | |
290 while (pItem->m_pParent != NULL) { | |
291 pItem = pItem->m_pParent; | |
292 } | |
293 while (TRUE) { | |
294 while (pItem->m_pNext != NULL) { | |
295 pItem = pItem->m_pNext; | |
296 } | |
297 if (pItem->m_pChild == NULL) { | |
298 break; | |
299 } | |
300 pItem = pItem->m_pChild; | |
301 } | |
302 return pItem == (CFDE_XMLNode*)this ? NULL : pItem; | |
303 } | |
304 case IFDE_XMLNode::FirstChild: | |
305 return m_pChild; | |
306 case IFDE_XMLNode::LastChild: { | |
307 if (m_pChild == NULL) { | |
308 return NULL; | |
309 } | |
310 CFDE_XMLNode* pChild = m_pChild; | |
311 while (pChild->m_pNext != NULL) { | |
312 pChild = pChild->m_pNext; | |
313 } | |
314 return pChild; | |
315 } | |
316 default: | |
317 break; | |
318 } | |
319 return NULL; | |
320 } | |
321 int32_t CFDE_XMLNode::GetNodeLevel() const { | |
322 int32_t iLevel = 0; | |
323 CFDE_XMLNode* pItem = (CFDE_XMLNode*)this; | |
324 while ((pItem = pItem->m_pParent) != NULL) { | |
325 iLevel++; | |
326 } | |
327 return iLevel; | |
328 } | |
329 FX_BOOL CFDE_XMLNode::InsertNodeItem(IFDE_XMLNode::NodeItem eItem, | |
330 CFDE_XMLNode* pNode) { | |
331 FXSYS_assert(pNode != NULL); | |
332 switch (eItem) { | |
333 case IFDE_XMLNode::NextSibling: { | |
334 pNode->m_pParent = m_pParent; | |
335 pNode->m_pNext = m_pNext; | |
336 pNode->m_pPrior = this; | |
337 if (m_pNext) { | |
338 m_pNext->m_pPrior = pNode; | |
339 } | |
340 m_pNext = pNode; | |
341 return TRUE; | |
342 } | |
343 case IFDE_XMLNode::PriorSibling: { | |
344 pNode->m_pParent = m_pParent; | |
345 pNode->m_pNext = this; | |
346 pNode->m_pPrior = m_pPrior; | |
347 if (m_pPrior) { | |
348 m_pPrior->m_pNext = pNode; | |
349 } else if (m_pParent) { | |
350 m_pParent->m_pChild = pNode; | |
351 } | |
352 m_pPrior = pNode; | |
353 return TRUE; | |
354 } | |
355 default: | |
356 return FALSE; | |
357 } | |
358 return FALSE; | |
359 } | |
360 CFDE_XMLNode* CFDE_XMLNode::RemoveNodeItem(IFDE_XMLNode::NodeItem eItem) { | |
361 CFDE_XMLNode* pNode = NULL; | |
362 switch (eItem) { | |
363 case IFDE_XMLNode::NextSibling: | |
364 if (m_pNext) { | |
365 pNode = m_pNext; | |
366 m_pNext = pNode->m_pNext; | |
367 if (m_pNext) { | |
368 m_pNext->m_pPrior = this; | |
369 } | |
370 pNode->m_pParent = NULL; | |
371 pNode->m_pNext = NULL; | |
372 pNode->m_pPrior = NULL; | |
373 } | |
374 break; | |
375 default: | |
376 break; | |
377 } | |
378 return pNode; | |
379 } | |
380 CFDE_XMLNode* CFDE_XMLNode::Clone(FX_BOOL bRecursive) { | |
381 return NULL; | |
382 } | |
383 void CFDE_XMLNode::SaveXMLNode(IFX_Stream* pXMLStream) { | |
384 CFDE_XMLNode* pNode = (CFDE_XMLNode*)this; | |
385 FXSYS_assert(pXMLStream != NULL && pNode != NULL); | |
386 switch (pNode->GetType()) { | |
387 case FDE_XMLNODE_Instruction: { | |
388 CFX_WideString ws; | |
389 CFDE_XMLInstruction* pInstruction = (CFDE_XMLInstruction*)pNode; | |
390 if (pInstruction->m_wsTarget.CompareNoCase(L"xml") == 0) { | |
391 ws = L"<?xml version=\"1.0\" encoding=\""; | |
392 FX_WORD wCodePage = pXMLStream->GetCodePage(); | |
393 if (wCodePage == FX_CODEPAGE_UTF16LE) { | |
394 ws += L"UTF-16"; | |
395 } else if (wCodePage == FX_CODEPAGE_UTF16BE) { | |
396 ws += L"UTF-16be"; | |
397 } else { | |
398 ws += L"UTF-8"; | |
399 } | |
400 ws += L"\"?>"; | |
401 pXMLStream->WriteString(ws, ws.GetLength()); | |
402 } else { | |
403 ws.Format(L"<?%s", (const FX_WCHAR*)pInstruction->m_wsTarget); | |
404 pXMLStream->WriteString(ws, ws.GetLength()); | |
405 CFX_WideStringArray& attributes = pInstruction->m_Attributes; | |
406 int32_t i, iCount = attributes.GetSize(); | |
407 CFX_WideString wsValue; | |
408 for (i = 0; i < iCount; i += 2) { | |
409 ws = L" "; | |
410 ws += attributes[i]; | |
411 ws += L"=\""; | |
412 wsValue = attributes[i + 1]; | |
413 wsValue.Replace(L"&", L"&"); | |
414 wsValue.Replace(L"<", L"<"); | |
415 wsValue.Replace(L">", L">"); | |
416 wsValue.Replace(L"\'", L"'"); | |
417 wsValue.Replace(L"\"", L"""); | |
418 ws += wsValue; | |
419 ws += L"\""; | |
420 pXMLStream->WriteString(ws, ws.GetLength()); | |
421 } | |
422 CFX_WideStringArray& targetdata = pInstruction->m_TargetData; | |
423 iCount = targetdata.GetSize(); | |
424 for (i = 0; i < iCount; i++) { | |
425 ws = L" \""; | |
426 ws += targetdata[i]; | |
427 ws += L"\""; | |
428 pXMLStream->WriteString(ws, ws.GetLength()); | |
429 } | |
430 ws = L"?>"; | |
431 pXMLStream->WriteString(ws, ws.GetLength()); | |
432 } | |
433 } break; | |
434 case FDE_XMLNODE_Element: { | |
435 CFX_WideString ws; | |
436 ws = L"<"; | |
437 ws += ((CFDE_XMLElement*)pNode)->m_wsTag; | |
438 pXMLStream->WriteString(ws, ws.GetLength()); | |
439 CFX_WideStringArray& attributes = ((CFDE_XMLElement*)pNode)->m_Attributes; | |
440 int32_t iCount = attributes.GetSize(); | |
441 CFX_WideString wsValue; | |
442 for (int32_t i = 0; i < iCount; i += 2) { | |
443 ws = L" "; | |
444 ws += attributes[i]; | |
445 ws += L"=\""; | |
446 wsValue = attributes[i + 1]; | |
447 wsValue.Replace(L"&", L"&"); | |
448 wsValue.Replace(L"<", L"<"); | |
449 wsValue.Replace(L">", L">"); | |
450 wsValue.Replace(L"\'", L"'"); | |
451 wsValue.Replace(L"\"", L"""); | |
452 ws += wsValue; | |
453 ws += L"\""; | |
454 pXMLStream->WriteString(ws, ws.GetLength()); | |
455 } | |
456 if (pNode->m_pChild == NULL) { | |
457 ws = L"\n/>"; | |
458 pXMLStream->WriteString(ws, ws.GetLength()); | |
459 } else { | |
460 ws = L"\n>"; | |
461 pXMLStream->WriteString(ws, ws.GetLength()); | |
462 CFDE_XMLNode* pChild = pNode->m_pChild; | |
463 while (pChild != NULL) { | |
464 pChild->SaveXMLNode(pXMLStream); | |
465 pChild = pChild->m_pNext; | |
466 } | |
467 ws = L"</"; | |
468 ws += ((CFDE_XMLElement*)pNode)->m_wsTag; | |
469 ws += L"\n>"; | |
470 pXMLStream->WriteString(ws, ws.GetLength()); | |
471 } | |
472 } break; | |
473 case FDE_XMLNODE_Text: { | |
474 CFX_WideString ws = ((CFDE_XMLText*)pNode)->m_wsText; | |
475 ws.Replace(L"&", L"&"); | |
476 ws.Replace(L"<", L"<"); | |
477 ws.Replace(L">", L">"); | |
478 ws.Replace(L"\'", L"'"); | |
479 ws.Replace(L"\"", L"""); | |
480 pXMLStream->WriteString(ws, ws.GetLength()); | |
481 } break; | |
482 case FDE_XMLNODE_CharData: { | |
483 CFX_WideString ws = L"<![CDATA["; | |
484 ws += ((CFDE_XMLCharData*)pNode)->m_wsCharData; | |
485 ws += L"]]>"; | |
486 pXMLStream->WriteString(ws, ws.GetLength()); | |
487 } break; | |
488 case FDE_XMLNODE_Unknown: | |
489 break; | |
490 default: | |
491 break; | |
492 } | |
493 } | |
494 void CFDE_XMLNode::CloneChildren(CFDE_XMLNode* pClone) { | |
495 if (!m_pChild) { | |
496 return; | |
497 } | |
498 CFDE_XMLNode* pNext = m_pChild; | |
499 CFDE_XMLNode* pCloneNext = pNext->Clone(TRUE); | |
500 pClone->InsertChildNode(pCloneNext); | |
501 pNext = pNext->m_pNext; | |
502 while (pNext) { | |
503 CFDE_XMLNode* pChild = pNext->Clone(TRUE); | |
504 pCloneNext->InsertNodeItem(IFDE_XMLNode::NextSibling, pChild); | |
505 pCloneNext = pChild; | |
506 pNext = pNext->m_pNext; | |
507 } | |
508 } | |
509 IFDE_XMLInstruction* IFDE_XMLInstruction::Create( | |
510 const CFX_WideString& wsTarget) { | |
511 return (IFDE_XMLInstruction*)new CFDE_XMLInstruction(wsTarget); | |
512 } | |
513 CFDE_XMLInstruction::CFDE_XMLInstruction(const CFX_WideString& wsTarget) | |
514 : m_wsTarget(wsTarget) { | |
515 FXSYS_assert(m_wsTarget.GetLength() > 0); | |
516 } | |
517 CFDE_XMLNode* CFDE_XMLInstruction::Clone(FX_BOOL bRecursive) { | |
518 CFDE_XMLInstruction* pClone = new CFDE_XMLInstruction(m_wsTarget); | |
519 if (!pClone) { | |
520 return pClone; | |
521 } | |
522 pClone->m_Attributes.Copy(m_Attributes); | |
523 pClone->m_TargetData.Copy(m_TargetData); | |
524 if (bRecursive) { | |
525 CloneChildren(pClone); | |
526 } | |
527 return pClone; | |
528 } | |
529 int32_t CFDE_XMLInstruction::CountAttributes() const { | |
530 return m_Attributes.GetSize() / 2; | |
531 } | |
532 FX_BOOL CFDE_XMLInstruction::GetAttribute(int32_t index, | |
533 CFX_WideString& wsAttriName, | |
534 CFX_WideString& wsAttriValue) const { | |
535 int32_t iCount = m_Attributes.GetSize(); | |
536 FXSYS_assert(index > -1 && index < iCount / 2); | |
537 for (int32_t i = 0; i < iCount; i += 2) { | |
538 if (index == 0) { | |
539 wsAttriName = m_Attributes[i]; | |
540 wsAttriValue = m_Attributes[i + 1]; | |
541 return TRUE; | |
542 } | |
543 index--; | |
544 } | |
545 return FALSE; | |
546 } | |
547 FX_BOOL CFDE_XMLInstruction::HasAttribute(const FX_WCHAR* pwsAttriName) const { | |
548 int32_t iCount = m_Attributes.GetSize(); | |
549 for (int32_t i = 0; i < iCount; i += 2) { | |
550 if (m_Attributes[i].Compare(pwsAttriName) == 0) { | |
551 return TRUE; | |
552 } | |
553 } | |
554 return FALSE; | |
555 } | |
556 void CFDE_XMLInstruction::GetString(const FX_WCHAR* pwsAttriName, | |
557 CFX_WideString& wsAttriValue, | |
558 const FX_WCHAR* pwsDefValue) const { | |
559 int32_t iCount = m_Attributes.GetSize(); | |
560 for (int32_t i = 0; i < iCount; i += 2) { | |
561 if (m_Attributes[i].Compare(pwsAttriName) == 0) { | |
562 wsAttriValue = m_Attributes[i + 1]; | |
563 return; | |
564 } | |
565 } | |
566 wsAttriValue = pwsDefValue; | |
567 } | |
568 void CFDE_XMLInstruction::SetString(const CFX_WideString& wsAttriName, | |
569 const CFX_WideString& wsAttriValue) { | |
570 FXSYS_assert(wsAttriName.GetLength() > 0); | |
571 int32_t iCount = m_Attributes.GetSize(); | |
572 for (int32_t i = 0; i < iCount; i += 2) { | |
573 if (m_Attributes[i].Compare(wsAttriName) == 0) { | |
574 m_Attributes[i] = wsAttriName; | |
575 m_Attributes[i + 1] = wsAttriValue; | |
576 return; | |
577 } | |
578 } | |
579 m_Attributes.Add(wsAttriName); | |
580 m_Attributes.Add(wsAttriValue); | |
581 } | |
582 int32_t CFDE_XMLInstruction::GetInteger(const FX_WCHAR* pwsAttriName, | |
583 int32_t iDefValue) const { | |
584 int32_t iCount = m_Attributes.GetSize(); | |
585 for (int32_t i = 0; i < iCount; i += 2) { | |
586 if (m_Attributes[i].Compare(pwsAttriName) == 0) { | |
587 return FXSYS_wtoi((const FX_WCHAR*)m_Attributes[i + 1]); | |
588 } | |
589 } | |
590 return iDefValue; | |
591 } | |
592 void CFDE_XMLInstruction::SetInteger(const FX_WCHAR* pwsAttriName, | |
593 int32_t iAttriValue) { | |
594 CFX_WideString wsValue; | |
595 wsValue.Format(L"%d", iAttriValue); | |
596 SetString(pwsAttriName, wsValue); | |
597 } | |
598 FX_FLOAT CFDE_XMLInstruction::GetFloat(const FX_WCHAR* pwsAttriName, | |
599 FX_FLOAT fDefValue) const { | |
600 int32_t iCount = m_Attributes.GetSize(); | |
601 for (int32_t i = 0; i < iCount; i += 2) { | |
602 if (m_Attributes[i].Compare(pwsAttriName) == 0) { | |
603 return FX_wcstof((const FX_WCHAR*)m_Attributes[i + 1]); | |
604 } | |
605 } | |
606 return fDefValue; | |
607 } | |
608 void CFDE_XMLInstruction::SetFloat(const FX_WCHAR* pwsAttriName, | |
609 FX_FLOAT fAttriValue) { | |
610 CFX_WideString wsValue; | |
611 wsValue.Format(L"%f", fAttriValue); | |
612 SetString(pwsAttriName, wsValue); | |
613 } | |
614 void CFDE_XMLInstruction::RemoveAttribute(const FX_WCHAR* pwsAttriName) { | |
615 int32_t iCount = m_Attributes.GetSize(); | |
616 for (int32_t i = 0; i < iCount; i += 2) { | |
617 if (m_Attributes[i].Compare(pwsAttriName) == 0) { | |
618 m_Attributes.RemoveAt(i + 1); | |
619 m_Attributes.RemoveAt(i); | |
620 return; | |
621 } | |
622 } | |
623 } | |
624 int32_t CFDE_XMLInstruction::CountData() const { | |
625 return m_TargetData.GetSize(); | |
626 } | |
627 FX_BOOL CFDE_XMLInstruction::GetData(int32_t index, | |
628 CFX_WideString& wsData) const { | |
629 if (index < 0 || index >= m_TargetData.GetSize()) { | |
630 return FALSE; | |
631 } | |
632 wsData = m_TargetData[index]; | |
633 return TRUE; | |
634 } | |
635 void CFDE_XMLInstruction::AppendData(const CFX_WideString& wsData) { | |
636 m_TargetData.Add(wsData); | |
637 } | |
638 void CFDE_XMLInstruction::RemoveData(int32_t index) { | |
639 m_TargetData.RemoveAt(index); | |
640 } | |
641 IFDE_XMLElement* IFDE_XMLElement::Create(const CFX_WideString& wsTag) { | |
642 return (IFDE_XMLElement*)new CFDE_XMLElement(wsTag); | |
643 } | |
644 CFDE_XMLElement::CFDE_XMLElement(const CFX_WideString& wsTag) | |
645 : CFDE_XMLNode(), m_wsTag(wsTag), m_Attributes() { | |
646 FXSYS_assert(m_wsTag.GetLength() > 0); | |
647 } | |
648 CFDE_XMLElement::~CFDE_XMLElement() { | |
649 m_Attributes.RemoveAll(); | |
650 } | |
651 CFDE_XMLNode* CFDE_XMLElement::Clone(FX_BOOL bRecursive) { | |
652 CFDE_XMLElement* pClone = new CFDE_XMLElement(m_wsTag); | |
653 if (!pClone) { | |
654 return NULL; | |
655 } | |
656 pClone->m_Attributes.Copy(m_Attributes); | |
657 if (bRecursive) { | |
658 CloneChildren(pClone); | |
659 } else { | |
660 CFX_WideString wsText; | |
661 CFDE_XMLNode* pChild = m_pChild; | |
662 while (pChild != NULL) { | |
663 switch (pChild->GetType()) { | |
664 case FDE_XMLNODE_Text: | |
665 wsText += ((CFDE_XMLText*)pChild)->m_wsText; | |
666 break; | |
667 default: | |
668 break; | |
669 } | |
670 pChild = pChild->m_pNext; | |
671 } | |
672 pClone->SetTextData(wsText); | |
673 } | |
674 return pClone; | |
675 } | |
676 void CFDE_XMLElement::GetTagName(CFX_WideString& wsTag) const { | |
677 wsTag = m_wsTag; | |
678 } | |
679 void CFDE_XMLElement::GetLocalTagName(CFX_WideString& wsTag) const { | |
680 FX_STRSIZE iFind = m_wsTag.Find(L':', 0); | |
681 if (iFind < 0) { | |
682 wsTag = m_wsTag; | |
683 } else { | |
684 wsTag = m_wsTag.Right(m_wsTag.GetLength() - iFind - 1); | |
685 } | |
686 } | |
687 void CFDE_XMLElement::GetNamespacePrefix(CFX_WideString& wsPrefix) const { | |
688 FX_STRSIZE iFind = m_wsTag.Find(L':', 0); | |
689 if (iFind < 0) { | |
690 wsPrefix.Empty(); | |
691 } else { | |
692 wsPrefix = m_wsTag.Left(iFind); | |
693 } | |
694 } | |
695 void CFDE_XMLElement::GetNamespaceURI(CFX_WideString& wsNamespace) const { | |
696 CFX_WideString wsAttri(L"xmlns"), wsPrefix; | |
697 GetNamespacePrefix(wsPrefix); | |
698 if (wsPrefix.GetLength() > 0) { | |
699 wsAttri += L":"; | |
700 wsAttri += wsPrefix; | |
701 } | |
702 wsNamespace.Empty(); | |
703 CFDE_XMLNode* pNode = (CFDE_XMLNode*)this; | |
704 while (pNode != NULL) { | |
705 if (pNode->GetType() != FDE_XMLNODE_Element) { | |
706 break; | |
707 } | |
708 CFDE_XMLElement* pElement = (CFDE_XMLElement*)pNode; | |
709 if (!pElement->HasAttribute(wsAttri)) { | |
710 pNode = pNode->GetNodeItem(IFDE_XMLNode::Parent); | |
711 continue; | |
712 } | |
713 pElement->GetString(wsAttri, wsNamespace); | |
714 break; | |
715 } | |
716 } | |
717 int32_t CFDE_XMLElement::CountAttributes() const { | |
718 return m_Attributes.GetSize() / 2; | |
719 } | |
720 FX_BOOL CFDE_XMLElement::GetAttribute(int32_t index, | |
721 CFX_WideString& wsAttriName, | |
722 CFX_WideString& wsAttriValue) const { | |
723 int32_t iCount = m_Attributes.GetSize(); | |
724 FXSYS_assert(index > -1 && index < iCount / 2); | |
725 for (int32_t i = 0; i < iCount; i += 2) { | |
726 if (index == 0) { | |
727 wsAttriName = m_Attributes[i]; | |
728 wsAttriValue = m_Attributes[i + 1]; | |
729 return TRUE; | |
730 } | |
731 index--; | |
732 } | |
733 return FALSE; | |
734 } | |
735 FX_BOOL CFDE_XMLElement::HasAttribute(const FX_WCHAR* pwsAttriName) const { | |
736 int32_t iCount = m_Attributes.GetSize(); | |
737 for (int32_t i = 0; i < iCount; i += 2) { | |
738 if (m_Attributes[i].Compare(pwsAttriName) == 0) { | |
739 return TRUE; | |
740 } | |
741 } | |
742 return FALSE; | |
743 } | |
744 void CFDE_XMLElement::GetString(const FX_WCHAR* pwsAttriName, | |
745 CFX_WideString& wsAttriValue, | |
746 const FX_WCHAR* pwsDefValue) const { | |
747 int32_t iCount = m_Attributes.GetSize(); | |
748 for (int32_t i = 0; i < iCount; i += 2) { | |
749 if (m_Attributes[i].Compare(pwsAttriName) == 0) { | |
750 wsAttriValue = m_Attributes[i + 1]; | |
751 return; | |
752 } | |
753 } | |
754 wsAttriValue = pwsDefValue; | |
755 } | |
756 void CFDE_XMLElement::SetString(const CFX_WideString& wsAttriName, | |
757 const CFX_WideString& wsAttriValue) { | |
758 FXSYS_assert(wsAttriName.GetLength() > 0); | |
759 int32_t iCount = m_Attributes.GetSize(); | |
760 for (int32_t i = 0; i < iCount; i += 2) { | |
761 if (m_Attributes[i].Compare(wsAttriName) == 0) { | |
762 m_Attributes[i] = wsAttriName; | |
763 m_Attributes[i + 1] = wsAttriValue; | |
764 return; | |
765 } | |
766 } | |
767 m_Attributes.Add(wsAttriName); | |
768 m_Attributes.Add(wsAttriValue); | |
769 } | |
770 int32_t CFDE_XMLElement::GetInteger(const FX_WCHAR* pwsAttriName, | |
771 int32_t iDefValue) const { | |
772 int32_t iCount = m_Attributes.GetSize(); | |
773 for (int32_t i = 0; i < iCount; i += 2) { | |
774 if (m_Attributes[i].Compare(pwsAttriName) == 0) { | |
775 return FXSYS_wtoi((const FX_WCHAR*)m_Attributes[i + 1]); | |
776 } | |
777 } | |
778 return iDefValue; | |
779 } | |
780 void CFDE_XMLElement::SetInteger(const FX_WCHAR* pwsAttriName, | |
781 int32_t iAttriValue) { | |
782 CFX_WideString wsValue; | |
783 wsValue.Format(L"%d", iAttriValue); | |
784 SetString(pwsAttriName, wsValue); | |
785 } | |
786 FX_FLOAT CFDE_XMLElement::GetFloat(const FX_WCHAR* pwsAttriName, | |
787 FX_FLOAT fDefValue) const { | |
788 int32_t iCount = m_Attributes.GetSize(); | |
789 for (int32_t i = 0; i < iCount; i += 2) { | |
790 if (m_Attributes[i].Compare(pwsAttriName) == 0) { | |
791 return FX_wcstof((const FX_WCHAR*)m_Attributes[i + 1]); | |
792 } | |
793 } | |
794 return fDefValue; | |
795 } | |
796 void CFDE_XMLElement::SetFloat(const FX_WCHAR* pwsAttriName, | |
797 FX_FLOAT fAttriValue) { | |
798 CFX_WideString wsValue; | |
799 wsValue.Format(L"%f", fAttriValue); | |
800 SetString(pwsAttriName, wsValue); | |
801 } | |
802 void CFDE_XMLElement::RemoveAttribute(const FX_WCHAR* pwsAttriName) { | |
803 int32_t iCount = m_Attributes.GetSize(); | |
804 for (int32_t i = 0; i < iCount; i += 2) { | |
805 if (m_Attributes[i].Compare(pwsAttriName) == 0) { | |
806 m_Attributes.RemoveAt(i + 1); | |
807 m_Attributes.RemoveAt(i); | |
808 return; | |
809 } | |
810 } | |
811 } | |
812 void CFDE_XMLElement::GetTextData(CFX_WideString& wsText) const { | |
813 CFX_WideTextBuf buffer; | |
814 CFDE_XMLNode* pChild = m_pChild; | |
815 while (pChild != NULL) { | |
816 switch (pChild->GetType()) { | |
817 case FDE_XMLNODE_Text: | |
818 buffer << ((CFDE_XMLText*)pChild)->m_wsText; | |
819 break; | |
820 case FDE_XMLNODE_CharData: | |
821 buffer << ((CFDE_XMLCharData*)pChild)->m_wsCharData; | |
822 break; | |
823 default: | |
824 break; | |
825 } | |
826 pChild = pChild->m_pNext; | |
827 } | |
828 wsText = buffer.GetWideString(); | |
829 } | |
830 void CFDE_XMLElement::SetTextData(const CFX_WideString& wsText) { | |
831 if (wsText.GetLength() < 1) { | |
832 return; | |
833 } | |
834 InsertChildNode(new CFDE_XMLText(wsText)); | |
835 } | |
836 IFDE_XMLText* IFDE_XMLText::Create(const CFX_WideString& wsText) { | |
837 return (IFDE_XMLText*)new CFDE_XMLText(wsText); | |
838 } | |
839 CFDE_XMLText::CFDE_XMLText(const CFX_WideString& wsText) | |
840 : CFDE_XMLNode(), m_wsText(wsText) {} | |
841 CFDE_XMLNode* CFDE_XMLText::Clone(FX_BOOL bRecursive) { | |
842 CFDE_XMLText* pClone = new CFDE_XMLText(m_wsText); | |
843 return pClone; | |
844 } | |
845 IFDE_XMLCharData* IFDE_XMLCharData::Create(const CFX_WideString& wsCData) { | |
846 return (IFDE_XMLCharData*)new CFDE_XMLCharData(wsCData); | |
847 } | |
848 CFDE_XMLCharData::CFDE_XMLCharData(const CFX_WideString& wsCData) | |
849 : CFDE_XMLDeclaration(), m_wsCharData(wsCData) {} | |
850 CFDE_XMLNode* CFDE_XMLCharData::Clone(FX_BOOL bRecursive) { | |
851 CFDE_XMLCharData* pClone = new CFDE_XMLCharData(m_wsCharData); | |
852 return pClone; | |
853 } | |
854 IFDE_XMLDoc* IFDE_XMLDoc::Create() { | |
855 return (IFDE_XMLDoc*)new CFDE_XMLDoc; | |
856 } | |
857 CFDE_XMLDoc::CFDE_XMLDoc() | |
858 : m_pRoot(NULL), m_pSyntaxParser(NULL), m_pXMLParser(NULL) { | |
859 Reset(TRUE); | |
860 CFDE_XMLInstruction* pXML = new CFDE_XMLInstruction(L"xml"); | |
861 m_pRoot->InsertChildNode(pXML); | |
862 } | |
863 CFDE_XMLDoc::~CFDE_XMLDoc() { | |
864 Reset(FALSE); | |
865 } | |
866 void CFDE_XMLDoc::Reset(FX_BOOL bInitRoot) { | |
867 m_iStatus = 0; | |
868 m_pStream = NULL; | |
869 if (bInitRoot) { | |
870 if (m_pRoot == NULL) { | |
871 m_pRoot = new CFDE_XMLNode; | |
872 } else { | |
873 m_pRoot->DeleteChildren(); | |
874 } | |
875 } else { | |
876 if (m_pRoot != NULL) { | |
877 m_pRoot->Release(); | |
878 m_pRoot = NULL; | |
879 } | |
880 } | |
881 ReleaseParser(); | |
882 } | |
883 void CFDE_XMLDoc::ReleaseParser() { | |
884 if (m_pXMLParser != NULL) { | |
885 m_pXMLParser->Release(); | |
886 m_pXMLParser = NULL; | |
887 } | |
888 if (m_pSyntaxParser != NULL) { | |
889 m_pSyntaxParser->Release(); | |
890 m_pSyntaxParser = NULL; | |
891 } | |
892 } | |
893 FX_BOOL CFDE_XMLDoc::LoadXML(IFX_Stream* pXMLStream, | |
894 int32_t iXMLPlaneSize, | |
895 int32_t iTextDataSize, | |
896 FDE_XMLREADERHANDLER* pHandler) { | |
897 if (pXMLStream == NULL) { | |
898 return FALSE; | |
899 } | |
900 Reset(TRUE); | |
901 iXMLPlaneSize = iXMLPlaneSize / 1024; | |
902 if (iXMLPlaneSize < 1) { | |
903 iXMLPlaneSize = 1; | |
904 } | |
905 iXMLPlaneSize *= 1024; | |
906 if (iXMLPlaneSize < 4096) { | |
907 iXMLPlaneSize = 4096; | |
908 } | |
909 iTextDataSize = iTextDataSize / 128; | |
910 if (iTextDataSize < 1) { | |
911 iTextDataSize = 1; | |
912 } | |
913 iTextDataSize *= 128; | |
914 if (iTextDataSize < 128) { | |
915 iTextDataSize = 128; | |
916 } | |
917 m_pStream = pXMLStream; | |
918 FX_WORD wCodePage = m_pStream->GetCodePage(); | |
919 if (wCodePage != FX_CODEPAGE_UTF16LE && wCodePage != FX_CODEPAGE_UTF16BE && | |
920 wCodePage != FX_CODEPAGE_UTF8) { | |
921 m_pStream->SetCodePage(FX_CODEPAGE_UTF8); | |
922 } | |
923 m_pSyntaxParser = IFDE_XMLSyntaxParser::Create(); | |
924 if (m_pSyntaxParser == NULL) { | |
925 return FALSE; | |
926 } | |
927 m_pSyntaxParser->Init(m_pStream, iXMLPlaneSize, iTextDataSize); | |
928 if (pHandler == NULL) { | |
929 m_pXMLParser = new CFDE_XMLDOMParser(m_pRoot, m_pSyntaxParser); | |
930 } else { | |
931 m_pXMLParser = new CFDE_XMLSAXParser(pHandler, m_pSyntaxParser); | |
932 } | |
933 return TRUE; | |
934 } | |
935 FX_BOOL CFDE_XMLDoc::LoadXML(IFDE_XMLParser* pXMLParser) { | |
936 if (pXMLParser == NULL) { | |
937 return FALSE; | |
938 } | |
939 Reset(TRUE); | |
940 m_pXMLParser = pXMLParser; | |
941 return m_pXMLParser != NULL; | |
942 } | |
943 int32_t CFDE_XMLDoc::DoLoad(IFX_Pause* pPause) { | |
944 if (m_iStatus >= 100) { | |
945 return m_iStatus; | |
946 } | |
947 FXSYS_assert(m_pXMLParser != NULL); | |
948 return m_iStatus = m_pXMLParser->DoParser(pPause); | |
949 } | |
950 void CFDE_XMLDoc::CloseXML() { | |
951 ReleaseParser(); | |
952 } | |
953 void CFDE_XMLDoc::SaveXMLNode(IFX_Stream* pXMLStream, IFDE_XMLNode* pINode) { | |
954 CFDE_XMLNode* pNode = (CFDE_XMLNode*)pINode; | |
955 FXSYS_assert(pXMLStream != NULL && pNode != NULL); | |
956 switch (pNode->GetType()) { | |
957 case FDE_XMLNODE_Instruction: { | |
958 CFX_WideString ws; | |
959 CFDE_XMLInstruction* pInstruction = (CFDE_XMLInstruction*)pNode; | |
960 if (pInstruction->m_wsTarget.CompareNoCase(L"xml") == 0) { | |
961 ws = L"<?xml version=\"1.0\" encoding=\""; | |
962 FX_WORD wCodePage = pXMLStream->GetCodePage(); | |
963 if (wCodePage == FX_CODEPAGE_UTF16LE) { | |
964 ws += L"UTF-16"; | |
965 } else if (wCodePage == FX_CODEPAGE_UTF16BE) { | |
966 ws += L"UTF-16be"; | |
967 } else { | |
968 ws += L"UTF-8"; | |
969 } | |
970 ws += L"\"?>"; | |
971 pXMLStream->WriteString(ws, ws.GetLength()); | |
972 } else { | |
973 ws.Format(L"<?%s", (const FX_WCHAR*)pInstruction->m_wsTarget); | |
974 pXMLStream->WriteString(ws, ws.GetLength()); | |
975 CFX_WideStringArray& attributes = pInstruction->m_Attributes; | |
976 int32_t i, iCount = attributes.GetSize(); | |
977 CFX_WideString wsValue; | |
978 for (i = 0; i < iCount; i += 2) { | |
979 ws = L" "; | |
980 ws += attributes[i]; | |
981 ws += L"=\""; | |
982 wsValue = attributes[i + 1]; | |
983 wsValue.Replace(L"&", L"&"); | |
984 wsValue.Replace(L"<", L"<"); | |
985 wsValue.Replace(L">", L">"); | |
986 wsValue.Replace(L"\'", L"'"); | |
987 wsValue.Replace(L"\"", L"""); | |
988 ws += wsValue; | |
989 ws += L"\""; | |
990 pXMLStream->WriteString(ws, ws.GetLength()); | |
991 } | |
992 CFX_WideStringArray& targetdata = pInstruction->m_TargetData; | |
993 iCount = targetdata.GetSize(); | |
994 for (i = 0; i < iCount; i++) { | |
995 ws = L" \""; | |
996 ws += targetdata[i]; | |
997 ws += L"\""; | |
998 pXMLStream->WriteString(ws, ws.GetLength()); | |
999 } | |
1000 ws = L"?>"; | |
1001 pXMLStream->WriteString(ws, ws.GetLength()); | |
1002 } | |
1003 } break; | |
1004 case FDE_XMLNODE_Element: { | |
1005 CFX_WideString ws; | |
1006 ws = L"<"; | |
1007 ws += ((CFDE_XMLElement*)pNode)->m_wsTag; | |
1008 pXMLStream->WriteString(ws, ws.GetLength()); | |
1009 CFX_WideStringArray& attributes = ((CFDE_XMLElement*)pNode)->m_Attributes; | |
1010 int32_t iCount = attributes.GetSize(); | |
1011 CFX_WideString wsValue; | |
1012 for (int32_t i = 0; i < iCount; i += 2) { | |
1013 ws = L" "; | |
1014 ws += attributes[i]; | |
1015 ws += L"=\""; | |
1016 wsValue = attributes[i + 1]; | |
1017 wsValue.Replace(L"&", L"&"); | |
1018 wsValue.Replace(L"<", L"<"); | |
1019 wsValue.Replace(L">", L">"); | |
1020 wsValue.Replace(L"\'", L"'"); | |
1021 wsValue.Replace(L"\"", L"""); | |
1022 ws += wsValue; | |
1023 ws += L"\""; | |
1024 pXMLStream->WriteString(ws, ws.GetLength()); | |
1025 } | |
1026 if (pNode->m_pChild == NULL) { | |
1027 ws = L"\n/>"; | |
1028 pXMLStream->WriteString(ws, ws.GetLength()); | |
1029 } else { | |
1030 ws = L"\n>"; | |
1031 pXMLStream->WriteString(ws, ws.GetLength()); | |
1032 CFDE_XMLNode* pChild = pNode->m_pChild; | |
1033 while (pChild != NULL) { | |
1034 SaveXMLNode(pXMLStream, (IFDE_XMLNode*)pChild); | |
1035 pChild = pChild->m_pNext; | |
1036 } | |
1037 ws = L"</"; | |
1038 ws += ((CFDE_XMLElement*)pNode)->m_wsTag; | |
1039 ws += L"\n>"; | |
1040 pXMLStream->WriteString(ws, ws.GetLength()); | |
1041 } | |
1042 } break; | |
1043 case FDE_XMLNODE_Text: { | |
1044 CFX_WideString ws = ((CFDE_XMLText*)pNode)->m_wsText; | |
1045 ws.Replace(L"&", L"&"); | |
1046 ws.Replace(L"<", L"<"); | |
1047 ws.Replace(L">", L">"); | |
1048 ws.Replace(L"\'", L"'"); | |
1049 ws.Replace(L"\"", L"""); | |
1050 pXMLStream->WriteString(ws, ws.GetLength()); | |
1051 } break; | |
1052 case FDE_XMLNODE_CharData: { | |
1053 CFX_WideString ws = L"<![CDATA["; | |
1054 ws += ((CFDE_XMLCharData*)pNode)->m_wsCharData; | |
1055 ws += L"]]>"; | |
1056 pXMLStream->WriteString(ws, ws.GetLength()); | |
1057 } break; | |
1058 case FDE_XMLNODE_Unknown: | |
1059 break; | |
1060 default: | |
1061 break; | |
1062 } | |
1063 } | |
1064 void CFDE_XMLDoc::SaveXML(IFX_Stream* pXMLStream, FX_BOOL bSaveBOM) { | |
1065 if (pXMLStream == NULL || pXMLStream == m_pStream) { | |
1066 m_pStream->Seek(FX_STREAMSEEK_Begin, 0); | |
1067 pXMLStream = m_pStream; | |
1068 } | |
1069 FXSYS_assert((pXMLStream->GetAccessModes() & FX_STREAMACCESS_Text) != 0); | |
1070 FXSYS_assert((pXMLStream->GetAccessModes() & FX_STREAMACCESS_Write) != 0); | |
1071 FX_WORD wCodePage = pXMLStream->GetCodePage(); | |
1072 if (wCodePage != FX_CODEPAGE_UTF16LE && wCodePage != FX_CODEPAGE_UTF16BE && | |
1073 wCodePage != FX_CODEPAGE_UTF8) { | |
1074 wCodePage = FX_CODEPAGE_UTF8; | |
1075 pXMLStream->SetCodePage(wCodePage); | |
1076 } | |
1077 if (bSaveBOM) { | |
1078 pXMLStream->WriteString(L"\xFEFF", 1); | |
1079 } | |
1080 CFDE_XMLNode* pNode = m_pRoot->m_pChild; | |
1081 while (pNode != NULL) { | |
1082 SaveXMLNode(pXMLStream, (IFDE_XMLNode*)pNode); | |
1083 pNode = pNode->m_pNext; | |
1084 } | |
1085 if (pXMLStream == m_pStream) { | |
1086 int32_t iPos = pXMLStream->GetPosition(); | |
1087 pXMLStream->SetLength(iPos); | |
1088 } | |
1089 } | |
1090 CFDE_XMLDOMParser::CFDE_XMLDOMParser(CFDE_XMLNode* pRoot, | |
1091 IFDE_XMLSyntaxParser* pParser) | |
1092 : m_pParser(pParser), | |
1093 m_pParent(pRoot), | |
1094 m_pChild(NULL), | |
1095 m_NodeStack(16), | |
1096 m_ws1(), | |
1097 m_ws2() { | |
1098 m_NodeStack.Push(m_pParent); | |
1099 } | |
1100 CFDE_XMLDOMParser::~CFDE_XMLDOMParser() { | |
1101 m_NodeStack.RemoveAll(); | |
1102 m_ws1.Empty(); | |
1103 m_ws2.Empty(); | |
1104 } | |
1105 int32_t CFDE_XMLDOMParser::DoParser(IFX_Pause* pPause) { | |
1106 FX_DWORD dwRet; | |
1107 int32_t iCount = 0; | |
1108 while (TRUE) { | |
1109 dwRet = m_pParser->DoSyntaxParse(); | |
1110 switch (dwRet) { | |
1111 case FDE_XMLSYNTAXSTATUS_InstructionOpen: | |
1112 break; | |
1113 case FDE_XMLSYNTAXSTATUS_InstructionClose: | |
1114 if (m_pChild->GetType() != FDE_XMLNODE_Instruction) { | |
1115 dwRet = FDE_XMLSYNTAXSTATUS_Error; | |
1116 break; | |
1117 } | |
1118 m_pChild = m_pParent; | |
1119 break; | |
1120 case FDE_XMLSYNTAXSTATUS_ElementOpen: | |
1121 case FDE_XMLSYNTAXSTATUS_ElementBreak: | |
1122 break; | |
1123 case FDE_XMLSYNTAXSTATUS_ElementClose: | |
1124 if (m_pChild->GetType() != FDE_XMLNODE_Element) { | |
1125 dwRet = FDE_XMLSYNTAXSTATUS_Error; | |
1126 break; | |
1127 } | |
1128 m_pParser->GetTagName(m_ws1); | |
1129 ((CFDE_XMLElement*)m_pChild)->GetTagName(m_ws2); | |
1130 if (m_ws1.GetLength() > 0 && m_ws1.Compare(m_ws2) != 0) { | |
1131 dwRet = FDE_XMLSYNTAXSTATUS_Error; | |
1132 break; | |
1133 } | |
1134 m_NodeStack.Pop(); | |
1135 if (m_NodeStack.GetSize() < 1) { | |
1136 dwRet = FDE_XMLSYNTAXSTATUS_Error; | |
1137 break; | |
1138 } | |
1139 m_pParent = (CFDE_XMLNode*)*m_NodeStack.GetTopElement(); | |
1140 m_pChild = m_pParent; | |
1141 iCount++; | |
1142 break; | |
1143 case FDE_XMLSYNTAXSTATUS_TargetName: | |
1144 m_pParser->GetTargetName(m_ws1); | |
1145 m_pChild = new CFDE_XMLInstruction(m_ws1); | |
1146 m_pParent->InsertChildNode(m_pChild); | |
1147 m_ws1.Empty(); | |
1148 break; | |
1149 case FDE_XMLSYNTAXSTATUS_TagName: | |
1150 m_pParser->GetTagName(m_ws1); | |
1151 m_pChild = new CFDE_XMLElement(m_ws1); | |
1152 m_pParent->InsertChildNode(m_pChild); | |
1153 m_NodeStack.Push(m_pChild); | |
1154 m_pParent = m_pChild; | |
1155 break; | |
1156 case FDE_XMLSYNTAXSTATUS_AttriName: | |
1157 m_pParser->GetAttributeName(m_ws1); | |
1158 break; | |
1159 case FDE_XMLSYNTAXSTATUS_AttriValue: | |
1160 if (m_pChild == NULL) { | |
1161 dwRet = FDE_XMLSYNTAXSTATUS_Error; | |
1162 break; | |
1163 } | |
1164 m_pParser->GetAttributeName(m_ws2); | |
1165 if (m_pChild->GetType() == FDE_XMLNODE_Element) { | |
1166 ((CFDE_XMLElement*)m_pChild)->SetString(m_ws1, m_ws2); | |
1167 } else if (m_pChild->GetType() == FDE_XMLNODE_Instruction) { | |
1168 ((CFDE_XMLInstruction*)m_pChild)->SetString(m_ws1, m_ws2); | |
1169 } | |
1170 m_ws1.Empty(); | |
1171 break; | |
1172 case FDE_XMLSYNTAXSTATUS_Text: | |
1173 m_pParser->GetTextData(m_ws1); | |
1174 m_pChild = new CFDE_XMLText(m_ws1); | |
1175 m_pParent->InsertChildNode(m_pChild); | |
1176 m_pChild = m_pParent; | |
1177 break; | |
1178 case FDE_XMLSYNTAXSTATUS_CData: | |
1179 m_pParser->GetTextData(m_ws1); | |
1180 m_pChild = new CFDE_XMLCharData(m_ws1); | |
1181 m_pParent->InsertChildNode(m_pChild); | |
1182 m_pChild = m_pParent; | |
1183 break; | |
1184 case FDE_XMLSYNTAXSTATUS_TargetData: | |
1185 if (m_pChild == NULL || | |
1186 m_pChild->GetType() != FDE_XMLNODE_Instruction) { | |
1187 dwRet = FDE_XMLSYNTAXSTATUS_Error; | |
1188 break; | |
1189 } | |
1190 if (!m_ws1.IsEmpty()) { | |
1191 ((CFDE_XMLInstruction*)m_pChild)->AppendData(m_ws1); | |
1192 } | |
1193 m_pParser->GetTargetData(m_ws1); | |
1194 ((CFDE_XMLInstruction*)m_pChild)->AppendData(m_ws1); | |
1195 m_ws1.Empty(); | |
1196 break; | |
1197 default: | |
1198 break; | |
1199 } | |
1200 if (dwRet == FDE_XMLSYNTAXSTATUS_Error || | |
1201 dwRet == FDE_XMLSYNTAXSTATUS_EOS) { | |
1202 break; | |
1203 } | |
1204 if (pPause != NULL && iCount > 500 && pPause->NeedToPauseNow()) { | |
1205 break; | |
1206 } | |
1207 } | |
1208 return m_pParser->GetStatus(); | |
1209 } | |
1210 CFDE_XMLSAXParser::CFDE_XMLSAXParser(FDE_XMLREADERHANDLER* pHandler, | |
1211 IFDE_XMLSyntaxParser* pParser) | |
1212 : m_pHandler(pHandler), | |
1213 m_pParser(pParser), | |
1214 m_TagStack(16), | |
1215 m_pTagTop(NULL), | |
1216 m_ws1(), | |
1217 m_ws2() {} | |
1218 CFDE_XMLSAXParser::~CFDE_XMLSAXParser() { | |
1219 m_TagStack.RemoveAll(); | |
1220 m_ws1.Empty(); | |
1221 m_ws2.Empty(); | |
1222 } | |
1223 int32_t CFDE_XMLSAXParser::DoParser(IFX_Pause* pPause) { | |
1224 FX_DWORD dwRet = 0; | |
1225 int32_t iCount = 0; | |
1226 while (TRUE) { | |
1227 dwRet = m_pParser->DoSyntaxParse(); | |
1228 switch (dwRet) { | |
1229 case FDE_XMLSYNTAXSTATUS_ElementBreak: | |
1230 if (m_pTagTop == NULL) { | |
1231 dwRet = FDE_XMLSYNTAXSTATUS_Error; | |
1232 break; | |
1233 } | |
1234 if (m_pTagTop->eType == FDE_XMLNODE_Element) { | |
1235 m_pHandler->OnTagBreak(m_pHandler, m_pTagTop->wsTagName); | |
1236 } | |
1237 break; | |
1238 case FDE_XMLSYNTAXSTATUS_ElementClose: | |
1239 if (m_pTagTop == NULL || m_pTagTop->eType != FDE_XMLNODE_Element) { | |
1240 dwRet = FDE_XMLSYNTAXSTATUS_Error; | |
1241 break; | |
1242 } | |
1243 m_pParser->GetTagName(m_ws1); | |
1244 if (m_ws1.GetLength() > 0 && m_ws1.Compare(m_pTagTop->wsTagName) != 0) { | |
1245 dwRet = FDE_XMLSYNTAXSTATUS_Error; | |
1246 break; | |
1247 } else if (m_ws1.GetLength() == 0) { | |
1248 m_pHandler->OnTagBreak(m_pHandler, m_pTagTop->wsTagName); | |
1249 } | |
1250 m_pHandler->OnTagClose(m_pHandler, m_pTagTop->wsTagName); | |
1251 Pop(); | |
1252 iCount++; | |
1253 break; | |
1254 case FDE_XMLSYNTAXSTATUS_TargetName: { | |
1255 m_pParser->GetTargetName(m_ws1); | |
1256 CFDE_XMLTAG xmlTag; | |
1257 xmlTag.wsTagName = m_ws1; | |
1258 xmlTag.eType = FDE_XMLNODE_Instruction; | |
1259 Push(xmlTag); | |
1260 m_pHandler->OnTagEnter(m_pHandler, FDE_XMLNODE_Instruction, | |
1261 m_pTagTop->wsTagName); | |
1262 m_ws1.Empty(); | |
1263 } break; | |
1264 case FDE_XMLSYNTAXSTATUS_TagName: { | |
1265 m_pParser->GetTargetName(m_ws1); | |
1266 CFDE_XMLTAG xmlTag; | |
1267 xmlTag.wsTagName = m_ws1; | |
1268 xmlTag.eType = FDE_XMLNODE_Element; | |
1269 Push(xmlTag); | |
1270 m_pHandler->OnTagEnter(m_pHandler, FDE_XMLNODE_Element, | |
1271 m_pTagTop->wsTagName); | |
1272 } break; | |
1273 case FDE_XMLSYNTAXSTATUS_AttriName: | |
1274 m_pParser->GetTargetName(m_ws1); | |
1275 break; | |
1276 case FDE_XMLSYNTAXSTATUS_AttriValue: | |
1277 m_pParser->GetAttributeName(m_ws2); | |
1278 if (m_pTagTop == NULL) { | |
1279 dwRet = FDE_XMLSYNTAXSTATUS_Error; | |
1280 break; | |
1281 } | |
1282 if (m_pTagTop->eType == FDE_XMLNODE_Element) { | |
1283 m_pHandler->OnAttribute(m_pHandler, m_ws1, m_ws2); | |
1284 } | |
1285 m_ws1.Empty(); | |
1286 break; | |
1287 case FDE_XMLSYNTAXSTATUS_CData: | |
1288 m_pParser->GetTextData(m_ws1); | |
1289 m_pHandler->OnData(m_pHandler, FDE_XMLNODE_CharData, m_ws1); | |
1290 break; | |
1291 case FDE_XMLSYNTAXSTATUS_Text: | |
1292 m_pParser->GetTextData(m_ws1); | |
1293 m_pHandler->OnData(m_pHandler, FDE_XMLNODE_Text, m_ws1); | |
1294 break; | |
1295 case FDE_XMLSYNTAXSTATUS_TargetData: | |
1296 m_pParser->GetTargetData(m_ws1); | |
1297 m_pHandler->OnData(m_pHandler, FDE_XMLNODE_Instruction, m_ws1); | |
1298 m_ws1.Empty(); | |
1299 break; | |
1300 default: | |
1301 break; | |
1302 } | |
1303 if (dwRet == FDE_XMLSYNTAXSTATUS_Error || | |
1304 dwRet == FDE_XMLSYNTAXSTATUS_EOS) { | |
1305 break; | |
1306 } | |
1307 if (pPause != NULL && iCount > 500 && pPause->NeedToPauseNow()) { | |
1308 break; | |
1309 } | |
1310 } | |
1311 return m_pParser->GetStatus(); | |
1312 } | |
1313 inline void CFDE_XMLSAXParser::Push(const CFDE_XMLTAG& xmlTag) { | |
1314 m_TagStack.Push(xmlTag); | |
1315 m_pTagTop = m_TagStack.GetTopElement(); | |
1316 } | |
1317 inline void CFDE_XMLSAXParser::Pop() { | |
1318 m_TagStack.Pop(); | |
1319 m_pTagTop = m_TagStack.GetTopElement(); | |
1320 } | |
1321 | |
1322 CFDE_BlockBuffer::CFDE_BlockBuffer(int32_t iAllocStep) | |
1323 : m_iDataLength(0), | |
1324 m_iBufferSize(0), | |
1325 m_iAllocStep(iAllocStep), | |
1326 m_iStartPosition(0) {} | |
1327 CFDE_BlockBuffer::~CFDE_BlockBuffer() { | |
1328 ClearBuffer(); | |
1329 } | |
1330 FX_WCHAR* CFDE_BlockBuffer::GetAvailableBlock(int32_t& iIndexInBlock) { | |
1331 iIndexInBlock = 0; | |
1332 if (!m_BlockArray.GetSize()) { | |
1333 return nullptr; | |
1334 } | |
1335 int32_t iRealIndex = m_iStartPosition + m_iDataLength; | |
1336 if (iRealIndex == m_iBufferSize) { | |
1337 FX_WCHAR* pBlock = FX_Alloc(FX_WCHAR, m_iAllocStep); | |
1338 m_BlockArray.Add(pBlock); | |
1339 m_iBufferSize += m_iAllocStep; | |
1340 return pBlock; | |
1341 } | |
1342 iIndexInBlock = iRealIndex % m_iAllocStep; | |
1343 return (FX_WCHAR*)m_BlockArray[iRealIndex / m_iAllocStep]; | |
1344 } | |
1345 FX_BOOL CFDE_BlockBuffer::InitBuffer(int32_t iBufferSize) { | |
1346 ClearBuffer(); | |
1347 int32_t iNumOfBlock = (iBufferSize - 1) / m_iAllocStep + 1; | |
1348 for (int32_t i = 0; i < iNumOfBlock; i++) { | |
1349 m_BlockArray.Add(FX_Alloc(FX_WCHAR, m_iAllocStep)); | |
1350 } | |
1351 m_iBufferSize = iNumOfBlock * m_iAllocStep; | |
1352 return TRUE; | |
1353 } | |
1354 void CFDE_BlockBuffer::SetTextChar(int32_t iIndex, FX_WCHAR ch) { | |
1355 if (iIndex < 0) { | |
1356 return; | |
1357 } | |
1358 int32_t iRealIndex = m_iStartPosition + iIndex; | |
1359 int32_t iBlockIndex = iRealIndex / m_iAllocStep; | |
1360 int32_t iInnerIndex = iRealIndex % m_iAllocStep; | |
1361 int32_t iBlockSize = m_BlockArray.GetSize(); | |
1362 if (iBlockIndex >= iBlockSize) { | |
1363 int32_t iNewBlocks = iBlockIndex - iBlockSize + 1; | |
1364 do { | |
1365 FX_WCHAR* pBlock = FX_Alloc(FX_WCHAR, m_iAllocStep); | |
1366 m_BlockArray.Add(pBlock); | |
1367 m_iBufferSize += m_iAllocStep; | |
1368 } while (--iNewBlocks); | |
1369 } | |
1370 FX_WCHAR* pTextData = (FX_WCHAR*)m_BlockArray[iBlockIndex]; | |
1371 *(pTextData + iInnerIndex) = ch; | |
1372 if (m_iDataLength <= iIndex) { | |
1373 m_iDataLength = iIndex + 1; | |
1374 } | |
1375 } | |
1376 int32_t CFDE_BlockBuffer::DeleteTextChars(int32_t iCount, FX_BOOL bDirection) { | |
1377 if (iCount <= 0) { | |
1378 return m_iDataLength; | |
1379 } | |
1380 if (iCount >= m_iDataLength) { | |
1381 Reset(FALSE); | |
1382 return 0; | |
1383 } | |
1384 if (bDirection) { | |
1385 m_iStartPosition += iCount; | |
1386 m_iDataLength -= iCount; | |
1387 } else { | |
1388 m_iDataLength -= iCount; | |
1389 } | |
1390 return m_iDataLength; | |
1391 } | |
1392 void CFDE_BlockBuffer::GetTextData(CFX_WideString& wsTextData, | |
1393 int32_t iStart, | |
1394 int32_t iLength) const { | |
1395 wsTextData.Empty(); | |
1396 int32_t iMaybeDataLength = m_iBufferSize - 1 - m_iStartPosition; | |
1397 if (iStart < 0 || iStart > iMaybeDataLength) { | |
1398 return; | |
1399 } | |
1400 if (iLength == -1 || iLength > iMaybeDataLength) { | |
1401 iLength = iMaybeDataLength; | |
1402 } | |
1403 if (iLength <= 0) { | |
1404 return; | |
1405 } | |
1406 FX_WCHAR* pBuf = wsTextData.GetBuffer(iLength); | |
1407 if (!pBuf) { | |
1408 return; | |
1409 } | |
1410 int32_t iStartBlockIndex = 0; | |
1411 int32_t iStartInnerIndex = 0; | |
1412 TextDataIndex2BufIndex(iStart, iStartBlockIndex, iStartInnerIndex); | |
1413 int32_t iEndBlockIndex = 0; | |
1414 int32_t iEndInnerIndex = 0; | |
1415 TextDataIndex2BufIndex(iStart + iLength, iEndBlockIndex, iEndInnerIndex); | |
1416 int32_t iPointer = 0; | |
1417 for (int32_t i = iStartBlockIndex; i <= iEndBlockIndex; i++) { | |
1418 int32_t iBufferPointer = 0; | |
1419 int32_t iCopyLength = m_iAllocStep; | |
1420 if (i == iStartBlockIndex) { | |
1421 iCopyLength -= iStartInnerIndex; | |
1422 iBufferPointer = iStartInnerIndex; | |
1423 } | |
1424 if (i == iEndBlockIndex) { | |
1425 iCopyLength -= ((m_iAllocStep - 1) - iEndInnerIndex); | |
1426 } | |
1427 FX_WCHAR* pBlockBuf = (FX_WCHAR*)m_BlockArray[i]; | |
1428 FXSYS_memcpy(pBuf + iPointer, pBlockBuf + iBufferPointer, | |
1429 iCopyLength * sizeof(FX_WCHAR)); | |
1430 iPointer += iCopyLength; | |
1431 } | |
1432 wsTextData.ReleaseBuffer(iLength); | |
1433 } | |
1434 void CFDE_BlockBuffer::TextDataIndex2BufIndex(const int32_t iIndex, | |
1435 int32_t& iBlockIndex, | |
1436 int32_t& iInnerIndex) const { | |
1437 FXSYS_assert(iIndex >= 0); | |
1438 int32_t iRealIndex = m_iStartPosition + iIndex; | |
1439 iBlockIndex = iRealIndex / m_iAllocStep; | |
1440 iInnerIndex = iRealIndex % m_iAllocStep; | |
1441 } | |
1442 void CFDE_BlockBuffer::ClearBuffer() { | |
1443 m_iBufferSize = 0; | |
1444 int32_t iSize = m_BlockArray.GetSize(); | |
1445 for (int32_t i = 0; i < iSize; i++) { | |
1446 FX_Free(m_BlockArray[i]); | |
1447 m_BlockArray[i] = NULL; | |
1448 } | |
1449 m_BlockArray.RemoveAll(); | |
1450 } | |
1451 | |
1452 IFDE_XMLSyntaxParser* IFDE_XMLSyntaxParser::Create() { | |
1453 return new CFDE_XMLSyntaxParser; | |
1454 } | |
1455 | |
1456 CFDE_XMLSyntaxParser::CFDE_XMLSyntaxParser() | |
1457 : m_pStream(nullptr), | |
1458 m_iXMLPlaneSize(-1), | |
1459 m_iCurrentPos(0), | |
1460 m_iCurrentNodeNum(-1), | |
1461 m_iLastNodeNum(-1), | |
1462 m_iParsedChars(0), | |
1463 m_iParsedBytes(0), | |
1464 m_pBuffer(nullptr), | |
1465 m_iBufferChars(0), | |
1466 m_bEOS(FALSE), | |
1467 m_pStart(nullptr), | |
1468 m_pEnd(nullptr), | |
1469 m_XMLNodeStack(16), | |
1470 m_iAllocStep(m_BlockBuffer.GetAllocStep()), | |
1471 m_iDataLength(m_BlockBuffer.GetDataLengthRef()), | |
1472 m_pCurrentBlock(nullptr), | |
1473 m_iIndexInBlock(0), | |
1474 m_iTextDataLength(0), | |
1475 m_dwStatus(FDE_XMLSYNTAXSTATUS_None), | |
1476 m_dwMode(FDE_XMLSYNTAXMODE_Text), | |
1477 m_wQuotationMark(0), | |
1478 m_iEntityStart(-1), | |
1479 m_SkipStack(16) { | |
1480 m_CurNode.iNodeNum = -1; | |
1481 m_CurNode.eNodeType = FDE_XMLNODE_Unknown; | |
1482 } | |
1483 void CFDE_XMLSyntaxParser::Init(IFX_Stream* pStream, | |
1484 int32_t iXMLPlaneSize, | |
1485 int32_t iTextDataSize) { | |
1486 FXSYS_assert(m_pStream == NULL && m_pBuffer == NULL); | |
1487 FXSYS_assert(pStream != NULL && iXMLPlaneSize > 0); | |
1488 int32_t iStreamLength = pStream->GetLength(); | |
1489 FXSYS_assert(iStreamLength > 0); | |
1490 m_pStream = pStream; | |
1491 m_iXMLPlaneSize = std::min(iXMLPlaneSize, iStreamLength); | |
1492 uint8_t bom[4]; | |
1493 m_iCurrentPos = m_pStream->GetBOM(bom); | |
1494 FXSYS_assert(m_pBuffer == NULL); | |
1495 m_pBuffer = FX_Alloc(FX_WCHAR, m_iXMLPlaneSize); | |
1496 m_pStart = m_pEnd = m_pBuffer; | |
1497 FXSYS_assert(!m_BlockBuffer.IsInitialized()); | |
1498 m_BlockBuffer.InitBuffer(); | |
1499 m_pCurrentBlock = m_BlockBuffer.GetAvailableBlock(m_iIndexInBlock); | |
1500 m_iParsedBytes = m_iParsedChars = 0; | |
1501 m_iBufferChars = 0; | |
1502 } | |
1503 FX_DWORD CFDE_XMLSyntaxParser::DoSyntaxParse() { | |
1504 if (m_dwStatus == FDE_XMLSYNTAXSTATUS_Error || | |
1505 m_dwStatus == FDE_XMLSYNTAXSTATUS_EOS) { | |
1506 return m_dwStatus; | |
1507 } | |
1508 FXSYS_assert(m_pStream && m_pBuffer && m_BlockBuffer.IsInitialized()); | |
1509 int32_t iStreamLength = m_pStream->GetLength(); | |
1510 int32_t iPos; | |
1511 FX_WCHAR ch; | |
1512 FX_DWORD dwStatus = FDE_XMLSYNTAXSTATUS_None; | |
1513 while (TRUE) { | |
1514 if (m_pStart >= m_pEnd) { | |
1515 if (m_bEOS || m_iCurrentPos >= iStreamLength) { | |
1516 m_dwStatus = FDE_XMLSYNTAXSTATUS_EOS; | |
1517 return m_dwStatus; | |
1518 } | |
1519 m_iParsedChars += (m_pEnd - m_pBuffer); | |
1520 m_iParsedBytes = m_iCurrentPos; | |
1521 if (m_pStream->GetPosition() != m_iCurrentPos) { | |
1522 m_pStream->Seek(FX_STREAMSEEK_Begin, m_iCurrentPos); | |
1523 } | |
1524 m_iBufferChars = | |
1525 m_pStream->ReadString(m_pBuffer, m_iXMLPlaneSize, m_bEOS); | |
1526 iPos = m_pStream->GetPosition(); | |
1527 if (m_iBufferChars < 1) { | |
1528 m_iCurrentPos = iStreamLength; | |
1529 m_dwStatus = FDE_XMLSYNTAXSTATUS_EOS; | |
1530 return m_dwStatus; | |
1531 } | |
1532 m_iCurrentPos = iPos; | |
1533 m_pStart = m_pBuffer; | |
1534 m_pEnd = m_pBuffer + m_iBufferChars; | |
1535 } | |
1536 while (m_pStart < m_pEnd) { | |
1537 ch = *m_pStart; | |
1538 switch (m_dwMode) { | |
1539 case FDE_XMLSYNTAXMODE_Text: | |
1540 if (ch == L'<') { | |
1541 if (m_iDataLength > 0) { | |
1542 m_iTextDataLength = m_iDataLength; | |
1543 m_BlockBuffer.Reset(); | |
1544 m_pCurrentBlock = | |
1545 m_BlockBuffer.GetAvailableBlock(m_iIndexInBlock); | |
1546 m_iEntityStart = -1; | |
1547 dwStatus = FDE_XMLSYNTAXSTATUS_Text; | |
1548 } else { | |
1549 m_pStart++; | |
1550 m_dwMode = FDE_XMLSYNTAXMODE_Node; | |
1551 } | |
1552 } else { | |
1553 ParseTextChar(ch); | |
1554 } | |
1555 break; | |
1556 case FDE_XMLSYNTAXMODE_Node: | |
1557 if (ch == L'!') { | |
1558 m_pStart++; | |
1559 m_dwMode = FDE_XMLSYNTAXMODE_SkipCommentOrDecl; | |
1560 } else if (ch == L'/') { | |
1561 m_pStart++; | |
1562 m_dwMode = FDE_XMLSYNTAXMODE_CloseElement; | |
1563 } else if (ch == L'?') { | |
1564 m_iLastNodeNum++; | |
1565 m_iCurrentNodeNum = m_iLastNodeNum; | |
1566 m_CurNode.iNodeNum = m_iLastNodeNum; | |
1567 m_CurNode.eNodeType = FDE_XMLNODE_Instruction; | |
1568 m_XMLNodeStack.Push(m_CurNode); | |
1569 m_pStart++; | |
1570 m_dwMode = FDE_XMLSYNTAXMODE_Target; | |
1571 dwStatus = FDE_XMLSYNTAXSTATUS_InstructionOpen; | |
1572 } else { | |
1573 m_iLastNodeNum++; | |
1574 m_iCurrentNodeNum = m_iLastNodeNum; | |
1575 m_CurNode.iNodeNum = m_iLastNodeNum; | |
1576 m_CurNode.eNodeType = FDE_XMLNODE_Element; | |
1577 m_XMLNodeStack.Push(m_CurNode); | |
1578 m_dwMode = FDE_XMLSYNTAXMODE_Tag; | |
1579 dwStatus = FDE_XMLSYNTAXSTATUS_ElementOpen; | |
1580 } | |
1581 break; | |
1582 case FDE_XMLSYNTAXMODE_Target: | |
1583 case FDE_XMLSYNTAXMODE_Tag: | |
1584 if (!FDE_IsXMLNameChar(ch, m_iDataLength < 1)) { | |
1585 if (m_iDataLength < 1) { | |
1586 m_dwStatus = FDE_XMLSYNTAXSTATUS_Error; | |
1587 return m_dwStatus; | |
1588 } else { | |
1589 m_iTextDataLength = m_iDataLength; | |
1590 m_BlockBuffer.Reset(); | |
1591 m_pCurrentBlock = | |
1592 m_BlockBuffer.GetAvailableBlock(m_iIndexInBlock); | |
1593 if (m_dwMode != FDE_XMLSYNTAXMODE_Target) { | |
1594 dwStatus = FDE_XMLSYNTAXSTATUS_TagName; | |
1595 } else { | |
1596 dwStatus = FDE_XMLSYNTAXSTATUS_TargetName; | |
1597 } | |
1598 m_dwMode = FDE_XMLSYNTAXMODE_AttriName; | |
1599 } | |
1600 } else { | |
1601 if (m_iIndexInBlock == m_iAllocStep) { | |
1602 m_pCurrentBlock = | |
1603 m_BlockBuffer.GetAvailableBlock(m_iIndexInBlock); | |
1604 if (!m_pCurrentBlock) { | |
1605 return FDE_XMLSYNTAXSTATUS_Error; | |
1606 } | |
1607 } | |
1608 m_pCurrentBlock[m_iIndexInBlock++] = ch; | |
1609 m_iDataLength++; | |
1610 m_pStart++; | |
1611 } | |
1612 break; | |
1613 case FDE_XMLSYNTAXMODE_AttriName: | |
1614 if (m_iDataLength < 1 && FDE_IsXMLWhiteSpace(ch)) { | |
1615 m_pStart++; | |
1616 break; | |
1617 } | |
1618 if (!FDE_IsXMLNameChar(ch, m_iDataLength < 1)) { | |
1619 if (m_iDataLength < 1) { | |
1620 if (m_CurNode.eNodeType == FDE_XMLNODE_Element) { | |
1621 if (ch == L'>' || ch == L'/') { | |
1622 m_dwMode = FDE_XMLSYNTAXMODE_BreakElement; | |
1623 break; | |
1624 } | |
1625 } else if (m_CurNode.eNodeType == FDE_XMLNODE_Instruction) { | |
1626 if (ch == L'?') { | |
1627 m_dwMode = FDE_XMLSYNTAXMODE_CloseInstruction; | |
1628 m_pStart++; | |
1629 } else { | |
1630 m_dwMode = FDE_XMLSYNTAXMODE_TargetData; | |
1631 } | |
1632 break; | |
1633 } | |
1634 m_dwStatus = FDE_XMLSYNTAXSTATUS_Error; | |
1635 return m_dwStatus; | |
1636 } else { | |
1637 if (m_CurNode.eNodeType == FDE_XMLNODE_Instruction) { | |
1638 if (ch != '=' && !FDE_IsXMLWhiteSpace(ch)) { | |
1639 m_dwMode = FDE_XMLSYNTAXMODE_TargetData; | |
1640 break; | |
1641 } | |
1642 } | |
1643 m_iTextDataLength = m_iDataLength; | |
1644 m_BlockBuffer.Reset(); | |
1645 m_pCurrentBlock = | |
1646 m_BlockBuffer.GetAvailableBlock(m_iIndexInBlock); | |
1647 m_dwMode = FDE_XMLSYNTAXMODE_AttriEqualSign; | |
1648 dwStatus = FDE_XMLSYNTAXSTATUS_AttriName; | |
1649 } | |
1650 } else { | |
1651 if (m_iIndexInBlock == m_iAllocStep) { | |
1652 m_pCurrentBlock = | |
1653 m_BlockBuffer.GetAvailableBlock(m_iIndexInBlock); | |
1654 if (!m_pCurrentBlock) { | |
1655 return FDE_XMLSYNTAXSTATUS_Error; | |
1656 } | |
1657 } | |
1658 m_pCurrentBlock[m_iIndexInBlock++] = ch; | |
1659 m_iDataLength++; | |
1660 m_pStart++; | |
1661 } | |
1662 break; | |
1663 case FDE_XMLSYNTAXMODE_AttriEqualSign: | |
1664 if (FDE_IsXMLWhiteSpace(ch)) { | |
1665 m_pStart++; | |
1666 break; | |
1667 } | |
1668 if (ch != L'=') { | |
1669 if (m_CurNode.eNodeType == FDE_XMLNODE_Instruction) { | |
1670 m_dwMode = FDE_XMLSYNTAXMODE_TargetData; | |
1671 break; | |
1672 } | |
1673 m_dwStatus = FDE_XMLSYNTAXSTATUS_Error; | |
1674 return m_dwStatus; | |
1675 } else { | |
1676 m_dwMode = FDE_XMLSYNTAXMODE_AttriQuotation; | |
1677 m_pStart++; | |
1678 } | |
1679 break; | |
1680 case FDE_XMLSYNTAXMODE_AttriQuotation: | |
1681 if (FDE_IsXMLWhiteSpace(ch)) { | |
1682 m_pStart++; | |
1683 break; | |
1684 } | |
1685 if (ch != L'\"' && ch != L'\'') { | |
1686 m_dwStatus = FDE_XMLSYNTAXSTATUS_Error; | |
1687 return m_dwStatus; | |
1688 } else { | |
1689 m_wQuotationMark = ch; | |
1690 m_dwMode = FDE_XMLSYNTAXMODE_AttriValue; | |
1691 m_pStart++; | |
1692 } | |
1693 break; | |
1694 case FDE_XMLSYNTAXMODE_AttriValue: | |
1695 if (ch == m_wQuotationMark) { | |
1696 if (m_iEntityStart > -1) { | |
1697 m_dwStatus = FDE_XMLSYNTAXSTATUS_Error; | |
1698 return m_dwStatus; | |
1699 } | |
1700 m_iTextDataLength = m_iDataLength; | |
1701 m_wQuotationMark = 0; | |
1702 m_BlockBuffer.Reset(); | |
1703 m_pCurrentBlock = m_BlockBuffer.GetAvailableBlock(m_iIndexInBlock); | |
1704 m_pStart++; | |
1705 m_dwMode = FDE_XMLSYNTAXMODE_AttriName; | |
1706 dwStatus = FDE_XMLSYNTAXSTATUS_AttriValue; | |
1707 } else { | |
1708 ParseTextChar(ch); | |
1709 } | |
1710 break; | |
1711 case FDE_XMLSYNTAXMODE_CloseInstruction: | |
1712 if (ch != L'>') { | |
1713 if (m_iIndexInBlock == m_iAllocStep) { | |
1714 m_pCurrentBlock = | |
1715 m_BlockBuffer.GetAvailableBlock(m_iIndexInBlock); | |
1716 if (!m_pCurrentBlock) { | |
1717 return FDE_XMLSYNTAXSTATUS_Error; | |
1718 } | |
1719 } | |
1720 m_pCurrentBlock[m_iIndexInBlock++] = ch; | |
1721 m_iDataLength++; | |
1722 m_dwMode = FDE_XMLSYNTAXMODE_TargetData; | |
1723 } else if (m_iDataLength > 0) { | |
1724 m_iTextDataLength = m_iDataLength; | |
1725 m_BlockBuffer.Reset(); | |
1726 m_pCurrentBlock = m_BlockBuffer.GetAvailableBlock(m_iIndexInBlock); | |
1727 dwStatus = FDE_XMLSYNTAXSTATUS_TargetData; | |
1728 } else { | |
1729 m_pStart++; | |
1730 FDE_XMLNODE* pXMLNode = m_XMLNodeStack.GetTopElement(); | |
1731 if (pXMLNode == NULL) { | |
1732 m_dwStatus = FDE_XMLSYNTAXSTATUS_Error; | |
1733 return m_dwStatus; | |
1734 } | |
1735 m_XMLNodeStack.Pop(); | |
1736 pXMLNode = m_XMLNodeStack.GetTopElement(); | |
1737 if (pXMLNode == NULL) { | |
1738 m_CurNode.iNodeNum = -1; | |
1739 m_CurNode.eNodeType = FDE_XMLNODE_Unknown; | |
1740 } else { | |
1741 m_CurNode = *pXMLNode; | |
1742 } | |
1743 m_iCurrentNodeNum = m_CurNode.iNodeNum; | |
1744 m_BlockBuffer.Reset(); | |
1745 m_pCurrentBlock = m_BlockBuffer.GetAvailableBlock(m_iIndexInBlock); | |
1746 m_dwMode = FDE_XMLSYNTAXMODE_Text; | |
1747 dwStatus = FDE_XMLSYNTAXSTATUS_InstructionClose; | |
1748 } | |
1749 break; | |
1750 case FDE_XMLSYNTAXMODE_BreakElement: | |
1751 if (ch == L'>') { | |
1752 m_dwMode = FDE_XMLSYNTAXMODE_Text; | |
1753 dwStatus = FDE_XMLSYNTAXSTATUS_ElementBreak; | |
1754 } else if (ch == L'/') { | |
1755 m_dwMode = FDE_XMLSYNTAXMODE_CloseElement; | |
1756 } else { | |
1757 m_dwStatus = FDE_XMLSYNTAXSTATUS_Error; | |
1758 return m_dwStatus; | |
1759 } | |
1760 m_pStart++; | |
1761 break; | |
1762 case FDE_XMLSYNTAXMODE_CloseElement: | |
1763 if (!FDE_IsXMLNameChar(ch, m_iDataLength < 1)) { | |
1764 if (ch == L'>') { | |
1765 FDE_XMLNODE* pXMLNode = m_XMLNodeStack.GetTopElement(); | |
1766 if (pXMLNode == NULL) { | |
1767 m_dwStatus = FDE_XMLSYNTAXSTATUS_Error; | |
1768 return m_dwStatus; | |
1769 } | |
1770 m_XMLNodeStack.Pop(); | |
1771 pXMLNode = m_XMLNodeStack.GetTopElement(); | |
1772 if (pXMLNode == NULL) { | |
1773 m_CurNode.iNodeNum = -1; | |
1774 m_CurNode.eNodeType = FDE_XMLNODE_Unknown; | |
1775 } else { | |
1776 m_CurNode = *pXMLNode; | |
1777 } | |
1778 m_iCurrentNodeNum = m_CurNode.iNodeNum; | |
1779 m_iTextDataLength = m_iDataLength; | |
1780 m_BlockBuffer.Reset(); | |
1781 m_pCurrentBlock = | |
1782 m_BlockBuffer.GetAvailableBlock(m_iIndexInBlock); | |
1783 m_dwMode = FDE_XMLSYNTAXMODE_Text; | |
1784 dwStatus = FDE_XMLSYNTAXSTATUS_ElementClose; | |
1785 } else if (!FDE_IsXMLWhiteSpace(ch)) { | |
1786 m_dwStatus = FDE_XMLSYNTAXSTATUS_Error; | |
1787 return m_dwStatus; | |
1788 } | |
1789 } else { | |
1790 if (m_iIndexInBlock == m_iAllocStep) { | |
1791 m_pCurrentBlock = | |
1792 m_BlockBuffer.GetAvailableBlock(m_iIndexInBlock); | |
1793 if (!m_pCurrentBlock) { | |
1794 return FDE_XMLSYNTAXSTATUS_Error; | |
1795 } | |
1796 } | |
1797 m_pCurrentBlock[m_iIndexInBlock++] = ch; | |
1798 m_iDataLength++; | |
1799 } | |
1800 m_pStart++; | |
1801 break; | |
1802 case FDE_XMLSYNTAXMODE_SkipCommentOrDecl: | |
1803 if (ch == '-') { | |
1804 m_dwMode = FDE_XMLSYNTAXMODE_SkipComment; | |
1805 } else { | |
1806 m_dwMode = FDE_XMLSYNTAXMODE_SkipDeclNode; | |
1807 m_SkipChar = L'>'; | |
1808 m_SkipStack.Push(L'>'); | |
1809 } | |
1810 break; | |
1811 case FDE_XMLSYNTAXMODE_SkipDeclNode: | |
1812 if (m_SkipChar == L'\'' || m_SkipChar == L'\"') { | |
1813 m_pStart++; | |
1814 if (ch != m_SkipChar) { | |
1815 break; | |
1816 } | |
1817 m_SkipStack.Pop(); | |
1818 FX_DWORD* pDWord = m_SkipStack.GetTopElement(); | |
1819 if (pDWord == NULL) { | |
1820 m_dwMode = FDE_XMLSYNTAXMODE_Text; | |
1821 } else { | |
1822 m_SkipChar = (FX_WCHAR)*pDWord; | |
1823 } | |
1824 } else { | |
1825 switch (ch) { | |
1826 case L'<': | |
1827 m_SkipChar = L'>'; | |
1828 m_SkipStack.Push(L'>'); | |
1829 break; | |
1830 case L'[': | |
1831 m_SkipChar = L']'; | |
1832 m_SkipStack.Push(L']'); | |
1833 break; | |
1834 case L'(': | |
1835 m_SkipChar = L')'; | |
1836 m_SkipStack.Push(L')'); | |
1837 break; | |
1838 case L'\'': | |
1839 m_SkipChar = L'\''; | |
1840 m_SkipStack.Push(L'\''); | |
1841 break; | |
1842 case L'\"': | |
1843 m_SkipChar = L'\"'; | |
1844 m_SkipStack.Push(L'\"'); | |
1845 break; | |
1846 default: | |
1847 if (ch == m_SkipChar) { | |
1848 m_SkipStack.Pop(); | |
1849 FX_DWORD* pDWord = m_SkipStack.GetTopElement(); | |
1850 if (pDWord == NULL) { | |
1851 if (m_iDataLength >= 9) { | |
1852 CFX_WideString wsHeader; | |
1853 m_BlockBuffer.GetTextData(wsHeader, 0, 7); | |
1854 if (wsHeader.Equal(FX_WSTRC(L"[CDATA["))) { | |
1855 CFX_WideString wsTailer; | |
1856 m_BlockBuffer.GetTextData(wsTailer, m_iDataLength - 2, | |
1857 2); | |
1858 if (wsTailer.Equal(FX_WSTRC(L"]]"))) { | |
1859 m_BlockBuffer.DeleteTextChars(7, TRUE); | |
1860 m_BlockBuffer.DeleteTextChars(2, FALSE); | |
1861 dwStatus = FDE_XMLSYNTAXSTATUS_CData; | |
1862 } | |
1863 } | |
1864 } | |
1865 m_iTextDataLength = m_iDataLength; | |
1866 m_BlockBuffer.Reset(); | |
1867 m_pCurrentBlock = | |
1868 m_BlockBuffer.GetAvailableBlock(m_iIndexInBlock); | |
1869 m_dwMode = FDE_XMLSYNTAXMODE_Text; | |
1870 } else { | |
1871 m_SkipChar = (FX_WCHAR)*pDWord; | |
1872 } | |
1873 } | |
1874 break; | |
1875 } | |
1876 if (m_SkipStack.GetSize() > 0) { | |
1877 if (m_iIndexInBlock == m_iAllocStep) { | |
1878 m_pCurrentBlock = | |
1879 m_BlockBuffer.GetAvailableBlock(m_iIndexInBlock); | |
1880 if (!m_pCurrentBlock) { | |
1881 return FDE_XMLSYNTAXSTATUS_Error; | |
1882 } | |
1883 } | |
1884 m_pCurrentBlock[m_iIndexInBlock++] = ch; | |
1885 m_iDataLength++; | |
1886 } | |
1887 m_pStart++; | |
1888 } | |
1889 break; | |
1890 case FDE_XMLSYNTAXMODE_SkipComment: | |
1891 if (ch == L'-') { | |
1892 if (m_iIndexInBlock == m_iAllocStep) { | |
1893 m_pCurrentBlock = | |
1894 m_BlockBuffer.GetAvailableBlock(m_iIndexInBlock); | |
1895 if (!m_pCurrentBlock) { | |
1896 return FDE_XMLSYNTAXSTATUS_Error; | |
1897 } | |
1898 } | |
1899 m_pCurrentBlock[m_iIndexInBlock++] = L'-'; | |
1900 m_iDataLength++; | |
1901 } else if (ch == L'>') { | |
1902 if (m_iDataLength > 1) { | |
1903 m_BlockBuffer.Reset(); | |
1904 m_pCurrentBlock = | |
1905 m_BlockBuffer.GetAvailableBlock(m_iIndexInBlock); | |
1906 m_dwMode = FDE_XMLSYNTAXMODE_Text; | |
1907 } | |
1908 } else { | |
1909 m_BlockBuffer.Reset(); | |
1910 m_pCurrentBlock = m_BlockBuffer.GetAvailableBlock(m_iIndexInBlock); | |
1911 } | |
1912 m_pStart++; | |
1913 break; | |
1914 case FDE_XMLSYNTAXMODE_TargetData: | |
1915 if (FDE_IsXMLWhiteSpace(ch)) { | |
1916 if (m_iDataLength < 1) { | |
1917 m_pStart++; | |
1918 break; | |
1919 } else if (m_wQuotationMark == 0) { | |
1920 m_iTextDataLength = m_iDataLength; | |
1921 m_wQuotationMark = 0; | |
1922 m_BlockBuffer.Reset(); | |
1923 m_pCurrentBlock = | |
1924 m_BlockBuffer.GetAvailableBlock(m_iIndexInBlock); | |
1925 m_pStart++; | |
1926 dwStatus = FDE_XMLSYNTAXSTATUS_TargetData; | |
1927 break; | |
1928 } | |
1929 } | |
1930 if (ch == '?') { | |
1931 m_dwMode = FDE_XMLSYNTAXMODE_CloseInstruction; | |
1932 m_pStart++; | |
1933 } else if (ch == '\"') { | |
1934 if (m_wQuotationMark == 0) { | |
1935 m_wQuotationMark = ch; | |
1936 m_pStart++; | |
1937 } else if (ch == m_wQuotationMark) { | |
1938 m_iTextDataLength = m_iDataLength; | |
1939 m_wQuotationMark = 0; | |
1940 m_BlockBuffer.Reset(); | |
1941 m_pCurrentBlock = | |
1942 m_BlockBuffer.GetAvailableBlock(m_iIndexInBlock); | |
1943 m_pStart++; | |
1944 dwStatus = FDE_XMLSYNTAXSTATUS_TargetData; | |
1945 } else { | |
1946 m_dwStatus = FDE_XMLSYNTAXSTATUS_Error; | |
1947 return m_dwStatus; | |
1948 } | |
1949 } else { | |
1950 if (m_iIndexInBlock == m_iAllocStep) { | |
1951 m_pCurrentBlock = | |
1952 m_BlockBuffer.GetAvailableBlock(m_iIndexInBlock); | |
1953 if (!m_pCurrentBlock) { | |
1954 return FDE_XMLSYNTAXSTATUS_Error; | |
1955 } | |
1956 } | |
1957 m_pCurrentBlock[m_iIndexInBlock++] = ch; | |
1958 m_iDataLength++; | |
1959 m_pStart++; | |
1960 } | |
1961 break; | |
1962 default: | |
1963 break; | |
1964 } | |
1965 if (dwStatus != FDE_XMLSYNTAXSTATUS_None) { | |
1966 return dwStatus; | |
1967 } | |
1968 } | |
1969 } | |
1970 return 0; | |
1971 } | |
1972 | |
1973 CFDE_XMLSyntaxParser::~CFDE_XMLSyntaxParser() { | |
1974 if (m_pCurrentBlock) { | |
1975 m_pCurrentBlock = NULL; | |
1976 } | |
1977 FX_Free(m_pBuffer); | |
1978 } | |
1979 | |
1980 int32_t CFDE_XMLSyntaxParser::GetStatus() const { | |
1981 if (m_pStream == NULL) { | |
1982 return -1; | |
1983 } | |
1984 int32_t iStreamLength = m_pStream->GetLength(); | |
1985 if (iStreamLength < 1) { | |
1986 return 100; | |
1987 } | |
1988 if (m_dwStatus == FDE_XMLSYNTAXSTATUS_Error) { | |
1989 return -1; | |
1990 } | |
1991 if (m_dwStatus == FDE_XMLSYNTAXSTATUS_EOS) { | |
1992 return 100; | |
1993 } | |
1994 return m_iParsedBytes * 100 / iStreamLength; | |
1995 } | |
1996 static int32_t FX_GetUTF8EncodeLength(const FX_WCHAR* pSrc, int32_t iSrcLen) { | |
1997 FX_DWORD unicode = 0; | |
1998 int32_t iDstNum = 0; | |
1999 while (iSrcLen-- > 0) { | |
2000 unicode = *pSrc++; | |
2001 int nbytes = 0; | |
2002 if ((FX_DWORD)unicode < 0x80) { | |
2003 nbytes = 1; | |
2004 } else if ((FX_DWORD)unicode < 0x800) { | |
2005 nbytes = 2; | |
2006 } else if ((FX_DWORD)unicode < 0x10000) { | |
2007 nbytes = 3; | |
2008 } else if ((FX_DWORD)unicode < 0x200000) { | |
2009 nbytes = 4; | |
2010 } else if ((FX_DWORD)unicode < 0x4000000) { | |
2011 nbytes = 5; | |
2012 } else { | |
2013 nbytes = 6; | |
2014 } | |
2015 iDstNum += nbytes; | |
2016 } | |
2017 return iDstNum; | |
2018 } | |
2019 FX_FILESIZE CFDE_XMLSyntaxParser::GetCurrentBinaryPos() const { | |
2020 if (m_pStream == NULL) { | |
2021 return 0; | |
2022 } | |
2023 int32_t nSrcLen = m_pStart - m_pBuffer; | |
2024 int32_t nDstLen = FX_GetUTF8EncodeLength(m_pBuffer, nSrcLen); | |
2025 return m_iParsedBytes + nDstLen; | |
2026 } | |
2027 | |
2028 void CFDE_XMLSyntaxParser::ParseTextChar(FX_WCHAR ch) { | |
2029 if (m_iIndexInBlock == m_iAllocStep) { | |
2030 m_pCurrentBlock = m_BlockBuffer.GetAvailableBlock(m_iIndexInBlock); | |
2031 if (!m_pCurrentBlock) { | |
2032 return; | |
2033 } | |
2034 } | |
2035 m_pCurrentBlock[m_iIndexInBlock++] = ch; | |
2036 m_iDataLength++; | |
2037 if (m_iEntityStart > -1 && ch == L';') { | |
2038 CFX_WideString csEntity; | |
2039 m_BlockBuffer.GetTextData(csEntity, m_iEntityStart + 1, | |
2040 (m_iDataLength - 1) - m_iEntityStart - 1); | |
2041 int32_t iLen = csEntity.GetLength(); | |
2042 if (iLen > 0) { | |
2043 if (csEntity[0] == L'#') { | |
2044 ch = 0; | |
2045 FX_WCHAR w; | |
2046 if (iLen > 1 && csEntity[1] == L'x') { | |
2047 for (int32_t i = 2; i < iLen; i++) { | |
2048 w = csEntity[i]; | |
2049 if (w >= L'0' && w <= L'9') { | |
2050 ch = (ch << 4) + w - L'0'; | |
2051 } else if (w >= L'A' && w <= L'F') { | |
2052 ch = (ch << 4) + w - 55; | |
2053 } else if (w >= L'a' && w <= L'f') { | |
2054 ch = (ch << 4) + w - 87; | |
2055 } else { | |
2056 break; | |
2057 } | |
2058 } | |
2059 } else { | |
2060 for (int32_t i = 1; i < iLen; i++) { | |
2061 w = csEntity[i]; | |
2062 if (w < L'0' || w > L'9') { | |
2063 break; | |
2064 } | |
2065 ch = ch * 10 + w - L'0'; | |
2066 } | |
2067 } | |
2068 if (ch != 0) { | |
2069 m_BlockBuffer.SetTextChar(m_iEntityStart, ch); | |
2070 m_iEntityStart++; | |
2071 } | |
2072 } else { | |
2073 if (csEntity.Compare(L"amp") == 0) { | |
2074 m_BlockBuffer.SetTextChar(m_iEntityStart, L'&'); | |
2075 m_iEntityStart++; | |
2076 } else if (csEntity.Compare(L"lt") == 0) { | |
2077 m_BlockBuffer.SetTextChar(m_iEntityStart, L'<'); | |
2078 m_iEntityStart++; | |
2079 } else if (csEntity.Compare(L"gt") == 0) { | |
2080 m_BlockBuffer.SetTextChar(m_iEntityStart, L'>'); | |
2081 m_iEntityStart++; | |
2082 } else if (csEntity.Compare(L"apos") == 0) { | |
2083 m_BlockBuffer.SetTextChar(m_iEntityStart, L'\''); | |
2084 m_iEntityStart++; | |
2085 } else if (csEntity.Compare(L"quot") == 0) { | |
2086 m_BlockBuffer.SetTextChar(m_iEntityStart, L'\"'); | |
2087 m_iEntityStart++; | |
2088 } | |
2089 } | |
2090 } | |
2091 m_BlockBuffer.DeleteTextChars(m_iDataLength - m_iEntityStart, FALSE); | |
2092 m_pCurrentBlock = m_BlockBuffer.GetAvailableBlock(m_iIndexInBlock); | |
2093 m_iEntityStart = -1; | |
2094 } else { | |
2095 if (m_iEntityStart < 0 && ch == L'&') { | |
2096 m_iEntityStart = m_iDataLength - 1; | |
2097 } | |
2098 } | |
2099 m_pStart++; | |
2100 } | |
OLD | NEW |