diff options
| author | Arseny Kapoulkine <arseny.kapoulkine@gmail.com> | 2014-11-04 09:58:04 +0100 | 
|---|---|---|
| committer | Arseny Kapoulkine <arseny.kapoulkine@gmail.com> | 2014-11-04 09:58:04 +0100 | 
| commit | b2a0ae13b61ba8cc9834f01851e2a643bae534fe (patch) | |
| tree | 5f9b01ae02b280115f0733fd2d78a895edce5c35 /src | |
| parent | 650c67a663515a3b76144a7dc16b26df0a8f2372 (diff) | |
| parent | 3950ee0433aaed3c35eaee7548bae5b00ee22a80 (diff) | |
Merge branch 'master' into compact
Diffstat (limited to 'src')
| -rw-r--r-- | src/pugixml.cpp | 105 | 
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;  			}  | 
