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 <algorithm> | |
8 | |
9 #include "xfa/src/foxitlib.h" | |
10 #include "fde_xml.h" | |
11 #ifdef __cplusplus | |
12 extern "C" { | |
13 #endif | |
14 #define FDE_XMLVALIDCHARRANGENUM 5 | |
15 static FX_WCHAR g_XMLValidCharRange[FDE_XMLVALIDCHARRANGENUM][2] = { | |
16 {0x09, 0x09}, | |
17 {0x0A, 0x0A}, | |
18 {0x0D, 0x0D}, | |
19 {0x20, 0xD7FF}, | |
20 {0xE000, 0xFFFD}}; | |
21 FX_BOOL FDE_IsXMLValidChar(FX_WCHAR ch) { | |
22 int32_t iStart = 0, iEnd = FDE_XMLVALIDCHARRANGENUM - 1, iMid; | |
23 while (iStart <= iEnd) { | |
24 iMid = (iStart + iEnd) / 2; | |
25 if (ch < g_XMLValidCharRange[iMid][0]) { | |
26 iEnd = iMid - 1; | |
27 } else if (ch > g_XMLValidCharRange[iMid][1]) { | |
28 iStart = iMid + 1; | |
29 } else { | |
30 return TRUE; | |
31 } | |
32 } | |
33 return FALSE; | |
34 } | |
35 FX_BOOL FDE_IsXMLWhiteSpace(FX_WCHAR ch) { | |
36 return ch == L' ' || ch == 0x0A || ch == 0x0D || ch == 0x09; | |
37 } | |
38 typedef struct _FDE_XMLNAMECHAR { | |
39 FX_WCHAR wStart; | |
40 FX_WCHAR wEnd; | |
41 FX_BOOL bStartChar; | |
42 } FDE_XMLNAMECHAR; | |
43 #define FDE_XMLNAMECHARSNUM 20 | |
44 static FDE_XMLNAMECHAR g_XMLNameChars[FDE_XMLNAMECHARSNUM] = { | |
45 {L'-', L'.', FALSE}, {L'0', L'9', FALSE}, {L':', L':', FALSE}, | |
46 {L'A', L'Z', TRUE}, {L'_', L'_', TRUE}, {L'a', L'z', TRUE}, | |
47 {0xB7, 0xB7, FALSE}, {0xC0, 0xD6, TRUE}, {0xD8, 0xF6, TRUE}, | |
48 {0xF8, 0x02FF, TRUE}, {0x0300, 0x036F, FALSE}, {0x0370, 0x037D, TRUE}, | |
49 {0x037F, 0x1FFF, TRUE}, {0x200C, 0x200D, TRUE}, {0x203F, 0x2040, FALSE}, | |
50 {0x2070, 0x218F, TRUE}, {0x2C00, 0x2FEF, TRUE}, {0x3001, 0xD7FF, TRUE}, | |
51 {0xF900, 0xFDCF, TRUE}, {0xFDF0, 0xFFFD, TRUE}, | |
52 }; | |
53 FX_BOOL FDE_IsXMLNameChar(FX_WCHAR ch, FX_BOOL bFirstChar) { | |
54 int32_t iStart = 0, iEnd = FDE_XMLNAMECHARSNUM - 1, iMid; | |
55 while (iStart <= iEnd) { | |
56 iMid = (iStart + iEnd) / 2; | |
57 if (ch < g_XMLNameChars[iMid].wStart) { | |
58 iEnd = iMid - 1; | |
59 } else if (ch > g_XMLNameChars[iMid].wEnd) { | |
60 iStart = iMid + 1; | |
61 } else { | |
62 if (bFirstChar) { | |
63 return g_XMLNameChars[iMid].bStartChar; | |
64 } | |
65 return TRUE; | |
66 } | |
67 } | |
68 return FALSE; | |
69 } | |
70 #ifdef __cplusplus | |
71 } | |
72 #endif | |
73 CFDE_XMLNode::CFDE_XMLNode() | |
74 : m_pParent(NULL), m_pChild(NULL), m_pPrior(NULL), m_pNext(NULL) {} | |
75 CFDE_XMLNode::~CFDE_XMLNode() { | |
76 DeleteChildren(); | |
77 } | |
78 void CFDE_XMLNode::DeleteChildren() { | |
79 CFDE_XMLNode *pChild = m_pChild, *pTemp; | |
80 while (pChild != NULL) { | |
81 pTemp = pChild->m_pNext; | |
82 pChild->Release(); | |
83 pChild = pTemp; | |
84 } | |
85 m_pChild = NULL; | |
86 } | |
87 int32_t CFDE_XMLNode::CountChildNodes() const { | |
88 int32_t iCount = 0; | |
89 CFDE_XMLNode* pChild = m_pChild; | |
90 while (pChild != NULL) { | |
91 iCount++; | |
92 pChild = pChild->m_pNext; | |
93 } | |
94 return iCount; | |
95 } | |
96 CFDE_XMLNode* CFDE_XMLNode::GetChildNode(int32_t index) const { | |
97 CFDE_XMLNode* pChild = m_pChild; | |
98 while (pChild != NULL) { | |
99 if (index == 0) { | |
100 return pChild; | |
101 } | |
102 index--; | |
103 pChild = pChild->m_pNext; | |
104 } | |
105 return NULL; | |
106 } | |
107 int32_t CFDE_XMLNode::GetChildNodeIndex(CFDE_XMLNode* pNode) const { | |
108 int32_t index = 0; | |
109 CFDE_XMLNode* pChild = m_pChild; | |
110 while (pChild != NULL) { | |
111 if (pChild == pNode) { | |
112 return index; | |
113 } | |
114 index++; | |
115 pChild = pChild->m_pNext; | |
116 } | |
117 return -1; | |
118 } | |
119 CFDE_XMLNode* CFDE_XMLNode::GetPath(const FX_WCHAR* pPath, | |
120 int32_t iLength, | |
121 FX_BOOL bQualifiedName) const { | |
122 FXSYS_assert(pPath != NULL); | |
123 if (iLength < 0) { | |
124 iLength = FXSYS_wcslen(pPath); | |
125 } | |
126 if (iLength == 0) { | |
127 return NULL; | |
128 } | |
129 CFX_WideString csPath; | |
130 const FX_WCHAR* pStart = pPath; | |
131 const FX_WCHAR* pEnd = pPath + iLength; | |
132 FX_WCHAR ch; | |
133 while (pStart < pEnd) { | |
134 ch = *pStart++; | |
135 if (ch == L'/') { | |
136 break; | |
137 } else { | |
138 csPath += ch; | |
139 } | |
140 } | |
141 iLength -= pStart - pPath; | |
142 CFDE_XMLNode* pFind = NULL; | |
143 if (csPath.GetLength() < 1) { | |
144 pFind = GetNodeItem(IFDE_XMLNode::Root); | |
145 } else if (csPath.Compare(L"..") == 0) { | |
146 pFind = m_pParent; | |
147 } else if (csPath.Compare(L".") == 0) { | |
148 pFind = (CFDE_XMLNode*)this; | |
149 } else { | |
150 CFX_WideString wsTag; | |
151 CFDE_XMLNode* pNode = m_pChild; | |
152 while (pNode != NULL) { | |
153 if (pNode->GetType() == FDE_XMLNODE_Element) { | |
154 if (bQualifiedName) { | |
155 ((CFDE_XMLElement*)pNode)->GetTagName(wsTag); | |
156 } else { | |
157 ((CFDE_XMLElement*)pNode)->GetLocalTagName(wsTag); | |
158 } | |
159 if (wsTag.Compare(csPath) == 0) { | |
160 if (iLength < 1) { | |
161 pFind = pNode; | |
162 } else { | |
163 pFind = pNode->GetPath(pStart, iLength, bQualifiedName); | |
164 } | |
165 if (pFind != NULL) { | |
166 return pFind; | |
167 } | |
168 } | |
169 } | |
170 pNode = pNode->m_pNext; | |
171 } | |
172 } | |
173 if (pFind == NULL || iLength < 1) { | |
174 return pFind; | |
175 } | |
176 return pFind->GetPath(pStart, iLength, bQualifiedName); | |
177 } | |
178 int32_t CFDE_XMLNode::InsertChildNode(CFDE_XMLNode* pNode, int32_t index) { | |
179 FXSYS_assert(pNode != NULL); | |
180 pNode->m_pParent = this; | |
181 if (m_pChild == NULL) { | |
182 m_pChild = pNode; | |
183 pNode->m_pPrior = NULL; | |
184 pNode->m_pNext = NULL; | |
185 return 0; | |
186 } else if (index == 0) { | |
187 pNode->m_pNext = m_pChild; | |
188 pNode->m_pPrior = NULL; | |
189 m_pChild->m_pPrior = pNode; | |
190 m_pChild = pNode; | |
191 return 0; | |
192 } | |
193 int32_t iCount = 0; | |
194 CFDE_XMLNode* pFind = m_pChild; | |
195 while (++iCount != index && pFind->m_pNext != NULL) { | |
196 pFind = pFind->m_pNext; | |
197 } | |
198 pNode->m_pPrior = pFind; | |
199 pNode->m_pNext = pFind->m_pNext; | |
200 if (pFind->m_pNext != NULL) { | |
201 pFind->m_pNext->m_pPrior = pNode; | |
202 } | |
203 pFind->m_pNext = pNode; | |
204 return iCount; | |
205 } | |
206 void CFDE_XMLNode::RemoveChildNode(CFDE_XMLNode* pNode) { | |
207 FXSYS_assert(m_pChild != NULL && pNode != NULL); | |
208 if (m_pChild == pNode) { | |
209 m_pChild = pNode->m_pNext; | |
210 } else { | |
211 pNode->m_pPrior->m_pNext = pNode->m_pNext; | |
212 } | |
213 if (pNode->m_pNext != NULL) { | |
214 pNode->m_pNext->m_pPrior = pNode->m_pPrior; | |
215 } | |
216 pNode->m_pParent = NULL; | |
217 pNode->m_pNext = NULL; | |
218 pNode->m_pPrior = NULL; | |
219 } | |
220 CFDE_XMLNode* CFDE_XMLNode::GetNodeItem(IFDE_XMLNode::NodeItem eItem) const { | |
221 switch (eItem) { | |
222 case IFDE_XMLNode::Root: { | |
223 CFDE_XMLNode* pParent = (CFDE_XMLNode*)this; | |
224 while (pParent->m_pParent != NULL) { | |
225 pParent = pParent->m_pParent; | |
226 } | |
227 return pParent; | |
228 } | |
229 case IFDE_XMLNode::Parent: | |
230 return m_pParent; | |
231 case IFDE_XMLNode::FirstSibling: { | |
232 CFDE_XMLNode* pItem = (CFDE_XMLNode*)this; | |
233 while (pItem->m_pPrior != NULL) { | |
234 pItem = pItem->m_pPrior; | |
235 } | |
236 return pItem == (CFDE_XMLNode*)this ? NULL : pItem; | |
237 } | |
238 case IFDE_XMLNode::PriorSibling: | |
239 return m_pPrior; | |
240 case IFDE_XMLNode::NextSibling: | |
241 return m_pNext; | |
242 case IFDE_XMLNode::LastSibling: { | |
243 CFDE_XMLNode* pItem = (CFDE_XMLNode*)this; | |
244 while (pItem->m_pNext != NULL) { | |
245 pItem = pItem->m_pNext; | |
246 } | |
247 return pItem == (CFDE_XMLNode*)this ? NULL : pItem; | |
248 } | |
249 case IFDE_XMLNode::FirstNeighbor: { | |
250 CFDE_XMLNode* pParent = (CFDE_XMLNode*)this; | |
251 while (pParent->m_pParent != NULL) { | |
252 pParent = pParent->m_pParent; | |
253 } | |
254 return pParent == (CFDE_XMLNode*)this ? NULL : pParent; | |
255 } | |
256 case IFDE_XMLNode::PriorNeighbor: { | |
257 if (m_pPrior == NULL) { | |
258 return m_pParent; | |
259 } | |
260 CFDE_XMLNode* pItem = m_pPrior; | |
261 while (CFDE_XMLNode* pTemp = pItem->m_pChild) { | |
262 pItem = pTemp; | |
263 while ((pTemp = pItem->m_pNext) != NULL) { | |
264 pItem = pTemp; | |
265 } | |
266 } | |
267 return pItem; | |
268 } | |
269 case IFDE_XMLNode::NextNeighbor: { | |
270 if (m_pChild != NULL) { | |
271 return m_pChild; | |
272 } | |
273 if (m_pNext != NULL) { | |
274 return m_pNext; | |
275 } | |
276 CFDE_XMLNode* pItem = m_pParent; | |
277 while (pItem != NULL) { | |
278 if (pItem->m_pNext != NULL) { | |
279 return pItem->m_pNext; | |
280 } | |
281 pItem = pItem->m_pParent; | |
282 } | |
283 return NULL; | |
284 } | |
285 case IFDE_XMLNode::LastNeighbor: { | |
286 CFDE_XMLNode* pItem = (CFDE_XMLNode*)this; | |
287 while (pItem->m_pParent != NULL) { | |
288 pItem = pItem->m_pParent; | |
289 } | |
290 while (TRUE) { | |
291 while (pItem->m_pNext != NULL) { | |
292 pItem = pItem->m_pNext; | |
293 } | |
294 if (pItem->m_pChild == NULL) { | |
295 break; | |
296 } | |
297 pItem = pItem->m_pChild; | |
298 } | |
299 return pItem == (CFDE_XMLNode*)this ? NULL : pItem; | |
300 } | |
301 case IFDE_XMLNode::FirstChild: | |
302 return m_pChild; | |
303 case IFDE_XMLNode::LastChild: { | |
304 if (m_pChild == NULL) { | |
305 return NULL; | |
306 } | |
307 CFDE_XMLNode* pChild = m_pChild; | |
308 while (pChild->m_pNext != NULL) { | |
309 pChild = pChild->m_pNext; | |
310 } | |
311 return pChild; | |
312 } | |
313 default: | |
314 break; | |
315 } | |
316 return NULL; | |
317 } | |
318 int32_t CFDE_XMLNode::GetNodeLevel() const { | |
319 int32_t iLevel = 0; | |
320 CFDE_XMLNode* pItem = (CFDE_XMLNode*)this; | |
321 while ((pItem = pItem->m_pParent) != NULL) { | |
322 iLevel++; | |
323 } | |
324 return iLevel; | |
325 } | |
326 FX_BOOL CFDE_XMLNode::InsertNodeItem(IFDE_XMLNode::NodeItem eItem, | |
327 CFDE_XMLNode* pNode) { | |
328 FXSYS_assert(pNode != NULL); | |
329 switch (eItem) { | |
330 case IFDE_XMLNode::NextSibling: { | |
331 pNode->m_pParent = m_pParent; | |
332 pNode->m_pNext = m_pNext; | |
333 pNode->m_pPrior = this; | |
334 if (m_pNext) { | |
335 m_pNext->m_pPrior = pNode; | |
336 } | |
337 m_pNext = pNode; | |
338 return TRUE; | |
339 } | |
340 case IFDE_XMLNode::PriorSibling: { | |
341 pNode->m_pParent = m_pParent; | |
342 pNode->m_pNext = this; | |
343 pNode->m_pPrior = m_pPrior; | |
344 if (m_pPrior) { | |
345 m_pPrior->m_pNext = pNode; | |
346 } else if (m_pParent) { | |
347 m_pParent->m_pChild = pNode; | |
348 } | |
349 m_pPrior = pNode; | |
350 return TRUE; | |
351 } | |
352 default: | |
353 return FALSE; | |
354 } | |
355 return FALSE; | |
356 } | |
357 CFDE_XMLNode* CFDE_XMLNode::RemoveNodeItem(IFDE_XMLNode::NodeItem eItem) { | |
358 CFDE_XMLNode* pNode = NULL; | |
359 switch (eItem) { | |
360 case IFDE_XMLNode::NextSibling: | |
361 if (m_pNext) { | |
362 pNode = m_pNext; | |
363 m_pNext = pNode->m_pNext; | |
364 if (m_pNext) { | |
365 m_pNext->m_pPrior = this; | |
366 } | |
367 pNode->m_pParent = NULL; | |
368 pNode->m_pNext = NULL; | |
369 pNode->m_pPrior = NULL; | |
370 } | |
371 break; | |
372 default: | |
373 break; | |
374 } | |
375 return pNode; | |
376 } | |
377 CFDE_XMLNode* CFDE_XMLNode::Clone(FX_BOOL bRecursive) { | |
378 return NULL; | |
379 } | |
380 void CFDE_XMLNode::SaveXMLNode(IFX_Stream* pXMLStream) { | |
381 CFDE_XMLNode* pNode = (CFDE_XMLNode*)this; | |
382 FXSYS_assert(pXMLStream != NULL && pNode != NULL); | |
383 switch (pNode->GetType()) { | |
384 case FDE_XMLNODE_Instruction: { | |
385 CFX_WideString ws; | |
386 CFDE_XMLInstruction* pInstruction = (CFDE_XMLInstruction*)pNode; | |
387 if (pInstruction->m_wsTarget.CompareNoCase(L"xml") == 0) { | |
388 ws = L"<?xml version=\"1.0\" encoding=\""; | |
389 FX_WORD wCodePage = pXMLStream->GetCodePage(); | |
390 if (wCodePage == FX_CODEPAGE_UTF16LE) { | |
391 ws += L"UTF-16"; | |
392 } else if (wCodePage == FX_CODEPAGE_UTF16BE) { | |
393 ws += L"UTF-16be"; | |
394 } else { | |
395 ws += L"UTF-8"; | |
396 } | |
397 ws += L"\"?>"; | |
398 pXMLStream->WriteString(ws, ws.GetLength()); | |
399 } else { | |
400 ws.Format(L"<?%s", (const FX_WCHAR*)pInstruction->m_wsTarget); | |
401 pXMLStream->WriteString(ws, ws.GetLength()); | |
402 CFX_WideStringArray& attributes = pInstruction->m_Attributes; | |
403 int32_t i, iCount = attributes.GetSize(); | |
404 CFX_WideString wsValue; | |
405 for (i = 0; i < iCount; i += 2) { | |
406 ws = L" "; | |
407 ws += attributes[i]; | |
408 ws += L"=\""; | |
409 wsValue = attributes[i + 1]; | |
410 wsValue.Replace(L"&", L"&"); | |
411 wsValue.Replace(L"<", L"<"); | |
412 wsValue.Replace(L">", L">"); | |
413 wsValue.Replace(L"\'", L"'"); | |
414 wsValue.Replace(L"\"", L"""); | |
415 ws += wsValue; | |
416 ws += L"\""; | |
417 pXMLStream->WriteString(ws, ws.GetLength()); | |
418 } | |
419 CFX_WideStringArray& targetdata = pInstruction->m_TargetData; | |
420 iCount = targetdata.GetSize(); | |
421 for (i = 0; i < iCount; i++) { | |
422 ws = L" \""; | |
423 ws += targetdata[i]; | |
424 ws += L"\""; | |
425 pXMLStream->WriteString(ws, ws.GetLength()); | |
426 } | |
427 ws = L"?>"; | |
428 pXMLStream->WriteString(ws, ws.GetLength()); | |
429 } | |
430 } break; | |
431 case FDE_XMLNODE_Element: { | |
432 CFX_WideString ws; | |
433 ws = L"<"; | |
434 ws += ((CFDE_XMLElement*)pNode)->m_wsTag; | |
435 pXMLStream->WriteString(ws, ws.GetLength()); | |
436 CFX_WideStringArray& attributes = ((CFDE_XMLElement*)pNode)->m_Attributes; | |
437 int32_t iCount = attributes.GetSize(); | |
438 CFX_WideString wsValue; | |
439 for (int32_t i = 0; i < iCount; i += 2) { | |
440 ws = L" "; | |
441 ws += attributes[i]; | |
442 ws += L"=\""; | |
443 wsValue = attributes[i + 1]; | |
444 wsValue.Replace(L"&", L"&"); | |
445 wsValue.Replace(L"<", L"<"); | |
446 wsValue.Replace(L">", L">"); | |
447 wsValue.Replace(L"\'", L"'"); | |
448 wsValue.Replace(L"\"", L"""); | |
449 ws += wsValue; | |
450 ws += L"\""; | |
451 pXMLStream->WriteString(ws, ws.GetLength()); | |
452 } | |
453 if (pNode->m_pChild == NULL) { | |
454 ws = L"\n/>"; | |
455 pXMLStream->WriteString(ws, ws.GetLength()); | |
456 } else { | |
457 ws = L"\n>"; | |
458 pXMLStream->WriteString(ws, ws.GetLength()); | |
459 CFDE_XMLNode* pChild = pNode->m_pChild; | |
460 while (pChild != NULL) { | |
461 pChild->SaveXMLNode(pXMLStream); | |
462 pChild = pChild->m_pNext; | |
463 } | |
464 ws = L"</"; | |
465 ws += ((CFDE_XMLElement*)pNode)->m_wsTag; | |
466 ws += L"\n>"; | |
467 pXMLStream->WriteString(ws, ws.GetLength()); | |
468 } | |
469 } break; | |
470 case FDE_XMLNODE_Text: { | |
471 CFX_WideString ws = ((CFDE_XMLText*)pNode)->m_wsText; | |
472 ws.Replace(L"&", L"&"); | |
473 ws.Replace(L"<", L"<"); | |
474 ws.Replace(L">", L">"); | |
475 ws.Replace(L"\'", L"'"); | |
476 ws.Replace(L"\"", L"""); | |
477 pXMLStream->WriteString(ws, ws.GetLength()); | |
478 } break; | |
479 case FDE_XMLNODE_CharData: { | |
480 CFX_WideString ws = L"<![CDATA["; | |
481 ws += ((CFDE_XMLCharData*)pNode)->m_wsCharData; | |
482 ws += L"]]>"; | |
483 pXMLStream->WriteString(ws, ws.GetLength()); | |
484 } break; | |
485 case FDE_XMLNODE_Unknown: | |
486 break; | |
487 default: | |
488 break; | |
489 } | |
490 } | |
491 void CFDE_XMLNode::CloneChildren(CFDE_XMLNode* pClone) { | |
492 if (!m_pChild) { | |
493 return; | |
494 } | |
495 CFDE_XMLNode* pNext = m_pChild; | |
496 CFDE_XMLNode* pCloneNext = pNext->Clone(TRUE); | |
497 pClone->InsertChildNode(pCloneNext); | |
498 pNext = pNext->m_pNext; | |
499 while (pNext) { | |
500 CFDE_XMLNode* pChild = pNext->Clone(TRUE); | |
501 pCloneNext->InsertNodeItem(IFDE_XMLNode::NextSibling, pChild); | |
502 pCloneNext = pChild; | |
503 pNext = pNext->m_pNext; | |
504 } | |
505 } | |
506 IFDE_XMLInstruction* IFDE_XMLInstruction::Create( | |
507 const CFX_WideString& wsTarget) { | |
508 return (IFDE_XMLInstruction*)new CFDE_XMLInstruction(wsTarget); | |
509 } | |
510 CFDE_XMLInstruction::CFDE_XMLInstruction(const CFX_WideString& wsTarget) | |
511 : m_wsTarget(wsTarget) { | |
512 FXSYS_assert(m_wsTarget.GetLength() > 0); | |
513 } | |
514 CFDE_XMLNode* CFDE_XMLInstruction::Clone(FX_BOOL bRecursive) { | |
515 CFDE_XMLInstruction* pClone = new CFDE_XMLInstruction(m_wsTarget); | |
516 if (!pClone) { | |
517 return pClone; | |
518 } | |
519 pClone->m_Attributes.Copy(m_Attributes); | |
520 pClone->m_TargetData.Copy(m_TargetData); | |
521 if (bRecursive) { | |
522 CloneChildren(pClone); | |
523 } | |
524 return pClone; | |
525 } | |
526 int32_t CFDE_XMLInstruction::CountAttributes() const { | |
527 return m_Attributes.GetSize() / 2; | |
528 } | |
529 FX_BOOL CFDE_XMLInstruction::GetAttribute(int32_t index, | |
530 CFX_WideString& wsAttriName, | |
531 CFX_WideString& wsAttriValue) const { | |
532 int32_t iCount = m_Attributes.GetSize(); | |
533 FXSYS_assert(index > -1 && index < iCount / 2); | |
534 for (int32_t i = 0; i < iCount; i += 2) { | |
535 if (index == 0) { | |
536 wsAttriName = m_Attributes[i]; | |
537 wsAttriValue = m_Attributes[i + 1]; | |
538 return TRUE; | |
539 } | |
540 index--; | |
541 } | |
542 return FALSE; | |
543 } | |
544 FX_BOOL CFDE_XMLInstruction::HasAttribute(const FX_WCHAR* pwsAttriName) const { | |
545 int32_t iCount = m_Attributes.GetSize(); | |
546 for (int32_t i = 0; i < iCount; i += 2) { | |
547 if (m_Attributes[i].Compare(pwsAttriName) == 0) { | |
548 return TRUE; | |
549 } | |
550 } | |
551 return FALSE; | |
552 } | |
553 void CFDE_XMLInstruction::GetString(const FX_WCHAR* pwsAttriName, | |
554 CFX_WideString& wsAttriValue, | |
555 const FX_WCHAR* pwsDefValue) const { | |
556 int32_t iCount = m_Attributes.GetSize(); | |
557 for (int32_t i = 0; i < iCount; i += 2) { | |
558 if (m_Attributes[i].Compare(pwsAttriName) == 0) { | |
559 wsAttriValue = m_Attributes[i + 1]; | |
560 return; | |
561 } | |
562 } | |
563 wsAttriValue = pwsDefValue; | |
564 } | |
565 void CFDE_XMLInstruction::SetString(const CFX_WideString& wsAttriName, | |
566 const CFX_WideString& wsAttriValue) { | |
567 FXSYS_assert(wsAttriName.GetLength() > 0); | |
568 int32_t iCount = m_Attributes.GetSize(); | |
569 for (int32_t i = 0; i < iCount; i += 2) { | |
570 if (m_Attributes[i].Compare(wsAttriName) == 0) { | |
571 m_Attributes[i] = wsAttriName; | |
572 m_Attributes[i + 1] = wsAttriValue; | |
573 return; | |
574 } | |
575 } | |
576 m_Attributes.Add(wsAttriName); | |
577 m_Attributes.Add(wsAttriValue); | |
578 } | |
579 int32_t CFDE_XMLInstruction::GetInteger(const FX_WCHAR* pwsAttriName, | |
580 int32_t iDefValue) const { | |
581 int32_t iCount = m_Attributes.GetSize(); | |
582 for (int32_t i = 0; i < iCount; i += 2) { | |
583 if (m_Attributes[i].Compare(pwsAttriName) == 0) { | |
584 return FXSYS_wtoi((const FX_WCHAR*)m_Attributes[i + 1]); | |
585 } | |
586 } | |
587 return iDefValue; | |
588 } | |
589 void CFDE_XMLInstruction::SetInteger(const FX_WCHAR* pwsAttriName, | |
590 int32_t iAttriValue) { | |
591 CFX_WideString wsValue; | |
592 wsValue.Format(L"%d", iAttriValue); | |
593 SetString(pwsAttriName, wsValue); | |
594 } | |
595 FX_FLOAT CFDE_XMLInstruction::GetFloat(const FX_WCHAR* pwsAttriName, | |
596 FX_FLOAT fDefValue) const { | |
597 int32_t iCount = m_Attributes.GetSize(); | |
598 for (int32_t i = 0; i < iCount; i += 2) { | |
599 if (m_Attributes[i].Compare(pwsAttriName) == 0) { | |
600 return FX_wcstof((const FX_WCHAR*)m_Attributes[i + 1]); | |
601 } | |
602 } | |
603 return fDefValue; | |
604 } | |
605 void CFDE_XMLInstruction::SetFloat(const FX_WCHAR* pwsAttriName, | |
606 FX_FLOAT fAttriValue) { | |
607 CFX_WideString wsValue; | |
608 wsValue.Format(L"%f", fAttriValue); | |
609 SetString(pwsAttriName, wsValue); | |
610 } | |
611 void CFDE_XMLInstruction::RemoveAttribute(const FX_WCHAR* pwsAttriName) { | |
612 int32_t iCount = m_Attributes.GetSize(); | |
613 for (int32_t i = 0; i < iCount; i += 2) { | |
614 if (m_Attributes[i].Compare(pwsAttriName) == 0) { | |
615 m_Attributes.RemoveAt(i + 1); | |
616 m_Attributes.RemoveAt(i); | |
617 return; | |
618 } | |
619 } | |
620 } | |
621 int32_t CFDE_XMLInstruction::CountData() const { | |
622 return m_TargetData.GetSize(); | |
623 } | |
624 FX_BOOL CFDE_XMLInstruction::GetData(int32_t index, | |
625 CFX_WideString& wsData) const { | |
626 if (index < 0 || index >= m_TargetData.GetSize()) { | |
627 return FALSE; | |
628 } | |
629 wsData = m_TargetData[index]; | |
630 return TRUE; | |
631 } | |
632 void CFDE_XMLInstruction::AppendData(const CFX_WideString& wsData) { | |
633 m_TargetData.Add(wsData); | |
634 } | |
635 void CFDE_XMLInstruction::RemoveData(int32_t index) { | |
636 m_TargetData.RemoveAt(index); | |
637 } | |
638 IFDE_XMLElement* IFDE_XMLElement::Create(const CFX_WideString& wsTag) { | |
639 return (IFDE_XMLElement*)new CFDE_XMLElement(wsTag); | |
640 } | |
641 CFDE_XMLElement::CFDE_XMLElement(const CFX_WideString& wsTag) | |
642 : CFDE_XMLNode(), m_wsTag(wsTag), m_Attributes() { | |
643 FXSYS_assert(m_wsTag.GetLength() > 0); | |
644 } | |
645 CFDE_XMLElement::~CFDE_XMLElement() { | |
646 m_Attributes.RemoveAll(); | |
647 } | |
648 CFDE_XMLNode* CFDE_XMLElement::Clone(FX_BOOL bRecursive) { | |
649 CFDE_XMLElement* pClone = new CFDE_XMLElement(m_wsTag); | |
650 if (!pClone) { | |
651 return NULL; | |
652 } | |
653 pClone->m_Attributes.Copy(m_Attributes); | |
654 if (bRecursive) { | |
655 CloneChildren(pClone); | |
656 } else { | |
657 CFX_WideString wsText; | |
658 CFDE_XMLNode* pChild = m_pChild; | |
659 while (pChild != NULL) { | |
660 switch (pChild->GetType()) { | |
661 case FDE_XMLNODE_Text: | |
662 wsText += ((CFDE_XMLText*)pChild)->m_wsText; | |
663 break; | |
664 default: | |
665 break; | |
666 } | |
667 pChild = pChild->m_pNext; | |
668 } | |
669 pClone->SetTextData(wsText); | |
670 } | |
671 return pClone; | |
672 } | |
673 void CFDE_XMLElement::GetTagName(CFX_WideString& wsTag) const { | |
674 wsTag = m_wsTag; | |
675 } | |
676 void CFDE_XMLElement::GetLocalTagName(CFX_WideString& wsTag) const { | |
677 FX_STRSIZE iFind = m_wsTag.Find(L':', 0); | |
678 if (iFind < 0) { | |
679 wsTag = m_wsTag; | |
680 } else { | |
681 wsTag = m_wsTag.Right(m_wsTag.GetLength() - iFind - 1); | |
682 } | |
683 } | |
684 void CFDE_XMLElement::GetNamespacePrefix(CFX_WideString& wsPrefix) const { | |
685 FX_STRSIZE iFind = m_wsTag.Find(L':', 0); | |
686 if (iFind < 0) { | |
687 wsPrefix.Empty(); | |
688 } else { | |
689 wsPrefix = m_wsTag.Left(iFind); | |
690 } | |
691 } | |
692 void CFDE_XMLElement::GetNamespaceURI(CFX_WideString& wsNamespace) const { | |
693 CFX_WideString wsAttri(L"xmlns"), wsPrefix; | |
694 GetNamespacePrefix(wsPrefix); | |
695 if (wsPrefix.GetLength() > 0) { | |
696 wsAttri += L":"; | |
697 wsAttri += wsPrefix; | |
698 } | |
699 wsNamespace.Empty(); | |
700 CFDE_XMLNode* pNode = (CFDE_XMLNode*)this; | |
701 while (pNode != NULL) { | |
702 if (pNode->GetType() != FDE_XMLNODE_Element) { | |
703 break; | |
704 } | |
705 CFDE_XMLElement* pElement = (CFDE_XMLElement*)pNode; | |
706 if (!pElement->HasAttribute(wsAttri)) { | |
707 pNode = pNode->GetNodeItem(IFDE_XMLNode::Parent); | |
708 continue; | |
709 } | |
710 pElement->GetString(wsAttri, wsNamespace); | |
711 break; | |
712 } | |
713 } | |
714 int32_t CFDE_XMLElement::CountAttributes() const { | |
715 return m_Attributes.GetSize() / 2; | |
716 } | |
717 FX_BOOL CFDE_XMLElement::GetAttribute(int32_t index, | |
718 CFX_WideString& wsAttriName, | |
719 CFX_WideString& wsAttriValue) const { | |
720 int32_t iCount = m_Attributes.GetSize(); | |
721 FXSYS_assert(index > -1 && index < iCount / 2); | |
722 for (int32_t i = 0; i < iCount; i += 2) { | |
723 if (index == 0) { | |
724 wsAttriName = m_Attributes[i]; | |
725 wsAttriValue = m_Attributes[i + 1]; | |
726 return TRUE; | |
727 } | |
728 index--; | |
729 } | |
730 return FALSE; | |
731 } | |
732 FX_BOOL CFDE_XMLElement::HasAttribute(const FX_WCHAR* pwsAttriName) const { | |
733 int32_t iCount = m_Attributes.GetSize(); | |
734 for (int32_t i = 0; i < iCount; i += 2) { | |
735 if (m_Attributes[i].Compare(pwsAttriName) == 0) { | |
736 return TRUE; | |
737 } | |
738 } | |
739 return FALSE; | |
740 } | |
741 void CFDE_XMLElement::GetString(const FX_WCHAR* pwsAttriName, | |
742 CFX_WideString& wsAttriValue, | |
743 const FX_WCHAR* pwsDefValue) const { | |
744 int32_t iCount = m_Attributes.GetSize(); | |
745 for (int32_t i = 0; i < iCount; i += 2) { | |
746 if (m_Attributes[i].Compare(pwsAttriName) == 0) { | |
747 wsAttriValue = m_Attributes[i + 1]; | |
748 return; | |
749 } | |
750 } | |
751 wsAttriValue = pwsDefValue; | |
752 } | |
753 void CFDE_XMLElement::SetString(const CFX_WideString& wsAttriName, | |
754 const CFX_WideString& wsAttriValue) { | |
755 FXSYS_assert(wsAttriName.GetLength() > 0); | |
756 int32_t iCount = m_Attributes.GetSize(); | |
757 for (int32_t i = 0; i < iCount; i += 2) { | |
758 if (m_Attributes[i].Compare(wsAttriName) == 0) { | |
759 m_Attributes[i] = wsAttriName; | |
760 m_Attributes[i + 1] = wsAttriValue; | |
761 return; | |
762 } | |
763 } | |
764 m_Attributes.Add(wsAttriName); | |
765 m_Attributes.Add(wsAttriValue); | |
766 } | |
767 int32_t CFDE_XMLElement::GetInteger(const FX_WCHAR* pwsAttriName, | |
768 int32_t iDefValue) const { | |
769 int32_t iCount = m_Attributes.GetSize(); | |
770 for (int32_t i = 0; i < iCount; i += 2) { | |
771 if (m_Attributes[i].Compare(pwsAttriName) == 0) { | |
772 return FXSYS_wtoi((const FX_WCHAR*)m_Attributes[i + 1]); | |
773 } | |
774 } | |
775 return iDefValue; | |
776 } | |
777 void CFDE_XMLElement::SetInteger(const FX_WCHAR* pwsAttriName, | |
778 int32_t iAttriValue) { | |
779 CFX_WideString wsValue; | |
780 wsValue.Format(L"%d", iAttriValue); | |
781 SetString(pwsAttriName, wsValue); | |
782 } | |
783 FX_FLOAT CFDE_XMLElement::GetFloat(const FX_WCHAR* pwsAttriName, | |
784 FX_FLOAT fDefValue) const { | |
785 int32_t iCount = m_Attributes.GetSize(); | |
786 for (int32_t i = 0; i < iCount; i += 2) { | |
787 if (m_Attributes[i].Compare(pwsAttriName) == 0) { | |
788 return FX_wcstof((const FX_WCHAR*)m_Attributes[i + 1]); | |
789 } | |
790 } | |
791 return fDefValue; | |
792 } | |
793 void CFDE_XMLElement::SetFloat(const FX_WCHAR* pwsAttriName, | |
794 FX_FLOAT fAttriValue) { | |
795 CFX_WideString wsValue; | |
796 wsValue.Format(L"%f", fAttriValue); | |
797 SetString(pwsAttriName, wsValue); | |
798 } | |
799 void CFDE_XMLElement::RemoveAttribute(const FX_WCHAR* pwsAttriName) { | |
800 int32_t iCount = m_Attributes.GetSize(); | |
801 for (int32_t i = 0; i < iCount; i += 2) { | |
802 if (m_Attributes[i].Compare(pwsAttriName) == 0) { | |
803 m_Attributes.RemoveAt(i + 1); | |
804 m_Attributes.RemoveAt(i); | |
805 return; | |
806 } | |
807 } | |
808 } | |
809 void CFDE_XMLElement::GetTextData(CFX_WideString& wsText) const { | |
810 CFX_WideTextBuf buffer; | |
811 CFDE_XMLNode* pChild = m_pChild; | |
812 while (pChild != NULL) { | |
813 switch (pChild->GetType()) { | |
814 case FDE_XMLNODE_Text: | |
815 buffer << ((CFDE_XMLText*)pChild)->m_wsText; | |
816 break; | |
817 case FDE_XMLNODE_CharData: | |
818 buffer << ((CFDE_XMLCharData*)pChild)->m_wsCharData; | |
819 break; | |
820 default: | |
821 break; | |
822 } | |
823 pChild = pChild->m_pNext; | |
824 } | |
825 wsText = buffer.GetWideString(); | |
826 } | |
827 void CFDE_XMLElement::SetTextData(const CFX_WideString& wsText) { | |
828 if (wsText.GetLength() < 1) { | |
829 return; | |
830 } | |
831 InsertChildNode(new CFDE_XMLText(wsText)); | |
832 } | |
833 IFDE_XMLText* IFDE_XMLText::Create(const CFX_WideString& wsText) { | |
834 return (IFDE_XMLText*)new CFDE_XMLText(wsText); | |
835 } | |
836 CFDE_XMLText::CFDE_XMLText(const CFX_WideString& wsText) | |
837 : CFDE_XMLNode(), m_wsText(wsText) {} | |
838 CFDE_XMLNode* CFDE_XMLText::Clone(FX_BOOL bRecursive) { | |
839 CFDE_XMLText* pClone = new CFDE_XMLText(m_wsText); | |
840 return pClone; | |
841 } | |
842 IFDE_XMLCharData* IFDE_XMLCharData::Create(const CFX_WideString& wsCData) { | |
843 return (IFDE_XMLCharData*)new CFDE_XMLCharData(wsCData); | |
844 } | |
845 CFDE_XMLCharData::CFDE_XMLCharData(const CFX_WideString& wsCData) | |
846 : CFDE_XMLDeclaration(), m_wsCharData(wsCData) {} | |
847 CFDE_XMLNode* CFDE_XMLCharData::Clone(FX_BOOL bRecursive) { | |
848 CFDE_XMLCharData* pClone = new CFDE_XMLCharData(m_wsCharData); | |
849 return pClone; | |
850 } | |
851 IFDE_XMLDoc* IFDE_XMLDoc::Create() { | |
852 return (IFDE_XMLDoc*)new CFDE_XMLDoc; | |
853 } | |
854 CFDE_XMLDoc::CFDE_XMLDoc() | |
855 : m_pRoot(NULL), m_pSyntaxParser(NULL), m_pXMLParser(NULL) { | |
856 Reset(TRUE); | |
857 CFDE_XMLInstruction* pXML = new CFDE_XMLInstruction(L"xml"); | |
858 m_pRoot->InsertChildNode(pXML); | |
859 } | |
860 CFDE_XMLDoc::~CFDE_XMLDoc() { | |
861 Reset(FALSE); | |
862 } | |
863 void CFDE_XMLDoc::Reset(FX_BOOL bInitRoot) { | |
864 m_iStatus = 0; | |
865 m_pStream = NULL; | |
866 if (bInitRoot) { | |
867 if (m_pRoot == NULL) { | |
868 m_pRoot = new CFDE_XMLNode; | |
869 } else { | |
870 m_pRoot->DeleteChildren(); | |
871 } | |
872 } else { | |
873 if (m_pRoot != NULL) { | |
874 m_pRoot->Release(); | |
875 m_pRoot = NULL; | |
876 } | |
877 } | |
878 ReleaseParser(); | |
879 } | |
880 void CFDE_XMLDoc::ReleaseParser() { | |
881 if (m_pXMLParser != NULL) { | |
882 m_pXMLParser->Release(); | |
883 m_pXMLParser = NULL; | |
884 } | |
885 if (m_pSyntaxParser != NULL) { | |
886 m_pSyntaxParser->Release(); | |
887 m_pSyntaxParser = NULL; | |
888 } | |
889 } | |
890 FX_BOOL CFDE_XMLDoc::LoadXML(IFX_Stream* pXMLStream, | |
891 int32_t iXMLPlaneSize, | |
892 int32_t iTextDataSize, | |
893 FDE_LPXMLREADERHANDLER pHandler) { | |
894 if (pXMLStream == NULL) { | |
895 return FALSE; | |
896 } | |
897 Reset(TRUE); | |
898 iXMLPlaneSize = iXMLPlaneSize / 1024; | |
899 if (iXMLPlaneSize < 1) { | |
900 iXMLPlaneSize = 1; | |
901 } | |
902 iXMLPlaneSize *= 1024; | |
903 if (iXMLPlaneSize < 4096) { | |
904 iXMLPlaneSize = 4096; | |
905 } | |
906 iTextDataSize = iTextDataSize / 128; | |
907 if (iTextDataSize < 1) { | |
908 iTextDataSize = 1; | |
909 } | |
910 iTextDataSize *= 128; | |
911 if (iTextDataSize < 128) { | |
912 iTextDataSize = 128; | |
913 } | |
914 m_pStream = pXMLStream; | |
915 FX_WORD wCodePage = m_pStream->GetCodePage(); | |
916 if (wCodePage != FX_CODEPAGE_UTF16LE && wCodePage != FX_CODEPAGE_UTF16BE && | |
917 wCodePage != FX_CODEPAGE_UTF8) { | |
918 m_pStream->SetCodePage(FX_CODEPAGE_UTF8); | |
919 } | |
920 m_pSyntaxParser = IFDE_XMLSyntaxParser::Create(); | |
921 if (m_pSyntaxParser == NULL) { | |
922 return FALSE; | |
923 } | |
924 m_pSyntaxParser->Init(m_pStream, iXMLPlaneSize, iTextDataSize); | |
925 if (pHandler == NULL) { | |
926 m_pXMLParser = new CFDE_XMLDOMParser(m_pRoot, m_pSyntaxParser); | |
927 } else { | |
928 m_pXMLParser = new CFDE_XMLSAXParser(pHandler, m_pSyntaxParser); | |
929 } | |
930 return TRUE; | |
931 } | |
932 FX_BOOL CFDE_XMLDoc::LoadXML(IFDE_XMLParser* pXMLParser) { | |
933 if (pXMLParser == NULL) { | |
934 return FALSE; | |
935 } | |
936 Reset(TRUE); | |
937 m_pXMLParser = pXMLParser; | |
938 return m_pXMLParser != NULL; | |
939 } | |
940 int32_t CFDE_XMLDoc::DoLoad(IFX_Pause* pPause) { | |
941 if (m_iStatus >= 100) { | |
942 return m_iStatus; | |
943 } | |
944 FXSYS_assert(m_pXMLParser != NULL); | |
945 return m_iStatus = m_pXMLParser->DoParser(pPause); | |
946 } | |
947 void CFDE_XMLDoc::CloseXML() { | |
948 ReleaseParser(); | |
949 } | |
950 void CFDE_XMLDoc::SaveXMLNode(IFX_Stream* pXMLStream, IFDE_XMLNode* pINode) { | |
951 CFDE_XMLNode* pNode = (CFDE_XMLNode*)pINode; | |
952 FXSYS_assert(pXMLStream != NULL && pNode != NULL); | |
953 switch (pNode->GetType()) { | |
954 case FDE_XMLNODE_Instruction: { | |
955 CFX_WideString ws; | |
956 CFDE_XMLInstruction* pInstruction = (CFDE_XMLInstruction*)pNode; | |
957 if (pInstruction->m_wsTarget.CompareNoCase(L"xml") == 0) { | |
958 ws = L"<?xml version=\"1.0\" encoding=\""; | |
959 FX_WORD wCodePage = pXMLStream->GetCodePage(); | |
960 if (wCodePage == FX_CODEPAGE_UTF16LE) { | |
961 ws += L"UTF-16"; | |
962 } else if (wCodePage == FX_CODEPAGE_UTF16BE) { | |
963 ws += L"UTF-16be"; | |
964 } else { | |
965 ws += L"UTF-8"; | |
966 } | |
967 ws += L"\"?>"; | |
968 pXMLStream->WriteString(ws, ws.GetLength()); | |
969 } else { | |
970 ws.Format(L"<?%s", (const FX_WCHAR*)pInstruction->m_wsTarget); | |
971 pXMLStream->WriteString(ws, ws.GetLength()); | |
972 CFX_WideStringArray& attributes = pInstruction->m_Attributes; | |
973 int32_t i, iCount = attributes.GetSize(); | |
974 CFX_WideString wsValue; | |
975 for (i = 0; i < iCount; i += 2) { | |
976 ws = L" "; | |
977 ws += attributes[i]; | |
978 ws += L"=\""; | |
979 wsValue = attributes[i + 1]; | |
980 wsValue.Replace(L"&", L"&"); | |
981 wsValue.Replace(L"<", L"<"); | |
982 wsValue.Replace(L">", L">"); | |
983 wsValue.Replace(L"\'", L"'"); | |
984 wsValue.Replace(L"\"", L"""); | |
985 ws += wsValue; | |
986 ws += L"\""; | |
987 pXMLStream->WriteString(ws, ws.GetLength()); | |
988 } | |
989 CFX_WideStringArray& targetdata = pInstruction->m_TargetData; | |
990 iCount = targetdata.GetSize(); | |
991 for (i = 0; i < iCount; i++) { | |
992 ws = L" \""; | |
993 ws += targetdata[i]; | |
994 ws += L"\""; | |
995 pXMLStream->WriteString(ws, ws.GetLength()); | |
996 } | |
997 ws = L"?>"; | |
998 pXMLStream->WriteString(ws, ws.GetLength()); | |
999 } | |
1000 } break; | |
1001 case FDE_XMLNODE_Element: { | |
1002 CFX_WideString ws; | |
1003 ws = L"<"; | |
1004 ws += ((CFDE_XMLElement*)pNode)->m_wsTag; | |
1005 pXMLStream->WriteString(ws, ws.GetLength()); | |
1006 CFX_WideStringArray& attributes = ((CFDE_XMLElement*)pNode)->m_Attributes; | |
1007 int32_t iCount = attributes.GetSize(); | |
1008 CFX_WideString wsValue; | |
1009 for (int32_t i = 0; i < iCount; i += 2) { | |
1010 ws = L" "; | |
1011 ws += attributes[i]; | |
1012 ws += L"=\""; | |
1013 wsValue = attributes[i + 1]; | |
1014 wsValue.Replace(L"&", L"&"); | |
1015 wsValue.Replace(L"<", L"<"); | |
1016 wsValue.Replace(L">", L">"); | |
1017 wsValue.Replace(L"\'", L"'"); | |
1018 wsValue.Replace(L"\"", L"""); | |
1019 ws += wsValue; | |
1020 ws += L"\""; | |
1021 pXMLStream->WriteString(ws, ws.GetLength()); | |
1022 } | |
1023 if (pNode->m_pChild == NULL) { | |
1024 ws = L"\n/>"; | |
1025 pXMLStream->WriteString(ws, ws.GetLength()); | |
1026 } else { | |
1027 ws = L"\n>"; | |
1028 pXMLStream->WriteString(ws, ws.GetLength()); | |
1029 CFDE_XMLNode* pChild = pNode->m_pChild; | |
1030 while (pChild != NULL) { | |
1031 SaveXMLNode(pXMLStream, (IFDE_XMLNode*)pChild); | |
1032 pChild = pChild->m_pNext; | |
1033 } | |
1034 ws = L"</"; | |
1035 ws += ((CFDE_XMLElement*)pNode)->m_wsTag; | |
1036 ws += L"\n>"; | |
1037 pXMLStream->WriteString(ws, ws.GetLength()); | |
1038 } | |
1039 } break; | |
1040 case FDE_XMLNODE_Text: { | |
1041 CFX_WideString ws = ((CFDE_XMLText*)pNode)->m_wsText; | |
1042 ws.Replace(L"&", L"&"); | |
1043 ws.Replace(L"<", L"<"); | |
1044 ws.Replace(L">", L">"); | |
1045 ws.Replace(L"\'", L"'"); | |
1046 ws.Replace(L"\"", L"""); | |
1047 pXMLStream->WriteString(ws, ws.GetLength()); | |
1048 } break; | |
1049 case FDE_XMLNODE_CharData: { | |
1050 CFX_WideString ws = L"<![CDATA["; | |
1051 ws += ((CFDE_XMLCharData*)pNode)->m_wsCharData; | |
1052 ws += L"]]>"; | |
1053 pXMLStream->WriteString(ws, ws.GetLength()); | |
1054 } break; | |
1055 case FDE_XMLNODE_Unknown: | |
1056 break; | |
1057 default: | |
1058 break; | |
1059 } | |
1060 } | |
1061 void CFDE_XMLDoc::SaveXML(IFX_Stream* pXMLStream, FX_BOOL bSaveBOM) { | |
1062 if (pXMLStream == NULL || pXMLStream == m_pStream) { | |
1063 m_pStream->Seek(FX_STREAMSEEK_Begin, 0); | |
1064 pXMLStream = m_pStream; | |
1065 } | |
1066 FXSYS_assert((pXMLStream->GetAccessModes() & FX_STREAMACCESS_Text) != 0); | |
1067 FXSYS_assert((pXMLStream->GetAccessModes() & FX_STREAMACCESS_Write) != 0); | |
1068 FX_WORD wCodePage = pXMLStream->GetCodePage(); | |
1069 if (wCodePage != FX_CODEPAGE_UTF16LE && wCodePage != FX_CODEPAGE_UTF16BE && | |
1070 wCodePage != FX_CODEPAGE_UTF8) { | |
1071 wCodePage = FX_CODEPAGE_UTF8; | |
1072 pXMLStream->SetCodePage(wCodePage); | |
1073 } | |
1074 if (bSaveBOM) { | |
1075 pXMLStream->WriteString(L"\xFEFF", 1); | |
1076 } | |
1077 CFDE_XMLNode* pNode = m_pRoot->m_pChild; | |
1078 while (pNode != NULL) { | |
1079 SaveXMLNode(pXMLStream, (IFDE_XMLNode*)pNode); | |
1080 pNode = pNode->m_pNext; | |
1081 } | |
1082 if (pXMLStream == m_pStream) { | |
1083 int32_t iPos = pXMLStream->GetPosition(); | |
1084 pXMLStream->SetLength(iPos); | |
1085 } | |
1086 } | |
1087 CFDE_XMLDOMParser::CFDE_XMLDOMParser(CFDE_XMLNode* pRoot, | |
1088 IFDE_XMLSyntaxParser* pParser) | |
1089 : m_pParser(pParser), | |
1090 m_pParent(pRoot), | |
1091 m_pChild(NULL), | |
1092 m_NodeStack(16), | |
1093 m_ws1(), | |
1094 m_ws2() { | |
1095 m_NodeStack.Push(m_pParent); | |
1096 } | |
1097 CFDE_XMLDOMParser::~CFDE_XMLDOMParser() { | |
1098 m_NodeStack.RemoveAll(); | |
1099 m_ws1.Empty(); | |
1100 m_ws2.Empty(); | |
1101 } | |
1102 int32_t CFDE_XMLDOMParser::DoParser(IFX_Pause* pPause) { | |
1103 FX_DWORD dwRet; | |
1104 int32_t iCount = 0; | |
1105 while (TRUE) { | |
1106 dwRet = m_pParser->DoSyntaxParse(); | |
1107 switch (dwRet) { | |
1108 case FDE_XMLSYNTAXSTATUS_InstructionOpen: | |
1109 break; | |
1110 case FDE_XMLSYNTAXSTATUS_InstructionClose: | |
1111 if (m_pChild->GetType() != FDE_XMLNODE_Instruction) { | |
1112 dwRet = FDE_XMLSYNTAXSTATUS_Error; | |
1113 break; | |
1114 } | |
1115 m_pChild = m_pParent; | |
1116 break; | |
1117 case FDE_XMLSYNTAXSTATUS_ElementOpen: | |
1118 case FDE_XMLSYNTAXSTATUS_ElementBreak: | |
1119 break; | |
1120 case FDE_XMLSYNTAXSTATUS_ElementClose: | |
1121 if (m_pChild->GetType() != FDE_XMLNODE_Element) { | |
1122 dwRet = FDE_XMLSYNTAXSTATUS_Error; | |
1123 break; | |
1124 } | |
1125 m_pParser->GetTagName(m_ws1); | |
1126 ((CFDE_XMLElement*)m_pChild)->GetTagName(m_ws2); | |
1127 if (m_ws1.GetLength() > 0 && m_ws1.Compare(m_ws2) != 0) { | |
1128 dwRet = FDE_XMLSYNTAXSTATUS_Error; | |
1129 break; | |
1130 } | |
1131 m_NodeStack.Pop(); | |
1132 if (m_NodeStack.GetSize() < 1) { | |
1133 dwRet = FDE_XMLSYNTAXSTATUS_Error; | |
1134 break; | |
1135 } | |
1136 m_pParent = (CFDE_XMLNode*)*m_NodeStack.GetTopElement(); | |
1137 m_pChild = m_pParent; | |
1138 iCount++; | |
1139 break; | |
1140 case FDE_XMLSYNTAXSTATUS_TargetName: | |
1141 m_pParser->GetTargetName(m_ws1); | |
1142 m_pChild = new CFDE_XMLInstruction(m_ws1); | |
1143 m_pParent->InsertChildNode(m_pChild); | |
1144 m_ws1.Empty(); | |
1145 break; | |
1146 case FDE_XMLSYNTAXSTATUS_TagName: | |
1147 m_pParser->GetTagName(m_ws1); | |
1148 m_pChild = new CFDE_XMLElement(m_ws1); | |
1149 m_pParent->InsertChildNode(m_pChild); | |
1150 m_NodeStack.Push(m_pChild); | |
1151 m_pParent = m_pChild; | |
1152 break; | |
1153 case FDE_XMLSYNTAXSTATUS_AttriName: | |
1154 m_pParser->GetAttributeName(m_ws1); | |
1155 break; | |
1156 case FDE_XMLSYNTAXSTATUS_AttriValue: | |
1157 if (m_pChild == NULL) { | |
1158 dwRet = FDE_XMLSYNTAXSTATUS_Error; | |
1159 break; | |
1160 } | |
1161 m_pParser->GetAttributeName(m_ws2); | |
1162 if (m_pChild->GetType() == FDE_XMLNODE_Element) { | |
1163 ((CFDE_XMLElement*)m_pChild)->SetString(m_ws1, m_ws2); | |
1164 } else if (m_pChild->GetType() == FDE_XMLNODE_Instruction) { | |
1165 ((CFDE_XMLInstruction*)m_pChild)->SetString(m_ws1, m_ws2); | |
1166 } | |
1167 m_ws1.Empty(); | |
1168 break; | |
1169 case FDE_XMLSYNTAXSTATUS_Text: | |
1170 m_pParser->GetTextData(m_ws1); | |
1171 m_pChild = new CFDE_XMLText(m_ws1); | |
1172 m_pParent->InsertChildNode(m_pChild); | |
1173 m_pChild = m_pParent; | |
1174 break; | |
1175 case FDE_XMLSYNTAXSTATUS_CData: | |
1176 m_pParser->GetTextData(m_ws1); | |
1177 m_pChild = new CFDE_XMLCharData(m_ws1); | |
1178 m_pParent->InsertChildNode(m_pChild); | |
1179 m_pChild = m_pParent; | |
1180 break; | |
1181 case FDE_XMLSYNTAXSTATUS_TargetData: | |
1182 if (m_pChild == NULL || | |
1183 m_pChild->GetType() != FDE_XMLNODE_Instruction) { | |
1184 dwRet = FDE_XMLSYNTAXSTATUS_Error; | |
1185 break; | |
1186 } | |
1187 if (!m_ws1.IsEmpty()) { | |
1188 ((CFDE_XMLInstruction*)m_pChild)->AppendData(m_ws1); | |
1189 } | |
1190 m_pParser->GetTargetData(m_ws1); | |
1191 ((CFDE_XMLInstruction*)m_pChild)->AppendData(m_ws1); | |
1192 m_ws1.Empty(); | |
1193 break; | |
1194 default: | |
1195 break; | |
1196 } | |
1197 if (dwRet == FDE_XMLSYNTAXSTATUS_Error || | |
1198 dwRet == FDE_XMLSYNTAXSTATUS_EOS) { | |
1199 break; | |
1200 } | |
1201 if (pPause != NULL && iCount > 500 && pPause->NeedToPauseNow()) { | |
1202 break; | |
1203 } | |
1204 } | |
1205 return m_pParser->GetStatus(); | |
1206 } | |
1207 CFDE_XMLSAXParser::CFDE_XMLSAXParser(FDE_LPXMLREADERHANDLER pHandler, | |
1208 IFDE_XMLSyntaxParser* pParser) | |
1209 : m_pHandler(pHandler), | |
1210 m_pParser(pParser), | |
1211 m_TagStack(16), | |
1212 m_pTagTop(NULL), | |
1213 m_ws1(), | |
1214 m_ws2() {} | |
1215 CFDE_XMLSAXParser::~CFDE_XMLSAXParser() { | |
1216 m_TagStack.RemoveAll(); | |
1217 m_ws1.Empty(); | |
1218 m_ws2.Empty(); | |
1219 } | |
1220 int32_t CFDE_XMLSAXParser::DoParser(IFX_Pause* pPause) { | |
1221 FX_DWORD dwRet = 0; | |
1222 int32_t iCount = 0; | |
1223 while (TRUE) { | |
1224 dwRet = m_pParser->DoSyntaxParse(); | |
1225 switch (dwRet) { | |
1226 case FDE_XMLSYNTAXSTATUS_ElementBreak: | |
1227 if (m_pTagTop == NULL) { | |
1228 dwRet = FDE_XMLSYNTAXSTATUS_Error; | |
1229 break; | |
1230 } | |
1231 if (m_pTagTop->eType == FDE_XMLNODE_Element) { | |
1232 m_pHandler->OnTagBreak(m_pHandler, m_pTagTop->wsTagName); | |
1233 } | |
1234 break; | |
1235 case FDE_XMLSYNTAXSTATUS_ElementClose: | |
1236 if (m_pTagTop == NULL || m_pTagTop->eType != FDE_XMLNODE_Element) { | |
1237 dwRet = FDE_XMLSYNTAXSTATUS_Error; | |
1238 break; | |
1239 } | |
1240 m_pParser->GetTagName(m_ws1); | |
1241 if (m_ws1.GetLength() > 0 && m_ws1.Compare(m_pTagTop->wsTagName) != 0) { | |
1242 dwRet = FDE_XMLSYNTAXSTATUS_Error; | |
1243 break; | |
1244 } else if (m_ws1.GetLength() == 0) { | |
1245 m_pHandler->OnTagBreak(m_pHandler, m_pTagTop->wsTagName); | |
1246 } | |
1247 m_pHandler->OnTagClose(m_pHandler, m_pTagTop->wsTagName); | |
1248 Pop(); | |
1249 iCount++; | |
1250 break; | |
1251 case FDE_XMLSYNTAXSTATUS_TargetName: { | |
1252 m_pParser->GetTargetName(m_ws1); | |
1253 CFDE_XMLTAG xmlTag; | |
1254 xmlTag.wsTagName = m_ws1; | |
1255 xmlTag.eType = FDE_XMLNODE_Instruction; | |
1256 Push(xmlTag); | |
1257 m_pHandler->OnTagEnter(m_pHandler, FDE_XMLNODE_Instruction, | |
1258 m_pTagTop->wsTagName); | |
1259 m_ws1.Empty(); | |
1260 } break; | |
1261 case FDE_XMLSYNTAXSTATUS_TagName: { | |
1262 m_pParser->GetTargetName(m_ws1); | |
1263 CFDE_XMLTAG xmlTag; | |
1264 xmlTag.wsTagName = m_ws1; | |
1265 xmlTag.eType = FDE_XMLNODE_Element; | |
1266 Push(xmlTag); | |
1267 m_pHandler->OnTagEnter(m_pHandler, FDE_XMLNODE_Element, | |
1268 m_pTagTop->wsTagName); | |
1269 } break; | |
1270 case FDE_XMLSYNTAXSTATUS_AttriName: | |
1271 m_pParser->GetTargetName(m_ws1); | |
1272 break; | |
1273 case FDE_XMLSYNTAXSTATUS_AttriValue: | |
1274 m_pParser->GetAttributeName(m_ws2); | |
1275 if (m_pTagTop == NULL) { | |
1276 dwRet = FDE_XMLSYNTAXSTATUS_Error; | |
1277 break; | |
1278 } | |
1279 if (m_pTagTop->eType == FDE_XMLNODE_Element) { | |
1280 m_pHandler->OnAttribute(m_pHandler, m_ws1, m_ws2); | |
1281 } | |
1282 m_ws1.Empty(); | |
1283 break; | |
1284 case FDE_XMLSYNTAXSTATUS_CData: | |
1285 m_pParser->GetTextData(m_ws1); | |
1286 m_pHandler->OnData(m_pHandler, FDE_XMLNODE_CharData, m_ws1); | |
1287 break; | |
1288 case FDE_XMLSYNTAXSTATUS_Text: | |
1289 m_pParser->GetTextData(m_ws1); | |
1290 m_pHandler->OnData(m_pHandler, FDE_XMLNODE_Text, m_ws1); | |
1291 break; | |
1292 case FDE_XMLSYNTAXSTATUS_TargetData: | |
1293 m_pParser->GetTargetData(m_ws1); | |
1294 m_pHandler->OnData(m_pHandler, FDE_XMLNODE_Instruction, m_ws1); | |
1295 m_ws1.Empty(); | |
1296 break; | |
1297 default: | |
1298 break; | |
1299 } | |
1300 if (dwRet == FDE_XMLSYNTAXSTATUS_Error || | |
1301 dwRet == FDE_XMLSYNTAXSTATUS_EOS) { | |
1302 break; | |
1303 } | |
1304 if (pPause != NULL && iCount > 500 && pPause->NeedToPauseNow()) { | |
1305 break; | |
1306 } | |
1307 } | |
1308 return m_pParser->GetStatus(); | |
1309 } | |
1310 inline void CFDE_XMLSAXParser::Push(const CFDE_XMLTAG& xmlTag) { | |
1311 m_TagStack.Push(xmlTag); | |
1312 m_pTagTop = m_TagStack.GetTopElement(); | |
1313 } | |
1314 inline void CFDE_XMLSAXParser::Pop() { | |
1315 m_TagStack.Pop(); | |
1316 m_pTagTop = m_TagStack.GetTopElement(); | |
1317 } | |
1318 #ifdef _FDE_BLOCK_BUFFER | |
1319 CFDE_BlockBuffer::CFDE_BlockBuffer(int32_t iAllocStep) | |
1320 : m_iDataLength(0), | |
1321 m_iBufferSize(0), | |
1322 m_iAllocStep(iAllocStep), | |
1323 m_iStartPosition(0) { | |
1324 } | |
1325 CFDE_BlockBuffer::~CFDE_BlockBuffer() { | |
1326 ClearBuffer(); | |
1327 } | |
1328 FX_WCHAR* CFDE_BlockBuffer::GetAvailableBlock(int32_t& iIndexInBlock) { | |
1329 iIndexInBlock = 0; | |
1330 if (!m_BlockArray.GetSize()) { | |
1331 return nullptr; | |
1332 } | |
1333 int32_t iRealIndex = m_iStartPosition + m_iDataLength; | |
1334 if (iRealIndex == m_iBufferSize) { | |
1335 FX_WCHAR* pBlock = FX_Alloc(FX_WCHAR, m_iAllocStep); | |
1336 m_BlockArray.Add(pBlock); | |
1337 m_iBufferSize += m_iAllocStep; | |
1338 return pBlock; | |
1339 } | |
1340 iIndexInBlock = iRealIndex % m_iAllocStep; | |
1341 return (FX_WCHAR*)m_BlockArray[iRealIndex / m_iAllocStep]; | |
1342 } | |
1343 FX_BOOL CFDE_BlockBuffer::InitBuffer(int32_t iBufferSize) { | |
1344 ClearBuffer(); | |
1345 int32_t iNumOfBlock = (iBufferSize - 1) / m_iAllocStep + 1; | |
1346 for (int32_t i = 0; i < iNumOfBlock; i++) { | |
1347 m_BlockArray.Add(FX_Alloc(FX_WCHAR, m_iAllocStep)); | |
1348 } | |
1349 m_iBufferSize = iNumOfBlock * m_iAllocStep; | |
1350 return TRUE; | |
1351 } | |
1352 void CFDE_BlockBuffer::SetTextChar(int32_t iIndex, FX_WCHAR ch) { | |
1353 if (iIndex < 0) { | |
1354 return; | |
1355 } | |
1356 int32_t iRealIndex = m_iStartPosition + iIndex; | |
1357 int32_t iBlockIndex = iRealIndex / m_iAllocStep; | |
1358 int32_t iInnerIndex = iRealIndex % m_iAllocStep; | |
1359 int32_t iBlockSize = m_BlockArray.GetSize(); | |
1360 if (iBlockIndex >= iBlockSize) { | |
1361 int32_t iNewBlocks = iBlockIndex - iBlockSize + 1; | |
1362 do { | |
1363 FX_WCHAR* pBlock = FX_Alloc(FX_WCHAR, m_iAllocStep); | |
1364 m_BlockArray.Add(pBlock); | |
1365 m_iBufferSize += m_iAllocStep; | |
1366 } while (--iNewBlocks); | |
1367 } | |
1368 FX_WCHAR* pTextData = (FX_WCHAR*)m_BlockArray[iBlockIndex]; | |
1369 *(pTextData + iInnerIndex) = ch; | |
1370 if (m_iDataLength <= iIndex) { | |
1371 m_iDataLength = iIndex + 1; | |
1372 } | |
1373 } | |
1374 int32_t CFDE_BlockBuffer::DeleteTextChars(int32_t iCount, FX_BOOL bDirection) { | |
1375 if (iCount <= 0) { | |
1376 return m_iDataLength; | |
1377 } | |
1378 if (iCount >= m_iDataLength) { | |
1379 Reset(FALSE); | |
1380 return 0; | |
1381 } | |
1382 if (bDirection) { | |
1383 m_iStartPosition += iCount; | |
1384 m_iDataLength -= iCount; | |
1385 } else { | |
1386 m_iDataLength -= iCount; | |
1387 } | |
1388 return m_iDataLength; | |
1389 } | |
1390 void CFDE_BlockBuffer::GetTextData(CFX_WideString& wsTextData, | |
1391 int32_t iStart, | |
1392 int32_t iLength) const { | |
1393 wsTextData.Empty(); | |
1394 int32_t iMaybeDataLength = m_iBufferSize - 1 - m_iStartPosition; | |
1395 if (iStart < 0 || iStart > iMaybeDataLength) { | |
1396 return; | |
1397 } | |
1398 if (iLength == -1 || iLength > iMaybeDataLength) { | |
1399 iLength = iMaybeDataLength; | |
1400 } | |
1401 if (iLength <= 0) { | |
1402 return; | |
1403 } | |
1404 FX_WCHAR* pBuf = wsTextData.GetBuffer(iLength); | |
1405 if (!pBuf) { | |
1406 return; | |
1407 } | |
1408 int32_t iStartBlockIndex = 0; | |
1409 int32_t iStartInnerIndex = 0; | |
1410 TextDataIndex2BufIndex(iStart, iStartBlockIndex, iStartInnerIndex); | |
1411 int32_t iEndBlockIndex = 0; | |
1412 int32_t iEndInnerIndex = 0; | |
1413 TextDataIndex2BufIndex(iStart + iLength, iEndBlockIndex, iEndInnerIndex); | |
1414 int32_t iPointer = 0; | |
1415 for (int32_t i = iStartBlockIndex; i <= iEndBlockIndex; i++) { | |
1416 int32_t iBufferPointer = 0; | |
1417 int32_t iCopyLength = m_iAllocStep; | |
1418 if (i == iStartBlockIndex) { | |
1419 iCopyLength -= iStartInnerIndex; | |
1420 iBufferPointer = iStartInnerIndex; | |
1421 } | |
1422 if (i == iEndBlockIndex) { | |
1423 iCopyLength -= ((m_iAllocStep - 1) - iEndInnerIndex); | |
1424 } | |
1425 FX_WCHAR* pBlockBuf = (FX_WCHAR*)m_BlockArray[i]; | |
1426 FXSYS_memcpy(pBuf + iPointer, pBlockBuf + iBufferPointer, | |
1427 iCopyLength * sizeof(FX_WCHAR)); | |
1428 iPointer += iCopyLength; | |
1429 } | |
1430 wsTextData.ReleaseBuffer(iLength); | |
1431 } | |
1432 void CFDE_BlockBuffer::TextDataIndex2BufIndex(const int32_t iIndex, | |
1433 int32_t& iBlockIndex, | |
1434 int32_t& iInnerIndex) const { | |
1435 FXSYS_assert(iIndex >= 0); | |
1436 int32_t iRealIndex = m_iStartPosition + iIndex; | |
1437 iBlockIndex = iRealIndex / m_iAllocStep; | |
1438 iInnerIndex = iRealIndex % m_iAllocStep; | |
1439 } | |
1440 void CFDE_BlockBuffer::ClearBuffer() { | |
1441 m_iBufferSize = 0; | |
1442 int32_t iSize = m_BlockArray.GetSize(); | |
1443 for (int32_t i = 0; i < iSize; i++) { | |
1444 FX_Free(m_BlockArray[i]); | |
1445 m_BlockArray[i] = NULL; | |
1446 } | |
1447 m_BlockArray.RemoveAll(); | |
1448 } | |
1449 #endif | |
1450 IFDE_XMLSyntaxParser* IFDE_XMLSyntaxParser::Create() { | |
1451 return new CFDE_XMLSyntaxParser; | |
1452 } | |
1453 #ifdef _FDE_BLOCK_BUFFER | |
1454 CFDE_XMLSyntaxParser::CFDE_XMLSyntaxParser() | |
1455 : m_pStream(nullptr), | |
1456 m_iXMLPlaneSize(-1), | |
1457 m_iCurrentPos(0), | |
1458 m_iCurrentNodeNum(-1), | |
1459 m_iLastNodeNum(-1), | |
1460 m_iParsedChars(0), | |
1461 m_iParsedBytes(0), | |
1462 m_pBuffer(nullptr), | |
1463 m_iBufferChars(0), | |
1464 m_bEOS(FALSE), | |
1465 m_pStart(nullptr), | |
1466 m_pEnd(nullptr), | |
1467 m_XMLNodeStack(16), | |
1468 m_iAllocStep(m_BlockBuffer.GetAllocStep()), | |
1469 m_iDataLength(m_BlockBuffer.GetDataLengthRef()), | |
1470 m_pCurrentBlock(nullptr), | |
1471 m_iIndexInBlock(0), | |
1472 m_iTextDataLength(0), | |
1473 m_dwStatus(FDE_XMLSYNTAXSTATUS_None), | |
1474 m_dwMode(FDE_XMLSYNTAXMODE_Text), | |
1475 m_wQuotationMark(0), | |
1476 m_iEntityStart(-1), | |
1477 m_SkipStack(16) { | |
1478 m_CurNode.iNodeNum = -1; | |
1479 m_CurNode.eNodeType = FDE_XMLNODE_Unknown; | |
1480 } | |
1481 void CFDE_XMLSyntaxParser::Init(IFX_Stream* pStream, | |
1482 int32_t iXMLPlaneSize, | |
1483 int32_t iTextDataSize) { | |
1484 FXSYS_assert(m_pStream == NULL && m_pBuffer == NULL); | |
1485 FXSYS_assert(pStream != NULL && iXMLPlaneSize > 0); | |
1486 int32_t iStreamLength = pStream->GetLength(); | |
1487 FXSYS_assert(iStreamLength > 0); | |
1488 m_pStream = pStream; | |
1489 m_iXMLPlaneSize = std::min(iXMLPlaneSize, iStreamLength); | |
1490 uint8_t bom[4]; | |
1491 m_iCurrentPos = m_pStream->GetBOM(bom); | |
1492 FXSYS_assert(m_pBuffer == NULL); | |
1493 m_pBuffer = FX_Alloc(FX_WCHAR, m_iXMLPlaneSize); | |
1494 m_pStart = m_pEnd = m_pBuffer; | |
1495 FXSYS_assert(!m_BlockBuffer.IsInitialized()); | |
1496 m_BlockBuffer.InitBuffer(); | |
1497 m_pCurrentBlock = m_BlockBuffer.GetAvailableBlock(m_iIndexInBlock); | |
1498 m_iParsedBytes = m_iParsedChars = 0; | |
1499 m_iBufferChars = 0; | |
1500 } | |
1501 FX_DWORD CFDE_XMLSyntaxParser::DoSyntaxParse() { | |
1502 if (m_dwStatus == FDE_XMLSYNTAXSTATUS_Error || | |
1503 m_dwStatus == FDE_XMLSYNTAXSTATUS_EOS) { | |
1504 return m_dwStatus; | |
1505 } | |
1506 FXSYS_assert(m_pStream && m_pBuffer && m_BlockBuffer.IsInitialized()); | |
1507 int32_t iStreamLength = m_pStream->GetLength(); | |
1508 int32_t iPos; | |
1509 FX_WCHAR ch; | |
1510 FX_DWORD dwStatus = FDE_XMLSYNTAXSTATUS_None; | |
1511 while (TRUE) { | |
1512 if (m_pStart >= m_pEnd) { | |
1513 if (m_bEOS || m_iCurrentPos >= iStreamLength) { | |
1514 m_dwStatus = FDE_XMLSYNTAXSTATUS_EOS; | |
1515 return m_dwStatus; | |
1516 } | |
1517 m_iParsedChars += (m_pEnd - m_pBuffer); | |
1518 m_iParsedBytes = m_iCurrentPos; | |
1519 m_pStream->Lock(); | |
1520 if (m_pStream->GetPosition() != m_iCurrentPos) { | |
1521 m_pStream->Seek(FX_STREAMSEEK_Begin, m_iCurrentPos); | |
1522 } | |
1523 m_iBufferChars = | |
1524 m_pStream->ReadString(m_pBuffer, m_iXMLPlaneSize, m_bEOS); | |
1525 iPos = m_pStream->GetPosition(); | |
1526 m_pStream->Unlock(); | |
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_LPXMLNODE 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_LPXMLNODE 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 #else | |
1973 CFDE_XMLSyntaxParser::CFDE_XMLSyntaxParser() | |
1974 : m_pStream(NULL), | |
1975 m_iXMLPlaneSize(-1), | |
1976 m_iTextDataSize(256), | |
1977 m_iCurrentPos(0), | |
1978 m_iCurrentNodeNum(-1), | |
1979 m_iLastNodeNum(-1), | |
1980 m_iParsedChars(0), | |
1981 m_iParsedBytes(0), | |
1982 m_pBuffer(NULL), | |
1983 m_iBufferChars(0), | |
1984 m_bEOS(FALSE), | |
1985 m_pStart(NULL), | |
1986 m_pEnd(NULL), | |
1987 m_XMLNodeStack(16), | |
1988 m_pwsTextData(NULL), | |
1989 m_iDataPos(0), | |
1990 m_dwStatus(FDE_XMLSYNTAXSTATUS_None), | |
1991 m_dwMode(FDE_XMLSYNTAXMODE_Text), | |
1992 m_wQuotationMark(0), | |
1993 m_iTextDataLength(0), | |
1994 m_iEntityStart(-1), | |
1995 m_SkipStack(16) { | |
1996 m_CurNode.iNodeNum = -1; | |
1997 m_CurNode.eNodeType = FDE_XMLNODE_Unknown; | |
1998 } | |
1999 void CFDE_XMLSyntaxParser::Init(IFX_Stream* pStream, | |
2000 int32_t iXMLPlaneSize, | |
2001 int32_t iTextDataSize) { | |
2002 FXSYS_assert(m_pStream == NULL && m_pBuffer == NULL); | |
2003 FXSYS_assert(pStream != NULL && iXMLPlaneSize > 0 && iTextDataSize > 0); | |
2004 int32_t iStreamLength = pStream->GetLength(); | |
2005 FXSYS_assert(iStreamLength > 0); | |
2006 m_pStream = pStream; | |
2007 m_iXMLPlaneSize = std::min(iXMLPlaneSize, iStreamLength); | |
2008 m_iTextDataSize = iTextDataSize; | |
2009 uint8_t bom[4]; | |
2010 m_iCurrentPos = m_pStream->GetBOM(bom); | |
2011 FXSYS_assert(m_pBuffer == NULL); | |
2012 m_pBuffer = FX_Alloc(FX_WCHAR, m_iXMLPlaneSize); | |
2013 m_pStart = m_pEnd = m_pBuffer; | |
2014 FXSYS_assert(m_pwsTextData == NULL); | |
2015 m_pwsTextData = FX_Alloc(FX_WCHAR, m_iTextDataSize); | |
2016 m_iParsedBytes = 0; | |
2017 m_iParsedChars = 0; | |
2018 m_iBufferChars = 0; | |
2019 } | |
2020 FX_DWORD CFDE_XMLSyntaxParser::DoSyntaxParse() { | |
2021 if (m_dwStatus == FDE_XMLSYNTAXSTATUS_Error || | |
2022 m_dwStatus == FDE_XMLSYNTAXSTATUS_EOS) { | |
2023 return m_dwStatus; | |
2024 } | |
2025 FXSYS_assert(m_pStream != NULL && m_pBuffer != NULL && m_pwsTextData != NULL); | |
2026 int32_t iStreamLength = m_pStream->GetLength(); | |
2027 int32_t iPos; | |
2028 FX_WCHAR ch; | |
2029 FX_DWORD dwStatus = FDE_XMLSYNTAXSTATUS_None; | |
2030 while (TRUE) { | |
2031 if (m_pStart >= m_pEnd) { | |
2032 if (m_bEOS || m_iCurrentPos >= iStreamLength) { | |
2033 m_dwStatus = FDE_XMLSYNTAXSTATUS_EOS; | |
2034 return m_dwStatus; | |
2035 } | |
2036 m_iParsedChars += (m_pEnd - m_pBuffer); | |
2037 m_iParsedBytes = m_iCurrentPos; | |
2038 m_pStream->Lock(); | |
2039 if (m_pStream->GetPosition() != m_iCurrentPos) { | |
2040 m_pStream->Seek(FX_STREAMSEEK_Begin, m_iCurrentPos); | |
2041 } | |
2042 m_iBufferChars = | |
2043 m_pStream->ReadString(m_pBuffer, m_iXMLPlaneSize, m_bEOS); | |
2044 iPos = m_pStream->GetPosition(); | |
2045 m_pStream->Unlock(); | |
2046 if (m_iBufferChars < 1) { | |
2047 m_iCurrentPos = iStreamLength; | |
2048 m_dwStatus = FDE_XMLSYNTAXSTATUS_EOS; | |
2049 return m_dwStatus; | |
2050 } | |
2051 m_iCurrentPos = iPos; | |
2052 m_pStart = m_pBuffer; | |
2053 m_pEnd = m_pBuffer + m_iBufferChars; | |
2054 } | |
2055 while (m_pStart < m_pEnd) { | |
2056 ch = *m_pStart; | |
2057 switch (m_dwMode) { | |
2058 case FDE_XMLSYNTAXMODE_Text: | |
2059 if (ch == L'<') { | |
2060 if (m_iDataPos > 0) { | |
2061 m_iTextDataLength = m_iDataPos; | |
2062 m_iDataPos = 0; | |
2063 m_iEntityStart = -1; | |
2064 dwStatus = FDE_XMLSYNTAXSTATUS_Text; | |
2065 } else { | |
2066 m_pStart++; | |
2067 m_dwMode = FDE_XMLSYNTAXMODE_Node; | |
2068 } | |
2069 } else { | |
2070 ParseTextChar(ch); | |
2071 } | |
2072 break; | |
2073 case FDE_XMLSYNTAXMODE_Node: | |
2074 if (ch == L'!') { | |
2075 m_pStart++; | |
2076 m_dwMode = FDE_XMLSYNTAXMODE_SkipCommentOrDecl; | |
2077 } else if (ch == L'/') { | |
2078 m_pStart++; | |
2079 m_dwMode = FDE_XMLSYNTAXMODE_CloseElement; | |
2080 } else if (ch == L'?') { | |
2081 m_iLastNodeNum++; | |
2082 m_iCurrentNodeNum = m_iLastNodeNum; | |
2083 m_CurNode.iNodeNum = m_iLastNodeNum; | |
2084 m_CurNode.eNodeType = FDE_XMLNODE_Instruction; | |
2085 m_XMLNodeStack.Push(m_CurNode); | |
2086 m_pStart++; | |
2087 m_dwMode = FDE_XMLSYNTAXMODE_Target; | |
2088 dwStatus = FDE_XMLSYNTAXSTATUS_InstructionOpen; | |
2089 } else { | |
2090 m_iLastNodeNum++; | |
2091 m_iCurrentNodeNum = m_iLastNodeNum; | |
2092 m_CurNode.iNodeNum = m_iLastNodeNum; | |
2093 m_CurNode.eNodeType = FDE_XMLNODE_Element; | |
2094 m_XMLNodeStack.Push(m_CurNode); | |
2095 m_dwMode = FDE_XMLSYNTAXMODE_Tag; | |
2096 dwStatus = FDE_XMLSYNTAXSTATUS_ElementOpen; | |
2097 } | |
2098 break; | |
2099 case FDE_XMLSYNTAXMODE_Target: | |
2100 case FDE_XMLSYNTAXMODE_Tag: | |
2101 if (!FDE_IsXMLNameChar(ch, m_iDataPos < 1)) { | |
2102 if (m_iDataPos < 1) { | |
2103 m_dwStatus = FDE_XMLSYNTAXSTATUS_Error; | |
2104 return m_dwStatus; | |
2105 } else { | |
2106 m_iTextDataLength = m_iDataPos; | |
2107 m_iDataPos = 0; | |
2108 if (m_dwMode != FDE_XMLSYNTAXMODE_Target) { | |
2109 dwStatus = FDE_XMLSYNTAXSTATUS_TagName; | |
2110 } else { | |
2111 dwStatus = FDE_XMLSYNTAXSTATUS_TargetName; | |
2112 } | |
2113 m_dwMode = FDE_XMLSYNTAXMODE_AttriName; | |
2114 } | |
2115 } else { | |
2116 if (m_iDataPos >= m_iTextDataSize) { | |
2117 ReallocTextDataBuffer(); | |
2118 } | |
2119 m_pwsTextData[m_iDataPos++] = ch; | |
2120 m_pStart++; | |
2121 } | |
2122 break; | |
2123 case FDE_XMLSYNTAXMODE_AttriName: | |
2124 if (m_iDataPos < 1 && FDE_IsXMLWhiteSpace(ch)) { | |
2125 m_pStart++; | |
2126 break; | |
2127 } | |
2128 if (!FDE_IsXMLNameChar(ch, m_iDataPos < 1)) { | |
2129 if (m_iDataPos < 1) { | |
2130 if (m_CurNode.eNodeType == FDE_XMLNODE_Element) { | |
2131 if (ch == L'>' || ch == L'/') { | |
2132 m_dwMode = FDE_XMLSYNTAXMODE_BreakElement; | |
2133 break; | |
2134 } | |
2135 } else if (m_CurNode.eNodeType == FDE_XMLNODE_Instruction) { | |
2136 if (ch == L'?') { | |
2137 m_dwMode = FDE_XMLSYNTAXMODE_CloseInstruction; | |
2138 m_pStart++; | |
2139 } else { | |
2140 m_dwMode = FDE_XMLSYNTAXMODE_TargetData; | |
2141 } | |
2142 break; | |
2143 } | |
2144 m_dwStatus = FDE_XMLSYNTAXSTATUS_Error; | |
2145 return m_dwStatus; | |
2146 } else { | |
2147 if (m_CurNode.eNodeType == FDE_XMLNODE_Instruction) { | |
2148 if (ch != '=' && !FDE_IsXMLWhiteSpace(ch)) { | |
2149 m_dwMode = FDE_XMLSYNTAXMODE_TargetData; | |
2150 break; | |
2151 } | |
2152 } | |
2153 m_iTextDataLength = m_iDataPos; | |
2154 m_iDataPos = 0; | |
2155 m_dwMode = FDE_XMLSYNTAXMODE_AttriEqualSign; | |
2156 dwStatus = FDE_XMLSYNTAXSTATUS_AttriName; | |
2157 } | |
2158 } else { | |
2159 if (m_iDataPos >= m_iTextDataSize) { | |
2160 ReallocTextDataBuffer(); | |
2161 } | |
2162 m_pwsTextData[m_iDataPos++] = ch; | |
2163 m_pStart++; | |
2164 } | |
2165 break; | |
2166 case FDE_XMLSYNTAXMODE_AttriEqualSign: | |
2167 if (FDE_IsXMLWhiteSpace(ch)) { | |
2168 m_pStart++; | |
2169 break; | |
2170 } | |
2171 if (ch != L'=') { | |
2172 if (m_CurNode.eNodeType == FDE_XMLNODE_Instruction) { | |
2173 m_dwMode = FDE_XMLSYNTAXMODE_TargetData; | |
2174 break; | |
2175 } | |
2176 m_dwStatus = FDE_XMLSYNTAXSTATUS_Error; | |
2177 return m_dwStatus; | |
2178 } else { | |
2179 m_dwMode = FDE_XMLSYNTAXMODE_AttriQuotation; | |
2180 m_pStart++; | |
2181 } | |
2182 break; | |
2183 case FDE_XMLSYNTAXMODE_AttriQuotation: | |
2184 if (FDE_IsXMLWhiteSpace(ch)) { | |
2185 m_pStart++; | |
2186 break; | |
2187 } | |
2188 if (ch != L'\"' && ch != L'\'') { | |
2189 m_dwStatus = FDE_XMLSYNTAXSTATUS_Error; | |
2190 return m_dwStatus; | |
2191 } else { | |
2192 m_wQuotationMark = ch; | |
2193 m_dwMode = FDE_XMLSYNTAXMODE_AttriValue; | |
2194 m_pStart++; | |
2195 } | |
2196 break; | |
2197 case FDE_XMLSYNTAXMODE_AttriValue: | |
2198 if (ch == m_wQuotationMark) { | |
2199 if (m_iEntityStart > -1) { | |
2200 m_dwStatus = FDE_XMLSYNTAXSTATUS_Error; | |
2201 return m_dwStatus; | |
2202 } | |
2203 m_iTextDataLength = m_iDataPos; | |
2204 m_wQuotationMark = 0; | |
2205 m_iDataPos = 0; | |
2206 m_pStart++; | |
2207 m_dwMode = FDE_XMLSYNTAXMODE_AttriName; | |
2208 dwStatus = FDE_XMLSYNTAXSTATUS_AttriValue; | |
2209 } else { | |
2210 ParseTextChar(ch); | |
2211 } | |
2212 break; | |
2213 case FDE_XMLSYNTAXMODE_CloseInstruction: | |
2214 if (ch != L'>') { | |
2215 if (m_iDataPos >= m_iTextDataSize) { | |
2216 ReallocTextDataBuffer(); | |
2217 } | |
2218 m_pwsTextData[m_iDataPos++] = ch; | |
2219 m_dwMode = FDE_XMLSYNTAXMODE_TargetData; | |
2220 } else if (m_iDataPos > 0) { | |
2221 m_iTextDataLength = m_iDataPos; | |
2222 m_iDataPos = 0; | |
2223 dwStatus = FDE_XMLSYNTAXSTATUS_TargetData; | |
2224 } else { | |
2225 m_pStart++; | |
2226 FDE_LPXMLNODE pXMLNode = m_XMLNodeStack.GetTopElement(); | |
2227 if (pXMLNode == NULL) { | |
2228 m_dwStatus = FDE_XMLSYNTAXSTATUS_Error; | |
2229 return m_dwStatus; | |
2230 } | |
2231 m_XMLNodeStack.Pop(); | |
2232 pXMLNode = m_XMLNodeStack.GetTopElement(); | |
2233 if (pXMLNode == NULL) { | |
2234 m_CurNode.iNodeNum = -1; | |
2235 m_CurNode.eNodeType = FDE_XMLNODE_Unknown; | |
2236 } else { | |
2237 m_CurNode = *pXMLNode; | |
2238 } | |
2239 m_iCurrentNodeNum = m_CurNode.iNodeNum; | |
2240 m_iDataPos = 0; | |
2241 m_dwMode = FDE_XMLSYNTAXMODE_Text; | |
2242 dwStatus = FDE_XMLSYNTAXSTATUS_InstructionClose; | |
2243 } | |
2244 break; | |
2245 case FDE_XMLSYNTAXMODE_BreakElement: | |
2246 if (ch == L'>') { | |
2247 m_dwMode = FDE_XMLSYNTAXMODE_Text; | |
2248 dwStatus = FDE_XMLSYNTAXSTATUS_ElementBreak; | |
2249 } else if (ch == L'/') { | |
2250 m_dwMode = FDE_XMLSYNTAXMODE_CloseElement; | |
2251 } else { | |
2252 m_dwStatus = FDE_XMLSYNTAXSTATUS_Error; | |
2253 return m_dwStatus; | |
2254 } | |
2255 m_pStart++; | |
2256 break; | |
2257 case FDE_XMLSYNTAXMODE_CloseElement: | |
2258 if (!FDE_IsXMLNameChar(ch, m_iDataPos < 1)) { | |
2259 if (ch == L'>') { | |
2260 FDE_LPXMLNODE pXMLNode = m_XMLNodeStack.GetTopElement(); | |
2261 if (pXMLNode == NULL) { | |
2262 m_dwStatus = FDE_XMLSYNTAXSTATUS_Error; | |
2263 return m_dwStatus; | |
2264 } | |
2265 m_XMLNodeStack.Pop(); | |
2266 pXMLNode = m_XMLNodeStack.GetTopElement(); | |
2267 if (pXMLNode == NULL) { | |
2268 m_CurNode.iNodeNum = -1; | |
2269 m_CurNode.eNodeType = FDE_XMLNODE_Unknown; | |
2270 } else { | |
2271 m_CurNode = *pXMLNode; | |
2272 } | |
2273 m_iCurrentNodeNum = m_CurNode.iNodeNum; | |
2274 m_iTextDataLength = m_iDataPos; | |
2275 m_iDataPos = 0; | |
2276 m_dwMode = FDE_XMLSYNTAXMODE_Text; | |
2277 dwStatus = FDE_XMLSYNTAXSTATUS_ElementClose; | |
2278 } else if (!FDE_IsXMLWhiteSpace(ch)) { | |
2279 m_dwStatus = FDE_XMLSYNTAXSTATUS_Error; | |
2280 return m_dwStatus; | |
2281 } | |
2282 } else { | |
2283 if (m_iDataPos >= m_iTextDataSize) { | |
2284 ReallocTextDataBuffer(); | |
2285 } | |
2286 m_pwsTextData[m_iDataPos++] = ch; | |
2287 } | |
2288 m_pStart++; | |
2289 break; | |
2290 case FDE_XMLSYNTAXMODE_SkipCommentOrDecl: | |
2291 if (ch == '-') { | |
2292 m_dwMode = FDE_XMLSYNTAXMODE_SkipComment; | |
2293 } else { | |
2294 m_dwMode = FDE_XMLSYNTAXMODE_SkipDeclNode; | |
2295 m_SkipChar = L'>'; | |
2296 m_SkipStack.Push(L'>'); | |
2297 } | |
2298 break; | |
2299 case FDE_XMLSYNTAXMODE_SkipDeclNode: | |
2300 if (m_SkipChar == L'\'' || m_SkipChar == L'\"') { | |
2301 m_pStart++; | |
2302 if (ch != m_SkipChar) { | |
2303 break; | |
2304 } | |
2305 m_SkipStack.Pop(); | |
2306 FX_DWORD* pDWord = m_SkipStack.GetTopElement(); | |
2307 if (pDWord == NULL) { | |
2308 m_dwMode = FDE_XMLSYNTAXMODE_Text; | |
2309 } else { | |
2310 m_SkipChar = (FX_WCHAR)*pDWord; | |
2311 } | |
2312 } else { | |
2313 switch (ch) { | |
2314 case L'<': | |
2315 m_SkipChar = L'>'; | |
2316 m_SkipStack.Push(L'>'); | |
2317 break; | |
2318 case L'[': | |
2319 m_SkipChar = L']'; | |
2320 m_SkipStack.Push(L']'); | |
2321 break; | |
2322 case L'(': | |
2323 m_SkipChar = L')'; | |
2324 m_SkipStack.Push(L')'); | |
2325 break; | |
2326 case L'\'': | |
2327 m_SkipChar = L'\''; | |
2328 m_SkipStack.Push(L'\''); | |
2329 break; | |
2330 case L'\"': | |
2331 m_SkipChar = L'\"'; | |
2332 m_SkipStack.Push(L'\"'); | |
2333 break; | |
2334 default: | |
2335 if (ch == m_SkipChar) { | |
2336 m_SkipStack.Pop(); | |
2337 FX_DWORD* pDWord = m_SkipStack.GetTopElement(); | |
2338 if (pDWord == NULL) { | |
2339 m_iTextDataLength = m_iDataPos; | |
2340 m_iDataPos = 0; | |
2341 if (m_iTextDataLength >= 9 && | |
2342 FXSYS_memcmp(m_pwsTextData, L"[CDATA[", | |
2343 7 * sizeof(FX_WCHAR)) == 0 && | |
2344 FXSYS_memcmp(m_pwsTextData + m_iTextDataLength - 2, | |
2345 L"]]", 2 * sizeof(FX_WCHAR)) == 0) { | |
2346 m_iTextDataLength -= 9; | |
2347 FXSYS_memmove(m_pwsTextData, m_pwsTextData + 7, | |
2348 m_iTextDataLength * sizeof(FX_WCHAR)); | |
2349 dwStatus = FDE_XMLSYNTAXSTATUS_CData; | |
2350 } | |
2351 m_dwMode = FDE_XMLSYNTAXMODE_Text; | |
2352 } else { | |
2353 m_SkipChar = (FX_WCHAR)*pDWord; | |
2354 } | |
2355 } | |
2356 break; | |
2357 } | |
2358 if (m_SkipStack.GetSize() > 0) { | |
2359 if (m_iDataPos >= m_iTextDataSize) { | |
2360 ReallocTextDataBuffer(); | |
2361 } | |
2362 m_pwsTextData[m_iDataPos++] = ch; | |
2363 } | |
2364 m_pStart++; | |
2365 } | |
2366 break; | |
2367 case FDE_XMLSYNTAXMODE_SkipComment: | |
2368 if (ch == L'-') { | |
2369 m_iDataPos++; | |
2370 } else if (ch == L'>') { | |
2371 if (m_iDataPos > 1) { | |
2372 m_iDataPos = 0; | |
2373 m_dwMode = FDE_XMLSYNTAXMODE_Text; | |
2374 } | |
2375 } else { | |
2376 m_iDataPos = 0; | |
2377 } | |
2378 m_pStart++; | |
2379 break; | |
2380 case FDE_XMLSYNTAXMODE_TargetData: | |
2381 if (FDE_IsXMLWhiteSpace(ch)) { | |
2382 if (m_iDataPos < 1) { | |
2383 m_pStart++; | |
2384 break; | |
2385 } else if (m_wQuotationMark == 0) { | |
2386 m_iTextDataLength = m_iDataPos; | |
2387 m_wQuotationMark = 0; | |
2388 m_iDataPos = 0; | |
2389 m_pStart++; | |
2390 dwStatus = FDE_XMLSYNTAXSTATUS_TargetData; | |
2391 break; | |
2392 } | |
2393 } | |
2394 if (ch == '?') { | |
2395 m_dwMode = FDE_XMLSYNTAXMODE_CloseInstruction; | |
2396 m_pStart++; | |
2397 } else if (ch == '\"') { | |
2398 if (m_wQuotationMark == 0) { | |
2399 m_wQuotationMark = ch; | |
2400 m_pStart++; | |
2401 } else if (ch == m_wQuotationMark) { | |
2402 m_iTextDataLength = m_iDataPos; | |
2403 m_wQuotationMark = 0; | |
2404 m_iDataPos = 0; | |
2405 m_pStart++; | |
2406 dwStatus = FDE_XMLSYNTAXSTATUS_TargetData; | |
2407 } else { | |
2408 m_dwStatus = FDE_XMLSYNTAXSTATUS_Error; | |
2409 return m_dwStatus; | |
2410 } | |
2411 } else { | |
2412 if (m_iDataPos >= m_iTextDataSize) { | |
2413 ReallocTextDataBuffer(); | |
2414 } | |
2415 m_pwsTextData[m_iDataPos++] = ch; | |
2416 m_pStart++; | |
2417 } | |
2418 break; | |
2419 default: | |
2420 break; | |
2421 } | |
2422 if (dwStatus != FDE_XMLSYNTAXSTATUS_None) { | |
2423 return dwStatus; | |
2424 } | |
2425 } | |
2426 } | |
2427 return 0; | |
2428 } | |
2429 #endif | |
2430 CFDE_XMLSyntaxParser::~CFDE_XMLSyntaxParser() { | |
2431 #ifdef _FDE_BLOCK_BUFFER | |
2432 if (m_pCurrentBlock) { | |
2433 m_pCurrentBlock = NULL; | |
2434 } | |
2435 #else | |
2436 FX_Free(m_pwsTextData); | |
2437 #endif | |
2438 FX_Free(m_pBuffer); | |
2439 } | |
2440 int32_t CFDE_XMLSyntaxParser::GetStatus() const { | |
2441 if (m_pStream == NULL) { | |
2442 return -1; | |
2443 } | |
2444 int32_t iStreamLength = m_pStream->GetLength(); | |
2445 if (iStreamLength < 1) { | |
2446 return 100; | |
2447 } | |
2448 if (m_dwStatus == FDE_XMLSYNTAXSTATUS_Error) { | |
2449 return -1; | |
2450 } | |
2451 if (m_dwStatus == FDE_XMLSYNTAXSTATUS_EOS) { | |
2452 return 100; | |
2453 } | |
2454 return m_iParsedBytes * 100 / iStreamLength; | |
2455 } | |
2456 static int32_t FX_GetUTF8EncodeLength(const FX_WCHAR* pSrc, int32_t iSrcLen) { | |
2457 FX_DWORD unicode = 0; | |
2458 int32_t iDstNum = 0; | |
2459 while (iSrcLen-- > 0) { | |
2460 unicode = *pSrc++; | |
2461 int nbytes = 0; | |
2462 if ((FX_DWORD)unicode < 0x80) { | |
2463 nbytes = 1; | |
2464 } else if ((FX_DWORD)unicode < 0x800) { | |
2465 nbytes = 2; | |
2466 } else if ((FX_DWORD)unicode < 0x10000) { | |
2467 nbytes = 3; | |
2468 } else if ((FX_DWORD)unicode < 0x200000) { | |
2469 nbytes = 4; | |
2470 } else if ((FX_DWORD)unicode < 0x4000000) { | |
2471 nbytes = 5; | |
2472 } else { | |
2473 nbytes = 6; | |
2474 } | |
2475 iDstNum += nbytes; | |
2476 } | |
2477 return iDstNum; | |
2478 } | |
2479 FX_FILESIZE CFDE_XMLSyntaxParser::GetCurrentBinaryPos() const { | |
2480 if (m_pStream == NULL) { | |
2481 return 0; | |
2482 } | |
2483 int32_t nSrcLen = m_pStart - m_pBuffer; | |
2484 int32_t nDstLen = FX_GetUTF8EncodeLength(m_pBuffer, nSrcLen); | |
2485 return m_iParsedBytes + nDstLen; | |
2486 } | |
2487 #ifdef _FDE_BLOCK_BUFFER | |
2488 void CFDE_XMLSyntaxParser::ParseTextChar(FX_WCHAR ch) { | |
2489 if (m_iIndexInBlock == m_iAllocStep) { | |
2490 m_pCurrentBlock = m_BlockBuffer.GetAvailableBlock(m_iIndexInBlock); | |
2491 if (!m_pCurrentBlock) { | |
2492 return; | |
2493 } | |
2494 } | |
2495 m_pCurrentBlock[m_iIndexInBlock++] = ch; | |
2496 m_iDataLength++; | |
2497 if (m_iEntityStart > -1 && ch == L';') { | |
2498 CFX_WideString csEntity; | |
2499 m_BlockBuffer.GetTextData(csEntity, m_iEntityStart + 1, | |
2500 (m_iDataLength - 1) - m_iEntityStart - 1); | |
2501 int32_t iLen = csEntity.GetLength(); | |
2502 if (iLen > 0) { | |
2503 if (csEntity[0] == L'#') { | |
2504 ch = 0; | |
2505 FX_WCHAR w; | |
2506 if (iLen > 1 && csEntity[1] == L'x') { | |
2507 for (int32_t i = 2; i < iLen; i++) { | |
2508 w = csEntity[i]; | |
2509 if (w >= L'0' && w <= L'9') { | |
2510 ch = (ch << 4) + w - L'0'; | |
2511 } else if (w >= L'A' && w <= L'F') { | |
2512 ch = (ch << 4) + w - 55; | |
2513 } else if (w >= L'a' && w <= L'f') { | |
2514 ch = (ch << 4) + w - 87; | |
2515 } else { | |
2516 break; | |
2517 } | |
2518 } | |
2519 } else { | |
2520 for (int32_t i = 1; i < iLen; i++) { | |
2521 w = csEntity[i]; | |
2522 if (w < L'0' || w > L'9') { | |
2523 break; | |
2524 } | |
2525 ch = ch * 10 + w - L'0'; | |
2526 } | |
2527 } | |
2528 if (ch != 0) { | |
2529 m_BlockBuffer.SetTextChar(m_iEntityStart, ch); | |
2530 m_iEntityStart++; | |
2531 } | |
2532 } else { | |
2533 if (csEntity.Compare(L"amp") == 0) { | |
2534 m_BlockBuffer.SetTextChar(m_iEntityStart, L'&'); | |
2535 m_iEntityStart++; | |
2536 } else if (csEntity.Compare(L"lt") == 0) { | |
2537 m_BlockBuffer.SetTextChar(m_iEntityStart, L'<'); | |
2538 m_iEntityStart++; | |
2539 } else if (csEntity.Compare(L"gt") == 0) { | |
2540 m_BlockBuffer.SetTextChar(m_iEntityStart, L'>'); | |
2541 m_iEntityStart++; | |
2542 } else if (csEntity.Compare(L"apos") == 0) { | |
2543 m_BlockBuffer.SetTextChar(m_iEntityStart, L'\''); | |
2544 m_iEntityStart++; | |
2545 } else if (csEntity.Compare(L"quot") == 0) { | |
2546 m_BlockBuffer.SetTextChar(m_iEntityStart, L'\"'); | |
2547 m_iEntityStart++; | |
2548 } | |
2549 } | |
2550 } | |
2551 m_BlockBuffer.DeleteTextChars(m_iDataLength - m_iEntityStart, FALSE); | |
2552 m_pCurrentBlock = m_BlockBuffer.GetAvailableBlock(m_iIndexInBlock); | |
2553 m_iEntityStart = -1; | |
2554 } else { | |
2555 if (m_iEntityStart < 0 && ch == L'&') { | |
2556 m_iEntityStart = m_iDataLength - 1; | |
2557 } | |
2558 } | |
2559 m_pStart++; | |
2560 } | |
2561 #else | |
2562 void CFDE_XMLSyntaxParser::ParseTextChar(FX_WCHAR ch) { | |
2563 if (m_iDataPos >= m_iTextDataSize) { | |
2564 ReallocTextDataBuffer(); | |
2565 } | |
2566 m_pwsTextData[m_iDataPos] = ch; | |
2567 if (m_iEntityStart > -1 && ch == L';') { | |
2568 CFX_WideString csEntity(m_pwsTextData + m_iEntityStart + 1, | |
2569 m_iDataPos - m_iEntityStart - 1); | |
2570 int32_t iLen = csEntity.GetLength(); | |
2571 if (iLen > 0) { | |
2572 if (csEntity[0] == L'#') { | |
2573 ch = 0; | |
2574 FX_WCHAR w; | |
2575 if (iLen > 1 && csEntity[1] == L'x') { | |
2576 for (int32_t i = 2; i < iLen; i++) { | |
2577 w = csEntity[i]; | |
2578 if (w >= L'0' && w <= L'9') { | |
2579 ch = (ch << 4) + w - L'0'; | |
2580 } else if (w >= L'A' && w <= L'F') { | |
2581 ch = (ch << 4) + w - 55; | |
2582 } else if (w >= L'a' && w <= L'f') { | |
2583 ch = (ch << 4) + w - 87; | |
2584 } else { | |
2585 break; | |
2586 } | |
2587 } | |
2588 } else { | |
2589 for (int32_t i = 1; i < iLen; i++) { | |
2590 w = csEntity[i]; | |
2591 if (w < L'0' || w > L'9') { | |
2592 break; | |
2593 } | |
2594 ch = ch * 10 + w - L'0'; | |
2595 } | |
2596 } | |
2597 if (ch != 0) { | |
2598 m_pwsTextData[m_iEntityStart++] = ch; | |
2599 } | |
2600 } else { | |
2601 if (csEntity.Compare(L"amp") == 0) { | |
2602 m_pwsTextData[m_iEntityStart++] = L'&'; | |
2603 } else if (csEntity.Compare(L"lt") == 0) { | |
2604 m_pwsTextData[m_iEntityStart++] = L'<'; | |
2605 } else if (csEntity.Compare(L"gt") == 0) { | |
2606 m_pwsTextData[m_iEntityStart++] = L'>'; | |
2607 } else if (csEntity.Compare(L"apos") == 0) { | |
2608 m_pwsTextData[m_iEntityStart++] = L'\''; | |
2609 } else if (csEntity.Compare(L"quot") == 0) { | |
2610 m_pwsTextData[m_iEntityStart++] = L'\"'; | |
2611 } | |
2612 } | |
2613 } | |
2614 m_iDataPos = m_iEntityStart; | |
2615 m_iEntityStart = -1; | |
2616 } else { | |
2617 if (m_iEntityStart < 0 && ch == L'&') { | |
2618 m_iEntityStart = m_iDataPos; | |
2619 } | |
2620 m_iDataPos++; | |
2621 } | |
2622 m_pStart++; | |
2623 } | |
2624 void CFDE_XMLSyntaxParser::ReallocTextDataBuffer() { | |
2625 FXSYS_assert(m_pwsTextData != NULL); | |
2626 if (m_iTextDataSize <= 1024 * 1024) { | |
2627 m_iTextDataSize *= 2; | |
2628 } else { | |
2629 m_iTextDataSize += 1024 * 1024; | |
2630 } | |
2631 m_pwsTextData = FX_Realloc(FX_WCHAR, m_pwsTextData, m_iTextDataSize); | |
2632 } | |
2633 void CFDE_XMLSyntaxParser::GetData(CFX_WideString& wsData) const { | |
2634 FX_WCHAR* pBuf = wsData.GetBuffer(m_iTextDataLength); | |
2635 FXSYS_memcpy(pBuf, m_pwsTextData, m_iTextDataLength * sizeof(FX_WCHAR)); | |
2636 wsData.ReleaseBuffer(m_iTextDataLength); | |
2637 } | |
2638 #endif | |
OLD | NEW |