indent classes, align by spaces
This commit is contained in:
@@ -28,32 +28,32 @@
|
||||
class XMLAttrVisitor
|
||||
{
|
||||
public:
|
||||
virtual void visit( const char* name, const char* value ) = 0;
|
||||
virtual void visit( const char* name, const char* value ) = 0;
|
||||
};
|
||||
|
||||
class XMLElement
|
||||
{
|
||||
public:
|
||||
virtual const char* name() const = 0;
|
||||
virtual const char* attribute( const char* name ) const = 0;
|
||||
virtual void forEachAttribute( XMLAttrVisitor& visitor ) const = 0;
|
||||
virtual const char* name() const = 0;
|
||||
virtual const char* attribute( const char* name ) const = 0;
|
||||
virtual void forEachAttribute( XMLAttrVisitor& visitor ) const = 0;
|
||||
};
|
||||
|
||||
class XMLImporter : public TextOutputStream
|
||||
{
|
||||
public:
|
||||
STRING_CONSTANT( Name, "XMLImporter" );
|
||||
STRING_CONSTANT( Name, "XMLImporter" );
|
||||
|
||||
virtual void pushElement( const XMLElement& element ) = 0;
|
||||
virtual void popElement( const char* name ) = 0;
|
||||
virtual void pushElement( const XMLElement& element ) = 0;
|
||||
virtual void popElement( const char* name ) = 0;
|
||||
};
|
||||
|
||||
class XMLExporter
|
||||
{
|
||||
public:
|
||||
STRING_CONSTANT( Name, "XMLExporter" );
|
||||
STRING_CONSTANT( Name, "XMLExporter" );
|
||||
|
||||
virtual void exportXML( XMLImporter& importer ) = 0;
|
||||
virtual void exportXML( XMLImporter& importer ) = 0;
|
||||
};
|
||||
|
||||
|
||||
|
||||
@@ -31,69 +31,69 @@
|
||||
/// copied and must stay valid for the lifetime of the instance.
|
||||
class StaticElement : public XMLElement
|
||||
{
|
||||
typedef std::map<const char*, const char*, RawStringLess> attrs_t;
|
||||
typedef std::map<const char*, const char*, RawStringLess> attrs_t;
|
||||
public:
|
||||
StaticElement( const char* name )
|
||||
: m_name( name ){
|
||||
}
|
||||
void insertAttribute( const char* name, const char* value ){
|
||||
m_attrs.insert( attrs_t::value_type( name, value ) );
|
||||
}
|
||||
const char* name() const {
|
||||
return m_name;
|
||||
}
|
||||
const char* attribute( const char* name ) const {
|
||||
attrs_t::const_iterator i = m_attrs.find( name );
|
||||
if ( i != m_attrs.end() ) {
|
||||
return i->second;
|
||||
StaticElement( const char* name )
|
||||
: m_name( name ){
|
||||
}
|
||||
else{
|
||||
return "";
|
||||
void insertAttribute( const char* name, const char* value ){
|
||||
m_attrs.insert( attrs_t::value_type( name, value ) );
|
||||
}
|
||||
}
|
||||
void forEachAttribute( XMLAttrVisitor& visitor ) const {
|
||||
for ( attrs_t::const_iterator i = m_attrs.begin(); i != m_attrs.end(); ++i )
|
||||
{
|
||||
visitor.visit( i->first, i->second );
|
||||
const char* name() const {
|
||||
return m_name;
|
||||
}
|
||||
const char* attribute( const char* name ) const {
|
||||
attrs_t::const_iterator i = m_attrs.find( name );
|
||||
if ( i != m_attrs.end() ) {
|
||||
return i->second;
|
||||
}
|
||||
else{
|
||||
return "";
|
||||
}
|
||||
}
|
||||
void forEachAttribute( XMLAttrVisitor& visitor ) const {
|
||||
for ( attrs_t::const_iterator i = m_attrs.begin(); i != m_attrs.end(); ++i )
|
||||
{
|
||||
visitor.visit( i->first, i->second );
|
||||
}
|
||||
}
|
||||
}
|
||||
private:
|
||||
const char* m_name;
|
||||
attrs_t m_attrs;
|
||||
const char* m_name;
|
||||
attrs_t m_attrs;
|
||||
};
|
||||
|
||||
///\brief All string pointers passed to an instance of this class are copied.
|
||||
class DynamicElement : public XMLElement
|
||||
{
|
||||
typedef std::map<CopiedString, CopiedString> attrs_t;
|
||||
typedef std::map<CopiedString, CopiedString> attrs_t;
|
||||
public:
|
||||
DynamicElement( const char* name )
|
||||
: m_name( name ){
|
||||
}
|
||||
void insertAttribute( const char* name, const char* value ){
|
||||
m_attrs.insert( attrs_t::value_type( name, value ) );
|
||||
}
|
||||
const char* name() const {
|
||||
return m_name.c_str();
|
||||
}
|
||||
const char* attribute( const char* name ) const {
|
||||
attrs_t::const_iterator i = m_attrs.find( name );
|
||||
if ( i != m_attrs.end() ) {
|
||||
return i->second.c_str();
|
||||
DynamicElement( const char* name )
|
||||
: m_name( name ){
|
||||
}
|
||||
else{
|
||||
return "";
|
||||
void insertAttribute( const char* name, const char* value ){
|
||||
m_attrs.insert( attrs_t::value_type( name, value ) );
|
||||
}
|
||||
}
|
||||
void forEachAttribute( XMLAttrVisitor& visitor ) const {
|
||||
for ( attrs_t::const_iterator i = m_attrs.begin(); i != m_attrs.end(); ++i )
|
||||
{
|
||||
visitor.visit( i->first.c_str(), i->second.c_str() );
|
||||
const char* name() const {
|
||||
return m_name.c_str();
|
||||
}
|
||||
const char* attribute( const char* name ) const {
|
||||
attrs_t::const_iterator i = m_attrs.find( name );
|
||||
if ( i != m_attrs.end() ) {
|
||||
return i->second.c_str();
|
||||
}
|
||||
else{
|
||||
return "";
|
||||
}
|
||||
}
|
||||
void forEachAttribute( XMLAttrVisitor& visitor ) const {
|
||||
for ( attrs_t::const_iterator i = m_attrs.begin(); i != m_attrs.end(); ++i )
|
||||
{
|
||||
visitor.visit( i->first.c_str(), i->second.c_str() );
|
||||
}
|
||||
}
|
||||
}
|
||||
private:
|
||||
CopiedString m_name;
|
||||
attrs_t m_attrs;
|
||||
CopiedString m_name;
|
||||
attrs_t m_attrs;
|
||||
};
|
||||
|
||||
#endif
|
||||
|
||||
@@ -33,34 +33,34 @@ class TextInputStream;
|
||||
class SAXElement : public XMLElement
|
||||
{
|
||||
public:
|
||||
SAXElement( const char* name, const char** atts )
|
||||
: m_name( name ), m_atts( atts ){
|
||||
}
|
||||
const char* name() const {
|
||||
return m_name;
|
||||
}
|
||||
const char* attribute( const char* name ) const {
|
||||
if ( m_atts != 0 ) {
|
||||
for ( const char** att = m_atts; *att != 0; att += 2 )
|
||||
{
|
||||
if ( strcmp( *att, name ) == 0 ) {
|
||||
return *( ++att );
|
||||
SAXElement( const char* name, const char** atts )
|
||||
: m_name( name ), m_atts( atts ){
|
||||
}
|
||||
const char* name() const {
|
||||
return m_name;
|
||||
}
|
||||
const char* attribute( const char* name ) const {
|
||||
if ( m_atts != 0 ) {
|
||||
for ( const char** att = m_atts; *att != 0; att += 2 )
|
||||
{
|
||||
if ( strcmp( *att, name ) == 0 ) {
|
||||
return *( ++att );
|
||||
}
|
||||
}
|
||||
}
|
||||
return "";
|
||||
}
|
||||
void forEachAttribute( XMLAttrVisitor& visitor ) const {
|
||||
if ( m_atts != 0 ) {
|
||||
for ( const char** att = m_atts; *att != 0; att += 2 )
|
||||
{
|
||||
visitor.visit( *att, *( att + 1 ) );
|
||||
}
|
||||
}
|
||||
}
|
||||
return "";
|
||||
}
|
||||
void forEachAttribute( XMLAttrVisitor& visitor ) const {
|
||||
if ( m_atts != 0 ) {
|
||||
for ( const char** att = m_atts; *att != 0; att += 2 )
|
||||
{
|
||||
visitor.visit( *att, *( att + 1 ) );
|
||||
}
|
||||
}
|
||||
}
|
||||
private:
|
||||
const char* m_name;
|
||||
const char** m_atts;
|
||||
const char* m_name;
|
||||
const char** m_atts;
|
||||
};
|
||||
|
||||
#include <stdarg.h>
|
||||
@@ -68,25 +68,25 @@ const char** m_atts;
|
||||
class FormattedVA
|
||||
{
|
||||
public:
|
||||
const char* m_format;
|
||||
va_list& m_arguments;
|
||||
FormattedVA( const char* format, va_list& m_arguments )
|
||||
: m_format( format ), m_arguments( m_arguments ){
|
||||
}
|
||||
const char* m_format;
|
||||
va_list& m_arguments;
|
||||
FormattedVA( const char* format, va_list& m_arguments )
|
||||
: m_format( format ), m_arguments( m_arguments ){
|
||||
}
|
||||
};
|
||||
|
||||
class Formatted
|
||||
{
|
||||
public:
|
||||
const char* m_format;
|
||||
mutable va_list m_arguments;
|
||||
Formatted( const char* format, ... )
|
||||
: m_format( format ){
|
||||
va_start( m_arguments, format );
|
||||
}
|
||||
~Formatted(){
|
||||
va_end( m_arguments );
|
||||
}
|
||||
const char* m_format;
|
||||
mutable va_list m_arguments;
|
||||
Formatted( const char* format, ... )
|
||||
: m_format( format ){
|
||||
va_start( m_arguments, format );
|
||||
}
|
||||
~Formatted(){
|
||||
va_end( m_arguments );
|
||||
}
|
||||
};
|
||||
|
||||
#ifdef _MSC_VER
|
||||
@@ -111,107 +111,107 @@ inline TextOutputStreamType& ostream_write( TextOutputStreamType& ostream, const
|
||||
|
||||
class XMLSAXImporter
|
||||
{
|
||||
XMLImporter& m_importer;
|
||||
xmlSAXHandler m_sax;
|
||||
XMLImporter& m_importer;
|
||||
xmlSAXHandler m_sax;
|
||||
|
||||
static void startElement( void *user_data, const xmlChar *name, const xmlChar **atts ){
|
||||
SAXElement element( reinterpret_cast<const char*>( name ), reinterpret_cast<const char**>( atts ) );
|
||||
reinterpret_cast<XMLSAXImporter*>( user_data )->m_importer.pushElement( element );
|
||||
}
|
||||
static void endElement( void *user_data, const xmlChar *name ){
|
||||
reinterpret_cast<XMLSAXImporter*>( user_data )->m_importer.popElement( reinterpret_cast<const char*>( name ) );
|
||||
}
|
||||
static void characters( void *user_data, const xmlChar *ch, int len ){
|
||||
reinterpret_cast<XMLSAXImporter*>( user_data )->m_importer
|
||||
<< StringRange( reinterpret_cast<const char*>( ch ), reinterpret_cast<const char*>( ch + len ) );
|
||||
}
|
||||
static void startElement( void *user_data, const xmlChar *name, const xmlChar **atts ){
|
||||
SAXElement element( reinterpret_cast<const char*>( name ), reinterpret_cast<const char**>( atts ) );
|
||||
reinterpret_cast<XMLSAXImporter*>( user_data )->m_importer.pushElement( element );
|
||||
}
|
||||
static void endElement( void *user_data, const xmlChar *name ){
|
||||
reinterpret_cast<XMLSAXImporter*>( user_data )->m_importer.popElement( reinterpret_cast<const char*>( name ) );
|
||||
}
|
||||
static void characters( void *user_data, const xmlChar *ch, int len ){
|
||||
reinterpret_cast<XMLSAXImporter*>( user_data )->m_importer
|
||||
<< StringRange( reinterpret_cast<const char*>( ch ), reinterpret_cast<const char*>( ch + len ) );
|
||||
}
|
||||
|
||||
static void warning( void *user_data, const char *msg, ... ){
|
||||
va_list args;
|
||||
va_start( args, msg );
|
||||
globalWarningStream() << "XML WARNING: " << FormattedVA( msg, args );
|
||||
va_end( args );
|
||||
}
|
||||
static void error( void *user_data, const char *msg, ... ){
|
||||
va_list args;
|
||||
va_start( args, msg );
|
||||
globalErrorStream() << "XML ERROR: " << FormattedVA( msg, args );
|
||||
va_end( args );
|
||||
}
|
||||
static void warning( void *user_data, const char *msg, ... ){
|
||||
va_list args;
|
||||
va_start( args, msg );
|
||||
globalWarningStream() << "XML WARNING: " << FormattedVA( msg, args );
|
||||
va_end( args );
|
||||
}
|
||||
static void error( void *user_data, const char *msg, ... ){
|
||||
va_list args;
|
||||
va_start( args, msg );
|
||||
globalErrorStream() << "XML ERROR: " << FormattedVA( msg, args );
|
||||
va_end( args );
|
||||
}
|
||||
|
||||
public:
|
||||
XMLSAXImporter( XMLImporter& importer ) : m_importer( importer ){
|
||||
m_sax.internalSubset = 0;
|
||||
m_sax.isStandalone = 0;
|
||||
m_sax.hasInternalSubset = 0;
|
||||
m_sax.hasExternalSubset = 0;
|
||||
m_sax.resolveEntity = 0;
|
||||
m_sax.getEntity = 0;
|
||||
m_sax.entityDecl = 0;
|
||||
m_sax.notationDecl = 0;
|
||||
m_sax.attributeDecl = 0;
|
||||
m_sax.elementDecl = 0;
|
||||
m_sax.unparsedEntityDecl = 0;
|
||||
m_sax.setDocumentLocator = 0;
|
||||
m_sax.startDocument = 0;
|
||||
m_sax.endDocument = 0;
|
||||
m_sax.startElement = startElement;
|
||||
m_sax.endElement = endElement;
|
||||
m_sax.reference = 0;
|
||||
m_sax.characters = characters;
|
||||
m_sax.ignorableWhitespace = 0;
|
||||
m_sax.processingInstruction = 0;
|
||||
m_sax.comment = 0;
|
||||
m_sax.warning = warning;
|
||||
m_sax.error = error;
|
||||
m_sax.fatalError = 0;
|
||||
m_sax.getParameterEntity = 0;
|
||||
m_sax.cdataBlock = 0;
|
||||
m_sax.externalSubset = 0;
|
||||
m_sax.initialized = 1;
|
||||
}
|
||||
XMLSAXImporter( XMLImporter& importer ) : m_importer( importer ){
|
||||
m_sax.internalSubset = 0;
|
||||
m_sax.isStandalone = 0;
|
||||
m_sax.hasInternalSubset = 0;
|
||||
m_sax.hasExternalSubset = 0;
|
||||
m_sax.resolveEntity = 0;
|
||||
m_sax.getEntity = 0;
|
||||
m_sax.entityDecl = 0;
|
||||
m_sax.notationDecl = 0;
|
||||
m_sax.attributeDecl = 0;
|
||||
m_sax.elementDecl = 0;
|
||||
m_sax.unparsedEntityDecl = 0;
|
||||
m_sax.setDocumentLocator = 0;
|
||||
m_sax.startDocument = 0;
|
||||
m_sax.endDocument = 0;
|
||||
m_sax.startElement = startElement;
|
||||
m_sax.endElement = endElement;
|
||||
m_sax.reference = 0;
|
||||
m_sax.characters = characters;
|
||||
m_sax.ignorableWhitespace = 0;
|
||||
m_sax.processingInstruction = 0;
|
||||
m_sax.comment = 0;
|
||||
m_sax.warning = warning;
|
||||
m_sax.error = error;
|
||||
m_sax.fatalError = 0;
|
||||
m_sax.getParameterEntity = 0;
|
||||
m_sax.cdataBlock = 0;
|
||||
m_sax.externalSubset = 0;
|
||||
m_sax.initialized = 1;
|
||||
}
|
||||
|
||||
xmlSAXHandler* callbacks(){
|
||||
return &m_sax;
|
||||
}
|
||||
void* context(){
|
||||
return this;
|
||||
}
|
||||
xmlSAXHandler* callbacks(){
|
||||
return &m_sax;
|
||||
}
|
||||
void* context(){
|
||||
return this;
|
||||
}
|
||||
};
|
||||
|
||||
class XMLStreamParser : public XMLExporter
|
||||
{
|
||||
enum unnamed0 { BUFSIZE = 1024 };
|
||||
enum unnamed0 { BUFSIZE = 1024 };
|
||||
public:
|
||||
XMLStreamParser( TextInputStream& istream )
|
||||
: m_istream( istream ){
|
||||
}
|
||||
virtual void exportXML( XMLImporter& importer ){
|
||||
//bool wellFormed = false;
|
||||
|
||||
char chars[BUFSIZE];
|
||||
std::size_t res = m_istream.read( chars, 4 );
|
||||
if ( res > 0 ) {
|
||||
XMLSAXImporter sax( importer );
|
||||
|
||||
xmlParserCtxtPtr ctxt = xmlCreatePushParserCtxt( sax.callbacks(), sax.context(), chars, static_cast<int>( res ), 0 );
|
||||
ctxt->replaceEntities = 1;
|
||||
|
||||
while ( ( res = m_istream.read( chars, BUFSIZE ) ) > 0 )
|
||||
{
|
||||
xmlParseChunk( ctxt, chars, static_cast<int>( res ), 0 );
|
||||
}
|
||||
xmlParseChunk( ctxt, chars, 0, 1 );
|
||||
|
||||
//wellFormed = ( ctxt->wellFormed == 1 );
|
||||
|
||||
xmlFreeParserCtxt( ctxt );
|
||||
XMLStreamParser( TextInputStream& istream )
|
||||
: m_istream( istream ){
|
||||
}
|
||||
virtual void exportXML( XMLImporter& importer ){
|
||||
//bool wellFormed = false;
|
||||
|
||||
//return wellFormed;
|
||||
}
|
||||
char chars[BUFSIZE];
|
||||
std::size_t res = m_istream.read( chars, 4 );
|
||||
if ( res > 0 ) {
|
||||
XMLSAXImporter sax( importer );
|
||||
|
||||
xmlParserCtxtPtr ctxt = xmlCreatePushParserCtxt( sax.callbacks(), sax.context(), chars, static_cast<int>( res ), 0 );
|
||||
ctxt->replaceEntities = 1;
|
||||
|
||||
while ( ( res = m_istream.read( chars, BUFSIZE ) ) > 0 )
|
||||
{
|
||||
xmlParseChunk( ctxt, chars, static_cast<int>( res ), 0 );
|
||||
}
|
||||
xmlParseChunk( ctxt, chars, 0, 1 );
|
||||
|
||||
//wellFormed = ( ctxt->wellFormed == 1 );
|
||||
|
||||
xmlFreeParserCtxt( ctxt );
|
||||
}
|
||||
|
||||
//return wellFormed;
|
||||
}
|
||||
private:
|
||||
TextInputStream& m_istream;
|
||||
TextInputStream& m_istream;
|
||||
};
|
||||
|
||||
|
||||
|
||||
@@ -52,52 +52,52 @@ enum TextureType
|
||||
class XmlTagBuilder
|
||||
{
|
||||
private:
|
||||
CopiedString m_savefilename;
|
||||
xmlDocPtr doc;
|
||||
xmlXPathContextPtr context;
|
||||
CopiedString m_savefilename;
|
||||
xmlDocPtr doc;
|
||||
xmlXPathContextPtr context;
|
||||
|
||||
xmlXPathObjectPtr XpathEval( const char* queryString ){
|
||||
const xmlChar* expression = (const xmlChar*)queryString;
|
||||
xmlXPathObjectPtr result = xmlXPathEvalExpression( expression, context );
|
||||
return result;
|
||||
};
|
||||
|
||||
char* GetTagsXpathExpression( char* buffer, const char* shader, NodeTagType nodeTagType ){
|
||||
strcpy( buffer, "/root/*/*[@path='" );
|
||||
strcat( buffer, shader );
|
||||
|
||||
switch ( nodeTagType )
|
||||
{
|
||||
case TAG:
|
||||
strcat( buffer, "']/tag" );
|
||||
break;
|
||||
case EMPTY:
|
||||
strcat( buffer, "']" );
|
||||
xmlXPathObjectPtr XpathEval( const char* queryString ){
|
||||
const xmlChar* expression = (const xmlChar*)queryString;
|
||||
xmlXPathObjectPtr result = xmlXPathEvalExpression( expression, context );
|
||||
return result;
|
||||
};
|
||||
|
||||
return buffer;
|
||||
}
|
||||
char* GetTagsXpathExpression( char* buffer, const char* shader, NodeTagType nodeTagType ){
|
||||
strcpy( buffer, "/root/*/*[@path='" );
|
||||
strcat( buffer, shader );
|
||||
|
||||
switch ( nodeTagType )
|
||||
{
|
||||
case TAG:
|
||||
strcat( buffer, "']/tag" );
|
||||
break;
|
||||
case EMPTY:
|
||||
strcat( buffer, "']" );
|
||||
};
|
||||
|
||||
return buffer;
|
||||
}
|
||||
|
||||
public:
|
||||
XmlTagBuilder();
|
||||
~XmlTagBuilder();
|
||||
XmlTagBuilder();
|
||||
~XmlTagBuilder();
|
||||
|
||||
bool CreateXmlDocument();
|
||||
bool OpenXmlDoc( const char* file, const char* savefile = 0 );
|
||||
bool SaveXmlDoc( const char* file );
|
||||
bool SaveXmlDoc( void );
|
||||
bool AddShaderNode( const char* shader, TextureType textureType, NodeShaderType nodeShaderType );
|
||||
bool DeleteShaderNode( const char* shader );
|
||||
bool CheckShaderTag( const char* shader );
|
||||
bool CheckShaderTag( const char* shader, const char* content );
|
||||
bool AddShaderTag( const char* shader, const char* content, NodeTagType nodeTagType );
|
||||
bool DeleteTag( const char* tag );
|
||||
int RenameShaderTag( const char* oldtag, CopiedString newtag );
|
||||
bool DeleteShaderTag( const char* shader, const char* tag );
|
||||
void GetShaderTags( const char* shader, std::vector<CopiedString>& tags );
|
||||
void GetUntagged( std::set<CopiedString>& shaders );
|
||||
void GetAllTags( std::set<CopiedString>& tags );
|
||||
void TagSearch( const char* expression, std::set<CopiedString>& paths );
|
||||
bool CreateXmlDocument();
|
||||
bool OpenXmlDoc( const char* file, const char* savefile = 0 );
|
||||
bool SaveXmlDoc( const char* file );
|
||||
bool SaveXmlDoc( void );
|
||||
bool AddShaderNode( const char* shader, TextureType textureType, NodeShaderType nodeShaderType );
|
||||
bool DeleteShaderNode( const char* shader );
|
||||
bool CheckShaderTag( const char* shader );
|
||||
bool CheckShaderTag( const char* shader, const char* content );
|
||||
bool AddShaderTag( const char* shader, const char* content, NodeTagType nodeTagType );
|
||||
bool DeleteTag( const char* tag );
|
||||
int RenameShaderTag( const char* oldtag, CopiedString newtag );
|
||||
bool DeleteShaderTag( const char* shader, const char* tag );
|
||||
void GetShaderTags( const char* shader, std::vector<CopiedString>& tags );
|
||||
void GetUntagged( std::set<CopiedString>& shaders );
|
||||
void GetAllTags( std::set<CopiedString>& tags );
|
||||
void TagSearch( const char* expression, std::set<CopiedString>& paths );
|
||||
};
|
||||
|
||||
#endif
|
||||
|
||||
@@ -28,57 +28,57 @@
|
||||
|
||||
class XMLEntityOutputStream
|
||||
{
|
||||
SingleCharacterOutputStream m_ostream;
|
||||
SingleCharacterOutputStream m_ostream;
|
||||
public:
|
||||
XMLEntityOutputStream( TextOutputStream& ostream )
|
||||
: m_ostream( ostream ){
|
||||
}
|
||||
void write( const char c ){
|
||||
m_ostream.write( c );
|
||||
}
|
||||
void writeEscaped( const char c ){
|
||||
switch ( c )
|
||||
{
|
||||
case '<':
|
||||
write( '&' );
|
||||
write( 'l' );
|
||||
write( 't' );
|
||||
write( ';' );
|
||||
break;
|
||||
case '>':
|
||||
write( '&' );
|
||||
write( 'g' );
|
||||
write( 't' );
|
||||
write( ';' );
|
||||
break;
|
||||
case '"':
|
||||
write( '&' );
|
||||
write( 'q' );
|
||||
write( 'u' );
|
||||
write( 'o' );
|
||||
write( 't' );
|
||||
write( ';' );
|
||||
break;
|
||||
case '&':
|
||||
write( '&' );
|
||||
write( 'a' );
|
||||
write( 'm' );
|
||||
write( 'p' );
|
||||
write( ';' );
|
||||
break;
|
||||
default:
|
||||
write( c );
|
||||
break;
|
||||
XMLEntityOutputStream( TextOutputStream& ostream )
|
||||
: m_ostream( ostream ){
|
||||
}
|
||||
}
|
||||
std::size_t write( const char* buffer, std::size_t length ){
|
||||
const char*const end = buffer + length;
|
||||
for ( const char* p = buffer; p != end; ++p )
|
||||
{
|
||||
writeEscaped( *p );
|
||||
void write( const char c ){
|
||||
m_ostream.write( c );
|
||||
}
|
||||
void writeEscaped( const char c ){
|
||||
switch ( c )
|
||||
{
|
||||
case '<':
|
||||
write( '&' );
|
||||
write( 'l' );
|
||||
write( 't' );
|
||||
write( ';' );
|
||||
break;
|
||||
case '>':
|
||||
write( '&' );
|
||||
write( 'g' );
|
||||
write( 't' );
|
||||
write( ';' );
|
||||
break;
|
||||
case '"':
|
||||
write( '&' );
|
||||
write( 'q' );
|
||||
write( 'u' );
|
||||
write( 'o' );
|
||||
write( 't' );
|
||||
write( ';' );
|
||||
break;
|
||||
case '&':
|
||||
write( '&' );
|
||||
write( 'a' );
|
||||
write( 'm' );
|
||||
write( 'p' );
|
||||
write( ';' );
|
||||
break;
|
||||
default:
|
||||
write( c );
|
||||
break;
|
||||
}
|
||||
}
|
||||
std::size_t write( const char* buffer, std::size_t length ){
|
||||
const char*const end = buffer + length;
|
||||
for ( const char* p = buffer; p != end; ++p )
|
||||
{
|
||||
writeEscaped( *p );
|
||||
}
|
||||
return length;
|
||||
}
|
||||
return length;
|
||||
}
|
||||
};
|
||||
|
||||
template<typename T>
|
||||
@@ -89,89 +89,89 @@ inline XMLEntityOutputStream& operator<<( XMLEntityOutputStream& ostream, const
|
||||
|
||||
class XMLStreamWriter : public XMLImporter, public XMLAttrVisitor
|
||||
{
|
||||
class state_t
|
||||
{
|
||||
public:
|
||||
enum EState
|
||||
{
|
||||
eStartElement,
|
||||
eContent,
|
||||
};
|
||||
state_t()
|
||||
: m_state( eStartElement )
|
||||
{}
|
||||
EState m_state;
|
||||
};
|
||||
|
||||
XMLEntityOutputStream m_ostream;
|
||||
std::vector<state_t> m_elements;
|
||||
|
||||
void write_cdata( const char* buffer, std::size_t length ){
|
||||
m_ostream << StringRange( buffer, buffer + length );
|
||||
}
|
||||
void write_string( const char* string ){
|
||||
m_ostream << string;
|
||||
}
|
||||
void write_quoted_string( const char* string ){
|
||||
m_ostream.write( '"' );
|
||||
m_ostream << string;
|
||||
m_ostream.write( '"' );
|
||||
}
|
||||
public:
|
||||
XMLStreamWriter( TextOutputStream& ostream )
|
||||
: m_ostream( ostream ){
|
||||
m_elements.push_back( state_t() );
|
||||
m_elements.back().m_state = state_t::eContent;
|
||||
m_ostream.write( '<' );
|
||||
m_ostream.write( '?' );
|
||||
write_string( "xml" );
|
||||
visit( "version", "1.0" );
|
||||
m_ostream.write( '?' );
|
||||
m_ostream.write( '>' );
|
||||
}
|
||||
|
||||
void pushElement( const XMLElement& element ){
|
||||
if ( m_elements.back().m_state == state_t::eStartElement ) {
|
||||
m_elements.back().m_state = state_t::eContent;
|
||||
m_ostream.write( '>' );
|
||||
}
|
||||
|
||||
m_elements.push_back( state_t() );
|
||||
|
||||
m_ostream.write( '<' );
|
||||
write_string( element.name() );
|
||||
element.forEachAttribute( *this );
|
||||
}
|
||||
void popElement( const char* name ){
|
||||
if ( m_elements.back().m_state == state_t::eStartElement ) {
|
||||
m_ostream.write( '/' );
|
||||
m_ostream.write( '>' );
|
||||
m_elements.pop_back();
|
||||
}
|
||||
else
|
||||
class state_t
|
||||
{
|
||||
m_ostream.write( '<' );
|
||||
m_ostream.write( '/' );
|
||||
write_string( name );
|
||||
m_ostream.write( '>' );
|
||||
m_elements.pop_back();
|
||||
}
|
||||
}
|
||||
std::size_t write( const char* data, std::size_t length ){
|
||||
if ( m_elements.back().m_state == state_t::eStartElement ) {
|
||||
m_elements.back().m_state = state_t::eContent;
|
||||
m_ostream.write( '>' );
|
||||
}
|
||||
write_cdata( data, length );
|
||||
return length;
|
||||
}
|
||||
public:
|
||||
enum EState
|
||||
{
|
||||
eStartElement,
|
||||
eContent,
|
||||
};
|
||||
state_t()
|
||||
: m_state( eStartElement )
|
||||
{}
|
||||
EState m_state;
|
||||
};
|
||||
|
||||
void visit( const char* name, const char* value ){
|
||||
m_ostream.write( ' ' );
|
||||
write_string( name );
|
||||
m_ostream.write( '=' );
|
||||
write_quoted_string( value );
|
||||
}
|
||||
XMLEntityOutputStream m_ostream;
|
||||
std::vector<state_t> m_elements;
|
||||
|
||||
void write_cdata( const char* buffer, std::size_t length ){
|
||||
m_ostream << StringRange( buffer, buffer + length );
|
||||
}
|
||||
void write_string( const char* string ){
|
||||
m_ostream << string;
|
||||
}
|
||||
void write_quoted_string( const char* string ){
|
||||
m_ostream.write( '"' );
|
||||
m_ostream << string;
|
||||
m_ostream.write( '"' );
|
||||
}
|
||||
public:
|
||||
XMLStreamWriter( TextOutputStream& ostream )
|
||||
: m_ostream( ostream ){
|
||||
m_elements.push_back( state_t() );
|
||||
m_elements.back().m_state = state_t::eContent;
|
||||
m_ostream.write( '<' );
|
||||
m_ostream.write( '?' );
|
||||
write_string( "xml" );
|
||||
visit( "version", "1.0" );
|
||||
m_ostream.write( '?' );
|
||||
m_ostream.write( '>' );
|
||||
}
|
||||
|
||||
void pushElement( const XMLElement& element ){
|
||||
if ( m_elements.back().m_state == state_t::eStartElement ) {
|
||||
m_elements.back().m_state = state_t::eContent;
|
||||
m_ostream.write( '>' );
|
||||
}
|
||||
|
||||
m_elements.push_back( state_t() );
|
||||
|
||||
m_ostream.write( '<' );
|
||||
write_string( element.name() );
|
||||
element.forEachAttribute( *this );
|
||||
}
|
||||
void popElement( const char* name ){
|
||||
if ( m_elements.back().m_state == state_t::eStartElement ) {
|
||||
m_ostream.write( '/' );
|
||||
m_ostream.write( '>' );
|
||||
m_elements.pop_back();
|
||||
}
|
||||
else
|
||||
{
|
||||
m_ostream.write( '<' );
|
||||
m_ostream.write( '/' );
|
||||
write_string( name );
|
||||
m_ostream.write( '>' );
|
||||
m_elements.pop_back();
|
||||
}
|
||||
}
|
||||
std::size_t write( const char* data, std::size_t length ){
|
||||
if ( m_elements.back().m_state == state_t::eStartElement ) {
|
||||
m_elements.back().m_state = state_t::eContent;
|
||||
m_ostream.write( '>' );
|
||||
}
|
||||
write_cdata( data, length );
|
||||
return length;
|
||||
}
|
||||
|
||||
void visit( const char* name, const char* value ){
|
||||
m_ostream.write( ' ' );
|
||||
write_string( name );
|
||||
m_ostream.write( '=' );
|
||||
write_quoted_string( value );
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
|
||||
Reference in New Issue
Block a user