12796 lines · 323.1 KB · C++
RawDownload
/** * pugixml parser - version 1.9 * -------------------------------------------------------- * Copyright (C) 2006-2018, by Arseny Kapoulkine (arseny.kapoulkine@gmail.com) * Report bugs and download new versions at http://pugixml.org/ * * This library is distributed under the MIT License. See notice at the end * of this file. * * This work is based on the pugxml parser, which is: * Copyright (C) 2003, by Kristen Wegner (kristen@tima.net) */ #ifndef SOURCE_PUGIXML_CPP#define SOURCE_PUGIXML_CPP #include "pugixml.hpp" #include <stdlib.h>#include <stdio.h>#include <string.h>#include <assert.h>#include <limits.h> #ifdef PUGIXML_WCHAR_MODE#	include <wchar.h>#endif #ifndef PUGIXML_NO_XPATH#	include <math.h>#	include <float.h>#endif #ifndef PUGIXML_NO_STL#	include <istream>#	include <ostream>#	include <string>#endif // For placement new#include <new> #ifdef _MSC_VER#	pragma warning(push)#	pragma warning(disable: 4127) // conditional expression is constant#	pragma warning(disable: 4324) // structure was padded due to __declspec(align())#	pragma warning(disable: 4702) // unreachable code#	pragma warning(disable: 4996) // this function or variable may be unsafe#endif #if defined(_MSC_VER) && defined(__c2__)#	pragma clang diagnostic push#	pragma clang diagnostic ignored "-Wdeprecated" // this function or variable may be unsafe#endif #ifdef __INTEL_COMPILER#	pragma warning(disable: 177) // function was declared but never referenced#	pragma warning(disable: 279) // controlling expression is constant#	pragma warning(disable: 1478 1786) // function was declared "deprecated"#	pragma warning(disable: 1684) // conversion from pointer to same-sized integral type#endif #if defined(__BORLANDC__) && defined(PUGIXML_HEADER_ONLY)#	pragma warn -8080 // symbol is declared but never used; disabling this inside push/pop bracket does not make the warning go away#endif #ifdef __BORLANDC__#	pragma option push#	pragma warn -8008 // condition is always false#	pragma warn -8066 // unreachable code#endif #ifdef __SNC__// Using diag_push/diag_pop does not disable the warnings inside templates due to a compiler bug#	pragma diag_suppress=178 // function was declared but never referenced#	pragma diag_suppress=237 // controlling expression is constant#endif #ifdef __TI_COMPILER_VERSION__#	pragma diag_suppress 179 // function was declared but never referenced#endif // Inlining controls#if defined(_MSC_VER) && _MSC_VER >= 1300#	define PUGI__NO_INLINE __declspec(noinline)#elif defined(__GNUC__)#	define PUGI__NO_INLINE __attribute__((noinline))#else#	define PUGI__NO_INLINE#endif // Branch weight controls#if defined(__GNUC__) && !defined(__c2__)#	define PUGI__UNLIKELY(cond) __builtin_expect(cond, 0)#else#	define PUGI__UNLIKELY(cond) (cond)#endif // Simple static assertion#define PUGI__STATIC_ASSERT(cond) { static const char condition_failed[(cond) ? 1 : -1] = {0}; (void)condition_failed[0]; } // Digital Mars C++ bug workaround for passing char loaded from memory via stack#ifdef __DMC__#	define PUGI__DMC_VOLATILE volatile#else#	define PUGI__DMC_VOLATILE#endif // Integer sanitizer workaround; we only apply this for clang since gcc8 has no_sanitize but not unsigned-integer-overflow and produces "attribute directive ignored" warnings#if defined(__clang__) && defined(__has_attribute)#	if __has_attribute(no_sanitize)#		define PUGI__UNSIGNED_OVERFLOW __attribute__((no_sanitize("unsigned-integer-overflow")))#	else#		define PUGI__UNSIGNED_OVERFLOW#	endif#else#	define PUGI__UNSIGNED_OVERFLOW#endif // Borland C++ bug workaround for not defining ::memcpy depending on header include order (can't always use std::memcpy because some compilers don't have it at all)#if defined(__BORLANDC__) && !defined(__MEM_H_USING_LIST)using std::memcpy;using std::memmove;using std::memset;#endif // Some MinGW/GCC versions have headers that erroneously omit LLONG_MIN/LLONG_MAX/ULLONG_MAX definitions from limits.h in some configurations#if defined(PUGIXML_HAS_LONG_LONG) && defined(__GNUC__) && !defined(LLONG_MAX) && !defined(LLONG_MIN) && !defined(ULLONG_MAX)#	define LLONG_MIN (-LLONG_MAX - 1LL)#	define LLONG_MAX __LONG_LONG_MAX__#	define ULLONG_MAX (LLONG_MAX * 2ULL + 1ULL)#endif // In some environments MSVC is a compiler but the CRT lacks certain MSVC-specific features#if defined(_MSC_VER) && !defined(__S3E__)#	define PUGI__MSVC_CRT_VERSION _MSC_VER#endif // Not all platforms have snprintf; we define a wrapper that uses snprintf if possible. This only works with buffers with a known size.#if __cplusplus >= 201103#	define PUGI__SNPRINTF(buf, ...) snprintf(buf, sizeof(buf), __VA_ARGS__)#elif defined(PUGI__MSVC_CRT_VERSION) && PUGI__MSVC_CRT_VERSION >= 1400#	define PUGI__SNPRINTF(buf, ...) _snprintf_s(buf, _countof(buf), _TRUNCATE, __VA_ARGS__)#else#	define PUGI__SNPRINTF sprintf#endif // We put implementation details into an anonymous namespace in source mode, but have to keep it in non-anonymous namespace in header-only mode to prevent binary bloat.#ifdef PUGIXML_HEADER_ONLY#	define PUGI__NS_BEGIN namespace pugi { namespace impl {#	define PUGI__NS_END } }#	define PUGI__FN inline#	define PUGI__FN_NO_INLINE inline#else#	if defined(_MSC_VER) && _MSC_VER < 1300 // MSVC6 seems to have an amusing bug with anonymous namespaces inside namespaces#		define PUGI__NS_BEGIN namespace pugi { namespace impl {#		define PUGI__NS_END } }#	else#		define PUGI__NS_BEGIN namespace pugi { namespace impl { namespace {#		define PUGI__NS_END } } }#	endif#	define PUGI__FN#	define PUGI__FN_NO_INLINE PUGI__NO_INLINE#endif // uintptr_t#if (defined(_MSC_VER) && _MSC_VER < 1600) || (defined(__BORLANDC__) && __BORLANDC__ < 0x561)namespace pugi{#	ifndef _UINTPTR_T_DEFINED	typedef size_t uintptr_t;#	endif 	typedef unsigned __int8 uint8_t;	typedef unsigned __int16 uint16_t;	typedef unsigned __int32 uint32_t;}#else#	include <stdint.h>#endif // Memory allocationPUGI__NS_BEGIN	PUGI__FN void* default_allocate(size_t size)	{		return malloc(size);	} 	PUGI__FN void default_deallocate(void* ptr)	{		free(ptr);	} 	template <typename T>	struct xml_memory_management_function_storage	{		static allocation_function allocate;		static deallocation_function deallocate;	}; 	// Global allocation functions are stored in class statics so that in header mode linker deduplicates them	// Without a template<> we'll get multiple definitions of the same static	template <typename T> allocation_function xml_memory_management_function_storage<T>::allocate = default_allocate;	template <typename T> deallocation_function xml_memory_management_function_storage<T>::deallocate = default_deallocate; 	typedef xml_memory_management_function_storage<int> xml_memory;PUGI__NS_END // String utilitiesPUGI__NS_BEGIN	// Get string length	PUGI__FN size_t strlength(const char_t* s)	{		assert(s); 	#ifdef PUGIXML_WCHAR_MODE		return wcslen(s);	#else		return strlen(s);	#endif	} 	// Compare two strings	PUGI__FN bool strequal(const char_t* src, const char_t* dst)	{		assert(src && dst); 	#ifdef PUGIXML_WCHAR_MODE		return wcscmp(src, dst) == 0;	#else		return strcmp(src, dst) == 0;	#endif	} 	// Compare lhs with [rhs_begin, rhs_end)	PUGI__FN bool strequalrange(const char_t* lhs, const char_t* rhs, size_t count)	{		for (size_t i = 0; i < count; ++i)			if (lhs[i] != rhs[i])				return false; 		return lhs[count] == 0;	} 	// Get length of wide string, even if CRT lacks wide character support	PUGI__FN size_t strlength_wide(const wchar_t* s)	{		assert(s); 	#ifdef PUGIXML_WCHAR_MODE		return wcslen(s);	#else		const wchar_t* end = s;		while (*end) end++;		return static_cast<size_t>(end - s);	#endif	}PUGI__NS_END // auto_ptr-like object for exception recoveryPUGI__NS_BEGIN	template <typename T> struct auto_deleter	{		typedef void (*D)(T*); 		T* data;		D deleter; 		auto_deleter(T* data_, D deleter_): data(data_), deleter(deleter_)		{		} 		~auto_deleter()		{			if (data) deleter(data);		} 		T* release()		{			T* result = data;			data = 0;			return result;		}	};PUGI__NS_END #ifdef PUGIXML_COMPACTPUGI__NS_BEGIN	class compact_hash_table	{	public:		compact_hash_table(): _items(0), _capacity(0), _count(0)		{		} 		void clear()		{			if (_items)			{				xml_memory::deallocate(_items);				_items = 0;				_capacity = 0;				_count = 0;			}		} 		void* find(const void* key)		{			if (_capacity == 0) return 0; 			item_t* item = get_item(key);			assert(item);			assert(item->key == key || (item->key == 0 && item->value == 0)); 			return item->value;		} 		void insert(const void* key, void* value)		{			assert(_capacity != 0 && _count < _capacity - _capacity / 4); 			item_t* item = get_item(key);			assert(item); 			if (item->key == 0)			{				_count++;				item->key = key;			} 			item->value = value;		} 		bool reserve(size_t extra = 16)		{			if (_count + extra >= _capacity - _capacity / 4)				return rehash(_count + extra); 			return true;		} 	private:		struct item_t		{			const void* key;			void* value;		}; 		item_t* _items;		size_t _capacity; 		size_t _count; 		bool rehash(size_t count); 		item_t* get_item(const void* key)		{			assert(key);			assert(_capacity > 0); 			size_t hashmod = _capacity - 1;			size_t bucket = hash(key) & hashmod; 			for (size_t probe = 0; probe <= hashmod; ++probe)			{				item_t& probe_item = _items[bucket]; 				if (probe_item.key == key || probe_item.key == 0)					return &probe_item; 				// hash collision, quadratic probing				bucket = (bucket + probe + 1) & hashmod;			} 			assert(false && "Hash table is full"); // unreachable			return 0;		} 		static PUGI__UNSIGNED_OVERFLOW unsigned int hash(const void* key)		{			unsigned int h = static_cast<unsigned int>(reinterpret_cast<uintptr_t>(key)); 			// MurmurHash3 32-bit finalizer			h ^= h >> 16;			h *= 0x85ebca6bu;			h ^= h >> 13;			h *= 0xc2b2ae35u;			h ^= h >> 16; 			return h;		}	}; 	PUGI__FN_NO_INLINE bool compact_hash_table::rehash(size_t count)	{		size_t capacity = 32;		while (count >= capacity - capacity / 4)			capacity *= 2; 		compact_hash_table rt;		rt._capacity = capacity;		rt._items = static_cast<item_t*>(xml_memory::allocate(sizeof(item_t) * capacity)); 		if (!rt._items)			return false; 		memset(rt._items, 0, sizeof(item_t) * capacity); 		for (size_t i = 0; i < _capacity; ++i)			if (_items[i].key)				rt.insert(_items[i].key, _items[i].value); 		if (_items)			xml_memory::deallocate(_items); 		_capacity = capacity;		_items = rt._items; 		assert(_count == rt._count); 		return true;	} PUGI__NS_END#endif PUGI__NS_BEGIN#ifdef PUGIXML_COMPACT	static const uintptr_t xml_memory_block_alignment = 4;#else	static const uintptr_t xml_memory_block_alignment = sizeof(void*);#endif 	// extra metadata bits	static const uintptr_t xml_memory_page_contents_shared_mask = 64;	static const uintptr_t xml_memory_page_name_allocated_mask = 32;	static const uintptr_t xml_memory_page_value_allocated_mask = 16;	static const uintptr_t xml_memory_page_type_mask = 15; 	// combined masks for string uniqueness	static const uintptr_t xml_memory_page_name_allocated_or_shared_mask = xml_memory_page_name_allocated_mask | xml_memory_page_contents_shared_mask;	static const uintptr_t xml_memory_page_value_allocated_or_shared_mask = xml_memory_page_value_allocated_mask | xml_memory_page_contents_shared_mask; #ifdef PUGIXML_COMPACT	#define PUGI__GETHEADER_IMPL(object, page, flags) // unused	#define PUGI__GETPAGE_IMPL(header) (header).get_page()#else	#define PUGI__GETHEADER_IMPL(object, page, flags) (((reinterpret_cast<char*>(object) - reinterpret_cast<char*>(page)) << 8) | (flags))	// this macro casts pointers through void* to avoid 'cast increases required alignment of target type' warnings	#define PUGI__GETPAGE_IMPL(header) static_cast<impl::xml_memory_page*>(const_cast<void*>(static_cast<const void*>(reinterpret_cast<const char*>(&header) - (header >> 8))))#endif 	#define PUGI__GETPAGE(n) PUGI__GETPAGE_IMPL((n)->header)	#define PUGI__NODETYPE(n) static_cast<xml_node_type>((n)->header & impl::xml_memory_page_type_mask) 	struct xml_allocator; 	struct xml_memory_page	{		static xml_memory_page* construct(void* memory)		{			xml_memory_page* result = static_cast<xml_memory_page*>(memory); 			result->allocator = 0;			result->prev = 0;			result->next = 0;			result->busy_size = 0;			result->freed_size = 0; 		#ifdef PUGIXML_COMPACT			result->compact_string_base = 0;			result->compact_shared_parent = 0;			result->compact_page_marker = 0;		#endif 			return result;		} 		xml_allocator* allocator; 		xml_memory_page* prev;		xml_memory_page* next; 		size_t busy_size;		size_t freed_size; 	#ifdef PUGIXML_COMPACT		char_t* compact_string_base;		void* compact_shared_parent;		uint32_t* compact_page_marker;	#endif	}; 	static const size_t xml_memory_page_size =	#ifdef PUGIXML_MEMORY_PAGE_SIZE		(PUGIXML_MEMORY_PAGE_SIZE)	#else		32768	#endif		- sizeof(xml_memory_page);

Lines 1–500 of 12796.

Keyboard shortcuts

General

Show keyboard shortcuts
?
Focus the current search
/

Issues and pull requests

Open filters
f

Issues, pull requests and Inbox

Select next item
j↓
Select previous item
k↑
Open selected item
Enter
Dismiss filters or clear selection
Esc

Repository code

Go to file
t