blob: 7580312d9e8ff78b3b9c89ad92f2055f82c985ab [file] [log] [blame]
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001/*
2 * Copyright (C) 2007 The Android Open Source Project
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 * http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 */
16
17#include <xml/xml_tinyParser.h>
18
19int32_t xml_errno;
20
21#ifdef XML_DOM_PARSER
22
23#define XML_IS_WHITESPACE(x) ((x) == '\t' || (x) == '\n' || (x) == ' ' || (x) == '\r')
24#define XML_IS_NAMECHAR(ch) (isalpha(ch) || isdigit(ch) || ch ==':' || \
25 ch == '_' || ch == '-' || ch =='.')
26
27static uint8_t *xml_ignore_blank(uint8_t *buffer)
28{
29 if (NULL == buffer)
30 return NULL;
31
32 while (XML_IS_WHITESPACE(*buffer))
33 buffer++;
34
35 return buffer;
36}
37
38static uint8_t *xml_goto_tagend(uint8_t *buffer)
39{
40 int32_t nameLen, valueLen;
41 uint8_t *name, *value;
42
43 if (NULL == buffer)
44 return NULL;
45
46 /* Ignore the start-tag */
47 if (*buffer == '<') {
48 buffer++;
49 while (buffer != NULL && XML_IS_NAMECHAR(*buffer))
50 buffer++;
51 if (NULL == buffer)
52 return NULL;
53 }
54
55 do {
56 if (NULL == (buffer = xml_ignore_blank(buffer)))
57 return NULL;
58
59 if (*buffer == '>' || (*buffer == '/' && *(buffer + 1) == '>'))
60 return buffer;
61
62 if (NULL ==
63 XML_DOM_getAttr(buffer, &name, &nameLen, &value, &valueLen))
64 return NULL;
65
66 buffer = value + valueLen + 1;
67 } while (*buffer != '\0');
68
69 return NULL;
70}
71
72static uint8_t *xml_match_tag(uint8_t *buffer)
73{
74 int32_t tagLen, tagType, bal;
75
76 if (NULL == buffer)
77 return NULL;
78
79 bal = 0;
80 do {
81 if (NULL == (buffer = XML_DOM_getTag(buffer, &tagLen, &tagType)))
82 return NULL;
83
84 switch (tagType) {
85 case XML_TAG_SELF:
86 case XML_TAG_START:
87 if (NULL == (buffer = xml_goto_tagend(buffer + tagLen + 1)))
88 return NULL;
89 if (strncmp((char *)buffer, "/>", 2) == 0) {
90 buffer += 2;
91 } else {
92 bal++;
93 }
94 break;
95
96 case XML_TAG_END:
97 if (bal <= 0)
98 return NULL;
99 buffer = buffer + tagLen + 2;
100 bal--;
101 break;
102 }
103 } while (bal != 0);
104
105 return buffer;
106}
107
108uint8_t *XML_DOM_getAttr(uint8_t *buffer, uint8_t **pName, int32_t *nameLen,
109 uint8_t **pValue, int32_t *valueLen)
110{
111 uint8_t charQuoted;
112
113 if (NULL == buffer) {
114 XML_ERROR(XML_ERROR_BUFFER_NULL);
115 return NULL;
116 }
117
118 /* Ignore the tag */
119 if (*buffer == '<') {
120 buffer++;
121 /* Ignore the STag */
122 while (buffer != NULL && XML_IS_NAMECHAR(*buffer))
123 buffer++;
124 if (NULL == buffer)
125 return NULL;
126 }
127
128 if (NULL == (buffer = xml_ignore_blank(buffer))) {
129 XML_ERROR(XML_ERROR_BUFFER_NULL);
130 return NULL;
131 }
132
133 /* Name */
134 *pName = buffer;
135 while (buffer != NULL && XML_IS_NAMECHAR(*buffer))
136 buffer++;
137 if (NULL == buffer) {
138 XML_ERROR(XML_ERROR_ATTR_NAME);
139 return NULL;
140 }
141 *nameLen = buffer - *pName;
142 if (*nameLen <= 0) {
143 XML_ERROR(XML_ERROR_ATTR_NAME);
144 return NULL;
145 }
146
147 /* '=' */
148 buffer = xml_ignore_blank(buffer);
149 if (NULL == buffer || *buffer != '=') {
150 XML_ERROR(XML_ERROR_ATTR_MISSED_EQUAL);
151 return NULL;
152 }
153
154 /* Value */
155 buffer++;
156 buffer = xml_ignore_blank(buffer);
157 if (NULL == buffer || (*buffer != '"' && *buffer != '\'')) {
158 XML_ERROR(XML_ERROR_ATTR_VALUE);
159 return NULL;
160 }
161 charQuoted = *buffer++;
162 *pValue = buffer;
163 while (*buffer != '\0' && *buffer != charQuoted)
164 buffer++;
165 if (*buffer != charQuoted) {
166 XML_ERROR(XML_ERROR_ATTR_VALUE);
167 return NULL;
168 }
169 *valueLen = buffer - *pValue;
170
171 XML_ERROR(XML_ERROR_OK);
172
173 return buffer + 1;
174}
175
176uint8_t *XML_DOM_getValue(uint8_t *buffer, uint8_t **pValue, int32_t *valueLen)
177{
178 uint8_t *pEnd;
179
180 if (NULL == buffer) {
181 XML_ERROR(XML_ERROR_BUFFER_NULL);
182 return NULL;
183 }
184
185 /* Ignore the STag */
186 if (*buffer == '<') {
187 buffer++;
188 /* If it's an end_tag, no value should be returned */
189 if (*buffer == '/') {
190 *valueLen = 0;
191 XML_ERROR(XML_ERROR_NOVALUE);
192 return NULL;
193 }
194
195 while (buffer != NULL && XML_IS_NAMECHAR(*buffer))
196 buffer++;
197 if (NULL == buffer) {
198 XML_ERROR(XML_ERROR_BUFFER_NULL);
199 return NULL;
200 }
201
202 if (NULL == (buffer = xml_goto_tagend(buffer))) {
203 XML_ERROR(XML_ERROR_PROPERTY_END);
204 return NULL;
205 }
206 }
207
208 /* <test/> node found */
209 if (*buffer == '/') {
210 if (*(buffer + 1) != '>') {
211 XML_ERROR(XML_ERROR_PROPERTY_END);
212 return NULL;
213 }
214 XML_ERROR(XML_ERROR_OK);
215 *valueLen = 0;
216 return buffer;
217 }
218
219 if (*buffer == '>')
220 buffer++;
221
222 if (NULL == (buffer = xml_ignore_blank(buffer))) {
223 XML_ERROR(XML_ERROR_BUFFER_NULL);
224 return NULL;
225 }
226
227 /* the following is a tag instead of the value */
228 if (*buffer == '<') { /* nono value, such as <test></test> */
229 buffer++;
230 if (*buffer != '/') {
231 XML_ERROR(XML_ERROR_ENDTAG);
232 return NULL;
233 }
234 *valueLen = 0;
235 XML_ERROR(XML_ERROR_OK);
236 return NULL;
237 }
238
239 *pValue = buffer;
240 pEnd = NULL;
241 while (*buffer != '\0' && *buffer != '<') {
242 if (!XML_IS_WHITESPACE(*buffer))
243 pEnd = buffer;
244 buffer++;
245 }
246 if (*buffer != '<' || pEnd == NULL) {
247 XML_ERROR(XML_ERROR_VALUE);
248 return NULL;
249 }
250
251 *valueLen = pEnd - *pValue + 1;
252
253 buffer++;
254 if (*buffer != '/') {
255 XML_ERROR(XML_ERROR_ENDTAG);
256 return NULL;
257 }
258
259 XML_ERROR(XML_ERROR_OK);
260
261 return buffer - 1;
262}
263
264uint8_t *XML_DOM_getTag(uint8_t *buffer, int32_t *tagLen, int32_t *tagType)
265{
266 uint8_t *pStart;
267
268 /* WARNING: <!-- --> comment is not supported in this verison */
269 if (NULL == buffer) {
270 XML_ERROR(XML_ERROR_BUFFER_NULL);
271 return NULL;
272 }
273
274 do {
275 while (*buffer != '<') {
276 if (*buffer == '\0') {
277 XML_ERROR(XML_ERROR_BUFFER_NULL);
278 return NULL;
279 }
280
281 if (*buffer == '\"' || *buffer == '\'') {
282 uint8_t charQuoted = *buffer;
283 buffer++;
284 while (*buffer != '\0' && *buffer != charQuoted)
285 buffer++;
286 if (*buffer == '\0') {
287 XML_ERROR(XML_ERROR_BUFFER_NULL);
288 return NULL;
289 }
290 }
291 buffer++;
292 }
293 buffer++;
294 } while (*buffer == '!' || *buffer == '?');
295
296 pStart = buffer - 1;
297
298 if (*buffer == '/') {
299 buffer++;
300 *tagType = XML_TAG_END;
301 } else {
302 /* check here if it is self-end-tag */
303 uint8_t *pCheck = xml_goto_tagend(pStart);
304 if (pCheck == NULL) {
305 XML_ERROR(XML_ERROR_PROPERTY_END);
306 return NULL;
307 }
308
309 if (*pCheck == '>')
310 *tagType = XML_TAG_START;
311 else if (strncmp((char *)pCheck, "/>", 2) == 0)
312 *tagType = XML_TAG_SELF;
313 else {
314 XML_ERROR(XML_ERROR_PROPERTY_END);
315 return NULL;
316 }
317 }
318
319 while (buffer != NULL && XML_IS_NAMECHAR(*buffer))
320 buffer++;
321 if (NULL == buffer) {
322 XML_ERROR(XML_ERROR_BUFFER_NULL);
323 return NULL;
324 }
325
326 if (*tagType == XML_TAG_END)
327 *tagLen = buffer - pStart - 2;
328 else
329 *tagLen = buffer - pStart - 1;
330
331 XML_ERROR(XML_ERROR_OK);
332
333 return pStart;
334}
335
336uint8_t *XML_DOM_getNode(uint8_t *buffer, const uint8_t *const node)
337{
338 uint8_t *pStart;
339 uint8_t buf[XML_MAX_PROPERTY_LEN + 2];
340 uint8_t *nodeStr = buf;
341 uint8_t *retPtr = NULL;
342 int32_t tagLen, tagType;
343 uint8_t *lastNode = (uint8_t *)"";
344
345 if (NULL == buffer) {
346 XML_ERROR(XML_ERROR_BUFFER_NULL);
347 return NULL;
348 }
349
350 strncpy((char *)nodeStr, (char *)node, XML_MAX_PROPERTY_LEN);
351 strcat((char *)nodeStr, "\\");
352 pStart = (uint8_t *)strchr((char *)nodeStr, '\\');
353
354 while (pStart != NULL) {
355 *pStart = '\0';
356
357 /* get the first start_tag from buffer */
358 if (NULL == (buffer = XML_DOM_getTag(buffer, &tagLen, &tagType))) {
359 XML_ERROR(XML_ERROR_NO_SUCH_NODE);
360 return NULL;
361 }
362
363 if (tagType == XML_TAG_END) {
364 if (0 ==
365 strncmp((char *)lastNode, (char *)(buffer + 2), strlen((char *)lastNode)))
366 XML_ERROR(XML_ERROR_NO_SUCH_NODE);
367 else
368 XML_ERROR(XML_ERROR_NO_START_TAG);
369 return NULL;
370 }
371
372 /* wrong node, contiue to fetch the next node */
373 if ((int32_t) strlen((char *)nodeStr) != tagLen
374 || strncmp((char *)nodeStr, (char *)(buffer + 1), tagLen) != 0) {
375 /* we should ignore all the middle code */
376 buffer = xml_match_tag(buffer);
377 continue;
378 }
379
380 retPtr = buffer; /* retPtr starts with '<xxx>' */
381 buffer += (tagLen + 1);
382
383 if (tagType == XML_TAG_SELF) {
384 nodeStr = pStart + 1;
385 break;
386 }
387
388 lastNode = nodeStr;
389 nodeStr = pStart + 1;
390 pStart = (uint8_t *)strchr((char *)nodeStr, '\\');
391 }
392
393 /* Check 5: nodeStr should be empty here */
394 if (*nodeStr != '\0') {
395 XML_ERROR(XML_ERROR_NO_SUCH_NODE);
396 return NULL;
397 }
398
399 XML_ERROR(XML_ERROR_OK);
400
401 return retPtr;
402}
403
404uint8_t *XML_DOM_getNodeValue(uint8_t *buffer, uint8_t *node,
405 uint8_t **value, int32_t *valueLen)
406{
407 uint8_t *pStart;
408 uint8_t *lastTag;
409
410 if (NULL == node || NULL == buffer) {
411 XML_ERROR(XML_ERROR_BUFFER_NULL);
412 return NULL;
413 }
414
415 lastTag = node + strlen((char *)node) - 1;
416 while (lastTag >= node && *lastTag != '\\')
417 lastTag--;
418 lastTag++;
419
420 if (NULL == (pStart = XML_DOM_getNode(buffer, node)))
421 return NULL;
422
423 pStart += (strlen((char *)lastTag) + 1);
424
425 if (NULL == (pStart = xml_goto_tagend(pStart))) {
426 XML_ERROR(XML_ERROR_PROPERTY_END);
427 return NULL;
428 }
429
430 if (NULL == (pStart = XML_DOM_getValue(pStart, value, valueLen)))
431 return NULL;
432
433 /* Check the end tag */
434#ifdef XML_DOM_CHECK_ENDTAG
435 if (strncmp((char *)pStart, "/>", 2) == 0) {
436
437 } else if (strncmp((char *)lastTag, (char *)(pStart + 2), strlen((char *)lastTag)) !=
438 0) {
439 XML_ERROR(XML_ERROR_ENDTAG);
440 return NULL;
441 }
442#endif
443
444 XML_ERROR(XML_ERROR_OK);
445
446 return *value;
447}
448
449uint8_t *XML_DOM_getNextNode(uint8_t *buffer, uint8_t **pNodeName, int32_t *nodenameLen)
450{
451 int32_t tagType;
452
453 if (NULL == buffer)
454 return NULL;
455
456 do {
457 if (NULL ==
458 (buffer = XML_DOM_getTag(buffer + 1, nodenameLen, &tagType))) {
459 XML_ERROR(XML_ERROR_NO_SUCH_NODE);
460 return NULL;
461 }
462 } while (tagType == XML_TAG_END);
463
464 *pNodeName = buffer + 1;
465
466 XML_ERROR(XML_ERROR_OK);
467
468 return buffer;
469}
470
471#endif /* XML_DOM_PARSER */
472
473#ifdef WBXML_DOM_PARSER
474
475#ifdef WBXML_OLD_VERSION
476uint8_t *WBXML_DOM_getNode(uint8_t *buffer, int32_t bufferLen,
477 uint8_t *node)
478{
479 int32_t i = 0, j = 0;
480
481 if (NULL == buffer || node == NULL) {
482 XML_ERROR(XML_ERROR_BUFFER_NULL);
483 return NULL;
484 }
485
486 while (i < bufferLen) {
487 if (WBXML_GET_TAG(buffer[i]) == WBXML_GET_TAG(node[j])) {
488 j++;
489 if (node[j] == '\0')
490 break;
491
492 /* Check if there is the content(it should have content) */
493 if (!WBXML_HAS_CONTENT(buffer[i])) {
494 /*XML_ERROR(WBXML_ERROR_MISSED_CONTENT); */
495 XML_ERROR(XML_ERROR_NO_SUCH_NODE);
496 return NULL;
497 }
498
499 /* Ignore the attrib filed */
500 if (WBXML_HAS_ATTR(buffer[i])) {
501 while (i < bufferLen && buffer[i] != WBXML_ATTR_END)
502 i++;
503 if (i >= bufferLen)
504 break;
505 }
506 }
507 i++;
508
509 /* Ignore the content filed */
510 if (buffer[i] == WBXML_STR_I) {
511 while (i < bufferLen && buffer[i] != WBXML_END)
512 i++;
513 if (i >= bufferLen)
514 break;
515 i++;
516 }
517 }
518
519 if (i >= bufferLen) {
520 XML_ERROR(XML_ERROR_NO_SUCH_NODE);
521 return NULL;
522 }
523
524 XML_ERROR(XML_ERROR_OK);
525
526 return buffer + i + 1;
527}
528
529uint8_t *WBXML_DOM_getNodeValue(uint8_t *buffer, int32_t bufferLen,
530 uint8_t *node,
531 uint8_t **value, int32_t *valueLen)
532{
533 int32_t i;
534 uint8_t *pEnd;
535
536 *value = NULL;
537 *valueLen = 0;
538
539 pEnd = buffer + bufferLen;
540 buffer = WBXML_DOM_getNode(buffer, bufferLen, node);
541 if (NULL == buffer) {
542 XML_ERROR(XML_ERROR_NO_SUCH_NODE);
543 return NULL;
544 }
545
546 if (*buffer == WBXML_OPAUE) {
547 buffer++;
548 *valueLen = WBXML_GetUintVar(buffer, &i);
549 if (*valueLen < 0) {
550 XML_ERROR(WBXML_ERROR_MBUINT32);
551 return NULL;
552 }
553 buffer += i;
554 *value = buffer;
555 return *value;
556 }
557
558 if (*buffer != WBXML_STR_I) {
559 XML_ERROR(WBXML_ERROR_MISSED_STARTTAG);
560 return NULL;
561 }
562
563 buffer++;
564
565 i = 0;
566 while ((buffer + i) < pEnd && buffer[i] != WBXML_END)
567 i++;
568
569 if (buffer[i] != WBXML_END) {
570 XML_ERROR(WBXML_ERROR_MISSED_ENDTAG);
571 return NULL;
572 }
573
574 *value = buffer;
575 *valueLen = i;
576 XML_ERROR(XML_ERROR_OK);
577
578 return *value;
579}
580#endif /* WBXML_OLD_VERSION */
581
582#define MAX_UINT_VAR_BYTE 4
583#define UINTVAR_INVALID -1
584int32_t WBXML_GetUintVar(const uint8_t *const buffer, int32_t *len)
585{
586 int32_t i, byteLen;
587 int32_t sum;
588
589 byteLen = 0;
590 while ((buffer[byteLen] & 0x80) > 0 && byteLen < MAX_UINT_VAR_BYTE)
591 byteLen++;
592
593 if (byteLen > MAX_UINT_VAR_BYTE)
594 return UINTVAR_INVALID;
595
596 *len = byteLen + 1;
597 sum = buffer[byteLen];
598 for (i = byteLen - 1; i >= 0; i--)
599 sum += ((buffer[i] & 0x7F) << 7 * (byteLen - i));
600
601 return sum;
602}
603
604XML_BOOL WBXML_DOM_Init(WBXML * pWbxml, uint8_t *buffer,
605 int32_t bufferLen)
606{
607 int32_t num, len;
608
609 pWbxml->End = buffer + bufferLen;
610 pWbxml->version = *buffer++;
611 if (UINTVAR_INVALID == (num = WBXML_GetUintVar(buffer, &len)))
612 return XML_FALSE;
613 buffer += len;
614 pWbxml->publicid = num;
615 if (UINTVAR_INVALID == (num = WBXML_GetUintVar(buffer, &len)))
616 return XML_FALSE;
617 buffer += len;
618 pWbxml->charset = num;
619 if (UINTVAR_INVALID == (num = WBXML_GetUintVar(buffer, &len)))
620 return XML_FALSE;
621 buffer += len;
622 pWbxml->strTable = buffer;
623 pWbxml->strTableLen = num;
624 buffer += num;
625 pWbxml->curPtr = pWbxml->Content = buffer;
626 pWbxml->depth = 0;
627
628 return XML_TRUE;
629}
630
631void WBXML_DOM_Rewind(WBXML * pWbxml)
632{
633 pWbxml->curPtr = pWbxml->Content;
634}
635
636XML_BOOL WBXML_DOM_Eof(WBXML * pWbxml)
637{
638 if (pWbxml->curPtr > pWbxml->End)
639 return XML_TRUE;
640
641 return XML_FALSE;
642}
643
644uint8_t WBXML_DOM_GetTag(WBXML * pWbxml)
645{
646 uint8_t tagChar;
647
648 if (pWbxml->curPtr > pWbxml->End)
649 return XML_EOF;
650
651 tagChar = *pWbxml->curPtr;
652 pWbxml->curPtr++;
653
654 if (WBXML_GET_TAG(tagChar) == WBXML_CONTENT_END)
655 pWbxml->depth--;
656 else
657 pWbxml->depth++;
658
659 return tagChar;
660}
661
662uint8_t WBXML_DOM_GetChar(WBXML * pWbxml)
663{
664 return *pWbxml->curPtr++;
665}
666
667void WBXML_DOM_Seek(WBXML * pWbxml, int32_t offset)
668{
669 pWbxml->curPtr += offset;
670}
671
672uint8_t WBXML_DOM_GetUIntVar(WBXML * pWbxml)
673{
674 int32_t num, len;
675
676 num = WBXML_GetUintVar(pWbxml->curPtr, &len);
677 pWbxml->curPtr += len;
678
679 return (uint8_t)num;
680}
681
682#ifdef XML_TREE_STRUCTURE
683
684#ifdef DEBUG_MODE
685static int32_t malloc_times = 0;
686static int32_t free_times = 0;
687void XML_PrintMallocInfo()
688{
689 printf("====XML_PrintMallocInfo====\n");
690 printf(" Total malloc times:%d\n", malloc_times);
691 printf(" Total free times:%d\n", free_times);
692 printf("===========================\n");
693}
694#endif
695
696void *xml_malloc(int32_t size)
697{
698#ifdef DEBUG_MODE
699 malloc_times++;
700#endif
701 return malloc(size);
702}
703
704void xml_free(void *buffer)
705{
706#ifdef DEBUG_MODE
707 free_times++;
708#endif
709 free(buffer);
710}
711
712XML_TREE *xml_tree_fillnode(uint8_t **buf, int32_t tagLen)
713{
714 XML_TREE *Tree;
715 uint8_t *pAttr, *pName, *pValue;
716 int32_t nameLen, valueLen;
717 uint8_t *buffer = *buf;
718
719 if (NULL == (Tree = (XML_TREE *) xml_malloc(sizeof(XML_TREE))))
720 return NULL;
721 memset(Tree, 0, sizeof(XML_TREE));
722
723 strncpy((char *)Tree->tag, (char *)++buffer, tagLen);
724 buffer += tagLen;
725 pAttr = buffer;
726
727 /* attribute */
728 while (NULL !=
729 (pAttr =
730 XML_DOM_getAttr(pAttr, &pName, &nameLen, &pValue,
731 &valueLen))) {
732 XML_TREE_ATTR *attr;
733 if (NULL ==
734 (attr = (XML_TREE_ATTR *) xml_malloc(sizeof(XML_TREE_ATTR))))
735 return NULL;
736 memset(attr, 0, sizeof(XML_TREE_ATTR));
737 strncpy((char *)attr->name, (char *)pName, nameLen);
738 strncpy((char *)attr->value, (char *)pValue, valueLen);
739 buffer = pValue + valueLen + 1;
740
741 if (NULL != Tree->attr) // no attribute now
742 Tree->last_attr->next = attr;
743 else
744 Tree->attr = attr;
745 Tree->last_attr = attr;
746 }
747
748 /* value */
749 pAttr = XML_DOM_getValue(buffer, &pValue, &valueLen);
750 if (pAttr != NULL && valueLen > 0) {
751 strncpy((char *)Tree->value, (char *)pValue, valueLen);
752 buffer = pValue + valueLen;
753 }
754
755 *buf = buffer;
756 return Tree;
757}
758
759XML_TREE *XML_makeTree(uint8_t **buf)
760{
761 uint8_t *pBuf;
762 int32_t valueLen, tagType;
763 uint8_t *buffer = *buf;
764 XML_TREE *TreeHead = NULL;
765
766 if (NULL == (buffer = XML_DOM_getTag(buffer, &valueLen, &tagType)))
767 return NULL;
768 if (XML_TAG_END == tagType)
769 return NULL;
770 if (NULL == (TreeHead = xml_tree_fillnode(&buffer, valueLen)))
771 return NULL;
772 if (XML_TAG_SELF == tagType) {
773 *buf = buffer;
774 return TreeHead;
775 }
776
777 do {
778 if (NULL == (pBuf = XML_DOM_getTag(buffer, &valueLen, &tagType)))
779 return NULL;
780
781 switch (tagType) {
782 case XML_TAG_SELF:
783 case XML_TAG_START:
784 if (NULL == TreeHead->child)
785 TreeHead->child = XML_makeTree(&buffer);
786 else if (NULL == TreeHead->child->last_brother) {
787 TreeHead->child->brother = XML_makeTree(&buffer);
788 TreeHead->child->last_brother = TreeHead->child->brother;
789 } else {
790 TreeHead->child->last_brother->brother =
791 XML_makeTree(&buffer);
792 TreeHead->child->last_brother =
793 TreeHead->child->last_brother->brother;
794 }
795 break;
796 case XML_TAG_END:
797 *buf = pBuf;
798 return TreeHead;
799 }
800 buffer++;
801 } while (1);
802}
803
804void XML_freeTree(XML_TREE * pTree)
805{
806 XML_TREE *p, *pNext;
807 XML_TREE_ATTR *pa, *lastpa;
808
809 if (NULL == pTree)
810 return;
811
812 p = pTree->brother;
813 while (NULL != p) {
814 pNext = p->brother;
815 p->brother = NULL;
816 XML_freeTree(p);
817 p = pNext;
818 }
819
820 if (NULL != pTree->child)
821 XML_freeTree(pTree->child);
822
823 pa = pTree->attr;
824 while (NULL != pa) {
825 lastpa = pa;
826 pa = pa->next;
827 xml_free(lastpa);
828 }
829 xml_free(pTree);
830}
831
832#endif /* XML_TREE_STRUCTURE */
833
834#endif /* WBXML_DOM_PARSER */