diff --git a/src/pugixml.cpp b/src/pugixml.cpp index 89123c7..0a493be 100644 --- a/src/pugixml.cpp +++ b/src/pugixml.cpp @@ -247,6 +247,16 @@ PUGI_IMPL_NS_BEGIN #endif } + // Compare lhs (0 terminated) with [rhs_begin, rhs_end) + PUGI_IMPL_FN bool strequal(const char_t* lhs, const char_t* rhs, size_t count) + { + for (size_t i = 0; i < count; ++i) + if (lhs[i] == 0 || lhs[i] != rhs[i]) + return false; + + return lhs[count] == 0; + } + // Compare lhs with [rhs_begin, rhs_end) PUGI_IMPL_FN bool strequalrange(const char_t* lhs, const char_t* rhs, size_t count) { @@ -5656,6 +5666,20 @@ namespace pugi return xml_node(); } + PUGI_IMPL_FN xml_node xml_node::child(const char_t* name_, size_t sz) const + { + if (!_root) return xml_node(); + + for (xml_node_struct* i = _root->first_child; i; i = i->next_sibling) + { + const char_t* iname = i->name; + if (iname && impl::strequal(iname, name_, sz)) + return xml_node(i); + } + + return xml_node(); + } + PUGI_IMPL_FN xml_attribute xml_node::attribute(const char_t* name_) const { if (!_root) return xml_attribute(); @@ -5670,6 +5694,20 @@ namespace pugi return xml_attribute(); } + PUGI_IMPL_FN xml_attribute xml_node::attribute(const char_t* name_, size_t sz) const + { + if (!_root) return xml_attribute(); + + for (xml_attribute_struct* i = _root->first_attribute; i; i = i->next_attribute) + { + const char_t* iname = i->name; + if (iname && impl::strequal(iname, name_, sz)) + return xml_attribute(i); + } + + return xml_attribute(); + } + PUGI_IMPL_FN xml_node xml_node::next_sibling(const char_t* name_) const { if (!_root) return xml_node(); @@ -5870,6 +5908,23 @@ namespace pugi return a; } + PUGI_IMPL_FN xml_attribute xml_node::append_attribute(const char_t* name_, size_t sz) + { + if (!impl::allow_insert_attribute(type())) return xml_attribute(); + + impl::xml_allocator& alloc = impl::get_allocator(_root); + if (!alloc.reserve()) return xml_attribute(); + + xml_attribute a(impl::allocate_attribute(alloc)); + if (!a) return xml_attribute(); + + impl::append_attribute(a._attr, _root); + + a.set_name(name_, sz); + + return a; + } + PUGI_IMPL_FN xml_attribute xml_node::prepend_attribute(const char_t* name_) { if (!impl::allow_insert_attribute(type())) return xml_attribute(); @@ -6072,6 +6127,16 @@ namespace pugi return result; } + + PUGI_IMPL_FN xml_node xml_node::append_child(const char_t* name_, size_t sz) + { + xml_node result = append_child(node_element); + + result.set_name(name_, sz); + + return result; + } + PUGI_IMPL_FN xml_node xml_node::prepend_child(const char_t* name_) { xml_node result = prepend_child(node_element); diff --git a/src/pugixml.hpp b/src/pugixml.hpp index d17a7e6..9a0406b 100644 --- a/src/pugixml.hpp +++ b/src/pugixml.hpp @@ -543,7 +543,9 @@ namespace pugi // Get child, attribute or next/previous sibling with the specified name xml_node child(const char_t* name) const; + xml_node child(const char_t* name, size_t sz) const; xml_attribute attribute(const char_t* name) const; + xml_attribute attribute(const char_t* name, size_t) const; xml_node next_sibling(const char_t* name) const; xml_node previous_sibling(const char_t* name) const; @@ -564,6 +566,7 @@ namespace pugi // Add attribute with specified name. Returns added attribute, or empty attribute on errors. xml_attribute append_attribute(const char_t* name); + xml_attribute append_attribute(const char_t* name, size_t sz); xml_attribute prepend_attribute(const char_t* name); xml_attribute insert_attribute_after(const char_t* name, const xml_attribute& attr); xml_attribute insert_attribute_before(const char_t* name, const xml_attribute& attr); @@ -582,6 +585,7 @@ namespace pugi // Add child element with specified name. Returns added node, or empty node on errors. xml_node append_child(const char_t* name); + xml_node append_child(const char_t* name, size_t sz); xml_node prepend_child(const char_t* name); xml_node insert_child_after(const char_t* name, const xml_node& node); xml_node insert_child_before(const char_t* name, const xml_node& node);