1// (C) Copyright Gennadiy Rozental 2001.
2// Distributed under the Boost Software License, Version 1.0.
3// (See accompanying file LICENSE_1_0.txt or copy at
4// http://www.boost.org/LICENSE_1_0.txt)
5
6// See http://www.boost.org/libs/test for the library home page.
7//
8// File : $RCSfile$
9//
10// Version : $Revision$
11//
12// Description : common code used by any agent serving as OF_XML printer
13// ***************************************************************************
14
15#ifndef BOOST_TEST_UTILS_XML_PRINTER_HPP
16#define BOOST_TEST_UTILS_XML_PRINTER_HPP
17
18// Boost.Test
19#include <boost/test/utils/basic_cstring/basic_cstring.hpp>
20#include <boost/test/utils/custom_manip.hpp>
21#include <boost/test/utils/foreach.hpp>
22#include <boost/test/utils/basic_cstring/io.hpp>
23
24// Boost
25#include <boost/config.hpp>
26
27// STL
28#include <iostream>
29
30#include <boost/test/detail/suppress_warnings.hpp>
31
32//____________________________________________________________________________//
33
34namespace boost {
35namespace unit_test {
36namespace utils {
37
38// ************************************************************************** //
39// ************** xml print helpers ************** //
40// ************************************************************************** //
41
42inline void
43print_escaped( std::ostream& where_to, const_string value )
44{
45#if !defined(BOOST_NO_CXX11_HDR_INITIALIZER_LIST) && !defined(BOOST_NO_CXX11_UNIFIED_INITIALIZATION_SYNTAX)
46 static std::map<char,char const*> const char_type{{
47 {'<' , "lt"},
48 {'>' , "gt"},
49 {'&' , "amp"},
50 {'\'', "apos"},
51 {'"' , "quot"}
52 }};
53#else
54 static std::map<char,char const*> char_type;
55
56 if( char_type.empty() ) {
57 char_type['<'] = "lt";
58 char_type['>'] = "gt";
59 char_type['&'] = "amp";
60 char_type['\'']= "apos";
61 char_type['"'] = "quot";
62 }
63#endif
64
65 BOOST_TEST_FOREACH( char, c, value ) {
66 std::map<char,char const*>::const_iterator found_ref = char_type.find( c );
67
68 if( found_ref != char_type.end() )
69 where_to << '&' << found_ref->second << ';';
70 else
71 where_to << c;
72 }
73}
74
75//____________________________________________________________________________//
76
77inline void
78print_escaped( std::ostream& where_to, std::string const& value )
79{
80 print_escaped( where_to, const_string( value ) );
81}
82
83//____________________________________________________________________________//
84
85template<typename T>
86inline void
87print_escaped( std::ostream& where_to, T const& value )
88{
89 where_to << value;
90}
91
92//____________________________________________________________________________//
93
94inline void
95print_escaped_cdata( std::ostream& where_to, const_string value )
96{
97 static const_string cdata_end( "]]>" );
98
99 const_string::size_type pos = value.find( cdata_end );
100 if( pos == const_string::npos )
101 where_to << value;
102 else {
103 where_to << value.substr( 0, pos+2 ) << cdata_end
104 << BOOST_TEST_L( "<![CDATA[" ) << value.substr( pos+2 );
105 }
106}
107
108//____________________________________________________________________________//
109
110typedef custom_manip<struct attr_value_t> attr_value;
111
112template<typename T>
113inline std::ostream&
114operator<<( custom_printer<attr_value> const& p, T const& value )
115{
116 *p << "=\"";
117 print_escaped( *p, value );
118 *p << '"';
119
120 return *p;
121}
122
123//____________________________________________________________________________//
124
125typedef custom_manip<struct cdata_t> cdata;
126
127inline std::ostream&
128operator<<( custom_printer<cdata> const& p, const_string value )
129{
130 *p << BOOST_TEST_L( "<![CDATA[" );
131 print_escaped_cdata( *p, value );
132 return *p << BOOST_TEST_L( "]]>" );
133}
134
135//____________________________________________________________________________//
136
137} // namespace utils
138} // namespace unit_test
139} // namespace boost
140
141#include <boost/test/detail/enable_warnings.hpp>
142
143#endif // BOOST_TEST_UTILS_XML_PRINTER_HPP
144