summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/pugixml.cpp105
1 files changed, 62 insertions, 43 deletions
diff --git a/src/pugixml.cpp b/src/pugixml.cpp
index 163af21..5e9c4b8 100644
--- a/src/pugixml.cpp
+++ b/src/pugixml.cpp
@@ -1845,7 +1845,11 @@ PUGI__NS_BEGIN
char_t* buffer = static_cast<char_t*>(xml_memory::allocate((length + 1) * sizeof(char_t)));
if (!buffer) return false;
- memcpy(buffer, contents, length * sizeof(char_t));
+ if (contents)
+ memcpy(buffer, contents, length * sizeof(char_t));
+ else
+ assert(length == 0);
+
buffer[length] = 0;
out_buffer = buffer;
@@ -3016,8 +3020,6 @@ PUGI__NS_BEGIN
PUGI__PUSHNODE(node_doctype);
cursor->contents = mark;
-
- PUGI__POPNODE();
}
}
else if (*s == 0 && endch == '-') PUGI__THROW_ERROR(status_bad_comment, s);
@@ -4156,7 +4158,7 @@ PUGI__NS_BEGIN
while (node != root);
}
- PUGI__FN bool has_declaration(const xml_node node)
+ PUGI__FN bool has_declaration(xml_node node)
{
for (xml_node child = node.first_child(); child; child = child.next_sibling())
{
@@ -4187,7 +4189,7 @@ PUGI__NS_BEGIN
return true;
}
- PUGI__FN bool allow_move(const xml_node parent, const xml_node child)
+ PUGI__FN bool allow_move(xml_node parent, xml_node child)
{
// check that child can be a child of parent
if (!allow_insert_child(parent.type(), child.type()))
@@ -7875,7 +7877,7 @@ PUGI__NS_BEGIN
prefix_length = pos ? static_cast<size_t>(pos - name) : 0;
}
- bool operator()(const xml_attribute a) const
+ bool operator()(xml_attribute a) const
{
const char_t* name = a.name();
@@ -7885,7 +7887,7 @@ PUGI__NS_BEGIN
}
};
- PUGI__FN const char_t* namespace_uri(const xml_node node)
+ PUGI__FN const char_t* namespace_uri(xml_node node)
{
namespace_uri_predicate pred = node.name();
@@ -7903,7 +7905,7 @@ PUGI__NS_BEGIN
return PUGIXML_TEXT("");
}
- PUGI__FN const char_t* namespace_uri(const xml_attribute attr, const xml_node parent)
+ PUGI__FN const char_t* namespace_uri(xml_attribute attr, xml_node parent)
{
namespace_uri_predicate pred = attr.name();
@@ -8318,6 +8320,8 @@ PUGI__NS_BEGIN
void append(const xpath_node* begin_, const xpath_node* end_, xpath_allocator* alloc)
{
+ if (begin_ == end_) return;
+
size_t size_ = static_cast<size_t>(_end - _begin);
size_t capacity = static_cast<size_t>(_eos - _begin);
size_t count = static_cast<size_t>(end_ - begin_);
@@ -9051,44 +9055,59 @@ PUGI__NS_BEGIN
}
}
- static void apply_predicate(xpath_node_set_raw& ns, size_t first, xpath_ast_node* expr, const xpath_stack& stack, bool once)
+ static void apply_predicate_boolean(xpath_node_set_raw& ns, size_t first, xpath_ast_node* expr, const xpath_stack& stack, bool once)
{
assert(ns.size() >= first);
+ assert(expr->rettype() != xpath_type_number);
size_t i = 1;
size_t size = ns.size() - first;
-
+
xpath_node* last = ns.begin() + first;
// remove_if... or well, sort of
for (xpath_node* it = last; it != ns.end(); ++it, ++i)
{
xpath_context c(*it, i, size);
-
- if (expr->rettype() == xpath_type_number)
+
+ if (expr->eval_boolean(c, stack))
{
- if (expr->eval_number(c, stack) == i)
- {
- *last++ = *it;
+ *last++ = *it;
- if (once) break;
- }
+ if (once) break;
}
- else
+ }
+
+ ns.truncate(last);
+ }
+
+ static void apply_predicate_number(xpath_node_set_raw& ns, size_t first, xpath_ast_node* expr, const xpath_stack& stack, bool once)
+ {
+ assert(ns.size() >= first);
+ assert(expr->rettype() == xpath_type_number);
+
+ size_t i = 1;
+ size_t size = ns.size() - first;
+
+ xpath_node* last = ns.begin() + first;
+
+ // remove_if... or well, sort of
+ for (xpath_node* it = last; it != ns.end(); ++it, ++i)
+ {
+ xpath_context c(*it, i, size);
+
+ if (expr->eval_number(c, stack) == i)
{
- if (expr->eval_boolean(c, stack))
- {
- *last++ = *it;
+ *last++ = *it;
- if (once) break;
- }
+ if (once) break;
}
}
-
+
ns.truncate(last);
}
- static void apply_predicate_const(xpath_node_set_raw& ns, size_t first, xpath_ast_node* expr, const xpath_stack& stack)
+ static void apply_predicate_number_const(xpath_node_set_raw& ns, size_t first, xpath_ast_node* expr, const xpath_stack& stack)
{
assert(ns.size() >= first);
assert(expr->rettype() == xpath_type_number);
@@ -9116,21 +9135,28 @@ PUGI__NS_BEGIN
ns.truncate(last);
}
+ void apply_predicate(xpath_node_set_raw& ns, size_t first, const xpath_stack& stack, bool once)
+ {
+ if (ns.size() == first) return;
+
+ assert(_type == ast_filter || _type == ast_predicate);
+
+ if (_test == predicate_constant || _test == predicate_constant_one)
+ apply_predicate_number_const(ns, first, _right, stack);
+ else if (_right->rettype() == xpath_type_number)
+ apply_predicate_number(ns, first, _right, stack, once);
+ else
+ apply_predicate_boolean(ns, first, _right, stack, once);
+ }
+
void apply_predicates(xpath_node_set_raw& ns, size_t first, const xpath_stack& stack, nodeset_eval_t eval)
{
if (ns.size() == first) return;
-
+
bool last_once = eval_once(ns.type() == xpath_node_set::type_sorted, eval);
for (xpath_ast_node* pred = _right; pred; pred = pred->_next)
- {
- assert(pred->_type == ast_predicate);
-
- if (pred->_test == predicate_constant || pred->_test == predicate_constant_one)
- apply_predicate_const(ns, first, pred->_right, stack);
- else
- apply_predicate(ns, first, pred->_right, stack, !pred->_next && last_once);
- }
+ pred->apply_predicate(ns, first, stack, !pred->_next && last_once);
}
bool step_push(xpath_node_set_raw& ns, xml_attribute_struct* a, xml_node_struct* parent, xpath_allocator* alloc)
@@ -10208,16 +10234,9 @@ PUGI__NS_BEGIN
// either expression is a number or it contains position() call; sort by document order
if (_test != predicate_posinv) set.sort_do();
- if (_test == predicate_constant || _test == predicate_constant_one)
- {
- apply_predicate_const(set, 0, _right, stack);
- }
- else
- {
- bool once = eval_once(set.type() == xpath_node_set::type_sorted, eval);
+ bool once = eval_once(set.type() == xpath_node_set::type_sorted, eval);
- apply_predicate(set, 0, _right, stack, once);
- }
+ apply_predicate(set, 0, stack, once);
return set;
}