// Copyright 2017 Google Inc. All rights reserved. // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. // You may obtain a copy of the License at // // http://www.apache.org/licenses/LICENSE-2.0 // // Unless required by applicable law or agreed to in writing, software // distributed under the License is distributed on an "AS IS" BASIS, // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. // See the License for the specific language governing permissions and // limitations under the License. #include "examples/xml/xml_writer.h" #include #include #include "examples/xml/xml.pb.h" namespace protobuf_mutator { namespace xml { namespace { class XmlWriter { public: XmlWriter(); std::string ToXml(const Document& doc); private: void ToXml(const std::string& name, const std::string& value); void ToXml(const Element& element); void ToXml(const Content& content); void ToXml(const Misk& misk); void ToXml(const DoctypeDecl& doctype); std::ostringstream out_; }; XmlWriter::XmlWriter() {} void XmlWriter::ToXml(const std::string& name, const std::string& value) { char quote = (name.size() % 2) ? '"' : '\''; out_ << " " << name << "=" << quote << value << quote; } void XmlWriter::ToXml(const Misk& misk) { if (misk.has_pi()) { out_ << ""; } if (misk.has_comment()) { out_ << ""; } } void XmlWriter::ToXml(const DoctypeDecl& doctype) { out_ << ""; } void XmlWriter::ToXml(const Content& content) { if (content.has_char_data()) out_ << content.char_data(); if (content.has_element()) ToXml(content.element()); if (content.has_reference()) { out_ << (content.reference().entry() ? '&' : '%') << content.reference().name() << ';'; } if (content.has_cdsect()) out_ << ""; if (content.has_misk()) ToXml(content.misk()); } void XmlWriter::ToXml(const Element& element) { std::string tag; std::string name; tag += element.tag().name(); out_ << "<" << tag; for (int i = 0; i < element.tag().attribute_size(); ++i) { ToXml(element.tag().attribute(i).name(), element.tag().attribute(i).value()); } if (element.content_size() == 0) { out_ << "/>"; } else { out_ << ">"; for (int i = 0; i < element.content_size(); ++i) ToXml(element.content(i)); out_ << ""; } } std::string XmlWriter::ToXml(const Document& doc) { out_.str(""); if (doc.has_version() || doc.has_encoding() || doc.has_standalone()) { out_ << ""; } for (int i = 0; i < doc.misk1_size(); ++i) ToXml(doc.misk1(i)); if (doc.has_doctype()) ToXml(doc.doctype()); ToXml(doc.element()); for (int i = 0; i < doc.misk2_size(); ++i) ToXml(doc.misk2(i)); return out_.str(); } } // namespace std::string MessageToXml(const Document& document) { XmlWriter writer; return writer.ToXml(document); } } // namespace xml } // namespace protobuf_mutator