1c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie/* 2c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew XieOriginal code by Lee Thomason (www.grinninglizard.com) 3c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie 4c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew XieThis software is provided 'as-is', without any express or implied 5c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xiewarranty. In no event will the authors be held liable for any 6c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xiedamages arising from the use of this software. 7c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie 8c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew XiePermission is granted to anyone to use this software for any 9c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xiepurpose, including commercial applications, and to alter it and 10c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xieredistribute it freely, subject to the following restrictions: 11c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie 12c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie1. The origin of this software must not be misrepresented; you must 13c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xienot claim that you wrote the original software. If you use this 14c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xiesoftware in a product, an acknowledgment in the product documentation 15c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xiewould be appreciated but is not required. 16c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie 17c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie2. Altered source versions must be plainly marked as such, and 18c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xiemust not be misrepresented as being the original software. 19c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie 20c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie3. This notice may not be removed or altered from any source 21c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xiedistribution. 22c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie*/ 23c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie#include "tinyxml2.h" 24c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie 25c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie#include <cstdio> 26c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie#include <cstdlib> 27c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie#include <new> 28c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie#include <cstddef> 29c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie 30c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie#include <fcntl.h> 31c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xieusing namespace tinyxml2; 32c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie 33c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xiestatic const char LINE_FEED = (char)0x0a; // all line endings are normalized to LF 34c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xiestatic const char LF = LINE_FEED; 35c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xiestatic const char CARRIAGE_RETURN = (char)0x0d; // CR gets filtered out 36c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xiestatic const char CR = CARRIAGE_RETURN; 37c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xiestatic const char SINGLE_QUOTE = '\''; 38c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xiestatic const char DOUBLE_QUOTE = '\"'; 39c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie 40c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie// Bunch of unicode info at: 41c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie// http://www.unicode.org/faq/utf_bom.html 42c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie// ef bb bf (Microsoft "lead bytes") - designates UTF-8 43c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie 44c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xiestatic const unsigned char TIXML_UTF_LEAD_0 = 0xefU; 45c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xiestatic const unsigned char TIXML_UTF_LEAD_1 = 0xbbU; 46c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xiestatic const unsigned char TIXML_UTF_LEAD_2 = 0xbfU; 47c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie 48c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie 49c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie#define DELETE_NODE( node ) { \ 50c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie if ( node ) { \ 51c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie MemPool* pool = node->memPool; \ 52c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie node->~XMLNode(); \ 53c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie pool->Free( node ); \ 54c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie } \ 55c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie} 56c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie#define DELETE_ATTRIBUTE( attrib ) { \ 57c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie if ( attrib ) { \ 58c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie MemPool* pool = attrib->memPool; \ 59c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie attrib->~XMLAttribute(); \ 60c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie pool->Free( attrib ); \ 61c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie } \ 62c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie} 63c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie 64c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xiestruct Entity { 65c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie const char* pattern; 66c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie int length; 67c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie char value; 68c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie}; 69c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie 70c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xiestatic const int NUM_ENTITIES = 5; 71c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xiestatic const Entity entities[NUM_ENTITIES] = 72c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie{ 73c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie { "quot", 4, DOUBLE_QUOTE }, 74c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie { "amp", 3, '&' }, 75c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie { "apos", 4, SINGLE_QUOTE }, 76c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie { "lt", 2, '<' }, 77c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie { "gt", 2, '>' } 78c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie}; 79c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie 80c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie 81c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew XieStrPair::~StrPair() 82c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie{ 83c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie Reset(); 84c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie} 85c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie 86c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie 87c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xievoid StrPair::Reset() 88c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie{ 89c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie if ( flags & NEEDS_DELETE ) { 90c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie delete [] start; 91c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie } 92c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie flags = 0; 93c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie start = 0; 94c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie end = 0; 95c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie} 96c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie 97c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie 98c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xievoid StrPair::SetStr( const char* str, int flags ) 99c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie{ 100c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie Reset(); 101c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie size_t len = strlen( str ); 102c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie start = new char[ len+1 ]; 103c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie memcpy( start, str, len+1 ); 104c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie end = start + len; 105c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie this->flags = flags | NEEDS_DELETE; 106c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie} 107c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie 108c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie 109c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xiechar* StrPair::ParseText( char* p, const char* endTag, int strFlags ) 110c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie{ 111c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie TIXMLASSERT( endTag && *endTag ); 112c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie 113c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie char* start = p; // fixme: hides a member 114c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie char endChar = *endTag; 115c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie size_t length = strlen( endTag ); 116c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie 117c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie // Inner loop of text parsing. 118c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie while ( *p ) { 119c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie if ( *p == endChar && strncmp( p, endTag, length ) == 0 ) { 120c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie Set( start, p, strFlags ); 121c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie return p + length; 122c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie } 123c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie ++p; 124c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie } 125c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie return 0; 126c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie} 127c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie 128c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie 129c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xiechar* StrPair::ParseName( char* p ) 130c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie{ 131c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie char* start = p; 132c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie 133c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie if ( !start || !(*start) ) { 134c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie return 0; 135c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie } 136c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie 137c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie if ( !XMLUtil::IsAlpha( *p ) ) { 138c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie return 0; 139c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie } 140c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie 141c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie while( *p && ( 142c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie XMLUtil::IsAlphaNum( (unsigned char) *p ) 143c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie || *p == '_' 144c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie || *p == '-' 145c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie || *p == '.' 146c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie || *p == ':' )) 147c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie { 148c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie ++p; 149c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie } 150c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie 151c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie if ( p > start ) { 152c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie Set( start, p, 0 ); 153c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie return p; 154c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie } 155c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie return 0; 156c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie} 157c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie 158c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie 159c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie 160c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xieconst char* StrPair::GetStr() 161c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie{ 162c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie if ( flags & NEEDS_FLUSH ) { 163c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie *end = 0; 164c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie flags ^= NEEDS_FLUSH; 165c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie 166c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie if ( flags ) { 167c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie char* p = start; // the read pointer 168c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie char* q = start; // the write pointer 169c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie 170c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie while( p < end ) { 171c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie if ( (flags & NEEDS_NEWLINE_NORMALIZATION) && *p == CR ) { 172c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie // CR-LF pair becomes LF 173c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie // CR alone becomes LF 174c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie // LF-CR becomes LF 175c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie if ( *(p+1) == LF ) { 176c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie p += 2; 177c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie } 178c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie else { 179c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie ++p; 180c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie } 181c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie *q++ = LF; 182c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie } 183c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie else if ( (flags & NEEDS_NEWLINE_NORMALIZATION) && *p == LF ) { 184c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie if ( *(p+1) == CR ) { 185c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie p += 2; 186c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie } 187c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie else { 188c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie ++p; 189c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie } 190c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie *q++ = LF; 191c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie } 192c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie else if ( (flags & NEEDS_ENTITY_PROCESSING) && *p == '&' ) { 193c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie // Entities handled by tinyXML2: 194c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie // - special entities in the entity table [in/out] 195c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie // - numeric character reference [in] 196c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie // 中 or 中 197c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie 198c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie if ( *(p+1) == '#' ) { 199c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie char buf[10] = { 0 }; 200c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie int len; 201c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie p = const_cast<char*>( XMLUtil::GetCharacterRef( p, buf, &len ) ); 202c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie for( int i=0; i<len; ++i ) { 203c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie *q++ = buf[i]; 204c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie } 205c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie TIXMLASSERT( q <= p ); 206c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie } 207c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie else { 208c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie int i=0; 209c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie for(; i<NUM_ENTITIES; ++i ) { 210c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie if ( strncmp( p+1, entities[i].pattern, entities[i].length ) == 0 211c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie && *(p+entities[i].length+1) == ';' ) 212c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie { 213c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie // Found an entity convert; 214c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie *q = entities[i].value; 215c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie ++q; 216c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie p += entities[i].length + 2; 217c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie break; 218c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie } 219c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie } 220c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie if ( i == NUM_ENTITIES ) { 221c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie // fixme: treat as error? 222c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie ++p; 223c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie ++q; 224c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie } 225c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie } 226c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie } 227c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie else { 228c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie *q = *p; 229c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie ++p; 230c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie ++q; 231c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie } 232c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie } 233c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie *q = 0; 234c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie } 235c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie flags = (flags & NEEDS_DELETE); 236c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie } 237c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie return start; 238c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie} 239c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie 240c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie 241c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie 242c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie 243c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie// --------- XMLUtil ----------- // 244c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie 245c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xieconst char* XMLUtil::ReadBOM( const char* p, bool* bom ) 246c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie{ 247c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie *bom = false; 248c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie const unsigned char* pu = reinterpret_cast<const unsigned char*>(p); 249c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie // Check for BOM: 250c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie if ( *(pu+0) == TIXML_UTF_LEAD_0 251c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie && *(pu+1) == TIXML_UTF_LEAD_1 252c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie && *(pu+2) == TIXML_UTF_LEAD_2 ) 253c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie { 254c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie *bom = true; 255c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie p += 3; 256c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie } 257c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie return p; 258c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie} 259c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie 260c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie 261c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xievoid XMLUtil::ConvertUTF32ToUTF8( unsigned long input, char* output, int* length ) 262c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie{ 263c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie const unsigned long BYTE_MASK = 0xBF; 264c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie const unsigned long BYTE_MARK = 0x80; 265c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie const unsigned long FIRST_BYTE_MARK[7] = { 0x00, 0x00, 0xC0, 0xE0, 0xF0, 0xF8, 0xFC }; 266c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie 267c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie if (input < 0x80) 268c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie *length = 1; 269c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie else if ( input < 0x800 ) 270c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie *length = 2; 271c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie else if ( input < 0x10000 ) 272c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie *length = 3; 273c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie else if ( input < 0x200000 ) 274c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie *length = 4; 275c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie else 276c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie { *length = 0; return; } // This code won't covert this correctly anyway. 277c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie 278c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie output += *length; 279c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie 280c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie // Scary scary fall throughs. 281c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie switch (*length) 282c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie { 283c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie case 4: 284c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie --output; 285c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie *output = (char)((input | BYTE_MARK) & BYTE_MASK); 286c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie input >>= 6; 287c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie case 3: 288c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie --output; 289c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie *output = (char)((input | BYTE_MARK) & BYTE_MASK); 290c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie input >>= 6; 291c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie case 2: 292c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie --output; 293c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie *output = (char)((input | BYTE_MARK) & BYTE_MASK); 294c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie input >>= 6; 295c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie case 1: 296c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie --output; 297c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie *output = (char)(input | FIRST_BYTE_MARK[*length]); 298c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie } 299c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie} 300c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie 301c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie 302c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xieconst char* XMLUtil::GetCharacterRef( const char* p, char* value, int* length ) 303c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie{ 304c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie // Presume an entity, and pull it out. 305c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie *length = 0; 306c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie 307c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie if ( *(p+1) == '#' && *(p+2) ) 308c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie { 309c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie unsigned long ucs = 0; 310c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie ptrdiff_t delta = 0; 311c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie unsigned mult = 1; 312c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie 313c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie if ( *(p+2) == 'x' ) 314c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie { 315c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie // Hexadecimal. 316c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie if ( !*(p+3) ) return 0; 317c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie 318c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie const char* q = p+3; 319c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie q = strchr( q, ';' ); 320c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie 321c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie if ( !q || !*q ) return 0; 322c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie 323c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie delta = q-p; 324c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie --q; 325c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie 326c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie while ( *q != 'x' ) 327c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie { 328c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie if ( *q >= '0' && *q <= '9' ) 329c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie ucs += mult * (*q - '0'); 330c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie else if ( *q >= 'a' && *q <= 'f' ) 331c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie ucs += mult * (*q - 'a' + 10); 332c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie else if ( *q >= 'A' && *q <= 'F' ) 333c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie ucs += mult * (*q - 'A' + 10 ); 334c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie else 335c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie return 0; 336c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie mult *= 16; 337c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie --q; 338c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie } 339c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie } 340c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie else 341c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie { 342c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie // Decimal. 343c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie if ( !*(p+2) ) return 0; 344c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie 345c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie const char* q = p+2; 346c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie q = strchr( q, ';' ); 347c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie 348c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie if ( !q || !*q ) return 0; 349c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie 350c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie delta = q-p; 351c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie --q; 352c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie 353c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie while ( *q != '#' ) 354c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie { 355c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie if ( *q >= '0' && *q <= '9' ) 356c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie ucs += mult * (*q - '0'); 357c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie else 358c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie return 0; 359c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie mult *= 10; 360c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie --q; 361c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie } 362c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie } 363c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie // convert the UCS to UTF-8 364c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie ConvertUTF32ToUTF8( ucs, value, length ); 365c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie return p + delta + 1; 366c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie } 367c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie return p+1; 368c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie} 369c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie 370c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie 371c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xievoid XMLUtil::ToStr( int v, char* buffer, int bufferSize ) 372c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie{ 373c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie TIXML_SNPRINTF( buffer, bufferSize, "%d", v ); 374c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie} 375c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie 376c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie 377c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xievoid XMLUtil::ToStr( unsigned v, char* buffer, int bufferSize ) 378c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie{ 379c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie TIXML_SNPRINTF( buffer, bufferSize, "%u", v ); 380c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie} 381c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie 382c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie 383c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xievoid XMLUtil::ToStr( bool v, char* buffer, int bufferSize ) 384c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie{ 385c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie TIXML_SNPRINTF( buffer, bufferSize, "%d", v ? 1 : 0 ); 386c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie} 387c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie 388c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie 389c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xievoid XMLUtil::ToStr( float v, char* buffer, int bufferSize ) 390c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie{ 391c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie TIXML_SNPRINTF( buffer, bufferSize, "%f", v ); 392c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie} 393c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie 394c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie 395c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xievoid XMLUtil::ToStr( double v, char* buffer, int bufferSize ) 396c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie{ 397c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie TIXML_SNPRINTF( buffer, bufferSize, "%f", v ); 398c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie} 399c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie 400c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie 401c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xiebool XMLUtil::ToInt( const char* str, int* value ) 402c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie{ 403c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie if ( TIXML_SSCANF( str, "%d", value ) == 1 ) 404c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie return true; 405c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie return false; 406c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie} 407c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie 408c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xiebool XMLUtil::ToUnsigned( const char* str, unsigned *value ) 409c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie{ 410c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie if ( TIXML_SSCANF( str, "%u", value ) == 1 ) 411c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie return true; 412c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie return false; 413c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie} 414c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie 415c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xiebool XMLUtil::ToBool( const char* str, bool* value ) 416c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie{ 417c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie int ival = 0; 418c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie if ( ToInt( str, &ival )) { 419c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie *value = (ival==0) ? false : true; 420c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie return true; 421c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie } 422c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie if ( StringEqual( str, "true" ) ) { 423c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie *value = true; 424c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie return true; 425c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie } 426c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie else if ( StringEqual( str, "false" ) ) { 427c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie *value = false; 428c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie return true; 429c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie } 430c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie return false; 431c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie} 432c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie 433c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie 434c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xiebool XMLUtil::ToFloat( const char* str, float* value ) 435c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie{ 436c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie if ( TIXML_SSCANF( str, "%f", value ) == 1 ) { 437c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie return true; 438c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie } 439c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie return false; 440c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie} 441c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie 442c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xiebool XMLUtil::ToDouble( const char* str, double* value ) 443c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie{ 444c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie if ( TIXML_SSCANF( str, "%lf", value ) == 1 ) { 445c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie return true; 446c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie } 447c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie return false; 448c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie} 449c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie 450c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie 451c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xiechar* XMLDocument::Identify( char* p, XMLNode** node ) 452c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie{ 453c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie XMLNode* returnNode = 0; 454c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie char* start = p; 455c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie p = XMLUtil::SkipWhiteSpace( p ); 456c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie if( !p || !*p ) 457c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie { 458c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie return p; 459c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie } 460c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie 461c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie // What is this thing? 462c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie // - Elements start with a letter or underscore, but xml is reserved. 463c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie // - Comments: <!-- 464c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie // - Decleration: <? 465c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie // - Everthing else is unknown to tinyxml. 466c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie // 467c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie 468c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie static const char* xmlHeader = { "<?" }; 469c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie static const char* commentHeader = { "<!--" }; 470c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie static const char* dtdHeader = { "<!" }; 471c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie static const char* cdataHeader = { "<![CDATA[" }; 472c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie static const char* elementHeader = { "<" }; // and a header for everything else; check last. 473c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie 474c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie static const int xmlHeaderLen = 2; 475c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie static const int commentHeaderLen = 4; 476c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie static const int dtdHeaderLen = 2; 477c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie static const int cdataHeaderLen = 9; 478c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie static const int elementHeaderLen = 1; 479c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie 480c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie#if defined(_MSC_VER) 481c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie#pragma warning ( push ) 482c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie#pragma warning ( disable : 4127 ) 483c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie#endif 484c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie TIXMLASSERT( sizeof( XMLComment ) == sizeof( XMLUnknown ) ); // use same memory pool 485c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie TIXMLASSERT( sizeof( XMLComment ) == sizeof( XMLDeclaration ) ); // use same memory pool 486c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie#if defined(_MSC_VER) 487c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie#pragma warning (pop) 488c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie#endif 489c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie if ( XMLUtil::StringEqual( p, xmlHeader, xmlHeaderLen ) ) { 490c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie returnNode = new (commentPool.Alloc()) XMLDeclaration( this ); 491c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie returnNode->memPool = &commentPool; 492c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie p += xmlHeaderLen; 493c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie } 494c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie else if ( XMLUtil::StringEqual( p, commentHeader, commentHeaderLen ) ) { 495c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie returnNode = new (commentPool.Alloc()) XMLComment( this ); 496c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie returnNode->memPool = &commentPool; 497c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie p += commentHeaderLen; 498c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie } 499c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie else if ( XMLUtil::StringEqual( p, cdataHeader, cdataHeaderLen ) ) { 500c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie XMLText* text = new (textPool.Alloc()) XMLText( this ); 501c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie returnNode = text; 502c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie returnNode->memPool = &textPool; 503c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie p += cdataHeaderLen; 504c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie text->SetCData( true ); 505c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie } 506c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie else if ( XMLUtil::StringEqual( p, dtdHeader, dtdHeaderLen ) ) { 507c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie returnNode = new (commentPool.Alloc()) XMLUnknown( this ); 508c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie returnNode->memPool = &commentPool; 509c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie p += dtdHeaderLen; 510c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie } 511c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie else if ( XMLUtil::StringEqual( p, elementHeader, elementHeaderLen ) ) { 512c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie returnNode = new (elementPool.Alloc()) XMLElement( this ); 513c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie returnNode->memPool = &elementPool; 514c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie p += elementHeaderLen; 515c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie } 516c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie else { 517c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie returnNode = new (textPool.Alloc()) XMLText( this ); 518c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie returnNode->memPool = &textPool; 519c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie p = start; // Back it up, all the text counts. 520c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie } 521c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie 522c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie *node = returnNode; 523c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie return p; 524c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie} 525c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie 526c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie 527c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xiebool XMLDocument::Accept( XMLVisitor* visitor ) const 528c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie{ 529c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie if ( visitor->VisitEnter( *this ) ) 530c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie { 531c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie for ( const XMLNode* node=FirstChild(); node; node=node->NextSibling() ) 532c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie { 533c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie if ( !node->Accept( visitor ) ) 534c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie break; 535c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie } 536c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie } 537c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie return visitor->VisitExit( *this ); 538c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie} 539c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie 540c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie 541c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie// --------- XMLNode ----------- // 542c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie 543c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew XieXMLNode::XMLNode( XMLDocument* doc ) : 544c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie document( doc ), 545c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie parent( 0 ), 546c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie firstChild( 0 ), lastChild( 0 ), 547c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie prev( 0 ), next( 0 ) 548c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie{ 549c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie} 550c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie 551c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie 552c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew XieXMLNode::~XMLNode() 553c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie{ 554c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie DeleteChildren(); 555c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie if ( parent ) { 556c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie parent->Unlink( this ); 557c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie } 558c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie} 559c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie 560c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie 561c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xievoid XMLNode::SetValue( const char* str, bool staticMem ) 562c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie{ 563c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie if ( staticMem ) 564c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie value.SetInternedStr( str ); 565c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie else 566c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie value.SetStr( str ); 567c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie} 568c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie 569c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie 570c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xievoid XMLNode::DeleteChildren() 571c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie{ 572c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie while( firstChild ) { 573c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie XMLNode* node = firstChild; 574c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie Unlink( node ); 575c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie 576c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie DELETE_NODE( node ); 577c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie } 578c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie firstChild = lastChild = 0; 579c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie} 580c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie 581c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie 582c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xievoid XMLNode::Unlink( XMLNode* child ) 583c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie{ 584c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie TIXMLASSERT( child->parent == this ); 585c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie if ( child == firstChild ) 586c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie firstChild = firstChild->next; 587c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie if ( child == lastChild ) 588c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie lastChild = lastChild->prev; 589c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie 590c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie if ( child->prev ) { 591c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie child->prev->next = child->next; 592c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie } 593c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie if ( child->next ) { 594c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie child->next->prev = child->prev; 595c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie } 596c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie child->parent = 0; 597c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie} 598c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie 599c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie 600c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xievoid XMLNode::DeleteChild( XMLNode* node ) 601c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie{ 602c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie TIXMLASSERT( node->parent == this ); 603c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie DELETE_NODE( node ); 604c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie} 605c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie 606c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie 607c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew XieXMLNode* XMLNode::InsertEndChild( XMLNode* addThis ) 608c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie{ 609c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie if ( lastChild ) { 610c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie TIXMLASSERT( firstChild ); 611c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie TIXMLASSERT( lastChild->next == 0 ); 612c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie lastChild->next = addThis; 613c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie addThis->prev = lastChild; 614c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie lastChild = addThis; 615c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie 616c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie addThis->next = 0; 617c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie } 618c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie else { 619c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie TIXMLASSERT( firstChild == 0 ); 620c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie firstChild = lastChild = addThis; 621c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie 622c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie addThis->prev = 0; 623c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie addThis->next = 0; 624c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie } 625c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie addThis->parent = this; 626c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie return addThis; 627c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie} 628c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie 629c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie 630c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew XieXMLNode* XMLNode::InsertFirstChild( XMLNode* addThis ) 631c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie{ 632c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie if ( firstChild ) { 633c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie TIXMLASSERT( lastChild ); 634c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie TIXMLASSERT( firstChild->prev == 0 ); 635c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie 636c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie firstChild->prev = addThis; 637c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie addThis->next = firstChild; 638c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie firstChild = addThis; 639c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie 640c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie addThis->prev = 0; 641c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie } 642c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie else { 643c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie TIXMLASSERT( lastChild == 0 ); 644c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie firstChild = lastChild = addThis; 645c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie 646c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie addThis->prev = 0; 647c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie addThis->next = 0; 648c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie } 649c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie addThis->parent = this; 650c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie return addThis; 651c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie} 652c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie 653c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie 654c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew XieXMLNode* XMLNode::InsertAfterChild( XMLNode* afterThis, XMLNode* addThis ) 655c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie{ 656c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie TIXMLASSERT( afterThis->parent == this ); 657c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie if ( afterThis->parent != this ) 658c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie return 0; 659c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie 660c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie if ( afterThis->next == 0 ) { 661c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie // The last node or the only node. 662c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie return InsertEndChild( addThis ); 663c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie } 664c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie addThis->prev = afterThis; 665c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie addThis->next = afterThis->next; 666c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie afterThis->next->prev = addThis; 667c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie afterThis->next = addThis; 668c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie addThis->parent = this; 669c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie return addThis; 670c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie} 671c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie 672c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie 673c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie 674c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie 675c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xieconst XMLElement* XMLNode::FirstChildElement( const char* value ) const 676c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie{ 677c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie for( XMLNode* node=firstChild; node; node=node->next ) { 678c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie XMLElement* element = node->ToElement(); 679c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie if ( element ) { 680c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie if ( !value || XMLUtil::StringEqual( element->Name(), value ) ) { 681c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie return element; 682c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie } 683c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie } 684c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie } 685c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie return 0; 686c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie} 687c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie 688c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie 689c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xieconst XMLElement* XMLNode::LastChildElement( const char* value ) const 690c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie{ 691c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie for( XMLNode* node=lastChild; node; node=node->prev ) { 692c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie XMLElement* element = node->ToElement(); 693c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie if ( element ) { 694c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie if ( !value || XMLUtil::StringEqual( element->Name(), value ) ) { 695c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie return element; 696c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie } 697c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie } 698c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie } 699c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie return 0; 700c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie} 701c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie 702c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie 703c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xieconst XMLElement* XMLNode::NextSiblingElement( const char* value ) const 704c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie{ 705c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie for( XMLNode* element=this->next; element; element = element->next ) { 706c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie if ( element->ToElement() 707c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie && (!value || XMLUtil::StringEqual( value, element->Value() ))) 708c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie { 709c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie return element->ToElement(); 710c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie } 711c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie } 712c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie return 0; 713c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie} 714c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie 715c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie 716c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xieconst XMLElement* XMLNode::PreviousSiblingElement( const char* value ) const 717c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie{ 718c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie for( XMLNode* element=this->prev; element; element = element->prev ) { 719c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie if ( element->ToElement() 720c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie && (!value || XMLUtil::StringEqual( value, element->Value() ))) 721c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie { 722c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie return element->ToElement(); 723c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie } 724c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie } 725c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie return 0; 726c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie} 727c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie 728c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie 729c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xiechar* XMLNode::ParseDeep( char* p, StrPair* parentEnd ) 730c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie{ 731c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie // This is a recursive method, but thinking about it "at the current level" 732c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie // it is a pretty simple flat list: 733c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie // <foo/> 734c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie // <!-- comment --> 735c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie // 736c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie // With a special case: 737c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie // <foo> 738c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie // </foo> 739c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie // <!-- comment --> 740c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie // 741c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie // Where the closing element (/foo) *must* be the next thing after the opening 742c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie // element, and the names must match. BUT the tricky bit is that the closing 743c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie // element will be read by the child. 744c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie // 745c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie // 'endTag' is the end tag for this node, it is returned by a call to a child. 746c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie // 'parentEnd' is the end tag for the parent, which is filled in and returned. 747c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie 748c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie while( p && *p ) { 749c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie XMLNode* node = 0; 750c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie 751c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie p = document->Identify( p, &node ); 752c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie if ( p == 0 || node == 0 ) { 753c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie break; 754c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie } 755c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie 756c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie StrPair endTag; 757c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie p = node->ParseDeep( p, &endTag ); 758c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie if ( !p ) { 759c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie DELETE_NODE( node ); 760c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie node = 0; 761c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie if ( !document->Error() ) { 762c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie document->SetError( XML_ERROR_PARSING, 0, 0 ); 763c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie } 764c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie break; 765c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie } 766c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie 767c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie // We read the end tag. Return it to the parent. 768c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie if ( node->ToElement() && node->ToElement()->ClosingType() == XMLElement::CLOSING ) { 769c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie if ( parentEnd ) { 770c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie *parentEnd = static_cast<XMLElement*>(node)->value; 771c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie } 772c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie DELETE_NODE( node ); 773c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie return p; 774c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie } 775c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie 776c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie // Handle an end tag returned to this level. 777c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie // And handle a bunch of annoying errors. 778c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie XMLElement* ele = node->ToElement(); 779c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie if ( ele ) { 780c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie if ( endTag.Empty() && ele->ClosingType() == XMLElement::OPEN ) { 781c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie document->SetError( XML_ERROR_MISMATCHED_ELEMENT, node->Value(), 0 ); 782c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie p = 0; 783c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie } 784c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie else if ( !endTag.Empty() && ele->ClosingType() != XMLElement::OPEN ) { 785c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie document->SetError( XML_ERROR_MISMATCHED_ELEMENT, node->Value(), 0 ); 786c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie p = 0; 787c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie } 788c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie else if ( !endTag.Empty() ) { 789c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie if ( !XMLUtil::StringEqual( endTag.GetStr(), node->Value() )) { 790c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie document->SetError( XML_ERROR_MISMATCHED_ELEMENT, node->Value(), 0 ); 791c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie p = 0; 792c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie } 793c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie } 794c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie } 795c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie if ( p == 0 ) { 796c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie DELETE_NODE( node ); 797c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie node = 0; 798c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie } 799c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie if ( node ) { 800c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie this->InsertEndChild( node ); 801c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie } 802c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie } 803c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie return 0; 804c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie} 805c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie 806c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie// --------- XMLText ---------- // 807c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xiechar* XMLText::ParseDeep( char* p, StrPair* ) 808c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie{ 809c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie const char* start = p; 810c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie if ( this->CData() ) { 811c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie p = value.ParseText( p, "]]>", StrPair::NEEDS_NEWLINE_NORMALIZATION ); 812c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie if ( !p ) { 813c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie document->SetError( XML_ERROR_PARSING_CDATA, start, 0 ); 814c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie } 815c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie return p; 816c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie } 817c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie else { 818c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie p = value.ParseText( p, "<", document->ProcessEntities() ? StrPair::TEXT_ELEMENT : StrPair::TEXT_ELEMENT_LEAVE_ENTITIES ); 819c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie if ( !p ) { 820c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie document->SetError( XML_ERROR_PARSING_TEXT, start, 0 ); 821c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie } 822c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie if ( p && *p ) { 823c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie return p-1; 824c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie } 825c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie } 826c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie return 0; 827c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie} 828c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie 829c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie 830c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew XieXMLNode* XMLText::ShallowClone( XMLDocument* doc ) const 831c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie{ 832c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie if ( !doc ) { 833c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie doc = document; 834c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie } 835c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie XMLText* text = doc->NewText( Value() ); // fixme: this will always allocate memory. Intern? 836c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie text->SetCData( this->CData() ); 837c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie return text; 838c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie} 839c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie 840c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie 841c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xiebool XMLText::ShallowEqual( const XMLNode* compare ) const 842c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie{ 843c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie return ( compare->ToText() && XMLUtil::StringEqual( compare->ToText()->Value(), Value() )); 844c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie} 845c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie 846c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie 847c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xiebool XMLText::Accept( XMLVisitor* visitor ) const 848c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie{ 849c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie return visitor->Visit( *this ); 850c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie} 851c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie 852c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie 853c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie// --------- XMLComment ---------- // 854c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie 855c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew XieXMLComment::XMLComment( XMLDocument* doc ) : XMLNode( doc ) 856c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie{ 857c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie} 858c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie 859c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie 860c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew XieXMLComment::~XMLComment() 861c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie{ 862c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie //printf( "~XMLComment\n" ); 863c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie} 864c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie 865c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie 866c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xiechar* XMLComment::ParseDeep( char* p, StrPair* ) 867c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie{ 868c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie // Comment parses as text. 869c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie const char* start = p; 870c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie p = value.ParseText( p, "-->", StrPair::COMMENT ); 871c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie if ( p == 0 ) { 872c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie document->SetError( XML_ERROR_PARSING_COMMENT, start, 0 ); 873c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie } 874c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie return p; 875c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie} 876c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie 877c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie 878c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew XieXMLNode* XMLComment::ShallowClone( XMLDocument* doc ) const 879c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie{ 880c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie if ( !doc ) { 881c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie doc = document; 882c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie } 883c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie XMLComment* comment = doc->NewComment( Value() ); // fixme: this will always allocate memory. Intern? 884c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie return comment; 885c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie} 886c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie 887c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie 888c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xiebool XMLComment::ShallowEqual( const XMLNode* compare ) const 889c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie{ 890c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie return ( compare->ToComment() && XMLUtil::StringEqual( compare->ToComment()->Value(), Value() )); 891c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie} 892c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie 893c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie 894c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xiebool XMLComment::Accept( XMLVisitor* visitor ) const 895c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie{ 896c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie return visitor->Visit( *this ); 897c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie} 898c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie 899c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie 900c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie// --------- XMLDeclaration ---------- // 901c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie 902c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew XieXMLDeclaration::XMLDeclaration( XMLDocument* doc ) : XMLNode( doc ) 903c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie{ 904c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie} 905c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie 906c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie 907c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew XieXMLDeclaration::~XMLDeclaration() 908c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie{ 909c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie //printf( "~XMLDeclaration\n" ); 910c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie} 911c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie 912c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie 913c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xiechar* XMLDeclaration::ParseDeep( char* p, StrPair* ) 914c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie{ 915c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie // Declaration parses as text. 916c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie const char* start = p; 917c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie p = value.ParseText( p, "?>", StrPair::NEEDS_NEWLINE_NORMALIZATION ); 918c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie if ( p == 0 ) { 919c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie document->SetError( XML_ERROR_PARSING_DECLARATION, start, 0 ); 920c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie } 921c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie return p; 922c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie} 923c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie 924c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie 925c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew XieXMLNode* XMLDeclaration::ShallowClone( XMLDocument* doc ) const 926c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie{ 927c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie if ( !doc ) { 928c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie doc = document; 929c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie } 930c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie XMLDeclaration* dec = doc->NewDeclaration( Value() ); // fixme: this will always allocate memory. Intern? 931c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie return dec; 932c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie} 933c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie 934c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie 935c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xiebool XMLDeclaration::ShallowEqual( const XMLNode* compare ) const 936c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie{ 937c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie return ( compare->ToDeclaration() && XMLUtil::StringEqual( compare->ToDeclaration()->Value(), Value() )); 938c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie} 939c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie 940c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie 941c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie 942c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xiebool XMLDeclaration::Accept( XMLVisitor* visitor ) const 943c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie{ 944c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie return visitor->Visit( *this ); 945c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie} 946c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie 947c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie// --------- XMLUnknown ---------- // 948c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie 949c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew XieXMLUnknown::XMLUnknown( XMLDocument* doc ) : XMLNode( doc ) 950c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie{ 951c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie} 952c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie 953c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie 954c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew XieXMLUnknown::~XMLUnknown() 955c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie{ 956c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie} 957c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie 958c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie 959c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xiechar* XMLUnknown::ParseDeep( char* p, StrPair* ) 960c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie{ 961c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie // Unknown parses as text. 962c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie const char* start = p; 963c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie 964c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie p = value.ParseText( p, ">", StrPair::NEEDS_NEWLINE_NORMALIZATION ); 965c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie if ( !p ) { 966c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie document->SetError( XML_ERROR_PARSING_UNKNOWN, start, 0 ); 967c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie } 968c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie return p; 969c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie} 970c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie 971c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie 972c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew XieXMLNode* XMLUnknown::ShallowClone( XMLDocument* doc ) const 973c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie{ 974c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie if ( !doc ) { 975c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie doc = document; 976c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie } 977c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie XMLUnknown* text = doc->NewUnknown( Value() ); // fixme: this will always allocate memory. Intern? 978c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie return text; 979c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie} 980c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie 981c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie 982c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xiebool XMLUnknown::ShallowEqual( const XMLNode* compare ) const 983c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie{ 984c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie return ( compare->ToUnknown() && XMLUtil::StringEqual( compare->ToUnknown()->Value(), Value() )); 985c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie} 986c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie 987c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie 988c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xiebool XMLUnknown::Accept( XMLVisitor* visitor ) const 989c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie{ 990c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie return visitor->Visit( *this ); 991c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie} 992c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie 993c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie// --------- XMLAttribute ---------- // 994c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xiechar* XMLAttribute::ParseDeep( char* p, bool processEntities ) 995c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie{ 996c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie // Parse using the name rules: bug fix, was using ParseText before 997c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie p = name.ParseName( p ); 998c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie if ( !p || !*p ) return 0; 999c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie 1000c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie // Skip white space before = 1001c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie p = XMLUtil::SkipWhiteSpace( p ); 1002c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie if ( !p || *p != '=' ) return 0; 1003c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie 1004c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie ++p; // move up to opening quote 1005c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie p = XMLUtil::SkipWhiteSpace( p ); 1006c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie if ( *p != '\"' && *p != '\'' ) return 0; 1007c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie 1008c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie char endTag[2] = { *p, 0 }; 1009c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie ++p; // move past opening quote 1010c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie 1011c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie p = value.ParseText( p, endTag, processEntities ? StrPair::ATTRIBUTE_VALUE : StrPair::ATTRIBUTE_VALUE_LEAVE_ENTITIES ); 1012c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie return p; 1013c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie} 1014c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie 1015c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie 1016c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xievoid XMLAttribute::SetName( const char* n ) 1017c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie{ 1018c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie name.SetStr( n ); 1019c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie} 1020c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie 1021c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie 1022c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xieint XMLAttribute::QueryIntValue( int* value ) const 1023c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie{ 1024c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie if ( XMLUtil::ToInt( Value(), value )) 1025c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie return XML_NO_ERROR; 1026c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie return XML_WRONG_ATTRIBUTE_TYPE; 1027c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie} 1028c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie 1029c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie 1030c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xieint XMLAttribute::QueryUnsignedValue( unsigned int* value ) const 1031c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie{ 1032c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie if ( XMLUtil::ToUnsigned( Value(), value )) 1033c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie return XML_NO_ERROR; 1034c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie return XML_WRONG_ATTRIBUTE_TYPE; 1035c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie} 1036c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie 1037c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie 1038c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xieint XMLAttribute::QueryBoolValue( bool* value ) const 1039c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie{ 1040c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie if ( XMLUtil::ToBool( Value(), value )) { 1041c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie return XML_NO_ERROR; 1042c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie } 1043c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie return XML_WRONG_ATTRIBUTE_TYPE; 1044c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie} 1045c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie 1046c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie 1047c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xieint XMLAttribute::QueryFloatValue( float* value ) const 1048c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie{ 1049c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie if ( XMLUtil::ToFloat( Value(), value )) 1050c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie return XML_NO_ERROR; 1051c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie return XML_WRONG_ATTRIBUTE_TYPE; 1052c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie} 1053c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie 1054c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie 1055c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xieint XMLAttribute::QueryDoubleValue( double* value ) const 1056c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie{ 1057c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie if ( XMLUtil::ToDouble( Value(), value )) 1058c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie return XML_NO_ERROR; 1059c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie return XML_WRONG_ATTRIBUTE_TYPE; 1060c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie} 1061c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie 1062c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie 1063c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xievoid XMLAttribute::SetAttribute( const char* v ) 1064c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie{ 1065c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie value.SetStr( v ); 1066c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie} 1067c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie 1068c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie 1069c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xievoid XMLAttribute::SetAttribute( int v ) 1070c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie{ 1071c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie char buf[BUF_SIZE]; 1072c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie XMLUtil::ToStr( v, buf, BUF_SIZE ); 1073c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie value.SetStr( buf ); 1074c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie} 1075c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie 1076c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie 1077c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xievoid XMLAttribute::SetAttribute( unsigned v ) 1078c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie{ 1079c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie char buf[BUF_SIZE]; 1080c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie XMLUtil::ToStr( v, buf, BUF_SIZE ); 1081c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie value.SetStr( buf ); 1082c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie} 1083c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie 1084c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie 1085c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xievoid XMLAttribute::SetAttribute( bool v ) 1086c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie{ 1087c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie char buf[BUF_SIZE]; 1088c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie XMLUtil::ToStr( v, buf, BUF_SIZE ); 1089c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie value.SetStr( buf ); 1090c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie} 1091c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie 1092c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xievoid XMLAttribute::SetAttribute( double v ) 1093c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie{ 1094c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie char buf[BUF_SIZE]; 1095c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie XMLUtil::ToStr( v, buf, BUF_SIZE ); 1096c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie value.SetStr( buf ); 1097c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie} 1098c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie 1099c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xievoid XMLAttribute::SetAttribute( float v ) 1100c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie{ 1101c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie char buf[BUF_SIZE]; 1102c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie XMLUtil::ToStr( v, buf, BUF_SIZE ); 1103c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie value.SetStr( buf ); 1104c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie} 1105c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie 1106c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie 1107c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie// --------- XMLElement ---------- // 1108c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew XieXMLElement::XMLElement( XMLDocument* doc ) : XMLNode( doc ), 1109c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie closingType( 0 ), 1110c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie rootAttribute( 0 ) 1111c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie{ 1112c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie} 1113c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie 1114c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie 1115c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew XieXMLElement::~XMLElement() 1116c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie{ 1117c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie while( rootAttribute ) { 1118c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie XMLAttribute* next = rootAttribute->next; 1119c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie DELETE_ATTRIBUTE( rootAttribute ); 1120c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie rootAttribute = next; 1121c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie } 1122c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie} 1123c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie 1124c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie 1125c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew XieXMLAttribute* XMLElement::FindAttribute( const char* name ) 1126c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie{ 1127c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie XMLAttribute* a = 0; 1128c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie for( a=rootAttribute; a; a = a->next ) { 1129c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie if ( XMLUtil::StringEqual( a->Name(), name ) ) 1130c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie return a; 1131c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie } 1132c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie return 0; 1133c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie} 1134c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie 1135c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie 1136c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xieconst XMLAttribute* XMLElement::FindAttribute( const char* name ) const 1137c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie{ 1138c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie XMLAttribute* a = 0; 1139c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie for( a=rootAttribute; a; a = a->next ) { 1140c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie if ( XMLUtil::StringEqual( a->Name(), name ) ) 1141c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie return a; 1142c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie } 1143c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie return 0; 1144c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie} 1145c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie 1146c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie 1147c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xieconst char* XMLElement::Attribute( const char* name, const char* value ) const 1148c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie{ 1149c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie const XMLAttribute* a = FindAttribute( name ); 1150c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie if ( !a ) 1151c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie return 0; 1152c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie if ( !value || XMLUtil::StringEqual( a->Value(), value )) 1153c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie return a->Value(); 1154c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie return 0; 1155c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie} 1156c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie 1157c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie 1158c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xieconst char* XMLElement::GetText() const 1159c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie{ 1160c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie if ( FirstChild() && FirstChild()->ToText() ) { 1161c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie return FirstChild()->ToText()->Value(); 1162c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie } 1163c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie return 0; 1164c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie} 1165c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie 1166c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie 1167c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xieint XMLElement::QueryIntText( int* _value ) const 1168c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie{ 1169c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie if ( FirstChild() && FirstChild()->ToText() ) { 1170c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie const char* t = FirstChild()->ToText()->Value(); 1171c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie if ( XMLUtil::ToInt( t, _value ) ) { 1172c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie return XML_SUCCESS; 1173c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie } 1174c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie return XML_CAN_NOT_CONVERT_TEXT; 1175c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie } 1176c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie return XML_NO_TEXT_NODE; 1177c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie} 1178c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie 1179c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie 1180c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xieint XMLElement::QueryUnsignedText( unsigned* _value ) const 1181c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie{ 1182c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie if ( FirstChild() && FirstChild()->ToText() ) { 1183c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie const char* t = FirstChild()->ToText()->Value(); 1184c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie if ( XMLUtil::ToUnsigned( t, _value ) ) { 1185c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie return XML_SUCCESS; 1186c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie } 1187c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie return XML_CAN_NOT_CONVERT_TEXT; 1188c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie } 1189c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie return XML_NO_TEXT_NODE; 1190c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie} 1191c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie 1192c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie 1193c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xieint XMLElement::QueryBoolText( bool* _value ) const 1194c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie{ 1195c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie if ( FirstChild() && FirstChild()->ToText() ) { 1196c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie const char* t = FirstChild()->ToText()->Value(); 1197c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie if ( XMLUtil::ToBool( t, _value ) ) { 1198c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie return XML_SUCCESS; 1199c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie } 1200c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie return XML_CAN_NOT_CONVERT_TEXT; 1201c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie } 1202c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie return XML_NO_TEXT_NODE; 1203c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie} 1204c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie 1205c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie 1206c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xieint XMLElement::QueryDoubleText( double* _value ) const 1207c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie{ 1208c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie if ( FirstChild() && FirstChild()->ToText() ) { 1209c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie const char* t = FirstChild()->ToText()->Value(); 1210c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie if ( XMLUtil::ToDouble( t, _value ) ) { 1211c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie return XML_SUCCESS; 1212c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie } 1213c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie return XML_CAN_NOT_CONVERT_TEXT; 1214c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie } 1215c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie return XML_NO_TEXT_NODE; 1216c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie} 1217c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie 1218c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie 1219c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xieint XMLElement::QueryFloatText( float* _value ) const 1220c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie{ 1221c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie if ( FirstChild() && FirstChild()->ToText() ) { 1222c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie const char* t = FirstChild()->ToText()->Value(); 1223c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie if ( XMLUtil::ToFloat( t, _value ) ) { 1224c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie return XML_SUCCESS; 1225c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie } 1226c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie return XML_CAN_NOT_CONVERT_TEXT; 1227c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie } 1228c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie return XML_NO_TEXT_NODE; 1229c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie} 1230c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie 1231c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie 1232c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie 1233c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew XieXMLAttribute* XMLElement::FindOrCreateAttribute( const char* name ) 1234c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie{ 1235c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie XMLAttribute* last = 0; 1236c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie XMLAttribute* attrib = 0; 1237c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie for( attrib = rootAttribute; 1238c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie attrib; 1239c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie last = attrib, attrib = attrib->next ) 1240c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie { 1241c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie if ( XMLUtil::StringEqual( attrib->Name(), name ) ) { 1242c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie break; 1243c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie } 1244c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie } 1245c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie if ( !attrib ) { 1246c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie attrib = new (document->attributePool.Alloc() ) XMLAttribute(); 1247c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie attrib->memPool = &document->attributePool; 1248c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie if ( last ) { 1249c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie last->next = attrib; 1250c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie } 1251c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie else { 1252c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie rootAttribute = attrib; 1253c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie } 1254c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie attrib->SetName( name ); 1255c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie } 1256c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie return attrib; 1257c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie} 1258c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie 1259c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie 1260c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xievoid XMLElement::DeleteAttribute( const char* name ) 1261c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie{ 1262c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie XMLAttribute* prev = 0; 1263c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie for( XMLAttribute* a=rootAttribute; a; a=a->next ) { 1264c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie if ( XMLUtil::StringEqual( name, a->Name() ) ) { 1265c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie if ( prev ) { 1266c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie prev->next = a->next; 1267c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie } 1268c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie else { 1269c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie rootAttribute = a->next; 1270c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie } 1271c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie DELETE_ATTRIBUTE( a ); 1272c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie break; 1273c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie } 1274c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie prev = a; 1275c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie } 1276c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie} 1277c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie 1278c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie 1279c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xiechar* XMLElement::ParseAttributes( char* p ) 1280c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie{ 1281c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie const char* start = p; 1282c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie XMLAttribute* prevAttribute = 0; 1283c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie 1284c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie // Read the attributes. 1285c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie while( p ) { 1286c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie p = XMLUtil::SkipWhiteSpace( p ); 1287c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie if ( !p || !(*p) ) { 1288c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie document->SetError( XML_ERROR_PARSING_ELEMENT, start, Name() ); 1289c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie return 0; 1290c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie } 1291c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie 1292c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie // attribute. 1293c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie if ( XMLUtil::IsAlpha( *p ) ) { 1294c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie XMLAttribute* attrib = new (document->attributePool.Alloc() ) XMLAttribute(); 1295c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie attrib->memPool = &document->attributePool; 1296c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie 1297c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie p = attrib->ParseDeep( p, document->ProcessEntities() ); 1298c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie if ( !p || Attribute( attrib->Name() ) ) { 1299c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie DELETE_ATTRIBUTE( attrib ); 1300c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie document->SetError( XML_ERROR_PARSING_ATTRIBUTE, start, p ); 1301c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie return 0; 1302c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie } 1303c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie // There is a minor bug here: if the attribute in the source xml 1304c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie // document is duplicated, it will not be detected and the 1305c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie // attribute will be doubly added. However, tracking the 'prevAttribute' 1306c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie // avoids re-scanning the attribute list. Preferring performance for 1307c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie // now, may reconsider in the future. 1308c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie if ( prevAttribute ) { 1309c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie prevAttribute->next = attrib; 1310c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie } 1311c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie else { 1312c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie rootAttribute = attrib; 1313c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie } 1314c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie prevAttribute = attrib; 1315c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie } 1316c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie // end of the tag 1317c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie else if ( *p == '/' && *(p+1) == '>' ) { 1318c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie closingType = CLOSED; 1319c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie return p+2; // done; sealed element. 1320c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie } 1321c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie // end of the tag 1322c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie else if ( *p == '>' ) { 1323c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie ++p; 1324c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie break; 1325c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie } 1326c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie else { 1327c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie document->SetError( XML_ERROR_PARSING_ELEMENT, start, p ); 1328c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie return 0; 1329c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie } 1330c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie } 1331c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie return p; 1332c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie} 1333c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie 1334c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie 1335c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie// 1336c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie// <ele></ele> 1337c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie// <ele>foo<b>bar</b></ele> 1338c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie// 1339c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xiechar* XMLElement::ParseDeep( char* p, StrPair* strPair ) 1340c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie{ 1341c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie // Read the element name. 1342c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie p = XMLUtil::SkipWhiteSpace( p ); 1343c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie if ( !p ) return 0; 1344c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie 1345c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie // The closing element is the </element> form. It is 1346c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie // parsed just like a regular element then deleted from 1347c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie // the DOM. 1348c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie if ( *p == '/' ) { 1349c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie closingType = CLOSING; 1350c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie ++p; 1351c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie } 1352c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie 1353c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie p = value.ParseName( p ); 1354c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie if ( value.Empty() ) return 0; 1355c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie 1356c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie p = ParseAttributes( p ); 1357c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie if ( !p || !*p || closingType ) 1358c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie return p; 1359c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie 1360c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie p = XMLNode::ParseDeep( p, strPair ); 1361c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie return p; 1362c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie} 1363c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie 1364c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie 1365c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie 1366c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew XieXMLNode* XMLElement::ShallowClone( XMLDocument* doc ) const 1367c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie{ 1368c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie if ( !doc ) { 1369c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie doc = document; 1370c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie } 1371c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie XMLElement* element = doc->NewElement( Value() ); // fixme: this will always allocate memory. Intern? 1372c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie for( const XMLAttribute* a=FirstAttribute(); a; a=a->Next() ) { 1373c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie element->SetAttribute( a->Name(), a->Value() ); // fixme: this will always allocate memory. Intern? 1374c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie } 1375c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie return element; 1376c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie} 1377c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie 1378c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie 1379c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xiebool XMLElement::ShallowEqual( const XMLNode* compare ) const 1380c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie{ 1381c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie const XMLElement* other = compare->ToElement(); 1382c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie if ( other && XMLUtil::StringEqual( other->Value(), Value() )) { 1383c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie 1384c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie const XMLAttribute* a=FirstAttribute(); 1385c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie const XMLAttribute* b=other->FirstAttribute(); 1386c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie 1387c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie while ( a && b ) { 1388c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie if ( !XMLUtil::StringEqual( a->Value(), b->Value() ) ) { 1389c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie return false; 1390c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie } 1391c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie a = a->Next(); 1392c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie b = b->Next(); 1393c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie } 1394c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie if ( a || b ) { 1395c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie // different count 1396c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie return false; 1397c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie } 1398c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie return true; 1399c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie } 1400c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie return false; 1401c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie} 1402c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie 1403c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie 1404c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xiebool XMLElement::Accept( XMLVisitor* visitor ) const 1405c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie{ 1406c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie if ( visitor->VisitEnter( *this, rootAttribute ) ) 1407c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie { 1408c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie for ( const XMLNode* node=FirstChild(); node; node=node->NextSibling() ) 1409c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie { 1410c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie if ( !node->Accept( visitor ) ) 1411c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie break; 1412c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie } 1413c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie } 1414c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie return visitor->VisitExit( *this ); 1415c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie} 1416c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie 1417c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie 1418c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie// --------- XMLDocument ----------- // 1419c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew XieXMLDocument::XMLDocument( bool _processEntities ) : 1420c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie XMLNode( 0 ), 1421c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie writeBOM( false ), 1422c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie processEntities( _processEntities ), 1423c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie errorID( 0 ), 1424c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie errorStr1( 0 ), 1425c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie errorStr2( 0 ), 1426c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie charBuffer( 0 ) 1427c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie{ 1428c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie document = this; // avoid warning about 'this' in initializer list 1429c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie} 1430c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie 1431c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie 1432c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew XieXMLDocument::~XMLDocument() 1433c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie{ 1434c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie DeleteChildren(); 1435c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie delete [] charBuffer; 1436c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie 1437c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie#if 0 1438c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie textPool.Trace( "text" ); 1439c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie elementPool.Trace( "element" ); 1440c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie commentPool.Trace( "comment" ); 1441c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie attributePool.Trace( "attribute" ); 1442c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie#endif 1443c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie 1444c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie TIXMLASSERT( textPool.CurrentAllocs() == 0 ); 1445c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie TIXMLASSERT( elementPool.CurrentAllocs() == 0 ); 1446c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie TIXMLASSERT( commentPool.CurrentAllocs() == 0 ); 1447c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie TIXMLASSERT( attributePool.CurrentAllocs() == 0 ); 1448c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie} 1449c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie 1450c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie 1451c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xievoid XMLDocument::InitDocument() 1452c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie{ 1453c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie errorID = XML_NO_ERROR; 1454c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie errorStr1 = 0; 1455c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie errorStr2 = 0; 1456c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie 1457c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie delete [] charBuffer; 1458c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie charBuffer = 0; 1459c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie 1460c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie} 1461c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie 1462c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie 1463c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew XieXMLElement* XMLDocument::NewElement( const char* name ) 1464c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie{ 1465c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie XMLElement* ele = new (elementPool.Alloc()) XMLElement( this ); 1466c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie ele->memPool = &elementPool; 1467c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie ele->SetName( name ); 1468c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie return ele; 1469c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie} 1470c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie 1471c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie 1472c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew XieXMLComment* XMLDocument::NewComment( const char* str ) 1473c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie{ 1474c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie XMLComment* comment = new (commentPool.Alloc()) XMLComment( this ); 1475c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie comment->memPool = &commentPool; 1476c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie comment->SetValue( str ); 1477c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie return comment; 1478c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie} 1479c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie 1480c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie 1481c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew XieXMLText* XMLDocument::NewText( const char* str ) 1482c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie{ 1483c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie XMLText* text = new (textPool.Alloc()) XMLText( this ); 1484c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie text->memPool = &textPool; 1485c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie text->SetValue( str ); 1486c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie return text; 1487c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie} 1488c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie 1489c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie 1490c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew XieXMLDeclaration* XMLDocument::NewDeclaration( const char* str ) 1491c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie{ 1492c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie XMLDeclaration* dec = new (commentPool.Alloc()) XMLDeclaration( this ); 1493c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie dec->memPool = &commentPool; 1494c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie dec->SetValue( str ? str : "xml version=\"1.0\" encoding=\"UTF-8\"" ); 1495c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie return dec; 1496c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie} 1497c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie 1498c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie 1499c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew XieXMLUnknown* XMLDocument::NewUnknown( const char* str ) 1500c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie{ 1501c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie XMLUnknown* unk = new (commentPool.Alloc()) XMLUnknown( this ); 1502c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie unk->memPool = &commentPool; 1503c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie unk->SetValue( str ); 1504c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie return unk; 1505c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie} 1506c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie 1507c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie 1508c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xieint XMLDocument::LoadFile( const char* filename ) 1509c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie{ 1510c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie DeleteChildren(); 1511c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie InitDocument(); 1512c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie 1513c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie#if defined(_MSC_VER) 1514c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie#pragma warning ( push ) 1515c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie#pragma warning ( disable : 4996 ) // Fail to see a compelling reason why this should be deprecated. 1516c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie#endif 1517c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie FILE* fp = fopen( filename, "rb" ); 1518c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie#if defined(_MSC_VER) 1519c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie#pragma warning ( pop ) 1520c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie#endif 1521c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie if ( !fp ) { 1522c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie SetError( XML_ERROR_FILE_NOT_FOUND, filename, 0 ); 1523c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie return errorID; 1524c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie } 1525c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie LoadFile( fp ); 1526c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie fclose( fp ); 1527c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie return errorID; 1528c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie} 1529c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie 1530c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie 1531c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xieint XMLDocument::LoadFile( FILE* fp ) 1532c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie{ 1533c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie DeleteChildren(); 1534c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie InitDocument(); 1535c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie 1536c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie fseek( fp, 0, SEEK_END ); 1537c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie unsigned size = ftell( fp ); 1538c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie fseek( fp, 0, SEEK_SET ); 1539c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie 1540c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie if ( size == 0 ) { 1541c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie return errorID; 1542c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie } 1543c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie 1544c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie charBuffer = new char[size+1]; 1545c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie size_t read = fread( charBuffer, 1, size, fp ); 1546c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie if ( read != size ) { 1547c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie SetError( XML_ERROR_FILE_READ_ERROR, 0, 0 ); 1548c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie return errorID; 1549c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie } 1550c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie 1551c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie charBuffer[size] = 0; 1552c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie 1553c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie const char* p = charBuffer; 1554c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie p = XMLUtil::SkipWhiteSpace( p ); 1555c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie p = XMLUtil::ReadBOM( p, &writeBOM ); 1556c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie if ( !p || !*p ) { 1557c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie SetError( XML_ERROR_EMPTY_DOCUMENT, 0, 0 ); 1558c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie return errorID; 1559c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie } 1560c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie 1561c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie ParseDeep( charBuffer + (p-charBuffer), 0 ); 1562c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie return errorID; 1563c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie} 1564c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie 1565c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie 1566c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xieint XMLDocument::SaveFile( const char* filename ) 1567c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie{ 1568c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie#if defined(_MSC_VER) 1569c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie#pragma warning ( push ) 1570c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie#pragma warning ( disable : 4996 ) // Fail to see a compelling reason why this should be deprecated. 1571c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie#endif 1572c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie int fd = open(filename, O_RDWR|O_CREAT, 0644); 1573c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie FILE* fp = fdopen(fd, "w"); 1574c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie //FILE* fp = fopen( filename, "w" ); 1575c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie#if defined(_MSC_VER) 1576c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie#pragma warning ( pop ) 1577c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie#endif 1578c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie if ( !fp ) { 1579c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie SetError( XML_ERROR_FILE_COULD_NOT_BE_OPENED, filename, 0 ); 1580c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie return errorID; 1581c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie } 1582c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie SaveFile(fp); 1583c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie fclose( fp ); 1584c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie return errorID; 1585c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie} 1586c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie 1587c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie 1588c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xieint XMLDocument::SaveFile( FILE* fp ) 1589c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie{ 1590c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie XMLPrinter stream( fp ); 1591c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie Print( &stream ); 1592c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie return errorID; 1593c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie} 1594c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie 1595c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie 1596c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xieint XMLDocument::Parse( const char* p ) 1597c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie{ 1598c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie DeleteChildren(); 1599c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie InitDocument(); 1600c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie 1601c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie if ( !p || !*p ) { 1602c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie SetError( XML_ERROR_EMPTY_DOCUMENT, 0, 0 ); 1603c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie return errorID; 1604c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie } 1605c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie p = XMLUtil::SkipWhiteSpace( p ); 1606c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie p = XMLUtil::ReadBOM( p, &writeBOM ); 1607c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie if ( !p || !*p ) { 1608c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie SetError( XML_ERROR_EMPTY_DOCUMENT, 0, 0 ); 1609c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie return errorID; 1610c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie } 1611c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie 1612c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie size_t len = strlen( p ); 1613c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie charBuffer = new char[ len+1 ]; 1614c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie memcpy( charBuffer, p, len+1 ); 1615c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie 1616c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie 1617c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie ParseDeep( charBuffer, 0 ); 1618c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie return errorID; 1619c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie} 1620c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie 1621c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie 1622c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xievoid XMLDocument::Print( XMLPrinter* streamer ) 1623c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie{ 1624c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie XMLPrinter stdStreamer( stdout ); 1625c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie if ( !streamer ) 1626c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie streamer = &stdStreamer; 1627c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie Accept( streamer ); 1628c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie} 1629c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie 1630c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie 1631c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xievoid XMLDocument::SetError( int error, const char* str1, const char* str2 ) 1632c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie{ 1633c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie errorID = error; 1634c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie errorStr1 = str1; 1635c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie errorStr2 = str2; 1636c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie} 1637c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie 1638c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie 1639c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xievoid XMLDocument::PrintError() const 1640c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie{ 1641c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie if ( errorID ) { 1642c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie static const int LEN = 20; 1643c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie char buf1[LEN] = { 0 }; 1644c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie char buf2[LEN] = { 0 }; 1645c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie 1646c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie if ( errorStr1 ) { 1647c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie TIXML_SNPRINTF( buf1, LEN, "%s", errorStr1 ); 1648c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie } 1649c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie if ( errorStr2 ) { 1650c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie TIXML_SNPRINTF( buf2, LEN, "%s", errorStr2 ); 1651c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie } 1652c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie 1653c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie printf( "XMLDocument error id=%d str1=%s str2=%s\n", 1654c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie errorID, buf1, buf2 ); 1655c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie } 1656c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie} 1657c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie 1658c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie 1659c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew XieXMLPrinter::XMLPrinter( FILE* file, bool compact ) : 1660c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie elementJustOpened( false ), 1661c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie firstElement( true ), 1662c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie fp( file ), 1663c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie depth( 0 ), 1664c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie textDepth( -1 ), 1665c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie processEntities( true ), 1666c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie compactMode( compact ) 1667c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie{ 1668c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie for( int i=0; i<ENTITY_RANGE; ++i ) { 1669c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie entityFlag[i] = false; 1670c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie restrictedEntityFlag[i] = false; 1671c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie } 1672c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie for( int i=0; i<NUM_ENTITIES; ++i ) { 1673c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie TIXMLASSERT( entities[i].value < ENTITY_RANGE ); 1674c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie if ( entities[i].value < ENTITY_RANGE ) { 1675c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie entityFlag[ (int)entities[i].value ] = true; 1676c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie } 1677c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie } 1678c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie restrictedEntityFlag[(int)'&'] = true; 1679c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie restrictedEntityFlag[(int)'<'] = true; 1680c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie restrictedEntityFlag[(int)'>'] = true; // not required, but consistency is nice 1681c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie buffer.Push( 0 ); 1682c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie} 1683c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie 1684c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie 1685c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xievoid XMLPrinter::Print( const char* format, ... ) 1686c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie{ 1687c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie va_list va; 1688c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie va_start( va, format ); 1689c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie 1690c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie if ( fp ) { 1691c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie vfprintf( fp, format, va ); 1692c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie } 1693c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie else { 1694c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie // This seems brutally complex. Haven't figured out a better 1695c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie // way on windows. 1696c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie #ifdef _MSC_VER 1697c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie int len = -1; 1698c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie int expand = 1000; 1699c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie while ( len < 0 ) { 1700c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie len = vsnprintf_s( accumulator.Mem(), accumulator.Capacity(), _TRUNCATE, format, va ); 1701c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie if ( len < 0 ) { 1702c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie expand *= 3/2; 1703c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie accumulator.PushArr( expand ); 1704c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie } 1705c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie } 1706c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie char* p = buffer.PushArr( len ) - 1; 1707c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie memcpy( p, accumulator.Mem(), len+1 ); 1708c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie #else 1709c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie int len = vsnprintf( 0, 0, format, va ); 1710c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie // Close out and re-start the va-args 1711c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie va_end( va ); 1712c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie va_start( va, format ); 1713c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie char* p = buffer.PushArr( len ) - 1; 1714c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie vsnprintf( p, len+1, format, va ); 1715c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie #endif 1716c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie } 1717c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie va_end( va ); 1718c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie} 1719c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie 1720c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie 1721c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xievoid XMLPrinter::PrintSpace( int depth ) 1722c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie{ 1723c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie for( int i=0; i<depth; ++i ) { 1724c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie Print( " " ); 1725c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie } 1726c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie} 1727c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie 1728c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie 1729c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xievoid XMLPrinter::PrintString( const char* p, bool restricted ) 1730c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie{ 1731c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie // Look for runs of bytes between entities to print. 1732c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie const char* q = p; 1733c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie const bool* flag = restricted ? restrictedEntityFlag : entityFlag; 1734c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie 1735c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie if ( processEntities ) { 1736c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie while ( *q ) { 1737c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie // Remember, char is sometimes signed. (How many times has that bitten me?) 1738c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie if ( *q > 0 && *q < ENTITY_RANGE ) { 1739c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie // Check for entities. If one is found, flush 1740c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie // the stream up until the entity, write the 1741c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie // entity, and keep looking. 1742c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie if ( flag[(unsigned)(*q)] ) { 1743c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie while ( p < q ) { 1744c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie Print( "%c", *p ); 1745c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie ++p; 1746c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie } 1747c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie for( int i=0; i<NUM_ENTITIES; ++i ) { 1748c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie if ( entities[i].value == *q ) { 1749c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie Print( "&%s;", entities[i].pattern ); 1750c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie break; 1751c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie } 1752c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie } 1753c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie ++p; 1754c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie } 1755c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie } 1756c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie ++q; 1757c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie } 1758c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie } 1759c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie // Flush the remaining string. This will be the entire 1760c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie // string if an entity wasn't found. 1761c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie if ( !processEntities || (q-p > 0) ) { 1762c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie Print( "%s", p ); 1763c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie } 1764c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie} 1765c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie 1766c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie 1767c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xievoid XMLPrinter::PushHeader( bool writeBOM, bool writeDec ) 1768c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie{ 1769c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie static const unsigned char bom[] = { TIXML_UTF_LEAD_0, TIXML_UTF_LEAD_1, TIXML_UTF_LEAD_2, 0 }; 1770c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie if ( writeBOM ) { 1771c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie Print( "%s", bom ); 1772c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie } 1773c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie if ( writeDec ) { 1774c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie PushDeclaration( "xml version=\"1.0\"" ); 1775c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie } 1776c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie} 1777c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie 1778c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie 1779c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xievoid XMLPrinter::OpenElement( const char* name ) 1780c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie{ 1781c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie if ( elementJustOpened ) { 1782c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie SealElement(); 1783c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie } 1784c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie stack.Push( name ); 1785c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie 1786c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie if ( textDepth < 0 && !firstElement && !compactMode ) { 1787c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie Print( "\n" ); 1788c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie PrintSpace( depth ); 1789c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie } 1790c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie 1791c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie Print( "<%s", name ); 1792c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie elementJustOpened = true; 1793c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie firstElement = false; 1794c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie ++depth; 1795c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie} 1796c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie 1797c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie 1798c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xievoid XMLPrinter::PushAttribute( const char* name, const char* value ) 1799c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie{ 1800c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie TIXMLASSERT( elementJustOpened ); 1801c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie Print( " %s=\"", name ); 1802c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie PrintString( value, false ); 1803c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie Print( "\"" ); 1804c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie} 1805c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie 1806c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie 1807c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xievoid XMLPrinter::PushAttribute( const char* name, int v ) 1808c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie{ 1809c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie char buf[BUF_SIZE]; 1810c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie XMLUtil::ToStr( v, buf, BUF_SIZE ); 1811c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie PushAttribute( name, buf ); 1812c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie} 1813c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie 1814c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie 1815c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xievoid XMLPrinter::PushAttribute( const char* name, unsigned v ) 1816c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie{ 1817c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie char buf[BUF_SIZE]; 1818c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie XMLUtil::ToStr( v, buf, BUF_SIZE ); 1819c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie PushAttribute( name, buf ); 1820c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie} 1821c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie 1822c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie 1823c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xievoid XMLPrinter::PushAttribute( const char* name, bool v ) 1824c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie{ 1825c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie char buf[BUF_SIZE]; 1826c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie XMLUtil::ToStr( v, buf, BUF_SIZE ); 1827c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie PushAttribute( name, buf ); 1828c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie} 1829c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie 1830c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie 1831c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xievoid XMLPrinter::PushAttribute( const char* name, double v ) 1832c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie{ 1833c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie char buf[BUF_SIZE]; 1834c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie XMLUtil::ToStr( v, buf, BUF_SIZE ); 1835c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie PushAttribute( name, buf ); 1836c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie} 1837c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie 1838c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie 1839c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xievoid XMLPrinter::CloseElement() 1840c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie{ 1841c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie --depth; 1842c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie const char* name = stack.Pop(); 1843c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie 1844c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie if ( elementJustOpened ) { 1845c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie Print( "/>" ); 1846c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie } 1847c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie else { 1848c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie if ( textDepth < 0 && !compactMode) { 1849c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie Print( "\n" ); 1850c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie PrintSpace( depth ); 1851c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie } 1852c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie Print( "</%s>", name ); 1853c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie } 1854c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie 1855c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie if ( textDepth == depth ) 1856c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie textDepth = -1; 1857c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie if ( depth == 0 && !compactMode) 1858c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie Print( "\n" ); 1859c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie elementJustOpened = false; 1860c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie} 1861c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie 1862c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie 1863c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xievoid XMLPrinter::SealElement() 1864c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie{ 1865c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie elementJustOpened = false; 1866c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie Print( ">" ); 1867c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie} 1868c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie 1869c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie 1870c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xievoid XMLPrinter::PushText( const char* text, bool cdata ) 1871c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie{ 1872c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie textDepth = depth-1; 1873c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie 1874c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie if ( elementJustOpened ) { 1875c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie SealElement(); 1876c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie } 1877c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie if ( cdata ) { 1878c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie Print( "<![CDATA[" ); 1879c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie Print( "%s", text ); 1880c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie Print( "]]>" ); 1881c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie } 1882c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie else { 1883c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie PrintString( text, true ); 1884c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie } 1885c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie} 1886c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie 1887c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xievoid XMLPrinter::PushText( int value ) 1888c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie{ 1889c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie char buf[BUF_SIZE]; 1890c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie XMLUtil::ToStr( value, buf, BUF_SIZE ); 1891c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie PushText( buf, false ); 1892c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie} 1893c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie 1894c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie 1895c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xievoid XMLPrinter::PushText( unsigned value ) 1896c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie{ 1897c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie char buf[BUF_SIZE]; 1898c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie XMLUtil::ToStr( value, buf, BUF_SIZE ); 1899c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie PushText( buf, false ); 1900c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie} 1901c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie 1902c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie 1903c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xievoid XMLPrinter::PushText( bool value ) 1904c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie{ 1905c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie char buf[BUF_SIZE]; 1906c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie XMLUtil::ToStr( value, buf, BUF_SIZE ); 1907c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie PushText( buf, false ); 1908c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie} 1909c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie 1910c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie 1911c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xievoid XMLPrinter::PushText( float value ) 1912c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie{ 1913c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie char buf[BUF_SIZE]; 1914c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie XMLUtil::ToStr( value, buf, BUF_SIZE ); 1915c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie PushText( buf, false ); 1916c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie} 1917c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie 1918c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie 1919c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xievoid XMLPrinter::PushText( double value ) 1920c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie{ 1921c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie char buf[BUF_SIZE]; 1922c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie XMLUtil::ToStr( value, buf, BUF_SIZE ); 1923c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie PushText( buf, false ); 1924c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie} 1925c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie 1926c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie 1927c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xievoid XMLPrinter::PushComment( const char* comment ) 1928c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie{ 1929c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie if ( elementJustOpened ) { 1930c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie SealElement(); 1931c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie } 1932c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie if ( textDepth < 0 && !firstElement && !compactMode) { 1933c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie Print( "\n" ); 1934c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie PrintSpace( depth ); 1935c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie } 1936c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie firstElement = false; 1937c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie Print( "<!--%s-->", comment ); 1938c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie} 1939c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie 1940c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie 1941c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xievoid XMLPrinter::PushDeclaration( const char* value ) 1942c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie{ 1943c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie if ( elementJustOpened ) { 1944c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie SealElement(); 1945c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie } 1946c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie if ( textDepth < 0 && !firstElement && !compactMode) { 1947c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie Print( "\n" ); 1948c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie PrintSpace( depth ); 1949c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie } 1950c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie firstElement = false; 1951c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie Print( "<?%s?>", value ); 1952c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie} 1953c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie 1954c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie 1955c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xievoid XMLPrinter::PushUnknown( const char* value ) 1956c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie{ 1957c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie if ( elementJustOpened ) { 1958c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie SealElement(); 1959c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie } 1960c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie if ( textDepth < 0 && !firstElement && !compactMode) { 1961c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie Print( "\n" ); 1962c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie PrintSpace( depth ); 1963c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie } 1964c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie firstElement = false; 1965c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie Print( "<!%s>", value ); 1966c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie} 1967c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie 1968c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie 1969c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xiebool XMLPrinter::VisitEnter( const XMLDocument& doc ) 1970c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie{ 1971c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie processEntities = doc.ProcessEntities(); 1972c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie if ( doc.HasBOM() ) { 1973c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie PushHeader( true, false ); 1974c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie } 1975c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie return true; 1976c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie} 1977c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie 1978c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie 1979c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xiebool XMLPrinter::VisitEnter( const XMLElement& element, const XMLAttribute* attribute ) 1980c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie{ 1981c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie OpenElement( element.Name() ); 1982c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie while ( attribute ) { 1983c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie PushAttribute( attribute->Name(), attribute->Value() ); 1984c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie attribute = attribute->Next(); 1985c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie } 1986c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie return true; 1987c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie} 1988c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie 1989c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie 1990c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xiebool XMLPrinter::VisitExit( const XMLElement& ) 1991c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie{ 1992c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie CloseElement(); 1993c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie return true; 1994c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie} 1995c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie 1996c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie 1997c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xiebool XMLPrinter::Visit( const XMLText& text ) 1998c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie{ 1999c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie PushText( text.Value(), text.CData() ); 2000c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie return true; 2001c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie} 2002c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie 2003c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie 2004c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xiebool XMLPrinter::Visit( const XMLComment& comment ) 2005c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie{ 2006c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie PushComment( comment.Value() ); 2007c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie return true; 2008c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie} 2009c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie 2010c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xiebool XMLPrinter::Visit( const XMLDeclaration& declaration ) 2011c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie{ 2012c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie PushDeclaration( declaration.Value() ); 2013c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie return true; 2014c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie} 2015c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie 2016c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie 2017c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xiebool XMLPrinter::Visit( const XMLUnknown& unknown ) 2018c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie{ 2019c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie PushUnknown( unknown.Value() ); 2020c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie return true; 2021c74b546f5af36968ffa56d7fd4529f4273b96f48Matthew Xie} 2022