blob: 63b870774effdcf4a42da05083f35bd5558da05c [file] [log] [blame]
U-Lama\Lee560bd472011-12-28 19:42:49 -08001#include "tinyxml2.h"
2
3#include <string.h>
4#include <stdlib.h>
5#include <stdio.h>
U-Lama\Lee4cee6112011-12-31 14:58:18 -08006#include <ctype.h>
U-Lama\Lee560bd472011-12-28 19:42:49 -08007
8using namespace tinyxml2;
9
Lee Thomason3f57d272012-01-11 15:30:03 -080010// --------- CharBuffer ----------- //
U-Lama\Lee560bd472011-12-28 19:42:49 -080011/*static*/ CharBuffer* CharBuffer::Construct( const char* in )
12{
13 size_t len = strlen( in );
14 size_t size = len + sizeof( CharBuffer );
15 CharBuffer* cb = (CharBuffer*) malloc( size );
16 cb->length = len;
17 strcpy( cb->mem, in );
18 return cb;
19}
20
21
22/*static*/ void CharBuffer::Free( CharBuffer* cb )
23{
24 free( cb );
25}
26
27
Lee Thomason3f57d272012-01-11 15:30:03 -080028// --------- XMLNode ----------- //
29
30XMLNode::XMLNode( XMLDocument* doc ) :
31 document( doc ),
32 parent( 0 ),
33 firstChild( 0 ), lastChild( 0 ),
34 prev( 0 ), next( 0 )
U-Lama\Lee4cee6112011-12-31 14:58:18 -080035{
Lee Thomason3f57d272012-01-11 15:30:03 -080036
37}
38
39
40XMLNode::~XMLNode()
41{
42 XMLNode* node=firstChild;
43 while( node ) {
44 XMLNode* temp = node->next;
45 delete node;
46 node = temp;
U-Lama\Lee4cee6112011-12-31 14:58:18 -080047 }
Lee Thomason3f57d272012-01-11 15:30:03 -080048}
49
50
51XMLNode* XMLNode::InsertEndChild( XMLNode* addThis )
52{
53 if ( lastChild ) {
54 TIXMLASSERT( firstChild );
55 TIXMLASSERT( lastChild->next == 0 );
56 lastChild->next = addThis;
57 addThis->prev = lastChild;
58 lastChild = addThis;
59
60 addThis->parent = this;
Lee Thomasonce0763e2012-01-11 15:43:54 -080061 addThis->next = 0;
Lee Thomason3f57d272012-01-11 15:30:03 -080062 }
63 else {
64 TIXMLASSERT( firstChild == 0 );
65 firstChild = lastChild = addThis;
66
67 addThis->parent = this;
68 addThis->prev = 0;
Lee Thomasonce0763e2012-01-11 15:43:54 -080069 addThis->next = 0;
70 }
71 return addThis;
72}
73
74
75void XMLNode::Print( FILE* fp, int depth )
76{
77 for( int i=0; i<depth; ++i ) {
78 fprintf( fp, " " );
Lee Thomason3f57d272012-01-11 15:30:03 -080079 }
80}
81
82
83const char* XMLNode::ParseText( char* p, const char* endTag, char** next )
84{
85 TIXMLASSERT( endTag && *endTag );
86
87 char* start = SkipWhiteSpace( p );
88 if ( !start )
Lee Thomasonce0763e2012-01-11 15:43:54 -080089 return 0;
Lee Thomason3f57d272012-01-11 15:30:03 -080090
91 char endChar = *endTag;
92 p = start;
93 int length = strlen( endTag );
94
95 while ( *p ) {
96 if ( *p == endChar ) {
97 if ( strncmp( p, endTag, length ) == 0 ) {
98 *p = 0;
99 *next = p + length;
100 return start;
101 }
102 }
103 ++p;
104 }
105 return 0;
106}
107
108
109// --------- XMLComment ---------- //
110
111XMLComment::XMLComment( XMLDocument* doc ) : XMLNode( doc )
112{
113}
114
115
Lee Thomasonce0763e2012-01-11 15:43:54 -0800116XMLComment::~XMLComment()
Lee Thomason3f57d272012-01-11 15:30:03 -0800117{
118
119}
120
121
Lee Thomasonce0763e2012-01-11 15:43:54 -0800122void XMLComment::Print( FILE* fp, int depth )
123{
124 XMLNode::Print( fp, depth );
125 fprintf( fp, "<!-- %s -->\n", value );
126}
127
128
129char* XMLComment::ParseDeep( char* p )
Lee Thomason3f57d272012-01-11 15:30:03 -0800130{
131 // Comment parses as text.
132 value = ParseText( p, "-->", &p );
U-Lama\Lee4cee6112011-12-31 14:58:18 -0800133 return p;
134}
135
136
Lee Thomason3f57d272012-01-11 15:30:03 -0800137// --------- XMLDocument ----------- //
U-Lama\Lee560bd472011-12-28 19:42:49 -0800138XMLDocument::XMLDocument() :
139 charBuffer( 0 )
140{
141}
U-Lama\Leee13c3e62011-12-28 14:36:55 -0800142
143
Lee Thomason3f57d272012-01-11 15:30:03 -0800144XMLDocument::~XMLDocument()
145{
146 delete root;
147 delete charBuffer;
148}
149
150
151
152bool XMLDocument::Parse( const char* p )
153{
Lee Thomasonce0763e2012-01-11 15:43:54 -0800154 charBuffer = CharBuffer::Construct( p );
Lee Thomason3f57d272012-01-11 15:30:03 -0800155 XMLNode* node = 0;
Lee Thomasonce0763e2012-01-11 15:43:54 -0800156 char* q = Identify( charBuffer->mem, &node );
157 node->ParseDeep( q );
158 return true;
Lee Thomason3f57d272012-01-11 15:30:03 -0800159}
160
161
Lee Thomasonce0763e2012-01-11 15:43:54 -0800162void XMLDocument::Print( FILE* fp, int depth )
Lee Thomason3f57d272012-01-11 15:30:03 -0800163{
Lee Thomasonce0763e2012-01-11 15:43:54 -0800164 for( XMLNode* node = root->firstChild; node; node=node->next ) {
165 node->Print( fp, depth );
166 }
Lee Thomason3f57d272012-01-11 15:30:03 -0800167}
168
169
Lee Thomason3f57d272012-01-11 15:30:03 -0800170char* XMLDocument::Identify( char* p, XMLNode** node )
U-Lama\Leee13c3e62011-12-28 14:36:55 -0800171{
U-Lama\Lee4cee6112011-12-31 14:58:18 -0800172 XMLNode* returnNode = 0;
173
174 p = XMLNode::SkipWhiteSpace( p );
175 if( !p || !*p || *p != '<' )
176 {
177 return 0;
178 }
179
180 // What is this thing?
181 // - Elements start with a letter or underscore, but xml is reserved.
182 // - Comments: <!--
183 // - Decleration: <?xml
184 // - Everthing else is unknown to tinyxml.
185 //
186
187 const char* xmlHeader = { "<?xml" };
188 const char* commentHeader = { "<!--" };
189 const char* dtdHeader = { "<!" };
190 const char* cdataHeader = { "<![CDATA[" };
191
192 if ( XMLNode::StringEqual( p, xmlHeader, 5 ) ) {
Lee Thomasonce0763e2012-01-11 15:43:54 -0800193 returnNode = new XMLComment( this );
U-Lama\Lee4cee6112011-12-31 14:58:18 -0800194 }
195 else {
196 TIXMLASSERT( 0 );
197 }
U-Lama\Leee13c3e62011-12-28 14:36:55 -0800198
Lee Thomason3f57d272012-01-11 15:30:03 -0800199 *node = returnNode;
200 return p;
U-Lama\Leee13c3e62011-12-28 14:36:55 -0800201}