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.
This commit is contained in:
parent
a80d944944
commit
e590d90bf6
|
@ -15,6 +15,7 @@
|
||||||
#define _INCLUDE__UTIL__XML_GENERATOR_H_
|
#define _INCLUDE__UTIL__XML_GENERATOR_H_
|
||||||
|
|
||||||
#include <util/string.h>
|
#include <util/string.h>
|
||||||
|
#include <util/print_lines.h>
|
||||||
#include <base/snprintf.h>
|
#include <base/snprintf.h>
|
||||||
|
|
||||||
namespace Genode { class Xml_generator; }
|
namespace Genode { class Xml_generator; }
|
||||||
|
@ -110,10 +111,20 @@ class Genode::Xml_generator
|
||||||
return Out_buffer(_dst + at, len);
|
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
|
* Return number of unused bytes of the buffer
|
||||||
*/
|
*/
|
||||||
size_t used() const { return _used; }
|
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;
|
Out_buffer _out_buffer;
|
||||||
|
|
||||||
bool _has_sub_nodes = false;
|
bool _has_content = false;
|
||||||
|
bool _is_indented = false;
|
||||||
bool _has_attributes = false;
|
bool _has_attributes = false;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -140,15 +152,23 @@ class Genode::Xml_generator
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Called by sub node
|
* 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(">");
|
||||||
|
|
||||||
_out_buffer.append("\n");
|
if (indented)
|
||||||
|
_out_buffer.append("\n");
|
||||||
|
|
||||||
_has_sub_nodes = true;
|
_has_content = true;
|
||||||
|
_is_indented = indented;
|
||||||
|
|
||||||
return _out_buffer.remainder();
|
return _out_buffer.remainder();
|
||||||
}
|
}
|
||||||
|
@ -178,12 +198,21 @@ class Genode::Xml_generator
|
||||||
_attr_offset += gap;
|
_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 <typename FUNC>
|
template <typename FUNC>
|
||||||
Node(Xml_generator &xml, char const *name, FUNC const &func)
|
Node(Xml_generator &xml, char const *name, FUNC const &func)
|
||||||
:
|
:
|
||||||
_indent_level(xml._curr_indent),
|
_indent_level(xml._curr_indent),
|
||||||
_parent_node(xml._curr_node),
|
_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)
|
: xml._out_buffer)
|
||||||
{
|
{
|
||||||
_out_buffer.append('\t', _indent_level);
|
_out_buffer.append('\t', _indent_level);
|
||||||
|
@ -202,9 +231,12 @@ class Genode::Xml_generator
|
||||||
xml._curr_node = _parent_node;
|
xml._curr_node = _parent_node;
|
||||||
xml._curr_indent--;
|
xml._curr_indent--;
|
||||||
|
|
||||||
if (_has_sub_nodes) {
|
if (_is_indented) {
|
||||||
_out_buffer.append("\n");
|
_out_buffer.append("\n");
|
||||||
_out_buffer.append('\t', _indent_level);
|
_out_buffer.append('\t', _indent_level);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (_has_content) {
|
||||||
_out_buffer.append("</");
|
_out_buffer.append("</");
|
||||||
_out_buffer.append(name);
|
_out_buffer.append(name);
|
||||||
_out_buffer.append(">");
|
_out_buffer.append(">");
|
||||||
|
@ -258,6 +290,16 @@ class Genode::Xml_generator
|
||||||
_curr_node->insert_attribute(name, buf);
|
_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(); }
|
size_t used() const { return _out_buffer.used(); }
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue
Block a user