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.
This commit is contained in:
Arseny Kapoulkine 2014-11-06 09:20:34 +01:00
parent f39a73f6e1
commit 224b9b7ba7

View File

@ -972,6 +972,19 @@ namespace pugi
impl::compact_pointer<xml_attribute_struct, 11, 0> first_attribute; ///< First attribute impl::compact_pointer<xml_attribute_struct, 11, 0> 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 #else
namespace pugi namespace pugi
@ -1015,6 +1028,16 @@ namespace pugi
xml_attribute_struct* first_attribute; ///< First attribute 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<uintptr_t>(page)), pi_value(0)
{
}
uintptr_t pi_header;
char_t* pi_value;
};
} }
#endif #endif
@ -1069,12 +1092,22 @@ PUGI__NS_BEGIN
} }
inline xml_node_struct* allocate_node(xml_allocator& alloc, xml_node_type type) inline xml_node_struct* allocate_node(xml_allocator& alloc, xml_node_type type)
{
if (type != node_pi)
{ {
xml_memory_page* page; xml_memory_page* page;
void* memory = alloc.allocate_memory(sizeof(xml_node_struct), page); void* memory = alloc.allocate_memory(sizeof(xml_node_struct), page);
return new (memory) xml_node_struct(page, type); 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_pi_struct(page);
}
}
inline void destroy_attribute(xml_attribute_struct* a, xml_allocator& alloc) inline void destroy_attribute(xml_attribute_struct* a, xml_allocator& alloc)
{ {
@ -3097,7 +3130,8 @@ PUGI__NS_BEGIN
else else
{ {
// store value and step over > // store value and step over >
// TODO: node_pi value:cursor->value = value; static_cast<xml_node_pi_struct*>(cursor)->pi_value = value;
PUGI__POPNODE(); PUGI__POPNODE();
PUGI__ENDSEG(); PUGI__ENDSEG();
@ -4060,10 +4094,10 @@ PUGI__NS_BEGIN
writer.write('<', '?'); writer.write('<', '?');
writer.write_string(node->contents ? node->contents : default_name); writer.write_string(node->contents ? node->contents : default_name);
if (node->contents) if (static_cast<xml_node_pi_struct*>(node)->pi_value)
{ {
writer.write(' '); writer.write(' ');
writer.write_string(node->contents); writer.write_string(static_cast<xml_node_pi_struct*>(node)->pi_value);
} }
writer.write('?', '>'); 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); 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<xml_node_pi_struct*>(dn);
xml_node_pi_struct* snp = static_cast<xml_node_pi_struct*>(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) for (xml_attribute_struct* sa = sn->first_attribute; sa; sa = sa->next_attribute)
{ {
xml_attribute_struct* da = append_new_attribute(dn, get_allocator(dn)); 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 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<xml_node_pi_struct*>(_root)->pi_value)
return static_cast<xml_node_pi_struct*>(_root)->pi_value;
}
return PUGIXML_TEXT("");
} }
PUGI__FN xml_node xml_node::child(const char_t* name_) const PUGI__FN xml_node xml_node::child(const char_t* name_) const
@ -5382,6 +5433,12 @@ namespace pugi
switch (type()) switch (type())
{ {
case node_pi: case node_pi:
{
xml_node_pi_struct* pn = static_cast<xml_node_pi_struct*>(_root);
return impl::strcpy_insitu(pn->pi_value, pn->pi_header, impl::xml_memory_page_contents_allocated_mask, rhs);
}
case node_cdata: case node_cdata:
case node_pcdata: case node_pcdata:
case node_comment: case node_comment: