Alan M. Carroll - 2008-08-08

I have been working with RapidXML as my primary XML parser. It works well, but I was wondering if you had considered an improvement I made to increase ease of use. I did it in another header, to minimize impact on the distribution, but it would go something like this --

template < typename Ch = char >
struct copy
{
    Ch const * _s; ///< Pointer to data.
    size_t _n; ///< Size (optional - if zero, presume C-string

    /// Constructor from C-string.
    copy(String value) : _s(value), _n(0) {}
    /// Construct from memory chunk.
    copy(String value, size_t size) : _s(value), _n(size) {}
    /// Copy to document
    Ch const * get(memory_pool* pool) const
    {
        return pool->allocate_string(_s,_n);
    }
};

// Now add some overloads

memory_pool::allocate_node(node_type type, Ch const* name, copy const& value, size_t name_size = 0)
{
    return this->allocate_node(type, name, this->allocate_string(value._s, value._n), name_size, value._n);
}

memory_pool::allocate_node(node_type type, copy const& name, copy const& value,)
{
    return this->allocate_node(type, this->allocate_string(name._s, name._n), this->allocate_string(value._s, value._n), name_size, name._n, value._n);
}

// Client use

xml_document<> xd;
char *some_name, *some_value; // initialized somehow
// Copy name and value
xd.append_node(xd.allocate_node(node_element, copy<>(some_name), copy<>(some_value)));
// Copy just the value with null terminated name
xd.append_node(xd.allocate_node(node_element, some_name, copy<>(some_value)));
// Copy just the value with name length specified
xd.append_node(xd.allocate_node(node_element, some_name, copy<>(some_value), name_count));
// Copy just the value with value length specified
xd.append_node(xd.allocate_node(node_element, some_name, copy<>(some_value, value_count)));
// Copy value but not name with lengths specified is a bit awkward,
// but an overload could take care of that.
// memory_pool::allocate_node(node_type type, Ch const* name, size_t name_size, copy const& value )
xd.append_node(xd.allocate_node(node_element, some_name, copy<>(some_value, value_count), name_count));