xml-copy-editor-code/src/housestylewriter.cpp

201 lines
5.2 KiB
C++
Raw Normal View History

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
}
}