diff options
-rw-r--r-- | src/pugixml.cpp | 154 |
1 files changed, 97 insertions, 57 deletions
diff --git a/src/pugixml.cpp b/src/pugixml.cpp index 085d4e3..b6559e7 100644 --- a/src/pugixml.cpp +++ b/src/pugixml.cpp @@ -602,33 +602,105 @@ PUGI__NS_BEGIN alloc.deallocate_memory(n, sizeof(xml_node_struct), reinterpret_cast<xml_memory_page*>(header & xml_memory_page_pointer_mask)); } - PUGI__FN_NO_INLINE xml_node_struct* append_node(xml_node_struct* node, xml_allocator& alloc, xml_node_type type = node_element) + inline void append_node(xml_node_struct* child, xml_node_struct* node) { - xml_node_struct* child = allocate_node(alloc, type); - if (!child) return 0; - child->parent = node; - xml_node_struct* first_child = node->first_child; - - if (first_child) + xml_node_struct* head = node->first_child; + + if (head) { - xml_node_struct* last_child = first_child->prev_sibling_c; + xml_node_struct* tail = head->prev_sibling_c; - last_child->next_sibling = child; - child->prev_sibling_c = last_child; - first_child->prev_sibling_c = child; + tail->next_sibling = child; + child->prev_sibling_c = tail; + head->prev_sibling_c = child; } else { node->first_child = child; child->prev_sibling_c = child; } - + } + + inline void prepend_node(xml_node_struct* child, xml_node_struct* node) + { + child->parent = node; + + xml_node_struct* head = node->first_child; + + if (head) + { + child->prev_sibling_c = head->prev_sibling_c; + head->prev_sibling_c = child; + } + else + child->prev_sibling_c = child; + + child->next_sibling = head; + node->first_child = child; + } + + inline void insert_node_before(xml_node_struct* child, xml_node_struct* node) + { + xml_node_struct* parent = node->parent; + + child->parent = parent; + + if (node->prev_sibling_c->next_sibling) + node->prev_sibling_c->next_sibling = child; + else + parent->first_child = child; + + child->prev_sibling_c = node->prev_sibling_c; + child->next_sibling = node; + + node->prev_sibling_c = child; + } + + inline void insert_node_after(xml_node_struct* child, xml_node_struct* node) + { + xml_node_struct* parent = node->parent; + + child->parent = parent; + + if (node->next_sibling) + node->next_sibling->prev_sibling_c = child; + else + parent->first_child->prev_sibling_c = child; + + child->next_sibling = node->next_sibling; + child->prev_sibling_c = node; + + node->next_sibling = child; + } + + inline void remove_node(xml_node_struct* node) + { + xml_node_struct* parent = node->parent; + + if (node->next_sibling) + node->next_sibling->prev_sibling_c = node->prev_sibling_c; + else if (parent->first_child) + parent->first_child->prev_sibling_c = node->prev_sibling_c; + + if (node->prev_sibling_c->next_sibling) + node->prev_sibling_c->next_sibling = node->next_sibling; + else + parent->first_child = node->next_sibling; + } + + PUGI__FN_NO_INLINE xml_node_struct* append_new_node(xml_node_struct* node, xml_allocator& alloc, xml_node_type type = node_element) + { + xml_node_struct* child = allocate_node(alloc, type); + if (!child) return 0; + + append_node(child, node); + return child; } - PUGI__FN_NO_INLINE xml_attribute_struct* append_attribute_ll(xml_node_struct* node, xml_allocator& alloc) + PUGI__FN_NO_INLINE xml_attribute_struct* append_new_attribute(xml_node_struct* node, xml_allocator& alloc) { xml_attribute_struct* a = allocate_attribute(alloc); if (!a) return 0; @@ -2139,7 +2211,7 @@ PUGI__NS_BEGIN // Parser utilities. #define PUGI__SKIPWS() { while (PUGI__IS_CHARTYPE(*s, ct_space)) ++s; } #define PUGI__OPTSET(OPT) ( optmsk & (OPT) ) - #define PUGI__PUSHNODE(TYPE) { cursor = append_node(cursor, alloc, TYPE); if (!cursor) PUGI__THROW_ERROR(status_out_of_memory, s); } + #define PUGI__PUSHNODE(TYPE) { cursor = append_new_node(cursor, alloc, TYPE); if (!cursor) PUGI__THROW_ERROR(status_out_of_memory, s); } #define PUGI__POPNODE() { cursor = cursor->parent; } #define PUGI__SCANFOR(X) { while (*s != 0 && !(X)) ++s; } #define PUGI__SCANWHILE(X) { while ((X)) ++s; } @@ -2503,7 +2575,7 @@ PUGI__NS_BEGIN if (PUGI__IS_CHARTYPE(*s, ct_start_symbol)) // <... #... { - xml_attribute_struct* a = append_attribute_ll(cursor, alloc); // Make space for this attribute. + xml_attribute_struct* a = append_new_attribute(cursor, alloc); // Make space for this attribute. if (!a) PUGI__THROW_ERROR(status_out_of_memory, s); a->name = s; // Save the offset. @@ -4494,7 +4566,7 @@ namespace pugi { if (type() != node_element && type() != node_declaration) return xml_attribute(); - xml_attribute a(impl::append_attribute_ll(_root, impl::get_allocator(_root))); + xml_attribute a(impl::append_new_attribute(_root, impl::get_allocator(_root))); a.set_name(name_); return a; @@ -4625,7 +4697,10 @@ namespace pugi { if (!impl::allow_insert_child(this->type(), type_)) return xml_node(); - xml_node n(impl::append_node(_root, impl::get_allocator(_root), type_)); + xml_node n(impl::allocate_node(impl::get_allocator(_root), type_)); + if (!n) return xml_node(); + + impl::append_node(n._root, _root); if (type_ == node_declaration) n.set_name(PUGIXML_TEXT("xml")); @@ -4639,20 +4714,7 @@ namespace pugi xml_node n(impl::allocate_node(impl::get_allocator(_root), type_)); if (!n) return xml_node(); - n._root->parent = _root; - - xml_node_struct* head = _root->first_child; - - if (head) - { - n._root->prev_sibling_c = head->prev_sibling_c; - head->prev_sibling_c = n._root; - } - else - n._root->prev_sibling_c = n._root; - - n._root->next_sibling = head; - _root->first_child = n._root; + impl::prepend_node(n._root, _root); if (type_ == node_declaration) n.set_name(PUGIXML_TEXT("xml")); @@ -4667,16 +4729,7 @@ namespace pugi xml_node n(impl::allocate_node(impl::get_allocator(_root), type_)); if (!n) return xml_node(); - n._root->parent = _root; - - if (node._root->prev_sibling_c->next_sibling) - node._root->prev_sibling_c->next_sibling = n._root; - else - _root->first_child = n._root; - - n._root->prev_sibling_c = node._root->prev_sibling_c; - n._root->next_sibling = node._root; - node._root->prev_sibling_c = n._root; + impl::insert_node_before(n._root, node._root); if (type_ == node_declaration) n.set_name(PUGIXML_TEXT("xml")); @@ -4691,16 +4744,7 @@ namespace pugi xml_node n(impl::allocate_node(impl::get_allocator(_root), type_)); if (!n) return xml_node(); - n._root->parent = _root; - - if (node._root->next_sibling) - node._root->next_sibling->prev_sibling_c = n._root; - else - _root->first_child->prev_sibling_c = n._root; - - n._root->next_sibling = node._root->next_sibling; - n._root->prev_sibling_c = node._root; - node._root->next_sibling = n._root; + impl::insert_node_after(n._root, node._root); if (type_ == node_declaration) n.set_name(PUGIXML_TEXT("xml")); @@ -4815,12 +4859,8 @@ namespace pugi { if (!_root || !n._root || n._root->parent != _root) return false; - if (n._root->next_sibling) n._root->next_sibling->prev_sibling_c = n._root->prev_sibling_c; - else if (_root->first_child) _root->first_child->prev_sibling_c = n._root->prev_sibling_c; - - if (n._root->prev_sibling_c->next_sibling) n._root->prev_sibling_c->next_sibling = n._root->next_sibling; - else _root->first_child = n._root->next_sibling; - + impl::remove_node(n._root); + impl::destroy_node(n._root, impl::get_allocator(_root)); return true; |