14#ifndef SOURCE_PUGIXML_CPP
15#define SOURCE_PUGIXML_CPP
25#ifdef PUGIXML_WCHAR_MODE
29#ifndef PUGIXML_NO_XPATH
44# pragma clang diagnostic push
45# pragma clang diagnostic ignored "-Wconversion"
46# pragma clang diagnostic ignored "-Wdouble-promotion"
55 #pragma warning(disable: 4127)
58 #pragma warning(disable: 4324)
61 #pragma warning(disable: 4702)
64 #pragma warning(disable: 4996)
68#if defined(_MSC_VER) && defined(__clang__)
70 #pragma clang diagnostic push
73 #pragma clang diagnostic ignored "-Wdeprecated"
77#ifdef __INTEL_COMPILER
79 #pragma warning(disable: 177)
82 #pragma warning(disable: 279)
85 #pragma warning(disable: 1478 1786)
88 #pragma warning(disable: 1684)
92#if defined(__BORLANDC__) && defined(PUGIXML_HEADER_ONLY)
97#if defined(__BORLANDC__) && defined(PUGIXML_HEADER_ONLY)
109# pragma diag_suppress=178
110# pragma diag_suppress=237
113#ifdef __TI_COMPILER_VERSION__
114# pragma diag_suppress 179
118#if defined(_MSC_VER) && _MSC_VER >= 1300
119# define PUGI__NO_INLINE __declspec(noinline)
120#elif defined(__GNUC__)
121# define PUGI__NO_INLINE __attribute__((noinline))
123# define PUGI__NO_INLINE
127#if defined(__GNUC__) && !defined(__c2__)
128# define PUGI__UNLIKELY(cond) __builtin_expect(cond, 0)
130# define PUGI__UNLIKELY(cond) (cond)
134#define PUGI__STATIC_ASSERT(cond) { static const char condition_failed[(cond) ? 1 : -1] = {0}; (void)condition_failed[0]; }
138# define PUGI__DMC_VOLATILE volatile
140# define PUGI__DMC_VOLATILE
144#if defined(__clang__) && defined(__has_attribute)
145# if __has_attribute(no_sanitize)
146# define PUGI__UNSIGNED_OVERFLOW __attribute__((no_sanitize("unsigned-integer-overflow")))
148# define PUGI__UNSIGNED_OVERFLOW
151# define PUGI__UNSIGNED_OVERFLOW
155#if defined(__BORLANDC__) && !defined(__MEM_H_USING_LIST)
162#if defined(PUGIXML_HAS_LONG_LONG) && defined(__GNUC__) && !defined(LLONG_MAX) && !defined(LLONG_MIN) && !defined(ULLONG_MAX)
163# define LLONG_MIN (-LLONG_MAX - 1LL)
164# define LLONG_MAX __LONG_LONG_MAX__
165# define ULLONG_MAX (LLONG_MAX * 2ULL + 1ULL)
169#if defined(_MSC_VER) && !defined(__S3E__)
170# define PUGI__MSVC_CRT_VERSION _MSC_VER
174#if __cplusplus >= 201103
175# define PUGI__SNPRINTF(buf, ...) snprintf(buf, sizeof(buf), __VA_ARGS__)
176#elif defined(PUGI__MSVC_CRT_VERSION) && PUGI__MSVC_CRT_VERSION >= 1400
177# define PUGI__SNPRINTF(buf, ...) _snprintf_s(buf, _countof(buf), _TRUNCATE, __VA_ARGS__)
179# define PUGI__SNPRINTF sprintf
183#ifdef PUGIXML_HEADER_ONLY
184# define PUGI__NS_BEGIN namespace pugi { namespace impl {
185# define PUGI__NS_END } }
186# define PUGI__FN inline
187# define PUGI__FN_NO_INLINE inline
189# if defined(_MSC_VER) && _MSC_VER < 1300
190# define PUGI__NS_BEGIN namespace pugi { namespace impl {
191# define PUGI__NS_END } }
193# define PUGI__NS_BEGIN namespace pugi { namespace impl { namespace {
194# define PUGI__NS_END } } }
197# define PUGI__FN_NO_INLINE PUGI__NO_INLINE
201#if (defined(_MSC_VER) && _MSC_VER < 1600) || (defined(__BORLANDC__) && __BORLANDC__ < 0x561)
204# ifndef _UINTPTR_T_DEFINED
205 typedef size_t uintptr_t;
208 typedef unsigned __int8 uint8_t;
209 typedef unsigned __int16 uint16_t;
210 typedef unsigned __int32 uint32_t;
257#ifdef PUGIXML_WCHAR_MODE
270#ifdef PUGIXML_WCHAR_MODE
271 return wcscmp(src, dst) == 0;
273 return strcmp(src, dst) == 0;
281 for (
size_t i = 0; i < count; ++i)
282 if (lhs[i] != rhs[i])
286 return lhs[count] == 0;
295#ifdef PUGIXML_WCHAR_MODE
300 const wchar_t*
end = s;
302 return static_cast<size_t>(
end - s);
313 typedef void (*
D)(T*);
341#ifdef PUGIXML_COMPACT
344 class compact_hash_table
348 compact_hash_table(): _items(0), _capacity(0), _count(0)
366 void* find(
const void* key)
369 if (_capacity == 0)
return 0;
371 item_t* item = get_item(key);
374 assert(item->key == key || (item->key == 0 && item->value == 0));
379 void insert(
const void* key,
void* value)
382 assert(_capacity != 0 && _count < _capacity - _capacity / 4);
384 item_t* item = get_item(key);
399 bool reserve(
size_t extra = 16)
402 if (_count + extra >= _capacity - _capacity / 4)
405 return rehash(_count + extra);
406 return rehash(_count + extra);
425 bool rehash(
size_t count);
427 item_t* get_item(
const void* key)
432 assert(_capacity > 0);
434 size_t hashmod = _capacity - 1;
436 size_t bucket = hash(key) & hashmod;
438 for (
size_t probe = 0; probe <= hashmod; ++probe)
441 item_t& probe_item = _items[bucket];
443 if (probe_item.key == key || probe_item.key == 0)
448 bucket = (bucket + probe + 1) & hashmod;
451 assert(
false &&
"Hash table is full");
460 unsigned int h =
static_cast<unsigned int>(
reinterpret_cast<uintptr_t
>(key));
476 size_t capacity = 32;
478 while (count >= capacity - capacity / 4)
481 compact_hash_table rt;
483 rt._capacity = capacity;
490 memset(rt._items, 0,
sizeof(item_t) * capacity);
492 for (
size_t i = 0; i < _capacity; ++i)
494 rt.insert(_items[i].key, _items[i].value);
499 _capacity = capacity;
502 assert(_count == rt._count);
513#ifdef PUGIXML_COMPACT
531#ifdef PUGIXML_COMPACT
532 #define PUGI__GETHEADER_IMPL(object, page, flags)
533 #define PUGI__GETPAGE_IMPL(header) (header).get_page()
537 #define PUGI__GETHEADER_IMPL(object, page, flags) (((reinterpret_cast<char*>(object) - reinterpret_cast<char*>(page)) << 8) | (flags))
540 #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))))
544 #define PUGI__GETPAGE(n) PUGI__GETPAGE_IMPL((n)->header)
546 #define PUGI__NODETYPE(n) static_cast<xml_node_type>((n)->header & impl::xml_memory_page_type_mask)
564 #ifdef PUGIXML_COMPACT
565 result->compact_string_base = 0;
566 result->compact_shared_parent = 0;
567 result->compact_page_marker = 0;
582 #ifdef PUGIXML_COMPACT
583 char_t* compact_string_base;
584 void* compact_shared_parent;
585 uint32_t* compact_page_marker;
590 #ifdef PUGIXML_MEMORY_PAGE_SIZE
591 (PUGIXML_MEMORY_PAGE_SIZE)
610 #ifdef PUGIXML_COMPACT
623 if (!memory)
return 0;
666 #ifdef PUGIXML_COMPACT
674 if (!result)
return 0;
677 ptrdiff_t offset =
static_cast<char*
>(result) -
reinterpret_cast<char*
>(out_page->compact_page_marker);
683 uint32_t* marker =
static_cast<uint32_t*
>(result);
684 *marker =
static_cast<uint32_t
>(
reinterpret_cast<char*
>(marker) -
reinterpret_cast<char*
>(out_page));
685 out_page->compact_page_marker = marker;
729 assert(
_root == page);
736#ifdef PUGIXML_COMPACT
738 page->compact_string_base = 0;
739 page->compact_shared_parent = 0;
740 page->compact_page_marker = 0;
748 assert(
_root != page);
777 if (!header)
return 0;
780 ptrdiff_t page_offset =
reinterpret_cast<char*
>(header) -
reinterpret_cast<char*
>(page) -
sizeof(
xml_memory_page);
783 assert(page_offset >= 0 &&
static_cast<size_t>(page_offset) < max_encoded_offset);
788 assert(full_size < max_encoded_offset || (page->
busy_size == full_size && page_offset == 0));
793 return static_cast<char_t*
>(
static_cast<void*
>(header + 1));
823 #ifdef PUGIXML_COMPACT
824 return _hash->reserve();
833 #ifdef PUGIXML_COMPACT
834 compact_hash_table* _hash;
851 if (size <= large_allocation_threshold)
884#ifdef PUGIXML_COMPACT
888 static const uintptr_t compact_alignment_log2 = 2;
890 static const uintptr_t compact_alignment = 1 << compact_alignment_log2;
901 ptrdiff_t offset = (
reinterpret_cast<char*
>(
this) -
reinterpret_cast<char*
>(page->compact_page_marker));
903 assert(offset % compact_alignment == 0 &&
static_cast<uintptr_t
>(offset) < 256 * compact_alignment);
905 _page =
static_cast<unsigned char>(offset >> compact_alignment_log2);
907 _flags =
static_cast<unsigned char>(flags);
910 void operator&=(uintptr_t mod)
912 _flags &=
static_cast<unsigned char>(mod);
915 void operator|=(uintptr_t mod)
917 _flags |=
static_cast<unsigned char>(mod);
920 uintptr_t operator&(uintptr_t mod)
const
928 const char* page_marker =
reinterpret_cast<const char*
>(
this) - (_page << compact_alignment_log2);
929 const char* page = page_marker - *
reinterpret_cast<const uint32_t*
>(
static_cast<const void*
>(page_marker));
938 unsigned char _flags;
945 const compact_header* header =
reinterpret_cast<const compact_header*
>(
static_cast<const char*
>(object) - header_offset);
947 return header->get_page();
951 template <
int header_offset,
typename T>
PUGI__FN_NO_INLINE T* compact_get_value(
const void*
object)
953 return static_cast<T*
>(compact_get_page(
object, header_offset)->allocator->_hash->find(
object));
956 template <
int header_offset,
typename T>
PUGI__FN_NO_INLINE void compact_set_value(
const void*
object, T* value)
959 compact_get_page(
object, header_offset)->allocator->_hash->insert(
object, value);
962 template <
typename T,
int header_offset,
int start = -126>
class compact_pointer
966 compact_pointer(): _data(0)
970 void operator=(
const compact_pointer& rhs)
987 ptrdiff_t diff =
reinterpret_cast<char*
>(value) -
reinterpret_cast<char*
>(
this);
988 ptrdiff_t offset = ((diff + int(compact_alignment - 1)) >> compact_alignment_log2) - start;
991 if (
static_cast<uintptr_t
>(offset) <= 253)
992 _data =
static_cast<unsigned char>(offset + 1);
996 compact_set_value<header_offset>(
this, value);
1013 uintptr_t base =
reinterpret_cast<uintptr_t
>(
this) & ~(compact_alignment - 1);
1016 return reinterpret_cast<T*
>(base + (_data - 1 + start) * compact_alignment);
1020 return compact_get_value<header_offset, T>(
this);
1026 T* operator->()
const
1033 unsigned char _data;
1036 template <
typename T,
int header_offset>
class compact_pointer_parent
1040 compact_pointer_parent(): _data(0)
1044 void operator=(
const compact_pointer_parent& rhs)
1058 ptrdiff_t diff =
reinterpret_cast<char*
>(value) -
reinterpret_cast<char*
>(
this);
1059 ptrdiff_t offset = ((diff + int(compact_alignment - 1)) >> compact_alignment_log2) + 65533;
1061 if (
static_cast<uintptr_t
>(offset) <= 65533)
1063 _data =
static_cast<unsigned short>(offset + 1);
1072 page->compact_shared_parent = value;
1074 if (page->compact_shared_parent == value)
1081 compact_set_value<header_offset>(
this, value);
1101 uintptr_t base =
reinterpret_cast<uintptr_t
>(
this) & ~(compact_alignment - 1);
1104 return reinterpret_cast<T*
>(base + (_data - 1 - 65533) * compact_alignment);
1106 else if (_data == 65534)
1108 return static_cast<T*
>(compact_get_page(
this, header_offset)->compact_shared_parent);
1111 return compact_get_value<header_offset, T>(
this);
1118 T* operator->()
const
1128 template <
int header_offset,
int base_offset>
class compact_string
1131 compact_string(): _data(0)
1135 void operator=(
const compact_string& rhs)
1148 page->compact_string_base = value;
1150 ptrdiff_t offset = value - page->compact_string_base;
1152 if (
static_cast<uintptr_t
>(offset) < (65535 << 7))
1155 uint16_t* base =
reinterpret_cast<uint16_t*
>(
static_cast<void*
>(
reinterpret_cast<char*
>(
this) - base_offset));
1161 *base =
static_cast<uint16_t
>((offset >> 7) + 1);
1162 _data =
static_cast<unsigned char>((offset & 127) + 1);
1167 ptrdiff_t remainder = offset - ((*base - 1) << 7);
1169 if (
static_cast<uintptr_t
>(remainder) <= 253)
1172 _data =
static_cast<unsigned char>(remainder + 1);
1177 compact_set_value<header_offset>(
this, value);
1186 compact_set_value<header_offset>(
this, value);
1198 operator char_t*()
const
1207 const uint16_t* base =
reinterpret_cast<const uint16_t*
>(
static_cast<const void*
>(
reinterpret_cast<const char*
>(
this) - base_offset));
1210 ptrdiff_t offset = ((*base - 1) << 7) + (_data - 1);
1212 return page->compact_string_base + offset;
1216 return compact_get_value<header_offset, char_t>(
this);
1224 unsigned char _data;
1231#ifdef PUGIXML_COMPACT
1235 struct xml_attribute_struct
1243 impl::compact_header
header;
1245 uint16_t namevalue_base;
1247 impl::compact_string<4, 2>
name;
1248 impl::compact_string<5, 3>
value;
1251 impl::compact_pointer<xml_attribute_struct, 7, 0>
next_attribute;
1263 impl::compact_header
header;
1265 uint16_t namevalue_base;
1267 impl::compact_string<4, 2>
name;
1268 impl::compact_string<5, 3>
value;
1270 impl::compact_pointer_parent<xml_node_struct, 6>
parent;
1272 impl::compact_pointer<xml_node_struct, 8, 0>
first_child;
1275 impl::compact_pointer<xml_node_struct, 10, 0>
next_sibling;
1344 #ifdef PUGIXML_COMPACT
1345 compact_hash_table hash;
1371 void* memory = alloc.
allocate_object(
sizeof(xml_attribute_struct), page);
1372 if (!memory)
return 0;
1374 return new (memory) xml_attribute_struct(page);
1381 if (!memory)
return 0;
1388 if (a->header & impl::xml_memory_page_name_allocated_mask)
1391 if (a->header & impl::xml_memory_page_value_allocated_mask)
1399 if (n->header & impl::xml_memory_page_name_allocated_mask)
1402 if (n->header & impl::xml_memory_page_value_allocated_mask)
1405 for (xml_attribute_struct* attr = n->first_attribute; attr; )
1407 xml_attribute_struct* next = attr->next_attribute;
1428 child->parent = node;
1436 tail->next_sibling = child;
1437 child->prev_sibling_c = tail;
1438 head->prev_sibling_c = child;
1442 node->first_child = child;
1443 child->prev_sibling_c = child;
1449 child->parent = node;
1455 child->prev_sibling_c = head->prev_sibling_c;
1456 head->prev_sibling_c = child;
1459 child->prev_sibling_c = child;
1461 child->next_sibling = head;
1462 node->first_child = child;
1469 child->parent = parent;
1471 if (node->next_sibling)
1472 node->next_sibling->prev_sibling_c = child;
1474 parent->first_child->prev_sibling_c = child;
1476 child->next_sibling = node->next_sibling;
1477 child->prev_sibling_c = node;
1479 node->next_sibling = child;
1486 child->parent = parent;
1488 if (node->prev_sibling_c->next_sibling)
1489 node->prev_sibling_c->next_sibling = child;
1491 parent->first_child = child;
1493 child->prev_sibling_c = node->prev_sibling_c;
1494 child->next_sibling = node;
1496 node->prev_sibling_c = child;
1503 if (node->next_sibling)
1504 node->next_sibling->prev_sibling_c = node->prev_sibling_c;
1506 parent->first_child->prev_sibling_c = node->prev_sibling_c;
1508 if (node->prev_sibling_c->next_sibling)
1509 node->prev_sibling_c->next_sibling = node->next_sibling;
1511 parent->first_child = node->next_sibling;
1514 node->prev_sibling_c = 0;
1515 node->next_sibling = 0;
1520 xml_attribute_struct* head = node->first_attribute;
1524 xml_attribute_struct* tail = head->prev_attribute_c;
1526 tail->next_attribute = attr;
1527 attr->prev_attribute_c = tail;
1528 head->prev_attribute_c = attr;
1532 node->first_attribute = attr;
1533 attr->prev_attribute_c = attr;
1539 xml_attribute_struct* head = node->first_attribute;
1543 attr->prev_attribute_c = head->prev_attribute_c;
1544 head->prev_attribute_c = attr;
1547 attr->prev_attribute_c = attr;
1549 attr->next_attribute = head;
1550 node->first_attribute = attr;
1555 if (place->next_attribute)
1556 place->next_attribute->prev_attribute_c = attr;
1558 node->first_attribute->prev_attribute_c = attr;
1560 attr->next_attribute = place->next_attribute;
1561 attr->prev_attribute_c = place;
1562 place->next_attribute = attr;
1567 if (place->prev_attribute_c->next_attribute)
1568 place->prev_attribute_c->next_attribute = attr;
1570 node->first_attribute = attr;
1572 attr->prev_attribute_c = place->prev_attribute_c;
1573 attr->next_attribute = place;
1574 place->prev_attribute_c = attr;
1579 if (attr->next_attribute)
1580 attr->next_attribute->prev_attribute_c = attr->prev_attribute_c;
1582 node->first_attribute->prev_attribute_c = attr->prev_attribute_c;
1584 if (attr->prev_attribute_c->next_attribute)
1585 attr->prev_attribute_c->next_attribute = attr->next_attribute;
1587 node->first_attribute = attr->next_attribute;
1589 attr->prev_attribute_c = 0;
1590 attr->next_attribute = 0;
1595 if (!alloc.
reserve())
return 0;
1598 if (!child)
return 0;
1607 if (!alloc.
reserve())
return 0;
1610 if (!attr)
return 0;
1635 return static_cast<uint16_t
>(((value & 0xff) << 8) | (value >> 8));
1640 return ((value & 0xff) << 24) | ((value & 0xff00) << 8) | ((value & 0xff0000) >> 8) | (value >> 24);
1650 if (ch < 0x80)
return result + 1;
1652 else if (ch < 0x800)
return result + 2;
1654 else return result + 3;
1673 *result =
static_cast<uint8_t
>(ch);
1677 else if (ch < 0x800)
1679 result[0] =
static_cast<uint8_t
>(0xC0 | (ch >> 6));
1680 result[1] =
static_cast<uint8_t
>(0x80 | (ch & 0x3F));
1686 result[0] =
static_cast<uint8_t
>(0xE0 | (ch >> 12));
1687 result[1] =
static_cast<uint8_t
>(0x80 | ((ch >> 6) & 0x3F));
1688 result[2] =
static_cast<uint8_t
>(0x80 | (ch & 0x3F));
1696 result[0] =
static_cast<uint8_t
>(0xF0 | (ch >> 18));
1697 result[1] =
static_cast<uint8_t
>(0x80 | ((ch >> 12) & 0x3F));
1698 result[2] =
static_cast<uint8_t
>(0x80 | ((ch >> 6) & 0x3F));
1699 result[3] =
static_cast<uint8_t
>(0x80 | (ch & 0x3F));
1705 return (ch < 0x10000) ?
low(result, ch) :
high(result, ch);
1730 *result =
static_cast<uint16_t
>(ch);
1737 uint32_t msh =
static_cast<uint32_t
>(ch - 0x10000) >> 10;
1738 uint32_t lsh =
static_cast<uint32_t
>(ch - 0x10000) & 0x3ff;
1740 result[0] =
static_cast<uint16_t
>(0xD800 + msh);
1741 result[1] =
static_cast<uint16_t
>(0xDC00 + lsh);
1748 return (ch < 0x10000) ?
low(result, ch) :
high(result, ch);
1799 *result =
static_cast<uint8_t
>(ch > 255 ?
'?' : ch);
1818 template <
typename Traits>
static inline typename Traits::value_type
process(
const uint8_t* data,
size_t size,
typename Traits::value_type result, Traits)
1820 const uint8_t utf8_byte_mask = 0x3f;
1824 uint8_t lead = *data;
1830 result = Traits::low(result, lead);
1835 if ((
reinterpret_cast<uintptr_t
>(data) & 3) == 0)
1838 while (size >= 4 && (*
static_cast<const uint32_t*
>(
static_cast<const void*
>(data)) & 0x80808080) == 0)
1840 result = Traits::low(result, data[0]);
1841 result = Traits::low(result, data[1]);
1842 result = Traits::low(result, data[2]);
1843 result = Traits::low(result, data[3]);
1850 else if (
static_cast<unsigned int>(lead - 0xC0) < 0x20 && size >= 2 && (data[1] & 0xc0) == 0x80)
1852 result = Traits::low(result, ((lead & ~0xC0) << 6) | (data[1] & utf8_byte_mask));
1857 else if (
static_cast<unsigned int>(lead - 0xE0) < 0x10 && size >= 3 && (data[1] & 0xc0) == 0x80 && (data[2] & 0xc0) == 0x80)
1859 result = Traits::low(result, ((lead & ~0xE0) << 12) | ((data[1] & utf8_byte_mask) << 6) | (data[2] & utf8_byte_mask));
1864 else if (
static_cast<unsigned int>(lead - 0xF0) < 0x08 && size >= 4 && (data[1] & 0xc0) == 0x80 && (data[2] & 0xc0) == 0x80 && (data[3] & 0xc0) == 0x80)
1866 result = Traits::high(result, ((lead & ~0xF0) << 18) | ((data[1] & utf8_byte_mask) << 12) | ((data[2] & utf8_byte_mask) << 6) | (data[3] & utf8_byte_mask));
1886 template <
typename Traits>
static inline typename Traits::value_type
process(
const uint16_t* data,
size_t size,
typename Traits::value_type result, Traits)
1890 uint16_t lead = opt_swap::value ?
endian_swap(*data) : *data;
1895 result = Traits::low(result, lead);
1900 else if (
static_cast<unsigned int>(lead - 0xE000) < 0x2000)
1902 result = Traits::low(result, lead);
1907 else if (
static_cast<unsigned int>(lead - 0xD800) < 0x400 && size >= 2)
1909 uint16_t next = opt_swap::value ?
endian_swap(data[1]) : data[1];
1911 if (
static_cast<unsigned int>(next - 0xDC00) < 0x400)
1913 result = Traits::high(result, 0x10000 + ((lead & 0x3ff) << 10) + (next & 0x3ff));
1938 template <
typename Traits>
static inline typename Traits::value_type
process(
const uint32_t* data,
size_t size,
typename Traits::value_type result, Traits)
1945 uint32_t lead = opt_swap::value ?
endian_swap(*data) : *data;
1952 result = Traits::low(result, lead);
1959 result = Traits::high(result, lead);
1973 template <
typename Traits>
static inline typename Traits::value_type
process(
const uint8_t* data,
size_t size,
typename Traits::value_type result, Traits)
1977 result = Traits::low(result, *data);
2011 template <
typename Traits>
static inline typename Traits::value_type
process(
const wchar_t* data,
size_t size,
typename Traits::value_type result, Traits traits)
2015 return decoder::process(
reinterpret_cast<const typename decoder::type*
>(data), size, result, traits);
2019#ifdef PUGIXML_WCHAR_MODE
2020 PUGI__FN void convert_wchar_endian_swap(
wchar_t* result,
const wchar_t* data,
size_t length)
2022 for (
size_t i = 0; i < length; ++i)
2043 55, 0, 0, 0, 0, 0, 0, 0, 0, 12, 12, 0, 0, 63, 0, 0,
2044 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
2045 8, 0, 6, 0, 0, 0, 7, 6, 0, 0, 0, 0, 0, 96, 64, 0,
2046 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 192, 0, 1, 0, 48, 0,
2047 0, 192, 192, 192, 192, 192, 192, 192, 192, 192, 192, 192, 192, 192, 192, 192,
2048 192, 192, 192, 192, 192, 192, 192, 192, 192, 192, 192, 0, 0, 16, 0, 192,
2049 0, 192, 192, 192, 192, 192, 192, 192, 192, 192, 192, 192, 192, 192, 192, 192,
2050 192, 192, 192, 192, 192, 192, 192, 192, 192, 192, 192, 0, 0, 0, 0, 0,
2052 192, 192, 192, 192, 192, 192, 192, 192, 192, 192, 192, 192, 192, 192, 192, 192,
2053 192, 192, 192, 192, 192, 192, 192, 192, 192, 192, 192, 192, 192, 192, 192, 192,
2054 192, 192, 192, 192, 192, 192, 192, 192, 192, 192, 192, 192, 192, 192, 192, 192,
2055 192, 192, 192, 192, 192, 192, 192, 192, 192, 192, 192, 192, 192, 192, 192, 192,
2056 192, 192, 192, 192, 192, 192, 192, 192, 192, 192, 192, 192, 192, 192, 192, 192,
2057 192, 192, 192, 192, 192, 192, 192, 192, 192, 192, 192, 192, 192, 192, 192, 192,
2058 192, 192, 192, 192, 192, 192, 192, 192, 192, 192, 192, 192, 192, 192, 192, 192,
2059 192, 192, 192, 192, 192, 192, 192, 192, 192, 192, 192, 192, 192, 192, 192, 192
2073 3, 3, 3, 3, 3, 3, 3, 3, 3, 0, 2, 3, 3, 2, 3, 3,
2074 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3,
2075 0, 0, 2, 0, 0, 0, 3, 0, 0, 0, 0, 0, 0, 16, 16, 0,
2076 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 0, 0, 3, 0, 3, 0,
2078 0, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20,
2079 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 0, 0, 0, 0, 20,
2080 0, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20,
2081 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 0, 0, 0, 0, 0,
2083 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20,
2084 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20,
2085 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20,
2086 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20,
2087 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20,
2088 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20,
2089 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20,
2090 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20
2093#ifdef PUGIXML_WCHAR_MODE
2094 #define PUGI__IS_CHARTYPE_IMPL(c, ct, table) ((static_cast<unsigned int>(c) < 128 ? table[static_cast<unsigned int>(c)] : table[128]) & (ct))
2096 #define PUGI__IS_CHARTYPE_IMPL(c, ct, table) (table[static_cast<unsigned char>(c)] & (ct))
2099 #define PUGI__IS_CHARTYPE(c, ct) PUGI__IS_CHARTYPE_IMPL(c, ct, chartype_table)
2100 #define PUGI__IS_CHARTYPEX(c, ct) PUGI__IS_CHARTYPE_IMPL(c, ct, chartypex_table)
2104 unsigned int ui = 1;
2106 return *
reinterpret_cast<unsigned char*
>(&ui) == 1;
2113 if (
sizeof(
wchar_t) == 2)
2121 #define PUGI__SCANCHAR(ch) { if (offset >= size || data[offset] != ch) return false; offset++; }
2122 #define PUGI__SCANCHARTYPE(ct) { while (offset < size && PUGI__IS_CHARTYPE(data[offset], ct)) offset++;
2125 if (size < 6 || !((data[0] ==
'<') & (data[1] ==
'?') & (data[2] ==
'x') & (data[3] ==
'm') & (data[4] ==
'l') &&
PUGI__IS_CHARTYPE(data[5],
ct_space)))
2129 for (
size_t i = 6; i + 1 < size; ++i)
2135 if (data[i] ==
'e' && data[i + 1] ==
'n')
2149 uint8_t delimiter = (offset < size && data[offset] ==
'"') ?
'"' :
'\'';
2153 size_t start = offset;
2155 out_encoding = data + offset;
2159 out_length = offset - start;
2169 #undef PUGI__SCANCHAR
2170 #undef PUGI__SCANCHARTYPE
2176 if (size < 4)
return encoding_utf8;
2178 uint8_t d0 = data[0], d1 = data[1], d2 = data[2], d3 = data[3];
2181 if (d0 == 0 && d1 == 0 && d2 == 0xfe && d3 == 0xff)
return encoding_utf32_be;
2182 if (d0 == 0xff && d1 == 0xfe && d2 == 0 && d3 == 0)
return encoding_utf32_le;
2183 if (d0 == 0xfe && d1 == 0xff)
return encoding_utf16_be;
2184 if (d0 == 0xff && d1 == 0xfe)
return encoding_utf16_le;
2185 if (d0 == 0xef && d1 == 0xbb && d2 == 0xbf)
return encoding_utf8;
2188 if (d0 == 0 && d1 == 0 && d2 == 0 && d3 == 0x3c)
return encoding_utf32_be;
2189 if (d0 == 0x3c && d1 == 0 && d2 == 0 && d3 == 0)
return encoding_utf32_le;
2190 if (d0 == 0 && d1 == 0x3c && d2 == 0 && d3 == 0x3f)
return encoding_utf16_be;
2191 if (d0 == 0x3c && d1 == 0 && d2 == 0x3f && d3 == 0)
return encoding_utf16_le;
2194 if (d0 == 0 && d1 == 0x3c)
return encoding_utf16_be;
2195 if (d0 == 0x3c && d1 == 0)
return encoding_utf16_le;
2198 const uint8_t* enc = 0;
2199 size_t enc_length = 0;
2204 if (enc_length == 10
2205 && (enc[0] |
' ') ==
'i' && (enc[1] |
' ') ==
's' && (enc[2] |
' ') ==
'o'
2206 && enc[3] ==
'-' && enc[4] ==
'8' && enc[5] ==
'8' && enc[6] ==
'5' && enc[7] ==
'9'
2207 && enc[8] ==
'-' && enc[9] ==
'1')
2208 return encoding_latin1;
2212 && (enc[0] |
' ') ==
'l' && (enc[1] |
' ') ==
'a' && (enc[2] |
' ') ==
't'
2213 && (enc[3] |
' ') ==
'i' && (enc[4] |
' ') ==
'n'
2215 return encoding_latin1;
2218 return encoding_utf8;
2227 if (encoding == encoding_utf16)
return is_little_endian() ? encoding_utf16_le : encoding_utf16_be;
2230 if (encoding == encoding_utf32)
return is_little_endian() ? encoding_utf32_le : encoding_utf32_be;
2233 if (encoding != encoding_auto)
return encoding;
2236 const uint8_t* data =
static_cast<const uint8_t*
>(contents);
2243 size_t length = size /
sizeof(char_t);
2247 out_buffer =
static_cast<char_t*
>(
const_cast<void*
>(contents));
2248 out_length = length;
2253 if (!buffer)
return false;
2256 memcpy(buffer, contents, length *
sizeof(char_t));
2258 assert(length == 0);
2262 out_buffer = buffer;
2263 out_length = length + 1;
2269#ifdef PUGIXML_WCHAR_MODE
2270 PUGI__FN bool need_endian_swap_utf(xml_encoding le, xml_encoding re)
2276 PUGI__FN bool convert_buffer_endian_swap(char_t*& out_buffer,
size_t& out_length,
const void* contents,
size_t size,
bool is_mutable)
2278 const char_t* data =
static_cast<const char_t*
>(contents);
2279 size_t length = size /
sizeof(char_t);
2283 char_t* buffer =
const_cast<char_t*
>(data);
2285 convert_wchar_endian_swap(buffer, data, length);
2287 out_buffer = buffer;
2288 out_length = length;
2293 if (!buffer)
return false;
2295 convert_wchar_endian_swap(buffer, data, length);
2298 out_buffer = buffer;
2299 out_length = length + 1;
2307 const typename D::type* data =
static_cast<const typename D::type*
>(contents);
2308 size_t data_length = size /
sizeof(
typename D::type);
2311 size_t length = D::process(data, data_length, 0,
wchar_counter());
2315 if (!buffer)
return false;
2318 wchar_writer::value_type obegin =
reinterpret_cast<wchar_writer::value_type
>(buffer);
2319 wchar_writer::value_type oend = D::process(data, data_length, obegin,
wchar_writer());
2321 assert(oend == obegin + length);
2324 out_buffer = buffer;
2325 out_length = length + 1;
2330 PUGI__FN bool convert_buffer(char_t*& out_buffer,
size_t& out_length, xml_encoding encoding,
const void* contents,
size_t size,
bool is_mutable)
2336 if (encoding == wchar_encoding)
2340 if (need_endian_swap_utf(encoding, wchar_encoding))
2341 return convert_buffer_endian_swap(out_buffer, out_length, contents, size, is_mutable);
2344 if (encoding == encoding_utf8)
2348 if (encoding == encoding_utf16_be || encoding == encoding_utf16_le)
2352 return (native_encoding == encoding) ?
2358 if (encoding == encoding_utf32_be || encoding == encoding_utf32_le)
2362 return (native_encoding == encoding) ?
2368 if (encoding == encoding_latin1)
2371 assert(
false &&
"Invalid encoding");
2377 const typename D::type* data =
static_cast<const typename D::type*
>(contents);
2378 size_t data_length = size /
sizeof(
typename D::type);
2381 size_t length = D::process(data, data_length, 0,
utf8_counter());
2385 if (!buffer)
return false;
2388 uint8_t* obegin =
reinterpret_cast<uint8_t*
>(buffer);
2389 uint8_t* oend = D::process(data, data_length, obegin,
utf8_writer());
2391 assert(oend == obegin + length);
2394 out_buffer = buffer;
2395 out_length = length + 1;
2402 for (
size_t i = 0; i < size; ++i)
2411 const uint8_t* data =
static_cast<const uint8_t*
>(contents);
2412 size_t data_length = size;
2416 assert(prefix_length <= data_length);
2418 const uint8_t* postfix = data + prefix_length;
2419 size_t postfix_length = data_length - prefix_length;
2422 if (postfix_length == 0)
return get_mutable_buffer(out_buffer, out_length, contents, size, is_mutable);
2429 if (!buffer)
return false;
2432 memcpy(buffer, data, prefix_length);
2434 uint8_t* obegin =
reinterpret_cast<uint8_t*
>(buffer);
2437 assert(oend == obegin + length);
2440 out_buffer = buffer;
2441 out_length = length + 1;
2446 PUGI__FN bool convert_buffer(char_t*& out_buffer,
size_t& out_length, xml_encoding encoding,
const void* contents,
size_t size,
bool is_mutable)
2449 if (encoding == encoding_utf8)
2453 if (encoding == encoding_utf16_be || encoding == encoding_utf16_le)
2455 xml_encoding native_encoding =
is_little_endian() ? encoding_utf16_le : encoding_utf16_be;
2457 return (native_encoding == encoding) ?
2463 if (encoding == encoding_utf32_be || encoding == encoding_utf32_le)
2465 xml_encoding native_encoding =
is_little_endian() ? encoding_utf32_le : encoding_utf32_be;
2467 return (native_encoding == encoding) ?
2473 if (encoding == encoding_latin1)
2476 assert(
false &&
"Invalid encoding");
2490 uint8_t*
begin =
reinterpret_cast<uint8_t*
>(buffer);
2498#ifndef PUGIXML_NO_STL
2506 result.resize(size);
2509 if (size > 0)
as_utf8_end(&result[0], size, str, length);
2516 const uint8_t* data =
reinterpret_cast<const uint8_t*
>(str);
2522 std::basic_string<wchar_t> result;
2523 result.resize(length);
2528 wchar_writer::value_type
begin =
reinterpret_cast<wchar_writer::value_type
>(&result[0]);
2539 template <
typename Header>
2545 size_t target_length =
strlength(target);
2548 if ((header & header_mask) == 0)
return target_length >= length;
2551 const size_t reuse_threshold = 32;
2553 return target_length >= length && (target_length < reuse_threshold || target_length - length < target_length / 2);
2556 template <
typename String,
typename Header>
2559 if (source_length == 0)
2568 header &= ~header_mask;
2575 memcpy(dest, source, source_length *
sizeof(char_t));
2576 dest[source_length] = 0;
2584 if (!alloc->
reserve())
return false;
2588 if (!buf)
return false;
2591 memcpy(buf, source, source_length *
sizeof(char_t));
2592 buf[source_length] = 0;
2599 header |= header_mask;
2616 void push(char_t*& s,
size_t count)
2622 memmove(
end -
size,
end,
reinterpret_cast<char*
>(s) -
reinterpret_cast<char*
>(
end));
2639 memmove(
end -
size,
end,
reinterpret_cast<char*
>(s) -
reinterpret_cast<char*
>(
end));
2649 char_t* stre = s + 1;
2655 unsigned int ucsc = 0;
2663 if (ch ==
';')
return stre;
2667 if (
static_cast<unsigned int>(ch -
'0') <= 9)
2668 ucsc = 16 * ucsc + (ch -
'0');
2669 else if (
static_cast<unsigned int>((ch |
' ') -
'a') <= 5)
2670 ucsc = 16 * ucsc + ((ch |
' ') -
'a' + 10);
2683 char_t ch = *++stre;
2685 if (ch ==
';')
return stre;
2689 if (
static_cast<unsigned int>(ch -
'0') <= 9)
2690 ucsc = 10 * ucsc + (ch -
'0');
2702 #ifdef PUGIXML_WCHAR_MODE
2703 s =
reinterpret_cast<char_t*
>(wchar_writer::any(
reinterpret_cast<wchar_writer::value_type
>(s), ucsc));
2705 s =
reinterpret_cast<char_t*
>(
utf8_writer::any(
reinterpret_cast<uint8_t*
>(s), ucsc));
2708 g.
push(s, stre - s);
2718 if (*++stre ==
'p' && *++stre ==
';')
2723 g.
push(s, stre - s);
2727 else if (*stre ==
'p')
2729 if (*++stre ==
'o' && *++stre ==
's' && *++stre ==
';')
2734 g.
push(s, stre - s);
2743 if (*++stre ==
't' && *++stre ==
';')
2748 g.
push(s, stre - s);
2756 if (*++stre ==
't' && *++stre ==
';')
2761 g.
push(s, stre - s);
2769 if (*++stre ==
'u' && *++stre ==
'o' && *++stre ==
't' && *++stre ==
';')
2774 g.
push(s, stre - s);
2788 #define PUGI__ENDSWITH(c, e) ((c) == (e) || ((c) == 0 && endch == (e)))
2789 #define PUGI__SKIPWS() { while (PUGI__IS_CHARTYPE(*s, ct_space)) ++s; }
2790 #define PUGI__OPTSET(OPT) ( optmsk & (OPT) )
2791 #define PUGI__PUSHNODE(TYPE) { cursor = append_new_node(cursor, *alloc, TYPE); if (!cursor) PUGI__THROW_ERROR(status_out_of_memory, s); }
2792 #define PUGI__POPNODE() { cursor = cursor->parent; }
2793 #define PUGI__SCANFOR(X) { while (*s != 0 && !(X)) ++s; }
2794 #define PUGI__SCANWHILE(X) { while (X) ++s; }
2795 #define PUGI__SCANWHILE_UNROLL(X) { for (;;) { char_t ss = s[0]; if (PUGI__UNLIKELY(!(X))) { break; } ss = s[1]; if (PUGI__UNLIKELY(!(X))) { s += 1; break; } ss = s[2]; if (PUGI__UNLIKELY(!(X))) { s += 2; break; } ss = s[3]; if (PUGI__UNLIKELY(!(X))) { s += 3; break; } s += 4; } }
2796 #define PUGI__ENDSEG() { ch = *s; *s = 0; ++s; }
2797 #define PUGI__THROW_ERROR(err, m) return error_offset = m, error_status = err, static_cast<char_t*>(0)
2798 #define PUGI__CHECK_ERROR(err, m) { if (*s == 0) PUGI__THROW_ERROR(err, m); }
2812 if (*s ==
'\n') g.
push(s, 1);
2814 else if (s[0] ==
'-' && s[1] ==
'-' &&
PUGI__ENDSWITH(s[2],
'>'))
2818 return s + (s[2] ==
'>' ? 3 : 2);
2840 if (*s ==
'\n') g.
push(s, 1);
2842 else if (s[0] ==
']' && s[1] ==
']' &&
PUGI__ENDSWITH(s[2],
'>'))
2856 typedef char_t* (*strconv_pcdata_t)(char_t*);
2874 if (opt_trim::value)
2882 else if (opt_eol::value && *s ==
'\r')
2886 if (*s ==
'\n') g.
push(s, 1);
2888 else if (opt_escape::value && *s ==
'&')
2896 if (opt_trim::value)
2911 PUGI__STATIC_ASSERT(parse_escapes == 0x10 && parse_eol == 0x20 && parse_trim_pcdata == 0x0800);
2913 switch (((optmask >> 4) & 3) | ((optmask >> 9) & 4))
2923 default: assert(
false);
return 0;
2927 typedef char_t* (*strconv_attribute_t)(char_t*, char_t);
2950 if (*s == end_quote)
2952 char_t* str = g.
flush(s);
2965 char_t* str = s + 1;
2971 else if (opt_escape::value && *s ==
'&')
2991 if (*s == end_quote)
3003 if (*s ==
'\n') g.
push(s, 1);
3007 else if (opt_escape::value && *s ==
'&')
3027 if (*s == end_quote)
3033 else if (*s ==
'\r')
3037 if (*s ==
'\n') g.
push(s, 1);
3039 else if (opt_escape::value && *s ==
'&')
3059 if (*s == end_quote)
3065 else if (opt_escape::value && *s ==
'&')
3080 PUGI__STATIC_ASSERT(parse_escapes == 0x10 && parse_eol == 0x20 && parse_wconv_attribute == 0x40 && parse_wnorm_attribute == 0x80);
3082 switch ((optmask >> 4) & 15)
3100 default: assert(
false);
return 0;
3106 xml_parse_result result;
3107 result.status = status;
3108 result.offset = offset;
3132 if (*s ==
'"' || *s ==
'\'')
3141 else if (s[0] ==
'<' && s[1] ==
'?')
3150 else if (s[0] ==
'<' && s[1] ==
'!' && s[2] ==
'-' && s[3] ==
'-')
3167 assert(s[0] ==
'<' && s[1] ==
'!' && s[2] ==
'[');
3172 if (s[0] ==
'<' && s[1] ==
'!' && s[2] ==
'[')
3178 else if (s[0] ==
']' && s[1] ==
']' && s[2] ==
'>')
3198 assert((s[0] ==
'<' || s[0] == 0) && s[1] ==
'!');
3203 if (s[0] ==
'<' && s[1] ==
'!' && s[2] !=
'-')
3218 else if (s[0] ==
'<' || s[0] ==
'"' || s[0] ==
'\'')
3274 s += (s[2] ==
'>' ? 3 : 2);
3282 if (*++s==
'C' && *++s==
'D' && *++s==
'A' && *++s==
'T' && *++s==
'A' && *++s ==
'[')
3315 s += (s[1] ==
'>' ? 2 : 1);
3319 else if (s[0] ==
'D' && s[1] ==
'O' && s[2] ==
'C' && s[3] ==
'T' && s[4] ==
'Y' && s[5] ==
'P' &&
PUGI__ENDSWITH(s[6],
'E'))
3325 char_t* mark = s + 9;
3330 assert((*s == 0 && endch ==
'>') || *s ==
'>');
3339 cursor->value = mark;
3367 bool declaration = (target[0] |
' ') ==
'x' && (target[1] |
' ') ==
'm' && (target[2] |
' ') ==
'l' && target + 3 == s;
3383 cursor->name = target;
3417 cursor->value = value;
3434 s += (s[1] ==
'>' ? 2 : 1);
3438 ref_cursor = cursor;
3501 if (*s ==
'"' || *s ==
'\'')
3507 s = strconv_attribute(s, ch);
3530 else if (*s == 0 && endch ==
'>')
3543 else if (*s == 0 && endch ==
'>')
3575 char_t* name = cursor->name;
3585 if (*s == 0 && name[0] == endch && name[1] == 0)
PUGI__THROW_ERROR(status_bad_end_element, s);
3609 if (
PUGI__NODETYPE(cursor) == node_declaration)
goto LOC_ATTRIBUTES;
3625 if (*s ==
'<' || !*s)
3636 if (s[0] !=
'<' || s[1] !=
'/' || cursor->first_child)
continue;
3645 if (
PUGI__OPTSET(parse_embed_pcdata) && cursor->parent && !cursor->first_child && !cursor->value)
3658 s = strconv_pcdata(s);
3681 #ifdef PUGIXML_WCHAR_MODE
3684 unsigned int bom = 0xfeff;
3685 return (s[0] ==
static_cast<wchar_t>(bom)) ? s + 1 : s;
3690 return (s[0] ==
'\xef' && s[1] ==
'\xbb' && s[2] ==
'\xbf') ? s + 3 : s;
3700 node = node->next_sibling;
3713 xml_node_struct* last_root_child = root->first_child ? root->first_child->prev_sibling_c + 0 : 0;
3719 char_t endch = buffer[length - 1];
3720 buffer[length - 1] = 0;
3726 parser.
parse_tree(buffer_data, root, optmsk, endch);
3729 assert(result.offset >= 0 &&
static_cast<size_t>(result.offset) <= length);
3738 xml_node_struct* first_root_child_parsed = last_root_child ? last_root_child->next_sibling + 0 : root->first_child+ 0;
3746 if (result.offset > 0 &&
static_cast<size_t>(result.offset) == length - 1 && endch == 0)
3757 #ifdef PUGIXML_WCHAR_MODE
3760 return encoding_utf8;
3770 if (encoding == encoding_utf16)
return is_little_endian() ? encoding_utf16_le : encoding_utf16_be;
3773 if (encoding == encoding_utf32)
return is_little_endian() ? encoding_utf32_le : encoding_utf32_be;
3776 if (encoding != encoding_auto)
return encoding;
3779 return encoding_utf8;
3786 typename T::value_type
end = D::process(
reinterpret_cast<const typename D::type*
>(data), length, dest, T());
3788 return static_cast<size_t>(
end - dest) *
sizeof(*dest);
3795 typename T::value_type
end = D::process(
reinterpret_cast<const typename D::type*
>(data), length, dest, T());
3799 for (
typename T::value_type i = dest; i !=
end; ++i)
3803 return static_cast<size_t>(
end - dest) *
sizeof(*dest);
3806#ifdef PUGIXML_WCHAR_MODE
3809 if (length < 1)
return 0;
3812 return (
sizeof(
wchar_t) == 2 &&
static_cast<unsigned int>(
static_cast<uint16_t
>(data[length - 1]) - 0xD800) < 0x400) ? length - 1 : length;
3815 PUGI__FN size_t convert_buffer_output(char_t* r_char, uint8_t* r_u8, uint16_t* r_u16, uint32_t* r_u32,
const char_t* data,
size_t length, xml_encoding encoding)
3820 convert_wchar_endian_swap(r_char, data, length);
3822 return length *
sizeof(char_t);
3826 if (encoding == encoding_utf8)
3830 if (encoding == encoding_utf16_be || encoding == encoding_utf16_le)
3838 if (encoding == encoding_utf32_be || encoding == encoding_utf32_le)
3846 if (encoding == encoding_latin1)
3849 assert(
false &&
"Invalid encoding");
3855 if (length < 5)
return 0;
3857 for (
size_t i = 1; i <= 4; ++i)
3859 uint8_t ch =
static_cast<uint8_t
>(data[length - i]);
3862 if ((ch & 0xc0) != 0x80)
return length - i;
3871 if (encoding == encoding_utf16_be || encoding == encoding_utf16_le)
3873 xml_encoding native_encoding =
is_little_endian() ? encoding_utf16_le : encoding_utf16_be;
3878 if (encoding == encoding_utf32_be || encoding == encoding_utf32_le)
3880 xml_encoding native_encoding =
is_little_endian() ? encoding_utf32_le : encoding_utf32_be;
3885 if (encoding == encoding_latin1)
3888 assert(
false &&
"Invalid encoding");
3911 void flush(
const char_t* data,
size_t size)
3913 if (size == 0)
return;
3917 writer.write(data, size *
sizeof(char_t));
3922 assert(result <=
sizeof(
scratch));
3940 writer.write(data, length *
sizeof(char_t));
3953 flush(data, chunk_size);
3957 length -= chunk_size;
3974 memcpy(
buffer + offset, data, length *
sizeof(char_t));
3989 buffer[offset++] = *data++;
3999 size_t length = offset -
bufsize;
4027 void write(char_t d0, char_t d1, char_t d2)
4038 void write(char_t d0, char_t d1, char_t d2, char_t d3)
4050 void write(char_t d0, char_t d1, char_t d2, char_t d3, char_t d4)
4063 void write(char_t d0, char_t d1, char_t d2, char_t d3, char_t d4, char_t d5)
4083 #ifdef PUGIXML_MEMORY_OUTPUT_STACK
4084 PUGIXML_MEMORY_OUTPUT_STACK
4111 const char_t* prev = s;
4116 writer.
write_buffer(prev,
static_cast<size_t>(s - prev));
4122 writer.
write(
'&',
'a',
'm',
'p',
';');
4126 writer.
write(
'&',
'l',
't',
';');
4130 writer.
write(
'&',
'g',
't',
';');
4134 writer.
write(
'&',
'q',
'u',
'o',
't',
';');
4139 unsigned int ch =
static_cast<unsigned int>(*s++);
4142 writer.
write(
'&',
'#',
static_cast<char_t
>((ch / 10) +
'0'),
static_cast<char_t
>((ch % 10) +
'0'),
';');
4150 if (flags & format_no_escapes)
4160 writer.
write(
'<',
'!',
'[',
'C',
'D');
4161 writer.
write(
'A',
'T',
'A',
'[');
4163 const char_t* prev = s;
4166 while (*s && !(s[0] ==
']' && s[1] ==
']' && s[2] ==
'>')) ++s;
4171 writer.
write_buffer(prev,
static_cast<size_t>(s - prev));
4173 writer.
write(
']',
']',
'>');
4180 switch (indent_length)
4184 for (
unsigned int i = 0; i < depth; ++i)
4185 writer.
write(indent[0]);
4191 for (
unsigned int i = 0; i < depth; ++i)
4192 writer.
write(indent[0], indent[1]);
4198 for (
unsigned int i = 0; i < depth; ++i)
4199 writer.
write(indent[0], indent[1], indent[2]);
4205 for (
unsigned int i = 0; i < depth; ++i)
4206 writer.
write(indent[0], indent[1], indent[2], indent[3]);
4212 for (
unsigned int i = 0; i < depth; ++i)
4220 writer.
write(
'<',
'!',
'-',
'-');
4224 const char_t* prev = s;
4227 while (*s && !(s[0] ==
'-' && (s[1] ==
'-' || s[1] == 0))) ++s;
4229 writer.
write_buffer(prev,
static_cast<size_t>(s - prev));
4235 writer.
write(
'-',
' ');
4240 writer.
write(
'-',
'-',
'>');
4247 const char_t* prev = s;
4250 while (*s && !(s[0] ==
'?' && s[1] ==
'>')) ++s;
4252 writer.
write_buffer(prev,
static_cast<size_t>(s - prev));
4256 assert(s[0] ==
'?' && s[1] ==
'>');
4258 writer.
write(
'?',
' ',
'>');
4266 const char_t* default_name =
PUGIXML_TEXT(
":anonymous");
4268 for (xml_attribute_struct* a = node->first_attribute; a; a = a->next_attribute)
4270 if ((flags & (format_indent_attributes | format_raw)) == format_indent_attributes)
4281 writer.
write_string(a->name ? a->name + 0 : default_name);
4282 writer.
write(
'=',
'"');
4293 const char_t* default_name =
PUGIXML_TEXT(
":anonymous");
4294 const char_t* name = node->name ? node->name + 0 : default_name;
4299 if (node->first_attribute)
4305 if (!node->first_child)
4307 if (flags & format_no_empty_element_tags)
4309 writer.
write(
'>',
'<',
'/');
4317 if ((flags & format_raw) == 0)
4320 writer.
write(
'/',
'>');
4338 if (!node->first_child)
4340 writer.
write(
'<',
'/');
4355 const char_t* default_name =
PUGIXML_TEXT(
":anonymous");
4356 const char_t* name = node->name ? node->name + 0 : default_name;
4358 writer.
write(
'<',
'/');
4365 const char_t* default_name =
PUGIXML_TEXT(
":anonymous");
4382 writer.
write(
'<',
'?');
4383 writer.
write_string(node->name ? node->name + 0 : default_name);
4391 writer.
write(
'?',
'>');
4394 case node_declaration:
4395 writer.
write(
'<',
'?');
4396 writer.
write_string(node->name ? node->name + 0 : default_name);
4398 writer.
write(
'?',
'>');
4402 writer.
write(
'<',
'!',
'D',
'O',
'C');
4403 writer.
write(
'T',
'Y',
'P',
'E');
4415 assert(
false &&
"Invalid node type");
4427 size_t indent_length = ((flags & (format_indent | format_indent_attributes)) && (flags & format_raw) == 0) ?
strlength(indent) : 0;
4445 if ((indent_flags &
indent_newline) && (flags & format_raw) == 0)
4461 node = node->first_child;
4470 if (node->first_child)
4472 node = node->first_child;
4485 while (node != root)
4487 if (node->next_sibling)
4489 node = node->next_sibling;
4493 node = node->parent;
4500 if ((indent_flags &
indent_newline) && (flags & format_raw) == 0)
4512 while (node != root);
4514 if ((indent_flags &
indent_newline) && (flags & format_raw) == 0)
4520 for (
xml_node_struct* child = node->first_child; child; child = child->next_sibling)
4524 if (type == node_declaration)
return true;
4525 if (type == node_element)
return false;
4533 for (xml_attribute_struct* a = node->first_attribute; a; a = a->next_attribute)
4542 return parent == node_element || parent == node_declaration;
4547 if (parent != node_document && parent != node_element)
return false;
4548 if (child == node_document || child == node_null)
return false;
4549 if (parent != node_document && (child == node_declaration || child == node_doctype))
return false;
4561 if (parent.root() != child.root())
4565 xml_node cur = parent;
4578 template <
typename String,
typename Header>
4581 assert(!dest && (header & header_mask) == 0);
4585 if (alloc && (source_header & header_mask) == 0)
4603 for (xml_attribute_struct* sa =
sn->first_attribute; sa; sa = sa->next_attribute)
4625 while (sit && sit !=
sn)
4636 if (sit->first_child)
4639 sit = sit->first_child;
4648 if (sit->next_sibling)
4650 sit = sit->next_sibling;
4674 return type == node_pcdata || type == node_cdata;
4681 const char_t* s = value;
4686 bool negative = (*s ==
'-');
4688 s += (*s ==
'+' || *s ==
'-');
4690 bool overflow =
false;
4692 if (s[0] ==
'0' && (s[1] |
' ') ==
'x')
4700 const char_t* start = s;
4704 if (
static_cast<unsigned>(*s -
'0') < 10)
4705 result = result * 16 + (*s -
'0');
4706 else if (
static_cast<unsigned>((*s |
' ') -
'a') < 6)
4707 result = result * 16 + ((*s |
' ') -
'a' + 10);
4714 size_t digits =
static_cast<size_t>(s - start);
4716 overflow = digits >
sizeof(U) * 2;
4724 const char_t* start = s;
4728 if (
static_cast<unsigned>(*s -
'0') < 10)
4729 result = result * 10 + (*s -
'0');
4736 size_t digits =
static_cast<size_t>(s - start);
4740 const size_t max_digits10 =
sizeof(U) == 8 ? 20 :
sizeof(U) == 4 ? 10 : 5;
4741 const char_t max_lead =
sizeof(U) == 8 ?
'1' :
sizeof(U) == 4 ?
'4' :
'6';
4742 const size_t high_bit =
sizeof(U) * 8 - 1;
4744 overflow = digits >= max_digits10 && !(digits == max_digits10 && (*start < max_lead || (*start == max_lead && result >> high_bit)));
4751 return (overflow || result > ~minv + 1) ? minv : ~result + 1;
4753 return (overflow || result > 0 - minv) ? minv : 0 - result;
4757 return (overflow || result > maxv) ? maxv : result;
4762 return string_to_integer<unsigned int>(value,
static_cast<unsigned int>(INT_MIN), INT_MAX);
4767 return string_to_integer<unsigned int>(value, 0, UINT_MAX);
4772 #ifdef PUGIXML_WCHAR_MODE
4773 return wcstod(value, 0);
4775 return strtod(value, 0);
4781 #ifdef PUGIXML_WCHAR_MODE
4782 return static_cast<float>(wcstod(value, 0));
4784 return static_cast<float>(strtod(value, 0));
4791 char_t first = *value;
4794 return (first ==
'1' || first ==
't' || first ==
'T' || first ==
'y' || first ==
'Y');
4797#ifdef PUGIXML_HAS_LONG_LONG
4798 PUGI__FN long long get_value_llong(
const char_t* value)
4800 return string_to_integer<unsigned long long>(value,
static_cast<unsigned long long>(LLONG_MIN), LLONG_MAX);
4803 PUGI__FN unsigned long long get_value_ullong(
const char_t* value)
4805 return string_to_integer<unsigned long long>(value, 0, ULLONG_MAX);
4811 char_t* result =
end - 1;
4812 U rest = negative ? 0 - value : value;
4816 *result-- =
static_cast<char_t
>(
'0' + (rest % 10));
4821 assert(result >=
begin);
4826 return result + !negative;
4830 template <
typename String,
typename Header>
4833 #ifdef PUGIXML_WCHAR_MODE
4835 assert(strlen(buf) <
sizeof(wbuf) /
sizeof(wbuf[0]));
4838 for (; buf[offset]; ++offset) wbuf[offset] = buf[offset];
4840 return strcpy_insitu(dest, header, header_mask, wbuf, offset);
4842 return strcpy_insitu(dest, header, header_mask, buf, strlen(buf));
4846 template <
typename U,
typename String,
typename Header>
4850 char_t*
end = buf +
sizeof(buf) /
sizeof(buf[0]);
4856 template <
typename String,
typename Header>
4865 template <
typename String,
typename Header>
4874 template <
typename String,
typename Header>
4886 xml_encoding buffer_encoding = impl::get_buffer_encoding(encoding, contents, size);
4892 if (!impl::convert_buffer(buffer, length, buffer_encoding, contents, size, is_mutable))
return impl::make_parse_result(status_out_of_memory);
4895 if (own && buffer != contents && contents) impl::xml_memory::deallocate(contents);
4898 if (own || buffer != contents) *out_buffer = buffer;
4904 xml_parse_result res = impl::xml_parser::parse(buffer, length, doc, root, options);
4907 res.encoding = buffer_encoding;
4915 #if defined(PUGI__MSVC_CRT_VERSION) && PUGI__MSVC_CRT_VERSION >= 1400 && !defined(_WIN32_WCE)
4917 typedef __int64 length_type;
4919 _fseeki64(file, 0, SEEK_END);
4920 length_type length = _ftelli64(file);
4921 _fseeki64(file, 0, SEEK_SET);
4922 #elif defined(__MINGW32__) && !defined(__NO_MINGW_LFS) && (!defined(__STRICT_ANSI__) || defined(__MINGW64_VERSION_MAJOR))
4924 typedef off64_t length_type;
4926 fseeko64(file, 0, SEEK_END);
4927 length_type length = ftello64(file);
4928 fseeko64(file, 0, SEEK_SET);
4931 typedef long length_type;
4933 fseek(file, 0, SEEK_END);
4934 length_type length = ftell(file);
4935 fseek(file, 0, SEEK_SET);
4939 if (length < 0)
return status_io_error;
4942 size_t result =
static_cast<size_t>(length);
4944 if (
static_cast<length_type
>(result) != length)
return status_out_of_memory;
4947 out_result = result;
4956 #ifdef PUGIXML_WCHAR_MODE
4959 if (encoding == wchar_encoding || need_endian_swap_utf(encoding, wchar_encoding))
4961 size_t length = size /
sizeof(char_t);
4963 static_cast<char_t*
>(buffer)[length] = 0;
4964 return (length + 1) *
sizeof(char_t);
4967 if (encoding == encoding_utf8)
4969 static_cast<char*
>(buffer)[size] = 0;
4986 size_t max_suffix_size =
sizeof(char_t);
4993 size_t read_size = fread(contents, 1, size, file);
4995 if (read_size != size)
5003 return load_buffer_impl(doc, doc, contents,
zero_terminate_buffer(contents, size, real_encoding), options, real_encoding,
true,
true, out_buffer);
5011#ifndef PUGIXML_NO_STL
5017 if (!memory)
return 0;
5053 while (!stream.eof())
5057 if (!chunk)
return status_out_of_memory;
5060 if (last) last = last->
next = chunk;
5061 else chunks.
data = last = chunk;
5064 stream.read(chunk->
data,
static_cast<std::streamsize
>(
sizeof(chunk->
data) /
sizeof(T)));
5065 chunk->
size =
static_cast<size_t>(stream.gcount()) *
sizeof(T);
5068 if (stream.bad() || (!stream.eof() && stream.fail()))
return status_io_error;
5071 if (total + chunk->
size < total)
return status_out_of_memory;
5072 total += chunk->
size;
5075 size_t max_suffix_size =
sizeof(char_t);
5079 if (!buffer)
return status_out_of_memory;
5081 char* write = buffer;
5085 assert(write + chunk->size <= buffer + total);
5086 memcpy(write, chunk->data, chunk->size);
5087 write += chunk->size;
5090 assert(write == buffer + total);
5093 *out_buffer = buffer;
5102 typename std::basic_istream<T>::pos_type pos = stream.tellg();
5103 stream.seekg(0, std::ios::end);
5104 std::streamoff length = stream.tellg() - pos;
5107 if (stream.fail() || pos < 0)
return status_io_error;
5110 size_t read_length =
static_cast<size_t>(length);
5112 if (
static_cast<std::streamsize
>(read_length) != length || length < 0)
return status_out_of_memory;
5114 size_t max_suffix_size =
sizeof(char_t);
5118 if (!buffer.
data)
return status_out_of_memory;
5120 stream.read(
static_cast<T*
>(buffer.
data),
static_cast<std::streamsize
>(read_length));
5123 if (stream.bad() || (!stream.eof() && stream.fail()))
return status_io_error;
5126 size_t actual_length =
static_cast<size_t>(stream.gcount());
5127 assert(actual_length <= read_length);
5129 *out_buffer = buffer.
release();
5130 *out_size = actual_length *
sizeof(T);
5139 xml_parse_status status = status_ok;
5145 if (stream.tellg() < 0)
5157 return load_buffer_impl(doc, doc, buffer,
zero_terminate_buffer(buffer, size, real_encoding), options, real_encoding,
true,
true, out_buffer);
5161#if defined(PUGI__MSVC_CRT_VERSION) || defined(__BORLANDC__) || (defined(__MINGW32__) && (!defined(__STRICT_ANSI__) || defined(__MINGW64_VERSION_MAJOR)))
5164 return _wfopen(path, mode);
5177 if (!result)
return 0;
5192 if (!path_utf8)
return 0;
5195 char mode_ascii[4] = {0};
5196 for (
size_t i = 0; mode[i]; ++i) mode_ascii[i] =
static_cast<char>(mode[i]);
5199 FILE* result = fopen(path_utf8, mode_ascii);
5208 PUGI__FN bool save_file_impl(
const xml_document& doc, FILE* file,
const char_t* indent,
unsigned int flags, xml_encoding encoding)
5210 if (!file)
return false;
5212 xml_writer_file writer(file);
5213 doc.save(writer, indent, flags, encoding);
5215 return ferror(file) == 0;
5243 size_t result = fwrite(data, 1, size,
static_cast<FILE*
>(
file));
5247#ifndef PUGIXML_NO_STL
5261 narrow_stream->write(
reinterpret_cast<const char*
>(data),
static_cast<std::streamsize
>(size));
5266 assert(size %
sizeof(
wchar_t) == 0);
5268 wide_stream->write(
reinterpret_cast<const wchar_t*
>(data),
static_cast<std::streamsize
>(size /
sizeof(
wchar_t)));
5388#ifdef PUGIXML_HAS_LONG_LONG
5389 PUGI__FN long long xml_attribute::as_llong(
long long def)
const
5394 PUGI__FN unsigned long long xml_attribute::as_ullong(
unsigned long long def)
const
5473#ifdef PUGIXML_HAS_LONG_LONG
5489 if (!
_attr)
return false;
5491 return impl::strcpy_insitu(
_attr->
name,
_attr->
header, impl::xml_memory_page_name_allocated_mask, rhs, impl::strlength(rhs));
5496 if (!
_attr)
return false;
5498 return impl::strcpy_insitu(
_attr->
value,
_attr->
header, impl::xml_memory_page_value_allocated_mask, rhs, impl::strlength(rhs));
5503 if (!
_attr)
return false;
5505 return impl::set_value_integer<unsigned int>(
_attr->
value,
_attr->
header, impl::xml_memory_page_value_allocated_mask, rhs, rhs < 0);
5510 if (!
_attr)
return false;
5512 return impl::set_value_integer<unsigned int>(
_attr->
value,
_attr->
header, impl::xml_memory_page_value_allocated_mask, rhs,
false);
5517 if (!
_attr)
return false;
5519 return impl::set_value_integer<unsigned long>(
_attr->
value,
_attr->
header, impl::xml_memory_page_value_allocated_mask, rhs, rhs < 0);
5524 if (!
_attr)
return false;
5526 return impl::set_value_integer<unsigned long>(
_attr->
value,
_attr->
header, impl::xml_memory_page_value_allocated_mask, rhs,
false);
5531 if (!
_attr)
return false;
5533 return impl::set_value_convert(
_attr->
value,
_attr->
header, impl::xml_memory_page_value_allocated_mask, rhs);
5538 if (!
_attr)
return false;
5540 return impl::set_value_convert(
_attr->
value,
_attr->
header, impl::xml_memory_page_value_allocated_mask, rhs);
5545 if (!
_attr)
return false;
5547 return impl::set_value_bool(
_attr->
value,
_attr->
header, impl::xml_memory_page_value_allocated_mask, rhs);
5550#ifdef PUGIXML_HAS_LONG_LONG
5553 if (!
_attr)
return false;
5555 return impl::set_value_integer<unsigned long long>(
_attr->
value,
_attr->
header, impl::xml_memory_page_value_allocated_mask, rhs, rhs < 0);
5560 if (!
_attr)
return false;
5562 return impl::set_value_integer<unsigned long long>(
_attr->
value,
_attr->
header, impl::xml_memory_page_value_allocated_mask, rhs,
false);
5567 PUGI__FN bool operator&&(
const xml_attribute& lhs,
bool rhs)
5569 return (
bool)lhs && rhs;
5572 PUGI__FN bool operator||(
const xml_attribute& lhs,
bool rhs)
5574 return (
bool)lhs || rhs;
5690 if (i->name && impl::strequal(name_, i->name))
return xml_node(i);
5700 if (i->name && impl::strequal(name_, i->name))
5711 if (i->name && impl::strequal(name_, i->name))
return xml_node(i);
5726 if (i->name && impl::strequal(name_, i->name))
return xml_node(i);
5736 assert(!hint || (
_root && impl::is_attribute_of(hint,
_root)));
5742 if (i->name && impl::strequal(name_, i->name))
5753 if (j->name && impl::strequal(name_, j->name))
5796 if (impl::is_text_node(i) && i->value)
5834 return impl::strcpy_insitu(
_root->
name,
_root->
header, impl::xml_memory_page_name_allocated_mask, rhs, impl::strlength(rhs));
5844 return impl::strcpy_insitu(
_root->
value,
_root->
header, impl::xml_memory_page_value_allocated_mask, rhs, impl::strlength(rhs));
5851 impl::xml_allocator& alloc = impl::get_allocator(
_root);
5868 impl::xml_allocator& alloc = impl::get_allocator(
_root);
5886 impl::xml_allocator& alloc = impl::get_allocator(
_root);
5904 impl::xml_allocator& alloc = impl::get_allocator(
_root);
5922 impl::xml_allocator& alloc = impl::get_allocator(
_root);
5929 impl::node_copy_attribute(a.
_attr, proto.
_attr);
5939 impl::xml_allocator& alloc = impl::get_allocator(
_root);
5946 impl::node_copy_attribute(a.
_attr, proto.
_attr);
5957 impl::xml_allocator& alloc = impl::get_allocator(
_root);
5964 impl::node_copy_attribute(a.
_attr, proto.
_attr);
5975 impl::xml_allocator& alloc = impl::get_allocator(
_root);
5982 impl::node_copy_attribute(a.
_attr, proto.
_attr);
5989 if (!impl::allow_insert_child(
type(), type_))
return xml_node();
5991 impl::xml_allocator& alloc = impl::get_allocator(
_root);
5992 if (!alloc.reserve())
return xml_node();
5994 xml_node n(impl::allocate_node(alloc, type_));
6006 if (!impl::allow_insert_child(
type(), type_))
return xml_node();
6008 impl::xml_allocator& alloc = impl::get_allocator(
_root);
6009 if (!alloc.reserve())
return xml_node();
6011 xml_node n(impl::allocate_node(alloc, type_));
6023 if (!impl::allow_insert_child(
type(), type_))
return xml_node();
6026 impl::xml_allocator& alloc = impl::get_allocator(
_root);
6027 if (!alloc.reserve())
return xml_node();
6029 xml_node n(impl::allocate_node(alloc, type_));
6032 impl::insert_node_before(n.
_root, node.
_root);
6041 if (!impl::allow_insert_child(
type(), type_))
return xml_node();
6044 impl::xml_allocator& alloc = impl::get_allocator(
_root);
6045 if (!alloc.reserve())
return xml_node();
6047 xml_node n(impl::allocate_node(alloc, type_));
6050 impl::insert_node_after(n.
_root, node.
_root);
6096 if (!impl::allow_insert_child(
type(), type_))
return xml_node();
6098 impl::xml_allocator& alloc = impl::get_allocator(
_root);
6099 if (!alloc.reserve())
return xml_node();
6101 xml_node n(impl::allocate_node(alloc, type_));
6113 if (!impl::allow_insert_child(
type(), type_))
return xml_node();
6115 impl::xml_allocator& alloc = impl::get_allocator(
_root);
6116 if (!alloc.reserve())
return xml_node();
6118 xml_node n(impl::allocate_node(alloc, type_));
6130 if (!impl::allow_insert_child(
type(), type_))
return xml_node();
6133 impl::xml_allocator& alloc = impl::get_allocator(
_root);
6134 if (!alloc.reserve())
return xml_node();
6136 xml_node n(impl::allocate_node(alloc, type_));
6139 impl::insert_node_after(n.
_root, node.
_root);
6148 if (!impl::allow_insert_child(
type(), type_))
return xml_node();
6151 impl::xml_allocator& alloc = impl::get_allocator(
_root);
6152 if (!alloc.reserve())
return xml_node();
6154 xml_node n(impl::allocate_node(alloc, type_));
6157 impl::insert_node_before(n.
_root, node.
_root);
6165 if (!impl::allow_move(*
this, moved))
return xml_node();
6167 impl::xml_allocator& alloc = impl::get_allocator(
_root);
6168 if (!alloc.reserve())
return xml_node();
6171 impl::get_document(
_root).header |= impl::xml_memory_page_contents_shared_mask;
6173 impl::remove_node(moved.
_root);
6181 if (!impl::allow_move(*
this, moved))
return xml_node();
6183 impl::xml_allocator& alloc = impl::get_allocator(
_root);
6184 if (!alloc.reserve())
return xml_node();
6187 impl::get_document(
_root).header |= impl::xml_memory_page_contents_shared_mask;
6189 impl::remove_node(moved.
_root);
6197 if (!impl::allow_move(*
this, moved))
return xml_node();
6201 impl::xml_allocator& alloc = impl::get_allocator(
_root);
6202 if (!alloc.reserve())
return xml_node();
6205 impl::get_document(
_root).header |= impl::xml_memory_page_contents_shared_mask;
6207 impl::remove_node(moved.
_root);
6208 impl::insert_node_after(moved.
_root, node.
_root);
6215 if (!impl::allow_move(*
this, moved))
return xml_node();
6219 impl::xml_allocator& alloc = impl::get_allocator(
_root);
6220 if (!alloc.reserve())
return xml_node();
6223 impl::get_document(
_root).header |= impl::xml_memory_page_contents_shared_mask;
6225 impl::remove_node(moved.
_root);
6226 impl::insert_node_before(moved.
_root, node.
_root);
6239 if (!impl::is_attribute_of(a.
_attr,
_root))
return false;
6241 impl::xml_allocator& alloc = impl::get_allocator(
_root);
6242 if (!alloc.reserve())
return false;
6245 impl::destroy_attribute(a.
_attr, alloc);
6259 impl::xml_allocator& alloc = impl::get_allocator(
_root);
6260 if (!alloc.reserve())
return false;
6262 impl::remove_node(n.
_root);
6263 impl::destroy_node(n.
_root, alloc);
6274 impl::xml_document_struct* doc = &impl::get_document(
_root);
6277 doc->header |= impl::xml_memory_page_contents_shared_mask;
6280 impl::xml_memory_page* page = 0;
6281 impl::xml_extra_buffer* extra =
static_cast<impl::xml_extra_buffer*
>(doc->allocate_memory(
sizeof(impl::xml_extra_buffer) +
sizeof(
void*), page));
6286 #ifdef PUGIXML_COMPACT
6289 extra =
reinterpret_cast<impl::xml_extra_buffer*
>((
reinterpret_cast<uintptr_t
>(extra) + (
sizeof(
void*) - 1)) & ~(
sizeof(
void*) - 1));
6294 extra->next = doc->extra_buffers;
6295 doc->extra_buffers = extra;
6298 impl::name_null_sentry sentry(
_root);
6300 return impl::load_buffer_impl(doc,
_root,
const_cast<void*
>(contents), size, options, encoding,
false,
false, &extra->buffer);
6308 if (i->name && impl::strequal(name_, i->name))
6311 if (a->name && impl::strequal(attr_name, a->name) && impl::strequal(attr_value, a->value ? a->value + 0 :
PUGIXML_TEXT(
"")))
6324 if (a->name && impl::strequal(attr_name, a->name) && impl::strequal(attr_value, a->value ? a->value + 0 :
PUGIXML_TEXT(
"")))
6330#ifndef PUGIXML_NO_STL
6339 offset += (i !=
_root);
6340 offset += i->name ? impl::strlength(i->name) : 0;
6344 result.resize(offset);
6349 result[--offset] = delimiter;
6353 size_t length = impl::strlength(j->name);
6356 memcpy(&result[offset], j->name, length *
sizeof(
char_t));
6360 assert(offset == 0);
6370 if (!
_root || !path_[0])
return found;
6372 if (path_[0] == delimiter)
6375 found = found.
root();
6379 const char_t* path_segment = path_;
6381 while (*path_segment == delimiter) ++path_segment;
6383 const char_t* path_segment_end = path_segment;
6385 while (*path_segment_end && *path_segment_end != delimiter) ++path_segment_end;
6387 if (path_segment == path_segment_end)
return found;
6389 const char_t* next_segment = path_segment_end;
6391 while (*next_segment == delimiter) ++next_segment;
6393 if (*path_segment ==
'.' && path_segment + 1 == path_segment_end)
6395 else if (*path_segment ==
'.' && *(path_segment+1) ==
'.' && path_segment + 2 == path_segment_end)
6401 if (j->name && impl::strequalrange(j->name, path_segment,
static_cast<size_t>(path_segment_end - path_segment)))
6405 if (subsearch)
return subsearch;
6418 if (!walker.
begin(arg_begin))
return false;
6429 if (!walker.
for_each(arg_for_each))
6451 while (cur && cur !=
_root);
6454 assert(walker.
_depth == -1);
6457 return walker.
end(arg_end);
6474 impl::xml_buffered_writer buffered_writer(writer, encoding);
6476 impl::node_output(buffered_writer,
_root, indent, flags, depth);
6478 buffered_writer.flush();
6481#ifndef PUGIXML_NO_STL
6486 print(writer, indent, flags, encoding, depth);
6489 PUGI__FN void xml_node::print(std::basic_ostream<
wchar_t, std::char_traits<wchar_t> >& stream,
const char_t* indent,
unsigned int flags,
unsigned int depth)
const
6499 if (!
_root)
return -1;
6501 impl::xml_document_struct& doc = impl::get_document(
_root);
6504 if (!doc.buffer || doc.extra_buffers)
return -1;
6523 assert(
false &&
"Invalid node type");
6531 return (
bool)lhs && rhs;
6534 PUGI__FN bool operator||(
const xml_node& lhs,
bool rhs)
6536 return (
bool)lhs || rhs;
6553 if (impl::is_text_node(node))
6587 return _data() == 0;
6608 return (d && d->
value) ? impl::get_value_int(d->
value) : def;
6615 return (d && d->
value) ? impl::get_value_uint(d->
value) : def;
6622 return (d && d->
value) ? impl::get_value_double(d->
value) : def;
6629 return (d && d->
value) ? impl::get_value_float(d->
value) : def;
6636 return (d && d->
value) ? impl::get_value_bool(d->
value) : def;
6639#ifdef PUGIXML_HAS_LONG_LONG
6640 PUGI__FN long long xml_text::as_llong(
long long def)
const
6644 return (d && d->
value) ? impl::get_value_llong(d->
value) : def;
6647 PUGI__FN unsigned long long xml_text::as_ullong(
unsigned long long def)
const
6651 return (d && d->value) ? impl::get_value_ullong(d->value) : def;
6659 return dn ? impl::strcpy_insitu(dn->
value, dn->
header, impl::xml_memory_page_value_allocated_mask, rhs, impl::strlength(rhs)) :
false;
6666 return dn ? impl::set_value_integer<unsigned int>(dn->
value, dn->
header, impl::xml_memory_page_value_allocated_mask, rhs, rhs < 0) :
false;
6673 return dn ? impl::set_value_integer<unsigned int>(dn->
value, dn->
header, impl::xml_memory_page_value_allocated_mask, rhs,
false) :
false;
6680 return dn ? impl::set_value_integer<unsigned long>(dn->
value, dn->
header, impl::xml_memory_page_value_allocated_mask, rhs, rhs < 0) :
false;
6687 return dn ? impl::set_value_integer<unsigned long>(dn->
value, dn->
header, impl::xml_memory_page_value_allocated_mask, rhs,
false) :
false;
6694 return dn ? impl::set_value_convert(dn->
value, dn->
header, impl::xml_memory_page_value_allocated_mask, rhs) :
false;
6701 return dn ? impl::set_value_convert(dn->
value, dn->
header, impl::xml_memory_page_value_allocated_mask, rhs) :
false;
6708 return dn ? impl::set_value_bool(dn->
value, dn->
header, impl::xml_memory_page_value_allocated_mask, rhs) :
false;
6711#ifdef PUGIXML_HAS_LONG_LONG
6716 return dn ? impl::set_value_integer<unsigned long long>(dn->
value, dn->
header, impl::xml_memory_page_value_allocated_mask, rhs, rhs < 0) : false;
6723 return dn ? impl::set_value_integer<unsigned long long>(dn->value, dn->header, impl::xml_memory_page_value_allocated_mask, rhs,
false) : false;
6775#ifdef PUGIXML_HAS_LONG_LONG
6797 return (
bool)lhs && rhs;
6800 PUGI__FN bool operator||(
const xml_text& lhs,
bool rhs)
6802 return (
bool)lhs || rhs;
7020 case status_bad_pi:
return "Error parsing document declaration/processing instruction";
7034 default:
return "Unknown error";
7048#ifdef PUGIXML_HAS_MOVE
7057 if (
this == &rhs)
return *
this;
7085 #ifdef PUGIXML_COMPACT
7087 const size_t page_offset =
sizeof(
void*);
7089 const size_t page_offset = 0;
7096 impl::xml_memory_page* page = impl::xml_memory_page::construct(
_memory);
7099 page->busy_size = impl::xml_memory_page_size;
7102 #ifdef PUGIXML_COMPACT
7104 page->compact_page_marker =
reinterpret_cast<uint32_t*
>(
static_cast<void*
>(
reinterpret_cast<char*
>(page) +
sizeof(impl::xml_memory_page)));
7105 *page->compact_page_marker =
sizeof(impl::xml_memory_page);
7109 _root =
new (
reinterpret_cast<char*
>(page) +
sizeof(impl::xml_memory_page) + page_offset) impl::xml_document_struct(page);
7113 page->allocator =
static_cast<impl::xml_document_struct*
>(
_root);
7116 #ifdef PUGIXML_COMPACT
7117 page->allocator->_hash = &
static_cast<impl::xml_document_struct*
>(
_root)->hash;
7121 assert(
reinterpret_cast<char*
>(
_root) +
sizeof(impl::xml_document_struct) <=
_memory +
sizeof(
_memory));
7131 impl::xml_memory::deallocate(
_buffer);
7136 for (impl::xml_extra_buffer* extra =
static_cast<impl::xml_document_struct*
>(
_root)->extra_buffers; extra; extra = extra->next)
7138 if (extra->buffer) impl::xml_memory::deallocate(extra->buffer);
7143 assert(root_page && !root_page->prev);
7144 assert(
reinterpret_cast<char*
>(root_page) >=
_memory &&
reinterpret_cast<char*
>(root_page) <
_memory +
sizeof(
_memory));
7146 for (impl::xml_memory_page* page = root_page->
next; page; )
7148 impl::xml_memory_page* next = page->
next;
7150 impl::xml_allocator::deallocate_page(page);
7155 #ifdef PUGIXML_COMPACT
7157 static_cast<impl::xml_document_struct*
>(
_root)->hash.clear();
7163#ifdef PUGIXML_HAS_MOVE
7166 impl::xml_document_struct* doc =
static_cast<impl::xml_document_struct*
>(_root);
7167 impl::xml_document_struct* other =
static_cast<impl::xml_document_struct*
>(rhs._root);
7172 #ifdef PUGIXML_COMPACT
7175 if (other_first_child)
7177 size_t other_children = 0;
7185 if (!other->_hash->reserve(other_children + 1))
7187 #ifdef PUGIXML_NO_EXCEPTIONS
7190 throw std::bad_alloc();
7197 doc->_root = other->_root;
7198 doc->_busy_size = other->_busy_size;
7201 doc->buffer = other->buffer;
7202 doc->extra_buffers = other->extra_buffers;
7203 _buffer = rhs._buffer;
7205 #ifdef PUGIXML_COMPACT
7207 doc->hash = other->hash;
7208 doc->_hash = &doc->hash;
7216 assert(doc_page && !doc_page->prev && !doc_page->next);
7219 assert(other_page && !other_page->prev);
7222 if (impl::xml_memory_page* page = other_page->next)
7224 assert(page->
prev == other_page);
7226 page->
prev = doc_page;
7228 doc_page->
next = page;
7229 other_page->
next = 0;
7233 for (impl::xml_memory_page* page = doc_page->next; page; page = page->
next)
7239 #ifdef PUGIXML_COMPACT
7241 if (page->compact_shared_parent == other)
7242 page->compact_shared_parent = doc;
7247 assert(!doc->first_child);
7249 doc->first_child = other_first_child;
7251 for (
xml_node_struct* node = other_first_child; node; node = node->next_sibling)
7253 #ifdef PUGIXML_COMPACT
7255 assert(node->parent == other || node->parent == doc);
7259 assert(node->parent == other);
7265 new (other) impl::xml_document_struct(
PUGI__GETPAGE(other));
7270#ifndef PUGIXML_NO_STL
7275 return impl::load_stream_impl(
static_cast<impl::xml_document_struct*
>(
_root), stream, options, encoding, &
_buffer);
7289 #ifdef PUGIXML_WCHAR_MODE
7295 return load_buffer(contents, impl::strlength(contents) *
sizeof(
char_t), options, encoding);
7307 using impl::auto_deleter;
7310 return impl::load_file_impl(
static_cast<impl::xml_document_struct*
>(
_root), file.
data, options, encoding, &
_buffer);
7317 using impl::auto_deleter;
7320 return impl::load_file_impl(
static_cast<impl::xml_document_struct*
>(
_root), file.
data, options, encoding, &
_buffer);
7327 return impl::load_buffer_impl(
static_cast<impl::xml_document_struct*
>(
_root),
_root,
const_cast<void*
>(contents), size, options, encoding,
false,
false, &
_buffer);
7334 return impl::load_buffer_impl(
static_cast<impl::xml_document_struct*
>(
_root),
_root, contents, size, options, encoding,
true,
false, &
_buffer);
7341 return impl::load_buffer_impl(
static_cast<impl::xml_document_struct*
>(
_root),
_root, contents, size, options, encoding,
true,
true, &
_buffer);
7346 impl::xml_buffered_writer buffered_writer(writer, encoding);
7351 #ifdef PUGIXML_WCHAR_MODE
7352 unsigned int bom = 0xfeff;
7353 buffered_writer.write(
static_cast<wchar_t>(bom));
7355 buffered_writer.write(
'\xef',
'\xbb',
'\xbf');
7361 buffered_writer.write_string(
PUGIXML_TEXT(
"<?xml version=\"1.0\""));
7363 buffered_writer.write(
'?',
'>');
7364 if (!(flags &
format_raw)) buffered_writer.write(
'\n');
7367 impl::node_output(buffered_writer,
_root, indent, flags, 0);
7369 buffered_writer.flush();
7372#ifndef PUGIXML_NO_STL
7377 save(writer, indent, flags, encoding);
7390 using impl::auto_deleter;
7393 return impl::save_file_impl(*
this, file.
data, indent, flags, encoding);
7398 using impl::auto_deleter;
7401 return impl::save_file_impl(*
this, file.
data, indent, flags, encoding);
7415#ifndef PUGIXML_NO_STL
7420 return impl::as_utf8_impl(str, impl::strlength_wide(str));
7425 return impl::as_utf8_impl(str.c_str(), str.size());
7432 return impl::as_wide_impl(str, strlen(str));
7437 return impl::as_wide_impl(str.c_str(), str.size());
7443 impl::xml_memory::allocate = allocate;
7444 impl::xml_memory::deallocate = deallocate;
7449 return impl::xml_memory::allocate;
7454 return impl::xml_memory::deallocate;
7458#if !defined(PUGIXML_NO_STL) && (defined(_MSC_VER) || defined(__ICC))
7464 return std::bidirectional_iterator_tag();
7469 return std::bidirectional_iterator_tag();
7474 return std::bidirectional_iterator_tag();
7479#if !defined(PUGIXML_NO_STL) && defined(__SUNPRO_CC)
7485 return std::bidirectional_iterator_tag();
7490 return std::bidirectional_iterator_tag();
7495 return std::bidirectional_iterator_tag();
7500#ifndef PUGIXML_NO_XPATH
7505 template <
typename T>
bool operator()(
const T& lhs,
const T& rhs)
const
7513 template <
typename T>
bool operator()(
const T& lhs,
const T& rhs)
const
7521 template <
typename T>
bool operator()(
const T& lhs,
const T& rhs)
const
7529 template <
typename T>
bool operator()(
const T& lhs,
const T& rhs)
const
7535 template <
typename T>
void swap(T& lhs, T& rhs)
7546 for (I it =
begin + 1; it !=
end; ++it)
7547 if (pred(*it, *result))
7571 if (*
begin != *write)
7572 *++write = *
begin++;
7586 for (T* it =
begin + 1; it !=
end; ++it)
7592 while (hole >
begin && pred(val, *(hole - 1)))
7594 *hole = *(hole - 1);
7603 template <
typename I,
typename Pred> I
median3(I first, I middle, I last,
const Pred& pred)
7605 if (pred(*middle, *first))
swap(middle, first);
7606 if (pred(*last, *middle))
swap(last, middle);
7607 if (pred(*middle, *first))
swap(middle, first);
7612 template <
typename T,
typename Pred>
void partition3(T*
begin, T*
end, T pivot,
const Pred& pred, T** out_eqbeg, T** out_eqend)
7621 if (pred(*lt, pivot))
7623 else if (*lt == pivot)
7632 for (T* it =
begin; it != eq; ++it)
7633 swap(*it, *--eqbeg);
7639 template <
typename I,
typename Pred>
void sort(I
begin, I
end,
const Pred& pred)
7673 #ifdef PUGIXML_MEMORY_XPATH_PAGE_SIZE
7674 PUGIXML_MEMORY_XPATH_PAGE_SIZE
7718 size_t block_capacity_base =
sizeof(
_root->
data);
7719 size_t block_capacity_req = size + block_capacity_base / 4;
7720 size_t block_capacity = (block_capacity_base > block_capacity_req) ? block_capacity_base : block_capacity_req;
7751 if (ptr &&
_root_size - old_size + new_size <= _root->capacity)
7759 if (!result)
return 0;
7765 assert(new_size >= old_size);
7766 memcpy(result, ptr, old_size);
7793 while (cur != state.
_root)
7879 char_t* result =
static_cast<char_t*
>(alloc->
allocate((
length + 1) *
sizeof(char_t)));
7880 if (!result)
return 0;
7882 memcpy(result,
string,
length *
sizeof(char_t));
7935 size_t target_length =
length();
7936 size_t source_length = o.
length();
7937 size_t result_length = target_length + source_length;
7940 char_t* result =
static_cast<char_t*
>(alloc->
reallocate(
_uses_heap ?
const_cast<char_t*
>(
_buffer) : 0, (target_length + 1) *
sizeof(char_t), (result_length + 1) *
sizeof(char_t)));
7941 if (!result)
return;
7947 memcpy(result + target_length, o.
_buffer, source_length *
sizeof(char_t));
7948 result[result_length] = 0;
7975 if (!data_)
return 0;
7982 return const_cast<char_t*
>(
_buffer);
8010 while (*pattern && *
string == *pattern)
8016 return *pattern == 0;
8021 #ifdef PUGIXML_WCHAR_MODE
8022 return wcschr(s, c);
8024 return strchr(s, c);
8030 #ifdef PUGIXML_WCHAR_MODE
8032 return (*p == 0) ? s : wcsstr(s, p);
8034 return strstr(s, p);
8041 return static_cast<unsigned int>(ch -
'A') < 26 ?
static_cast<char_t
>(ch |
' ') : ch;
8050 xml_node n = na.node();
8069 xml_node cur = n.first_child();
8071 while (cur && cur != n)
8073 if (cur.type() == node_pcdata || cur.type() == node_cdata)
8076 if (cur.first_child())
8077 cur = cur.first_child();
8078 else if (cur.next_sibling())
8079 cur = cur.next_sibling();
8082 while (!cur.next_sibling() && cur != n)
8085 if (cur != n) cur = cur.next_sibling();
8100 assert(ln->parent == rn->parent);
8103 if (!ln->parent)
return ln < rn;
8111 if (ls == rn)
return true;
8112 if (rs == ln)
return false;
8114 ls = ls->next_sibling;
8115 rs = rs->next_sibling;
8128 while (lp && rp && lp->parent != rp->parent)
8138 bool left_higher = !lp;
8153 if (ln == rn)
return left_higher;
8156 while (ln->parent != rn->parent)
8167 while (node && node != parent) node = node->parent;
8169 return parent && node == parent;
8180 if (node->name && (node->header & impl::xml_memory_page_name_allocated_or_shared_mask) == 0)
return node->name;
8181 if (node->value && (node->header & impl::xml_memory_page_value_allocated_or_shared_mask) == 0)
return node->value;
8187 xml_attribute_struct* attr = xnode.attribute().internal_object();
8193 if ((attr->header & impl::xml_memory_page_name_allocated_or_shared_mask) == 0)
return attr->name;
8194 if ((attr->header & impl::xml_memory_page_value_allocated_or_shared_mask) == 0)
return attr->value;
8205 bool operator()(
const xpath_node& lhs,
const xpath_node& rhs)
const
8211 if (lo && ro)
return lo < ro;
8214 xml_node ln = lhs.node(), rn = rhs.node();
8217 if (lhs.attribute() && rhs.attribute())
8220 if (lhs.parent() == rhs.parent())
8223 for (xml_attribute a = lhs.attribute(); a; a = a.next_attribute())
8224 if (a == rhs.attribute())
8234 else if (lhs.attribute())
8237 if (lhs.parent() == rhs.node())
return false;
8241 else if (rhs.attribute())
8244 if (rhs.parent() == lhs.node())
return true;
8249 if (ln == rn)
return false;
8251 if (!ln || !rn)
return ln < rn;
8253 return node_is_before(ln.internal_object(), rn.internal_object());
8259 bool operator()(
const xpath_node& lhs,
const xpath_node& rhs)
const
8261 if (lhs.attribute())
return rhs.attribute() ? lhs.attribute() < rhs.attribute() :
true;
8262 else return rhs.attribute() ? false : lhs.node() < rhs.node();
8268 #if defined(__STDC_IEC_559__) || ((FLT_RADIX - 0 == 2) && (FLT_MAX_EXP - 0 == 128) && (FLT_MANT_DIG - 0 == 24))
8270 typedef uint32_t UI;
8271 union {
float f; UI i; } u;
8276 const volatile double zero = 0.0;
8283 #if defined(PUGI__MSVC_CRT_VERSION) || defined(__BORLANDC__)
8284 return !!_isnan(value);
8285 #elif defined(fpclassify) && defined(FP_NAN)
8286 return fpclassify(value) == FP_NAN;
8289 const volatile double v = value;
8296 #if defined(PUGI__MSVC_CRT_VERSION) || defined(__BORLANDC__)
8297 if (_finite(value))
return (value == 0) ?
PUGIXML_TEXT(
"0") : 0;
8300 #elif defined(fpclassify) && defined(FP_NAN) && defined(FP_INFINITE) && defined(FP_ZERO)
8301 switch (fpclassify(value))
8317 const volatile double v = value;
8328 return (value != 0 && !
is_nan(value));
8339#if defined(PUGI__MSVC_CRT_VERSION) && PUGI__MSVC_CRT_VERSION >= 1400 && !defined(_WIN32_WCE)
8344 _ecvt_s(buffer,
sizeof(buffer), value, DBL_DIG + 1, &exponent, &sign);
8350 *out_mantissa = buffer;
8351 *out_exponent = exponent;
8360 char* exponent_string = strchr(buffer,
'e');
8361 assert(exponent_string);
8363 int exponent = atoi(exponent_string + 1);
8366 char* mantissa = buffer[0] ==
'-' ? buffer + 1 : buffer;
8367 assert(mantissa[0] !=
'0' && mantissa[1] ==
'.');
8370 mantissa[1] = mantissa[0];
8378 *out_mantissa = mantissa;
8379 *out_exponent = exponent;
8390 char mantissa_buffer[32];
8397 size_t result_size = strlen(mantissa_buffer) + (exponent > 0 ? exponent : -exponent) + 4;
8398 char_t* result =
static_cast<char_t*
>(alloc->
allocate(
sizeof(char_t) * result_size));
8405 if (value < 0) *s++ =
'-';
8414 while (exponent > 0)
8416 assert(*mantissa == 0 ||
static_cast<unsigned int>(*mantissa -
'0') <= 9);
8417 *s++ = *mantissa ? *mantissa++ :
'0';
8429 while (exponent < 0)
8438 assert(
static_cast<unsigned int>(*mantissa -
'0') <= 9);
8444 assert(s < result + result_size);
8456 if (*
string ==
'-') ++string;
8458 if (!*
string)
return false;
8477 return *
string == 0;
8486 #ifdef PUGIXML_WCHAR_MODE
8487 return wcstod(
string, 0);
8489 return strtod(
string, 0);
8495 size_t length =
static_cast<size_t>(
end -
begin);
8496 char_t* scratch = buffer;
8498 if (length >=
sizeof(buffer) /
sizeof(buffer[0]))
8502 if (!scratch)
return false;
8506 memcpy(scratch,
begin, length *
sizeof(char_t));
8507 scratch[length] = 0;
8519 return floor(value + 0.5);
8526 return (value >= -0.5 && value <= 0) ? ceil(value) : floor(value + 0.5);
8531 return node.attribute() ? node.attribute().name() : node.node().name();
8539 return p ? p + 1 : name;
8549 const char_t* pos =
find_char(name,
':');
8557 const char_t* name = a.name();
8573 xml_attribute a = p.find_attribute(pred);
8575 if (a)
return a.value();
8590 xml_node p = parent;
8594 xml_attribute a = p.find_attribute(pred);
8596 if (a)
return a.value();
8611 char_t* write = buffer;
8613 for (char_t* it = buffer; *it; )
8623 if (write != buffer) *write++ =
' ';
8639 char_t* write = buffer;
8645 const char_t* pos =
find_char(from, ch);
8649 else if (
static_cast<size_t>(pos - from) < to_length)
8650 *write++ = to[pos - from];
8661 unsigned char table[128] = {0};
8665 unsigned int fc =
static_cast<unsigned int>(*from);
8666 unsigned int tc =
static_cast<unsigned int>(*to);
8668 if (fc >= 128 || tc >= 128)
8673 table[fc] =
static_cast<unsigned char>(tc ? tc : 128);
8679 for (
int i = 0; i < 128; ++i)
8681 table[i] =
static_cast<unsigned char>(i);
8683 void* result = alloc->
allocate(
sizeof(table));
8684 if (!result)
return 0;
8686 memcpy(result, table,
sizeof(table));
8688 return static_cast<unsigned char*
>(result);
8693 char_t* write = buffer;
8697 char_t ch = *buffer++;
8698 unsigned int index =
static_cast<unsigned int>(ch);
8702 unsigned char code = table[index];
8706 *write =
static_cast<char_t
>(code);
8707 write += 1 - (code >> 7);
8776 unsigned int result = 0;
8780 result +=
static_cast<unsigned int>(*str++);
8781 result += result << 10;
8782 result ^= result >> 6;
8785 result += result << 3;
8786 result ^= result >> 11;
8787 result += result << 15;
8795 if (length == 0)
return 0;
8799 if (!memory)
return 0;
8801 T* result =
new (memory) T();
8803 memcpy(result->name, name, (length + 1) *
sizeof(char_t));
8812 case xpath_type_node_set:
8813 return new_xpath_variable<xpath_variable_node_set>(name);
8815 case xpath_type_number:
8816 return new_xpath_variable<xpath_variable_number>(name);
8818 case xpath_type_string:
8819 return new_xpath_variable<xpath_variable_string>(name);
8821 case xpath_type_boolean:
8822 return new_xpath_variable<xpath_variable_boolean>(name);
8839 case xpath_type_node_set:
8843 case xpath_type_number:
8847 case xpath_type_string:
8851 case xpath_type_boolean:
8856 assert(
false &&
"Invalid variable type");
8862 switch (rhs->type())
8864 case xpath_type_node_set:
8867 case xpath_type_number:
8870 case xpath_type_string:
8873 case xpath_type_boolean:
8877 assert(
false &&
"Invalid variable type");
8884 size_t length =
static_cast<size_t>(
end -
begin);
8885 char_t* scratch = buffer;
8887 if (length >=
sizeof(buffer) /
sizeof(buffer[0]))
8891 if (!scratch)
return false;
8895 memcpy(scratch,
begin, length *
sizeof(char_t));
8896 scratch[length] = 0;
8898 *out_result = set->get(scratch);
8912 return xpath_node_set::type_sorted;
8918 for (
const xpath_node* it =
begin + 1; it + 1 <
end; ++it)
8919 if (cmp(it[0], it[1]) != first)
8920 return xpath_node_set::type_unsorted;
8922 return first ? xpath_node_set::type_sorted : xpath_node_set::type_sorted_reverse;
8927 xpath_node_set::type_t order = rev ? xpath_node_set::type_sorted_reverse : xpath_node_set::type_sorted;
8929 if (type == xpath_node_set::type_unsorted)
8933 if (sorted == xpath_node_set::type_unsorted)
8937 type = xpath_node_set::type_sorted;
8950 if (
begin ==
end)
return xpath_node();
8954 case xpath_node_set::type_sorted:
8957 case xpath_node_set::type_sorted_reverse:
8960 case xpath_node_set::type_unsorted:
8964 assert(
false &&
"Invalid node set type");
8965 return xpath_node();
9019 if (begin_ == end_)
return;
9021 size_t size_ =
static_cast<size_t>(
_end -
_begin);
9022 size_t capacity =
static_cast<size_t>(
_eos -
_begin);
9023 size_t count =
static_cast<size_t>(end_ - begin_);
9025 if (size_ + count > capacity)
9028 xpath_node* data =
static_cast<xpath_node*
>(alloc->
reallocate(
_begin, capacity *
sizeof(xpath_node), (size_ + count) *
sizeof(xpath_node)));
9033 _end = data + size_;
9034 _eos = data + size_ + count;
9037 memcpy(
_end, begin_, count *
sizeof(xpath_node));
9055 if (
_type == xpath_node_set::type_unsorted)
9061 xpath_node_set::type_t
type()
const
9074 size_t capacity =
static_cast<size_t>(
_eos -
_begin);
9077 size_t new_capacity = capacity + capacity / 2 + 1;
9080 xpath_node* data =
static_cast<xpath_node*
>(alloc->
reallocate(
_begin, capacity *
sizeof(xpath_node), new_capacity *
sizeof(xpath_node)));
9085 _end = data + capacity;
9086 _eos = data + new_capacity;
9146 size_t length =
static_cast<size_t>(
end -
begin);
9173 const char_t* cur =
_cur;
9187 if (*(cur+1) ==
'=')
9200 if (*(cur+1) ==
'=')
9213 if (*(cur+1) ==
'=')
9312 if (*(cur+1) ==
'/')
9325 if (*(cur+1) ==
'.')
9358 char_t terminator = *cur;
9363 while (*cur && *cur != terminator) cur++;
9378 if (*(cur+1) ==
':')
9614 if (lt != xpath_type_node_set && rt != xpath_type_node_set)
9616 if (lt == xpath_type_boolean || rt == xpath_type_boolean)
9618 else if (lt == xpath_type_number || rt == xpath_type_number)
9620 else if (lt == xpath_type_string || rt == xpath_type_string)
9627 return comp(ls, rs);
9630 else if (lt == xpath_type_node_set && rt == xpath_type_node_set)
9637 for (
const xpath_node* li = ls.
begin(); li != ls.
end(); ++li)
9638 for (
const xpath_node* ri = rs.
begin(); ri != rs.
end(); ++ri)
9650 if (lt == xpath_type_node_set)
9656 if (lt == xpath_type_boolean)
9658 else if (lt == xpath_type_number)
9665 for (
const xpath_node* ri = rs.
begin(); ri != rs.
end(); ++ri)
9675 else if (lt == xpath_type_string)
9682 for (
const xpath_node* ri = rs.
begin(); ri != rs.
end(); ++ri)
9694 assert(
false &&
"Wrong types");
9707 if (lt != xpath_type_node_set && rt != xpath_type_node_set)
9709 else if (lt == xpath_type_node_set && rt == xpath_type_node_set)
9716 for (
const xpath_node* li = ls.
begin(); li != ls.
end(); ++li)
9722 for (
const xpath_node* ri = rs.
begin(); ri != rs.
end(); ++ri)
9733 else if (lt != xpath_type_node_set && rt == xpath_type_node_set)
9740 for (
const xpath_node* ri = rs.
begin(); ri != rs.
end(); ++ri)
9750 else if (lt == xpath_type_node_set && rt != xpath_type_node_set)
9757 for (
const xpath_node* li = ls.
begin(); li != ls.
end(); ++li)
9769 assert(
false &&
"Wrong types");
9776 assert(ns.
size() >= first);
9777 assert(expr->
rettype() != xpath_type_number);
9780 size_t size = ns.
size() - first;
9782 xpath_node* last = ns.
begin() + first;
9785 for (xpath_node* it = last; it != ns.
end(); ++it, ++i)
9802 assert(ns.
size() >= first);
9803 assert(expr->
rettype() == xpath_type_number);
9806 size_t size = ns.
size() - first;
9808 xpath_node* last = ns.
begin() + first;
9811 for (xpath_node* it = last; it != ns.
end(); ++it, ++i)
9828 assert(ns.
size() >= first);
9829 assert(expr->
rettype() == xpath_type_number);
9831 size_t size = ns.
size() - first;
9833 xpath_node* last = ns.
begin() + first;
9839 if (er >= 1.0 && er <= size)
9841 size_t eri =
static_cast<size_t>(er);
9845 xpath_node r = last[eri - 1];
9856 if (ns.
size() == first)
return;
9870 if (ns.
size() == first)
return;
9875 pred->apply_predicate(ns, first, stack, !pred->_next && last_once);
9882 const char_t* name = a->name ? a->name + 0 :
PUGIXML_TEXT(
"");
9889 ns.
push_back(xpath_node(xml_attribute(a), xml_node(parent)), alloc);
9898 ns.
push_back(xpath_node(xml_attribute(a), xml_node(parent)), alloc);
9906 ns.
push_back(xpath_node(xml_attribute(a), xml_node(parent)), alloc);
9927 if (type == node_element && n->name &&
strequal(n->name,
_data.nodetest))
9939 if (type == node_comment)
9947 if (type == node_pcdata || type == node_cdata)
9955 if (type == node_pi)
9963 if (type == node_pi && n->name &&
strequal(n->name,
_data.nodetest))
9971 if (type == node_element)
9979 if (type == node_element && n->name &&
starts_with(n->name,
_data.nodetest))
9987 assert(
false &&
"Unknown axis");
9995 const axis_t axis = T::axis;
10001 for (xml_attribute_struct* a = n->first_attribute; a; a = a->next_attribute)
10031 if (cur->first_child)
10032 cur = cur->first_child;
10035 while (!cur->next_sibling)
10039 if (cur == n)
return;
10042 cur = cur->next_sibling;
10060 for (
xml_node_struct* c = n->prev_sibling_c; c->next_sibling; c = c->prev_sibling_c)
10072 while (!cur->next_sibling)
10079 cur = cur->next_sibling;
10086 if (cur->first_child)
10087 cur = cur->first_child;
10090 while (!cur->next_sibling)
10097 cur = cur->next_sibling;
10109 while (!cur->prev_sibling_c->next_sibling)
10116 cur = cur->prev_sibling_c;
10120 if (cur->first_child)
10121 cur = cur->first_child->prev_sibling_c;
10128 while (!cur->prev_sibling_c->next_sibling)
10139 cur = cur->prev_sibling_c;
10182 assert(
false &&
"Unimplemented axis");
10188 const axis_t axis = T::axis;
10227 if (cur->first_child)
10228 cur = cur->first_child;
10231 while (!cur->next_sibling)
10238 cur = cur->next_sibling;
10263 assert(
false &&
"Unimplemented axis");
10269 const axis_t axis = T::axis;
10273 step_fill(ns, xn.node().internal_object(), alloc, once, v);
10274 else if (axis_has_attributes && xn.attribute() && xn.parent())
10275 step_fill(ns, xn.attribute().internal_object(), xn.parent().internal_object(), alloc, once, v);
10280 const axis_t axis = T::axis;
10282 const xpath_node_set::type_t axis_type = axis_reverse ? xpath_node_set::type_sorted_reverse : xpath_node_set::type_sorted;
10299 for (
const xpath_node* it = s.
begin(); it != s.
end(); ++it)
10301 size_t size = ns.
size();
10304 if (axis !=
axis_self && size != 0) ns.
set_type(xpath_node_set::type_unsorted);
10329 _data.string = value;
10336 _data.number = value;
10343 _data.variable = value;
10355 _data.nodetest = contents;
10436 if (c.
n.attribute())
return false;
10442 for (xml_node n = c.
n.node(); n; n = n.parent())
10444 xml_attribute a = n.attribute(
PUGIXML_TEXT(
"xml:lang"));
10448 const char_t* value = a.value();
10451 for (
const char_t* lit = lang.
c_str(); *lit; ++lit)
10457 return *value == 0 || *value ==
'-';
10477 if (
_rettype == xpath_type_boolean)
10478 return _data.variable->get_boolean();
10486 case xpath_type_number:
10489 case xpath_type_string:
10496 case xpath_type_node_set:
10504 assert(
false &&
"Wrong expression for return type boolean");
10534 return _data.number;
10537 return static_cast<double>(c.
size);
10540 return static_cast<double>(c.
position);
10581 for (
const xpath_node* it = ns.
begin(); it != ns.
end(); ++it)
10595 return r == r ? floor(r) : r;
10602 return r == r ? ceil(r) : r;
10612 if (
_rettype == xpath_type_number)
10613 return _data.variable->get_number();
10621 case xpath_type_boolean:
10624 case xpath_type_string:
10631 case xpath_type_node_set:
10639 assert(
false &&
"Wrong expression for return type number");
10668 assert(pos == count);
10672 for (
size_t i = 0; i < count; ++i) length += buffer[i].length();
10675 char_t* result =
static_cast<char_t*
>(stack.
result->
allocate((length + 1) *
sizeof(char_t)));
10678 char_t* ri = result;
10680 for (
size_t j = 0; j < count; ++j)
10681 for (
const char_t* bi = buffer[j].c_str(); *bi; ++bi)
10698 xpath_node na = c.
n;
10708 xpath_node na = ns.
first();
10715 xpath_node na = c.
n;
10725 xpath_node na = ns.
first();
10732 xpath_node na = c.
n;
10742 xpath_node na = ns.
first();
10782 const char_t* rbegin = pos + p.
length();
10795 size_t s_length = s.
length();
10800 else if (first >= s_length + 1)
return xpath_string();
10802 size_t pos = first < 1 ? 1 : static_cast<size_t>(first);
10803 assert(1 <= pos && pos <= s_length + 1);
10805 const char_t* rbegin = s.
c_str() + (pos - 1);
10818 size_t s_length = s.
length();
10824 else if (first >= s_length + 1)
return xpath_string();
10828 size_t pos = first < 1 ? 1 : static_cast<size_t>(first);
10829 size_t end = last >= s_length + 1 ? s_length + 1 :
static_cast<size_t>(last);
10831 assert(1 <= pos && pos <=
end &&
end <= s_length + 1);
10832 const char_t* rbegin = s.
c_str() + (pos - 1);
10833 const char_t* rend = s.
c_str() + (
end - 1);
10896 if (
_rettype == xpath_type_string)
10905 case xpath_type_boolean:
10908 case xpath_type_number:
10911 case xpath_type_node_set:
10922 assert(
false &&
"Wrong expression for return type string");
10943 rs.
set_type(xpath_node_set::type_unsorted);
11013 assert(
false &&
"Unknown axis");
11024 ns.
set_type(xpath_node_set::type_sorted);
11036 if (
_rettype == xpath_type_node_set)
11038 const xpath_node_set& s =
_data.variable->get_node_set();
11051 assert(
false &&
"Wrong expression for return type node set");
11155 if (!n->is_posinv_expr())
return false;
11178 return static_cast<xpath_value_type
>(
_rettype);
11218 return memory ?
new (memory)
xpath_ast_node(type, rettype, value) : 0;
11224 return memory ?
new (memory)
xpath_ast_node(type, rettype, value) : 0;
11230 return memory ?
new (memory)
xpath_ast_node(type, rettype, value) : 0;
11236 return memory ?
new (memory)
xpath_ast_node(type, rettype, left, right) : 0;
11242 return memory ?
new (memory)
xpath_ast_node(type, left, axis, test, contents) : 0;
11248 return memory ?
new (memory)
xpath_ast_node(type, left, right, test) : 0;
11256 size_t length =
static_cast<size_t>(value.
end - value.
begin);
11258 char_t* c =
static_cast<char_t*
>(
_alloc->
allocate((length + 1) *
sizeof(char_t)));
11261 memcpy(c, value.
begin, length *
sizeof(char_t));
11269 switch (name.
begin[0])
11280 if (args[0]->rettype() != xpath_type_node_set)
return error(
"Function has to be applied to node set");
11283 else if (name ==
PUGIXML_TEXT(
"contains") && argc == 2)
11287 else if (name ==
PUGIXML_TEXT(
"ceiling") && argc == 1)
11311 else if (name ==
PUGIXML_TEXT(
"local-name") && argc <= 1)
11313 if (argc == 1 && args[0]->rettype() != xpath_type_node_set)
return error(
"Function has to be applied to node set");
11322 if (argc == 1 && args[0]->rettype() != xpath_type_node_set)
return error(
"Function has to be applied to node set");
11325 else if (name ==
PUGIXML_TEXT(
"namespace-uri") && argc <= 1)
11327 if (argc == 1 && args[0]->rettype() != xpath_type_node_set)
return error(
"Function has to be applied to node set");
11330 else if (name ==
PUGIXML_TEXT(
"normalize-space") && argc <= 1)
11354 else if (name ==
PUGIXML_TEXT(
"string-length") && argc <= 1)
11356 else if (name ==
PUGIXML_TEXT(
"starts-with") && argc == 2)
11358 else if (name ==
PUGIXML_TEXT(
"substring-before") && argc == 2)
11360 else if (name ==
PUGIXML_TEXT(
"substring-after") && argc == 2)
11362 else if (name ==
PUGIXML_TEXT(
"substring") && (argc == 2 || argc == 3))
11366 if (args[0]->rettype() != xpath_type_node_set)
return error(
"Function has to be applied to node set");
11384 return error(
"Unrecognized function or wrong parameter count");
11391 switch (name.
begin[0])
11457 switch (name.
begin[0])
11500 return error(
"Unknown variable: variable set is not provided");
11507 return error(
"Unknown variable: variable set does not contain the given name");
11522 return error(
"Expected ')' to match an opening '('");
11532 if (!value)
return 0;
11562 return error(
"Unrecognized function call");
11570 return error(
"No comma between function arguments");
11577 if (argc < 2) args[argc] = n;
11590 return error(
"Unrecognizable primary expression");
11606 if (n->
rettype() != xpath_type_node_set)
11607 return error(
"Predicate has to be applied to node set");
11610 if (!expr)
return 0;
11616 return error(
"Expected ']' to match an opening '['");
11631 if (set && set->
rettype() != xpath_type_node_set)
11632 return error(
"Step has to be applied to node set");
11634 bool axis_specified =
false;
11640 axis_specified =
true;
11649 return error(
"Predicates are not allowed after an abbreviated step");
11658 return error(
"Predicates are not allowed after an abbreviated step");
11676 if (axis_specified)
11677 return error(
"Two axis specifiers in one step");
11681 if (!axis_specified)
11682 return error(
"Unknown axis");
11700 return error(
"Unrecognized node test");
11718 return error(
"Unrecognized node type");
11722 else if (nt_name ==
PUGIXML_TEXT(
"processing-instruction"))
11725 return error(
"Only literals are allowed as arguments to processing-instruction()");
11732 return error(
"Unmatched brace near processing-instruction()");
11737 return error(
"Unmatched brace near node type test");
11743 if (nt_name.
end - nt_name.
begin > 2 && nt_name.
end[-2] ==
':' && nt_name.
end[-1] ==
'*')
11763 return error(
"Unrecognized node test");
11767 if (!nt_name_copy)
return 0;
11779 if (!expr)
return 0;
11782 if (!pred)
return 0;
11785 return error(
"Expected ']' to match an opening '['");
11900 if (n->
rettype() != xpath_type_node_set)
11901 return error(
"Step has to be applied to node set");
12004 if (!rhs)
return 0;
12011 if (!rhs)
return 0;
12017 return error(
"Union operator has to be applied to node sets");
12020 if (!lhs)
return 0;
12065 return error(
"Incorrect query");
12074 return parser.
parse();
12083 if (!memory)
return 0;
12111 if (!impl)
return 0;
12113 if (impl->
root->
rettype() != xpath_type_node_set)
12115 #ifdef PUGIXML_NO_EXCEPTIONS
12118 xpath_parse_result res;
12119 res.error =
"Expression does not evaluate to node set";
12121 throw xpath_exception(res);
12131#ifndef PUGIXML_NO_EXCEPTIONS
12202 return (
bool)lhs && rhs;
12205 PUGI__FN bool operator||(
const xpath_node& lhs,
bool rhs)
12207 return (
bool)lhs || rhs;
12213 assert(begin_ <= end_);
12215 size_t size_ =
static_cast<size_t>(end_ - begin_);
12223 if (begin_ != end_)
_storage = *begin_;
12236 #ifdef PUGIXML_NO_EXCEPTIONS
12239 throw std::bad_alloc();
12243 memcpy(storage, begin_, size_ *
sizeof(
xpath_node));
12250 _end = storage + size_;
12255#ifdef PUGIXML_HAS_MOVE
12259 _storage = rhs._storage;
12260 _begin = (rhs._begin == &rhs._storage) ? &_storage : rhs._begin;
12261 _end = _begin + (rhs._end - rhs._begin);
12263 rhs._type = type_unsorted;
12264 rhs._begin = &rhs._storage;
12265 rhs._end = rhs._begin;
12275 _assign(begin_, end_, type_);
12281 impl::xml_memory::deallocate(
_begin);
12291 if (
this == &ns)
return *
this;
12298#ifdef PUGIXML_HAS_MOVE
12306 if (
this == &rhs)
return *
this;
12308 if (_begin != &_storage)
12309 impl::xml_memory::deallocate(_begin);
12334 assert(index <
size());
12381 return static_cast<const impl::xpath_variable_node_set*
>(
this)->
name;
12384 return static_cast<const impl::xpath_variable_number*
>(
this)->
name;
12387 return static_cast<const impl::xpath_variable_string*
>(
this)->
name;
12390 return static_cast<const impl::xpath_variable_boolean*
>(
this)->
name;
12393 assert(
false &&
"Invalid variable type");
12405 return (
_type ==
xpath_type_boolean) ?
static_cast<const impl::xpath_variable_boolean*
>(
this)->value :
false;
12410 return (
_type ==
xpath_type_number) ?
static_cast<const impl::xpath_variable_number*
>(
this)->value : impl::gen_nan();
12421 return (
_type ==
xpath_type_node_set) ?
static_cast<const impl::xpath_variable_node_set*
>(
this)->value : impl::dummy_node_set;
12428 static_cast<impl::xpath_variable_boolean*
>(
this)->value = value;
12436 static_cast<impl::xpath_variable_number*
>(
this)->value = value;
12444 impl::xpath_variable_string* var =
static_cast<impl::xpath_variable_string*
>(
this);
12447 size_t size = (impl::strlength(value) + 1) *
sizeof(
char_t);
12449 char_t* copy =
static_cast<char_t*
>(impl::xml_memory::allocate(size));
12450 if (!copy)
return false;
12452 memcpy(copy, value, size);
12455 if (var->value) impl::xml_memory::deallocate(var->value);
12465 static_cast<impl::xpath_variable_node_set*
>(
this)->value = value;
12471 for (
size_t i = 0; i <
sizeof(
_data) /
sizeof(
_data[0]); ++i)
12477 for (
size_t i = 0; i <
sizeof(
_data) /
sizeof(
_data[0]); ++i)
12483 for (
size_t i = 0; i <
sizeof(
_data) /
sizeof(
_data[0]); ++i)
12491 if (
this == &rhs)
return *
this;
12498#ifdef PUGIXML_HAS_MOVE
12501 for (
size_t i = 0; i <
sizeof(_data) /
sizeof(_data[0]); ++i)
12503 _data[i] = rhs._data[i];
12510 for (
size_t i = 0; i <
sizeof(_data) /
sizeof(_data[0]); ++i)
12512 _destroy(_data[i]);
12514 _data[i] = rhs._data[i];
12526 for (
size_t i = 0; i <
sizeof(
_data) /
sizeof(
_data[0]); ++i)
12535 for (
size_t i = 0; i <
sizeof(
_data) /
sizeof(
_data[0]); ++i)
12540 rhs.
_data[i] = chain;
12546 const size_t hash_size =
sizeof(
_data) /
sizeof(
_data[0]);
12547 size_t hash = impl::hash_string(name) % hash_size;
12551 if (impl::strequal(var->name(), name))
12565 if (!nvar)
return false;
12569 last->
_next = nvar;
12571 *out_result = nvar;
12576 if (!impl::copy_xpath_variable(nvar, var))
return false;
12590 impl::delete_xpath_variable(var->
_type, var);
12598 const size_t hash_size =
sizeof(
_data) /
sizeof(
_data[0]);
12599 size_t hash = impl::hash_string(name) % hash_size;
12603 if (impl::strequal(var->name(), name))
12604 return var->
type() == type ? var : 0;
12613 _data[hash] = result;
12622 return var ? var->
set(value) :
false;
12628 return var ? var->
set(value) :
false;
12634 return var ? var->
set(value) :
false;
12640 return var ? var->
set(value) :
false;
12645 return _find(name);
12650 return _find(name);
12655 impl::xpath_query_impl* qimpl = impl::xpath_query_impl::create();
12659 #ifdef PUGIXML_NO_EXCEPTIONS
12662 throw std::bad_alloc();
12667 using impl::auto_deleter;
12670 qimpl->root = impl::xpath_parser::parse(query, variables, &qimpl->alloc, &
_result);
12674 qimpl->root->optimize(&qimpl->alloc);
12681 #ifdef PUGIXML_NO_EXCEPTIONS
12684 if (qimpl->oom)
throw std::bad_alloc();
12698 impl::xpath_query_impl::destroy(
static_cast<impl::xpath_query_impl*
>(
_impl));
12701#ifdef PUGIXML_HAS_MOVE
12705 _result = rhs._result;
12712 if (
this == &rhs)
return *
this;
12715 impl::xpath_query_impl::destroy(
static_cast<impl::xpath_query_impl*
>(_impl));
12718 _result = rhs._result;
12720 rhs._result = xpath_parse_result();
12730 return static_cast<impl::xpath_query_impl*
>(
_impl)->root->rettype();
12735 if (!
_impl)
return false;
12737 impl::xpath_context c(n, 1, 1);
12738 impl::xpath_stack_data
sd;
12740 bool r =
static_cast<impl::xpath_query_impl*
>(
_impl)->root->eval_boolean(c,
sd.stack);
12744 #ifdef PUGIXML_NO_EXCEPTIONS
12747 throw std::bad_alloc();
12756 if (!
_impl)
return impl::gen_nan();
12758 impl::xpath_context c(n, 1, 1);
12759 impl::xpath_stack_data
sd;
12761 double r =
static_cast<impl::xpath_query_impl*
>(
_impl)->root->eval_number(c,
sd.stack);
12765 #ifdef PUGIXML_NO_EXCEPTIONS
12766 return impl::gen_nan();
12768 throw std::bad_alloc();
12775#ifndef PUGIXML_NO_STL
12780 impl::xpath_context c(n, 1, 1);
12781 impl::xpath_stack_data
sd;
12783 impl::xpath_string r =
static_cast<impl::xpath_query_impl*
>(
_impl)->root->eval_string(c,
sd.stack);
12787 #ifdef PUGIXML_NO_EXCEPTIONS
12790 throw std::bad_alloc();
12794 return string_t(r.c_str(), r.length());
12800 impl::xpath_context c(n, 1, 1);
12801 impl::xpath_stack_data
sd;
12803 impl::xpath_string r =
_impl ?
static_cast<impl::xpath_query_impl*
>(
_impl)->root->eval_string(c,
sd.stack) : impl::xpath_string();
12807 #ifdef PUGIXML_NO_EXCEPTIONS
12808 r = impl::xpath_string();
12810 throw std::bad_alloc();
12814 size_t full_size = r.length() + 1;
12818 size_t size = (full_size < capacity) ? full_size : capacity;
12821 memcpy(buffer, r.c_str(), (size - 1) *
sizeof(
char_t));
12822 buffer[size - 1] = 0;
12830 impl::xpath_ast_node* root = impl::evaluate_node_set_prepare(
static_cast<impl::xpath_query_impl*
>(
_impl));
12833 impl::xpath_context c(n, 1, 1);
12834 impl::xpath_stack_data
sd;
12836 impl::xpath_node_set_raw r = root->eval_node_set(c,
sd.stack, impl::nodeset_eval_all);
12840 #ifdef PUGIXML_NO_EXCEPTIONS
12843 throw std::bad_alloc();
12852 impl::xpath_ast_node* root = impl::evaluate_node_set_prepare(
static_cast<impl::xpath_query_impl*
>(
_impl));
12855 impl::xpath_context c(n, 1, 1);
12856 impl::xpath_stack_data
sd;
12858 impl::xpath_node_set_raw r = root->eval_node_set(c,
sd.stack, impl::nodeset_eval_first);
12862 #ifdef PUGIXML_NO_EXCEPTIONS
12865 throw std::bad_alloc();
12933#if defined(_MSC_VER) && !defined(__INTEL_COMPILER)
12934# pragma warning(pop)
12937#if defined(_MSC_VER) && defined(__c2__)
12938# pragma clang diagnostic pop
12941#if defined(__clang__)
12942# pragma clang diagnostic pop
12946#undef PUGI__NO_INLINE
12947#undef PUGI__UNLIKELY
12948#undef PUGI__STATIC_ASSERT
12949#undef PUGI__DMC_VOLATILE
12950#undef PUGI__UNSIGNED_OVERFLOW
12951#undef PUGI__MSVC_CRT_VERSION
12952#undef PUGI__SNPRINTF
12953#undef PUGI__NS_BEGIN
12956#undef PUGI__FN_NO_INLINE
12957#undef PUGI__GETHEADER_IMPL
12958#undef PUGI__GETPAGE_IMPL
12959#undef PUGI__GETPAGE
12960#undef PUGI__NODETYPE
12961#undef PUGI__IS_CHARTYPE_IMPL
12962#undef PUGI__IS_CHARTYPE
12963#undef PUGI__IS_CHARTYPEX
12964#undef PUGI__ENDSWITH
12967#undef PUGI__PUSHNODE
12968#undef PUGI__POPNODE
12969#undef PUGI__SCANFOR
12970#undef PUGI__SCANWHILE
12971#undef PUGI__SCANWHILE_UNROLL
12973#undef PUGI__THROW_ERROR
12974#undef PUGI__CHECK_ERROR
auto end() const noexcept
auto begin() const noexcept
名称范围迭代支持
ConcurrentQueue & operator=(ConcurrentQueue const &) MOODYCAMEL_DELETE_FUNCTION
bool operator!=(const xml_attribute_iterator &rhs) const
const xml_attribute_iterator & operator--()
xml_attribute * operator->() const
xml_attribute & operator*() const
bool operator==(const xml_attribute_iterator &rhs) const
const xml_attribute_iterator & operator++()
const char_t * as_string(const char_t *def=PUGIXML_TEXT("")) const
bool operator>=(const xml_attribute &r) const
bool as_bool(bool def=false) const
bool operator!=(const xml_attribute &r) const
bool operator<(const xml_attribute &r) const
int as_int(int def=0) const
float as_float(float def=0) const
bool operator==(const xml_attribute &r) const
size_t hash_value() const
const char_t * name() const
xml_attribute & operator=(const char_t *rhs)
xml_attribute previous_attribute() const
xml_attribute_struct * _attr
xml_attribute next_attribute() const
bool operator<=(const xml_attribute &r) const
double as_double(double def=0) const
void(* unspecified_bool_type)(xml_attribute ***)
bool set_name(const char_t *rhs)
bool set_value(const char_t *rhs)
unsigned int as_uint(unsigned int def=0) const
xml_attribute_struct * internal_object() const
bool operator>(const xml_attribute &r) const
const char_t * value() const
xml_parse_result load_buffer_inplace(void *contents, size_t size, unsigned int options=parse_default, xml_encoding encoding=encoding_auto)
xml_node document_element() const
xml_parse_result load_string(const char_t *contents, unsigned int options=parse_default)
bool save_file(const char *path, const char_t *indent=PUGIXML_TEXT("\t"), unsigned int flags=format_default, xml_encoding encoding=encoding_auto) const
xml_parse_result load_buffer_inplace_own(void *contents, size_t size, unsigned int options=parse_default, xml_encoding encoding=encoding_auto)
xml_parse_result load_file(const char *path, unsigned int options=parse_default, xml_encoding encoding=encoding_auto)
xml_parse_result load_buffer(const void *contents, size_t size, unsigned int options=parse_default, xml_encoding encoding=encoding_auto)
xml_document & operator=(const xml_document &)
xml_parse_result load(std::basic_istream< char, std::char_traits< char > > &stream, unsigned int options=parse_default, xml_encoding encoding=encoding_auto)
void save(xml_writer &writer, const char_t *indent=PUGIXML_TEXT("\t"), unsigned int flags=format_default, xml_encoding encoding=encoding_auto) const
void _move(xml_document &rhs) PUGIXML_NOEXCEPT_IF_NOT_COMPACT
xml_named_node_iterator()
bool operator!=(const xml_named_node_iterator &rhs) const
xml_node * operator->() const
const xml_named_node_iterator & operator--()
bool operator==(const xml_named_node_iterator &rhs) const
xml_node & operator*() const
const xml_named_node_iterator & operator++()
bool operator==(const xml_node_iterator &rhs) const
const xml_node_iterator & operator--()
xml_node * operator->() const
bool operator!=(const xml_node_iterator &rhs) const
const xml_node_iterator & operator++()
xml_node & operator*() const
string_t path(char_t delimiter='/') const
size_t hash_value() const
PUGIXML_DEPRECATED xpath_node select_single_node(const char_t *query, xpath_variable_set *variables=0) const
bool set_value(const char_t *rhs)
xml_node_type type() const
xml_node append_child(xml_node_type type=node_element)
xml_node child(const char_t *name) const
friend class xml_named_node_iterator
xml_node insert_move_after(const xml_node &moved, const xml_node &node)
xml_node last_child() const
xml_node append_move(const xml_node &moved)
xml_node first_child() const
bool operator>(const xml_node &r) const
xml_object_range< xml_node_iterator > children() const
xml_node prepend_move(const xml_node &moved)
xml_attribute append_attribute(const char_t *name)
xml_node next_sibling() const
xml_node_struct * internal_object() const
xml_object_range< xml_attribute_iterator > attributes() const
bool remove_child(const xml_node &n)
xml_attribute append_copy(const xml_attribute &proto)
xml_node insert_child_after(xml_node_type type, const xml_node &node)
xml_attribute last_attribute() const
attribute_iterator attributes_end() const
xml_node previous_sibling() const
xpath_node select_node(const char_t *query, xpath_variable_set *variables=0) const
ptrdiff_t offset_debug() const
xml_attribute insert_attribute_before(const char_t *name, const xml_attribute &attr)
xml_attribute insert_attribute_after(const char_t *name, const xml_attribute &attr)
bool operator!=(const xml_node &r) const
bool operator<(const xml_node &r) const
xml_attribute prepend_attribute(const char_t *name)
xml_parse_result append_buffer(const void *contents, size_t size, unsigned int options=parse_default, xml_encoding encoding=encoding_auto)
const char_t * value() const
void(* unspecified_bool_type)(xml_node ***)
xml_attribute_iterator attribute_iterator
bool traverse(xml_tree_walker &walker)
xml_node find_child_by_attribute(const char_t *name, const char_t *attr_name, const char_t *attr_value) const
const char_t * child_value() const
bool set_name(const char_t *rhs)
xml_node prepend_child(xml_node_type type=node_element)
xml_attribute first_attribute() const
bool operator>=(const xml_node &r) const
xml_attribute insert_copy_after(const xml_attribute &proto, const xml_attribute &attr)
xml_attribute prepend_copy(const xml_attribute &proto)
xml_node insert_move_before(const xml_node &moved, const xml_node &node)
xml_node first_element_by_path(const char_t *path, char_t delimiter='/') const
xml_attribute attribute(const char_t *name) const
const char_t * name() const
xml_attribute insert_copy_before(const xml_attribute &proto, const xml_attribute &attr)
attribute_iterator attributes_begin() const
xpath_node_set select_nodes(const char_t *query, xpath_variable_set *variables=0) const
xml_node_iterator iterator
bool operator<=(const xml_node &r) const
bool remove_attribute(const xml_attribute &a)
void print(xml_writer &writer, const char_t *indent=PUGIXML_TEXT("\t"), unsigned int flags=format_default, xml_encoding encoding=encoding_auto, unsigned int depth=0) const
xml_node insert_child_before(xml_node_type type, const xml_node &node)
bool operator==(const xml_node &r) const
const char_t * as_string(const char_t *def=PUGIXML_TEXT("")) const
double as_double(double def=0) const
xml_text & operator=(const char_t *rhs)
float as_float(float def=0) const
xml_node_struct * _data_new()
bool as_bool(bool def=false) const
bool set(const char_t *rhs)
int as_int(int def=0) const
unsigned int as_uint(unsigned int def=0) const
void(* unspecified_bool_type)(xml_text ***)
const char_t * get() const
xml_node_struct * _data() const
virtual bool end(xml_node &node)
virtual bool for_each(xml_node &node)=0
virtual bool begin(xml_node &node)
virtual ~xml_tree_walker()
xml_writer_file(void *file)
virtual void write(const void *data, size_t size) PUGIXML_OVERRIDE
xml_writer_stream(std::basic_ostream< char, std::char_traits< char > > &stream)
std::basic_ostream< wchar_t, std::char_traits< wchar_t > > * wide_stream
virtual void write(const void *data, size_t size) PUGIXML_OVERRIDE
std::basic_ostream< char, std::char_traits< char > > * narrow_stream
const xpath_parse_result & result() const
xpath_exception(const xpath_parse_result &result)
virtual const char * what() const noexcept PUGIXML_OVERRIDE
xpath_parse_result _result
xpath_node_set & operator=(const xpath_node_set &ns)
void _assign(const_iterator begin, const_iterator end, type_t type)
const_iterator end() const
void sort(bool reverse=false)
const_iterator begin() const
const xpath_node & operator[](size_t index) const
void _move(xpath_node_set &rhs) PUGIXML_NOEXCEPT
void(* unspecified_bool_type)(xpath_node ***)
xml_attribute attribute() const
bool operator!=(const xpath_node &n) const
bool operator==(const xpath_node &n) const
string_t evaluate_string(const xpath_node &n) const
void(* unspecified_bool_type)(xpath_query ***)
double evaluate_number(const xpath_node &n) const
xpath_node_set evaluate_node_set(const xpath_node &n) const
xpath_value_type return_type() const
xpath_parse_result _result
xpath_query & operator=(const xpath_query &)
const xpath_parse_result & result() const
bool evaluate_boolean(const xpath_node &n) const
xpath_node evaluate_node(const xpath_node &n) const
xpath_variable * add(const char_t *name, xpath_value_type type)
void _swap(xpath_variable_set &rhs)
bool set(const char_t *name, bool value)
void _assign(const xpath_variable_set &rhs)
static void _destroy(xpath_variable *var)
static bool _clone(xpath_variable *var, xpath_variable **out_result)
xpath_variable * get(const char_t *name)
xpath_variable * _data[64]
xpath_variable * _find(const char_t *name) const
xpath_variable_set & operator=(const xpath_variable_set &rhs)
xpath_variable(xpath_value_type type)
double get_number() const
const char_t * get_string() const
const xpath_node_set & get_node_set() const
xpath_value_type type() const
const char_t * name() const
void write_direct(const char_t *data, size_t length)
void write_string(const char_t *data)
union xml_buffered_writer::@16 scratch
xml_buffered_writer(xml_writer &writer_, xml_encoding user_encoding)
void write(char_t d0, char_t d1)
xml_buffered_writer(const xml_buffered_writer &)
char_t data_char[bufcapacity]
xml_buffered_writer & operator=(const xml_buffered_writer &)
char_t buffer[bufcapacity]
void flush(const char_t *data, size_t size)
uint16_t data_u16[2 *bufcapacity]
void write(char_t d0, char_t d1, char_t d2, char_t d3, char_t d4)
uint8_t data_u8[4 *bufcapacity]
void write_buffer(const char_t *data, size_t length)
void write(char_t d0, char_t d1, char_t d2, char_t d3, char_t d4, char_t d5)
void write(char_t d0, char_t d1, char_t d2, char_t d3)
void write(char_t d0, char_t d1, char_t d2)
uint32_t data_u32[bufcapacity]
const unsigned char * table
xpath_variable * variable
void set_next(xpath_ast_node *value)
bool step_push(xpath_node_set_raw &ns, xml_node_struct *n, xpath_allocator *alloc)
xpath_value_type rettype() const
xpath_node_set_raw step_do(const xpath_context &c, const xpath_stack &stack, nodeset_eval_t eval, T v)
static bool eval_once(xpath_node_set::type_t type, nodeset_eval_t eval)
void optimize_self(xpath_allocator *alloc)
bool is_posinv_expr() const
bool step_push(xpath_node_set_raw &ns, xml_attribute_struct *a, xml_node_struct *parent, xpath_allocator *alloc)
xpath_node_set_raw eval_node_set(const xpath_context &c, const xpath_stack &stack, nodeset_eval_t eval)
xpath_string eval_string(const xpath_context &c, const xpath_stack &stack)
union xpath_ast_node::@19 _data
xpath_ast_node(ast_type_t type, xpath_ast_node *left, axis_t axis, nodetest_t test, const char_t *contents)
void apply_predicate(xpath_node_set_raw &ns, size_t first, const xpath_stack &stack, bool once)
static void apply_predicate_number_const(xpath_node_set_raw &ns, size_t first, xpath_ast_node *expr, const xpath_stack &stack)
xpath_ast_node(ast_type_t type, xpath_value_type rettype_, xpath_variable *value)
double eval_number(const xpath_context &c, const xpath_stack &stack)
void optimize(xpath_allocator *alloc)
static bool compare_eq(xpath_ast_node *lhs, xpath_ast_node *rhs, const xpath_context &c, const xpath_stack &stack, const Comp &comp)
bool is_posinv_step() const
xpath_string eval_string_concat(const xpath_context &c, const xpath_stack &stack)
static void apply_predicate_boolean(xpath_node_set_raw &ns, size_t first, xpath_ast_node *expr, const xpath_stack &stack, bool once)
bool eval_boolean(const xpath_context &c, const xpath_stack &stack)
static bool compare_rel(xpath_ast_node *lhs, xpath_ast_node *rhs, const xpath_context &c, const xpath_stack &stack, const Comp &comp)
static void apply_predicate_number(xpath_node_set_raw &ns, size_t first, xpath_ast_node *expr, const xpath_stack &stack, bool once)
xpath_ast_node & operator=(const xpath_ast_node &)
void step_fill(xpath_node_set_raw &ns, xml_attribute_struct *a, xml_node_struct *p, xpath_allocator *alloc, bool once, T v)
void step_fill(xpath_node_set_raw &ns, xml_node_struct *n, xpath_allocator *alloc, bool once, T)
void step_fill(xpath_node_set_raw &ns, const xpath_node &xn, xpath_allocator *alloc, bool once, T v)
xpath_ast_node(ast_type_t type, xpath_value_type rettype_, double value)
xpath_ast_node(const xpath_ast_node &)
xpath_ast_node(ast_type_t type, xpath_ast_node *left, xpath_ast_node *right, predicate_t test)
void apply_predicates(xpath_node_set_raw &ns, size_t first, const xpath_stack &stack, nodeset_eval_t eval)
xpath_ast_node(ast_type_t type, xpath_value_type rettype_, const char_t *value)
xpath_ast_node(ast_type_t type, xpath_value_type rettype_, xpath_ast_node *left=0, xpath_ast_node *right=0)
void set_right(xpath_ast_node *value)
const char_t * _cur_lexeme_pos
const char_t * current_pos() const
xpath_lexer_string _cur_lexeme_contents
const xpath_lexer_string & contents() const
xpath_lexer(const char_t *query)
const char_t * state() const
xpath_node_set::type_t _type
void append(const xpath_node *begin_, const xpath_node *end_, xpath_allocator *alloc)
xpath_node_set::type_t type() const
void push_back(const xpath_node &node, xpath_allocator *alloc)
xpath_node * begin() const
void truncate(xpath_node *pos)
void push_back_grow(const xpath_node &node, xpath_allocator *alloc)
void set_type(xpath_node_set::type_t value)
static xpath_string from_heap_preallocated(const char_t *begin, const char_t *end)
static xpath_string from_const(const char_t *str)
bool operator!=(const xpath_string &o) const
xpath_string(const char_t *buffer, bool uses_heap_, size_t length_heap)
void append(const xpath_string &o, xpath_allocator *alloc)
static xpath_string from_heap(const char_t *begin, const char_t *end, xpath_allocator *alloc)
char_t * data(xpath_allocator *alloc)
bool operator==(const xpath_string &o) const
static char_t * duplicate_string(const char_t *string, size_t length, xpath_allocator *alloc)
const char_t * c_str() const
std::basic_string< PUGIXML_CHAR, std::char_traits< PUGIXML_CHAR >, std::allocator< PUGIXML_CHAR > > string_t
PUGI__FN deallocation_function PUGIXML_FUNCTION get_memory_deallocation_function()
PUGI__FN allocation_function PUGIXML_FUNCTION get_memory_allocation_function()
const unsigned int format_no_declaration
const unsigned int format_raw
void(* deallocation_function)(void *ptr)
static PUGI__FN void unspecified_bool_xpath_query(xpath_query ***)
static PUGI__FN void unspecified_bool_xml_node(xml_node ***)
void *(* allocation_function)(size_t size)
PUGI__FN std::string PUGIXML_FUNCTION as_utf8(const wchar_t *str)
static PUGI__FN void unspecified_bool_xml_attribute(xml_attribute ***)
@ status_append_invalid_root
@ status_end_element_mismatch
@ status_bad_start_element
@ status_unrecognized_tag
@ status_no_document_element
const unsigned int format_save_file_text
const unsigned int format_write_bom
PUGI__FN void PUGIXML_FUNCTION set_memory_management_functions(allocation_function allocate, deallocation_function deallocate)
static PUGI__FN void unspecified_bool_xpath_node(xpath_node ***)
static PUGI__FN void unspecified_bool_xml_text(xml_text ***)
PUGI__FN std::basic_string< wchar_t > PUGIXML_FUNCTION as_wide(const char *str)
void destroy_node(xml_node_struct *n, xml_allocator &alloc)
#define PUGI__CHECK_ERROR(err, m)
PUGI__FN void default_deallocate(void *ptr)
PUGI__FN size_t strlength_wide(const wchar_t *s)
void insertion_sort(T *begin, T *end, const Pred &pred)
static const size_t xml_memory_page_size
PUGI__FN void node_copy_string(String &dest, Header &header, uintptr_t header_mask, char_t *source, Header &source_header, xml_allocator *alloc)
#define PUGI__OPTSET(OPT)
PUGI__FN double round_nearest_nzero(double value)
PUGI__FN size_t get_latin1_7bit_prefix_length(const uint8_t *data, size_t size)
PUGI__FN xml_parse_result load_buffer_impl(xml_document_struct *doc, xml_node_struct *root, void *contents, size_t size, unsigned int options, xml_encoding encoding, bool is_mutable, bool own, char_t **out_buffer)
#define PUGI__NODETYPE(n)
@ ast_opt_translate_table
@ ast_opt_compare_attribute
@ ast_func_substring_before
@ ast_func_string_length_0
@ ast_func_namespace_uri_0
@ ast_func_normalize_space_1
@ ast_func_normalize_space_0
@ ast_func_substring_after
@ ast_func_namespace_uri_1
@ ast_func_string_length_1
@ ast_op_greater_or_equal
I median3(I first, I middle, I last, const Pred &pred)
PUGI__FN xml_encoding get_write_native_encoding()
PUGI__FN const char_t * qualified_name(const xpath_node &node)
PUGI__FN bool convert_number_to_boolean(double value)
PUGI__FN bool allow_insert_attribute(xml_node_type parent)
char_t *(* strconv_attribute_t)(char_t *, char_t)
#define PUGI__SCANWHILE_UNROLL(X)
PUGI__FN const void * document_buffer_order(const xpath_node &xnode)
PUGI__FN void as_utf8_end(char *buffer, size_t size, const wchar_t *str, size_t length)
wchar_selector< sizeof(wchar_t)>::writer wchar_writer
PUGI__FN xml_encoding get_wchar_encoding()
PUGI__FN PUGI__UNSIGNED_OVERFLOW U string_to_integer(const char_t *value, U minv, U maxv)
PUGI__FN void node_copy_attribute(xml_attribute_struct *da, xml_attribute_struct *sa)
PUGI__FN bool allow_insert_child(xml_node_type parent, xml_node_type child)
PUGI__FN FILE * open_file_wide(const wchar_t *path, const wchar_t *mode)
PUGI__FN size_t convert_buffer_output_generic(typename T::value_type dest, const char_t *data, size_t length, D, T)
PUGI__FN void text_output_cdata(xml_buffered_writer &writer, const char_t *s)
PUGI__FN PUGI__UNSIGNED_OVERFLOW unsigned int hash_string(const char_t *str)
PUGI__FN bool get_mutable_buffer(char_t *&out_buffer, size_t &out_length, const void *contents, size_t size, bool is_mutable)
PUGI__FN bool set_value_integer(String &dest, Header &header, uintptr_t header_mask, U value, bool negative)
PUGI__FN bool convert_buffer_generic(char_t *&out_buffer, size_t &out_length, const void *contents, size_t size, D)
static const uintptr_t xml_memory_page_type_mask
#define PUGI__UNSIGNED_OVERFLOW
PUGI__FN void node_copy_tree(xml_node_struct *dn, xml_node_struct *sn)
PUGI__FN xpath_string convert_number_to_string(double value, xpath_allocator *alloc)
PUGI__FN bool is_little_endian()
PUGI__FN void node_output(xml_buffered_writer &writer, xml_node_struct *root, const char_t *indent, unsigned int flags, unsigned int depth)
PUGI__FN size_t zero_terminate_buffer(void *buffer, size_t size, xml_encoding encoding)
PUGI__FN void node_output_simple(xml_buffered_writer &writer, xml_node_struct *node, unsigned int flags)
PUGI__FN float get_value_float(const char_t *value)
PUGI__FN char_t * strconv_comment(char_t *s, char_t endch)
#define PUGI__IS_CHARTYPE(c, ct)
PUGI__FN void node_copy_contents(xml_node_struct *dn, xml_node_struct *sn, xml_allocator *shared_alloc)
PUGI__FN double gen_nan()
PUGI__FN strconv_attribute_t get_strconv_attribute(unsigned int optmask)
PUGI__FN strconv_pcdata_t get_strconv_pcdata(unsigned int optmask)
PUGI__FN bool convert_buffer(char_t *&out_buffer, size_t &out_length, xml_encoding encoding, const void *contents, size_t size, bool is_mutable)
PUGI__FN xml_parse_status load_stream_data_seek(std::basic_istream< T > &stream, void **out_buffer, size_t *out_size)
PUGI__FN bool set_value_bool(String &dest, Header &header, uintptr_t header_mask, bool value)
I min_element(I begin, I end, const Pred &pred)
xml_document_struct & get_document(const Object *object)
PUGI__FN xml_encoding guess_buffer_encoding(const uint8_t *data, size_t size)
PUGI__FN char_t * strconv_escape(char_t *s, gap &g)
PUGI__FN void node_output_comment(xml_buffered_writer &writer, const char_t *s)
PUGI__FN bool node_is_ancestor(xml_node_struct *parent, xml_node_struct *node)
void sort(I begin, I end, const Pred &pred)
void destroy_attribute(xml_attribute_struct *a, xml_allocator &alloc)
PUGI__FN void node_output_pi_value(xml_buffered_writer &writer, const char_t *s)
wchar_selector< sizeof(wchar_t)>::counter wchar_counter
PUGI__NS_END PUGI__NS_BEGIN PUGI__FN bool starts_with(const char_t *string, const char_t *pattern)
static const uintptr_t xml_memory_page_name_allocated_or_shared_mask
#define PUGI__IS_CHARTYPEX(c, ct)
void remove_attribute(xml_attribute_struct *attr, xml_node_struct *node)
PUGI__NS_END PUGI__NS_BEGIN PUGI__FN xpath_node_set::type_t xpath_get_order(const xpath_node *begin, const xpath_node *end)
PUGI__FN int get_value_int(const char_t *value)
PUGI__FN bool node_is_before_sibling(xml_node_struct *ln, xml_node_struct *rn)
static const unsigned char chartypex_table[256]
PUGI__FN bool check_string_to_number_format(const char_t *string)
static const uintptr_t xml_memory_page_contents_shared_mask
void prepend_node(xml_node_struct *child, xml_node_struct *node)
PUGI__NS_END static PUGI__NS_BEGIN const uintptr_t xml_memory_block_alignment
PUGI__FN_NO_INLINE xml_attribute_struct * append_new_attribute(xml_node_struct *node, xml_allocator &alloc)
PUGI__FN T * new_xpath_variable(const char_t *name)
PUGI__FN const char_t * find_char(const char_t *s, char_t c)
PUGI__FN size_t get_valid_length(const char_t *data, size_t length)
void insert_node_before(xml_node_struct *child, xml_node_struct *node)
PUGI__FN std::string as_utf8_impl(const wchar_t *str, size_t length)
xml_memory_management_function_storage< int > xml_memory
PUGI__FN bool node_is_before(xml_node_struct *ln, xml_node_struct *rn)
PUGI__FN xml_parse_status get_file_size(FILE *file, size_t &out_result)
bool is_xpath_attribute(const char_t *name)
#define PUGI__SCANCHARTYPE(ct)
char_t *(* strconv_pcdata_t)(char_t *)
static const uintptr_t xpath_memory_block_alignment
void remove_node(xml_node_struct *node)
#define PUGI__GETPAGE_IMPL(header)
static const unsigned char chartype_table[256]
#define PUGI__ENDSWITH(c, e)
PUGI__NS_END PUGI__NS_BEGIN uint16_t endian_swap(uint16_t value)
PUGI__FN impl::xpath_ast_node * evaluate_node_set_prepare(xpath_query_impl *impl)
PUGI__FN bool get_variable_scratch(char_t(&buffer)[32], xpath_variable_set *set, const char_t *begin, const char_t *end, xpath_variable **out_result)
PUGI__FN char_t * normalize_space(char_t *buffer)
bool is_text_node(xml_node_struct *node)
PUGI__FN xpath_string string_value(const xpath_node &na, xpath_allocator *alloc)
PUGI__FN bool parse_declaration_encoding(const uint8_t *data, size_t size, const uint8_t *&out_encoding, size_t &out_length)
void reverse(I begin, I end)
#define PUGI__FN_NO_INLINE
#define PUGI__STATIC_ASSERT(cond)
PUGI__FN void text_output_indent(xml_buffered_writer &writer, const char_t *indent, size_t indent_length, unsigned int depth)
PUGI__FN void node_output_end(xml_buffered_writer &writer, xml_node_struct *node)
PUGI__FN double get_value_double(const char_t *value)
PUGI__FN xml_parse_status load_stream_data_noseek(std::basic_istream< T > &stream, void **out_buffer, size_t *out_size)
PUGI__FN void close_file(FILE *file)
PUGI__FN_NO_INLINE xml_node_struct * append_new_node(xml_node_struct *node, xml_allocator &alloc, xml_node_type type=node_element)
PUGI__FN PUGI__UNSIGNED_OVERFLOW char_t * integer_to_string(char_t *begin, char_t *end, U value, bool negative)
#define PUGI__DMC_VOLATILE
PUGI__NS_END PUGI__NS_BEGIN xml_attribute_struct * allocate_attribute(xml_allocator &alloc)
#define PUGI__UNLIKELY(cond)
#define PUGI__THROW_ERROR(err, m)
PUGI__FN const char_t * namespace_uri(xml_node node)
xml_parse_result make_parse_result(xml_parse_status status, ptrdiff_t offset=0)
xml_allocator & get_allocator(const Object *object)
PUGI__FN bool set_value_convert(String &dest, Header &header, uintptr_t header_mask, float value)
PUGI__FN bool allow_move(xml_node parent, xml_node child)
PUGI__FN size_t convert_buffer_output(char_t *, uint8_t *r_u8, uint16_t *r_u16, uint32_t *r_u32, const char_t *data, size_t length, xml_encoding encoding)
PUGI__FN char_t * translate_table(char_t *buffer, const unsigned char *table)
PUGI__FN const char_t * convert_number_to_string_special(double value)
PUGI__FN xml_parse_result load_stream_impl(xml_document_struct *doc, std::basic_istream< T > &stream, unsigned int options, xml_encoding encoding, char_t **out_buffer)
PUGI__FN bool is_attribute_of(xml_attribute_struct *attr, xml_node_struct *node)
static const uintptr_t xml_memory_page_name_allocated_mask
PUGI__FN bool convert_string_to_number_scratch(char_t(&buffer)[32], const char_t *begin, const char_t *end, double *out_result)
PUGI__FN xpath_node_set::type_t xpath_sort(xpath_node *begin, xpath_node *end, xpath_node_set::type_t type, bool rev)
PUGI__FN xml_encoding get_write_encoding(xml_encoding encoding)
PUGI__FN void delete_xpath_variable(T *var)
PUGI__FN bool convert_buffer_latin1(char_t *&out_buffer, size_t &out_length, const void *contents, size_t size, bool is_mutable)
void swap(T &lhs, T &rhs)
PUGI__NS_END PUGI__NS_BEGIN PUGI__FN size_t strlength(const char_t *s)
PUGI__FN char * convert_path_heap(const wchar_t *str)
PUGI__FN double round_nearest(double value)
PUGI__FN char_t * translate(char_t *buffer, const char_t *from, const char_t *to, size_t to_length)
void insert_node_after(xml_node_struct *child, xml_node_struct *node)
@ nodetest_all_in_namespace
void insert_attribute_before(xml_attribute_struct *attr, xml_attribute_struct *place, xml_node_struct *node)
PUGI__FN const char_t * find_substring(const char_t *s, const char_t *p)
PUGI__FN bool strequalrange(const char_t *lhs, const char_t *rhs, size_t count)
static const uintptr_t xml_memory_page_value_allocated_or_shared_mask
#define PUGI__SCANCHAR(ch)
PUGI__FN bool save_file_impl(const xml_document &doc, FILE *file, const char_t *indent, unsigned int flags, xml_encoding encoding)
PUGI__FN bool node_output_start(xml_buffered_writer &writer, xml_node_struct *node, const char_t *indent, size_t indent_length, unsigned int flags, unsigned int depth)
PUGI__FN bool has_declaration(xml_node_struct *node)
PUGI__FN double convert_string_to_number(const char_t *string)
PUGI__FN bool is_nan(double value)
PUGI__FN bool set_value_ascii(String &dest, Header &header, uintptr_t header_mask, char *buf)
static const uintptr_t xml_memory_page_value_allocated_mask
PUGI__FN xpath_node xpath_first(const xpath_node *begin, const xpath_node *end, xpath_node_set::type_t type)
#define PUGI__PUSHNODE(TYPE)
static const xpath_node_set dummy_node_set
PUGI__FN size_t as_utf8_begin(const wchar_t *str, size_t length)
PUGI__FN unsigned char * translate_table_generate(xpath_allocator *alloc, const char_t *from, const char_t *to)
PUGI__FN void text_output(xml_buffered_writer &writer, const char_t *s, chartypex_t type, unsigned int flags)
void append_attribute(xml_attribute_struct *attr, xml_node_struct *node)
void prepend_attribute(xml_attribute_struct *attr, xml_node_struct *node)
xml_node_struct * allocate_node(xml_allocator &alloc, xml_node_type type)
#define PUGI__GETHEADER_IMPL(object, page, flags)
PUGI__FN bool strcpy_insitu(String &dest, Header &header, uintptr_t header_mask, const char_t *source, size_t source_length)
#define PUGI__SCANWHILE(X)
PUGI__FN void node_output_attributes(xml_buffered_writer &writer, xml_node_struct *node, const char_t *indent, size_t indent_length, unsigned int flags, unsigned int depth)
PUGI__FN void truncate_zeros(char *begin, char *end)
@ axis_descendant_or_self
PUGI__FN xml_encoding get_buffer_encoding(xml_encoding encoding, const void *contents, size_t size)
PUGI__FN xml_parse_result load_file_impl(xml_document_struct *doc, FILE *file, unsigned int options, xml_encoding encoding, char_t **out_buffer)
void partition3(T *begin, T *end, T pivot, const Pred &pred, T **out_eqbeg, T **out_eqend)
PUGI__FN bool copy_xpath_variable(xpath_variable *lhs, const xpath_variable *rhs)
PUGI__FN const char_t * local_name(const xpath_node &node)
void append_node(xml_node_struct *child, xml_node_struct *node)
PUGI__FN unsigned int get_value_uint(const char_t *value)
PUGI__FN void convert_number_to_mantissa_exponent(double value, char(&buffer)[32], char **out_mantissa, int *out_exponent)
PUGI__FN bool get_value_bool(const char_t *value)
PUGI__NS_END static PUGI__NS_BEGIN const size_t xpath_memory_page_size
PUGI__FN bool strequal(const char_t *src, const char_t *dst)
PUGI__FN std::basic_string< wchar_t > as_wide_impl(const char *str, size_t size)
PUGI__FN char_t * strconv_cdata(char_t *s, char_t endch)
PUGI__NS_BEGIN PUGI__FN void * default_allocate(size_t size)
bool strcpy_insitu_allow(size_t length, const Header &header, uintptr_t header_mask, char_t *target)
PUGI__FN char_t tolower_ascii(char_t ch)
PUGI__FN void text_output_escaped(xml_buffered_writer &writer, const char_t *s, chartypex_t type)
void insert_attribute_after(xml_attribute_struct *attr, xml_attribute_struct *place, xml_node_struct *node)
#define PUGIXML_NOEXCEPT_IF_NOT_COMPACT
auto_deleter(T *data_, D deleter_)
bool operator()(const xpath_node &lhs, const xpath_node &rhs) const
bool operator()(const xpath_node &lhs, const xpath_node &rhs) const
bool operator()(const T &lhs, const T &rhs) const
char_t * flush(char_t *s)
void push(char_t *&s, size_t count)
static Traits::value_type process(const uint8_t *data, size_t size, typename Traits::value_type result, Traits)
static value_type high(value_type result, uint32_t ch)
static value_type low(value_type result, uint32_t ch)
bool operator()(const T &lhs, const T &rhs) const
bool operator()(const T &lhs, const T &rhs) const
name_null_sentry(xml_node_struct *node_)
namespace_uri_predicate(const char_t *name)
bool operator()(xml_attribute a) const
bool operator()(const T &lhs, const T &rhs) const
xml_attribute_struct * prev_attribute_c
xml_attribute_struct(impl::xml_memory_page *page)
xml_attribute_struct * next_attribute
xml_attribute_struct * first_attribute
xml_node_struct * prev_sibling_c
xml_node_struct * next_sibling
xml_node_struct * first_child
xml_node_struct(impl::xml_memory_page *page, xml_node_type type)
const char * description() const
const char * description() const
static char_t * parse_eol(char_t *s, char_t end_quote)
static char_t * parse_simple(char_t *s, char_t end_quote)
static char_t * parse_wnorm(char_t *s, char_t end_quote)
static char_t * parse_wconv(char_t *s, char_t end_quote)
static char_t * parse(char_t *s)
static value_type low(value_type result, uint32_t)
static value_type high(value_type result, uint32_t)
static Traits::value_type process(const uint16_t *data, size_t size, typename Traits::value_type result, Traits)
static value_type high(value_type result, uint32_t ch)
static value_type low(value_type result, uint32_t ch)
static value_type any(value_type result, uint32_t ch)
static value_type low(value_type result, uint32_t)
static value_type high(value_type result, uint32_t)
static Traits::value_type process(const uint32_t *data, size_t size, typename Traits::value_type result, Traits)
static value_type low(value_type result, uint32_t ch)
static value_type high(value_type result, uint32_t ch)
static value_type any(value_type result, uint32_t ch)
static value_type low(value_type result, uint32_t ch)
static value_type high(value_type result, uint32_t)
static Traits::value_type process(const uint8_t *data, size_t size, typename Traits::value_type result, Traits)
static value_type any(value_type result, uint32_t ch)
static value_type high(value_type result, uint32_t ch)
static value_type low(value_type result, uint32_t ch)
static Traits::value_type process(const wchar_t *data, size_t size, typename Traits::value_type result, Traits traits)
utf16_decoder< opt_false > decoder
utf32_decoder< opt_false > decoder
void * allocate_memory(size_t size, xml_memory_page *&out_page)
void * allocate_object(size_t size, xml_memory_page *&out_page)
char_t * allocate_string(size_t length)
static void deallocate_page(xml_memory_page *page)
void * allocate_memory_oob(size_t size, xml_memory_page *&out_page)
void deallocate_memory(void *ptr, size_t size, xml_memory_page *page)
xml_memory_page * allocate_page(size_t data_size)
xml_allocator(xml_memory_page *root)
void deallocate_string(char_t *string)
xml_document_struct(xml_memory_page *page)
xml_extra_buffer * extra_buffers
static deallocation_function deallocate
static allocation_function allocate
static xml_memory_page * construct(void *memory)
xml_allocator * allocator
static char_t * parse_skip_bom(char_t *s)
xml_parse_status error_status
xml_parser(xml_allocator *alloc_)
char_t * parse_doctype_primitive(char_t *s)
char_t * parse_tree(char_t *s, xml_node_struct *root, unsigned int optmsk, char_t endch)
static xml_parse_result parse(char_t *buffer, size_t length, xml_document_struct *xmldoc, xml_node_struct *root, unsigned int optmsk)
static bool has_element_node_siblings(xml_node_struct *node)
char_t * parse_doctype_group(char_t *s, char_t endch)
char_t * parse_question(char_t *s, xml_node_struct *&ref_cursor, unsigned int optmsk, char_t endch)
char_t * parse_doctype_ignore(char_t *s)
char_t * parse_exclamation(char_t *s, xml_node_struct *cursor, unsigned int optmsk, char_t endch)
static xml_stream_chunk * create()
T data[xml_memory_page_size/sizeof(T)]
static void destroy(xml_stream_chunk *chunk)
~xpath_allocator_capture()
xpath_allocator * _target
xpath_allocator_capture(xpath_allocator *alloc)
void * reallocate(void *ptr, size_t old_size, size_t new_size)
void * allocate(size_t size)
xpath_memory_block * _root
void revert(const xpath_allocator &state)
xpath_allocator(xpath_memory_block *root, bool *error=0)
xpath_context(const xpath_node &n_, size_t position_, size_t size_)
bool operator==(const char_t *other) const
char data[xpath_memory_page_size]
xpath_memory_block * next
binary_op_t(ast_type_t asttype_, xpath_value_type rettype_, int precedence_)
static binary_op_t parse(xpath_lexer &lexer)
xpath_ast_node * error(const char *message)
xpath_ast_node * parse_step(xpath_ast_node *set)
xpath_ast_node * error_oom()
xpath_variable_set * _variables
xpath_parser(const char_t *query, xpath_variable_set *variables, xpath_allocator *alloc, xpath_parse_result *result)
xpath_ast_node * alloc_node(ast_type_t type, xpath_ast_node *left, axis_t axis, nodetest_t test, const char_t *contents)
xpath_ast_node * parse_primary_expression()
xpath_ast_node * alloc_node(ast_type_t type, xpath_ast_node *left, xpath_ast_node *right, predicate_t test)
xpath_ast_node * alloc_node(ast_type_t type, xpath_value_type rettype, xpath_ast_node *left=0, xpath_ast_node *right=0)
xpath_ast_node * parse_filter_expression()
xpath_ast_node * parse_expression(int limit=0)
nodetest_t parse_node_test_type(const xpath_lexer_string &name)
const char_t * alloc_string(const xpath_lexer_string &value)
xpath_parse_result * _result
xpath_ast_node * parse_function(const xpath_lexer_string &name, size_t argc, xpath_ast_node *args[2])
xpath_ast_node * alloc_node(ast_type_t type, xpath_value_type rettype, xpath_variable *value)
xpath_ast_node * alloc_node(ast_type_t type, xpath_value_type rettype, double value)
static xpath_ast_node * parse(const char_t *query, xpath_variable_set *variables, xpath_allocator *alloc, xpath_parse_result *result)
xpath_ast_node * parse_path_or_unary_expression()
axis_t parse_axis_name(const xpath_lexer_string &name, bool &specified)
xpath_ast_node * parse_expression_rec(xpath_ast_node *lhs, int limit)
xpath_ast_node * parse_relative_location_path(xpath_ast_node *set)
xpath_ast_node * alloc_node(ast_type_t type, xpath_value_type rettype, const char_t *value)
xpath_ast_node * parse_location_path()
static void destroy(xpath_query_impl *impl)
static xpath_query_impl * create()
xpath_memory_block blocks[2]
xpath_variable_node_set()