~fluidity-core/fluidity/embedded_models

« back to all changes in this revision

Viewing changes to libvtkfortran/tinyxml.cpp

  • Committer: Timothy Bond
  • Date: 2011-04-14 15:40:24 UTC
  • Revision ID: timothy.bond@imperial.ac.uk-20110414154024-116ci9gq6mwigmaw
Following the move from svn to bzr we change the nature of inclusion of these
four software libraries. Previously, they were included as svn externals and
pulled at latest version for trunk, pinned to specific versions for release
and stable trunk. Since bzr is less elegant at dealing with externals we have
made the decision to include the packages directly into the trunk instead.

At this import the versions are:

libadaptivity: r163
libvtkfortran: r67
libspud: r545
libmba2d: r28

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
/*
 
2
www.sourceforge.net/projects/tinyxml
 
3
Original code (2.0 and earlier )copyright (c) 2000-2006 Lee Thomason (www.grinninglizard.com)
 
4
 
 
5
This software is provided 'as-is', without any express or implied
 
6
warranty. In no event will the authors be held liable for any
 
7
damages arising from the use of this software.
 
8
 
 
9
Permission is granted to anyone to use this software for any
 
10
purpose, including commercial applications, and to alter it and
 
11
redistribute it freely, subject to the following restrictions:
 
12
 
 
13
1. The origin of this software must not be misrepresented; you must
 
14
not claim that you wrote the original software. If you use this
 
15
software in a product, an acknowledgment in the product documentation
 
16
would be appreciated but is not required.
 
17
 
 
18
2. Altered source versions must be plainly marked as such, and
 
19
must not be misrepresented as being the original software.
 
20
 
 
21
3. This notice may not be removed or altered from any source
 
22
distribution.
 
23
*/
 
24
 
 
25
#include <ctype.h>
 
26
 
 
27
#ifdef TIXML_USE_STL
 
28
#include <sstream>
 
29
#include <iostream>
 
30
#endif
 
31
 
 
32
#include "tinyxml.h"
 
33
 
 
34
 
 
35
bool TiXmlBase::condenseWhiteSpace = true;
 
36
 
 
37
// Microsoft compiler security
 
38
FILE* TiXmlFOpen( const char* filename, const char* mode )
 
39
{
 
40
        #if defined(_MSC_VER) && (_MSC_VER >= 1400 )
 
41
                FILE* fp = 0;
 
42
                errno_t err = fopen_s( &fp, filename, mode );
 
43
                if ( !err && fp )
 
44
                        return fp;
 
45
                return 0;
 
46
        #else
 
47
                return fopen( filename, mode );
 
48
        #endif
 
49
}
 
50
 
 
51
void TiXmlBase::EncodeString( const TIXML_STRING& str, TIXML_STRING* outString )
 
52
{
 
53
        int i=0;
 
54
 
 
55
        while( i<(int)str.length() )
 
56
        {
 
57
                unsigned char c = (unsigned char) str[i];
 
58
 
 
59
                if (    c == '&' 
 
60
                     && i < ( (int)str.length() - 2 )
 
61
                         && str[i+1] == '#'
 
62
                         && str[i+2] == 'x' )
 
63
                {
 
64
                        // Hexadecimal character reference.
 
65
                        // Pass through unchanged.
 
66
                        // &#xA9;       -- copyright symbol, for example.
 
67
                        //
 
68
                        // The -1 is a bug fix from Rob Laveaux. It keeps
 
69
                        // an overflow from happening if there is no ';'.
 
70
                        // There are actually 2 ways to exit this loop -
 
71
                        // while fails (error case) and break (semicolon found).
 
72
                        // However, there is no mechanism (currently) for
 
73
                        // this function to return an error.
 
74
                        while ( i<(int)str.length()-1 )
 
75
                        {
 
76
                                outString->append( str.c_str() + i, 1 );
 
77
                                ++i;
 
78
                                if ( str[i] == ';' )
 
79
                                        break;
 
80
                        }
 
81
                }
 
82
                else if ( c == '&' )
 
83
                {
 
84
                        outString->append( entity[0].str, entity[0].strLength );
 
85
                        ++i;
 
86
                }
 
87
                else if ( c == '<' )
 
88
                {
 
89
                        outString->append( entity[1].str, entity[1].strLength );
 
90
                        ++i;
 
91
                }
 
92
                else if ( c == '>' )
 
93
                {
 
94
                        outString->append( entity[2].str, entity[2].strLength );
 
95
                        ++i;
 
96
                }
 
97
                else if ( c == '\"' )
 
98
                {
 
99
                        outString->append( entity[3].str, entity[3].strLength );
 
100
                        ++i;
 
101
                }
 
102
                else if ( c == '\'' )
 
103
                {
 
104
                        outString->append( entity[4].str, entity[4].strLength );
 
105
                        ++i;
 
106
                }
 
107
                else if ( c < 32 )
 
108
                {
 
109
                        // Easy pass at non-alpha/numeric/symbol
 
110
                        // Below 32 is symbolic.
 
111
                        char buf[ 32 ];
 
112
                        
 
113
                        #if defined(TIXML_SNPRINTF)             
 
114
                                TIXML_SNPRINTF( buf, sizeof(buf), "&#x%02X;", (unsigned) ( c & 0xff ) );
 
115
                        #else
 
116
                                sprintf( buf, "&#x%02X;", (unsigned) ( c & 0xff ) );
 
117
                        #endif          
 
118
 
 
119
                        //*ME:  warning C4267: convert 'size_t' to 'int'
 
120
                        //*ME:  Int-Cast to make compiler happy ...
 
121
                        outString->append( buf, (int)strlen( buf ) );
 
122
                        ++i;
 
123
                }
 
124
                else
 
125
                {
 
126
                        //char realc = (char) c;
 
127
                        //outString->append( &realc, 1 );
 
128
                        *outString += (char) c; // somewhat more efficient function call.
 
129
                        ++i;
 
130
                }
 
131
        }
 
132
}
 
133
 
 
134
 
 
135
TiXmlNode::TiXmlNode( NodeType _type ) : TiXmlBase()
 
136
{
 
137
        parent = 0;
 
138
        type = _type;
 
139
        firstChild = 0;
 
140
        lastChild = 0;
 
141
        prev = 0;
 
142
        next = 0;
 
143
}
 
144
 
 
145
 
 
146
TiXmlNode::~TiXmlNode()
 
147
{
 
148
        TiXmlNode* node = firstChild;
 
149
        TiXmlNode* temp = 0;
 
150
 
 
151
        while ( node )
 
152
        {
 
153
                temp = node;
 
154
                node = node->next;
 
155
                delete temp;
 
156
        }       
 
157
}
 
158
 
 
159
 
 
160
void TiXmlNode::CopyTo( TiXmlNode* target ) const
 
161
{
 
162
        target->SetValue (value.c_str() );
 
163
        target->userData = userData; 
 
164
}
 
165
 
 
166
 
 
167
void TiXmlNode::Clear()
 
168
{
 
169
        TiXmlNode* node = firstChild;
 
170
        TiXmlNode* temp = 0;
 
171
 
 
172
        while ( node )
 
173
        {
 
174
                temp = node;
 
175
                node = node->next;
 
176
                delete temp;
 
177
        }       
 
178
 
 
179
        firstChild = 0;
 
180
        lastChild = 0;
 
181
}
 
182
 
 
183
 
 
184
TiXmlNode* TiXmlNode::LinkEndChild( TiXmlNode* node )
 
185
{
 
186
        assert( node->parent == 0 || node->parent == this );
 
187
        assert( node->GetDocument() == 0 || node->GetDocument() == this->GetDocument() );
 
188
 
 
189
        if ( node->Type() == TiXmlNode::DOCUMENT )
 
190
        {
 
191
                delete node;
 
192
                if ( GetDocument() ) GetDocument()->SetError( TIXML_ERROR_DOCUMENT_TOP_ONLY, 0, 0, TIXML_ENCODING_UNKNOWN );
 
193
                return 0;
 
194
        }
 
195
 
 
196
        node->parent = this;
 
197
 
 
198
        node->prev = lastChild;
 
199
        node->next = 0;
 
200
 
 
201
        if ( lastChild )
 
202
                lastChild->next = node;
 
203
        else
 
204
                firstChild = node;                      // it was an empty list.
 
205
 
 
206
        lastChild = node;
 
207
        return node;
 
208
}
 
209
 
 
210
 
 
211
TiXmlNode* TiXmlNode::InsertEndChild( const TiXmlNode& addThis )
 
212
{
 
213
        if ( addThis.Type() == TiXmlNode::DOCUMENT )
 
214
        {
 
215
                if ( GetDocument() ) GetDocument()->SetError( TIXML_ERROR_DOCUMENT_TOP_ONLY, 0, 0, TIXML_ENCODING_UNKNOWN );
 
216
                return 0;
 
217
        }
 
218
        TiXmlNode* node = addThis.Clone();
 
219
        if ( !node )
 
220
                return 0;
 
221
 
 
222
        return LinkEndChild( node );
 
223
}
 
224
 
 
225
 
 
226
TiXmlNode* TiXmlNode::InsertBeforeChild( TiXmlNode* beforeThis, const TiXmlNode& addThis )
 
227
{       
 
228
        if ( !beforeThis || beforeThis->parent != this ) {
 
229
                return 0;
 
230
        }
 
231
        if ( addThis.Type() == TiXmlNode::DOCUMENT )
 
232
        {
 
233
                if ( GetDocument() ) GetDocument()->SetError( TIXML_ERROR_DOCUMENT_TOP_ONLY, 0, 0, TIXML_ENCODING_UNKNOWN );
 
234
                return 0;
 
235
        }
 
236
 
 
237
        TiXmlNode* node = addThis.Clone();
 
238
        if ( !node )
 
239
                return 0;
 
240
        node->parent = this;
 
241
 
 
242
        node->next = beforeThis;
 
243
        node->prev = beforeThis->prev;
 
244
        if ( beforeThis->prev )
 
245
        {
 
246
                beforeThis->prev->next = node;
 
247
        }
 
248
        else
 
249
        {
 
250
                assert( firstChild == beforeThis );
 
251
                firstChild = node;
 
252
        }
 
253
        beforeThis->prev = node;
 
254
        return node;
 
255
}
 
256
 
 
257
 
 
258
TiXmlNode* TiXmlNode::InsertAfterChild( TiXmlNode* afterThis, const TiXmlNode& addThis )
 
259
{
 
260
        if ( !afterThis || afterThis->parent != this ) {
 
261
                return 0;
 
262
        }
 
263
        if ( addThis.Type() == TiXmlNode::DOCUMENT )
 
264
        {
 
265
                if ( GetDocument() ) GetDocument()->SetError( TIXML_ERROR_DOCUMENT_TOP_ONLY, 0, 0, TIXML_ENCODING_UNKNOWN );
 
266
                return 0;
 
267
        }
 
268
 
 
269
        TiXmlNode* node = addThis.Clone();
 
270
        if ( !node )
 
271
                return 0;
 
272
        node->parent = this;
 
273
 
 
274
        node->prev = afterThis;
 
275
        node->next = afterThis->next;
 
276
        if ( afterThis->next )
 
277
        {
 
278
                afterThis->next->prev = node;
 
279
        }
 
280
        else
 
281
        {
 
282
                assert( lastChild == afterThis );
 
283
                lastChild = node;
 
284
        }
 
285
        afterThis->next = node;
 
286
        return node;
 
287
}
 
288
 
 
289
 
 
290
TiXmlNode* TiXmlNode::ReplaceChild( TiXmlNode* replaceThis, const TiXmlNode& withThis )
 
291
{
 
292
        if ( replaceThis->parent != this )
 
293
                return 0;
 
294
 
 
295
        TiXmlNode* node = withThis.Clone();
 
296
        if ( !node )
 
297
                return 0;
 
298
 
 
299
        node->next = replaceThis->next;
 
300
        node->prev = replaceThis->prev;
 
301
 
 
302
        if ( replaceThis->next )
 
303
                replaceThis->next->prev = node;
 
304
        else
 
305
                lastChild = node;
 
306
 
 
307
        if ( replaceThis->prev )
 
308
                replaceThis->prev->next = node;
 
309
        else
 
310
                firstChild = node;
 
311
 
 
312
        delete replaceThis;
 
313
        node->parent = this;
 
314
        return node;
 
315
}
 
316
 
 
317
 
 
318
bool TiXmlNode::RemoveChild( TiXmlNode* removeThis )
 
319
{
 
320
        if ( removeThis->parent != this )
 
321
        {       
 
322
                assert( 0 );
 
323
                return false;
 
324
        }
 
325
 
 
326
        if ( removeThis->next )
 
327
                removeThis->next->prev = removeThis->prev;
 
328
        else
 
329
                lastChild = removeThis->prev;
 
330
 
 
331
        if ( removeThis->prev )
 
332
                removeThis->prev->next = removeThis->next;
 
333
        else
 
334
                firstChild = removeThis->next;
 
335
 
 
336
        delete removeThis;
 
337
        return true;
 
338
}
 
339
 
 
340
const TiXmlNode* TiXmlNode::FirstChild( const char * _value ) const
 
341
{
 
342
        const TiXmlNode* node;
 
343
        for ( node = firstChild; node; node = node->next )
 
344
        {
 
345
                if ( strcmp( node->Value(), _value ) == 0 )
 
346
                        return node;
 
347
        }
 
348
        return 0;
 
349
}
 
350
 
 
351
 
 
352
const TiXmlNode* TiXmlNode::LastChild( const char * _value ) const
 
353
{
 
354
        const TiXmlNode* node;
 
355
        for ( node = lastChild; node; node = node->prev )
 
356
        {
 
357
                if ( strcmp( node->Value(), _value ) == 0 )
 
358
                        return node;
 
359
        }
 
360
        return 0;
 
361
}
 
362
 
 
363
 
 
364
const TiXmlNode* TiXmlNode::IterateChildren( const TiXmlNode* previous ) const
 
365
{
 
366
        if ( !previous )
 
367
        {
 
368
                return FirstChild();
 
369
        }
 
370
        else
 
371
        {
 
372
                assert( previous->parent == this );
 
373
                return previous->NextSibling();
 
374
        }
 
375
}
 
376
 
 
377
 
 
378
const TiXmlNode* TiXmlNode::IterateChildren( const char * val, const TiXmlNode* previous ) const
 
379
{
 
380
        if ( !previous )
 
381
        {
 
382
                return FirstChild( val );
 
383
        }
 
384
        else
 
385
        {
 
386
                assert( previous->parent == this );
 
387
                return previous->NextSibling( val );
 
388
        }
 
389
}
 
390
 
 
391
 
 
392
const TiXmlNode* TiXmlNode::NextSibling( const char * _value ) const 
 
393
{
 
394
        const TiXmlNode* node;
 
395
        for ( node = next; node; node = node->next )
 
396
        {
 
397
                if ( strcmp( node->Value(), _value ) == 0 )
 
398
                        return node;
 
399
        }
 
400
        return 0;
 
401
}
 
402
 
 
403
 
 
404
const TiXmlNode* TiXmlNode::PreviousSibling( const char * _value ) const
 
405
{
 
406
        const TiXmlNode* node;
 
407
        for ( node = prev; node; node = node->prev )
 
408
        {
 
409
                if ( strcmp( node->Value(), _value ) == 0 )
 
410
                        return node;
 
411
        }
 
412
        return 0;
 
413
}
 
414
 
 
415
 
 
416
void TiXmlElement::RemoveAttribute( const char * name )
 
417
{
 
418
    #ifdef TIXML_USE_STL
 
419
        TIXML_STRING str( name );
 
420
        TiXmlAttribute* node = attributeSet.Find( str );
 
421
        #else
 
422
        TiXmlAttribute* node = attributeSet.Find( name );
 
423
        #endif
 
424
        if ( node )
 
425
        {
 
426
                attributeSet.Remove( node );
 
427
                delete node;
 
428
        }
 
429
}
 
430
 
 
431
const TiXmlElement* TiXmlNode::FirstChildElement() const
 
432
{
 
433
        const TiXmlNode* node;
 
434
 
 
435
        for (   node = FirstChild();
 
436
                        node;
 
437
                        node = node->NextSibling() )
 
438
        {
 
439
                if ( node->ToElement() )
 
440
                        return node->ToElement();
 
441
        }
 
442
        return 0;
 
443
}
 
444
 
 
445
 
 
446
const TiXmlElement* TiXmlNode::FirstChildElement( const char * _value ) const
 
447
{
 
448
        const TiXmlNode* node;
 
449
 
 
450
        for (   node = FirstChild( _value );
 
451
                        node;
 
452
                        node = node->NextSibling( _value ) )
 
453
        {
 
454
                if ( node->ToElement() )
 
455
                        return node->ToElement();
 
456
        }
 
457
        return 0;
 
458
}
 
459
 
 
460
 
 
461
const TiXmlElement* TiXmlNode::NextSiblingElement() const
 
462
{
 
463
        const TiXmlNode* node;
 
464
 
 
465
        for (   node = NextSibling();
 
466
                        node;
 
467
                        node = node->NextSibling() )
 
468
        {
 
469
                if ( node->ToElement() )
 
470
                        return node->ToElement();
 
471
        }
 
472
        return 0;
 
473
}
 
474
 
 
475
 
 
476
const TiXmlElement* TiXmlNode::NextSiblingElement( const char * _value ) const
 
477
{
 
478
        const TiXmlNode* node;
 
479
 
 
480
        for (   node = NextSibling( _value );
 
481
                        node;
 
482
                        node = node->NextSibling( _value ) )
 
483
        {
 
484
                if ( node->ToElement() )
 
485
                        return node->ToElement();
 
486
        }
 
487
        return 0;
 
488
}
 
489
 
 
490
 
 
491
const TiXmlDocument* TiXmlNode::GetDocument() const
 
492
{
 
493
        const TiXmlNode* node;
 
494
 
 
495
        for( node = this; node; node = node->parent )
 
496
        {
 
497
                if ( node->ToDocument() )
 
498
                        return node->ToDocument();
 
499
        }
 
500
        return 0;
 
501
}
 
502
 
 
503
 
 
504
TiXmlElement::TiXmlElement (const char * _value)
 
505
        : TiXmlNode( TiXmlNode::ELEMENT )
 
506
{
 
507
        firstChild = lastChild = 0;
 
508
        value = _value;
 
509
}
 
510
 
 
511
 
 
512
#ifdef TIXML_USE_STL
 
513
TiXmlElement::TiXmlElement( const std::string& _value ) 
 
514
        : TiXmlNode( TiXmlNode::ELEMENT )
 
515
{
 
516
        firstChild = lastChild = 0;
 
517
        value = _value;
 
518
}
 
519
#endif
 
520
 
 
521
 
 
522
TiXmlElement::TiXmlElement( const TiXmlElement& copy)
 
523
        : TiXmlNode( TiXmlNode::ELEMENT )
 
524
{
 
525
        firstChild = lastChild = 0;
 
526
        copy.CopyTo( this );    
 
527
}
 
528
 
 
529
 
 
530
void TiXmlElement::operator=( const TiXmlElement& base )
 
531
{
 
532
        ClearThis();
 
533
        base.CopyTo( this );
 
534
}
 
535
 
 
536
 
 
537
TiXmlElement::~TiXmlElement()
 
538
{
 
539
        ClearThis();
 
540
}
 
541
 
 
542
 
 
543
void TiXmlElement::ClearThis()
 
544
{
 
545
        Clear();
 
546
        while( attributeSet.First() )
 
547
        {
 
548
                TiXmlAttribute* node = attributeSet.First();
 
549
                attributeSet.Remove( node );
 
550
                delete node;
 
551
        }
 
552
}
 
553
 
 
554
 
 
555
const char* TiXmlElement::Attribute( const char* name ) const
 
556
{
 
557
        const TiXmlAttribute* node = attributeSet.Find( name );
 
558
        if ( node )
 
559
                return node->Value();
 
560
        return 0;
 
561
}
 
562
 
 
563
 
 
564
#ifdef TIXML_USE_STL
 
565
const std::string* TiXmlElement::Attribute( const std::string& name ) const
 
566
{
 
567
        const TiXmlAttribute* node = attributeSet.Find( name );
 
568
        if ( node )
 
569
                return &node->ValueStr();
 
570
        return 0;
 
571
}
 
572
#endif
 
573
 
 
574
 
 
575
const char* TiXmlElement::Attribute( const char* name, int* i ) const
 
576
{
 
577
        const char* s = Attribute( name );
 
578
        if ( i )
 
579
        {
 
580
                if ( s ) {
 
581
                        *i = atoi( s );
 
582
                }
 
583
                else {
 
584
                        *i = 0;
 
585
                }
 
586
        }
 
587
        return s;
 
588
}
 
589
 
 
590
 
 
591
#ifdef TIXML_USE_STL
 
592
const std::string* TiXmlElement::Attribute( const std::string& name, int* i ) const
 
593
{
 
594
        const std::string* s = Attribute( name );
 
595
        if ( i )
 
596
        {
 
597
                if ( s ) {
 
598
                        *i = atoi( s->c_str() );
 
599
                }
 
600
                else {
 
601
                        *i = 0;
 
602
                }
 
603
        }
 
604
        return s;
 
605
}
 
606
#endif
 
607
 
 
608
 
 
609
const char* TiXmlElement::Attribute( const char* name, double* d ) const
 
610
{
 
611
        const char* s = Attribute( name );
 
612
        if ( d )
 
613
        {
 
614
                if ( s ) {
 
615
                        *d = atof( s );
 
616
                }
 
617
                else {
 
618
                        *d = 0;
 
619
                }
 
620
        }
 
621
        return s;
 
622
}
 
623
 
 
624
 
 
625
#ifdef TIXML_USE_STL
 
626
const std::string* TiXmlElement::Attribute( const std::string& name, double* d ) const
 
627
{
 
628
        const std::string* s = Attribute( name );
 
629
        if ( d )
 
630
        {
 
631
                if ( s ) {
 
632
                        *d = atof( s->c_str() );
 
633
                }
 
634
                else {
 
635
                        *d = 0;
 
636
                }
 
637
        }
 
638
        return s;
 
639
}
 
640
#endif
 
641
 
 
642
 
 
643
int TiXmlElement::QueryIntAttribute( const char* name, int* ival ) const
 
644
{
 
645
        const TiXmlAttribute* node = attributeSet.Find( name );
 
646
        if ( !node )
 
647
                return TIXML_NO_ATTRIBUTE;
 
648
        return node->QueryIntValue( ival );
 
649
}
 
650
 
 
651
 
 
652
#ifdef TIXML_USE_STL
 
653
int TiXmlElement::QueryIntAttribute( const std::string& name, int* ival ) const
 
654
{
 
655
        const TiXmlAttribute* node = attributeSet.Find( name );
 
656
        if ( !node )
 
657
                return TIXML_NO_ATTRIBUTE;
 
658
        return node->QueryIntValue( ival );
 
659
}
 
660
#endif
 
661
 
 
662
 
 
663
int TiXmlElement::QueryDoubleAttribute( const char* name, double* dval ) const
 
664
{
 
665
        const TiXmlAttribute* node = attributeSet.Find( name );
 
666
        if ( !node )
 
667
                return TIXML_NO_ATTRIBUTE;
 
668
        return node->QueryDoubleValue( dval );
 
669
}
 
670
 
 
671
 
 
672
#ifdef TIXML_USE_STL
 
673
int TiXmlElement::QueryDoubleAttribute( const std::string& name, double* dval ) const
 
674
{
 
675
        const TiXmlAttribute* node = attributeSet.Find( name );
 
676
        if ( !node )
 
677
                return TIXML_NO_ATTRIBUTE;
 
678
        return node->QueryDoubleValue( dval );
 
679
}
 
680
#endif
 
681
 
 
682
 
 
683
void TiXmlElement::SetAttribute( const char * name, int val )
 
684
{       
 
685
        char buf[64];
 
686
        #if defined(TIXML_SNPRINTF)             
 
687
                TIXML_SNPRINTF( buf, sizeof(buf), "%d", val );
 
688
        #else
 
689
                sprintf( buf, "%d", val );
 
690
        #endif
 
691
        SetAttribute( name, buf );
 
692
}
 
693
 
 
694
 
 
695
#ifdef TIXML_USE_STL
 
696
void TiXmlElement::SetAttribute( const std::string& name, int val )
 
697
{       
 
698
   std::ostringstream oss;
 
699
   oss << val;
 
700
   SetAttribute( name, oss.str() );
 
701
}
 
702
#endif
 
703
 
 
704
 
 
705
void TiXmlElement::SetDoubleAttribute( const char * name, double val )
 
706
{       
 
707
        char buf[256];
 
708
        #if defined(TIXML_SNPRINTF)             
 
709
                TIXML_SNPRINTF( buf, sizeof(buf), "%f", val );
 
710
        #else
 
711
                sprintf( buf, "%f", val );
 
712
        #endif
 
713
        SetAttribute( name, buf );
 
714
}
 
715
 
 
716
 
 
717
void TiXmlElement::SetAttribute( const char * cname, const char * cvalue )
 
718
{
 
719
    #ifdef TIXML_USE_STL
 
720
        TIXML_STRING _name( cname );
 
721
        TIXML_STRING _value( cvalue );
 
722
        #else
 
723
        const char* _name = cname;
 
724
        const char* _value = cvalue;
 
725
        #endif
 
726
 
 
727
        TiXmlAttribute* node = attributeSet.Find( _name );
 
728
        if ( node )
 
729
        {
 
730
                node->SetValue( _value );
 
731
                return;
 
732
        }
 
733
 
 
734
        TiXmlAttribute* attrib = new TiXmlAttribute( cname, cvalue );
 
735
        if ( attrib )
 
736
        {
 
737
                attributeSet.Add( attrib );
 
738
        }
 
739
        else
 
740
        {
 
741
                TiXmlDocument* document = GetDocument();
 
742
                if ( document ) document->SetError( TIXML_ERROR_OUT_OF_MEMORY, 0, 0, TIXML_ENCODING_UNKNOWN );
 
743
        }
 
744
}
 
745
 
 
746
 
 
747
#ifdef TIXML_USE_STL
 
748
void TiXmlElement::SetAttribute( const std::string& name, const std::string& _value )
 
749
{
 
750
        TiXmlAttribute* node = attributeSet.Find( name );
 
751
        if ( node )
 
752
        {
 
753
                node->SetValue( _value );
 
754
                return;
 
755
        }
 
756
 
 
757
        TiXmlAttribute* attrib = new TiXmlAttribute( name, _value );
 
758
        if ( attrib )
 
759
        {
 
760
                attributeSet.Add( attrib );
 
761
        }
 
762
        else
 
763
        {
 
764
                TiXmlDocument* document = GetDocument();
 
765
                if ( document ) document->SetError( TIXML_ERROR_OUT_OF_MEMORY, 0, 0, TIXML_ENCODING_UNKNOWN );
 
766
        }
 
767
}
 
768
#endif
 
769
 
 
770
 
 
771
void TiXmlElement::Print( FILE* cfile, int depth ) const
 
772
{
 
773
        int i;
 
774
        assert( cfile );
 
775
        for ( i=0; i<depth; i++ ) {
 
776
                fprintf( cfile, "    " );
 
777
        }
 
778
 
 
779
        fprintf( cfile, "<%s", value.c_str() );
 
780
 
 
781
        const TiXmlAttribute* attrib;
 
782
        for ( attrib = attributeSet.First(); attrib; attrib = attrib->Next() )
 
783
        {
 
784
                fprintf( cfile, " " );
 
785
                attrib->Print( cfile, depth );
 
786
        }
 
787
 
 
788
        // There are 3 different formatting approaches:
 
789
        // 1) An element without children is printed as a <foo /> node
 
790
        // 2) An element with only a text child is printed as <foo> text </foo>
 
791
        // 3) An element with children is printed on multiple lines.
 
792
        TiXmlNode* node;
 
793
        if ( !firstChild )
 
794
        {
 
795
                fprintf( cfile, " />" );
 
796
        }
 
797
        else if ( firstChild == lastChild && firstChild->ToText() )
 
798
        {
 
799
                fprintf( cfile, ">" );
 
800
                firstChild->Print( cfile, depth + 1 );
 
801
                fprintf( cfile, "</%s>", value.c_str() );
 
802
        }
 
803
        else
 
804
        {
 
805
                fprintf( cfile, ">" );
 
806
 
 
807
                for ( node = firstChild; node; node=node->NextSibling() )
 
808
                {
 
809
                        if ( !node->ToText() )
 
810
                        {
 
811
                                fprintf( cfile, "\n" );
 
812
                        }
 
813
                        node->Print( cfile, depth+1 );
 
814
                }
 
815
                fprintf( cfile, "\n" );
 
816
                for( i=0; i<depth; ++i ) {
 
817
                        fprintf( cfile, "    " );
 
818
                }
 
819
                fprintf( cfile, "</%s>", value.c_str() );
 
820
        }
 
821
}
 
822
 
 
823
 
 
824
void TiXmlElement::CopyTo( TiXmlElement* target ) const
 
825
{
 
826
        // superclass:
 
827
        TiXmlNode::CopyTo( target );
 
828
 
 
829
        // Element class: 
 
830
        // Clone the attributes, then clone the children.
 
831
        const TiXmlAttribute* attribute = 0;
 
832
        for(    attribute = attributeSet.First();
 
833
        attribute;
 
834
        attribute = attribute->Next() )
 
835
        {
 
836
                target->SetAttribute( attribute->Name(), attribute->Value() );
 
837
        }
 
838
 
 
839
        TiXmlNode* node = 0;
 
840
        for ( node = firstChild; node; node = node->NextSibling() )
 
841
        {
 
842
                target->LinkEndChild( node->Clone() );
 
843
        }
 
844
}
 
845
 
 
846
bool TiXmlElement::Accept( TiXmlVisitor* visitor ) const
 
847
{
 
848
        if ( visitor->VisitEnter( *this, attributeSet.First() ) ) 
 
849
        {
 
850
                for ( const TiXmlNode* node=FirstChild(); node; node=node->NextSibling() )
 
851
                {
 
852
                        if ( !node->Accept( visitor ) )
 
853
                                break;
 
854
                }
 
855
        }
 
856
        return visitor->VisitExit( *this );
 
857
}
 
858
 
 
859
 
 
860
TiXmlNode* TiXmlElement::Clone() const
 
861
{
 
862
        TiXmlElement* clone = new TiXmlElement( Value() );
 
863
        if ( !clone )
 
864
                return 0;
 
865
 
 
866
        CopyTo( clone );
 
867
        return clone;
 
868
}
 
869
 
 
870
 
 
871
const char* TiXmlElement::GetText() const
 
872
{
 
873
        const TiXmlNode* child = this->FirstChild();
 
874
        if ( child ) {
 
875
                const TiXmlText* childText = child->ToText();
 
876
                if ( childText ) {
 
877
                        return childText->Value();
 
878
                }
 
879
        }
 
880
        return 0;
 
881
}
 
882
 
 
883
 
 
884
TiXmlDocument::TiXmlDocument() : TiXmlNode( TiXmlNode::DOCUMENT )
 
885
{
 
886
        tabsize = 4;
 
887
        useMicrosoftBOM = false;
 
888
        ClearError();
 
889
}
 
890
 
 
891
TiXmlDocument::TiXmlDocument( const char * documentName ) : TiXmlNode( TiXmlNode::DOCUMENT )
 
892
{
 
893
        tabsize = 4;
 
894
        useMicrosoftBOM = false;
 
895
        value = documentName;
 
896
        ClearError();
 
897
}
 
898
 
 
899
 
 
900
#ifdef TIXML_USE_STL
 
901
TiXmlDocument::TiXmlDocument( const std::string& documentName ) : TiXmlNode( TiXmlNode::DOCUMENT )
 
902
{
 
903
        tabsize = 4;
 
904
        useMicrosoftBOM = false;
 
905
    value = documentName;
 
906
        ClearError();
 
907
}
 
908
#endif
 
909
 
 
910
 
 
911
TiXmlDocument::TiXmlDocument( const TiXmlDocument& copy ) : TiXmlNode( TiXmlNode::DOCUMENT )
 
912
{
 
913
        copy.CopyTo( this );
 
914
}
 
915
 
 
916
 
 
917
void TiXmlDocument::operator=( const TiXmlDocument& copy )
 
918
{
 
919
        Clear();
 
920
        copy.CopyTo( this );
 
921
}
 
922
 
 
923
 
 
924
bool TiXmlDocument::LoadFile( TiXmlEncoding encoding )
 
925
{
 
926
        // See STL_STRING_BUG below.
 
927
        //StringToBuffer buf( value );
 
928
 
 
929
        return LoadFile( Value(), encoding );
 
930
}
 
931
 
 
932
 
 
933
bool TiXmlDocument::SaveFile() const
 
934
{
 
935
        // See STL_STRING_BUG below.
 
936
//      StringToBuffer buf( value );
 
937
//
 
938
//      if ( buf.buffer && SaveFile( buf.buffer ) )
 
939
//              return true;
 
940
//
 
941
//      return false;
 
942
        return SaveFile( Value() );
 
943
}
 
944
 
 
945
bool TiXmlDocument::LoadFile( const char* _filename, TiXmlEncoding encoding )
 
946
{
 
947
        // There was a really terrifying little bug here. The code:
 
948
        //              value = filename
 
949
        // in the STL case, cause the assignment method of the std::string to
 
950
        // be called. What is strange, is that the std::string had the same
 
951
        // address as it's c_str() method, and so bad things happen. Looks
 
952
        // like a bug in the Microsoft STL implementation.
 
953
        // Add an extra string to avoid the crash.
 
954
        TIXML_STRING filename( _filename );
 
955
        value = filename;
 
956
 
 
957
        // reading in binary mode so that tinyxml can normalize the EOL
 
958
        FILE* file = TiXmlFOpen( value.c_str (), "rb" );        
 
959
 
 
960
        if ( file )
 
961
        {
 
962
                bool result = LoadFile( file, encoding );
 
963
                fclose( file );
 
964
                return result;
 
965
        }
 
966
        else
 
967
        {
 
968
                SetError( TIXML_ERROR_OPENING_FILE, 0, 0, TIXML_ENCODING_UNKNOWN );
 
969
                return false;
 
970
        }
 
971
}
 
972
 
 
973
bool TiXmlDocument::LoadFile( FILE* file, TiXmlEncoding encoding )
 
974
{
 
975
        if ( !file ) 
 
976
        {
 
977
                SetError( TIXML_ERROR_OPENING_FILE, 0, 0, TIXML_ENCODING_UNKNOWN );
 
978
                return false;
 
979
        }
 
980
 
 
981
        // Delete the existing data:
 
982
        Clear();
 
983
        location.Clear();
 
984
 
 
985
        // Get the file size, so we can pre-allocate the string. HUGE speed impact.
 
986
        long length = 0;
 
987
        fseek( file, 0, SEEK_END );
 
988
        length = ftell( file );
 
989
        fseek( file, 0, SEEK_SET );
 
990
 
 
991
        // Strange case, but good to handle up front.
 
992
        if ( length <= 0 )
 
993
        {
 
994
                SetError( TIXML_ERROR_DOCUMENT_EMPTY, 0, 0, TIXML_ENCODING_UNKNOWN );
 
995
                return false;
 
996
        }
 
997
 
 
998
        // If we have a file, assume it is all one big XML file, and read it in.
 
999
        // The document parser may decide the document ends sooner than the entire file, however.
 
1000
        TIXML_STRING data;
 
1001
        data.reserve( length );
 
1002
 
 
1003
        // Subtle bug here. TinyXml did use fgets. But from the XML spec:
 
1004
        // 2.11 End-of-Line Handling
 
1005
        // <snip>
 
1006
        // <quote>
 
1007
        // ...the XML processor MUST behave as if it normalized all line breaks in external 
 
1008
        // parsed entities (including the document entity) on input, before parsing, by translating 
 
1009
        // both the two-character sequence #xD #xA and any #xD that is not followed by #xA to 
 
1010
        // a single #xA character.
 
1011
        // </quote>
 
1012
        //
 
1013
        // It is not clear fgets does that, and certainly isn't clear it works cross platform. 
 
1014
        // Generally, you expect fgets to translate from the convention of the OS to the c/unix
 
1015
        // convention, and not work generally.
 
1016
 
 
1017
        /*
 
1018
        while( fgets( buf, sizeof(buf), file ) )
 
1019
        {
 
1020
                data += buf;
 
1021
        }
 
1022
        */
 
1023
 
 
1024
        char* buf = new char[ length+1 ];
 
1025
        buf[0] = 0;
 
1026
 
 
1027
        if ( fread( buf, length, 1, file ) != 1 ) {
 
1028
                delete [] buf;
 
1029
                SetError( TIXML_ERROR_OPENING_FILE, 0, 0, TIXML_ENCODING_UNKNOWN );
 
1030
                return false;
 
1031
        }
 
1032
 
 
1033
        const char* lastPos = buf;
 
1034
        const char* p = buf;
 
1035
 
 
1036
        buf[length] = 0;
 
1037
        while( *p ) {
 
1038
                assert( p < (buf+length) );
 
1039
                if ( *p == 0xa ) {
 
1040
                        // Newline character. No special rules for this. Append all the characters
 
1041
                        // since the last string, and include the newline.
 
1042
                        data.append( lastPos, (p-lastPos+1) );  // append, include the newline
 
1043
                        ++p;                                                                    // move past the newline
 
1044
                        lastPos = p;                                                    // and point to the new buffer (may be 0)
 
1045
                        assert( p <= (buf+length) );
 
1046
                }
 
1047
                else if ( *p == 0xd ) {
 
1048
                        // Carriage return. Append what we have so far, then
 
1049
                        // handle moving forward in the buffer.
 
1050
                        if ( (p-lastPos) > 0 ) {
 
1051
                                data.append( lastPos, p-lastPos );      // do not add the CR
 
1052
                        }
 
1053
                        data += (char)0xa;                                              // a proper newline
 
1054
 
 
1055
                        if ( *(p+1) == 0xa ) {
 
1056
                                // Carriage return - new line sequence
 
1057
                                p += 2;
 
1058
                                lastPos = p;
 
1059
                                assert( p <= (buf+length) );
 
1060
                        }
 
1061
                        else {
 
1062
                                // it was followed by something else...that is presumably characters again.
 
1063
                                ++p;
 
1064
                                lastPos = p;
 
1065
                                assert( p <= (buf+length) );
 
1066
                        }
 
1067
                }
 
1068
                else {
 
1069
                        ++p;
 
1070
                }
 
1071
        }
 
1072
        // Handle any left over characters.
 
1073
        if ( p-lastPos ) {
 
1074
                data.append( lastPos, p-lastPos );
 
1075
        }               
 
1076
        delete [] buf;
 
1077
        buf = 0;
 
1078
 
 
1079
        Parse( data.c_str(), 0, encoding );
 
1080
 
 
1081
        if (  Error() )
 
1082
        return false;
 
1083
    else
 
1084
                return true;
 
1085
}
 
1086
 
 
1087
 
 
1088
bool TiXmlDocument::SaveFile( const char * filename ) const
 
1089
{
 
1090
        // The old c stuff lives on...
 
1091
        FILE* fp = TiXmlFOpen( filename, "w" );
 
1092
        if ( fp )
 
1093
        {
 
1094
                bool result = SaveFile( fp );
 
1095
                fclose( fp );
 
1096
                return result;
 
1097
        }
 
1098
        return false;
 
1099
}
 
1100
 
 
1101
 
 
1102
bool TiXmlDocument::SaveFile( FILE* fp ) const
 
1103
{
 
1104
        if ( useMicrosoftBOM ) 
 
1105
        {
 
1106
                const unsigned char TIXML_UTF_LEAD_0 = 0xefU;
 
1107
                const unsigned char TIXML_UTF_LEAD_1 = 0xbbU;
 
1108
                const unsigned char TIXML_UTF_LEAD_2 = 0xbfU;
 
1109
 
 
1110
                fputc( TIXML_UTF_LEAD_0, fp );
 
1111
                fputc( TIXML_UTF_LEAD_1, fp );
 
1112
                fputc( TIXML_UTF_LEAD_2, fp );
 
1113
        }
 
1114
        Print( fp, 0 );
 
1115
        return (ferror(fp) == 0);
 
1116
}
 
1117
 
 
1118
 
 
1119
void TiXmlDocument::CopyTo( TiXmlDocument* target ) const
 
1120
{
 
1121
        TiXmlNode::CopyTo( target );
 
1122
 
 
1123
        target->error = error;
 
1124
        target->errorId = errorId;
 
1125
        target->errorDesc = errorDesc;
 
1126
        target->tabsize = tabsize;
 
1127
        target->errorLocation = errorLocation;
 
1128
        target->useMicrosoftBOM = useMicrosoftBOM;
 
1129
 
 
1130
        TiXmlNode* node = 0;
 
1131
        for ( node = firstChild; node; node = node->NextSibling() )
 
1132
        {
 
1133
                target->LinkEndChild( node->Clone() );
 
1134
        }       
 
1135
}
 
1136
 
 
1137
 
 
1138
TiXmlNode* TiXmlDocument::Clone() const
 
1139
{
 
1140
        TiXmlDocument* clone = new TiXmlDocument();
 
1141
        if ( !clone )
 
1142
                return 0;
 
1143
 
 
1144
        CopyTo( clone );
 
1145
        return clone;
 
1146
}
 
1147
 
 
1148
 
 
1149
void TiXmlDocument::Print( FILE* cfile, int depth ) const
 
1150
{
 
1151
        assert( cfile );
 
1152
        for ( const TiXmlNode* node=FirstChild(); node; node=node->NextSibling() )
 
1153
        {
 
1154
                node->Print( cfile, depth );
 
1155
                fprintf( cfile, "\n" );
 
1156
        }
 
1157
}
 
1158
 
 
1159
 
 
1160
bool TiXmlDocument::Accept( TiXmlVisitor* visitor ) const
 
1161
{
 
1162
        if ( visitor->VisitEnter( *this ) )
 
1163
        {
 
1164
                for ( const TiXmlNode* node=FirstChild(); node; node=node->NextSibling() )
 
1165
                {
 
1166
                        if ( !node->Accept( visitor ) )
 
1167
                                break;
 
1168
                }
 
1169
        }
 
1170
        return visitor->VisitExit( *this );
 
1171
}
 
1172
 
 
1173
 
 
1174
const TiXmlAttribute* TiXmlAttribute::Next() const
 
1175
{
 
1176
        // We are using knowledge of the sentinel. The sentinel
 
1177
        // have a value or name.
 
1178
        if ( next->value.empty() && next->name.empty() )
 
1179
                return 0;
 
1180
        return next;
 
1181
}
 
1182
 
 
1183
/*
 
1184
TiXmlAttribute* TiXmlAttribute::Next()
 
1185
{
 
1186
        // We are using knowledge of the sentinel. The sentinel
 
1187
        // have a value or name.
 
1188
        if ( next->value.empty() && next->name.empty() )
 
1189
                return 0;
 
1190
        return next;
 
1191
}
 
1192
*/
 
1193
 
 
1194
const TiXmlAttribute* TiXmlAttribute::Previous() const
 
1195
{
 
1196
        // We are using knowledge of the sentinel. The sentinel
 
1197
        // have a value or name.
 
1198
        if ( prev->value.empty() && prev->name.empty() )
 
1199
                return 0;
 
1200
        return prev;
 
1201
}
 
1202
 
 
1203
/*
 
1204
TiXmlAttribute* TiXmlAttribute::Previous()
 
1205
{
 
1206
        // We are using knowledge of the sentinel. The sentinel
 
1207
        // have a value or name.
 
1208
        if ( prev->value.empty() && prev->name.empty() )
 
1209
                return 0;
 
1210
        return prev;
 
1211
}
 
1212
*/
 
1213
 
 
1214
void TiXmlAttribute::Print( FILE* cfile, int /*depth*/, TIXML_STRING* str ) const
 
1215
{
 
1216
        TIXML_STRING n, v;
 
1217
 
 
1218
        EncodeString( name, &n );
 
1219
        EncodeString( value, &v );
 
1220
 
 
1221
        if (value.find ('\"') == TIXML_STRING::npos) {
 
1222
                if ( cfile ) {
 
1223
                fprintf (cfile, "%s=\"%s\"", n.c_str(), v.c_str() );
 
1224
                }
 
1225
                if ( str ) {
 
1226
                        (*str) += n; (*str) += "=\""; (*str) += v; (*str) += "\"";
 
1227
                }
 
1228
        }
 
1229
        else {
 
1230
                if ( cfile ) {
 
1231
                fprintf (cfile, "%s='%s'", n.c_str(), v.c_str() );
 
1232
                }
 
1233
                if ( str ) {
 
1234
                        (*str) += n; (*str) += "='"; (*str) += v; (*str) += "'";
 
1235
                }
 
1236
        }
 
1237
}
 
1238
 
 
1239
 
 
1240
int TiXmlAttribute::QueryIntValue( int* ival ) const
 
1241
{
 
1242
        if ( TIXML_SSCANF( value.c_str(), "%d", ival ) == 1 )
 
1243
                return TIXML_SUCCESS;
 
1244
        return TIXML_WRONG_TYPE;
 
1245
}
 
1246
 
 
1247
int TiXmlAttribute::QueryDoubleValue( double* dval ) const
 
1248
{
 
1249
        if ( TIXML_SSCANF( value.c_str(), "%lf", dval ) == 1 )
 
1250
                return TIXML_SUCCESS;
 
1251
        return TIXML_WRONG_TYPE;
 
1252
}
 
1253
 
 
1254
void TiXmlAttribute::SetIntValue( int _value )
 
1255
{
 
1256
        char buf [64];
 
1257
        #if defined(TIXML_SNPRINTF)             
 
1258
                TIXML_SNPRINTF(buf, sizeof(buf), "%d", _value);
 
1259
        #else
 
1260
                sprintf (buf, "%d", _value);
 
1261
        #endif
 
1262
        SetValue (buf);
 
1263
}
 
1264
 
 
1265
void TiXmlAttribute::SetDoubleValue( double _value )
 
1266
{
 
1267
        char buf [256];
 
1268
        #if defined(TIXML_SNPRINTF)             
 
1269
                TIXML_SNPRINTF( buf, sizeof(buf), "%lf", _value);
 
1270
        #else
 
1271
                sprintf (buf, "%lf", _value);
 
1272
        #endif
 
1273
        SetValue (buf);
 
1274
}
 
1275
 
 
1276
int TiXmlAttribute::IntValue() const
 
1277
{
 
1278
        return atoi (value.c_str ());
 
1279
}
 
1280
 
 
1281
double  TiXmlAttribute::DoubleValue() const
 
1282
{
 
1283
        return atof (value.c_str ());
 
1284
}
 
1285
 
 
1286
 
 
1287
TiXmlComment::TiXmlComment( const TiXmlComment& copy ) : TiXmlNode( TiXmlNode::COMMENT )
 
1288
{
 
1289
        copy.CopyTo( this );
 
1290
}
 
1291
 
 
1292
 
 
1293
void TiXmlComment::operator=( const TiXmlComment& base )
 
1294
{
 
1295
        Clear();
 
1296
        base.CopyTo( this );
 
1297
}
 
1298
 
 
1299
 
 
1300
void TiXmlComment::Print( FILE* cfile, int depth ) const
 
1301
{
 
1302
        assert( cfile );
 
1303
        for ( int i=0; i<depth; i++ )
 
1304
        {
 
1305
                fprintf( cfile,  "    " );
 
1306
        }
 
1307
        fprintf( cfile, "<!--%s-->", value.c_str() );
 
1308
}
 
1309
 
 
1310
 
 
1311
void TiXmlComment::CopyTo( TiXmlComment* target ) const
 
1312
{
 
1313
        TiXmlNode::CopyTo( target );
 
1314
}
 
1315
 
 
1316
 
 
1317
bool TiXmlComment::Accept( TiXmlVisitor* visitor ) const
 
1318
{
 
1319
        return visitor->Visit( *this );
 
1320
}
 
1321
 
 
1322
 
 
1323
TiXmlNode* TiXmlComment::Clone() const
 
1324
{
 
1325
        TiXmlComment* clone = new TiXmlComment();
 
1326
 
 
1327
        if ( !clone )
 
1328
                return 0;
 
1329
 
 
1330
        CopyTo( clone );
 
1331
        return clone;
 
1332
}
 
1333
 
 
1334
 
 
1335
void TiXmlText::Print( FILE* cfile, int depth ) const
 
1336
{
 
1337
        assert( cfile );
 
1338
        if ( cdata )
 
1339
        {
 
1340
                int i;
 
1341
                fprintf( cfile, "\n" );
 
1342
                for ( i=0; i<depth; i++ ) {
 
1343
                        fprintf( cfile, "    " );
 
1344
                }
 
1345
                fprintf( cfile, "<![CDATA[%s]]>\n", value.c_str() );    // unformatted output
 
1346
        }
 
1347
        else
 
1348
        {
 
1349
                TIXML_STRING buffer;
 
1350
                EncodeString( value, &buffer );
 
1351
                fprintf( cfile, "%s", buffer.c_str() );
 
1352
        }
 
1353
}
 
1354
 
 
1355
 
 
1356
void TiXmlText::CopyTo( TiXmlText* target ) const
 
1357
{
 
1358
        TiXmlNode::CopyTo( target );
 
1359
        target->cdata = cdata;
 
1360
}
 
1361
 
 
1362
 
 
1363
bool TiXmlText::Accept( TiXmlVisitor* visitor ) const
 
1364
{
 
1365
        return visitor->Visit( *this );
 
1366
}
 
1367
 
 
1368
 
 
1369
TiXmlNode* TiXmlText::Clone() const
 
1370
{       
 
1371
        TiXmlText* clone = 0;
 
1372
        clone = new TiXmlText( "" );
 
1373
 
 
1374
        if ( !clone )
 
1375
                return 0;
 
1376
 
 
1377
        CopyTo( clone );
 
1378
        return clone;
 
1379
}
 
1380
 
 
1381
 
 
1382
TiXmlDeclaration::TiXmlDeclaration( const char * _version,
 
1383
                                                                        const char * _encoding,
 
1384
                                                                        const char * _standalone )
 
1385
        : TiXmlNode( TiXmlNode::DECLARATION )
 
1386
{
 
1387
        version = _version;
 
1388
        encoding = _encoding;
 
1389
        standalone = _standalone;
 
1390
}
 
1391
 
 
1392
 
 
1393
#ifdef TIXML_USE_STL
 
1394
TiXmlDeclaration::TiXmlDeclaration(     const std::string& _version,
 
1395
                                                                        const std::string& _encoding,
 
1396
                                                                        const std::string& _standalone )
 
1397
        : TiXmlNode( TiXmlNode::DECLARATION )
 
1398
{
 
1399
        version = _version;
 
1400
        encoding = _encoding;
 
1401
        standalone = _standalone;
 
1402
}
 
1403
#endif
 
1404
 
 
1405
 
 
1406
TiXmlDeclaration::TiXmlDeclaration( const TiXmlDeclaration& copy )
 
1407
        : TiXmlNode( TiXmlNode::DECLARATION )
 
1408
{
 
1409
        copy.CopyTo( this );    
 
1410
}
 
1411
 
 
1412
 
 
1413
void TiXmlDeclaration::operator=( const TiXmlDeclaration& copy )
 
1414
{
 
1415
        Clear();
 
1416
        copy.CopyTo( this );
 
1417
}
 
1418
 
 
1419
 
 
1420
void TiXmlDeclaration::Print( FILE* cfile, int /*depth*/, TIXML_STRING* str ) const
 
1421
{
 
1422
        if ( cfile ) fprintf( cfile, "<?xml " );
 
1423
        if ( str )       (*str) += "<?xml ";
 
1424
 
 
1425
        if ( !version.empty() ) {
 
1426
                if ( cfile ) fprintf (cfile, "version=\"%s\" ", version.c_str ());
 
1427
                if ( str ) { (*str) += "version=\""; (*str) += version; (*str) += "\" "; }
 
1428
        }
 
1429
        if ( !encoding.empty() ) {
 
1430
                if ( cfile ) fprintf (cfile, "encoding=\"%s\" ", encoding.c_str ());
 
1431
                if ( str ) { (*str) += "encoding=\""; (*str) += encoding; (*str) += "\" "; }
 
1432
        }
 
1433
        if ( !standalone.empty() ) {
 
1434
                if ( cfile ) fprintf (cfile, "standalone=\"%s\" ", standalone.c_str ());
 
1435
                if ( str ) { (*str) += "standalone=\""; (*str) += standalone; (*str) += "\" "; }
 
1436
        }
 
1437
        if ( cfile ) fprintf( cfile, "?>" );
 
1438
        if ( str )       (*str) += "?>";
 
1439
}
 
1440
 
 
1441
 
 
1442
void TiXmlDeclaration::CopyTo( TiXmlDeclaration* target ) const
 
1443
{
 
1444
        TiXmlNode::CopyTo( target );
 
1445
 
 
1446
        target->version = version;
 
1447
        target->encoding = encoding;
 
1448
        target->standalone = standalone;
 
1449
}
 
1450
 
 
1451
 
 
1452
bool TiXmlDeclaration::Accept( TiXmlVisitor* visitor ) const
 
1453
{
 
1454
        return visitor->Visit( *this );
 
1455
}
 
1456
 
 
1457
 
 
1458
TiXmlNode* TiXmlDeclaration::Clone() const
 
1459
{       
 
1460
        TiXmlDeclaration* clone = new TiXmlDeclaration();
 
1461
 
 
1462
        if ( !clone )
 
1463
                return 0;
 
1464
 
 
1465
        CopyTo( clone );
 
1466
        return clone;
 
1467
}
 
1468
 
 
1469
 
 
1470
void TiXmlUnknown::Print( FILE* cfile, int depth ) const
 
1471
{
 
1472
        for ( int i=0; i<depth; i++ )
 
1473
                fprintf( cfile, "    " );
 
1474
        fprintf( cfile, "<%s>", value.c_str() );
 
1475
}
 
1476
 
 
1477
 
 
1478
void TiXmlUnknown::CopyTo( TiXmlUnknown* target ) const
 
1479
{
 
1480
        TiXmlNode::CopyTo( target );
 
1481
}
 
1482
 
 
1483
 
 
1484
bool TiXmlUnknown::Accept( TiXmlVisitor* visitor ) const
 
1485
{
 
1486
        return visitor->Visit( *this );
 
1487
}
 
1488
 
 
1489
 
 
1490
TiXmlNode* TiXmlUnknown::Clone() const
 
1491
{
 
1492
        TiXmlUnknown* clone = new TiXmlUnknown();
 
1493
 
 
1494
        if ( !clone )
 
1495
                return 0;
 
1496
 
 
1497
        CopyTo( clone );
 
1498
        return clone;
 
1499
}
 
1500
 
 
1501
 
 
1502
TiXmlAttributeSet::TiXmlAttributeSet()
 
1503
{
 
1504
        sentinel.next = &sentinel;
 
1505
        sentinel.prev = &sentinel;
 
1506
}
 
1507
 
 
1508
 
 
1509
TiXmlAttributeSet::~TiXmlAttributeSet()
 
1510
{
 
1511
        assert( sentinel.next == &sentinel );
 
1512
        assert( sentinel.prev == &sentinel );
 
1513
}
 
1514
 
 
1515
 
 
1516
void TiXmlAttributeSet::Add( TiXmlAttribute* addMe )
 
1517
{
 
1518
    #ifdef TIXML_USE_STL
 
1519
        assert( !Find( TIXML_STRING( addMe->Name() ) ) );       // Shouldn't be multiply adding to the set.
 
1520
        #else
 
1521
        assert( !Find( addMe->Name() ) );       // Shouldn't be multiply adding to the set.
 
1522
        #endif
 
1523
 
 
1524
        addMe->next = &sentinel;
 
1525
        addMe->prev = sentinel.prev;
 
1526
 
 
1527
        sentinel.prev->next = addMe;
 
1528
        sentinel.prev      = addMe;
 
1529
}
 
1530
 
 
1531
void TiXmlAttributeSet::Remove( TiXmlAttribute* removeMe )
 
1532
{
 
1533
        TiXmlAttribute* node;
 
1534
 
 
1535
        for( node = sentinel.next; node != &sentinel; node = node->next )
 
1536
        {
 
1537
                if ( node == removeMe )
 
1538
                {
 
1539
                        node->prev->next = node->next;
 
1540
                        node->next->prev = node->prev;
 
1541
                        node->next = 0;
 
1542
                        node->prev = 0;
 
1543
                        return;
 
1544
                }
 
1545
        }
 
1546
        assert( 0 );            // we tried to remove a non-linked attribute.
 
1547
}
 
1548
 
 
1549
 
 
1550
#ifdef TIXML_USE_STL
 
1551
const TiXmlAttribute* TiXmlAttributeSet::Find( const std::string& name ) const
 
1552
{
 
1553
        for( const TiXmlAttribute* node = sentinel.next; node != &sentinel; node = node->next )
 
1554
        {
 
1555
                if ( node->name == name )
 
1556
                        return node;
 
1557
        }
 
1558
        return 0;
 
1559
}
 
1560
 
 
1561
/*
 
1562
TiXmlAttribute* TiXmlAttributeSet::Find( const std::string& name )
 
1563
{
 
1564
        for( TiXmlAttribute* node = sentinel.next; node != &sentinel; node = node->next )
 
1565
        {
 
1566
                if ( node->name == name )
 
1567
                        return node;
 
1568
        }
 
1569
        return 0;
 
1570
}
 
1571
*/
 
1572
#endif
 
1573
 
 
1574
 
 
1575
const TiXmlAttribute* TiXmlAttributeSet::Find( const char* name ) const
 
1576
{
 
1577
        for( const TiXmlAttribute* node = sentinel.next; node != &sentinel; node = node->next )
 
1578
        {
 
1579
                if ( strcmp( node->name.c_str(), name ) == 0 )
 
1580
                        return node;
 
1581
        }
 
1582
        return 0;
 
1583
}
 
1584
 
 
1585
/*
 
1586
TiXmlAttribute* TiXmlAttributeSet::Find( const char* name )
 
1587
{
 
1588
        for( TiXmlAttribute* node = sentinel.next; node != &sentinel; node = node->next )
 
1589
        {
 
1590
                if ( strcmp( node->name.c_str(), name ) == 0 )
 
1591
                        return node;
 
1592
        }
 
1593
        return 0;
 
1594
}
 
1595
*/
 
1596
 
 
1597
#ifdef TIXML_USE_STL    
 
1598
std::istream& operator>> (std::istream & in, TiXmlNode & base)
 
1599
{
 
1600
        TIXML_STRING tag;
 
1601
        tag.reserve( 8 * 1000 );
 
1602
        base.StreamIn( &in, &tag );
 
1603
 
 
1604
        base.Parse( tag.c_str(), 0, TIXML_DEFAULT_ENCODING );
 
1605
        return in;
 
1606
}
 
1607
#endif
 
1608
 
 
1609
 
 
1610
#ifdef TIXML_USE_STL    
 
1611
std::ostream& operator<< (std::ostream & out, const TiXmlNode & base)
 
1612
{
 
1613
        TiXmlPrinter printer;
 
1614
        printer.SetStreamPrinting();
 
1615
        base.Accept( &printer );
 
1616
        out << printer.Str();
 
1617
 
 
1618
        return out;
 
1619
}
 
1620
 
 
1621
 
 
1622
std::string& operator<< (std::string& out, const TiXmlNode& base )
 
1623
{
 
1624
        TiXmlPrinter printer;
 
1625
        printer.SetStreamPrinting();
 
1626
        base.Accept( &printer );
 
1627
        out.append( printer.Str() );
 
1628
 
 
1629
        return out;
 
1630
}
 
1631
#endif
 
1632
 
 
1633
 
 
1634
TiXmlHandle TiXmlHandle::FirstChild() const
 
1635
{
 
1636
        if ( node )
 
1637
        {
 
1638
                TiXmlNode* child = node->FirstChild();
 
1639
                if ( child )
 
1640
                        return TiXmlHandle( child );
 
1641
        }
 
1642
        return TiXmlHandle( 0 );
 
1643
}
 
1644
 
 
1645
 
 
1646
TiXmlHandle TiXmlHandle::FirstChild( const char * value ) const
 
1647
{
 
1648
        if ( node )
 
1649
        {
 
1650
                TiXmlNode* child = node->FirstChild( value );
 
1651
                if ( child )
 
1652
                        return TiXmlHandle( child );
 
1653
        }
 
1654
        return TiXmlHandle( 0 );
 
1655
}
 
1656
 
 
1657
 
 
1658
TiXmlHandle TiXmlHandle::FirstChildElement() const
 
1659
{
 
1660
        if ( node )
 
1661
        {
 
1662
                TiXmlElement* child = node->FirstChildElement();
 
1663
                if ( child )
 
1664
                        return TiXmlHandle( child );
 
1665
        }
 
1666
        return TiXmlHandle( 0 );
 
1667
}
 
1668
 
 
1669
 
 
1670
TiXmlHandle TiXmlHandle::FirstChildElement( const char * value ) const
 
1671
{
 
1672
        if ( node )
 
1673
        {
 
1674
                TiXmlElement* child = node->FirstChildElement( value );
 
1675
                if ( child )
 
1676
                        return TiXmlHandle( child );
 
1677
        }
 
1678
        return TiXmlHandle( 0 );
 
1679
}
 
1680
 
 
1681
 
 
1682
TiXmlHandle TiXmlHandle::Child( int count ) const
 
1683
{
 
1684
        if ( node )
 
1685
        {
 
1686
                int i;
 
1687
                TiXmlNode* child = node->FirstChild();
 
1688
                for (   i=0;
 
1689
                                child && i<count;
 
1690
                                child = child->NextSibling(), ++i )
 
1691
                {
 
1692
                        // nothing
 
1693
                }
 
1694
                if ( child )
 
1695
                        return TiXmlHandle( child );
 
1696
        }
 
1697
        return TiXmlHandle( 0 );
 
1698
}
 
1699
 
 
1700
 
 
1701
TiXmlHandle TiXmlHandle::Child( const char* value, int count ) const
 
1702
{
 
1703
        if ( node )
 
1704
        {
 
1705
                int i;
 
1706
                TiXmlNode* child = node->FirstChild( value );
 
1707
                for (   i=0;
 
1708
                                child && i<count;
 
1709
                                child = child->NextSibling( value ), ++i )
 
1710
                {
 
1711
                        // nothing
 
1712
                }
 
1713
                if ( child )
 
1714
                        return TiXmlHandle( child );
 
1715
        }
 
1716
        return TiXmlHandle( 0 );
 
1717
}
 
1718
 
 
1719
 
 
1720
TiXmlHandle TiXmlHandle::ChildElement( int count ) const
 
1721
{
 
1722
        if ( node )
 
1723
        {
 
1724
                int i;
 
1725
                TiXmlElement* child = node->FirstChildElement();
 
1726
                for (   i=0;
 
1727
                                child && i<count;
 
1728
                                child = child->NextSiblingElement(), ++i )
 
1729
                {
 
1730
                        // nothing
 
1731
                }
 
1732
                if ( child )
 
1733
                        return TiXmlHandle( child );
 
1734
        }
 
1735
        return TiXmlHandle( 0 );
 
1736
}
 
1737
 
 
1738
 
 
1739
TiXmlHandle TiXmlHandle::ChildElement( const char* value, int count ) const
 
1740
{
 
1741
        if ( node )
 
1742
        {
 
1743
                int i;
 
1744
                TiXmlElement* child = node->FirstChildElement( value );
 
1745
                for (   i=0;
 
1746
                                child && i<count;
 
1747
                                child = child->NextSiblingElement( value ), ++i )
 
1748
                {
 
1749
                        // nothing
 
1750
                }
 
1751
                if ( child )
 
1752
                        return TiXmlHandle( child );
 
1753
        }
 
1754
        return TiXmlHandle( 0 );
 
1755
}
 
1756
 
 
1757
 
 
1758
bool TiXmlPrinter::VisitEnter( const TiXmlDocument& )
 
1759
{
 
1760
        return true;
 
1761
}
 
1762
 
 
1763
bool TiXmlPrinter::VisitExit( const TiXmlDocument& )
 
1764
{
 
1765
        return true;
 
1766
}
 
1767
 
 
1768
bool TiXmlPrinter::VisitEnter( const TiXmlElement& element, const TiXmlAttribute* firstAttribute )
 
1769
{
 
1770
        DoIndent();
 
1771
        buffer += "<";
 
1772
        buffer += element.Value();
 
1773
 
 
1774
        for( const TiXmlAttribute* attrib = firstAttribute; attrib; attrib = attrib->Next() )
 
1775
        {
 
1776
                buffer += " ";
 
1777
                attrib->Print( 0, 0, &buffer );
 
1778
        }
 
1779
 
 
1780
        if ( !element.FirstChild() ) 
 
1781
        {
 
1782
                buffer += " />";
 
1783
                DoLineBreak();
 
1784
        }
 
1785
        else 
 
1786
        {
 
1787
                buffer += ">";
 
1788
                if (    element.FirstChild()->ToText()
 
1789
                          && element.LastChild() == element.FirstChild()
 
1790
                          && element.FirstChild()->ToText()->CDATA() == false )
 
1791
                {
 
1792
                        simpleTextPrint = true;
 
1793
                        // no DoLineBreak()!
 
1794
                }
 
1795
                else
 
1796
                {
 
1797
                        DoLineBreak();
 
1798
                }
 
1799
        }
 
1800
        ++depth;        
 
1801
        return true;
 
1802
}
 
1803
 
 
1804
 
 
1805
bool TiXmlPrinter::VisitExit( const TiXmlElement& element )
 
1806
{
 
1807
        --depth;
 
1808
        if ( !element.FirstChild() ) 
 
1809
        {
 
1810
                // nothing.
 
1811
        }
 
1812
        else 
 
1813
        {
 
1814
                if ( simpleTextPrint )
 
1815
                {
 
1816
                        simpleTextPrint = false;
 
1817
                }
 
1818
                else
 
1819
                {
 
1820
                        DoIndent();
 
1821
                }
 
1822
                buffer += "</";
 
1823
                buffer += element.Value();
 
1824
                buffer += ">";
 
1825
                DoLineBreak();
 
1826
        }
 
1827
        return true;
 
1828
}
 
1829
 
 
1830
 
 
1831
bool TiXmlPrinter::Visit( const TiXmlText& text )
 
1832
{
 
1833
        if ( text.CDATA() )
 
1834
        {
 
1835
                DoIndent();
 
1836
                buffer += "<![CDATA[";
 
1837
                buffer += text.Value();
 
1838
                buffer += "]]>";
 
1839
                DoLineBreak();
 
1840
        }
 
1841
        else if ( simpleTextPrint )
 
1842
        {
 
1843
                TIXML_STRING str;
 
1844
                TiXmlBase::EncodeString( text.ValueTStr(), &str );
 
1845
                buffer += str;
 
1846
        }
 
1847
        else
 
1848
        {
 
1849
                DoIndent();
 
1850
                TIXML_STRING str;
 
1851
                TiXmlBase::EncodeString( text.ValueTStr(), &str );
 
1852
                buffer += str;
 
1853
                DoLineBreak();
 
1854
        }
 
1855
        return true;
 
1856
}
 
1857
 
 
1858
 
 
1859
bool TiXmlPrinter::Visit( const TiXmlDeclaration& declaration )
 
1860
{
 
1861
        DoIndent();
 
1862
        declaration.Print( 0, 0, &buffer );
 
1863
        DoLineBreak();
 
1864
        return true;
 
1865
}
 
1866
 
 
1867
 
 
1868
bool TiXmlPrinter::Visit( const TiXmlComment& comment )
 
1869
{
 
1870
        DoIndent();
 
1871
        buffer += "<!--";
 
1872
        buffer += comment.Value();
 
1873
        buffer += "-->";
 
1874
        DoLineBreak();
 
1875
        return true;
 
1876
}
 
1877
 
 
1878
 
 
1879
bool TiXmlPrinter::Visit( const TiXmlUnknown& unknown )
 
1880
{
 
1881
        DoIndent();
 
1882
        buffer += "<";
 
1883
        buffer += unknown.Value();
 
1884
        buffer += ">";
 
1885
        DoLineBreak();
 
1886
        return true;
 
1887
}
 
1888