From e590d90bf60ad0d798289143bc5e21c9abe1d39c Mon Sep 17 00:00:00 2001 From: Norman Feske Date: Tue, 22 Sep 2015 17:09:22 +0200 Subject: [PATCH] xml_generator: support appending of node content The new 'Xml_generator::append' method can be used to append strings into the body of an XML node. --- repos/os/include/util/xml_generator.h | 56 +++++++++++++++++++++++---- 1 file changed, 49 insertions(+), 7 deletions(-) diff --git a/repos/os/include/util/xml_generator.h b/repos/os/include/util/xml_generator.h index 89a879f6e..a35313c23 100644 --- a/repos/os/include/util/xml_generator.h +++ b/repos/os/include/util/xml_generator.h @@ -15,6 +15,7 @@ #define _INCLUDE__UTIL__XML_GENERATOR_H_ #include +#include #include namespace Genode { class Xml_generator; } @@ -110,10 +111,20 @@ class Genode::Xml_generator return Out_buffer(_dst + at, len); } + bool has_trailing_newline() const + { + return (_used > 1) && (_dst[_used - 1] == '\n'); + } + /** * Return number of unused bytes of the buffer */ size_t used() const { return _used; } + + void discard_trailing_whitespace() + { + for (; _used > 0 && is_whitespace(_dst[_used - 1]); _used--); + } }; @@ -130,7 +141,8 @@ class Genode::Xml_generator Out_buffer _out_buffer; - bool _has_sub_nodes = false; + bool _has_content = false; + bool _is_indented = false; bool _has_attributes = false; /** @@ -140,15 +152,23 @@ class Genode::Xml_generator /** * Called by sub node + * + * \param indented if true, the returned buffer and the + * end tag start at a fresh line. This is the + * case if the content buffer contains sub + * nodes. But when inserting raw content, + * such additional whitespaces are not desired. */ - Out_buffer _content_buffer() + Out_buffer _content_buffer(bool indented) { - if (!_has_sub_nodes) + if (!_has_content) _out_buffer.append(">"); - _out_buffer.append("\n"); + if (indented) + _out_buffer.append("\n"); - _has_sub_nodes = true; + _has_content = true; + _is_indented = indented; return _out_buffer.remainder(); } @@ -178,12 +198,21 @@ class Genode::Xml_generator _attr_offset += gap; } + void append(char const *src, size_t src_len) + { + Out_buffer content_buffer = _content_buffer(false); + + content_buffer.append(src, src_len); + + _commit_content(content_buffer); + } + template Node(Xml_generator &xml, char const *name, FUNC const &func) : _indent_level(xml._curr_indent), _parent_node(xml._curr_node), - _out_buffer(_parent_node ? _parent_node->_content_buffer() + _out_buffer(_parent_node ? _parent_node->_content_buffer(true) : xml._out_buffer) { _out_buffer.append('\t', _indent_level); @@ -202,9 +231,12 @@ class Genode::Xml_generator xml._curr_node = _parent_node; xml._curr_indent--; - if (_has_sub_nodes) { + if (_is_indented) { _out_buffer.append("\n"); _out_buffer.append('\t', _indent_level); + } + + if (_has_content) { _out_buffer.append(""); @@ -258,6 +290,16 @@ class Genode::Xml_generator _curr_node->insert_attribute(name, buf); } + /** + * Append content to XML node + * + * This method must not be followed by calls of 'attribute'. + */ + void append(char const *str, size_t str_len = ~0UL) + { + _curr_node->append(str, str_len == ~0UL ? strlen(str) : str_len); + } + size_t used() const { return _out_buffer.used(); } };