Create utility class for writing XML files to a stream

This commit is contained in:
2015-01-13 17:31:00 -05:00
parent 45bbed03f3
commit 0aec4c4c5d
5 changed files with 206 additions and 0 deletions

View File

@@ -46,6 +46,7 @@
<ClInclude Include="..\..\dialogxml\xml-parser\ticpprc.h" />
<ClInclude Include="..\..\dialogxml\xml-parser\tinystr.h" />
<ClInclude Include="..\..\dialogxml\xml-parser\tinyxml.h" />
<ClInclude Include="..\..\dialogxml\xml-parser\tinyprint.hpp" />
<ClInclude Include="..\..\oldstructs.h" />
<ClInclude Include="..\..\tools\cursors.hpp" />
<ClInclude Include="..\..\tools\fileio.hpp" />
@@ -96,6 +97,7 @@
<ClCompile Include="..\..\dialogxml\xml-parser\ticpp.cpp" />
<ClCompile Include="..\..\dialogxml\xml-parser\tinystr.cpp" />
<ClCompile Include="..\..\dialogxml\xml-parser\tinyxml.cpp" />
<ClCompile Include="..\..\dialogxml\xml-parser\tinyprint.cpp" />
<ClCompile Include="..\..\dialogxml\xml-parser\tinyxmlerror.cpp" />
<ClCompile Include="..\..\dialogxml\xml-parser\tinyxmlparser.cpp" />
<ClCompile Include="..\..\tools\cursors.win.cpp" />

View File

@@ -112,6 +112,9 @@
<ClInclude Include="..\..\dialogxml\xml-parser\tinyxml.h">
<Filter>DialogXML\TinyXML</Filter>
</ClInclude>
<ClInclude Include="..\..\dialogxml\xml-parser\tinyprint.hpp">
<Filter>DialogXML\TinyXML</Filter>
</ClInclude>
<ClInclude Include="..\..\dialogxml\button.hpp">
<Filter>DialogXML\Header Files</Filter>
</ClInclude>
@@ -265,6 +268,9 @@
<ClCompile Include="..\..\dialogxml\xml-parser\tinyxml.cpp">
<Filter>DialogXML\TinyXML</Filter>
</ClCompile>
<ClCompile Include="..\..\dialogxml\xml-parser\tinyprint.cpp">
<Filter>DialogXML\TinyXML</Filter>
</ClCompile>
<ClCompile Include="..\..\dialogxml\xml-parser\tinyxmlerror.cpp">
<Filter>DialogXML\TinyXML</Filter>
</ClCompile>

View File

@@ -151,6 +151,7 @@
91870F81190C8C1C0081C150 /* winutil.mac.mm in Sources */ = {isa = PBXBuildFile; fileRef = 919145FF18E63B70005CF3A4 /* winutil.mac.mm */; };
91870F83190C8C1F0081C150 /* tarball.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 91BFA3D81902AD78001686E4 /* tarball.cpp */; };
91870F84190C90980081C150 /* scen.menu.xib in Resources */ = {isa = PBXBuildFile; fileRef = 914CA49F190C4E9200B6ADD1 /* scen.menu.xib */; };
919086E01A65CA300071F7A0 /* tinyprint.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 919086DF1A65C8E30071F7A0 /* tinyprint.cpp */; };
919145FC18E3AB1B005CF3A4 /* boe.appleevents.mm in Sources */ = {isa = PBXBuildFile; fileRef = 919145FB18E3A32F005CF3A4 /* boe.appleevents.mm */; };
9192C12018F2745C0088A580 /* menu.xib in Resources */ = {isa = PBXBuildFile; fileRef = 9192C11E18F271920088A580 /* menu.xib */; };
919DDBFC19006CF2003E7FED /* libboost_filesystem.dylib in Copy Libraries and Frameworks */ = {isa = PBXBuildFile; fileRef = 919DDBFA19006CC9003E7FED /* libboost_filesystem.dylib */; };
@@ -601,6 +602,8 @@
9179A4641A48681800FEF872 /* stack.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = stack.cpp; sourceTree = "<group>"; };
917B573F100B956C0096C978 /* undo.hpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.h; path = undo.hpp; sourceTree = "<group>"; };
918D59A718EA513900735B66 /* dialog.keys.hpp */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.h; path = dialog.keys.hpp; sourceTree = "<group>"; };
919086DF1A65C8E30071F7A0 /* tinyprint.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = tinyprint.cpp; sourceTree = "<group>"; };
919086E11A65D3250071F7A0 /* tinyprint.hpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.h; path = tinyprint.hpp; sourceTree = "<group>"; };
919145FB18E3A32F005CF3A4 /* boe.appleevents.mm */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.objcpp; path = boe.appleevents.mm; sourceTree = "<group>"; };
919145FD18E3C750005CF3A4 /* scrollbar.hpp */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.h; path = scrollbar.hpp; sourceTree = "<group>"; };
919145FE18E63B41005CF3A4 /* winutil.hpp */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.h; path = winutil.hpp; sourceTree = "<group>"; };
@@ -836,6 +839,8 @@
910BBA2F0FB8C470001E34EA /* ticpprc.h */,
910BBA290FB8C459001E34EA /* tinystr.h */,
910BBA2B0FB8C459001E34EA /* tinyxml.h */,
919086E11A65D3250071F7A0 /* tinyprint.hpp */,
919086DF1A65C8E30071F7A0 /* tinyprint.cpp */,
);
path = "xml-parser";
sourceTree = "<group>";
@@ -1599,6 +1604,7 @@
91597A701A3C021600BE7BF9 /* spell.cpp in Sources */,
9179A4651A48683100FEF872 /* stack.cpp in Sources */,
91FDB57C1A4E77CA00DE5983 /* shop.cpp in Sources */,
919086E01A65CA300071F7A0 /* tinyprint.cpp in Sources */,
);
runOnlyForDeploymentPostprocessing = 0;
};

View File

@@ -0,0 +1,49 @@
//
// tinyprint.cpp
// BoE
//
// Created by Celtic Minstrel on 15-01-13.
//
//
#include "tinyprint.hpp"
#include <stdexcept>
using namespace ticpp;
Printer::Printer(std::string fname, std::ostream& to) : doc(fname), stream(to) {
Declaration* decl = new Declaration("1.0", "UTF-8", "no");
doc.LinkEndChild(decl);
}
void Printer::OpenElement(std::string tagName) {
openElements.push(new Element(tagName));
}
void Printer::CloseElement(std::string tagName) {
if(openElements.empty())
throw std::out_of_range("No elements left to close!");
if(tagName != openElements.top()->Value())
throw std::logic_error("Mismatched closing tag!");
Element* top = openElements.top();
openElements.pop();
PushNode(top);
}
void Printer::PushComment(std::string comment) {
PushNode(new Comment(comment));
}
void Printer::PushStylesheet(std::string value, std::string href) {
PushNode(new StylesheetReference(value, href));
}
void Printer::PushNode(Node* node) {
if(openElements.empty())
doc.LinkEndChild(node);
else openElements.top()->LinkEndChild(node);
}
Printer::~Printer() {
stream << doc;
}

View File

@@ -0,0 +1,143 @@
//
// tinyprint.hpp
// BoE
//
// Created by Celtic Minstrel on 15-01-13.
//
//
#ifndef BoE_tinyprint_hpp
#define BoE_tinyprint_hpp
#include "ticpp.h"
#include <string>
#include <stack>
#include <boost/lexical_cast.hpp>
#include <ios>
namespace ticpp {
class Printer : public Visitor {
Document doc;
std::ostream& stream;
std::stack<Element*> openElements;
public:
Printer(std::string fname, std::ostream& to);
~Printer();
void OpenElement(std::string tagName);
void CloseElement(std::string tagName);
void PushComment(std::string comment);
void PushStylesheet(std::string value, std::string href);
void PushNode(Node* node);
template<typename T> void PushAttribute(std::string attrName, T attrVal) {
openElements.top()->SetAttribute(attrName, boost::lexical_cast<std::string>(attrVal));
}
template<typename T> void PushText(T textVal) {
PushNode(new Text(boost::lexical_cast<std::string>(textVal)));
}
};
}
#if 0
class TINYXML2_LIB XMLPrinter : public XMLVisitor
{
public:
/** Construct the printer. If the FILE* is specified,
this will print to the FILE. Else it will print
to memory, and the result is available in CStr().
If 'compact' is set to true, then output is created
with only required whitespace and newlines.
*/
XMLPrinter( FILE* file=0, bool compact = false, int depth = 0 );
virtual ~XMLPrinter() {}
/** If streaming, write the BOM and declaration. */
void PushHeader( bool writeBOM, bool writeDeclaration );
/** If streaming, start writing an element.
The element must be closed with CloseElement()
*/
void OpenElement( const char* name, bool compactMode=false );
/// If streaming, add an attribute to an open element.
void PushAttribute( const char* name, const char* value );
void PushAttribute( const char* name, int value );
void PushAttribute( const char* name, unsigned value );
void PushAttribute( const char* name, bool value );
void PushAttribute( const char* name, double value );
/// If streaming, close the Element.
virtual void CloseElement( bool compactMode=false );
/// Add a text node.
void PushText( const char* text, bool cdata=false );
/// Add a text node from an integer.
void PushText( int value );
/// Add a text node from an unsigned.
void PushText( unsigned value );
/// Add a text node from a bool.
void PushText( bool value );
/// Add a text node from a float.
void PushText( float value );
/// Add a text node from a double.
void PushText( double value );
/// Add a comment
void PushComment( const char* comment );
void PushDeclaration( const char* value );
void PushUnknown( const char* value );
virtual bool VisitEnter( const XMLDocument& /*doc*/ );
virtual bool VisitExit( const XMLDocument& /*doc*/ ) {
return true;
}
virtual bool VisitEnter( const XMLElement& element, const XMLAttribute* attribute );
virtual bool VisitExit( const XMLElement& element );
virtual bool Visit( const XMLText& text );
virtual bool Visit( const XMLComment& comment );
virtual bool Visit( const XMLDeclaration& declaration );
virtual bool Visit( const XMLUnknown& unknown );
/**
If in print to memory mode, return a pointer to
the XML file in memory.
*/
const char* CStr() const {
return _buffer.Mem();
}
/**
If in print to memory mode, return the size
of the XML file in memory. (Note the size returned
includes the terminating null.)
*/
int CStrSize() const {
return _buffer.Size();
}
/**
If in print to memory mode, reset the buffer to the
beginning.
*/
void ClearBuffer() {
_buffer.Clear();
_buffer.Push(0);
}
protected:
virtual bool CompactMode( const XMLElement& ) { return _compactMode; }
/** Prints out the space before an element. You may override to change
the space and tabs used. A PrintSpace() override should call Print().
*/
virtual void PrintSpace( int depth );
void Print( const char* format, ... );
void SealElementIfJustOpened();
bool _elementJustOpened;
DynArray< const char*, 10 > _stack;
private:
void PrintString( const char*, bool restrictedEntitySet ); // prints out, after detecting entities.
bool _firstElement;
FILE* _fp;
int _depth;
int _textDepth;
bool _processEntities;
bool _compactMode;
enum {
ENTITY_RANGE = 64,
BUF_SIZE = 200
};
bool _entityFlag[ENTITY_RANGE];
bool _restrictedEntityFlag[ENTITY_RANGE];
DynArray< char, 20 > _buffer;
};
#endif
#endif