generate-shapes/src/util/xml/XmlWriter.h
2023-08-24 17:29:01 +02:00

135 lines
2.8 KiB
C++

// Copyright 2016, University of Freiburg,
// Chair of Algorithms and Data Structures.
// Authors: Patrick Brosi <brosi@informatik.uni-freiburg.de>
#ifndef UTIL_XML_XMLWRITER_H_
#define UTIL_XML_XMLWRITER_H_
#ifdef ZLIB_FOUND
#include <zlib.h>
#endif
#ifdef BZLIB_FOUND
#include <bzlib.h>
#endif
#include <map>
#include <ostream>
#include <fstream>
#include <stack>
#include <string>
namespace util {
namespace xml {
static const size_t BUFFER_S = 32 * 1024 * 1024;
class XmlWriterException : public std::exception {
public:
XmlWriterException(std::string msg) : _msg(msg) {}
~XmlWriterException() throw() {}
virtual const char* what() const throw() { return _msg.c_str(); };
private:
std::string _msg;
};
// simple XML writer class without much overhead
class XmlWriter {
public:
explicit XmlWriter(std::ostream* out);
XmlWriter(std::ostream* out, bool pretty);
XmlWriter(std::ostream* out, bool pretty, size_t indent);
explicit XmlWriter(const std::string& file);
XmlWriter(const std::string& file, bool pretty);
XmlWriter(const std::string& file, bool pretty, size_t indent);
~XmlWriter(){
#ifdef ZLIB_FOUND
if (_gzfile) gzclose(_gzfile);
#endif
#ifdef BZLIB_FOUND
int err;
if (_bzfile) {
flushBzip();
BZ2_bzWriteClose(&err, _bzfile, 0, 0, 0);
}
#endif
};
// open tag without attributes
void openTag(const std::string& tag);
// open tag with single attribute (for convenience...)
void openTag(const std::string& tag, const std::string& key,
const std::string& val);
// open tag with attribute list
void openTag(const std::string& tag,
const std::map<std::string, std::string>& attrs);
// open comment
void openComment();
// write text
void writeText(const std::string& text);
// close tag
void closeTag();
// close all open tags, essentially closing the document
void closeTags();
// pushes XML escaped text to stream
void putEsced(const std::string& str, char quot);
void put(const std::string& str);
void put(const char c);
private:
enum XML_NODE_T { TAG, TEXT, COMMENT };
struct XmlNode {
XmlNode(XML_NODE_T t, const std::string& pload, bool hanging)
: t(t), pload(pload), hanging(hanging) {}
XML_NODE_T t;
std::string pload;
bool hanging;
};
void flushBzip();
std::ostream* _out;
std::ofstream _outs;
std::stack<XmlNode> _nstack;
bool _pretty;
size_t _indent;
#ifdef ZLIB_FOUND
gzFile _gzfile;
#else
int _gzfile;
#endif
char* _bzbuf;
size_t _bzbufpos = 0;
#ifdef BZLIB_FOUND
BZFILE* _bzfile;
#else
int _bzfile;
#endif
// handles indentation
void doIndent();
// close "hanging" tags
void closeHanging();
// checks tag names for validiy
void checkTagName(const std::string& str) const;
};
} // namespace xml
} // namespace util
#endif // UTIL_XML_XMLWRITER_H_