Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(462)

Side by Side Diff: xfa/src/fde/xml/fde_xml_imp.cpp

Issue 1803723002: Move xfa/src up to xfa/. (Closed) Base URL: https://pdfium.googlesource.com/pdfium.git@master
Patch Set: Rebase to master Created 4 years, 9 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
« no previous file with comments | « xfa/src/fde/xml/fde_xml_imp.h ('k') | xfa/src/fee/fde_txtedtbuf.h » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
(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"&amp;");
414 wsValue.Replace(L"<", L"&lt;");
415 wsValue.Replace(L">", L"&gt;");
416 wsValue.Replace(L"\'", L"&apos;");
417 wsValue.Replace(L"\"", L"&quot;");
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"&amp;");
448 wsValue.Replace(L"<", L"&lt;");
449 wsValue.Replace(L">", L"&gt;");
450 wsValue.Replace(L"\'", L"&apos;");
451 wsValue.Replace(L"\"", L"&quot;");
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"&amp;");
476 ws.Replace(L"<", L"&lt;");
477 ws.Replace(L">", L"&gt;");
478 ws.Replace(L"\'", L"&apos;");
479 ws.Replace(L"\"", L"&quot;");
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"&amp;");
984 wsValue.Replace(L"<", L"&lt;");
985 wsValue.Replace(L">", L"&gt;");
986 wsValue.Replace(L"\'", L"&apos;");
987 wsValue.Replace(L"\"", L"&quot;");
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"&amp;");
1018 wsValue.Replace(L"<", L"&lt;");
1019 wsValue.Replace(L">", L"&gt;");
1020 wsValue.Replace(L"\'", L"&apos;");
1021 wsValue.Replace(L"\"", L"&quot;");
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"&amp;");
1046 ws.Replace(L"<", L"&lt;");
1047 ws.Replace(L">", L"&gt;");
1048 ws.Replace(L"\'", L"&apos;");
1049 ws.Replace(L"\"", L"&quot;");
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 }
OLDNEW
« no previous file with comments | « xfa/src/fde/xml/fde_xml_imp.h ('k') | xfa/src/fee/fde_txtedtbuf.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698