2007-09-07 23:17:30 +02:00
|
|
|
#include <set>
|
|
|
|
#include <string>
|
|
|
|
#include <vector>
|
|
|
|
#include <stdexcept>
|
|
|
|
#include <expat.h>
|
|
|
|
#include "housestylewriter.h"
|
|
|
|
#include "contexthandler.h"
|
|
|
|
|
|
|
|
using namespace std;
|
|
|
|
|
2007-09-08 00:25:30 +02:00
|
|
|
HouseStyleWriter::HouseStyleWriter ( vector<ContextMatch> &v ) :
|
|
|
|
hswd ( new HouseStyleWriterData() )
|
2007-09-07 23:17:30 +02:00
|
|
|
{
|
2007-09-08 00:25:30 +02:00
|
|
|
set<size_t> elementSet;
|
|
|
|
size_t vectorsize = v.size();
|
|
|
|
for ( size_t i = 0; i < vectorsize; ++i )
|
|
|
|
elementSet.insert ( v[i].elementCount );
|
|
|
|
|
|
|
|
hswd->setState ( STATE_UNKNOWN );
|
|
|
|
hswd->v = v;
|
|
|
|
hswd->elementSet = elementSet;
|
|
|
|
|
|
|
|
XML_SetUserData ( p, hswd.get() );
|
|
|
|
XML_SetElementHandler ( p, start, end );
|
|
|
|
XML_SetCharacterDataHandler ( p, characterdata );
|
|
|
|
XML_SetXmlDeclHandler ( p, xmldecl );
|
|
|
|
XML_SetCdataSectionHandler ( p, cdatastart, cdataend );
|
|
|
|
XML_SetDefaultHandler ( p, defaulthandler );
|
2007-09-07 23:17:30 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
HouseStyleWriter::~HouseStyleWriter()
|
2007-09-08 00:25:30 +02:00
|
|
|
{}
|
2007-09-07 23:17:30 +02:00
|
|
|
|
|
|
|
string HouseStyleWriter::getOutput()
|
|
|
|
{
|
2007-09-08 00:25:30 +02:00
|
|
|
return hswd->output;
|
2007-09-07 23:17:30 +02:00
|
|
|
}
|
|
|
|
|
2007-09-08 00:25:30 +02:00
|
|
|
void XMLCALL HouseStyleWriter::start ( void *data, const XML_Char *el, const XML_Char **attr )
|
2007-09-07 23:17:30 +02:00
|
|
|
{
|
2007-09-08 00:25:30 +02:00
|
|
|
HouseStyleWriterData *hswd;
|
|
|
|
hswd = ( HouseStyleWriterData * ) data;
|
|
|
|
hswd->setState ( STATE_ON_START );
|
|
|
|
|
|
|
|
if ( hswd->textnode.size() )
|
|
|
|
{
|
|
|
|
if ( hswd->elementSet.count ( hswd->getCount() ) )
|
|
|
|
modify ( hswd->v, hswd->textnode, hswd->getCount() );
|
|
|
|
hswd->output += xmliseTextNode ( hswd->textnode );
|
|
|
|
hswd->textnode = "";
|
|
|
|
}
|
|
|
|
|
|
|
|
hswd->output += '<';
|
|
|
|
hswd->output += el;
|
|
|
|
for ( ; *attr; attr += 2 )
|
|
|
|
{
|
|
|
|
hswd->output += ' ';
|
|
|
|
hswd->output += *attr;
|
|
|
|
hswd->output += "=\"";
|
|
|
|
hswd->output += xmliseAttribute ( * ( attr + 1 ) );
|
|
|
|
hswd->output += '"';
|
|
|
|
}
|
|
|
|
hswd->output += '>';
|
2007-09-07 23:17:30 +02:00
|
|
|
}
|
|
|
|
|
2007-09-08 00:25:30 +02:00
|
|
|
void XMLCALL HouseStyleWriter::end ( void *data, const XML_Char *el )
|
2007-09-07 23:17:30 +02:00
|
|
|
{
|
2007-09-08 00:25:30 +02:00
|
|
|
HouseStyleWriterData *hswd;
|
|
|
|
hswd = ( HouseStyleWriterData * ) data;
|
|
|
|
//++(hswd->elementCount);
|
|
|
|
hswd->setState ( STATE_ON_END );
|
|
|
|
|
|
|
|
if ( hswd->textnode.size() )
|
|
|
|
{
|
|
|
|
if ( hswd->elementSet.count ( hswd->getCount() ) )
|
|
|
|
modify ( hswd->v, hswd->textnode, hswd->getCount() );
|
|
|
|
hswd->output += xmliseTextNode ( hswd->textnode );
|
|
|
|
hswd->textnode = "";
|
|
|
|
}
|
|
|
|
hswd->output += "</";
|
|
|
|
hswd->output += el;
|
|
|
|
hswd->output += '>';
|
2007-09-07 23:17:30 +02:00
|
|
|
}
|
|
|
|
|
2007-09-08 00:25:30 +02:00
|
|
|
void XMLCALL HouseStyleWriter::characterdata ( void *data, const XML_Char *s, int len )
|
2007-09-07 23:17:30 +02:00
|
|
|
{
|
2007-09-08 00:25:30 +02:00
|
|
|
HouseStyleWriterData *hswd;
|
|
|
|
hswd = ( HouseStyleWriterData * ) data;
|
|
|
|
hswd->textnode.append ( s, len );
|
2007-09-07 23:17:30 +02:00
|
|
|
}
|
|
|
|
|
2007-09-08 00:25:30 +02:00
|
|
|
void XMLCALL HouseStyleWriter::xmldecl (
|
|
|
|
void *data,
|
|
|
|
const XML_Char *version,
|
|
|
|
const XML_Char *encoding,
|
|
|
|
int standalone )
|
2007-09-07 23:17:30 +02:00
|
|
|
{
|
2007-09-08 00:25:30 +02:00
|
|
|
HouseStyleWriterData *hswd;
|
|
|
|
hswd = ( HouseStyleWriterData * ) data;
|
|
|
|
hswd->output += "<?xml version=\"";
|
|
|
|
hswd->output += version;
|
|
|
|
hswd->output += "\" encoding=\"UTF-8\"";
|
|
|
|
if ( standalone != -1 )
|
|
|
|
{
|
|
|
|
hswd->output += " standalone=\"";
|
|
|
|
hswd->output += ( standalone ) ? "yes" : "no";
|
|
|
|
hswd->output += "\"";
|
|
|
|
}
|
|
|
|
hswd->output += "?>";
|
2007-09-07 23:17:30 +02:00
|
|
|
}
|
|
|
|
|
2007-09-08 00:25:30 +02:00
|
|
|
void XMLCALL HouseStyleWriter::cdatastart ( void *data )
|
2007-09-07 23:17:30 +02:00
|
|
|
{
|
2007-09-08 00:25:30 +02:00
|
|
|
HouseStyleWriterData *hswd;
|
|
|
|
hswd = ( HouseStyleWriterData * ) data;
|
|
|
|
hswd->setState ( STATE_ON_CDATA_START );
|
|
|
|
|
|
|
|
if ( hswd->textnode.size() )
|
|
|
|
{
|
|
|
|
if ( hswd->elementSet.count ( hswd->getCount() ) )
|
|
|
|
modify ( hswd->v, hswd->textnode, hswd->getCount() );
|
|
|
|
hswd->output += hswd->textnode;
|
|
|
|
hswd->textnode = "";
|
|
|
|
}
|
|
|
|
|
|
|
|
hswd->output += "<![CDATA[";
|
2007-09-07 23:17:30 +02:00
|
|
|
}
|
|
|
|
|
2007-09-08 00:25:30 +02:00
|
|
|
void XMLCALL HouseStyleWriter::cdataend ( void *data )
|
2007-09-07 23:17:30 +02:00
|
|
|
{
|
2007-09-08 00:25:30 +02:00
|
|
|
HouseStyleWriterData *hswd;
|
|
|
|
hswd = ( HouseStyleWriterData * ) data;
|
|
|
|
hswd->setState ( STATE_ON_CDATA_END );
|
|
|
|
|
|
|
|
if ( hswd->textnode.size() )
|
|
|
|
{
|
|
|
|
if ( hswd->elementSet.count ( hswd->getCount() ) )
|
|
|
|
modify ( hswd->v, hswd->textnode, hswd->getCount() );
|
|
|
|
hswd->output += hswd->textnode;
|
|
|
|
hswd->textnode = "";
|
|
|
|
}
|
|
|
|
|
|
|
|
hswd->output += "]]>";
|
2007-09-07 23:17:30 +02:00
|
|
|
}
|
|
|
|
|
2007-09-08 00:25:30 +02:00
|
|
|
void XMLCALL HouseStyleWriter::defaulthandler (
|
|
|
|
void *data,
|
|
|
|
const XML_Char *s,
|
|
|
|
int len )
|
2007-09-07 23:17:30 +02:00
|
|
|
{
|
2007-09-08 00:25:30 +02:00
|
|
|
HouseStyleWriterData *hswd;
|
|
|
|
hswd = ( HouseStyleWriterData * ) data;
|
|
|
|
hswd->output.append ( s, len );
|
2007-09-07 23:17:30 +02:00
|
|
|
}
|
|
|
|
|
2007-09-08 00:25:30 +02:00
|
|
|
void HouseStyleWriter::modify (
|
|
|
|
vector<ContextMatch> &v,
|
|
|
|
string &buffer,
|
|
|
|
unsigned elementCount )
|
2007-09-07 23:17:30 +02:00
|
|
|
{
|
2007-09-08 00:25:30 +02:00
|
|
|
int vectorsize, os_adjust, exclusion;
|
|
|
|
vectorsize = v.size();
|
|
|
|
os_adjust = exclusion = 0;
|
|
|
|
string cmp1, cmp2;
|
2007-09-07 23:17:30 +02:00
|
|
|
|
2007-09-08 00:25:30 +02:00
|
|
|
for ( int i = 0; i < vectorsize; ++i )
|
|
|
|
{
|
|
|
|
unsigned vectorElementCount = v[i].elementCount;
|
|
|
|
if ( vectorElementCount < elementCount )
|
2007-09-07 23:17:30 +02:00
|
|
|
continue;
|
2007-09-08 00:25:30 +02:00
|
|
|
else if ( vectorElementCount > elementCount )
|
|
|
|
break;
|
|
|
|
else if ( vectorElementCount == elementCount )
|
|
|
|
{
|
|
|
|
int offset = ( int ) v[i].offset + os_adjust;
|
|
|
|
|
|
|
|
if ( offset < exclusion )
|
|
|
|
continue;
|
|
|
|
|
|
|
|
// check match is as expected
|
|
|
|
try
|
|
|
|
{
|
|
|
|
cmp1 = v[i].match;
|
|
|
|
cmp2 = buffer.substr ( offset, v[i].match.size() );
|
|
|
|
}
|
|
|
|
catch ( std::exception& e )
|
|
|
|
{
|
|
|
|
continue;
|
|
|
|
}
|
|
|
|
|
|
|
|
if ( cmp1.compare ( cmp2 ) )
|
|
|
|
continue;
|
|
|
|
|
|
|
|
buffer.replace ( offset, v[i].match.size(), v[i].replace.c_str() );
|
|
|
|
|
|
|
|
os_adjust += v[i].replace.size() - v[i].match.size();
|
|
|
|
exclusion = offset + v[i].replace.size();
|
|
|
|
}
|
2007-09-07 23:17:30 +02:00
|
|
|
}
|
|
|
|
}
|