diff options
Diffstat (limited to 'main/xmlgenerator.cpp')
| -rw-r--r-- | main/xmlgenerator.cpp | 188 |
1 files changed, 188 insertions, 0 deletions
diff --git a/main/xmlgenerator.cpp b/main/xmlgenerator.cpp new file mode 100644 index 00000000..eb4f1577 --- /dev/null +++ b/main/xmlgenerator.cpp @@ -0,0 +1,188 @@ +#include <fstream> +#include <lib/base/eerror.h> +#include "xmlgenerator.h" + +XmlGenerator::XmlGenerator(FILE *f) : m_file(f), m_indent(true), m_level(0) +{ + ::fprintf(m_file, "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n"); +} + +XmlGenerator::~XmlGenerator() +{ +} + +void XmlGenerator::vprint(const char *fmt, va_list ap, bool newline) +{ + unsigned int i; + + if (m_indent) + for (i = 0; i < m_level; i++) + ::fprintf(m_file, "\t"); + + ::vfprintf(m_file, fmt, ap); + + if (newline) + ::fprintf(m_file, "\n"); +} + +void XmlGenerator::print(const char *fmt, ...) +{ + va_list ap; + + ::va_start(ap, fmt); + vprint(fmt, ap, false); + ::va_end(ap); +} + +void XmlGenerator::printLn(const char *fmt, ...) +{ + va_list ap; + + ::va_start(ap, fmt); + vprint(fmt, ap, true); + ::va_end(ap); +} + +void XmlGenerator::open(const std::string &tag, bool newline) +{ + if (newline) { + printLn("<%s>", tag.c_str()); + } else { + print("<%s>", tag.c_str()); + m_indent = false; + } + + m_tags.push(tag); + m_level++; +} + +void XmlGenerator::open(const std::string &tag) +{ + open(tag, true); +} + +void XmlGenerator::close() +{ + ASSERT(!m_tags.empty()); + ASSERT(m_level > 0); + m_level--; + + printLn("</%s>", m_tags.top().c_str()); + m_indent = true; + + m_tags.pop(); +} + +void XmlGenerator::comment(const std::string &str) +{ + printLn("<!-- %s -->", str.c_str()); +} + +void XmlGenerator::commentFromErrno(const std::string &tag) +{ + open(tag); + comment(strerror(errno)); + close(); +} + +std::string XmlGenerator::cDataEscape(const std::string &str) +{ + const std::string search = "]]>"; + const std::string replace = "]]]]><![CDATA[>"; + std::string ret; + size_t pos = 0, opos; + + for (;;) { + opos = pos; + pos = str.find(search, opos); + if (pos == std::string::npos) + break; + ret.append(str, opos, pos - opos); + ret.append(replace); + pos += search.size(); + } + + ret.append(str, opos, std::string::npos); + return ret; +} + +void XmlGenerator::cDataFromCmd(const std::string &tag, const std::string &cmd) +{ + FILE *pipe = ::popen(cmd.c_str(), "re"); + + if (pipe == 0) { + commentFromErrno(tag); + return; + } + + std::string result; + char *lineptr = NULL; + size_t n = 0; + + for (;;) { + ssize_t ret = ::getline(&lineptr, &n, pipe); + if (ret < 0) + break; + result.append(lineptr, ret); + } + + if (lineptr) + ::free(lineptr); + + ::pclose(pipe); + cDataFromString(tag, result); +} + +void XmlGenerator::cDataFromFile(const std::string &tag, const std::string &filename, const char *filter) +{ + std::ifstream in(filename.c_str()); + std::string line; + std::string content; + + if (!in.good()) { + commentFromErrno(tag); + return; + } + + while (std::getline(in, line)) + if (!filter || !line.find(filter)) + content += line + '\n'; + + in.close(); + cDataFromString(tag, content); +} + +void XmlGenerator::cDataFromString(const std::string &tag, const std::string &str) +{ + bool indent = false; + + open(tag); + printLn("<![CDATA["); + std::swap(m_indent, indent); + print("%s", cDataEscape(str).c_str()); + printLn("]]>"); + std::swap(m_indent, indent); + close(); +} + +void XmlGenerator::string(const std::string &tag, const std::string &str) +{ + open(tag, false); + print("%s", str.c_str()); + close(); +} + +void XmlGenerator::stringFromFile(const std::string &tag, const std::string &filename) +{ + std::ifstream in(filename.c_str()); + std::string line; + + if (!in.good()) { + commentFromErrno(tag); + return; + } + + std::getline(in, line); + in.close(); + string(tag, line); +} |
