#include #include #include "xmlgenerator.h" XmlGenerator::XmlGenerator(FILE *f) : m_file(f), m_indent(true), m_level(0) { ::fprintf(m_file, "\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("", m_tags.top().c_str()); m_indent = true; m_tags.pop(); } void XmlGenerator::comment(const std::string &str) { printLn("", 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 = "]]]]>"; 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(""); 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); }