20 size_t trailingBytes(
unsigned char c) {
21 if ((c & 0xE0) == 0xC0) {
24 if ((c & 0xF0) == 0xE0) {
27 if ((c & 0xF8) == 0xF0) {
33 uint32_t headerValue(
unsigned char c) {
34 if ((c & 0xE0) == 0xC0) {
37 if ((c & 0xF0) == 0xE0) {
40 if ((c & 0xF8) == 0xF0) {
46 void hexEscapeChar(std::ostream&
os,
unsigned char c) {
47 std::ios_base::fmtflags
f(
os.flags());
49 << std::uppercase << std::hex << std::setfill(
'0') << std::setw(2)
50 <<
static_cast<int>(c);
65 for( std::size_t idx = 0; idx < m_str.size(); ++ idx ) {
68 case '<':
os <<
"<";
break;
69 case '&':
os <<
"&";
break;
73 if (idx > 2 && m_str[idx - 1] ==
']' && m_str[idx - 2] ==
']')
91 if (c < 0x09 || (c > 0x0D && c < 0x20) || c == 0x7F) {
110 hexEscapeChar(
os, c);
114 auto encBytes = trailingBytes(c);
116 if (idx + encBytes - 1 >= m_str.size()) {
117 hexEscapeChar(
os, c);
125 for (std::size_t n = 1; n < encBytes; ++n) {
126 uchar nc = m_str[idx + n];
127 valid &= ((nc & 0xC0) == 0x80);
141 hexEscapeChar(
os, c);
146 for (std::size_t n = 0; n < encBytes; ++n) {
147 os << m_str[idx + n];
165 : m_writer( other.m_writer ){
166 other.m_writer =
nullptr;
170 m_writer->endElement();
172 m_writer = other.m_writer;
173 other.m_writer =
nullptr;
180 m_writer->endElement();
184 m_writer->writeText( text, indent );
194 while( !m_tags.empty() )
200 newlineIfNecessary();
201 m_os << m_indent <<
'<' <<
name;
202 m_tags.push_back(
name );
215 newlineIfNecessary();
216 m_indent = m_indent.substr( 0, m_indent.size()-2 );
222 m_os << m_indent <<
"</" << m_tags.back() <<
">";
230 if( !
name.empty() && !attribute.empty() )
236 m_os <<
' ' <<
name <<
"=\"" << ( attribute ?
"true" :
"false" ) <<
'"';
242 bool tagWasOpen = m_tagIsOpen;
244 if( tagWasOpen && indent )
247 m_needsNewline =
true;
254 m_os << m_indent <<
"<!--" << text <<
"-->";
255 m_needsNewline =
true;
260 m_os <<
"<?xml-stylesheet type=\"text/xsl\" href=\"" <<
url <<
"\"?>\n";
271 m_os <<
">" << std::endl;
276 void XmlWriter::writeDeclaration() {
277 m_os <<
"<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n";
280 void XmlWriter::newlineIfNecessary() {
281 if( m_needsNewline ) {
283 m_needsNewline =
false;
#define CATCH_INTERNAL_ERROR(msg)
void encodeTo(std::ostream &os) const
XmlEncode(std::string const &str, ForWhat forWhat=ForTextNodes)
ScopedElement & writeText(std::string const &text, bool indent=true)
ScopedElement & operator=(ScopedElement &&other) noexcept
ScopedElement(XmlWriter *writer)
XmlWriter(std::ostream &os=Catch::cout())
ScopedElement scopedElement(std::string const &name)
XmlWriter & writeText(std::string const &text, bool indent=true)
XmlWriter & startElement(std::string const &name)
void writeStylesheetRef(std::string const &url)
XmlWriter & writeComment(std::string const &text)
XmlWriter & writeBlankLine()
XmlWriter & writeAttribute(std::string const &name, std::string const &attribute)
auto operator<<(std::ostream &os, LazyExpression const &lazyExpr) -> std::ostream &