summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorarseny.kapoulkine <arseny.kapoulkine@99668b35-9821-0410-8761-19e4c4f06640>2010-09-13 20:02:04 +0000
committerarseny.kapoulkine <arseny.kapoulkine@99668b35-9821-0410-8761-19e4c4f06640>2010-09-13 20:02:04 +0000
commit0f7684b5671f8fd9ac461f1c75c3a04ba13cb65f (patch)
tree77db1e8772a923a0f40adc339183a6d7994dd58e
parent0b60037afccd5f22339658bc9c9a3bc2feae46ec (diff)
XPath: Stack construction refactoring
git-svn-id: http://pugixml.googlecode.com/svn/trunk@725 99668b35-9821-0410-8761-19e4c4f06640
-rw-r--r--src/pugixml.cpp91
1 files changed, 49 insertions, 42 deletions
diff --git a/src/pugixml.cpp b/src/pugixml.cpp
index 228dd9e..3e32217 100644
--- a/src/pugixml.cpp
+++ b/src/pugixml.cpp
@@ -4745,17 +4745,7 @@ namespace pugi
// free all allocated pages
xpath_allocator* alloc = static_cast<xpath_allocator*>(ptr);
- xpath_memory_block* cur = alloc->_root;
- assert(cur);
-
- while (cur->next)
- {
- xpath_memory_block* next = cur->next;
-
- global_deallocate(cur);
-
- cur = next;
- }
+ alloc->release();
// free allocator memory (with the first page)
global_deallocate(alloc);
@@ -4835,7 +4825,7 @@ namespace pugi
return result;
}
- void revert(xpath_allocator& state)
+ void revert(const xpath_allocator& state)
{
// free all new pages
xpath_memory_block* cur = _root;
@@ -4853,6 +4843,21 @@ namespace pugi
_root = state._root;
_root_size = state._root_size;
}
+
+ void release()
+ {
+ xpath_memory_block* cur = _root;
+ assert(cur);
+
+ while (cur->next)
+ {
+ xpath_memory_block* next = cur->next;
+
+ global_deallocate(cur);
+
+ cur = next;
+ }
+ }
};
struct xpath_allocator_capture
@@ -4875,6 +4880,28 @@ namespace pugi
xpath_allocator* result;
xpath_allocator* temp;
};
+
+ struct xpath_stack_data
+ {
+ xpath_memory_block blocks[2];
+ xpath_allocator result;
+ xpath_allocator temp;
+ xpath_stack stack;
+
+ xpath_stack_data(): result(blocks + 0), temp(blocks + 1)
+ {
+ blocks[0].next = blocks[1].next = 0;
+
+ stack.result = &result;
+ stack.temp = &temp;
+ }
+
+ ~xpath_stack_data()
+ {
+ result.release();
+ temp.release();
+ }
+ };
}
// String class
@@ -8973,13 +9000,9 @@ namespace pugi
if (!_root) return false;
xpath_context c(n, 1, 1);
+ xpath_stack_data sd;
- xpath_memory_block resultblock, tempblock;
- xpath_allocator result(&resultblock), temp(&tempblock);
- xpath_allocator_capture cr(&result), ct(&temp);
- xpath_stack stack = {&result, &temp};
-
- return _root->eval_boolean(c, stack);
+ return _root->eval_boolean(c, sd.stack);
}
double xpath_query::evaluate_number(const xpath_node& n) const
@@ -8987,13 +9010,9 @@ namespace pugi
if (!_root) return gen_nan();
xpath_context c(n, 1, 1);
-
- xpath_memory_block resultblock, tempblock;
- xpath_allocator result(&resultblock), temp(&tempblock);
- xpath_allocator_capture cr(&result), ct(&temp);
- xpath_stack stack = {&result, &temp};
+ xpath_stack_data sd;
- return _root->eval_number(c, stack);
+ return _root->eval_number(c, sd.stack);
}
#ifndef PUGIXML_NO_STL
@@ -9002,26 +9021,18 @@ namespace pugi
if (!_root) return string_t();
xpath_context c(n, 1, 1);
-
- xpath_memory_block resultblock, tempblock;
- xpath_allocator result(&resultblock), temp(&tempblock);
- xpath_allocator_capture cr(&result), ct(&temp);
- xpath_stack stack = {&result, &temp};
+ xpath_stack_data sd;
- return _root->eval_string(c, stack).c_str();
+ return _root->eval_string(c, sd.stack).c_str();
}
#endif
size_t xpath_query::evaluate_string(char_t* buffer, size_t capacity, const xpath_node& n) const
{
xpath_context c(n, 1, 1);
+ xpath_stack_data sd;
- xpath_memory_block resultblock, tempblock;
- xpath_allocator result(&resultblock), temp(&tempblock);
- xpath_allocator_capture cr(&result), ct(&temp);
- xpath_stack stack = {&result, &temp};
-
- xpath_string r = _root ? _root->eval_string(c, stack) : xpath_string();
+ xpath_string r = _root ? _root->eval_string(c, sd.stack) : xpath_string();
size_t size = r.length() + 1;
@@ -9046,13 +9057,9 @@ namespace pugi
}
xpath_context c(n, 1, 1);
-
- xpath_memory_block resultblock, tempblock;
- xpath_allocator result(&resultblock), temp(&tempblock);
- xpath_allocator_capture cr(&result), ct(&temp);
- xpath_stack stack = {&result, &temp};
+ xpath_stack_data sd;
- xpath_node_set_raw r = _root->eval_node_set(c, stack);
+ xpath_node_set_raw r = _root->eval_node_set(c, sd.stack);
return xpath_node_set(r.begin(), r.end(), r.type());
}