diff options
Diffstat (limited to 'Source/cmXMLWriter.cxx')
-rw-r--r-- | Source/cmXMLWriter.cxx | 132 |
1 files changed, 132 insertions, 0 deletions
diff --git a/Source/cmXMLWriter.cxx b/Source/cmXMLWriter.cxx new file mode 100644 index 0000000..2f50fe9 --- /dev/null +++ b/Source/cmXMLWriter.cxx @@ -0,0 +1,132 @@ +/* Distributed under the OSI-approved BSD 3-Clause License. See accompanying + file Copyright.txt or https://cmake.org/licensing for details. */ +#include "cmXMLWriter.h" + +#include <cassert> +#include <cmsys/FStream.hxx> + +cmXMLWriter::cmXMLWriter(std::ostream& output, std::size_t level) + : Output(output) + , Level(level) + , ElementOpen(false) + , BreakAttrib(false) + , IsContent(false) +{ +} + +cmXMLWriter::~cmXMLWriter() +{ + assert(this->Elements.empty()); +} + +void cmXMLWriter::StartDocument(const char* encoding) +{ + this->Output << "<?xml version=\"1.0\" encoding=\"" << encoding << "\"?>"; +} + +void cmXMLWriter::EndDocument() +{ + assert(this->Elements.empty()); + this->Output << '\n'; +} + +void cmXMLWriter::StartElement(std::string const& name) +{ + this->CloseStartElement(); + this->ConditionalLineBreak(!this->IsContent, this->Elements.size()); + this->Output << '<' << name; + this->Elements.push(name); + this->ElementOpen = true; + this->BreakAttrib = false; +} + +void cmXMLWriter::EndElement() +{ + assert(!this->Elements.empty()); + if (this->ElementOpen) { + this->Output << "/>"; + } else { + this->ConditionalLineBreak(!this->IsContent, this->Elements.size() - 1); + this->IsContent = false; + this->Output << "</" << this->Elements.top() << '>'; + } + this->Elements.pop(); + this->ElementOpen = false; +} + +void cmXMLWriter::Element(const char* name) +{ + this->CloseStartElement(); + this->ConditionalLineBreak(!this->IsContent, this->Elements.size()); + this->Output << '<' << name << "/>"; +} + +void cmXMLWriter::BreakAttributes() +{ + this->BreakAttrib = true; +} + +void cmXMLWriter::Comment(const char* comment) +{ + this->CloseStartElement(); + this->ConditionalLineBreak(!this->IsContent, this->Elements.size()); + this->Output << "<!-- " << comment << " -->"; +} + +void cmXMLWriter::CData(std::string const& data) +{ + this->PreContent(); + this->Output << "<![CDATA[" << data << "]]>"; +} + +void cmXMLWriter::Doctype(const char* doctype) +{ + this->CloseStartElement(); + this->ConditionalLineBreak(!this->IsContent, this->Elements.size()); + this->Output << "<!DOCTYPE " << doctype << ">"; +} + +void cmXMLWriter::ProcessingInstruction(const char* target, const char* data) +{ + this->CloseStartElement(); + this->ConditionalLineBreak(!this->IsContent, this->Elements.size()); + this->Output << "<?" << target << ' ' << data << "?>"; +} + +void cmXMLWriter::FragmentFile(const char* fname) +{ + this->CloseStartElement(); + cmsys::ifstream fin(fname, std::ios::in | std::ios::binary); + this->Output << fin.rdbuf(); +} + +void cmXMLWriter::ConditionalLineBreak(bool condition, std::size_t indent) +{ + if (condition) { + this->Output << '\n' << std::string(indent + this->Level, '\t'); + } +} + +void cmXMLWriter::PreAttribute() +{ + assert(this->ElementOpen); + this->ConditionalLineBreak(this->BreakAttrib, this->Elements.size()); + if (!this->BreakAttrib) { + this->Output << ' '; + } +} + +void cmXMLWriter::PreContent() +{ + this->CloseStartElement(); + this->IsContent = true; +} + +void cmXMLWriter::CloseStartElement() +{ + if (this->ElementOpen) { + this->ConditionalLineBreak(this->BreakAttrib, this->Elements.size()); + this->Output << '>'; + this->ElementOpen = false; + } +} |