diff options
| author | Arseny Kapoulkine <arseny.kapoulkine@gmail.com> | 2014-11-20 23:47:00 -0800 | 
|---|---|---|
| committer | Arseny Kapoulkine <arseny.kapoulkine@gmail.com> | 2014-11-20 23:47:16 -0800 | 
| commit | db8df4a5665cfb24c1c18be438d10b2e310a234e (patch) | |
| tree | 16d251ba91d88fd99343e9628348f912e0170f1a /src | |
| parent | cca23e636354dc73429a19e14e32cc9a5e632735 (diff) | |
| parent | 125aa55061ccde4ae7351a9a6c7270a15c9e0204 (diff) | |
Merge branch 'master' into compact
Diffstat (limited to 'src')
| -rw-r--r-- | src/pugiconfig.hpp | 2 | ||||
| -rw-r--r-- | src/pugixml.cpp | 123 | ||||
| -rw-r--r-- | src/pugixml.hpp | 9 | 
3 files changed, 90 insertions, 44 deletions
diff --git a/src/pugiconfig.hpp b/src/pugiconfig.hpp index 56f1d22..1c216e3 100644 --- a/src/pugiconfig.hpp +++ b/src/pugiconfig.hpp @@ -1,5 +1,5 @@  /** - * pugixml parser - version 1.4 + * pugixml parser - version 1.5   * --------------------------------------------------------   * Copyright (C) 2006-2014, by Arseny Kapoulkine (arseny.kapoulkine@gmail.com)   * Report bugs and download new versions at http://pugixml.org/ diff --git a/src/pugixml.cpp b/src/pugixml.cpp index f0efa90..46653d1 100644 --- a/src/pugixml.cpp +++ b/src/pugixml.cpp @@ -1,6 +1,5 @@  /** -{ - * pugixml parser - version 1.4 + * pugixml parser - version 1.5   * --------------------------------------------------------   * Copyright (C) 2006-2014, by Arseny Kapoulkine (arseny.kapoulkine@gmail.com)   * Report bugs and download new versions at http://pugixml.org/ @@ -485,7 +484,7 @@ PUGI__NS_BEGIN  			void* memory = xml_memory::allocate(size + xml_memory_page_alignment);  			if (!memory) return 0; -			// align upwards to page boundary (note: this guarantees at least 1 usable byte before the page) +			// align to next page boundary (note: this guarantees at least 1 usable byte before the page)  			char* page_memory = reinterpret_cast<char*>((reinterpret_cast<uintptr_t>(memory) + xml_memory_page_alignment) & ~(xml_memory_page_alignment - 1));  			// prepare page structure @@ -495,6 +494,7 @@ PUGI__NS_BEGIN  			page->allocator = _root->allocator;  			// record the offset for freeing the memory block +			assert(page_memory > memory && page_memory - static_cast<char*>(memory) <= 127);  			page_memory[-1] = static_cast<char>(page_memory - static_cast<char*>(memory));  			return page; @@ -1241,6 +1241,7 @@ PUGI__NS_BEGIN  		else  			parent->first_child = node->next_sibling; +		node->parent = 0;  		node->prev_sibling_c = 0;  		node->next_sibling = 0;  	} @@ -4181,11 +4182,12 @@ PUGI__NS_BEGIN  				}  				node = node->parent; -				depth--;  				// write closing node  				if (PUGI__NODETYPE(node) == node_element)  				{ +					depth--; +  					if (indent_length)  						text_output_indent(writer, indent, indent_length, depth); @@ -4196,11 +4198,11 @@ PUGI__NS_BEGIN  		while (node != root);  	} -	PUGI__FN bool has_declaration(xml_node node) +	PUGI__FN bool has_declaration(xml_node_struct* node)  	{ -		for (xml_node child = node.first_child(); child; child = child.next_sibling()) +		for (xml_node_struct* child = node->first_child; child; child = child->next_sibling)  		{ -			xml_node_type type = child.type(); +			xml_node_type type = PUGI__NODETYPE(child);  			if (type == node_declaration) return true;  			if (type == node_element) return false; @@ -4218,6 +4220,11 @@ PUGI__NS_BEGIN  		return false;  	} +	PUGI__FN bool allow_insert_attribute(xml_node_type parent) +	{ +		return parent == node_element || parent == node_declaration; +	} +  	PUGI__FN bool allow_insert_child(xml_node_type parent, xml_node_type child)  	{  		if (parent != node_document && parent != node_element) return false; @@ -4254,6 +4261,8 @@ PUGI__NS_BEGIN  	template <typename String, typename Header>  	PUGI__FN void node_copy_string(String& dest, Header& header, uintptr_t header_mask, char_t* source, Header& source_header, xml_allocator* alloc)  	{ +		assert(!dest && (header & header_mask) == 0); +  		if (source)  		{  			if (alloc && (source_header & header_mask) == 0) @@ -5452,7 +5461,7 @@ namespace pugi  	PUGI__FN xml_attribute xml_node::append_attribute(const char_t* name_)  	{ -		if (type() != node_element && type() != node_declaration) return xml_attribute(); +		if (!impl::allow_insert_attribute(type())) return xml_attribute();  		impl::xml_allocator& alloc = impl::get_allocator(_root);  		if (!alloc.reserve()) return xml_attribute(); @@ -5469,7 +5478,7 @@ namespace pugi  	PUGI__FN xml_attribute xml_node::prepend_attribute(const char_t* name_)  	{ -		if (type() != node_element && type() != node_declaration) return xml_attribute(); +		if (!impl::allow_insert_attribute(type())) return xml_attribute();  		impl::xml_allocator& alloc = impl::get_allocator(_root);  		if (!alloc.reserve()) return xml_attribute(); @@ -5486,7 +5495,7 @@ namespace pugi  	PUGI__FN xml_attribute xml_node::insert_attribute_after(const char_t* name_, const xml_attribute& attr)  	{ -		if (type() != node_element && type() != node_declaration) return xml_attribute(); +		if (!impl::allow_insert_attribute(type())) return xml_attribute();  		if (!attr || !impl::is_attribute_of(attr._attr, _root)) return xml_attribute();  		impl::xml_allocator& alloc = impl::get_allocator(_root); @@ -5504,7 +5513,7 @@ namespace pugi  	PUGI__FN xml_attribute xml_node::insert_attribute_before(const char_t* name_, const xml_attribute& attr)  	{ -		if (type() != node_element && type() != node_declaration) return xml_attribute(); +		if (!impl::allow_insert_attribute(type())) return xml_attribute();  		if (!attr || !impl::is_attribute_of(attr._attr, _root)) return xml_attribute();  		impl::xml_allocator& alloc = impl::get_allocator(_root); @@ -5562,7 +5571,7 @@ namespace pugi  	PUGI__FN xml_node xml_node::append_child(xml_node_type type_)  	{ -		if (!impl::allow_insert_child(this->type(), type_)) return xml_node(); +		if (!impl::allow_insert_child(type(), type_)) return xml_node();  		impl::xml_allocator& alloc = impl::get_allocator(_root);  		if (!alloc.reserve()) return xml_node(); @@ -5579,7 +5588,7 @@ namespace pugi  	PUGI__FN xml_node xml_node::prepend_child(xml_node_type type_)  	{ -		if (!impl::allow_insert_child(this->type(), type_)) return xml_node(); +		if (!impl::allow_insert_child(type(), type_)) return xml_node();  		impl::xml_allocator& alloc = impl::get_allocator(_root);  		if (!alloc.reserve()) return xml_node(); @@ -5596,7 +5605,7 @@ namespace pugi  	PUGI__FN xml_node xml_node::insert_child_before(xml_node_type type_, const xml_node& node)  	{ -		if (!impl::allow_insert_child(this->type(), type_)) return xml_node(); +		if (!impl::allow_insert_child(type(), type_)) return xml_node();  		if (!node._root || node._root->parent != _root) return xml_node();  		impl::xml_allocator& alloc = impl::get_allocator(_root); @@ -5614,7 +5623,7 @@ namespace pugi  	PUGI__FN xml_node xml_node::insert_child_after(xml_node_type type_, const xml_node& node)  	{ -		if (!impl::allow_insert_child(this->type(), type_)) return xml_node(); +		if (!impl::allow_insert_child(type(), type_)) return xml_node();  		if (!node._root || node._root->parent != _root) return xml_node();  		impl::xml_allocator& alloc = impl::get_allocator(_root); @@ -5668,38 +5677,60 @@ namespace pugi  	PUGI__FN xml_node xml_node::append_copy(const xml_node& proto)  	{ -		xml_node result = append_child(proto.type()); +		xml_node_type type_ = proto.type(); +		if (!impl::allow_insert_child(type(), type_)) return xml_node(); -		if (result) impl::node_copy_tree(result.internal_object(), proto.internal_object()); +		xml_node n(impl::allocate_node(impl::get_allocator(_root), type_)); +		if (!n) return xml_node(); -		return result; +		impl::append_node(n._root, _root); +		impl::node_copy_tree(n._root, proto._root); + +		return n;  	}  	PUGI__FN xml_node xml_node::prepend_copy(const xml_node& proto)  	{ -		xml_node result = prepend_child(proto.type()); +		xml_node_type type_ = proto.type(); +		if (!impl::allow_insert_child(type(), type_)) return xml_node(); -		if (result) impl::node_copy_tree(result.internal_object(), proto.internal_object()); +		xml_node n(impl::allocate_node(impl::get_allocator(_root), type_)); +		if (!n) return xml_node(); -		return result; +		impl::prepend_node(n._root, _root); +		impl::node_copy_tree(n._root, proto._root); + +		return n;  	}  	PUGI__FN xml_node xml_node::insert_copy_after(const xml_node& proto, const xml_node& node)  	{ -		xml_node result = insert_child_after(proto.type(), node); +		xml_node_type type_ = proto.type(); +		if (!impl::allow_insert_child(type(), type_)) return xml_node(); +		if (!node._root || node._root->parent != _root) return xml_node(); -		if (result) impl::node_copy_tree(result.internal_object(), proto.internal_object()); +		xml_node n(impl::allocate_node(impl::get_allocator(_root), type_)); +		if (!n) return xml_node(); -		return result; +		impl::insert_node_after(n._root, node._root); +		impl::node_copy_tree(n._root, proto._root); + +		return n;  	}  	PUGI__FN xml_node xml_node::insert_copy_before(const xml_node& proto, const xml_node& node)  	{ -		xml_node result = insert_child_before(proto.type(), node); +		xml_node_type type_ = proto.type(); +		if (!impl::allow_insert_child(type(), type_)) return xml_node(); +		if (!node._root || node._root->parent != _root) return xml_node(); -		if (result) impl::node_copy_tree(result.internal_object(), proto.internal_object()); +		xml_node n(impl::allocate_node(impl::get_allocator(_root), type_)); +		if (!n) return xml_node(); -		return result; +		impl::insert_node_before(n._root, node._root); +		impl::node_copy_tree(n._root, proto._root); + +		return n;  	}  	PUGI__FN xml_node xml_node::append_move(const xml_node& moved) @@ -6575,6 +6606,7 @@ namespace pugi  		// destroy dynamic storage, leave sentinel page (it's in static memory)  		impl::xml_memory_page* root_page = reinterpret_cast<impl::xml_memory_page*>(_root->header & impl::xml_memory_page_pointer_mask);  		assert(root_page && !root_page->prev); +		assert(reinterpret_cast<char*>(root_page) >= _memory && reinterpret_cast<char*>(root_page) < _memory + sizeof(_memory));  		for (impl::xml_memory_page* page = root_page->next; page; )  		{ @@ -6609,7 +6641,7 @@ namespace pugi  	}  #endif -	PUGI__FN xml_parse_result xml_document::load(const char_t* contents, unsigned int options) +	PUGI__FN xml_parse_result xml_document::load_string(const char_t* contents, unsigned int options)  	{  		// Force native encoding (skip autodetection)  	#ifdef PUGIXML_WCHAR_MODE @@ -6621,6 +6653,11 @@ namespace pugi  		return load_buffer(contents, impl::strlength(contents) * sizeof(char_t), options, encoding);  	} +	PUGI__FN xml_parse_result xml_document::load(const char_t* contents, unsigned int options) +	{ +		return load_string(contents, options); +	} +  	PUGI__FN xml_parse_result xml_document::load_file(const char* path_, unsigned int options, xml_encoding encoding)  	{  		reset(); @@ -6675,7 +6712,7 @@ namespace pugi  		#endif  		} -		if (!(flags & format_no_declaration) && !impl::has_declaration(*this)) +		if (!(flags & format_no_declaration) && !impl::has_declaration(_root))  		{  			buffered_writer.write_string(PUGIXML_TEXT("<?xml version=\"1.0\""));  			if (encoding == encoding_latin1) buffered_writer.write_string(PUGIXML_TEXT(" encoding=\"ISO-8859-1\"")); @@ -8040,6 +8077,7 @@ PUGI__NS_BEGIN  			if (fc >= 128 || tc >= 128)  				return 0; +			// code=128 means "skip character"  			if (!table[fc])  				table[fc] = static_cast<unsigned char>(tc ? tc : 128); @@ -8074,6 +8112,8 @@ PUGI__NS_BEGIN  			{  				unsigned char code = table[index]; +				// code=128 means "skip character" (table size is 128 so 128 can be a special value) +				// this code skips these characters without extra branches  				*write = static_cast<char_t>(code);  				write += 1 - (code >> 7);  			} @@ -9038,9 +9078,9 @@ PUGI__NS_BEGIN  			return false;  		} -		static bool eval_once(bool forward, nodeset_eval_t eval) +		static bool eval_once(xpath_node_set::type_t type, nodeset_eval_t eval)  		{ -			return forward ? eval != nodeset_eval_all : eval == nodeset_eval_any; +			return type == xpath_node_set::type_sorted ? eval != nodeset_eval_all : eval == nodeset_eval_any;  		}  		template <class Comp> static bool compare_rel(xpath_ast_node* lhs, xpath_ast_node* rhs, const xpath_context& c, const xpath_stack& stack, const Comp& comp) @@ -9212,7 +9252,7 @@ PUGI__NS_BEGIN  		{  			if (ns.size() == first) return; -			bool last_once = eval_once(ns.type() == xpath_node_set::type_sorted, eval); +			bool last_once = eval_once(ns.type(), eval);  			for (xpath_ast_node* pred = _right; pred; pred = pred->_next)  				pred->apply_predicate(ns, first, stack, !pred->_next && last_once); @@ -9610,7 +9650,7 @@ PUGI__NS_BEGIN  		template <class T> void step_fill(xpath_node_set_raw& ns, const xpath_node& xn, xpath_allocator* alloc, bool once, T v)  		{  			const axis_t axis = T::axis; -			bool axis_has_attributes = (axis == axis_ancestor || axis == axis_ancestor_or_self || axis == axis_descendant_or_self || axis == axis_following || axis == axis_parent || axis == axis_preceding || axis == axis_self); +			const bool axis_has_attributes = (axis == axis_ancestor || axis == axis_ancestor_or_self || axis == axis_descendant_or_self || axis == axis_following || axis == axis_parent || axis == axis_preceding || axis == axis_self);  			if (xn.node())  				step_fill(ns, xn.node().internal_object(), alloc, once, v); @@ -9621,15 +9661,16 @@ PUGI__NS_BEGIN  		template <class T> xpath_node_set_raw step_do(const xpath_context& c, const xpath_stack& stack, nodeset_eval_t eval, T v)  		{  			const axis_t axis = T::axis; -			bool axis_reverse = (axis == axis_ancestor || axis == axis_ancestor_or_self || axis == axis_preceding || axis == axis_preceding_sibling); +			const bool axis_reverse = (axis == axis_ancestor || axis == axis_ancestor_or_self || axis == axis_preceding || axis == axis_preceding_sibling); +			const xpath_node_set::type_t axis_type = axis_reverse ? xpath_node_set::type_sorted_reverse : xpath_node_set::type_sorted;  			bool once =  				(axis == axis_attribute && _test == nodetest_name) || -				(!_right && eval_once(!axis_reverse, eval)) || +				(!_right && eval_once(axis_type, eval)) ||  				(_right && !_right->_next && _right->_test == predicate_constant_one);  			xpath_node_set_raw ns; -			ns.set_type(axis_reverse ? xpath_node_set::type_sorted_reverse : xpath_node_set::type_sorted); +			ns.set_type(axis_type);  			if (_left)  			{ @@ -10130,9 +10171,10 @@ PUGI__NS_BEGIN  				const char_t* pos = find_substring(s.c_str(), p.c_str());  				if (!pos) return xpath_string(); -				const char_t* result = pos + p.length(); +				const char_t* rbegin = pos + p.length(); +				const char_t* rend = s.c_str() + s.length(); -				return s.uses_heap() ? xpath_string::from_heap(result, s.c_str() + s.length(), stack.result) : xpath_string::from_const(result); +				return s.uses_heap() ? xpath_string::from_heap(rbegin, rend, stack.result) : xpath_string::from_const(rbegin);  			}  			case ast_func_substring_2: @@ -10153,8 +10195,9 @@ PUGI__NS_BEGIN  				assert(1 <= pos && pos <= s_length + 1);  				const char_t* rbegin = s.c_str() + (pos - 1); +				const char_t* rend = s.c_str() + s.length(); -				return s.uses_heap() ? xpath_string::from_heap(rbegin, s.c_str() + s.length(), stack.result) : xpath_string::from_const(rbegin); +				return s.uses_heap() ? xpath_string::from_heap(rbegin, rend, stack.result) : xpath_string::from_const(rbegin);  			}  			case ast_func_substring_3: @@ -10293,7 +10336,7 @@ PUGI__NS_BEGIN  				// either expression is a number or it contains position() call; sort by document order  				if (_test != predicate_posinv) set.sort_do(); -				bool once = eval_once(set.type() == xpath_node_set::type_sorted, eval); +				bool once = eval_once(set.type(), eval);  				apply_predicate(set, 0, stack, once); diff --git a/src/pugixml.hpp b/src/pugixml.hpp index e252e16..917ef4a 100644 --- a/src/pugixml.hpp +++ b/src/pugixml.hpp @@ -1,5 +1,5 @@  /** - * pugixml parser - version 1.4 + * pugixml parser - version 1.5   * --------------------------------------------------------   * Copyright (C) 2006-2014, by Arseny Kapoulkine (arseny.kapoulkine@gmail.com)   * Report bugs and download new versions at http://pugixml.org/ @@ -13,7 +13,7 @@  #ifndef PUGIXML_VERSION  // Define version macro; evaluates to major * 100 + minor so that it's safe to use in less-than comparisons -#	define PUGIXML_VERSION 140 +#	define PUGIXML_VERSION 150  #endif  // Include user configuration file (this can define various configuration macros) @@ -959,9 +959,12 @@ namespace pugi  		xml_parse_result load(std::basic_istream<wchar_t, std::char_traits<wchar_t> >& stream, unsigned int options = parse_default);  	#endif -		// Load document from zero-terminated string. No encoding conversions are applied. +		// (deprecated: use load_string instead) Load document from zero-terminated string. No encoding conversions are applied.  		xml_parse_result load(const char_t* contents, unsigned int options = parse_default); +		// Load document from zero-terminated string. No encoding conversions are applied. +		xml_parse_result load_string(const char_t* contents, unsigned int options = parse_default); +  		// Load document from file  		xml_parse_result load_file(const char* path, unsigned int options = parse_default, xml_encoding encoding = encoding_auto);  		xml_parse_result load_file(const wchar_t* path, unsigned int options = parse_default, xml_encoding encoding = encoding_auto);  | 
