blob: cfe296964f9274956670bed422fbd7145a8e719c [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{
Lee Thomason85403d82012-01-11 15:55:05 -080077 for( XMLNode* node = firstChild; node; node=node->next ) {
78 node->Print( fp, depth );
79 }
80}
81
82void XMLNode::PrintSpace( FILE* fp, int depth )
83{
Lee Thomasonce0763e2012-01-11 15:43:54 -080084 for( int i=0; i<depth; ++i ) {
85 fprintf( fp, " " );
Lee Thomason3f57d272012-01-11 15:30:03 -080086 }
87}
88
89
90const char* XMLNode::ParseText( char* p, const char* endTag, char** next )
91{
92 TIXMLASSERT( endTag && *endTag );
93
94 char* start = SkipWhiteSpace( p );
95 if ( !start )
Lee Thomasonce0763e2012-01-11 15:43:54 -080096 return 0;
Lee Thomason3f57d272012-01-11 15:30:03 -080097
98 char endChar = *endTag;
99 p = start;
100 int length = strlen( endTag );
101
102 while ( *p ) {
103 if ( *p == endChar ) {
104 if ( strncmp( p, endTag, length ) == 0 ) {
105 *p = 0;
106 *next = p + length;
107 return start;
108 }
109 }
110 ++p;
111 }
112 return 0;
113}
114
115
116// --------- XMLComment ---------- //
117
118XMLComment::XMLComment( XMLDocument* doc ) : XMLNode( doc )
119{
120}
121
122
Lee Thomasonce0763e2012-01-11 15:43:54 -0800123XMLComment::~XMLComment()
Lee Thomason3f57d272012-01-11 15:30:03 -0800124{
125
126}
127
128
Lee Thomasonce0763e2012-01-11 15:43:54 -0800129void XMLComment::Print( FILE* fp, int depth )
130{
131 XMLNode::Print( fp, depth );
132 fprintf( fp, "<!-- %s -->\n", value );
133}
134
135
136char* XMLComment::ParseDeep( char* p )
Lee Thomason3f57d272012-01-11 15:30:03 -0800137{
138 // Comment parses as text.
139 value = ParseText( p, "-->", &p );
U-Lama\Lee4cee6112011-12-31 14:58:18 -0800140 return p;
141}
142
143
Lee Thomason3f57d272012-01-11 15:30:03 -0800144// --------- XMLDocument ----------- //
U-Lama\Lee560bd472011-12-28 19:42:49 -0800145XMLDocument::XMLDocument() :
146 charBuffer( 0 )
147{
Lee Thomason85403d82012-01-11 15:55:05 -0800148 root = new XMLNode( this );
U-Lama\Lee560bd472011-12-28 19:42:49 -0800149}
U-Lama\Leee13c3e62011-12-28 14:36:55 -0800150
151
Lee Thomason3f57d272012-01-11 15:30:03 -0800152XMLDocument::~XMLDocument()
153{
154 delete root;
155 delete charBuffer;
156}
157
158
159
160bool XMLDocument::Parse( const char* p )
161{
Lee Thomasonce0763e2012-01-11 15:43:54 -0800162 charBuffer = CharBuffer::Construct( p );
Lee Thomason3f57d272012-01-11 15:30:03 -0800163 XMLNode* node = 0;
Lee Thomason85403d82012-01-11 15:55:05 -0800164
Lee Thomasonce0763e2012-01-11 15:43:54 -0800165 char* q = Identify( charBuffer->mem, &node );
Lee Thomason85403d82012-01-11 15:55:05 -0800166 root->InsertEndChild( node );
Lee Thomasonce0763e2012-01-11 15:43:54 -0800167 node->ParseDeep( q );
Lee Thomason85403d82012-01-11 15:55:05 -0800168
Lee Thomasonce0763e2012-01-11 15:43:54 -0800169 return true;
Lee Thomason3f57d272012-01-11 15:30:03 -0800170}
171
172
Lee Thomasonce0763e2012-01-11 15:43:54 -0800173void XMLDocument::Print( FILE* fp, int depth )
Lee Thomason3f57d272012-01-11 15:30:03 -0800174{
Lee Thomasonce0763e2012-01-11 15:43:54 -0800175 for( XMLNode* node = root->firstChild; node; node=node->next ) {
176 node->Print( fp, depth );
177 }
Lee Thomason3f57d272012-01-11 15:30:03 -0800178}
179
180
Lee Thomason3f57d272012-01-11 15:30:03 -0800181char* XMLDocument::Identify( char* p, XMLNode** node )
U-Lama\Leee13c3e62011-12-28 14:36:55 -0800182{
U-Lama\Lee4cee6112011-12-31 14:58:18 -0800183 XMLNode* returnNode = 0;
184
185 p = XMLNode::SkipWhiteSpace( p );
186 if( !p || !*p || *p != '<' )
187 {
188 return 0;
189 }
190
191 // What is this thing?
192 // - Elements start with a letter or underscore, but xml is reserved.
193 // - Comments: <!--
194 // - Decleration: <?xml
195 // - Everthing else is unknown to tinyxml.
196 //
197
Lee Thomason85403d82012-01-11 15:55:05 -0800198 static const char* xmlHeader = { "<?xml" };
199 static const char* commentHeader = { "<!--" };
200 static const char* dtdHeader = { "<!" };
201 static const char* cdataHeader = { "<![CDATA[" };
U-Lama\Lee4cee6112011-12-31 14:58:18 -0800202
Lee Thomason85403d82012-01-11 15:55:05 -0800203 static const int xmlHeaderLen = 5;
204 static const int commentHeaderLen = 4;
205 static const int dtdHeaderLen = 2;
206 static const int cdataHeaderLen = 9;
207
208 if ( XMLNode::StringEqual( p, commentHeader, commentHeaderLen ) ) {
Lee Thomasonce0763e2012-01-11 15:43:54 -0800209 returnNode = new XMLComment( this );
Lee Thomason85403d82012-01-11 15:55:05 -0800210 p += commentHeaderLen;
U-Lama\Lee4cee6112011-12-31 14:58:18 -0800211 }
212 else {
213 TIXMLASSERT( 0 );
214 }
U-Lama\Leee13c3e62011-12-28 14:36:55 -0800215
Lee Thomason3f57d272012-01-11 15:30:03 -0800216 *node = returnNode;
217 return p;
U-Lama\Leee13c3e62011-12-28 14:36:55 -0800218}