mirror of https://github.com/AxioDL/tinyxml2.git
added attribute handling. StrPair can now new/delete memory.
This commit is contained in:
parent
1ff38e0a5c
commit
1a1d4a72dd
239
tinyxml2.cpp
239
tinyxml2.cpp
|
@ -37,6 +37,85 @@ static const Entity entities[NUM_ENTITIES] =
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
|
StrPair::~StrPair()
|
||||||
|
{
|
||||||
|
Reset();
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void StrPair::Reset()
|
||||||
|
{
|
||||||
|
if ( flags & NEEDS_DELETE ) {
|
||||||
|
delete [] start;
|
||||||
|
}
|
||||||
|
flags = 0;
|
||||||
|
start = 0;
|
||||||
|
end = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void StrPair::SetStr( const char* str, int flags )
|
||||||
|
{
|
||||||
|
Reset();
|
||||||
|
size_t len = strlen( str );
|
||||||
|
start = new char[ len+1 ];
|
||||||
|
strncpy( start, str, len );
|
||||||
|
end = start + len;
|
||||||
|
this->flags = flags | NEEDS_DELETE;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
char* StrPair::ParseText( char* p, const char* endTag, int strFlags )
|
||||||
|
{
|
||||||
|
TIXMLASSERT( endTag && *endTag );
|
||||||
|
|
||||||
|
char* start = p; // fixme: hides a member
|
||||||
|
char endChar = *endTag;
|
||||||
|
int length = strlen( endTag );
|
||||||
|
|
||||||
|
// Inner loop of text parsing.
|
||||||
|
while ( *p ) {
|
||||||
|
if ( *p == endChar && strncmp( p, endTag, length ) == 0 ) {
|
||||||
|
Set( start, p, strFlags );
|
||||||
|
return p + length;
|
||||||
|
}
|
||||||
|
++p;
|
||||||
|
}
|
||||||
|
return p;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
char* StrPair::ParseName( char* p )
|
||||||
|
{
|
||||||
|
char* start = p;
|
||||||
|
|
||||||
|
start = p;
|
||||||
|
if ( !start || !(*start) ) {
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
if ( !XMLUtil::IsAlpha( *p ) ) {
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
while( *p && (
|
||||||
|
XMLUtil::IsAlphaNum( (unsigned char) *p )
|
||||||
|
|| *p == '_'
|
||||||
|
|| *p == '-'
|
||||||
|
|| *p == '.'
|
||||||
|
|| *p == ':' ))
|
||||||
|
{
|
||||||
|
++p;
|
||||||
|
}
|
||||||
|
|
||||||
|
if ( p > start ) {
|
||||||
|
Set( start, p, 0 );
|
||||||
|
return p;
|
||||||
|
}
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
const char* StrPair::GetStr()
|
const char* StrPair::GetStr()
|
||||||
{
|
{
|
||||||
if ( flags & NEEDS_FLUSH ) {
|
if ( flags & NEEDS_FLUSH ) {
|
||||||
|
@ -96,91 +175,15 @@ const char* StrPair::GetStr()
|
||||||
}
|
}
|
||||||
*q = 0;
|
*q = 0;
|
||||||
}
|
}
|
||||||
flags = 0;
|
flags = (flags & NEEDS_DELETE);
|
||||||
}
|
}
|
||||||
return start;
|
return start;
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
|
||||||
const char* StringPool::Intern( const char* str )
|
|
||||||
{
|
|
||||||
// Treat the array as a linear, inplace hash table.
|
|
||||||
// Nothing can get deleted, so that's handy.
|
|
||||||
if ( size > pool.Size()*3/4 ) {
|
|
||||||
DynArray< const char*, 20 > store;
|
|
||||||
for( int i=0; i<pool.Size(); ++i ) {
|
|
||||||
if ( pool[i] != 0 ) {
|
|
||||||
store.Push( pool[i] );
|
|
||||||
}
|
|
||||||
}
|
|
||||||
int newSize = pool.Size() * 2;
|
|
||||||
pool.PopArr( pool.Size() );
|
|
||||||
|
|
||||||
const char** mem = pool.PushArr( newSize );
|
|
||||||
memset( (void*)mem, 0, sizeof(char)*newSize );
|
|
||||||
|
|
||||||
while ( !store.Empty() ) {
|
|
||||||
Intern( store.Pop() );
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
*/
|
|
||||||
|
|
||||||
|
|
||||||
// --------- XMLUtil ----------- //
|
// --------- XMLUtil ----------- //
|
||||||
|
|
||||||
char* StrPair::ParseText( char* p, const char* endTag, int strFlags )
|
|
||||||
{
|
|
||||||
TIXMLASSERT( endTag && *endTag );
|
|
||||||
|
|
||||||
char* start = p;
|
|
||||||
char endChar = *endTag;
|
|
||||||
int length = strlen( endTag );
|
|
||||||
|
|
||||||
// Inner loop of text parsing.
|
|
||||||
while ( *p ) {
|
|
||||||
if ( *p == endChar && strncmp( p, endTag, length ) == 0 ) {
|
|
||||||
Set( start, p, strFlags );
|
|
||||||
return p + length;
|
|
||||||
}
|
|
||||||
++p;
|
|
||||||
}
|
|
||||||
return p;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
char* StrPair::ParseName( char* p )
|
|
||||||
{
|
|
||||||
char* start = p;
|
|
||||||
|
|
||||||
start = p;
|
|
||||||
if ( !start || !(*start) ) {
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
if ( !XMLUtil::IsAlpha( *p ) ) {
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
while( *p && (
|
|
||||||
XMLUtil::IsAlphaNum( (unsigned char) *p )
|
|
||||||
|| *p == '_'
|
|
||||||
|| *p == '-'
|
|
||||||
|| *p == '.'
|
|
||||||
|| *p == ':' ))
|
|
||||||
{
|
|
||||||
++p;
|
|
||||||
}
|
|
||||||
|
|
||||||
if ( p > start ) {
|
|
||||||
Set( start, p, 0 );
|
|
||||||
return p;
|
|
||||||
}
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
char* XMLDocument::Identify( char* p, XMLNode** node )
|
char* XMLDocument::Identify( char* p, XMLNode** node )
|
||||||
{
|
{
|
||||||
XMLNode* returnNode = 0;
|
XMLNode* returnNode = 0;
|
||||||
|
@ -290,6 +293,15 @@ XMLNode::~XMLNode()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void XMLNode::SetValue( const char* str, bool staticMem )
|
||||||
|
{
|
||||||
|
if ( staticMem )
|
||||||
|
value.SetInternedStr( str );
|
||||||
|
else
|
||||||
|
value.SetStr( str );
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
void XMLNode::ClearChildren()
|
void XMLNode::ClearChildren()
|
||||||
{
|
{
|
||||||
while( firstChild ) {
|
while( firstChild ) {
|
||||||
|
@ -606,19 +618,47 @@ int XMLAttribute::QueryFloatAttribute( float* value ) const
|
||||||
|
|
||||||
void XMLAttribute::SetAttribute( const char* v )
|
void XMLAttribute::SetAttribute( const char* v )
|
||||||
{
|
{
|
||||||
value.SetInternedStr( v );
|
value.SetStr( v );
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/*
|
|
||||||
void XMLAttribute::SetAttribute( int v )
|
void XMLAttribute::SetAttribute( int v )
|
||||||
{
|
{
|
||||||
char buf[BUF_SIZE];
|
char buf[BUF_SIZE];
|
||||||
TIXML_SNPRINTF( buf, BUF_SIZE-1, "%d" );
|
TIXML_SNPRINTF( buf, BUF_SIZE-1, "%d", v );
|
||||||
|
value.SetStr( buf );
|
||||||
value.SetInternedStr( v );
|
|
||||||
}
|
}
|
||||||
*/
|
|
||||||
|
|
||||||
|
void XMLAttribute::SetAttribute( unsigned v )
|
||||||
|
{
|
||||||
|
char buf[BUF_SIZE];
|
||||||
|
TIXML_SNPRINTF( buf, BUF_SIZE-1, "%u", v );
|
||||||
|
value.SetStr( buf );
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void XMLAttribute::SetAttribute( bool v )
|
||||||
|
{
|
||||||
|
char buf[BUF_SIZE];
|
||||||
|
TIXML_SNPRINTF( buf, BUF_SIZE-1, "%d", v ? 1 : 0 );
|
||||||
|
value.SetStr( buf );
|
||||||
|
}
|
||||||
|
|
||||||
|
void XMLAttribute::SetAttribute( double v )
|
||||||
|
{
|
||||||
|
char buf[BUF_SIZE];
|
||||||
|
TIXML_SNPRINTF( buf, BUF_SIZE-1, "%f", v );
|
||||||
|
value.SetStr( buf );
|
||||||
|
}
|
||||||
|
|
||||||
|
void XMLAttribute::SetAttribute( float v )
|
||||||
|
{
|
||||||
|
char buf[BUF_SIZE];
|
||||||
|
TIXML_SNPRINTF( buf, BUF_SIZE-1, "%f", v );
|
||||||
|
value.SetStr( buf );
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
// --------- XMLElement ---------- //
|
// --------- XMLElement ---------- //
|
||||||
XMLElement::XMLElement( XMLDocument* doc ) : XMLNode( doc ),
|
XMLElement::XMLElement( XMLDocument* doc ) : XMLNode( doc ),
|
||||||
|
@ -640,6 +680,39 @@ XMLElement::~XMLElement()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
XMLAttribute* XMLElement::FindAttribute( const char* name )
|
||||||
|
{
|
||||||
|
XMLAttribute* a = 0;
|
||||||
|
for( a=rootAttribute; a; a = a->next ) {
|
||||||
|
if ( XMLUtil::StringEqual( a->Name(), name ) )
|
||||||
|
return a;
|
||||||
|
}
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
const XMLAttribute* XMLElement::FindAttribute( const char* name ) const
|
||||||
|
{
|
||||||
|
XMLAttribute* a = 0;
|
||||||
|
for( a=rootAttribute; a; a = a->next ) {
|
||||||
|
if ( XMLUtil::StringEqual( a->Name(), name ) )
|
||||||
|
return a;
|
||||||
|
}
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
XMLAttribute* XMLElement::FindOrCreateAttribute( const char* name )
|
||||||
|
{
|
||||||
|
XMLAttribute* attrib = FindAttribute( name );
|
||||||
|
if ( !attrib ) {
|
||||||
|
attrib = new (document->attributePool.Alloc() ) XMLAttribute( this );
|
||||||
|
attrib->memPool = &document->attributePool;
|
||||||
|
}
|
||||||
|
return attrib;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
char* XMLElement::ParseAttributes( char* p, bool* closedElement )
|
char* XMLElement::ParseAttributes( char* p, bool* closedElement )
|
||||||
{
|
{
|
||||||
const char* start = p;
|
const char* start = p;
|
||||||
|
|
47
tinyxml2.h
47
tinyxml2.h
|
@ -101,20 +101,28 @@ public:
|
||||||
};
|
};
|
||||||
|
|
||||||
StrPair() : flags( 0 ), start( 0 ), end( 0 ) {}
|
StrPair() : flags( 0 ), start( 0 ), end( 0 ) {}
|
||||||
|
~StrPair();
|
||||||
|
|
||||||
void Set( char* start, char* end, int flags ) {
|
void Set( char* start, char* end, int flags ) {
|
||||||
|
Reset();
|
||||||
this->start = start; this->end = end; this->flags = flags | NEEDS_FLUSH;
|
this->start = start; this->end = end; this->flags = flags | NEEDS_FLUSH;
|
||||||
}
|
}
|
||||||
const char* GetStr();
|
const char* GetStr();
|
||||||
bool Empty() const { return start == end; }
|
bool Empty() const { return start == end; }
|
||||||
|
|
||||||
void SetInternedStr( const char* str ) { this->start = (char*) str; this->end = 0; this->flags = 0; }
|
void SetInternedStr( const char* str ) { Reset(); this->start = (char*) str; }
|
||||||
|
void SetStr( const char* str, int flags=0 );
|
||||||
|
|
||||||
char* ParseText( char* in, const char* endTag, int strFlags );
|
char* ParseText( char* in, const char* endTag, int strFlags );
|
||||||
char* ParseName( char* in );
|
char* ParseName( char* in );
|
||||||
|
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
void Reset();
|
||||||
|
|
||||||
enum {
|
enum {
|
||||||
NEEDS_FLUSH = 0x100
|
NEEDS_FLUSH = 0x100,
|
||||||
|
NEEDS_DELETE = 0x200
|
||||||
};
|
};
|
||||||
|
|
||||||
// After parsing, if *end != 0, it can be set to zero.
|
// After parsing, if *end != 0, it can be set to zero.
|
||||||
|
@ -363,7 +371,7 @@ public:
|
||||||
virtual const XMLUnknown* ToUnknown() const { return 0; }
|
virtual const XMLUnknown* ToUnknown() const { return 0; }
|
||||||
|
|
||||||
const char* Value() const { return value.GetStr(); }
|
const char* Value() const { return value.GetStr(); }
|
||||||
void SetValue( const char* val ) { value.SetInternedStr( val ); }
|
void SetValue( const char* val, bool staticMem=false );
|
||||||
|
|
||||||
const XMLNode* Parent() const { return parent; }
|
const XMLNode* Parent() const { return parent; }
|
||||||
XMLNode* Parent() { return parent; }
|
XMLNode* Parent() { return parent; }
|
||||||
|
@ -548,16 +556,14 @@ public:
|
||||||
int QueryFloatAttribute( float* value ) const;
|
int QueryFloatAttribute( float* value ) const;
|
||||||
|
|
||||||
void SetAttribute( const char* value );
|
void SetAttribute( const char* value );
|
||||||
|
|
||||||
// NOTE: other sets aren't supported...need to deal with memory model?
|
|
||||||
/*
|
|
||||||
void SetAttribute( int value );
|
void SetAttribute( int value );
|
||||||
void SetAttribute( unsigned value );
|
void SetAttribute( unsigned value );
|
||||||
void SetAttribute( bool value );
|
void SetAttribute( bool value );
|
||||||
void SetAttribute( double value );
|
void SetAttribute( double value );
|
||||||
*/
|
void SetAttribute( float value );
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
enum { BUF_SIZE = 200 };
|
||||||
XMLAttribute( XMLElement* element ) : next( 0 ) {}
|
XMLAttribute( XMLElement* element ) : next( 0 ) {}
|
||||||
virtual ~XMLAttribute() {}
|
virtual ~XMLAttribute() {}
|
||||||
XMLAttribute( const XMLAttribute& ); // not supported
|
XMLAttribute( const XMLAttribute& ); // not supported
|
||||||
|
@ -578,29 +584,30 @@ class XMLElement : public XMLNode
|
||||||
friend class XMLDocument;
|
friend class XMLDocument;
|
||||||
public:
|
public:
|
||||||
const char* Name() const { return Value(); }
|
const char* Name() const { return Value(); }
|
||||||
void SetName( const char* str ) { SetValue( str ); }
|
void SetName( const char* str, bool staticMem=false ) { SetValue( str, staticMem ); }
|
||||||
|
|
||||||
virtual XMLElement* ToElement() { return this; }
|
virtual XMLElement* ToElement() { return this; }
|
||||||
virtual const XMLElement* ToElement() const { return this; }
|
virtual const XMLElement* ToElement() const { return this; }
|
||||||
virtual bool Accept( XMLVisitor* visitor ) const;
|
virtual bool Accept( XMLVisitor* visitor ) const;
|
||||||
|
|
||||||
const char* Attribute( const char* name ) const;
|
const char* Attribute( const char* name ) const { const XMLAttribute* a = FindAttribute( name ); if ( !a ) return 0; return a->Value(); }
|
||||||
|
|
||||||
int QueryIntAttribute( const char* name, int* value ) const;
|
int QueryIntAttribute( const char* name, int* value ) const { const XMLAttribute* a = FindAttribute( name ); if ( !a ) return NO_ATTRIBUTE; return a->QueryIntAttribute( value ); }
|
||||||
int QueryUnsignedAttribute( const char* name, unsigned int* value ) const;
|
int QueryUnsignedAttribute( const char* name, unsigned int* value ) const { const XMLAttribute* a = FindAttribute( name ); if ( !a ) return NO_ATTRIBUTE; return a->QueryUnsignedAttribute( value ); }
|
||||||
int QueryBoolAttribute( const char* name, bool* value ) const;
|
int QueryBoolAttribute( const char* name, bool* value ) const { const XMLAttribute* a = FindAttribute( name ); if ( !a ) return NO_ATTRIBUTE; return a->QueryBoolAttribute( value ); }
|
||||||
int QueryDoubleAttribute( const char* name, double* _value ) const;
|
int QueryDoubleAttribute( const char* name, double* value ) const { const XMLAttribute* a = FindAttribute( name ); if ( !a ) return NO_ATTRIBUTE; return a->QueryDoubleAttribute( value ); }
|
||||||
int QueryFloatAttribute( const char* name, float* _value ) const;
|
int QueryFloatAttribute( const char* name, float* value ) const { const XMLAttribute* a = FindAttribute( name ); if ( !a ) return NO_ATTRIBUTE; return a->QueryFloatAttribute( value ); }
|
||||||
|
|
||||||
void SetAttribute( const char* name, const char* value );
|
void SetAttribute( const char* name, const char* value ) { XMLAttribute* a = FindOrCreateAttribute( name ); a->SetAttribute( value ); }
|
||||||
void SetAttribute( const char* name, int value );
|
void SetAttribute( const char* name, int value ) { XMLAttribute* a = FindOrCreateAttribute( name ); a->SetAttribute( value ); }
|
||||||
void SetAttribute( const char* name, unsigned value );
|
void SetAttribute( const char* name, unsigned value ) { XMLAttribute* a = FindOrCreateAttribute( name ); a->SetAttribute( value ); }
|
||||||
void SetAttribute( const char* name, bool value );
|
void SetAttribute( const char* name, bool value ) { XMLAttribute* a = FindOrCreateAttribute( name ); a->SetAttribute( value ); }
|
||||||
void SetAttribute( const char* name, double value );
|
void SetAttribute( const char* name, double value ) { XMLAttribute* a = FindOrCreateAttribute( name ); a->SetAttribute( value ); }
|
||||||
|
|
||||||
void RemoveAttribute( const char* name );
|
void RemoveAttribute( const char* name );
|
||||||
|
|
||||||
const XMLAttribute* FirstAttribute() const { return rootAttribute; }
|
const XMLAttribute* FirstAttribute() const { return rootAttribute; }
|
||||||
|
const XMLAttribute* FindAttribute( const char* name ) const;
|
||||||
|
|
||||||
const char* GetText() const;
|
const char* GetText() const;
|
||||||
|
|
||||||
|
@ -614,6 +621,8 @@ private:
|
||||||
XMLElement( const XMLElement& ); // not supported
|
XMLElement( const XMLElement& ); // not supported
|
||||||
void operator=( const XMLElement& ); // not supported
|
void operator=( const XMLElement& ); // not supported
|
||||||
|
|
||||||
|
XMLAttribute* FindAttribute( const char* name );
|
||||||
|
XMLAttribute* FindOrCreateAttribute( const char* name );
|
||||||
char* ParseAttributes( char* p, bool *closedElement );
|
char* ParseAttributes( char* p, bool *closedElement );
|
||||||
|
|
||||||
bool closing;
|
bool closing;
|
||||||
|
|
Loading…
Reference in New Issue