1 /*
2  *  Created by Phil on 09/12/2010.
3  *  Copyright 2010 Two Blue Cubes Ltd. All rights reserved.
4  *
5  *  Distributed under the Boost Software License, Version 1.0. (See accompanying
6  *  file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
7  */
8 #ifndef TWOBLUECUBES_CATCH_XMLWRITER_HPP_INCLUDED
9 #define TWOBLUECUBES_CATCH_XMLWRITER_HPP_INCLUDED
10 
11 #include "catch_stream.h"
12 #include "catch_compiler_capabilities.h"
13 
14 #include <vector>
15 
16 namespace Catch {
17 
18     class XmlEncode {
19     public:
20         enum ForWhat { ForTextNodes, ForAttributes };
21 
22         XmlEncode( std::string const& str, ForWhat forWhat = ForTextNodes );
23 
24         void encodeTo( std::ostream& os ) const;
25 
26         friend std::ostream& operator << ( std::ostream& os, XmlEncode const& xmlEncode );
27 
28     private:
29         std::string m_str;
30         ForWhat m_forWhat;
31     };
32 
33     class XmlWriter {
34     public:
35 
36         class ScopedElement {
37         public:
38             ScopedElement( XmlWriter* writer );
39 
40             ScopedElement( ScopedElement&& other ) noexcept;
41             ScopedElement& operator=( ScopedElement&& other ) noexcept;
42 
43             ~ScopedElement();
44 
45             ScopedElement& writeText( std::string const& text, bool indent = true );
46 
47             template<typename T>
writeAttribute(std::string const & name,T const & attribute)48             ScopedElement& writeAttribute( std::string const& name, T const& attribute ) {
49                 m_writer->writeAttribute( name, attribute );
50                 return *this;
51             }
52 
53         private:
54             mutable XmlWriter* m_writer = nullptr;
55         };
56 
57         XmlWriter( std::ostream& os = Catch::cout() );
58         ~XmlWriter();
59 
60         XmlWriter( XmlWriter const& ) = delete;
61         XmlWriter& operator=( XmlWriter const& ) = delete;
62 
63         XmlWriter& startElement( std::string const& name );
64 
65         ScopedElement scopedElement( std::string const& name );
66 
67         XmlWriter& endElement();
68 
69         XmlWriter& writeAttribute( std::string const& name, std::string const& attribute );
70 
71         XmlWriter& writeAttribute( std::string const& name, bool attribute );
72 
73         template<typename T>
writeAttribute(std::string const & name,T const & attribute)74         XmlWriter& writeAttribute( std::string const& name, T const& attribute ) {
75             ReusableStringStream rss;
76             rss << attribute;
77             return writeAttribute( name, rss.str() );
78         }
79 
80         XmlWriter& writeText( std::string const& text, bool indent = true );
81 
82         XmlWriter& writeComment( std::string const& text );
83 
84         void writeStylesheetRef( std::string const& url );
85 
86         XmlWriter& writeBlankLine();
87 
88         void ensureTagClosed();
89 
90     private:
91 
92         void writeDeclaration();
93 
94         void newlineIfNecessary();
95 
96         bool m_tagIsOpen = false;
97         bool m_needsNewline = false;
98         std::vector<std::string> m_tags;
99         std::string m_indent;
100         std::ostream& m_os;
101     };
102 
103 }
104 
105 #endif // TWOBLUECUBES_CATCH_XMLWRITER_HPP_INCLUDED
106