From 224b9b7ba76311b6a5ab8efec97c16180f721843 Mon Sep 17 00:00:00 2001 From: Arseny Kapoulkine Date: Thu, 6 Nov 2014 09:20:34 +0100 Subject: Add a separate storage class for PI nodes This allows us to add pi value to restore target support for PI nodes without increasing the memory usage for other nodes. Right now the PI node has a separate header that's used for allocated bit; this allows us to reduce header bitcount in the future. --- src/pugixml.cpp | 71 +++++++++++++++++++++++++++++++++++++++++++++++++++------ 1 file changed, 64 insertions(+), 7 deletions(-) (limited to 'src') diff --git a/src/pugixml.cpp b/src/pugixml.cpp index 0fb0fe9..ef9400f 100644 --- a/src/pugixml.cpp +++ b/src/pugixml.cpp @@ -972,6 +972,19 @@ namespace pugi impl::compact_pointer first_attribute; ///< First attribute }; + + struct xml_node_pi_struct: xml_node_struct + { + xml_node_pi_struct(impl::xml_memory_page* page): xml_node_struct(page, node_pi), pi_header(page, 0) + { + PUGI__STATIC_ASSERT(sizeof(xml_node_pi_struct) == 20); + } + + impl::compact_header pi_header; + impl::compact_string<3> pi_value; + + unsigned char padding[2]; + }; } #else namespace pugi @@ -1015,6 +1028,16 @@ namespace pugi xml_attribute_struct* first_attribute; ///< First attribute }; + + struct xml_node_pi_struct: xml_node_struct + { + xml_node_pi_struct(impl::xml_memory_page* page): xml_node_struct(page, node_pi), pi_header(reinterpret_cast(page)), pi_value(0) + { + } + + uintptr_t pi_header; + char_t* pi_value; + }; } #endif @@ -1070,10 +1093,20 @@ PUGI__NS_BEGIN inline xml_node_struct* allocate_node(xml_allocator& alloc, xml_node_type type) { - xml_memory_page* page; - void* memory = alloc.allocate_memory(sizeof(xml_node_struct), page); + if (type != node_pi) + { + xml_memory_page* page; + void* memory = alloc.allocate_memory(sizeof(xml_node_struct), page); + + return new (memory) xml_node_struct(page, type); + } + else + { + xml_memory_page* page; + void* memory = alloc.allocate_memory(sizeof(xml_node_pi_struct), page); - return new (memory) xml_node_struct(page, type); + return new (memory) xml_node_pi_struct(page); + } } inline void destroy_attribute(xml_attribute_struct* a, xml_allocator& alloc) @@ -3097,7 +3130,8 @@ PUGI__NS_BEGIN else { // store value and step over > - // TODO: node_pi value:cursor->value = value; + static_cast(cursor)->pi_value = value; + PUGI__POPNODE(); PUGI__ENDSEG(); @@ -4060,10 +4094,10 @@ PUGI__NS_BEGIN writer.write('<', '?'); writer.write_string(node->contents ? node->contents : default_name); - if (node->contents) + if (static_cast(node)->pi_value) { writer.write(' '); - writer.write_string(node->contents); + writer.write_string(static_cast(node)->pi_value); } writer.write('?', '>'); @@ -4235,6 +4269,14 @@ PUGI__NS_BEGIN { node_copy_string(dn->contents, dn->header, xml_memory_page_contents_allocated_mask, sn->contents, sn->header, shared_alloc); + if (PUGI__NODETYPE(dn) == node_pi) + { + xml_node_pi_struct* dnp = static_cast(dn); + xml_node_pi_struct* snp = static_cast(sn); + + node_copy_string(dnp->pi_value, dnp->pi_header, xml_memory_page_contents_allocated_mask, snp->pi_value, snp->pi_header, shared_alloc); + } + for (xml_attribute_struct* sa = sn->first_attribute; sa; sa = sa->next_attribute) { xml_attribute_struct* da = append_new_attribute(dn, get_allocator(dn)); @@ -5251,7 +5293,16 @@ namespace pugi PUGI__FN const char_t* xml_node::value() const { - return (_root && impl::has_value(_root) && _root->contents) ? _root->contents + 0 : PUGIXML_TEXT(""); + if (_root) + { + if (impl::has_value(_root) && _root->contents) + return _root->contents; + + if (PUGI__NODETYPE(_root) == node_pi && static_cast(_root)->pi_value) + return static_cast(_root)->pi_value; + } + + return PUGIXML_TEXT(""); } PUGI__FN xml_node xml_node::child(const char_t* name_) const @@ -5382,6 +5433,12 @@ namespace pugi switch (type()) { case node_pi: + { + xml_node_pi_struct* pn = static_cast(_root); + + return impl::strcpy_insitu(pn->pi_value, pn->pi_header, impl::xml_memory_page_contents_allocated_mask, rhs); + } + case node_cdata: case node_pcdata: case node_comment: -- cgit v1.2.3