14 #ifndef SOURCE_PUGIXML_CPP 15 #define SOURCE_PUGIXML_CPP 25 #ifdef PUGIXML_WCHAR_MODE 29 #ifndef PUGIXML_NO_XPATH 34 #ifndef PUGIXML_NO_STL 43 #if defined(__clang__) 44 # pragma clang diagnostic push 45 # pragma clang diagnostic ignored "-Wconversion" 46 # pragma clang diagnostic ignored "-Wdouble-promotion" 50 # pragma warning(push) 51 # pragma warning(disable: 4127) // conditional expression is constant 52 # pragma warning(disable: 4324) // structure was padded due to __declspec(align()) 53 # pragma warning(disable: 4702) // unreachable code 54 # pragma warning(disable: 4996) // this function or variable may be unsafe 57 #if defined(_MSC_VER) && defined(__c2__) 58 # pragma clang diagnostic push 59 # pragma clang diagnostic ignored "-Wdeprecated" // this function or variable may be unsafe 62 #ifdef __INTEL_COMPILER 63 # pragma warning(disable: 177) // function was declared but never referenced 64 # pragma warning(disable: 279) // controlling expression is constant 65 # pragma warning(disable: 1478 1786) // function was declared "deprecated" 66 # pragma warning(disable: 1684) // conversion from pointer to same-sized integral type 69 #if defined(__BORLANDC__) && defined(PUGIXML_HEADER_ONLY) 70 # pragma warn -8080 // symbol is declared but never used; disabling this inside push/pop bracket does not make the warning go away 75 # pragma warn -8008 // condition is always false 76 # pragma warn -8066 // unreachable code 81 # pragma diag_suppress=178 // function was declared but never referenced 82 # pragma diag_suppress=237 // controlling expression is constant 85 #ifdef __TI_COMPILER_VERSION__ 86 # pragma diag_suppress 179 // function was declared but never referenced 90 #if defined(_MSC_VER) && _MSC_VER >= 1300 91 # define PUGI__NO_INLINE __declspec(noinline) 92 #elif defined(__GNUC__) 93 # define PUGI__NO_INLINE __attribute__((noinline)) 95 # define PUGI__NO_INLINE 99 #if defined(__GNUC__) && !defined(__c2__) 100 # define PUGI__UNLIKELY(cond) __builtin_expect(cond, 0) 102 # define PUGI__UNLIKELY(cond) (cond) 106 #define PUGI__STATIC_ASSERT(cond) { static const char condition_failed[(cond) ? 1 : -1] = {0}; (void)condition_failed[0]; } 110 # define PUGI__DMC_VOLATILE volatile 112 # define PUGI__DMC_VOLATILE 116 #if defined(__clang__) && defined(__has_attribute) 117 # if __has_attribute(no_sanitize) 118 # define PUGI__UNSIGNED_OVERFLOW __attribute__((no_sanitize("unsigned-integer-overflow"))) 120 # define PUGI__UNSIGNED_OVERFLOW 123 # define PUGI__UNSIGNED_OVERFLOW 127 #if defined(__BORLANDC__) && !defined(__MEM_H_USING_LIST) 134 #if defined(PUGIXML_HAS_LONG_LONG) && defined(__GNUC__) && !defined(LLONG_MAX) && !defined(LLONG_MIN) && !defined(ULLONG_MAX) 135 # define LLONG_MIN (-LLONG_MAX - 1LL) 136 # define LLONG_MAX __LONG_LONG_MAX__ 137 # define ULLONG_MAX (LLONG_MAX * 2ULL + 1ULL) 141 #if defined(_MSC_VER) && !defined(__S3E__) 142 # define PUGI__MSVC_CRT_VERSION _MSC_VER 146 #if __cplusplus >= 201103 147 # define PUGI__SNPRINTF(buf, ...) snprintf(buf, sizeof(buf), __VA_ARGS__) 148 #elif defined(PUGI__MSVC_CRT_VERSION) && PUGI__MSVC_CRT_VERSION >= 1400 149 # define PUGI__SNPRINTF(buf, ...) _snprintf_s(buf, _countof(buf), _TRUNCATE, __VA_ARGS__) 151 # define PUGI__SNPRINTF sprintf 155 #ifdef PUGIXML_HEADER_ONLY 156 # define PUGI__NS_BEGIN namespace pugi { namespace impl { 157 # define PUGI__NS_END } } 158 # define PUGI__FN inline 159 # define PUGI__FN_NO_INLINE inline 161 # if defined(_MSC_VER) && _MSC_VER < 1300 // MSVC6 seems to have an amusing bug with anonymous namespaces inside namespaces 162 # define PUGI__NS_BEGIN namespace pugi { namespace impl { 163 # define PUGI__NS_END } } 165 # define PUGI__NS_BEGIN namespace pugi { namespace impl { namespace { 166 # define PUGI__NS_END } } } 169 # define PUGI__FN_NO_INLINE PUGI__NO_INLINE 173 #if (defined(_MSC_VER) && _MSC_VER < 1600) || (defined(__BORLANDC__) && __BORLANDC__ < 0x561) 176 # ifndef _UINTPTR_T_DEFINED 177 typedef size_t uintptr_t;
180 typedef unsigned __int8 uint8_t;
181 typedef unsigned __int16 uint16_t;
182 typedef unsigned __int32 uint32_t;
200 template <
typename T>
222 #ifdef PUGIXML_WCHAR_MODE 234 #ifdef PUGIXML_WCHAR_MODE 235 return wcscmp(src, dst) == 0;
237 return strcmp(src, dst) == 0;
244 for (
size_t i = 0; i < count; ++i)
245 if (lhs[i] != rhs[i])
248 return lhs[count] == 0;
256 #ifdef PUGIXML_WCHAR_MODE 259 const wchar_t* end = s;
261 return static_cast<size_t>(end - s);
270 typedef void (*D)(T*);
281 if (data) deleter(data);
293 #ifdef PUGIXML_COMPACT 295 class compact_hash_table
298 compact_hash_table(): _items(0), _capacity(0), _count(0)
313 void* find(
const void* key)
315 if (_capacity == 0)
return 0;
317 item_t* item = get_item(key);
319 assert(item->key == key || (item->key == 0 && item->value == 0));
324 void insert(
const void* key,
void* value)
326 assert(_capacity != 0 && _count < _capacity - _capacity / 4);
328 item_t* item = get_item(key);
340 bool reserve(
size_t extra = 16)
342 if (_count + extra >= _capacity - _capacity / 4)
343 return rehash(_count + extra);
360 bool rehash(
size_t count);
362 item_t* get_item(
const void* key)
365 assert(_capacity > 0);
367 size_t hashmod = _capacity - 1;
368 size_t bucket = hash(key) & hashmod;
370 for (
size_t probe = 0; probe <= hashmod; ++probe)
372 item_t& probe_item = _items[bucket];
374 if (probe_item.key == key || probe_item.key == 0)
378 bucket = (bucket + probe + 1) & hashmod;
381 assert(
false &&
"Hash table is full");
387 unsigned int h =
static_cast<unsigned int>(
reinterpret_cast<uintptr_t
>(key));
402 size_t capacity = 32;
403 while (count >= capacity - capacity / 4)
406 compact_hash_table rt;
407 rt._capacity = capacity;
413 memset(rt._items, 0,
sizeof(item_t) * capacity);
415 for (
size_t i = 0; i < _capacity; ++i)
417 rt.insert(_items[i].key, _items[i].value);
422 _capacity = capacity;
425 assert(_count == rt._count);
434 #ifdef PUGIXML_COMPACT 450 #ifdef PUGIXML_COMPACT 451 #define PUGI__GETHEADER_IMPL(object, page, flags) // unused 452 #define PUGI__GETPAGE_IMPL(header) (header).get_page() 454 #define PUGI__GETHEADER_IMPL(object, page, flags) (((reinterpret_cast<char*>(object) - reinterpret_cast<char*>(page)) << 8) | (flags)) 456 #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)))) 459 #define PUGI__GETPAGE(n) PUGI__GETPAGE_IMPL((n)->header) 460 #define PUGI__NODETYPE(n) static_cast<xml_node_type>((n)->header & impl::xml_memory_page_type_mask) 476 #ifdef PUGIXML_COMPACT 477 result->compact_string_base = 0;
478 result->compact_shared_parent = 0;
479 result->compact_page_marker = 0;
493 #ifdef PUGIXML_COMPACT 494 char_t* compact_string_base;
495 void* compact_shared_parent;
496 uint32_t* compact_page_marker;
501 #ifdef PUGIXML_MEMORY_PAGE_SIZE 502 (PUGIXML_MEMORY_PAGE_SIZE)
518 #ifdef PUGIXML_COMPACT 529 if (!memory)
return 0;
550 return allocate_memory_oob(size, out_page);
552 void* buf =
reinterpret_cast<char*
>(_root) +
sizeof(
xml_memory_page) + _busy_size;
561 #ifdef PUGIXML_COMPACT 564 void* result = allocate_memory(size +
sizeof(uint32_t), out_page);
565 if (!result)
return 0;
568 ptrdiff_t offset =
static_cast<char*
>(result) - reinterpret_cast<char*>(out_page->compact_page_marker);
573 uint32_t* marker =
static_cast<uint32_t*
>(result);
575 *marker =
static_cast<uint32_t
>(
reinterpret_cast<char*
>(marker) - reinterpret_cast<char*>(out_page));
576 out_page->compact_page_marker = marker;
587 _busy_size -=
sizeof(uint32_t);
595 return allocate_memory(size, out_page);
601 if (page == _root) page->
busy_size = _busy_size;
613 assert(_root == page);
619 #ifdef PUGIXML_COMPACT 621 page->compact_string_base = 0;
622 page->compact_shared_parent = 0;
623 page->compact_page_marker = 0;
630 assert(_root != page);
638 deallocate_page(page);
658 if (!header)
return 0;
661 ptrdiff_t page_offset =
reinterpret_cast<char*
>(header) - reinterpret_cast<char*>(page) -
sizeof(
xml_memory_page);
664 assert(page_offset >= 0 && static_cast<size_t>(page_offset) < max_encoded_offset);
669 assert(full_size < max_encoded_offset || (page->
busy_size == full_size && page_offset == 0));
674 return static_cast<char_t*
>(
static_cast<void*
>(header + 1));
688 xml_memory_page* page = reinterpret_cast<xml_memory_page*>(static_cast<void*>(reinterpret_cast<char*>(header) - page_offset));
693 deallocate_memory(header, full_size, page);
698 #ifdef PUGIXML_COMPACT 699 return _hash->reserve();
708 #ifdef PUGIXML_COMPACT 709 compact_hash_table* _hash;
722 if (size <= large_allocation_threshold)
752 #ifdef PUGIXML_COMPACT 754 static const uintptr_t compact_alignment_log2 = 2;
755 static const uintptr_t compact_alignment = 1 << compact_alignment_log2;
764 ptrdiff_t offset = (
reinterpret_cast<char*
>(
this) - reinterpret_cast<char*>(page->compact_page_marker));
765 assert(offset % compact_alignment == 0 && static_cast<uintptr_t>(offset) < 256 * compact_alignment);
767 _page =
static_cast<unsigned char>(offset >> compact_alignment_log2);
768 _flags =
static_cast<unsigned char>(flags);
771 void operator&=(uintptr_t mod)
773 _flags &=
static_cast<unsigned char>(mod);
776 void operator|=(uintptr_t mod)
778 _flags |=
static_cast<unsigned char>(mod);
789 const char* page_marker =
reinterpret_cast<const char*
>(
this) - (_page << compact_alignment_log2);
790 const char* page = page_marker - *
reinterpret_cast<const uint32_t*
>(
static_cast<const void*
>(page_marker));
797 unsigned char _flags;
802 const compact_header* header =
reinterpret_cast<const compact_header*
>(
static_cast<const char*
>(object) - header_offset);
804 return header->get_page();
807 template <
int header_offset,
typename T>
PUGI__FN_NO_INLINE T* compact_get_value(
const void*
object)
809 return static_cast<T*
>(compact_get_page(
object, header_offset)->allocator->_hash->find(
object));
812 template <
int header_offset,
typename T>
PUGI__FN_NO_INLINE void compact_set_value(
const void*
object, T* value)
814 compact_get_page(
object, header_offset)->allocator->_hash->insert(
object, value);
817 template <
typename T,
int header_offset,
int start = -126>
class compact_pointer
820 compact_pointer(): _data(0)
824 void operator=(
const compact_pointer& rhs)
829 void operator=(T* value)
837 ptrdiff_t diff =
reinterpret_cast<char*
>(value) - reinterpret_cast<char*>(
this);
838 ptrdiff_t offset = ((diff + int(compact_alignment - 1)) >> compact_alignment_log2) - start;
840 if (static_cast<uintptr_t>(offset) <= 253)
841 _data = static_cast<unsigned char>(offset + 1);
844 compact_set_value<header_offset>(
this, value);
859 uintptr_t base =
reinterpret_cast<uintptr_t
>(
this) & ~(compact_alignment - 1);
861 return reinterpret_cast<T*
>(base + (_data - 1 + start) * compact_alignment);
864 return compact_get_value<header_offset, T>(
this);
870 T* operator->()
const 879 template <
typename T,
int header_offset>
class compact_pointer_parent
882 compact_pointer_parent(): _data(0)
886 void operator=(
const compact_pointer_parent& rhs)
891 void operator=(T* value)
899 ptrdiff_t diff =
reinterpret_cast<char*
>(value) - reinterpret_cast<char*>(
this);
900 ptrdiff_t offset = ((diff + int(compact_alignment - 1)) >> compact_alignment_log2) + 65533;
902 if (static_cast<uintptr_t>(offset) <= 65533)
904 _data =
static_cast<unsigned short>(offset + 1);
911 page->compact_shared_parent = value;
913 if (page->compact_shared_parent == value)
919 compact_set_value<header_offset>(
this, value);
937 uintptr_t base =
reinterpret_cast<uintptr_t
>(
this) & ~(compact_alignment - 1);
939 return reinterpret_cast<T*
>(base + (_data - 1 - 65533) * compact_alignment);
941 else if (_data == 65534)
942 return static_cast<T*
>(compact_get_page(
this, header_offset)->compact_shared_parent);
944 return compact_get_value<header_offset, T>(
this);
950 T* operator->()
const 959 template <
int header_offset,
int base_offset>
class compact_string
962 compact_string(): _data(0)
966 void operator=(
const compact_string& rhs)
971 void operator=(
char_t* value)
978 page->compact_string_base = value;
980 ptrdiff_t offset = value - page->compact_string_base;
982 if (static_cast<uintptr_t>(offset) < (65535 << 7))
985 uint16_t* base =
reinterpret_cast<uint16_t*
>(
static_cast<void*
>(
reinterpret_cast<char*
>(
this) - base_offset));
989 *base =
static_cast<uint16_t
>((offset >> 7) + 1);
990 _data =
static_cast<unsigned char>((offset & 127) + 1);
994 ptrdiff_t remainder = offset - ((*base - 1) << 7);
996 if (static_cast<uintptr_t>(remainder) <= 253)
998 _data =
static_cast<unsigned char>(remainder + 1);
1002 compact_set_value<header_offset>(
this, value);
1010 compact_set_value<header_offset>(
this, value);
1030 const uint16_t* base =
reinterpret_cast<const uint16_t*
>(
static_cast<const void*
>(
reinterpret_cast<const char*
>(
this) - base_offset));
1033 ptrdiff_t offset = ((*base - 1) << 7) + (_data - 1);
1035 return page->compact_string_base + offset;
1039 return compact_get_value<header_offset, char_t>(
this);
1047 unsigned char _data;
1052 #ifdef PUGIXML_COMPACT 1055 struct xml_attribute_struct
1057 xml_attribute_struct(impl::xml_memory_page* page): header(page, 0), namevalue_base(0)
1062 impl::compact_header header;
1064 uint16_t namevalue_base;
1066 impl::compact_string<4, 2> name;
1067 impl::compact_string<5, 3> value;
1069 impl::compact_pointer<xml_attribute_struct, 6> prev_attribute_c;
1070 impl::compact_pointer<xml_attribute_struct, 7, 0> next_attribute;
1080 impl::compact_header header;
1082 uint16_t namevalue_base;
1084 impl::compact_string<4, 2> name;
1085 impl::compact_string<5, 3> value;
1087 impl::compact_pointer_parent<xml_node_struct, 6> parent;
1089 impl::compact_pointer<xml_node_struct, 8, 0> first_child;
1091 impl::compact_pointer<xml_node_struct, 9> prev_sibling_c;
1092 impl::compact_pointer<xml_node_struct, 10, 0> next_sibling;
1094 impl::compact_pointer<xml_attribute_struct, 11, 0> first_attribute;
1118 xml_node_struct(impl::xml_memory_page* page,
xml_node_type type): name(0), value(0), parent(0), first_child(0), prev_sibling_c(0), next_sibling(0), first_attribute(0)
1157 #ifdef PUGIXML_COMPACT 1158 compact_hash_table hash;
1182 void* memory = alloc.
allocate_object(
sizeof(xml_attribute_struct), page);
1183 if (!memory)
return 0;
1185 return new (memory) xml_attribute_struct(page);
1192 if (!memory)
return 0;
1216 for (xml_attribute_struct* attr = n->first_attribute; attr; )
1218 xml_attribute_struct* next = attr->next_attribute;
1239 child->parent = node;
1247 tail->next_sibling = child;
1248 child->prev_sibling_c = tail;
1249 head->prev_sibling_c = child;
1253 node->first_child = child;
1254 child->prev_sibling_c = child;
1260 child->parent = node;
1266 child->prev_sibling_c = head->prev_sibling_c;
1267 head->prev_sibling_c = child;
1270 child->prev_sibling_c = child;
1272 child->next_sibling = head;
1273 node->first_child = child;
1280 child->parent = parent;
1282 if (node->next_sibling)
1283 node->next_sibling->prev_sibling_c = child;
1285 parent->first_child->prev_sibling_c = child;
1287 child->next_sibling = node->next_sibling;
1288 child->prev_sibling_c = node;
1290 node->next_sibling = child;
1297 child->parent = parent;
1299 if (node->prev_sibling_c->next_sibling)
1300 node->prev_sibling_c->next_sibling = child;
1302 parent->first_child = child;
1304 child->prev_sibling_c = node->prev_sibling_c;
1305 child->next_sibling = node;
1307 node->prev_sibling_c = child;
1314 if (node->next_sibling)
1315 node->next_sibling->prev_sibling_c = node->prev_sibling_c;
1317 parent->first_child->prev_sibling_c = node->prev_sibling_c;
1319 if (node->prev_sibling_c->next_sibling)
1320 node->prev_sibling_c->next_sibling = node->next_sibling;
1322 parent->first_child = node->next_sibling;
1325 node->prev_sibling_c = 0;
1326 node->next_sibling = 0;
1331 xml_attribute_struct* head = node->first_attribute;
1335 xml_attribute_struct* tail = head->prev_attribute_c;
1337 tail->next_attribute = attr;
1338 attr->prev_attribute_c = tail;
1339 head->prev_attribute_c = attr;
1343 node->first_attribute = attr;
1344 attr->prev_attribute_c = attr;
1350 xml_attribute_struct* head = node->first_attribute;
1354 attr->prev_attribute_c = head->prev_attribute_c;
1355 head->prev_attribute_c = attr;
1358 attr->prev_attribute_c = attr;
1360 attr->next_attribute = head;
1361 node->first_attribute = attr;
1366 if (place->next_attribute)
1367 place->next_attribute->prev_attribute_c = attr;
1369 node->first_attribute->prev_attribute_c = attr;
1371 attr->next_attribute = place->next_attribute;
1372 attr->prev_attribute_c = place;
1373 place->next_attribute = attr;
1378 if (place->prev_attribute_c->next_attribute)
1379 place->prev_attribute_c->next_attribute = attr;
1381 node->first_attribute = attr;
1383 attr->prev_attribute_c = place->prev_attribute_c;
1384 attr->next_attribute = place;
1385 place->prev_attribute_c = attr;
1390 if (attr->next_attribute)
1391 attr->next_attribute->prev_attribute_c = attr->prev_attribute_c;
1393 node->first_attribute->prev_attribute_c = attr->prev_attribute_c;
1395 if (attr->prev_attribute_c->next_attribute)
1396 attr->prev_attribute_c->next_attribute = attr->next_attribute;
1398 node->first_attribute = attr->next_attribute;
1400 attr->prev_attribute_c = 0;
1401 attr->next_attribute = 0;
1406 if (!alloc.
reserve())
return 0;
1409 if (!child)
return 0;
1418 if (!alloc.
reserve())
return 0;
1421 if (!attr)
return 0;
1446 return static_cast<uint16_t
>(((value & 0xff) << 8) | (value >> 8));
1451 return ((value & 0xff) << 24) | ((value & 0xff00) << 8) | ((value & 0xff0000) >> 8) | (value >> 24);
1458 static value_type
low(value_type result, uint32_t ch)
1461 if (ch < 0x80)
return result + 1;
1463 else if (ch < 0x800)
return result + 2;
1465 else return result + 3;
1468 static value_type
high(value_type result, uint32_t)
1479 static value_type
low(value_type result, uint32_t ch)
1484 *result =
static_cast<uint8_t
>(ch);
1488 else if (ch < 0x800)
1490 result[0] =
static_cast<uint8_t
>(0xC0 | (ch >> 6));
1491 result[1] =
static_cast<uint8_t
>(0x80 | (ch & 0x3F));
1497 result[0] =
static_cast<uint8_t
>(0xE0 | (ch >> 12));
1498 result[1] =
static_cast<uint8_t
>(0x80 | ((ch >> 6) & 0x3F));
1499 result[2] =
static_cast<uint8_t
>(0x80 | (ch & 0x3F));
1504 static value_type
high(value_type result, uint32_t ch)
1507 result[0] =
static_cast<uint8_t
>(0xF0 | (ch >> 18));
1508 result[1] =
static_cast<uint8_t
>(0x80 | ((ch >> 12) & 0x3F));
1509 result[2] =
static_cast<uint8_t
>(0x80 | ((ch >> 6) & 0x3F));
1510 result[3] =
static_cast<uint8_t
>(0x80 | (ch & 0x3F));
1514 static value_type
any(value_type result, uint32_t ch)
1516 return (ch < 0x10000) ? low(result, ch) : high(result, ch);
1524 static value_type
low(value_type result, uint32_t)
1529 static value_type
high(value_type result, uint32_t)
1539 static value_type
low(value_type result, uint32_t ch)
1541 *result =
static_cast<uint16_t
>(ch);
1546 static value_type
high(value_type result, uint32_t ch)
1548 uint32_t msh =
static_cast<uint32_t
>(ch - 0x10000) >> 10;
1549 uint32_t lsh =
static_cast<uint32_t
>(ch - 0x10000) & 0x3ff;
1551 result[0] =
static_cast<uint16_t
>(0xD800 + msh);
1552 result[1] =
static_cast<uint16_t
>(0xDC00 + lsh);
1557 static value_type
any(value_type result, uint32_t ch)
1559 return (ch < 0x10000) ? low(result, ch) : high(result, ch);
1567 static value_type
low(value_type result, uint32_t)
1572 static value_type
high(value_type result, uint32_t)
1582 static value_type
low(value_type result, uint32_t ch)
1589 static value_type
high(value_type result, uint32_t ch)
1596 static value_type
any(value_type result, uint32_t ch)
1608 static value_type
low(value_type result, uint32_t ch)
1610 *result =
static_cast<uint8_t
>(ch > 255 ?
'?' : ch);
1615 static value_type
high(value_type result, uint32_t ch)
1629 template <
typename Traits>
static inline typename Traits::value_type
process(
const uint8_t* data,
size_t size,
typename Traits::value_type result, Traits)
1631 const uint8_t utf8_byte_mask = 0x3f;
1635 uint8_t lead = *data;
1640 result = Traits::low(result, lead);
1645 if ((reinterpret_cast<uintptr_t>(data) & 3) == 0)
1648 while (size >= 4 && (*static_cast<const uint32_t*>(static_cast<const void*>(data)) & 0x80808080) == 0)
1650 result = Traits::low(result, data[0]);
1651 result = Traits::low(result, data[1]);
1652 result = Traits::low(result, data[2]);
1653 result = Traits::low(result, data[3]);
1660 else if (static_cast<unsigned int>(lead - 0xC0) < 0x20 && size >= 2 && (data[1] & 0xc0) == 0x80)
1662 result = Traits::low(result, ((lead & ~0xC0) << 6) | (data[1] & utf8_byte_mask));
1667 else if (static_cast<unsigned int>(lead - 0xE0) < 0x10 && size >= 3 && (data[1] & 0xc0) == 0x80 && (data[2] & 0xc0) == 0x80)
1669 result = Traits::low(result, ((lead & ~0xE0) << 12) | ((data[1] & utf8_byte_mask) << 6) | (data[2] & utf8_byte_mask));
1674 else if (static_cast<unsigned int>(lead - 0xF0) < 0x08 && size >= 4 && (data[1] & 0xc0) == 0x80 && (data[2] & 0xc0) == 0x80 && (data[3] & 0xc0) == 0x80)
1676 result = Traits::high(result, ((lead & ~0xF0) << 18) | ((data[1] & utf8_byte_mask) << 12) | ((data[2] & utf8_byte_mask) << 6) | (data[3] & utf8_byte_mask));
1696 template <
typename Traits>
static inline typename Traits::value_type
process(
const uint16_t* data,
size_t size,
typename Traits::value_type result, Traits)
1700 uint16_t lead = opt_swap::value ?
endian_swap(*data) : *data;
1705 result = Traits::low(result, lead);
1710 else if (static_cast<unsigned int>(lead - 0xE000) < 0x2000)
1712 result = Traits::low(result, lead);
1717 else if (static_cast<unsigned int>(lead - 0xD800) < 0x400 && size >= 2)
1719 uint16_t next = opt_swap::value ?
endian_swap(data[1]) : data[1];
1721 if (static_cast<unsigned int>(next - 0xDC00) < 0x400)
1723 result = Traits::high(result, 0x10000 + ((lead & 0x3ff) << 10) + (next & 0x3ff));
1748 template <
typename Traits>
static inline typename Traits::value_type
process(
const uint32_t* data,
size_t size,
typename Traits::value_type result, Traits)
1752 uint32_t lead = opt_swap::value ?
endian_swap(*data) : *data;
1757 result = Traits::low(result, lead);
1764 result = Traits::high(result, lead);
1778 template <
typename Traits>
static inline typename Traits::value_type
process(
const uint8_t* data,
size_t size,
typename Traits::value_type result, Traits)
1782 result = Traits::low(result, *data);
1816 template <
typename Traits>
static inline typename Traits::value_type
process(
const wchar_t* data,
size_t size,
typename Traits::value_type result, Traits traits)
1820 return decoder::process(reinterpret_cast<const typename decoder::type*>(data), size, result, traits);
1824 #ifdef PUGIXML_WCHAR_MODE 1825 PUGI__FN void convert_wchar_endian_swap(
wchar_t* result,
const wchar_t* data,
size_t length)
1827 for (
size_t i = 0; i < length; ++i)
1848 55, 0, 0, 0, 0, 0, 0, 0, 0, 12, 12, 0, 0, 63, 0, 0,
1849 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
1850 8, 0, 6, 0, 0, 0, 7, 6, 0, 0, 0, 0, 0, 96, 64, 0,
1851 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 192, 0, 1, 0, 48, 0,
1852 0, 192, 192, 192, 192, 192, 192, 192, 192, 192, 192, 192, 192, 192, 192, 192,
1853 192, 192, 192, 192, 192, 192, 192, 192, 192, 192, 192, 0, 0, 16, 0, 192,
1854 0, 192, 192, 192, 192, 192, 192, 192, 192, 192, 192, 192, 192, 192, 192, 192,
1855 192, 192, 192, 192, 192, 192, 192, 192, 192, 192, 192, 0, 0, 0, 0, 0,
1857 192, 192, 192, 192, 192, 192, 192, 192, 192, 192, 192, 192, 192, 192, 192, 192,
1858 192, 192, 192, 192, 192, 192, 192, 192, 192, 192, 192, 192, 192, 192, 192, 192,
1859 192, 192, 192, 192, 192, 192, 192, 192, 192, 192, 192, 192, 192, 192, 192, 192,
1860 192, 192, 192, 192, 192, 192, 192, 192, 192, 192, 192, 192, 192, 192, 192, 192,
1861 192, 192, 192, 192, 192, 192, 192, 192, 192, 192, 192, 192, 192, 192, 192, 192,
1862 192, 192, 192, 192, 192, 192, 192, 192, 192, 192, 192, 192, 192, 192, 192, 192,
1863 192, 192, 192, 192, 192, 192, 192, 192, 192, 192, 192, 192, 192, 192, 192, 192,
1864 192, 192, 192, 192, 192, 192, 192, 192, 192, 192, 192, 192, 192, 192, 192, 192
1878 3, 3, 3, 3, 3, 3, 3, 3, 3, 0, 2, 3, 3, 2, 3, 3,
1879 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3,
1880 0, 0, 2, 0, 0, 0, 3, 0, 0, 0, 0, 0, 0, 16, 16, 0,
1881 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 0, 0, 3, 0, 3, 0,
1883 0, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20,
1884 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 0, 0, 0, 0, 20,
1885 0, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20,
1886 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 0, 0, 0, 0, 0,
1888 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20,
1889 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20,
1890 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20,
1891 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20,
1892 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20,
1893 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20,
1894 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20,
1895 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20
1898 #ifdef PUGIXML_WCHAR_MODE 1899 #define PUGI__IS_CHARTYPE_IMPL(c, ct, table) ((static_cast<unsigned int>(c) < 128 ? table[static_cast<unsigned int>(c)] : table[128]) & (ct)) 1901 #define PUGI__IS_CHARTYPE_IMPL(c, ct, table) (table[static_cast<unsigned char>(c)] & (ct)) 1904 #define PUGI__IS_CHARTYPE(c, ct) PUGI__IS_CHARTYPE_IMPL(c, ct, chartype_table) 1905 #define PUGI__IS_CHARTYPEX(c, ct) PUGI__IS_CHARTYPE_IMPL(c, ct, chartypex_table) 1909 unsigned int ui = 1;
1911 return *
reinterpret_cast<unsigned char*
>(&ui) == 1;
1918 if (
sizeof(
wchar_t) == 2)
1926 #define PUGI__SCANCHAR(ch) { if (offset >= size || data[offset] != ch) return false; offset++; } 1927 #define PUGI__SCANCHARTYPE(ct) { while (offset < size && PUGI__IS_CHARTYPE(data[offset], ct)) offset++; } 1930 if (size < 6 || !((data[0] ==
'<') & (data[1] ==
'?') & (data[2] ==
'x') & (data[3] ==
'm') & (data[4] ==
'l') &&
PUGI__IS_CHARTYPE(data[5],
ct_space)))
1934 for (
size_t i = 6; i + 1 < size; ++i)
1940 if (data[i] ==
'e' && data[i + 1] ==
'n')
1954 uint8_t delimiter = (offset < size && data[offset] ==
'"') ?
'"' :
'\'';
1958 size_t start = offset;
1960 out_encoding = data + offset;
1964 out_length = offset - start;
1974 #undef PUGI__SCANCHAR 1975 #undef PUGI__SCANCHARTYPE 1983 uint8_t d0 = data[0], d1 = data[1], d2 = data[2], d3 = data[3];
1990 if (d0 == 0xef && d1 == 0xbb && d2 == 0xbf)
return encoding_utf8;
2003 const uint8_t* enc = 0;
2004 size_t enc_length = 0;
2009 if (enc_length == 10
2010 && (enc[0] |
' ') ==
'i' && (enc[1] |
' ') ==
's' && (enc[2] |
' ') ==
'o' 2011 && enc[3] ==
'-' && enc[4] ==
'8' && enc[5] ==
'8' && enc[6] ==
'5' && enc[7] ==
'9' 2012 && enc[8] ==
'-' && enc[9] ==
'1')
2017 && (enc[0] |
' ') ==
'l' && (enc[1] |
' ') ==
'a' && (enc[2] |
' ') ==
't' 2018 && (enc[3] |
' ') ==
'i' && (enc[4] |
' ') ==
'n' 2041 const uint8_t* data =
static_cast<const uint8_t*
>(contents);
2048 size_t length = size /
sizeof(
char_t);
2052 out_buffer =
static_cast<char_t*
>(
const_cast<void*
>(contents));
2053 out_length = length;
2058 if (!buffer)
return false;
2061 memcpy(buffer, contents, length *
sizeof(
char_t));
2063 assert(length == 0);
2067 out_buffer = buffer;
2068 out_length = length + 1;
2074 #ifdef PUGIXML_WCHAR_MODE 2081 PUGI__FN bool convert_buffer_endian_swap(
char_t*& out_buffer,
size_t& out_length,
const void* contents,
size_t size,
bool is_mutable)
2083 const char_t* data =
static_cast<const char_t*
>(contents);
2084 size_t length = size /
sizeof(
char_t);
2090 convert_wchar_endian_swap(buffer, data, length);
2092 out_buffer = buffer;
2093 out_length = length;
2098 if (!buffer)
return false;
2100 convert_wchar_endian_swap(buffer, data, length);
2103 out_buffer = buffer;
2104 out_length = length + 1;
2112 const typename D::type* data =
static_cast<const typename D::type*
>(contents);
2113 size_t data_length = size /
sizeof(
typename D::type);
2116 size_t length = D::process(data, data_length, 0,
wchar_counter());
2120 if (!buffer)
return false;
2123 wchar_writer::value_type obegin =
reinterpret_cast<wchar_writer::value_type
>(buffer);
2124 wchar_writer::value_type oend = D::process(data, data_length, obegin,
wchar_writer());
2126 assert(oend == obegin + length);
2129 out_buffer = buffer;
2130 out_length = length + 1;
2141 if (encoding == wchar_encoding)
2145 if (need_endian_swap_utf(encoding, wchar_encoding))
2146 return convert_buffer_endian_swap(out_buffer, out_length, contents, size, is_mutable);
2157 return (native_encoding == encoding) ?
2167 return (native_encoding == encoding) ?
2176 assert(
false &&
"Invalid encoding");
2182 const typename D::type* data =
static_cast<const typename D::type*
>(contents);
2183 size_t data_length = size /
sizeof(
typename D::type);
2186 size_t length = D::process(data, data_length, 0,
utf8_counter());
2190 if (!buffer)
return false;
2193 uint8_t* obegin =
reinterpret_cast<uint8_t*
>(buffer);
2194 uint8_t* oend = D::process(data, data_length, obegin,
utf8_writer());
2196 assert(oend == obegin + length);
2199 out_buffer = buffer;
2200 out_length = length + 1;
2207 for (
size_t i = 0; i < size; ++i)
2216 const uint8_t* data =
static_cast<const uint8_t*
>(contents);
2217 size_t data_length = size;
2221 assert(prefix_length <= data_length);
2223 const uint8_t* postfix = data + prefix_length;
2224 size_t postfix_length = data_length - prefix_length;
2227 if (postfix_length == 0)
return get_mutable_buffer(out_buffer, out_length, contents, size, is_mutable);
2234 if (!buffer)
return false;
2237 memcpy(buffer, data, prefix_length);
2239 uint8_t* obegin =
reinterpret_cast<uint8_t*
>(buffer);
2242 assert(oend == obegin + length);
2245 out_buffer = buffer;
2246 out_length = length + 1;
2262 return (native_encoding == encoding) ?
2272 return (native_encoding == encoding) ?
2281 assert(
false &&
"Invalid encoding");
2295 uint8_t* begin =
reinterpret_cast<uint8_t*
>(buffer);
2298 assert(begin + size == end);
2303 #ifndef PUGIXML_NO_STL 2311 result.resize(size);
2314 if (size > 0)
as_utf8_end(&result[0], size, str, length);
2321 const uint8_t* data =
reinterpret_cast<const uint8_t*
>(str);
2327 std::basic_string<wchar_t> result;
2328 result.resize(length);
2333 wchar_writer::value_type begin =
reinterpret_cast<wchar_writer::value_type
>(&result[0]);
2336 assert(begin + length == end);
2344 template <
typename Header>
2350 size_t target_length =
strlength(target);
2353 if ((header & header_mask) == 0)
return target_length >= length;
2356 const size_t reuse_threshold = 32;
2358 return target_length >= length && (target_length < reuse_threshold || target_length - length < target_length / 2);
2361 template <
typename String,
typename Header>
2364 if (source_length == 0)
2373 header &= ~header_mask;
2380 memcpy(dest, source, source_length *
sizeof(
char_t));
2381 dest[source_length] = 0;
2389 if (!alloc->
reserve())
return false;
2393 if (!buf)
return false;
2396 memcpy(buf, source, source_length *
sizeof(
char_t));
2397 buf[source_length] = 0;
2404 header |= header_mask;
2427 memmove(end - size, end, reinterpret_cast<char*>(s) - reinterpret_cast<char*>(end));
2444 memmove(end - size, end, reinterpret_cast<char*>(s) - reinterpret_cast<char*>(end));
2460 unsigned int ucsc = 0;
2468 if (ch ==
';')
return stre;
2472 if (static_cast<unsigned int>(ch -
'0') <= 9)
2473 ucsc = 16 * ucsc + (ch -
'0');
2474 else if (static_cast<unsigned int>((ch |
' ') -
'a') <= 5)
2475 ucsc = 16 * ucsc + ((ch |
' ') -
'a' + 10);
2490 if (ch ==
';')
return stre;
2494 if (static_cast<unsigned int>(ch -
'0') <= 9)
2495 ucsc = 10 * ucsc + (ch -
'0');
2507 #ifdef PUGIXML_WCHAR_MODE 2508 s =
reinterpret_cast<char_t*
>(wchar_writer::any(reinterpret_cast<wchar_writer::value_type>(s), ucsc));
2513 g.
push(s, stre - s);
2523 if (*++stre ==
'p' && *++stre ==
';')
2528 g.
push(s, stre - s);
2532 else if (*stre ==
'p')
2534 if (*++stre ==
'o' && *++stre ==
's' && *++stre ==
';')
2539 g.
push(s, stre - s);
2548 if (*++stre ==
't' && *++stre ==
';')
2553 g.
push(s, stre - s);
2561 if (*++stre ==
't' && *++stre ==
';')
2566 g.
push(s, stre - s);
2574 if (*++stre ==
'u' && *++stre ==
'o' && *++stre ==
't' && *++stre ==
';')
2579 g.
push(s, stre - s);
2593 #define PUGI__ENDSWITH(c, e) ((c) == (e) || ((c) == 0 && endch == (e))) 2594 #define PUGI__SKIPWS() { while (PUGI__IS_CHARTYPE(*s, ct_space)) ++s; } 2595 #define PUGI__OPTSET(OPT) ( optmsk & (OPT) ) 2596 #define PUGI__PUSHNODE(TYPE) { cursor = append_new_node(cursor, *alloc, TYPE); if (!cursor) PUGI__THROW_ERROR(status_out_of_memory, s); } 2597 #define PUGI__POPNODE() { cursor = cursor->parent; } 2598 #define PUGI__SCANFOR(X) { while (*s != 0 && !(X)) ++s; } 2599 #define PUGI__SCANWHILE(X) { while (X) ++s; } 2600 #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; } } 2601 #define PUGI__ENDSEG() { ch = *s; *s = 0; ++s; } 2602 #define PUGI__THROW_ERROR(err, m) return error_offset = m, error_status = err, static_cast<char_t*>(0) 2603 #define PUGI__CHECK_ERROR(err, m) { if (*s == 0) PUGI__THROW_ERROR(err, m); } 2617 if (*s ==
'\n') g.
push(s, 1);
2619 else if (s[0] ==
'-' && s[1] ==
'-' &&
PUGI__ENDSWITH(s[2],
'>'))
2623 return s + (s[2] ==
'>' ? 3 : 2);
2645 if (*s ==
'\n') g.
push(s, 1);
2647 else if (s[0] ==
']' && s[1] ==
']' &&
PUGI__ENDSWITH(s[2],
'>'))
2679 if (opt_trim::value)
2687 else if (opt_eol::value && *s ==
'\r')
2691 if (*s ==
'\n') g.
push(s, 1);
2693 else if (opt_escape::value && *s ==
'&')
2701 if (opt_trim::value)
2718 switch (((optmask >> 4) & 3) | ((optmask >> 9) & 4))
2728 default: assert(
false);
return 0;
2755 if (*s == end_quote)
2757 char_t* str = g.
flush(s);
2770 char_t* str = s + 1;
2776 else if (opt_escape::value && *s ==
'&')
2796 if (*s == end_quote)
2808 if (*s ==
'\n') g.
push(s, 1);
2812 else if (opt_escape::value && *s ==
'&')
2832 if (*s == end_quote)
2838 else if (*s ==
'\r')
2842 if (*s ==
'\n') g.
push(s, 1);
2844 else if (opt_escape::value && *s ==
'&')
2864 if (*s == end_quote)
2870 else if (opt_escape::value && *s ==
'&')
2887 switch ((optmask >> 4) & 15)
2905 default: assert(
false);
return 0;
2911 xml_parse_result result;
2912 result.status = status;
2913 result.offset = offset;
2937 if (*s ==
'"' || *s ==
'\'')
2946 else if (s[0] ==
'<' && s[1] ==
'?')
2955 else if (s[0] ==
'<' && s[1] ==
'!' && s[2] ==
'-' && s[3] ==
'-')
2972 assert(s[0] ==
'<' && s[1] ==
'!' && s[2] ==
'[');
2977 if (s[0] ==
'<' && s[1] ==
'!' && s[2] ==
'[')
2983 else if (s[0] ==
']' && s[1] ==
']' && s[2] ==
'>')
3003 assert((s[0] ==
'<' || s[0] == 0) && s[1] ==
'!');
3008 if (s[0] ==
'<' && s[1] ==
'!' && s[2] !=
'-')
3013 s = parse_doctype_ignore(s);
3023 else if (s[0] ==
'<' || s[0] ==
'"' || s[0] ==
'\'')
3026 s = parse_doctype_primitive(s);
3079 s += (s[2] ==
'>' ? 3 : 2);
3087 if (*++s==
'C' && *++s==
'D' && *++s==
'A' && *++s==
'T' && *++s==
'A' && *++s ==
'[')
3120 s += (s[1] ==
'>' ? 2 : 1);
3124 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'))
3130 char_t* mark = s + 9;
3132 s = parse_doctype_group(s, endch);
3135 assert((*s == 0 && endch ==
'>') || *s ==
'>');
3144 cursor->value = mark;
3172 bool declaration = (target[0] |
' ') ==
'x' && (target[1] |
' ') ==
'm' && (target[2] |
' ') ==
'l' && target + 3 == s;
3188 cursor->name = target;
3222 cursor->value = value;
3239 s += (s[1] ==
'>' ? 2 : 1);
3243 ref_cursor = cursor;
3306 if (*s ==
'"' || *s ==
'\'')
3312 s = strconv_attribute(s, ch);
3335 else if (*s == 0 && endch ==
'>')
3348 else if (*s == 0 && endch ==
'>')
3380 char_t* name = cursor->name;
3410 s = parse_question(s, cursor, optmsk, endch);
3418 s = parse_exclamation(s, cursor, optmsk, endch);
3430 if (*s ==
'<' || !*s)
3441 if (s[0] !=
'<' || s[1] !=
'/' || cursor->first_child)
continue;
3463 s = strconv_pcdata(s);
3486 #ifdef PUGIXML_WCHAR_MODE 3487 static char_t* parse_skip_bom(char_t* s)
3489 unsigned int bom = 0xfeff;
3490 return (s[0] == static_cast<wchar_t>(bom)) ? s + 1 : s;
3495 return (s[0] ==
'\xef' && s[1] ==
'\xbb' && s[2] ==
'\xbf') ? s + 3 : s;
3505 node = node->next_sibling;
3518 xml_node_struct* last_root_child = root->first_child ? root->first_child->prev_sibling_c + 0 : 0;
3521 xml_parser parser(static_cast<xml_allocator*>(xmldoc));
3524 char_t endch = buffer[length - 1];
3525 buffer[length - 1] = 0;
3528 char_t* buffer_data = parse_skip_bom(buffer);
3531 parser.
parse_tree(buffer_data, root, optmsk, endch);
3534 assert(result.offset >= 0 && static_cast<size_t>(result.offset) <= length);
3543 xml_node_struct* first_root_child_parsed = last_root_child ? last_root_child->next_sibling + 0 : root->first_child+ 0;
3551 if (result.offset > 0 && static_cast<size_t>(result.offset) == length - 1 && endch == 0)
3562 #ifdef PUGIXML_WCHAR_MODE 3591 typename T::value_type end = D::process(reinterpret_cast<const typename D::type*>(data), length, dest, T());
3593 return static_cast<size_t>(end - dest) *
sizeof(*dest);
3600 typename T::value_type end = D::process(reinterpret_cast<const typename D::type*>(data), length, dest, T());
3604 for (
typename T::value_type i = dest; i != end; ++i)
3608 return static_cast<size_t>(end - dest) *
sizeof(*dest);
3611 #ifdef PUGIXML_WCHAR_MODE 3614 if (length < 1)
return 0;
3617 return (
sizeof(
wchar_t) == 2 && static_cast<unsigned int>(static_cast<uint16_t>(data[length - 1]) - 0xD800) < 0x400) ? length - 1 : length;
3625 convert_wchar_endian_swap(r_char, data, length);
3627 return length *
sizeof(
char_t);
3654 assert(
false &&
"Invalid encoding");
3660 if (length < 5)
return 0;
3662 for (
size_t i = 1; i <= 4; ++i)
3664 uint8_t ch =
static_cast<uint8_t
>(data[length - i]);
3667 if ((ch & 0xc0) != 0x80)
return length - i;
3693 assert(
false &&
"Invalid encoding");
3711 flush(buffer, bufsize);
3716 void flush(
const char_t* data,
size_t size)
3718 if (size == 0)
return;
3722 writer.write(data, size *
sizeof(char_t));
3726 size_t result =
convert_buffer_output(scratch.data_char, scratch.data_u8, scratch.data_u16, scratch.data_u32, data, size, encoding);
3727 assert(result <=
sizeof(scratch));
3730 writer.write(scratch.data_u8, result);
3740 if (length > bufcapacity)
3745 writer.write(data, length *
sizeof(char_t));
3750 while (length > bufcapacity)
3758 flush(data, chunk_size);
3762 length -= chunk_size;
3769 memcpy(buffer + bufsize, data, length *
sizeof(char_t));
3775 size_t offset = bufsize;
3777 if (offset + length <= bufcapacity)
3779 memcpy(buffer + offset, data, length *
sizeof(char_t));
3780 bufsize = offset + length;
3784 write_direct(data, length);
3791 size_t offset = bufsize;
3793 while (*data && offset < bufcapacity)
3794 buffer[offset++] = *data++;
3797 if (offset < bufcapacity)
3804 size_t length = offset - bufsize;
3807 bufsize = offset - extra;
3809 write_direct(data - extra,
strlength(data) + extra);
3815 size_t offset = bufsize;
3816 if (offset > bufcapacity - 1) offset = flush();
3818 buffer[offset + 0] = d0;
3819 bufsize = offset + 1;
3824 size_t offset = bufsize;
3825 if (offset > bufcapacity - 2) offset = flush();
3827 buffer[offset + 0] = d0;
3828 buffer[offset + 1] = d1;
3829 bufsize = offset + 2;
3832 void write(char_t d0, char_t d1, char_t d2)
3834 size_t offset = bufsize;
3835 if (offset > bufcapacity - 3) offset = flush();
3837 buffer[offset + 0] = d0;
3838 buffer[offset + 1] = d1;
3839 buffer[offset + 2] = d2;
3840 bufsize = offset + 3;
3843 void write(char_t d0, char_t d1, char_t d2, char_t d3)
3845 size_t offset = bufsize;
3846 if (offset > bufcapacity - 4) offset = flush();
3848 buffer[offset + 0] = d0;
3849 buffer[offset + 1] = d1;
3850 buffer[offset + 2] = d2;
3851 buffer[offset + 3] = d3;
3852 bufsize = offset + 4;
3855 void write(char_t d0, char_t d1, char_t d2, char_t d3, char_t d4)
3857 size_t offset = bufsize;
3858 if (offset > bufcapacity - 5) offset = flush();
3860 buffer[offset + 0] = d0;
3861 buffer[offset + 1] = d1;
3862 buffer[offset + 2] = d2;
3863 buffer[offset + 3] = d3;
3864 buffer[offset + 4] = d4;
3865 bufsize = offset + 5;
3868 void write(char_t d0, char_t d1, char_t d2, char_t d3, char_t d4, char_t d5)
3870 size_t offset = bufsize;
3871 if (offset > bufcapacity - 6) offset = flush();
3873 buffer[offset + 0] = d0;
3874 buffer[offset + 1] = d1;
3875 buffer[offset + 2] = d2;
3876 buffer[offset + 3] = d3;
3877 buffer[offset + 4] = d4;
3878 buffer[offset + 5] = d5;
3879 bufsize = offset + 6;
3888 #ifdef PUGIXML_MEMORY_OUTPUT_STACK 3889 PUGIXML_MEMORY_OUTPUT_STACK
3894 bufcapacity = bufcapacitybytes / (
sizeof(
char_t) + 4)
3897 char_t buffer[bufcapacity];
3901 uint8_t data_u8[4 * bufcapacity];
3902 uint16_t data_u16[2 * bufcapacity];
3903 uint32_t data_u32[bufcapacity];
3904 char_t data_char[bufcapacity];
3916 const char_t* prev = s;
3921 writer.
write_buffer(prev, static_cast<size_t>(s - prev));
3927 writer.
write(
'&',
'a',
'm',
'p',
';');
3931 writer.
write(
'&',
'l',
't',
';');
3935 writer.
write(
'&',
'g',
't',
';');
3939 writer.
write(
'&',
'q',
'u',
'o',
't',
';');
3944 unsigned int ch =
static_cast<unsigned int>(*s++);
3947 writer.
write(
'&',
'#', static_cast<char_t>((ch / 10) +
'0'), static_cast<char_t>((ch % 10) +
'0'),
';');
3965 writer.
write(
'<',
'!',
'[',
'C',
'D');
3966 writer.
write(
'A',
'T',
'A',
'[');
3968 const char_t* prev = s;
3971 while (*s && !(s[0] ==
']' && s[1] ==
']' && s[2] ==
'>')) ++s;
3976 writer.
write_buffer(prev, static_cast<size_t>(s - prev));
3978 writer.
write(
']',
']',
'>');
3985 switch (indent_length)
3989 for (
unsigned int i = 0; i < depth; ++i)
3990 writer.
write(indent[0]);
3996 for (
unsigned int i = 0; i < depth; ++i)
3997 writer.
write(indent[0], indent[1]);
4003 for (
unsigned int i = 0; i < depth; ++i)
4004 writer.
write(indent[0], indent[1], indent[2]);
4010 for (
unsigned int i = 0; i < depth; ++i)
4011 writer.
write(indent[0], indent[1], indent[2], indent[3]);
4017 for (
unsigned int i = 0; i < depth; ++i)
4025 writer.
write(
'<',
'!',
'-',
'-');
4029 const char_t* prev = s;
4032 while (*s && !(s[0] ==
'-' && (s[1] ==
'-' || s[1] == 0))) ++s;
4034 writer.
write_buffer(prev, static_cast<size_t>(s - prev));
4040 writer.
write(
'-',
' ');
4045 writer.
write(
'-',
'-',
'>');
4052 const char_t* prev = s;
4055 while (*s && !(s[0] ==
'?' && s[1] ==
'>')) ++s;
4057 writer.
write_buffer(prev, static_cast<size_t>(s - prev));
4061 assert(s[0] ==
'?' && s[1] ==
'>');
4063 writer.
write(
'?',
' ',
'>');
4071 const char_t* default_name =
PUGIXML_TEXT(
":anonymous");
4073 for (xml_attribute_struct* a = node->first_attribute; a; a = a->next_attribute)
4086 writer.
write_string(a->name ? a->name + 0 : default_name);
4087 writer.
write(
'=',
'"');
4098 const char_t* default_name =
PUGIXML_TEXT(
":anonymous");
4099 const char_t* name = node->name ? node->name + 0 : default_name;
4104 if (node->first_attribute)
4110 if (!node->first_child)
4114 writer.
write(
'>',
'<',
'/');
4125 writer.
write(
'/',
'>');
4143 if (!node->first_child)
4145 writer.
write(
'<',
'/');
4160 const char_t* default_name =
PUGIXML_TEXT(
":anonymous");
4161 const char_t* name = node->name ? node->name + 0 : default_name;
4163 writer.
write(
'<',
'/');
4170 const char_t* default_name =
PUGIXML_TEXT(
":anonymous");
4187 writer.
write(
'<',
'?');
4188 writer.
write_string(node->name ? node->name + 0 : default_name);
4196 writer.
write(
'?',
'>');
4200 writer.
write(
'<',
'?');
4201 writer.
write_string(node->name ? node->name + 0 : default_name);
4203 writer.
write(
'?',
'>');
4207 writer.
write(
'<',
'!',
'D',
'O',
'C');
4208 writer.
write(
'T',
'Y',
'P',
'E');
4220 assert(
false &&
"Invalid node type");
4266 node = node->first_child;
4275 if (node->first_child)
4277 node = node->first_child;
4290 while (node != root)
4292 if (node->next_sibling)
4294 node = node->next_sibling;
4298 node = node->parent;
4317 while (node != root);
4325 for (
xml_node_struct* child = node->first_child; child; child = child->next_sibling)
4338 for (xml_attribute_struct* a = node->first_attribute; a; a = a->next_attribute)
4366 if (parent.root() != child.root())
4370 xml_node cur = parent;
4383 template <
typename String,
typename Header>
4386 assert(!dest && (header & header_mask) == 0);
4390 if (alloc && (source_header & header_mask) == 0)
4408 for (xml_attribute_struct* sa = sn->first_attribute; sa; sa = sa->next_attribute)
4430 while (sit && sit != sn)
4441 if (sit->first_child)
4444 sit = sit->first_child;
4453 if (sit->next_sibling)
4455 sit = sit->next_sibling;
4486 const char_t* s = value;
4491 bool negative = (*s ==
'-');
4493 s += (*s ==
'+' || *s ==
'-');
4495 bool overflow =
false;
4497 if (s[0] ==
'0' && (s[1] |
' ') ==
'x')
4505 const char_t* start = s;
4509 if (static_cast<unsigned>(*s -
'0') < 10)
4510 result = result * 16 + (*s -
'0');
4511 else if (static_cast<unsigned>((*s |
' ') -
'a') < 6)
4512 result = result * 16 + ((*s |
' ') -
'a' + 10);
4519 size_t digits =
static_cast<size_t>(s - start);
4521 overflow = digits >
sizeof(U) * 2;
4529 const char_t* start = s;
4533 if (static_cast<unsigned>(*s -
'0') < 10)
4534 result = result * 10 + (*s -
'0');
4541 size_t digits =
static_cast<size_t>(s - start);
4545 const size_t max_digits10 =
sizeof(U) == 8 ? 20 :
sizeof(U) == 4 ? 10 : 5;
4546 const char_t max_lead =
sizeof(U) == 8 ?
'1' :
sizeof(U) == 4 ?
'4' :
'6';
4547 const size_t high_bit =
sizeof(U) * 8 - 1;
4549 overflow = digits >= max_digits10 && !(digits == max_digits10 && (*start < max_lead || (*start == max_lead && result >> high_bit)));
4556 return (overflow || result > ~minv + 1) ? minv : ~result + 1;
4558 return (overflow || result > 0 - minv) ? minv : 0 - result;
4562 return (overflow || result > maxv) ? maxv : result;
4567 return string_to_integer<unsigned int>(value,
static_cast<unsigned int>(INT_MIN), INT_MAX);
4572 return string_to_integer<unsigned int>(value, 0, UINT_MAX);
4577 #ifdef PUGIXML_WCHAR_MODE 4578 return wcstod(value, 0);
4580 return strtod(value, 0);
4586 #ifdef PUGIXML_WCHAR_MODE 4587 return static_cast<float>(wcstod(value, 0));
4589 return static_cast<float>(strtod(value, 0));
4596 char_t first = *value;
4599 return (first ==
'1' || first ==
't' || first ==
'T' || first ==
'y' || first ==
'Y');
4602 #ifdef PUGIXML_HAS_LONG_LONG 4603 PUGI__FN long long get_value_llong(
const char_t* value)
4605 return string_to_integer<unsigned long long>(value,
static_cast<unsigned long long>(LLONG_MIN), LLONG_MAX);
4608 PUGI__FN unsigned long long get_value_ullong(
const char_t* value)
4610 return string_to_integer<unsigned long long>(value, 0, ULLONG_MAX);
4616 char_t* result = end - 1;
4617 U rest = negative ? 0 - value : value;
4621 *result-- =
static_cast<char_t
>(
'0' + (rest % 10));
4626 assert(result >= begin);
4631 return result + !negative;
4635 template <
typename String,
typename Header>
4638 #ifdef PUGIXML_WCHAR_MODE 4640 assert(strlen(buf) <
sizeof(wbuf) /
sizeof(wbuf[0]));
4643 for (; buf[offset]; ++offset) wbuf[offset] = buf[offset];
4645 return strcpy_insitu(dest, header, header_mask, wbuf, offset);
4647 return strcpy_insitu(dest, header, header_mask, buf, strlen(buf));
4651 template <
typename U,
typename String,
typename Header>
4655 char_t* end = buf +
sizeof(buf) /
sizeof(buf[0]);
4658 return strcpy_insitu(dest, header, header_mask, begin, end - begin);
4661 template <
typename String,
typename Header>
4670 template <
typename String,
typename Header>
4679 template <
typename String,
typename Header>
4700 if (own && buffer != contents && contents) impl::xml_memory::deallocate(contents);
4703 if (own || buffer != contents) *out_buffer = buffer;
4709 xml_parse_result res = impl::xml_parser::parse(buffer, length, doc, root, options);
4712 res.encoding = buffer_encoding;
4720 #if defined(PUGI__MSVC_CRT_VERSION) && PUGI__MSVC_CRT_VERSION >= 1400 && !defined(_WIN32_WCE) 4722 typedef __int64 length_type;
4724 _fseeki64(file, 0, SEEK_END);
4725 length_type length = _ftelli64(file);
4726 _fseeki64(file, 0, SEEK_SET);
4727 #elif defined(__MINGW32__) && !defined(__NO_MINGW_LFS) && (!defined(__STRICT_ANSI__) || defined(__MINGW64_VERSION_MAJOR)) 4729 typedef off64_t length_type;
4731 fseeko64(file, 0, SEEK_END);
4732 length_type length = ftello64(file);
4733 fseeko64(file, 0, SEEK_SET);
4736 typedef long length_type;
4738 fseek(file, 0, SEEK_END);
4739 length_type length = ftell(file);
4740 fseek(file, 0, SEEK_SET);
4747 size_t result =
static_cast<size_t>(length);
4752 out_result = result;
4761 #ifdef PUGIXML_WCHAR_MODE 4764 if (encoding == wchar_encoding || need_endian_swap_utf(encoding, wchar_encoding))
4766 size_t length = size /
sizeof(
char_t);
4768 static_cast<char_t*
>(buffer)[length] = 0;
4769 return (length + 1) *
sizeof(
char_t);
4774 static_cast<char*
>(buffer)[size] = 0;
4791 size_t max_suffix_size =
sizeof(
char_t);
4798 size_t read_size = fread(contents, 1, size, file);
4800 if (read_size != size)
4808 return load_buffer_impl(doc, doc, contents,
zero_terminate_buffer(contents, size, real_encoding), options, real_encoding,
true,
true, out_buffer);
4816 #ifndef PUGIXML_NO_STL 4822 if (!memory)
return 0;
4858 while (!stream.eof())
4865 if (last) last = last->
next = chunk;
4866 else chunks.
data = last = chunk;
4869 stream.read(chunk->
data, static_cast<std::streamsize>(
sizeof(chunk->
data) /
sizeof(T)));
4870 chunk->
size =
static_cast<size_t>(stream.gcount()) *
sizeof(T);
4873 if (stream.bad() || (!stream.eof() && stream.fail()))
return status_io_error;
4877 total += chunk->
size;
4880 size_t max_suffix_size =
sizeof(
char_t);
4886 char* write = buffer;
4890 assert(write + chunk->size <= buffer + total);
4891 memcpy(write, chunk->data, chunk->size);
4892 write += chunk->size;
4895 assert(write == buffer + total);
4898 *out_buffer = buffer;
4907 typename std::basic_istream<T>::pos_type pos = stream.tellg();
4908 stream.seekg(0, std::ios::end);
4909 std::streamoff length = stream.tellg() - pos;
4915 size_t read_length =
static_cast<size_t>(length);
4917 if (static_cast<std::streamsize>(read_length) != length || length < 0)
return status_out_of_memory;
4919 size_t max_suffix_size =
sizeof(
char_t);
4925 stream.read(static_cast<T*>(buffer.
data), static_cast<std::streamsize>(read_length));
4928 if (stream.bad() || (!stream.eof() && stream.fail()))
return status_io_error;
4931 size_t actual_length =
static_cast<size_t>(stream.gcount());
4932 assert(actual_length <= read_length);
4934 *out_buffer = buffer.
release();
4935 *out_size = actual_length *
sizeof(T);
4950 if (stream.tellg() < 0)
4962 return load_buffer_impl(doc, doc, buffer,
zero_terminate_buffer(buffer, size, real_encoding), options, real_encoding,
true,
true, out_buffer);
4966 #if defined(PUGI__MSVC_CRT_VERSION) || defined(__BORLANDC__) || (defined(__MINGW32__) && (!defined(__STRICT_ANSI__) || defined(__MINGW64_VERSION_MAJOR))) 4969 return _wfopen(path, mode);
4982 if (!result)
return 0;
4997 if (!path_utf8)
return 0;
5000 char mode_ascii[4] = {0};
5001 for (
size_t i = 0; mode[i]; ++i) mode_ascii[i] = static_cast<char>(mode[i]);
5004 FILE* result = fopen(path_utf8, mode_ascii);
5015 if (!file)
return false;
5017 xml_writer_file writer(file);
5018 doc.save(writer, indent, flags, encoding);
5020 return ferror(file) == 0;
5048 size_t result = fwrite(data, 1, size, static_cast<FILE*>(
file));
5052 #ifndef PUGIXML_NO_STL 5066 narrow_stream->write(reinterpret_cast<const char*>(data), static_cast<std::streamsize>(size));
5071 assert(size %
sizeof(
wchar_t) == 0);
5073 wide_stream->write(reinterpret_cast<const wchar_t*>(data), static_cast<std::streamsize>(size /
sizeof(
wchar_t)));
5193 #ifdef PUGIXML_HAS_LONG_LONG 5194 PUGI__FN long long xml_attribute::as_llong(
long long def)
const 5199 PUGI__FN unsigned long long xml_attribute::as_ullong(
unsigned long long def)
const 5278 #ifdef PUGIXML_HAS_LONG_LONG 5294 if (!
_attr)
return false;
5301 if (!
_attr)
return false;
5308 if (!
_attr)
return false;
5315 if (!
_attr)
return false;
5322 if (!
_attr)
return false;
5329 if (!
_attr)
return false;
5336 if (!
_attr)
return false;
5343 if (!
_attr)
return false;
5350 if (!
_attr)
return false;
5355 #ifdef PUGIXML_HAS_LONG_LONG 5358 if (!
_attr)
return false;
5365 if (!
_attr)
return false;
5374 return (
bool)lhs && rhs;
5379 return (
bool)lhs || rhs;
5797 if (!alloc.reserve())
return xml_node();
5814 if (!alloc.reserve())
return xml_node();
5832 if (!alloc.reserve())
return xml_node();
5850 if (!alloc.reserve())
return xml_node();
5904 if (!alloc.reserve())
return xml_node();
5921 if (!alloc.reserve())
return xml_node();
5939 if (!alloc.reserve())
return xml_node();
5957 if (!alloc.reserve())
return xml_node();
5973 if (!alloc.reserve())
return xml_node();
5989 if (!alloc.reserve())
return xml_node();
6007 if (!alloc.reserve())
return xml_node();
6025 if (!alloc.reserve())
return xml_node();
6047 if (!alloc.reserve())
return false;
6065 if (!alloc.reserve())
return false;
6085 impl::xml_memory_page* page = 0;
6086 impl::xml_extra_buffer* extra =
static_cast<impl::xml_extra_buffer*
>(doc->allocate_memory(
sizeof(impl::xml_extra_buffer) +
sizeof(
void*), page));
6091 #ifdef PUGIXML_COMPACT 6094 extra =
reinterpret_cast<impl::xml_extra_buffer*
>((
reinterpret_cast<uintptr_t
>(extra) + (
sizeof(
void*) - 1)) & ~(
sizeof(
void*) - 1));
6099 extra->next = doc->extra_buffers;
6100 doc->extra_buffers = extra;
6103 impl::name_null_sentry sentry(
_root);
6135 #ifndef PUGIXML_NO_STL 6144 offset += (i !=
_root);
6149 result.resize(offset);
6154 result[--offset] = delimiter;
6161 memcpy(&result[offset], j->name, length *
sizeof(char_t));
6165 assert(offset == 0);
6175 if (!
_root || !path_[0])
return found;
6177 if (path_[0] == delimiter)
6180 found = found.
root();
6184 const char_t* path_segment = path_;
6186 while (*path_segment == delimiter) ++path_segment;
6188 const char_t* path_segment_end = path_segment;
6190 while (*path_segment_end && *path_segment_end != delimiter) ++path_segment_end;
6192 if (path_segment == path_segment_end)
return found;
6194 const char_t* next_segment = path_segment_end;
6196 while (*next_segment == delimiter) ++next_segment;
6198 if (*path_segment ==
'.' && path_segment + 1 == path_segment_end)
6200 else if (*path_segment ==
'.' && *(path_segment+1) ==
'.' && path_segment + 2 == path_segment_end)
6206 if (j->name &&
impl::strequalrange(j->name, path_segment, static_cast<size_t>(path_segment_end - path_segment)))
6208 xml_node subsearch =
xml_node(j).first_element_by_path(next_segment, delimiter);
6210 if (subsearch)
return subsearch;
6223 if (!walker.
begin(arg_begin))
return false;
6234 if (!walker.
for_each(arg_for_each))
6256 while (cur && cur !=
_root);
6259 assert(walker.
_depth == -1);
6262 return walker.
end(arg_end);
6279 impl::xml_buffered_writer buffered_writer(writer, encoding);
6283 buffered_writer.flush();
6286 #ifndef PUGIXML_NO_STL 6291 print(writer, indent, flags, encoding, depth);
6294 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 6304 if (!
_root)
return -1;
6309 if (!doc.buffer || doc.extra_buffers)
return -1;
6328 assert(
false &&
"Invalid node type");
6336 return (
bool)lhs && rhs;
6341 return (
bool)lhs || rhs;
6392 return _data() == 0;
6444 #ifdef PUGIXML_HAS_LONG_LONG 6445 PUGI__FN long long xml_text::as_llong(
long long def)
const 6449 return (d && d->
value) ? impl::get_value_llong(d->
value) : def;
6452 PUGI__FN unsigned long long xml_text::as_ullong(
unsigned long long def)
const 6456 return (d && d->
value) ? impl::get_value_ullong(d->
value) : def;
6516 #ifdef PUGIXML_HAS_LONG_LONG 6580 #ifdef PUGIXML_HAS_LONG_LONG 6602 return (
bool)lhs && rhs;
6607 return (
bool)lhs || rhs;
6825 case status_bad_pi:
return "Error parsing document declaration/processing instruction";
6839 default:
return "Unknown error";
6853 #ifdef PUGIXML_HAS_MOVE 6862 if (
this == &rhs)
return *
this;
6890 #ifdef PUGIXML_COMPACT 6892 const size_t page_offset =
sizeof(
void*);
6894 const size_t page_offset = 0;
6901 impl::xml_memory_page* page = impl::xml_memory_page::construct(
_memory);
6907 #ifdef PUGIXML_COMPACT 6909 page->compact_page_marker =
reinterpret_cast<uint32_t*
>(
static_cast<void*
>(
reinterpret_cast<char*
>(page) +
sizeof(impl::xml_memory_page)));
6910 *page->compact_page_marker =
sizeof(impl::xml_memory_page);
6914 _root =
new (
reinterpret_cast<char*
>(page) +
sizeof(impl::xml_memory_page) + page_offset) impl::xml_document_struct(page);
6918 page->allocator =
static_cast<impl::xml_document_struct*
>(
_root);
6921 #ifdef PUGIXML_COMPACT 6922 page->allocator->_hash = &
static_cast<impl::xml_document_struct*
>(
_root)->hash;
6926 assert(reinterpret_cast<char*>(
_root) +
sizeof(impl::xml_document_struct) <=
_memory +
sizeof(
_memory));
6936 impl::xml_memory::deallocate(
_buffer);
6941 for (impl::xml_extra_buffer* extra = static_cast<impl::xml_document_struct*>(
_root)->extra_buffers; extra; extra = extra->next)
6943 if (extra->buffer) impl::xml_memory::deallocate(extra->buffer);
6948 assert(root_page && !root_page->prev);
6949 assert(reinterpret_cast<char*>(root_page) >=
_memory && reinterpret_cast<char*>(root_page) <
_memory +
sizeof(
_memory));
6951 for (impl::xml_memory_page* page = root_page->next; page; )
6953 impl::xml_memory_page* next = page->next;
6955 impl::xml_allocator::deallocate_page(page);
6960 #ifdef PUGIXML_COMPACT 6962 static_cast<impl::xml_document_struct*
>(
_root)->hash.clear();
6968 #ifdef PUGIXML_HAS_MOVE 6971 impl::xml_document_struct* doc =
static_cast<impl::xml_document_struct*
>(
_root);
6972 impl::xml_document_struct* other =
static_cast<impl::xml_document_struct*
>(rhs.
_root);
6977 #ifdef PUGIXML_COMPACT 6980 if (other_first_child)
6982 size_t other_children = 0;
6990 if (!other->_hash->reserve(other_children + 1))
6992 #ifdef PUGIXML_NO_EXCEPTIONS 6995 throw std::bad_alloc();
7002 doc->_root = other->_root;
7003 doc->_busy_size = other->_busy_size;
7006 doc->buffer = other->buffer;
7007 doc->extra_buffers = other->extra_buffers;
7010 #ifdef PUGIXML_COMPACT 7012 doc->hash = other->hash;
7013 doc->_hash = &doc->hash;
7021 assert(doc_page && !doc_page->prev && !doc_page->next);
7024 assert(other_page && !other_page->prev);
7027 if (impl::xml_memory_page* page = other_page->next)
7029 assert(page->prev == other_page);
7031 page->prev = doc_page;
7033 doc_page->next = page;
7034 other_page->next = 0;
7038 for (impl::xml_memory_page* page = doc_page->next; page; page = page->next)
7040 assert(page->allocator == other);
7042 page->allocator = doc;
7044 #ifdef PUGIXML_COMPACT 7046 if (page->compact_shared_parent == other)
7047 page->compact_shared_parent = doc;
7052 assert(!doc->first_child);
7054 doc->first_child = other_first_child;
7058 #ifdef PUGIXML_COMPACT 7060 assert(node->parent == other || node->parent == doc);
7064 assert(node->parent == other);
7070 new (other) impl::xml_document_struct(
PUGI__GETPAGE(other));
7075 #ifndef PUGIXML_NO_STL 7094 #ifdef PUGIXML_WCHAR_MODE 7112 using impl::auto_deleter;
7122 using impl::auto_deleter;
7151 impl::xml_buffered_writer buffered_writer(writer, encoding);
7156 #ifdef PUGIXML_WCHAR_MODE 7157 unsigned int bom = 0xfeff;
7158 buffered_writer.write(static_cast<wchar_t>(bom));
7160 buffered_writer.write(
'\xef',
'\xbb',
'\xbf');
7166 buffered_writer.write_string(
PUGIXML_TEXT(
"<?xml version=\"1.0\""));
7168 buffered_writer.write(
'?',
'>');
7169 if (!(flags &
format_raw)) buffered_writer.write(
'\n');
7174 buffered_writer.flush();
7177 #ifndef PUGIXML_NO_STL 7182 save(writer, indent, flags, encoding);
7185 PUGI__FN void xml_document::save(std::basic_ostream<
wchar_t, std::char_traits<wchar_t> >& stream,
const char_t* indent,
unsigned int flags)
const 7195 using impl::auto_deleter;
7203 using impl::auto_deleter;
7220 #ifndef PUGIXML_NO_STL 7248 impl::xml_memory::allocate = allocate;
7249 impl::xml_memory::deallocate = deallocate;
7254 return impl::xml_memory::allocate;
7259 return impl::xml_memory::deallocate;
7263 #if !defined(PUGIXML_NO_STL) && (defined(_MSC_VER) || defined(__ICC)) 7269 return std::bidirectional_iterator_tag();
7274 return std::bidirectional_iterator_tag();
7279 return std::bidirectional_iterator_tag();
7284 #if !defined(PUGIXML_NO_STL) && defined(__SUNPRO_CC) 7290 return std::bidirectional_iterator_tag();
7295 return std::bidirectional_iterator_tag();
7300 return std::bidirectional_iterator_tag();
7305 #ifndef PUGIXML_NO_XPATH 7310 template <
typename T>
bool operator()(
const T& lhs,
const T& rhs)
const 7318 template <
typename T>
bool operator()(
const T& lhs,
const T& rhs)
const 7326 template <
typename T>
bool operator()(
const T& lhs,
const T& rhs)
const 7334 template <
typename T>
bool operator()(
const T& lhs,
const T& rhs)
const 7340 template <
typename T>
void swap(T& lhs, T& rhs)
7351 for (I it = begin + 1; it !=
end; ++it)
7352 if (pred(*it, *result))
7360 while (end - begin > 1)
swap(*begin++, *--end);
7366 while (end - begin > 1 && *begin != *(begin + 1)) begin++;
7368 if (begin == end)
return begin;
7374 while (begin != end)
7376 if (*begin != *write)
7377 *++write = *begin++;
7391 for (T* it = begin + 1; it !=
end; ++it)
7397 while (hole > begin && pred(val, *(hole - 1)))
7399 *hole = *(hole - 1);
7408 template <
typename I,
typename Pred> I
median3(I first, I middle, I last,
const Pred& pred)
7410 if (pred(*middle, *first))
swap(middle, first);
7411 if (pred(*last, *middle))
swap(last, middle);
7412 if (pred(*middle, *first))
swap(middle, first);
7417 template <
typename T,
typename Pred>
void partition3(T*
begin, T*
end, T pivot,
const Pred& pred, T** out_eqbeg, T** out_eqend)
7426 if (pred(*lt, pivot))
7428 else if (*lt == pivot)
7437 for (T* it = begin; it != eq; ++it)
7438 swap(*it, *--eqbeg);
7444 template <
typename I,
typename Pred>
void sort(I
begin, I
end,
const Pred& pred)
7447 while (end - begin > 16)
7450 I middle = begin + (end -
begin) / 2;
7451 I median =
median3(begin, middle, end - 1, pred);
7455 partition3(begin, end, *median, pred, &eqbeg, &eqend);
7458 if (eqbeg - begin > end - eqend)
7460 sort(eqend, end, pred);
7465 sort(begin, eqbeg, pred);
7478 #ifdef PUGIXML_MEMORY_XPATH_PAGE_SIZE 7479 PUGIXML_MEMORY_XPATH_PAGE_SIZE
7512 size = (size + xpath_memory_block_alignment - 1) & ~(xpath_memory_block_alignment - 1);
7514 if (_root_size + size <= _root->capacity)
7516 void* buf = &_root->
data[0] + _root_size;
7523 size_t block_capacity_base =
sizeof(_root->
data);
7524 size_t block_capacity_req = size + block_capacity_base / 4;
7525 size_t block_capacity = (block_capacity_base > block_capacity_req) ? block_capacity_base : block_capacity_req;
7532 if (_error) *_error =
true;
7549 old_size = (old_size + xpath_memory_block_alignment - 1) & ~(xpath_memory_block_alignment - 1);
7550 new_size = (new_size + xpath_memory_block_alignment - 1) & ~(xpath_memory_block_alignment - 1);
7553 assert(ptr == 0 || static_cast<char*>(ptr) + old_size == &_root->
data[0] + _root_size);
7556 if (ptr && _root_size - old_size + new_size <= _root->capacity)
7558 _root_size = _root_size - old_size + new_size;
7563 void* result = allocate(new_size);
7564 if (!result)
return 0;
7570 assert(new_size >= old_size);
7571 memcpy(result, ptr, old_size);
7574 assert(_root->
data == result);
7575 assert(_root->
next);
7598 while (cur != state.
_root)
7608 _root = state.
_root;
7636 _target->revert(_state);
7659 blocks[0].
next = blocks[1].
next = 0;
7684 char_t* result =
static_cast<char_t*
>(alloc->
allocate((length + 1) *
sizeof(char_t)));
7685 if (!result)
return 0;
7687 memcpy(result,
string, length *
sizeof(char_t));
7693 xpath_string(
const char_t* buffer,
bool uses_heap_,
size_t length_heap): _buffer(buffer), _uses_heap(uses_heap_), _length_heap(length_heap)
7705 assert(begin <= end && *end == 0);
7707 return xpath_string(begin,
true, static_cast<size_t>(end - begin));
7712 assert(begin <= end);
7717 size_t length =
static_cast<size_t>(end -
begin);
7718 const char_t* data = duplicate_string(begin, length, alloc);
7720 return data ?
xpath_string(data,
true, length) : xpath_string();
7733 if (!*_buffer && !_uses_heap && !o.
_uses_heap)
7740 size_t target_length = length();
7741 size_t source_length = o.
length();
7742 size_t result_length = target_length + source_length;
7745 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)));
7746 if (!result)
return;
7749 if (!_uses_heap) memcpy(result, _buffer, target_length *
sizeof(char_t));
7752 memcpy(result + target_length, o.
_buffer, source_length *
sizeof(char_t));
7753 result[result_length] = 0;
7758 _length_heap = result_length;
7769 return _uses_heap ? _length_heap :
strlength(_buffer);
7778 const char_t* data_ = duplicate_string(_buffer, length_, alloc);
7780 if (!data_)
return 0;
7784 _length_heap = length_;
7787 return const_cast<char_t*
>(
_buffer);
7792 return *_buffer == 0;
7815 while (*pattern && *
string == *pattern)
7821 return *pattern == 0;
7826 #ifdef PUGIXML_WCHAR_MODE 7827 return wcschr(s, c);
7829 return strchr(s, c);
7835 #ifdef PUGIXML_WCHAR_MODE 7837 return (*p == 0) ? s : wcsstr(s, p);
7839 return strstr(s, p);
7846 return static_cast<unsigned int>(ch -
'A') < 26 ? static_cast<char_t>(ch |
' ') : ch;
7876 while (cur && cur != n)
7881 if (cur.first_child())
7882 cur = cur.first_child();
7883 else if (cur.next_sibling())
7884 cur = cur.next_sibling();
7887 while (!cur.next_sibling() && cur != n)
7890 if (cur != n) cur = cur.next_sibling();
7905 assert(ln->parent == rn->parent);
7908 if (!ln->parent)
return ln < rn;
7916 if (ls == rn)
return true;
7917 if (rs == ln)
return false;
7919 ls = ls->next_sibling;
7920 rs = rs->next_sibling;
7933 while (lp && rp && lp->parent != rp->parent)
7943 bool left_higher = !lp;
7958 if (ln == rn)
return left_higher;
7961 while (ln->parent != rn->parent)
7972 while (node && node != parent) node = node->parent;
7974 return parent && node ==
parent;
7992 xml_attribute_struct* attr = xnode.attribute().internal_object();
8010 bool operator()(
const xpath_node& lhs,
const xpath_node& rhs)
const 8016 if (lo && ro)
return lo < ro;
8019 xml_node ln = lhs.node(), rn = rhs.node();
8022 if (lhs.attribute() && rhs.attribute())
8025 if (lhs.parent() == rhs.parent())
8028 for (xml_attribute a = lhs.attribute(); a; a = a.next_attribute())
8029 if (a == rhs.attribute())
8039 else if (lhs.attribute())
8042 if (lhs.parent() == rhs.node())
return false;
8046 else if (rhs.attribute())
8049 if (rhs.parent() == lhs.node())
return true;
8054 if (ln == rn)
return false;
8056 if (!ln || !rn)
return ln < rn;
8058 return node_is_before(ln.internal_object(), rn.internal_object());
8064 bool operator()(
const xpath_node& lhs,
const xpath_node& rhs)
const 8066 if (lhs.attribute())
return rhs.attribute() ? lhs.attribute() < rhs.attribute() :
true;
8067 else return rhs.attribute() ? false : lhs.node() < rhs.node();
8073 #if defined(__STDC_IEC_559__) || ((FLT_RADIX - 0 == 2) && (FLT_MAX_EXP - 0 == 128) && (FLT_MANT_DIG - 0 == 24)) 8075 typedef uint32_t UI;
8076 union {
float f; UI i; } u;
8081 const volatile double zero = 0.0;
8088 #if defined(PUGI__MSVC_CRT_VERSION) || defined(__BORLANDC__) 8089 return !!_isnan(value);
8090 #elif defined(fpclassify) && defined(FP_NAN) 8091 return fpclassify(value) == FP_NAN;
8094 const volatile double v =
value;
8101 #if defined(PUGI__MSVC_CRT_VERSION) || defined(__BORLANDC__) 8102 if (_finite(value))
return (value == 0) ?
PUGIXML_TEXT(
"0") : 0;
8105 #elif defined(fpclassify) && defined(FP_NAN) && defined(FP_INFINITE) && defined(FP_ZERO) 8106 switch (fpclassify(value))
8122 const volatile double v =
value;
8133 return (value != 0 && !
is_nan(value));
8138 while (begin != end && end[-1] ==
'0') end--;
8144 #if defined(PUGI__MSVC_CRT_VERSION) && PUGI__MSVC_CRT_VERSION >= 1400 && !defined(_WIN32_WCE) 8149 _ecvt_s(buffer,
sizeof(buffer), value, DBL_DIG + 1, &exponent, &sign);
8155 *out_mantissa = buffer;
8156 *out_exponent = exponent;
8165 char* exponent_string = strchr(buffer,
'e');
8166 assert(exponent_string);
8168 int exponent = atoi(exponent_string + 1);
8171 char* mantissa = buffer[0] ==
'-' ? buffer + 1 : buffer;
8172 assert(mantissa[0] !=
'0' && mantissa[1] ==
'.');
8175 mantissa[1] = mantissa[0];
8183 *out_mantissa = mantissa;
8184 *out_exponent = exponent;
8195 char mantissa_buffer[32];
8202 size_t result_size = strlen(mantissa_buffer) + (exponent > 0 ? exponent : -exponent) + 4;
8203 char_t* result =
static_cast<char_t*
>(alloc->
allocate(
sizeof(char_t) * result_size));
8210 if (value < 0) *s++ =
'-';
8219 while (exponent > 0)
8221 assert(*mantissa == 0 || static_cast<unsigned int>(*mantissa -
'0') <= 9);
8222 *s++ = *mantissa ? *mantissa++ :
'0';
8234 while (exponent < 0)
8243 assert(static_cast<unsigned int>(*mantissa -
'0') <= 9);
8249 assert(s < result + result_size);
8261 if (*
string ==
'-') ++string;
8263 if (!*
string)
return false;
8282 return *
string == 0;
8291 #ifdef PUGIXML_WCHAR_MODE 8292 return wcstod(
string, 0);
8294 return strtod(
string, 0);
8300 size_t length =
static_cast<size_t>(end -
begin);
8301 char_t* scratch = buffer;
8303 if (length >=
sizeof(buffer) /
sizeof(buffer[0]))
8307 if (!scratch)
return false;
8311 memcpy(scratch, begin, length *
sizeof(char_t));
8312 scratch[length] = 0;
8324 return floor(value + 0.5);
8331 return (value >= -0.5 && value <= 0) ? ceil(value) : floor(value + 0.5);
8336 return node.attribute() ? node.attribute().name() : node.node().name();
8344 return p ? p + 1 :
name;
8354 const char_t* pos =
find_char(name,
':');
8356 prefix = pos ?
name : 0;
8357 prefix_length = pos ?
static_cast<size_t>(pos -
name) : 0;
8362 const char_t*
name = a.name();
8366 return prefix ? name[5] ==
':' &&
strequalrange(name + 6, prefix, prefix_length) : name[5] == 0;
8378 xml_attribute a = p.find_attribute(pred);
8380 if (a)
return a.value();
8401 if (a)
return a.
value();
8416 char_t* write = buffer;
8418 for (char_t* it = buffer; *it; )
8428 if (write != buffer) *write++ =
' ';
8444 char_t* write = buffer;
8450 const char_t* pos =
find_char(from, ch);
8454 else if (static_cast<size_t>(pos - from) < to_length)
8455 *write++ = to[pos - from];
8466 unsigned char table[128] = {0};
8470 unsigned int fc =
static_cast<unsigned int>(*from);
8471 unsigned int tc =
static_cast<unsigned int>(*to);
8473 if (fc >= 128 || tc >= 128)
8478 table[fc] =
static_cast<unsigned char>(tc ? tc : 128);
8484 for (
int i = 0; i < 128; ++i)
8486 table[i] =
static_cast<unsigned char>(i);
8488 void* result = alloc->
allocate(
sizeof(table));
8489 if (!result)
return 0;
8491 memcpy(result, table,
sizeof(table));
8493 return static_cast<unsigned char*
>(result);
8498 char_t* write = buffer;
8502 char_t ch = *buffer++;
8503 unsigned int index =
static_cast<unsigned int>(ch);
8507 unsigned char code = table[index];
8511 *write =
static_cast<char_t
>(code);
8512 write += 1 - (code >> 7);
8581 unsigned int result = 0;
8585 result +=
static_cast<unsigned int>(*str++);
8586 result += result << 10;
8587 result ^= result >> 6;
8590 result += result << 3;
8591 result ^= result >> 11;
8592 result += result << 15;
8600 if (length == 0)
return 0;
8604 if (!memory)
return 0;
8606 T* result =
new (memory) T();
8608 memcpy(result->name, name, (length + 1) *
sizeof(char_t));
8618 return new_xpath_variable<xpath_variable_node_set>(
name);
8621 return new_xpath_variable<xpath_variable_number>(
name);
8624 return new_xpath_variable<xpath_variable_string>(
name);
8627 return new_xpath_variable<xpath_variable_boolean>(
name);
8661 assert(
false &&
"Invalid variable type");
8667 switch (rhs->type())
8670 return lhs->set(static_cast<const xpath_variable_node_set*>(rhs)->value);
8673 return lhs->set(static_cast<const xpath_variable_number*>(rhs)->value);
8676 return lhs->set(static_cast<const xpath_variable_string*>(rhs)->value);
8679 return lhs->set(static_cast<const xpath_variable_boolean*>(rhs)->value);
8682 assert(
false &&
"Invalid variable type");
8689 size_t length =
static_cast<size_t>(end -
begin);
8690 char_t* scratch = buffer;
8692 if (length >=
sizeof(buffer) /
sizeof(buffer[0]))
8696 if (!scratch)
return false;
8700 memcpy(scratch, begin, length *
sizeof(char_t));
8701 scratch[length] = 0;
8703 *out_result =
set->get(scratch);
8716 if (end - begin < 2)
8721 bool first = cmp(begin[0], begin[1]);
8723 for (
const xpath_node* it = begin + 1; it + 1 <
end; ++it)
8724 if (cmp(it[0], it[1]) != first)
8748 if (type != order)
reverse(begin, end);
8755 if (begin == end)
return xpath_node();
8769 assert(
false &&
"Invalid node set type");
8770 return xpath_node();
8799 return _begin == _end;
8804 return static_cast<size_t>(_end - _begin);
8819 push_back_grow(node, alloc);
8824 if (begin_ == end_)
return;
8826 size_t size_ =
static_cast<size_t>(_end - _begin);
8827 size_t capacity =
static_cast<size_t>(_eos - _begin);
8828 size_t count =
static_cast<size_t>(end_ - begin_);
8830 if (size_ + count > capacity)
8833 xpath_node* data =
static_cast<xpath_node*
>(alloc->
reallocate(_begin, capacity *
sizeof(xpath_node), (size_ + count) *
sizeof(xpath_node)));
8838 _end = data + size_;
8839 _eos = data + size_ + count;
8842 memcpy(_end, begin_, count *
sizeof(xpath_node));
8848 _type =
xpath_sort(_begin, _end, _type,
false);
8853 assert(_begin <= pos && pos <= _end);
8863 _end =
unique(_begin, _end);
8879 size_t capacity =
static_cast<size_t>(_eos - _begin);
8882 size_t new_capacity = capacity + capacity / 2 + 1;
8885 xpath_node* data =
static_cast<xpath_node*
>(alloc->
reallocate(_begin, capacity *
sizeof(xpath_node), new_capacity *
sizeof(xpath_node)));
8890 _end = data + capacity;
8891 _eos = data + new_capacity;
8904 xpath_context(
const xpath_node& n_,
size_t position_,
size_t size_): n(n_), position(position_), size(size_)
8951 size_t length =
static_cast<size_t>(end -
begin);
8978 const char_t* cur = _cur;
8983 _cur_lexeme_pos = cur;
8992 if (*(cur+1) ==
'=')
9005 if (*(cur+1) ==
'=')
9018 if (*(cur+1) ==
'=')
9064 _cur_lexeme_contents.
begin = cur;
9075 _cur_lexeme_contents.
end = cur;
9117 if (*(cur+1) ==
'/')
9130 if (*(cur+1) ==
'.')
9137 _cur_lexeme_contents.
begin = cur;
9143 _cur_lexeme_contents.
end = cur;
9163 char_t terminator = *cur;
9167 _cur_lexeme_contents.
begin = cur;
9168 while (*cur && *cur != terminator) cur++;
9169 _cur_lexeme_contents.
end = cur;
9183 if (*(cur+1) ==
':')
9197 _cur_lexeme_contents.
begin = cur;
9208 _cur_lexeme_contents.
end = cur;
9214 _cur_lexeme_contents.
begin = cur;
9232 _cur_lexeme_contents.
end = cur;
9252 return _cur_lexeme_pos;
9259 return _cur_lexeme_contents;
9432 return comp(ls, rs);
9442 for (
const xpath_node* li = ls.
begin(); li != ls.
end(); ++li)
9443 for (
const xpath_node* ri = rs.
begin(); ri != rs.
end(); ++ri)
9470 for (
const xpath_node* ri = rs.
begin(); ri != rs.
end(); ++ri)
9487 for (
const xpath_node* ri = rs.
begin(); ri != rs.
end(); ++ri)
9499 assert(
false &&
"Wrong types");
9521 for (
const xpath_node* li = ls.
begin(); li != ls.
end(); ++li)
9527 for (
const xpath_node* ri = rs.
begin(); ri != rs.
end(); ++ri)
9545 for (
const xpath_node* ri = rs.
begin(); ri != rs.
end(); ++ri)
9562 for (
const xpath_node* li = ls.
begin(); li != ls.
end(); ++li)
9574 assert(
false &&
"Wrong types");
9581 assert(ns.
size() >= first);
9585 size_t size = ns.
size() - first;
9587 xpath_node* last = ns.
begin() + first;
9590 for (xpath_node* it = last; it != ns.
end(); ++it, ++i)
9607 assert(ns.
size() >= first);
9611 size_t size = ns.
size() - first;
9613 xpath_node* last = ns.
begin() + first;
9616 for (xpath_node* it = last; it != ns.
end(); ++it, ++i)
9633 assert(ns.
size() >= first);
9636 size_t size = ns.
size() - first;
9638 xpath_node* last = ns.
begin() + first;
9644 if (er >= 1.0 && er <= size)
9646 size_t eri =
static_cast<size_t>(er);
9650 xpath_node r = last[eri - 1];
9661 if (ns.
size() == first)
return;
9666 apply_predicate_number_const(ns, first, _right, stack);
9668 apply_predicate_number(ns, first, _right, stack, once);
9670 apply_predicate_boolean(ns, first, _right, stack, once);
9675 if (ns.
size() == first)
return;
9677 bool last_once = eval_once(ns.
type(), eval);
9680 pred->apply_predicate(ns, first, stack, !pred->_next && last_once);
9792 assert(
false &&
"Unknown axis");
9800 const axis_t axis = T::axis;
9806 for (xml_attribute_struct* a = n->first_attribute; a; a = a->next_attribute)
9807 if (step_push(ns, a, n, alloc) & once)
9816 if (step_push(ns, c, alloc) & once)
9826 if (step_push(ns, n, alloc) & once)
9833 if (step_push(ns, cur, alloc) & once)
9836 if (cur->first_child)
9837 cur = cur->first_child;
9840 while (!cur->next_sibling)
9844 if (cur == n)
return;
9847 cur = cur->next_sibling;
9857 if (step_push(ns, c, alloc) & once)
9865 for (
xml_node_struct* c = n->prev_sibling_c; c->next_sibling; c = c->prev_sibling_c)
9866 if (step_push(ns, c, alloc) & once)
9877 while (!cur->next_sibling)
9884 cur = cur->next_sibling;
9888 if (step_push(ns, cur, alloc) & once)
9891 if (cur->first_child)
9892 cur = cur->first_child;
9895 while (!cur->next_sibling)
9902 cur = cur->next_sibling;
9914 while (!cur->prev_sibling_c->next_sibling)
9921 cur = cur->prev_sibling_c;
9925 if (cur->first_child)
9926 cur = cur->first_child->prev_sibling_c;
9930 if (step_push(ns, cur, alloc) & once)
9933 while (!cur->prev_sibling_c->next_sibling)
9940 if (step_push(ns, cur, alloc) & once)
9944 cur = cur->prev_sibling_c;
9955 if (step_push(ns, n, alloc) & once)
9962 if (step_push(ns, cur, alloc) & once)
9973 step_push(ns, n, alloc);
9981 step_push(ns, n->parent, alloc);
9987 assert(
false &&
"Unimplemented axis");
9993 const axis_t axis = T::axis;
10001 if (step_push(ns, a, p, alloc) & once)
10008 if (step_push(ns, cur, alloc) & once)
10021 step_push(ns, a, p, alloc);
10032 if (cur->first_child)
10033 cur = cur->first_child;
10036 while (!cur->next_sibling)
10043 cur = cur->next_sibling;
10046 if (step_push(ns, cur, alloc) & once)
10055 step_push(ns, p, alloc);
10063 step_fill(ns, p, alloc, once, v);
10068 assert(
false &&
"Unimplemented axis");
10074 const axis_t axis = T::axis;
10078 step_fill(ns, xn.node().internal_object(), alloc, once, v);
10079 else if (axis_has_attributes && xn.attribute() && xn.parent())
10080 step_fill(ns, xn.attribute().internal_object(), xn.parent().internal_object(), alloc, once, v);
10085 const axis_t axis = T::axis;
10091 (!_right && eval_once(axis_type, eval)) ||
10104 for (
const xpath_node* it = s.
begin(); it != s.
end(); ++it)
10106 size_t size = ns.
size();
10111 step_fill(ns, *it, stack.
result, once, v);
10112 if (_right) apply_predicates(ns, size, stack, eval);
10117 step_fill(ns, c.
n, stack.
result, once, v);
10118 if (_right) apply_predicates(ns, 0, stack, eval);
10131 _type(static_cast<char>(type)), _rettype(static_cast<char>(rettype_)), _axis(0), _test(0), _left(0), _right(0), _next(0)
10134 _data.string =
value;
10138 _type(static_cast<char>(type)), _rettype(static_cast<char>(rettype_)), _axis(0), _test(0), _left(0), _right(0), _next(0)
10141 _data.number =
value;
10145 _type(static_cast<char>(type)), _rettype(static_cast<char>(rettype_)), _axis(0), _test(0), _left(0), _right(0), _next(0)
10148 _data.variable =
value;
10152 _type(static_cast<char>(type)), _rettype(static_cast<char>(rettype_)), _axis(0), _test(0), _left(left), _right(right), _next(0)
10157 _type(static_cast<char>(type)), _rettype(
xpath_type_node_set), _axis(static_cast<char>(axis)), _test(static_cast<char>(test)), _left(left), _right(0), _next(0)
10160 _data.nodetest = contents;
10164 _type(static_cast<char>(type)), _rettype(
xpath_type_node_set), _axis(0), _test(static_cast<char>(test)), _left(left), _right(right), _next(0)
10190 return compare_eq(_left, _right, c, stack,
equal_to());
10193 return compare_eq(_left, _right, c, stack,
not_equal_to());
10196 return compare_rel(_left, _right, c, stack,
less());
10199 return compare_rel(_right, _left, c, stack,
less());
10202 return compare_rel(_left, _right, c, stack,
less_equal());
10205 return compare_rel(_right, _left, c, stack,
less_equal());
10241 if (c.
n.attribute())
return false;
10247 for (
xml_node n = c.
n.node(); n; n = n.parent())
10249 xml_attribute a = n.attribute(
PUGIXML_TEXT(
"xml:lang"));
10253 const char_t* value = a.value();
10256 for (
const char_t* lit = lang.
c_str(); *lit; ++lit)
10262 return *value == 0 || *value ==
'-';
10273 xml_attribute attr = c.
n.node().attribute(_left->
_data.
nodetest);
10280 assert(_rettype == _data.variable->type());
10283 return _data.variable->get_boolean();
10298 return !eval_string(c, stack).empty();
10309 assert(
false &&
"Wrong expression for return type boolean");
10339 return _data.number;
10342 return static_cast<double>(c.
size);
10345 return static_cast<double>(c.
position);
10386 for (
const xpath_node* it = ns.
begin(); it != ns.
end(); ++it)
10400 return r == r ? floor(r) : r;
10407 return r == r ? ceil(r) : r;
10415 assert(_rettype == _data.variable->type());
10418 return _data.variable->get_number();
10427 return eval_boolean(c, stack) ? 1 : 0;
10444 assert(
false &&
"Wrong expression for return type number");
10469 buffer[0] = _left->
eval_string(c, swapped_stack);
10472 for (
xpath_ast_node* n = _right; n; n = n->
_next, ++pos) buffer[pos] = n->eval_string(c, swapped_stack);
10473 assert(pos == count);
10477 for (
size_t i = 0; i < count; ++i) length += buffer[i].length();
10480 char_t* result =
static_cast<char_t*
>(stack.
result->
allocate((length + 1) *
sizeof(char_t)));
10483 char_t* ri = result;
10485 for (
size_t j = 0; j < count; ++j)
10486 for (
const char_t* bi = buffer[j].c_str(); *bi; ++bi)
10503 xpath_node na = c.
n;
10513 xpath_node na = ns.
first();
10520 xpath_node na = c.
n;
10530 xpath_node na = ns.
first();
10537 xpath_node na = c.
n;
10547 xpath_node na = ns.
first();
10559 return eval_string_concat(c, stack);
10587 const char_t* rbegin = pos + p.
length();
10600 size_t s_length = s.
length();
10605 else if (first >= s_length + 1)
return xpath_string();
10607 size_t pos = first < 1 ? 1 : static_cast<size_t>(first);
10608 assert(1 <= pos && pos <= s_length + 1);
10610 const char_t* rbegin = s.
c_str() + (pos - 1);
10623 size_t s_length = s.
length();
10629 else if (first >= s_length + 1)
return xpath_string();
10633 size_t pos = first < 1 ? 1 : static_cast<size_t>(first);
10634 size_t end = last >= s_length + 1 ? s_length + 1 :
static_cast<size_t>(last);
10636 assert(1 <= pos && pos <= end && end <= s_length + 1);
10637 const char_t* rbegin = s.
c_str() + (pos - 1);
10638 const char_t* rend = s.
c_str() + (end - 1);
10699 assert(_rettype == _data.variable->type());
10727 assert(
false &&
"Wrong expression for return type string");
10763 bool once = eval_once(
set.
type(), eval);
10765 apply_predicate(
set, 0, stack, once);
10818 assert(
false &&
"Unknown axis");
10839 assert(_rettype == _data.variable->type());
10843 const xpath_node_set& s = _data.variable->get_node_set();
10856 assert(
false &&
"Wrong expression for return type node set");
10872 optimize_self(alloc);
10882 _right = _right->
_right;
10911 _left = _left->
_left;
10922 _data.table = table;
10960 if (!n->is_posinv_expr())
return false;
10997 char_t _scratch[32];
11001 _result->error = message;
11022 void* memory = alloc_node();
11023 return memory ?
new (memory)
xpath_ast_node(type, rettype, value) : 0;
11028 void* memory = alloc_node();
11029 return memory ?
new (memory)
xpath_ast_node(type, rettype, value) : 0;
11034 void* memory = alloc_node();
11035 return memory ?
new (memory)
xpath_ast_node(type, rettype, value) : 0;
11040 void* memory = alloc_node();
11041 return memory ?
new (memory)
xpath_ast_node(type, rettype, left, right) : 0;
11046 void* memory = alloc_node();
11047 return memory ?
new (memory)
xpath_ast_node(type, left, axis, test, contents) : 0;
11052 void* memory = alloc_node();
11053 return memory ?
new (memory)
xpath_ast_node(type, left, right, test) : 0;
11061 size_t length =
static_cast<size_t>(value.
end - value.
begin);
11063 char_t* c =
static_cast<char_t*
>(_alloc->
allocate((length + 1) *
sizeof(char_t)));
11066 memcpy(c, value.
begin, length *
sizeof(char_t));
11074 switch (name.
begin[0])
11085 if (args[0]->rettype() !=
xpath_type_node_set)
return error(
"Function has to be applied to node set");
11088 else if (name ==
PUGIXML_TEXT(
"contains") && argc == 2)
11092 else if (name ==
PUGIXML_TEXT(
"ceiling") && argc == 1)
11116 else if (name ==
PUGIXML_TEXT(
"local-name") && argc <= 1)
11118 if (argc == 1 && args[0]->rettype() !=
xpath_type_node_set)
return error(
"Function has to be applied to node set");
11127 if (argc == 1 && args[0]->rettype() !=
xpath_type_node_set)
return error(
"Function has to be applied to node set");
11130 else if (name ==
PUGIXML_TEXT(
"namespace-uri") && argc <= 1)
11132 if (argc == 1 && args[0]->rettype() !=
xpath_type_node_set)
return error(
"Function has to be applied to node set");
11135 else if (name ==
PUGIXML_TEXT(
"normalize-space") && argc <= 1)
11159 else if (name ==
PUGIXML_TEXT(
"string-length") && argc <= 1)
11161 else if (name ==
PUGIXML_TEXT(
"starts-with") && argc == 2)
11163 else if (name ==
PUGIXML_TEXT(
"substring-before") && argc == 2)
11165 else if (name ==
PUGIXML_TEXT(
"substring-after") && argc == 2)
11167 else if (name ==
PUGIXML_TEXT(
"substring") && (argc == 2 || argc == 3))
11171 if (args[0]->rettype() !=
xpath_type_node_set)
return error(
"Function has to be applied to node set");
11189 return error(
"Unrecognized function or wrong parameter count");
11196 switch (name.
begin[0])
11262 switch (name.
begin[0])
11305 return error(
"Unknown variable: variable set is not provided");
11309 return error_oom();
11312 return error(
"Unknown variable: variable set does not contain the given name");
11327 return error(
"Expected ')' to match an opening '('");
11336 const char_t* value = alloc_string(_lexer.
contents());
11337 if (!value)
return 0;
11349 return error_oom();
11367 return error(
"Unrecognized function call");
11375 return error(
"No comma between function arguments");
11382 if (argc < 2) args[argc] = n;
11391 return parse_function(
function, argc, args);
11395 return error(
"Unrecognizable primary expression");
11412 return error(
"Predicate has to be applied to node set");
11415 if (!expr)
return 0;
11421 return error(
"Expected ']' to match an opening '['");
11437 return error(
"Step has to be applied to node set");
11439 bool axis_specified =
false;
11445 axis_specified =
true;
11454 return error(
"Predicates are not allowed after an abbreviated step");
11463 return error(
"Predicates are not allowed after an abbreviated step");
11481 if (axis_specified)
11482 return error(
"Two axis specifiers in one step");
11484 axis = parse_axis_name(nt_name, axis_specified);
11486 if (!axis_specified)
11487 return error(
"Unknown axis");
11505 return error(
"Unrecognized node test");
11520 nt_type = parse_node_test_type(nt_name);
11523 return error(
"Unrecognized node type");
11527 else if (nt_name ==
PUGIXML_TEXT(
"processing-instruction"))
11530 return error(
"Only literals are allowed as arguments to processing-instruction()");
11537 return error(
"Unmatched brace near processing-instruction()");
11542 return error(
"Unmatched brace near node type test");
11548 if (nt_name.
end - nt_name.
begin > 2 && nt_name.
end[-2] ==
':' && nt_name.
end[-1] ==
'*')
11568 return error(
"Unrecognized node test");
11571 const char_t* nt_name_copy = alloc_string(nt_name);
11572 if (!nt_name_copy)
return 0;
11584 if (!expr)
return 0;
11587 if (!pred)
return 0;
11590 return error(
"Expected ']' to match an opening '['");
11641 return parse_relative_location_path(n);
11655 return parse_relative_location_path(n);
11659 return parse_relative_location_path(0);
11683 const char_t* state = _lexer.
state();
11688 return parse_location_path();
11692 return parse_location_path();
11706 return error(
"Step has to be applied to node set");
11713 return parse_relative_location_path(n);
11730 return parse_location_path();
11809 if (!rhs)
return 0;
11815 rhs = parse_expression_rec(rhs, nextop.
precedence);
11816 if (!rhs)
return 0;
11818 nextop = binary_op_t::parse(_lexer);
11822 return error(
"Union operator has to be applied to node sets");
11825 if (!lhs)
return 0;
11827 op = binary_op_t::parse(_lexer);
11856 return parse_expression_rec(n, limit);
11859 xpath_parser(
const char_t* query, xpath_variable_set* variables,
xpath_allocator* alloc, xpath_parse_result* result): _alloc(alloc), _lexer(query), _query(query), _variables(variables), _result(result)
11870 return error(
"Incorrect query");
11879 return parser.
parse();
11888 if (!memory)
return 0;
11905 block.capacity =
sizeof(block.data);
11916 if (!impl)
return 0;
11920 #ifdef PUGIXML_NO_EXCEPTIONS 11923 xpath_parse_result res;
11924 res.error =
"Expression does not evaluate to node set";
11926 throw xpath_exception(res);
11936 #ifndef PUGIXML_NO_EXCEPTIONS 12004 #ifdef __BORLANDC__ 12007 return (
bool)lhs && rhs;
12012 return (
bool)lhs || rhs;
12018 assert(begin_ <= end_);
12020 size_t size_ =
static_cast<size_t>(end_ - begin_);
12025 if (_begin != &_storage) impl::xml_memory::deallocate(_begin);
12028 if (begin_ != end_) _storage = *begin_;
12030 _begin = &_storage;
12031 _end = &_storage + size_;
12041 #ifdef PUGIXML_NO_EXCEPTIONS 12044 throw std::bad_alloc();
12048 memcpy(storage, begin_, size_ *
sizeof(
xpath_node));
12051 if (_begin != &_storage) impl::xml_memory::deallocate(_begin);
12055 _end = storage + size_;
12060 #ifdef PUGIXML_HAS_MOVE 12068 rhs.
_type = type_unsorted;
12080 _assign(begin_, end_, type_);
12086 impl::xml_memory::deallocate(
_begin);
12096 if (
this == &ns)
return *
this;
12103 #ifdef PUGIXML_HAS_MOVE 12111 if (
this == &rhs)
return *
this;
12114 impl::xml_memory::deallocate(
_begin);
12139 assert(index <
size());
12186 return static_cast<const impl::xpath_variable_node_set*
>(
this)->
name;
12189 return static_cast<const impl::xpath_variable_number*
>(
this)->
name;
12192 return static_cast<const impl::xpath_variable_string*
>(
this)->
name;
12195 return static_cast<const impl::xpath_variable_boolean*
>(
this)->
name;
12198 assert(
false &&
"Invalid variable type");
12210 return (
_type ==
xpath_type_boolean) ?
static_cast<const impl::xpath_variable_boolean*
>(
this)->value :
false;
12220 const char_t* value = (
_type ==
xpath_type_string) ? static_cast<const impl::xpath_variable_string*>(
this)->value : 0;
12233 static_cast<impl::xpath_variable_boolean*
>(
this)->value = value;
12241 static_cast<impl::xpath_variable_number*
>(
this)->value = value;
12249 impl::xpath_variable_string* var =
static_cast<impl::xpath_variable_string*
>(
this);
12254 char_t* copy =
static_cast<char_t*
>(impl::xml_memory::allocate(size));
12255 if (!copy)
return false;
12257 memcpy(copy, value, size);
12260 if (var->value) impl::xml_memory::deallocate(var->value);
12270 static_cast<impl::xpath_variable_node_set*
>(
this)->value = value;
12276 for (
size_t i = 0; i <
sizeof(_data) /
sizeof(_data[0]); ++i)
12282 for (
size_t i = 0; i <
sizeof(_data) /
sizeof(_data[0]); ++i)
12283 _destroy(_data[i]);
12288 for (
size_t i = 0; i <
sizeof(_data) /
sizeof(_data[0]); ++i)
12296 if (
this == &rhs)
return *
this;
12303 #ifdef PUGIXML_HAS_MOVE 12306 for (
size_t i = 0; i <
sizeof(_data) /
sizeof(_data[0]); ++i)
12308 _data[i] = rhs._data[i];
12315 for (
size_t i = 0; i <
sizeof(_data) /
sizeof(_data[0]); ++i)
12317 _destroy(_data[i]);
12319 _data[i] = rhs._data[i];
12331 for (
size_t i = 0; i <
sizeof(_data) /
sizeof(_data[0]); ++i)
12340 for (
size_t i = 0; i <
sizeof(_data) /
sizeof(_data[0]); ++i)
12344 _data[i] = rhs.
_data[i];
12345 rhs.
_data[i] = chain;
12351 const size_t hash_size =
sizeof(_data) /
sizeof(_data[0]);
12370 if (!nvar)
return false;
12374 last->
_next = nvar;
12376 *out_result = nvar;
12403 const size_t hash_size =
sizeof(_data) /
sizeof(_data[0]);
12409 return var->type() == type ? var : 0;
12416 result->
_next = _data[hash];
12418 _data[hash] = result;
12427 return var ? var->
set(value) :
false;
12433 return var ? var->
set(value) :
false;
12439 return var ? var->
set(value) :
false;
12445 return var ? var->
set(value) :
false;
12450 return _find(name);
12455 return _find(name);
12460 impl::xpath_query_impl* qimpl = impl::xpath_query_impl::create();
12464 #ifdef PUGIXML_NO_EXCEPTIONS 12467 throw std::bad_alloc();
12472 using impl::auto_deleter;
12475 qimpl->root = impl::xpath_parser::parse(query, variables, &qimpl->alloc, &
_result);
12479 qimpl->root->optimize(&qimpl->alloc);
12486 #ifdef PUGIXML_NO_EXCEPTIONS 12489 if (qimpl->oom)
throw std::bad_alloc();
12503 impl::xpath_query_impl::destroy(static_cast<impl::xpath_query_impl*>(
_impl));
12506 #ifdef PUGIXML_HAS_MOVE 12517 if (
this == &rhs)
return *
this;
12520 impl::xpath_query_impl::destroy(static_cast<impl::xpath_query_impl*>(
_impl));
12535 return static_cast<impl::xpath_query_impl*
>(
_impl)->root->rettype();
12540 if (!
_impl)
return false;
12542 impl::xpath_context c(n, 1, 1);
12543 impl::xpath_stack_data
sd;
12545 bool r =
static_cast<impl::xpath_query_impl*
>(
_impl)->root->eval_boolean(c, sd.stack);
12549 #ifdef PUGIXML_NO_EXCEPTIONS 12552 throw std::bad_alloc();
12563 impl::xpath_context c(n, 1, 1);
12564 impl::xpath_stack_data
sd;
12566 double r =
static_cast<impl::xpath_query_impl*
>(
_impl)->root->eval_number(c, sd.stack);
12570 #ifdef PUGIXML_NO_EXCEPTIONS 12573 throw std::bad_alloc();
12580 #ifndef PUGIXML_NO_STL 12585 impl::xpath_context c(n, 1, 1);
12586 impl::xpath_stack_data
sd;
12588 impl::xpath_string r =
static_cast<impl::xpath_query_impl*
>(
_impl)->root->eval_string(c, sd.stack);
12592 #ifdef PUGIXML_NO_EXCEPTIONS 12595 throw std::bad_alloc();
12599 return string_t(r.c_str(), r.length());
12605 impl::xpath_context c(n, 1, 1);
12606 impl::xpath_stack_data
sd;
12608 impl::xpath_string r =
_impl ?
static_cast<impl::xpath_query_impl*
>(
_impl)->root->eval_string(c, sd.stack) : impl::xpath_string();
12612 #ifdef PUGIXML_NO_EXCEPTIONS 12613 r = impl::xpath_string();
12615 throw std::bad_alloc();
12619 size_t full_size = r.length() + 1;
12623 size_t size = (full_size < capacity) ? full_size : capacity;
12626 memcpy(buffer, r.c_str(), (size - 1) *
sizeof(char_t));
12627 buffer[size - 1] = 0;
12638 impl::xpath_context c(n, 1, 1);
12639 impl::xpath_stack_data
sd;
12645 #ifdef PUGIXML_NO_EXCEPTIONS 12648 throw std::bad_alloc();
12660 impl::xpath_context c(n, 1, 1);
12661 impl::xpath_stack_data
sd;
12667 #ifdef PUGIXML_NO_EXCEPTIONS 12670 throw std::bad_alloc();
12732 #ifdef __BORLANDC__ 12733 # pragma option pop 12738 #if defined(_MSC_VER) && !defined(__INTEL_COMPILER) 12739 # pragma warning(pop) 12742 #if defined(_MSC_VER) && defined(__c2__) 12743 # pragma clang diagnostic pop 12746 #if defined(__clang__) 12747 # pragma clang diagnostic pop 12751 #undef PUGI__NO_INLINE 12752 #undef PUGI__UNLIKELY 12753 #undef PUGI__STATIC_ASSERT 12754 #undef PUGI__DMC_VOLATILE 12755 #undef PUGI__UNSIGNED_OVERFLOW 12756 #undef PUGI__MSVC_CRT_VERSION 12757 #undef PUGI__SNPRINTF 12758 #undef PUGI__NS_BEGIN 12759 #undef PUGI__NS_END 12761 #undef PUGI__FN_NO_INLINE 12762 #undef PUGI__GETHEADER_IMPL 12763 #undef PUGI__GETPAGE_IMPL 12764 #undef PUGI__GETPAGE 12765 #undef PUGI__NODETYPE 12766 #undef PUGI__IS_CHARTYPE_IMPL 12767 #undef PUGI__IS_CHARTYPE 12768 #undef PUGI__IS_CHARTYPEX 12769 #undef PUGI__ENDSWITH 12770 #undef PUGI__SKIPWS 12771 #undef PUGI__OPTSET 12772 #undef PUGI__PUSHNODE 12773 #undef PUGI__POPNODE 12774 #undef PUGI__SCANFOR 12775 #undef PUGI__SCANWHILE 12776 #undef PUGI__SCANWHILE_UNROLL 12777 #undef PUGI__ENDSEG 12778 #undef PUGI__THROW_ERROR 12779 #undef PUGI__CHECK_ERROR
xpath_ast_node * alloc_node(ast_type_t type, xpath_value_type rettype, xpath_variable *value)
xml_node_type type() const
virtual bool for_each(xml_node &node)=0
void(* unspecified_bool_type)(xml_attribute ***)
virtual bool begin(xml_node &node)
xpath_node * begin() const
#define PUGI__NODETYPE(n)
const char_t * value() const
xml_attribute prepend_attribute(const char_t *name)
xpath_node_set::type_t type() const
xpath_variable * get(const char_t *name)
PUGI__FN bool strcpy_insitu(String &dest, Header &header, uintptr_t header_mask, const char_t *source, size_t source_length)
#define PUGI__GETHEADER_IMPL(object, page, flags)
xml_attribute_struct * internal_object() const
char data[xpath_memory_page_size]
xml_memory_page * allocate_page(size_t data_size)
double as_double(double def=0) const
PUGI__FN strconv_pcdata_t get_strconv_pcdata(unsigned int optmask)
void(* unspecified_bool_type)(xpath_node ***)
xpath_allocator_capture(xpath_allocator *alloc)
PUGI__FN void text_output_cdata(xml_buffered_writer &writer, const char_t *s)
xpath_node_set_raw eval_node_set(const xpath_context &c, const xpath_stack &stack, nodeset_eval_t eval)
xml_attribute next_attribute() const
xml_node_iterator iterator
static value_type high(value_type result, uint32_t)
#define PUGI__UNSIGNED_OVERFLOW
std::basic_ostream< char, std::char_traits< char > > * narrow_stream
xpath_string eval_string(const xpath_context &c, const xpath_stack &stack)
PUGI__FN xml_encoding get_buffer_encoding(xml_encoding encoding, const void *contents, size_t size)
#define PUGI__FN_NO_INLINE
xml_attribute append_attribute(const char_t *name)
xml_node_struct * _data_new()
PUGI__FN std::basic_string< wchar_t > PUGIXML_FUNCTION as_wide(const char *str)
xml_parse_result make_parse_result(xml_parse_status status, ptrdiff_t offset=0)
wchar_selector< sizeof(wchar_t)>::writer wchar_writer
xml_node document_element() const
static void destroy(xml_stream_chunk *chunk)
void append(const xpath_string &o, xpath_allocator *alloc)
xpath_variable(xpath_value_type type)
PUGI__FN void node_copy_string(String &dest, Header &header, uintptr_t header_mask, char_t *source, Header &source_header, xml_allocator *alloc)
const char_t * _cur_lexeme_pos
#define PUGI__SCANCHAR(ch)
void insertion_sort(T *begin, T *end, const Pred &pred)
xml_node prepend_child(xml_node_type type=node_element)
static xpath_string from_heap_preallocated(const char_t *begin, const char_t *end)
union xpath_ast_node::@19 _data
const char_t * get_string() const
std::basic_string< PUGIXML_CHAR, std::char_traits< PUGIXML_CHAR >, std::allocator< PUGIXML_CHAR > > string_t
PUGI__FN const char_t * namespace_uri(xml_node node)
void write_string(const char_t *data)
void insert_node_after(xml_node_struct *child, xml_node_struct *node)
~xpath_allocator_capture()
void _swap(xpath_variable_set &rhs)
PUGI__FN size_t get_valid_length(const char_t *data, size_t length)
static value_type low(value_type result, uint32_t ch)
PUGI__FN int get_value_int(const char_t *value)
const unsigned int parse_ws_pcdata_single
PUGI__FN bool save_file_impl(const xml_document &doc, FILE *file, const char_t *indent, unsigned int flags, xml_encoding encoding)
bool set_name(const char_t *rhs)
PUGI__FN void text_output_escaped(xml_buffered_writer &writer, const char_t *s, chartypex_t type)
PUGI__FN bool is_nan(double value)
static xml_memory_page * construct(void *memory)
static binary_op_t parse(xpath_lexer &lexer)
bool is_text_node(xml_node_struct *node)
void write_direct(const char_t *data, size_t length)
char_t * data(xpath_allocator *alloc)
void deallocate_memory(void *ptr, size_t size, xml_memory_page *page)
PUGI__FN char_t * normalize_space(char_t *buffer)
void append_attribute(xml_attribute_struct *attr, xml_node_struct *node)
static void apply_predicate_number_const(xpath_node_set_raw &ns, size_t first, xpath_ast_node *expr, const xpath_stack &stack)
bool is_posinv_step() const
char_t * parse_doctype_group(char_t *s, char_t endch)
const char * description() const
void(* unspecified_bool_type)(xml_node ***)
const unsigned int parse_embed_pcdata
utf16_decoder< opt_false > decoder
PUGI__FN const char_t * local_name(const xpath_node &node)
void deallocate_string(char_t *string)
unsigned int as_uint(unsigned int def=0) const
bool operator<(const xml_node &r) const
xpath_variable_set & operator=(const xpath_variable_set &rhs)
void step_fill(xpath_node_set_raw &ns, const xpath_node &xn, xpath_allocator *alloc, bool once, T v)
const_iterator end() const
bool operator==(const xml_node &r) const
void remove_attribute(xml_attribute_struct *attr, xml_node_struct *node)
size_t hash_value() const
void * allocate_memory_oob(size_t size, xml_memory_page *&out_page)
PUGI__FN void node_output_pi_value(xml_buffered_writer &writer, const char_t *s)
bool operator<(const xml_attribute &r) const
xml_node & operator*() const
float as_float(float def=0) const
const char_t * current_pos() const
static EnumT operator &(EnumT lhs, EnumT rhs)
void apply_predicate(xpath_node_set_raw &ns, size_t first, const xpath_stack &stack, bool once)
PUGI__NS_END PUGI__NS_BEGIN uint16_t endian_swap(uint16_t value)
static const uintptr_t xml_memory_page_contents_shared_mask
#define PUGI__ENDSWITH(c, e)
bool set_value(const char_t *rhs)
xml_node append_move(const xml_node &moved)
bool step_push(xpath_node_set_raw &ns, xml_node_struct *n, xpath_allocator *alloc)
xpath_lexer_string _cur_lexeme_contents
void _assign(const xpath_variable_set &rhs)
static char_t * parse_wconv(char_t *s, char_t end_quote)
xpath_ast_node * alloc_node(ast_type_t type, xpath_ast_node *left, axis_t axis, nodetest_t test, const char_t *contents)
char_t *(* strconv_pcdata_t)(char_t *)
bool set(const char_t *rhs)
int as_int(int def=0) const
static void deallocate_page(xml_memory_page *page)
xpath_parse_result * _result
ptrdiff_t offset_debug() const
xml_node next_sibling() const
PUGI__FN xml_parse_status get_file_size(FILE *file, size_t &out_result)
xpath_variable * _data[64]
PUGI__FN bool has_declaration(xml_node_struct *node)
xpath_variable_node_set()
xpath_memory_block * next
xpath_ast_node(ast_type_t type, xpath_ast_node *left, xpath_ast_node *right, predicate_t test)
static void apply_predicate_boolean(xpath_node_set_raw &ns, size_t first, xpath_ast_node *expr, const xpath_stack &stack, bool once)
xml_attribute_struct(impl::xml_memory_page *page)
const char_t * get() const
I median3(I first, I middle, I last, const Pred &pred)
const xpath_node_set & get_node_set() const
static value_type high(value_type result, uint32_t ch)
bool traverse(xml_tree_walker &walker)
const char_t * as_string(const char_t *def=PUGIXML_TEXT("")) const
bool as_bool(bool def=false) const
static bool compare_eq(xpath_ast_node *lhs, xpath_ast_node *rhs, const xpath_context &c, const xpath_stack &stack, const Comp &comp)
const xml_named_node_iterator & operator--()
xml_parse_result load_file(const char *path, unsigned int options=parse_default, xml_encoding encoding=encoding_auto)
xml_node_struct * _data() const
namespace_uri_predicate(const char_t *name)
PUGI__FN char_t * strconv_comment(char_t *s, char_t endch)
PUGI__FN void text_output_indent(xml_buffered_writer &writer, const char_t *indent, size_t indent_length, unsigned int depth)
void step_fill(xpath_node_set_raw &ns, xml_node_struct *n, xpath_allocator *alloc, bool once, T)
void reverse(I begin, I end)
void swap(T &lhs, T &rhs)
bool operator==(const xml_attribute_iterator &rhs) const
void apply_predicates(xpath_node_set_raw &ns, size_t first, const xpath_stack &stack, nodeset_eval_t eval)
const xpath_node & operator[](size_t index) const
bool operator<=(const xml_attribute &r) const
bool operator()(const xpath_node &lhs, const xpath_node &rhs) const
PUGI__FN std::string as_utf8_impl(const wchar_t *str, size_t length)
static xpath_string from_const(const char_t *str)
const unsigned int parse_escapes
PUGI__FN const void * document_buffer_order(const xpath_node &xnode)
const char_t * name() const
static value_type any(value_type result, uint32_t ch)
xml_attribute prepend_copy(const xml_attribute &proto)
bool operator<=(const xml_node &r) const
xml_attribute attribute() const
void(* deallocation_function)(void *ptr)
PUGI__FN PUGI__UNSIGNED_OVERFLOW unsigned int hash_string(const char_t *str)
PUGI__FN bool node_is_ancestor(xml_node_struct *parent, xml_node_struct *node)
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 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 bool check_string_to_number_format(const char_t *string)
virtual ~xml_tree_walker()
xml_document_struct(xml_memory_page *page)
bool operator==(const xpath_string &o) const
void insert_attribute_before(xml_attribute_struct *attr, xml_attribute_struct *place, xml_node_struct *node)
const unsigned int format_write_bom
const unsigned int parse_trim_pcdata
xpath_context(const xpath_node &n_, size_t position_, size_t size_)
xpath_variable_set * _variables
PUGI__FN size_t strlength_wide(const wchar_t *s)
xml_object_range< xml_attribute_iterator > attributes() const
PUGI__FN std::string PUGIXML_FUNCTION as_utf8(const wchar_t *str)
xml_memory_management_function_storage< int > xml_memory
const unsigned int format_no_empty_element_tags
xml_parse_result append_buffer(const void *contents, size_t size, unsigned int options=parse_default, xml_encoding encoding=encoding_auto)
PUGI__NS_END PUGI__NS_BEGIN PUGI__FN xpath_node_set::type_t xpath_get_order(const xpath_node *begin, const xpath_node *end)
bool operator()(xml_attribute a) const
#define PUGI__STATIC_ASSERT(cond)
const unsigned int parse_comments
const xpath_parse_result & result() const
#define PUGI__SCANWHILE(X)
xpath_ast_node(ast_type_t type, xpath_value_type rettype_, xpath_variable *value)
bool set_value(const char_t *rhs)
string_t path(char_t delimiter='/') const
xpath_ast_node(ast_type_t type, xpath_ast_node *left, axis_t axis, nodetest_t test, const char_t *contents)
const unsigned int parse_wnorm_attribute
bool operator!=(const xml_node_iterator &rhs) const
static value_type high(value_type result, uint32_t)
xml_attribute_struct * first_attribute
char_t * allocate_string(size_t length)
char_t * flush(char_t *s)
bool operator!=(const xml_attribute_iterator &rhs) const
PUGI__FN bool is_little_endian()
xpath_lexer(const char_t *query)
xml_attribute & operator=(const char_t *rhs)
bool operator()(const xpath_node &lhs, const xpath_node &rhs) const
bool operator>(const xml_attribute &r) const
void _assign(const_iterator begin, const_iterator end, type_t type)
friend class xml_named_node_iterator
static char_t * parse_skip_bom(char_t *s)
PUGI__FN double round_nearest_nzero(double value)
void flush(const char_t *data, size_t size)
PUGI__FN char * convert_path_heap(const wchar_t *str)
xml_node * operator->() const
double get_number() const
PUGI__FN PUGI__UNSIGNED_OVERFLOW U string_to_integer(const char_t *value, U minv, U maxv)
void truncate(xpath_node *pos)
const char_t * alloc_string(const xpath_lexer_string &value)
PUGI__FN xpath_string string_value(const xpath_node &na, xpath_allocator *alloc)
void destroy_attribute(xml_attribute_struct *a, xml_allocator &alloc)
xpath_ast_node * alloc_node(ast_type_t type, xpath_value_type rettype, const char_t *value)
static bool compare_rel(xpath_ast_node *lhs, xpath_ast_node *rhs, const xpath_context &c, const xpath_stack &stack, const Comp &comp)
xml_attribute attribute(const char_t *name) const
const char_t * value() const
const unsigned int parse_eol
bool remove_attribute(const xml_attribute &a)
const xml_node_iterator & operator--()
xml_attribute insert_copy_before(const xml_attribute &proto, const xml_attribute &attr)
PUGI__FN xpath_node_set::type_t xpath_sort(xpath_node *begin, xpath_node *end, xpath_node_set::type_t type, bool rev)
xpath_ast_node * parse_step(xpath_ast_node *set)
void push(char_t *&s, size_t count)
xml_node insert_move_before(const xml_node &moved, const xml_node &node)
axis_t parse_axis_name(const xpath_lexer_string &name, bool &specified)
void append_node(xml_node_struct *child, xml_node_struct *node)
PUGI__FN bool node_is_before(xml_node_struct *ln, xml_node_struct *rn)
static Traits::value_type process(const wchar_t *data, size_t size, typename Traits::value_type result, Traits traits)
void write(char_t d0, char_t d1, char_t d2, char_t d3, char_t d4)
static const uintptr_t xml_memory_page_name_allocated_or_shared_mask
attribute_iterator attributes_end() const
PUGI__FN xml_encoding guess_buffer_encoding(const uint8_t *data, size_t size)
#define PUGIXML_NOEXCEPT_IF_NOT_COMPACT
bool save_file(const char *path, const char_t *indent=PUGIXML_TEXT("\), unsigned int flags=format_default, xml_encoding encoding=encoding_auto) const
static value_type high(value_type result, uint32_t)
xpath_ast_node * parse_filter_expression()
T data[xml_memory_page_size/sizeof(T)]
const unsigned int parse_ws_pcdata
char_t *(* strconv_attribute_t)(char_t *, char_t)
bool operator()(const T &lhs, const T &rhs) const
PUGI__FN allocation_function PUGIXML_FUNCTION get_memory_allocation_function()
void(* unspecified_bool_type)(xpath_query ***)
virtual bool end(xml_node &node)
xpath_node evaluate_node(const xpath_node &n) const
utf32_decoder< opt_false > decoder
PUGI__NS_END static PUGI__NS_BEGIN const size_t xpath_memory_page_size
xml_parse_status error_status
char_t * parse_exclamation(char_t *s, xml_node_struct *cursor, unsigned int optmsk, char_t endch)
PUGI__FN bool set_value_ascii(String &dest, Header &header, uintptr_t header_mask, char *buf)
PUGI__NS_END static PUGI__NS_BEGIN const uintptr_t xml_memory_block_alignment
const xpath_parse_result & result() const
bool operator()(const T &lhs, const T &rhs) const
bool operator>=(const xml_node &r) const
xml_attribute append_copy(const xml_attribute &proto)
void set_next(xpath_ast_node *value)
#define PUGI__OPTSET(OPT)
const xml_named_node_iterator & operator++()
static const uintptr_t xml_memory_page_value_allocated_mask
nodetest_t parse_node_test_type(const xpath_lexer_string &name)
bool operator==(const xml_node_iterator &rhs) const
xpath_parse_result _result
xpath_ast_node * parse_expression(int limit=0)
xpath_node_set_raw step_do(const xpath_context &c, const xpath_stack &stack, nodeset_eval_t eval, T v)
xpath_ast_node * parse_location_path()
xml_attribute_struct * prev_attribute_c
bool is_xpath_attribute(const char_t *name)
PUGI__FN bool parse_declaration_encoding(const uint8_t *data, size_t size, const uint8_t *&out_encoding, size_t &out_length)
bool operator!=(const xpath_string &o) const
PUGI__NS_END PUGI__NS_BEGIN xml_attribute_struct * allocate_attribute(xml_allocator &alloc)
static void apply_predicate_number(xpath_node_set_raw &ns, size_t first, xpath_ast_node *expr, const xpath_stack &stack, bool once)
xml_node insert_move_after(const xml_node &moved, const xml_node &node)
xml_parse_result load_buffer(const void *contents, size_t size, unsigned int options=parse_default, xml_encoding encoding=encoding_auto)
xpath_ast_node * error(const char *message)
static PUGI__FN void unspecified_bool_xml_node(xml_node ***)
PUGI__FN char_t * strconv_escape(char_t *s, gap &g)
const char * description() const
PUGI__FN char_t tolower_ascii(char_t ch)
xml_attribute find_attribute(Predicate pred) const
xml_node_struct * next_sibling
void write(char_t d0, char_t d1, char_t d2)
PUGI__FN xml_parse_result load_file_impl(xml_document_struct *doc, FILE *file, unsigned int options, xml_encoding encoding, char_t **out_buffer)
xml_document_struct & get_document(const Object *object)
static value_type any(value_type result, uint32_t ch)
bool strcpy_insitu_allow(size_t length, const Header &header, uintptr_t header_mask, char_t *target)
xml_node first_element_by_path(const char_t *path, char_t delimiter='/') const
static Traits::value_type process(const uint32_t *data, size_t size, typename Traits::value_type result, Traits)
static bool _clone(xpath_variable *var, xpath_variable **out_result)
PUGI__FN FILE * open_file_wide(const wchar_t *path, const wchar_t *mode)
PUGI__FN void as_utf8_end(char *buffer, size_t size, const wchar_t *str, size_t length)
void(* unspecified_bool_type)(xml_text ***)
xml_node append_child(xml_node_type type=node_element)
xml_node previous_sibling() const
const xpath_lexer_string & contents() const
wchar_selector< sizeof(wchar_t)>::counter wchar_counter
xpath_ast_node(ast_type_t type, xpath_value_type rettype_, double value)
void _move(xpath_node_set &rhs) PUGIXML_NOEXCEPT
int as_int(int def=0) const
static char_t * parse_simple(char_t *s, char_t end_quote)
PUGI__FN xpath_string convert_number_to_string(double value, xpath_allocator *alloc)
const char_t * state() const
#define PUGI__PUSHNODE(TYPE)
static PUGI__FN void unspecified_bool_xml_text(xml_text ***)
#define PUGI__THROW_ERROR(err, m)
#define PUGI__UNLIKELY(cond)
PUGI__FN bool convert_string_to_number_scratch(char_t(&buffer)[32], const char_t *begin, const char_t *end, double *out_result)
xml_parse_result load(std::basic_istream< char, std::char_traits< char > > &stream, unsigned int options=parse_default, xml_encoding encoding=encoding_auto)
xml_node child(const char_t *name) const
const char_t * as_string(const char_t *def=PUGIXML_TEXT("")) const
static Traits::value_type process(const uint16_t *data, size_t size, typename Traits::value_type result, Traits)
xml_node_struct(impl::xml_memory_page *page, xml_node_type type)
I min_element(I begin, I end, const Pred &pred)
static const xpath_node_set dummy_node_set
PUGI__FN void convert_number_to_mantissa_exponent(double value, char(&buffer)[32], char **out_mantissa, int *out_exponent)
xpath_variable * add(const char_t *name, xpath_value_type type)
PUGI__FN deallocation_function PUGIXML_FUNCTION get_memory_deallocation_function()
PUGI__FN PUGI__UNSIGNED_OVERFLOW char_t * integer_to_string(char_t *begin, char_t *end, U value, bool negative)
xpath_value_type rettype() const
PUGI__FN bool convert_buffer_generic(char_t *&out_buffer, size_t &out_length, const void *contents, size_t size, D)
xpath_ast_node * error_oom()
xpath_node_set evaluate_node_set(const xpath_node &n) const
PUGI__FN unsigned char * translate_table_generate(xpath_allocator *alloc, const char_t *from, const char_t *to)
void * reallocate(void *ptr, size_t old_size, size_t new_size)
void write(char_t d0, char_t d1, char_t d2, char_t d3, char_t d4, char_t d5)
xml_attribute insert_attribute_after(const char_t *name, const xml_attribute &attr)
PUGI__FN const char_t * find_char(const char_t *s, char_t c)
double evaluate_number(const xpath_node &n) const
const char_t * c_str() const
static PUGI__FN void unspecified_bool_xml_attribute(xml_attribute ***)
bool operator()(const T &lhs, const T &rhs) const
static value_type low(value_type result, uint32_t ch)
xml_extra_buffer * extra_buffers
void sort(bool reverse=false)
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)
xml_document & operator=(const xml_document &)
static xpath_string from_heap(const char_t *begin, const char_t *end, xpath_allocator *alloc)
PUGI__FN void PUGIXML_FUNCTION set_memory_management_functions(allocation_function allocate, deallocation_function deallocate)
static const uintptr_t xml_memory_page_value_allocated_or_shared_mask
xml_node_struct * prev_sibling_c
void set_right(xpath_ast_node *value)
xpath_variable * variable
xpath_node_set & operator=(const xpath_node_set &ns)
#define PUGI__SCANWHILE_UNROLL(X)
bool operator>=(const xml_attribute &r) const
PUGI__FN bool is_attribute_of(xml_attribute_struct *attr, xml_node_struct *node)
static value_type any(value_type result, uint32_t ch)
static value_type low(value_type result, uint32_t)
double as_double(double def=0) const
PUGI__FN void delete_xpath_variable(T *var)
void destroy_node(xml_node_struct *n, xml_allocator &alloc)
const unsigned int format_save_file_text
void remove_node(xml_node_struct *node)
xml_parse_result load_buffer_inplace(void *contents, size_t size, unsigned int options=parse_default, xml_encoding encoding=encoding_auto)
PUGI__FN xpath_node xpath_first(const xpath_node *begin, const xpath_node *end, xpath_node_set::type_t type)
xml_node_struct * first_child
xml_attribute insert_attribute_before(const char_t *name, const xml_attribute &attr)
PUGI__NS_END PUGI__NS_BEGIN PUGI__FN bool starts_with(const char_t *string, const char_t *pattern)
void partition3(T *begin, T *end, T pivot, const Pred &pred, T **out_eqbeg, T **out_eqend)
static const unsigned char chartypex_table[256]
const unsigned int parse_declaration
void push_back_grow(const xpath_node &node, xpath_allocator *alloc)
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 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)
static value_type high(value_type result, uint32_t ch)
PUGI__FN void close_file(FILE *file)
bool operator!=(const xpath_node &n) const
xpath_node select_node(const char_t *query, xpath_variable_set *variables=0) const
void _move(xml_document &rhs) PUGIXML_NOEXCEPT_IF_NOT_COMPACT
PUGI__FN const char_t * convert_number_to_string_special(double value)
xpath_string(const char_t *buffer, bool uses_heap_, size_t length_heap)
xpath_string eval_string_concat(const xpath_context &c, const xpath_stack &stack)
const unsigned int parse_fragment
void insert_attribute_after(xml_attribute_struct *attr, xml_attribute_struct *place, xml_node_struct *node)
xml_named_node_iterator()
bool operator!=(const xml_named_node_iterator &rhs) const
xml_node & operator*() const
xml_allocator(xml_memory_page *root)
xpath_node_set select_nodes(const char_t *query, xpath_variable_set *variables=0) const
PUGI__FN xml_encoding get_wchar_encoding()
xpath_ast_node * alloc_node(ast_type_t type, xpath_ast_node *left, xpath_ast_node *right, predicate_t test)
xpath_allocator(xpath_memory_block *root, bool *error=0)
float as_float(float def=0) const
PUGIXML_DEPRECATED xpath_node select_single_node(const char_t *query, xpath_variable_set *variables=0) const
auto_deleter(T *data_, D deleter_)
bool is_posinv_expr() const
xml_node last_child() const
xml_node prepend_move(const xml_node &moved)
void * allocate_object(size_t size, xml_memory_page *&out_page)
PUGI__FN void truncate_zeros(char *begin, char *end)
attribute_iterator attributes_begin() const
const unsigned int format_no_declaration
PUGI__FN void text_output(xml_buffered_writer &writer, const char_t *s, chartypex_t type, unsigned int flags)
bool operator>(const xml_node &r) const
xml_node insert_child_before(xml_node_type type, const xml_node &node)
char_t * parse_doctype_ignore(char_t *s)
const xml_node_iterator & operator++()
PUGI__FN void node_output(xml_buffered_writer &writer, xml_node_struct *root, const char_t *indent, unsigned int flags, unsigned int depth)
const unsigned int format_raw
const unsigned int format_no_escapes
static void destroy(xpath_query_impl *impl)
std::basic_ostream< wchar_t, std::char_traits< wchar_t > > * wide_stream
xml_parse_result load_string(const char_t *contents, unsigned int options=parse_default)
static xml_parse_result parse(char_t *buffer, size_t length, xml_document_struct *xmldoc, xml_node_struct *root, unsigned int optmsk)
static const size_t xml_memory_page_size
xpath_ast_node * alloc_node(ast_type_t type, xpath_value_type rettype, double value)
void prepend_node(xml_node_struct *child, xml_node_struct *node)
PUGI__FN T * new_xpath_variable(const char_t *name)
PUGI__FN void node_output_comment(xml_buffered_writer &writer, const char_t *s)
const unsigned int parse_doctype
const_iterator begin() const
#define PUGI__SCANCHARTYPE(ct)
static Traits::value_type process(const uint8_t *data, size_t size, typename Traits::value_type result, Traits)
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)
void write(char_t d0, char_t d1)
PUGI__FN size_t get_latin1_7bit_prefix_length(const uint8_t *data, size_t size)
xml_attribute_struct * _attr
xpath_ast_node * parse_function(const xpath_lexer_string &name, size_t argc, xpath_ast_node *args[2])
void *(* allocation_function)(size_t size)
PUGI__FN bool convert_number_to_boolean(double value)
bool operator!=(const xml_node &r) const
static allocation_function allocate
PUGI__FN bool get_value_bool(const char_t *value)
PUGI__NS_END PUGI__NS_BEGIN PUGI__FN size_t strlength(const char_t *s)
binary_op_t(ast_type_t asttype_, xpath_value_type rettype_, int precedence_)
bool operator==(const xml_named_node_iterator &rhs) const
static const uintptr_t xpath_memory_block_alignment
static char_t * parse_eol(char_t *s, char_t end_quote)
xml_attribute_iterator attribute_iterator
PUGI__FN double convert_string_to_number(const char_t *string)
xml_node first_child() const
xml_attribute first_attribute() const
PUGI__FN size_t as_utf8_begin(const wchar_t *str, size_t length)
PUGI__FN bool node_is_before_sibling(xml_node_struct *ln, xml_node_struct *rn)
static void _destroy(xpath_variable *var)
xpath_ast_node * parse_path_or_unary_expression()
xpath_node_set::type_t _type
void set_type(xpath_node_set::type_t value)
bool operator()(const T &lhs, const T &rhs) const
#define PUGI__IS_CHARTYPEX(c, ct)
bool operator==(const char_t *other) const
static value_type low(value_type result, uint32_t)
xml_node_struct * internal_object() const
const char_t * child_value() const
bool step_push(xpath_node_set_raw &ns, xml_attribute_struct *a, xml_node_struct *parent, xpath_allocator *alloc)
xml_attribute last_attribute() const
virtual const char * what() const noexcept PUGIXML_OVERRIDE
void optimize(xpath_allocator *alloc)
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 char_t * translate_table(char_t *buffer, const unsigned char *table)
virtual void write(const void *data, size_t size) PUGIXML_OVERRIDE
PUGI__FN xml_parse_status load_stream_data_seek(std::basic_istream< T > &stream, void **out_buffer, size_t *out_size)
xml_node insert_child_after(xml_node_type type, const xml_node &node)
PUGI__FN std::basic_string< wchar_t > as_wide_impl(const char *str, size_t size)
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 size_t zero_terminate_buffer(void *buffer, size_t size, xml_encoding encoding)
PUGI__FN bool set_value_integer(String &dest, Header &header, uintptr_t header_mask, U value, bool negative)
PUGI__FN const char_t * qualified_name(const xpath_node &node)
xml_attribute previous_attribute() const
static deallocation_function deallocate
bool operator==(const xml_attribute &r) const
PUGI__FN bool allow_move(xml_node parent, xml_node child)
void * allocate_memory(size_t size, xml_memory_page *&out_page)
bool operator==(const xpath_node &n) const
static bool has_element_node_siblings(xml_node_struct *node)
void append(const xpath_node *begin_, const xpath_node *end_, xpath_allocator *alloc)
PUGI__NS_BEGIN PUGI__FN void * default_allocate(size_t size)
const char_t * name() const
PUGI__FN float get_value_float(const char_t *value)
xml_writer_file(void *file)
xml_attribute insert_copy_after(const xml_attribute &proto, const xml_attribute &attr)
const unsigned int format_indent
xpath_ast_node * parse_expression_rec(xpath_ast_node *lhs, int limit)
xpath_ast_node * parse_relative_location_path(xpath_ast_node *set)
xml_node * operator->() const
void write_buffer(const char_t *data, size_t length)
void optimize_self(xpath_allocator *alloc)
PUGI__FN unsigned int get_value_uint(const char_t *value)
char_t * parse_tree(char_t *s, xml_node_struct *root, unsigned int optmsk, char_t endch)
#define PUGI__CHECK_ERROR(err, m)
char_t * parse_doctype_primitive(char_t *s)
xpath_ast_node(ast_type_t type, xpath_value_type rettype_, xpath_ast_node *left=0, xpath_ast_node *right=0)
xml_buffered_writer(xml_writer &writer_, xml_encoding user_encoding)
PUGI__FN xml_parse_status load_stream_data_noseek(std::basic_istream< T > &stream, void **out_buffer, size_t *out_size)
PUGI__FN bool convert_buffer_latin1(char_t *&out_buffer, size_t &out_length, const void *contents, size_t size, bool is_mutable)
void step_fill(xpath_node_set_raw &ns, xml_attribute_struct *a, xml_node_struct *p, xpath_allocator *alloc, bool once, T v)
#define PUGI__DMC_VOLATILE
PUGI__FN bool allow_insert_attribute(xml_node_type parent)
void print(xml_writer &writer, const char_t *indent=PUGIXML_TEXT("\), unsigned int flags=format_default, xml_encoding encoding=encoding_auto, unsigned int depth=0) const
PUGI__FN void node_copy_attribute(xml_attribute_struct *da, xml_attribute_struct *sa)
#define PUGI__IS_CHARTYPE(c, ct)
xml_parse_result load_buffer_inplace_own(void *contents, size_t size, unsigned int options=parse_default, xml_encoding encoding=encoding_auto)
xpath_allocator * _target
static xpath_ast_node * parse(const char_t *query, xpath_variable_set *variables, xpath_allocator *alloc, xpath_parse_result *result)
PUGI__FN const char_t * find_substring(const char_t *s, const char_t *p)
static value_type high(value_type result, uint32_t ch)
PUGI__FN size_t convert_buffer_output_generic(typename T::value_type dest, const char_t *data, size_t length, D, T)
xml_node find_child_by_attribute(const char_t *name, const char_t *attr_name, const char_t *attr_value) const
PUGI__FN bool copy_xpath_variable(xpath_variable *lhs, const xpath_variable *rhs)
string_t evaluate_string(const xpath_node &n) const
bool operator!=(const xml_attribute &r) const
xml_allocator * allocator
static value_type low(value_type result, uint32_t ch)
PUGI__FN void node_output_simple(xml_buffered_writer &writer, xml_node_struct *node, unsigned int flags)
double eval_number(const xpath_context &c, const xpath_stack &stack)
PUGI__FN char_t * strconv_cdata(char_t *s, char_t endch)
name_null_sentry(xml_node_struct *node_)
void insert_node_before(xml_node_struct *child, xml_node_struct *node)
PUGI__FN void node_output_end(xml_buffered_writer &writer, xml_node_struct *node)
xpath_value_type return_type() const
PUGI__FN impl::xpath_ast_node * evaluate_node_set_prepare(xpath_query_impl *impl)
const unsigned int parse_pi
PUGI__FN bool strequal(const char_t *src, const char_t *dst)
static char_t * parse(char_t *s)
const unsigned char * table
static xpath_query_impl * create()
static value_type high(value_type result, uint32_t ch)
xpath_variable * _find(const char_t *name) const
PUGI__FN double gen_nan()
bool evaluate_boolean(const xpath_node &n) const
PUGI__FN bool allow_insert_child(xml_node_type parent, xml_node_type child)
xpath_ast_node * parse_primary_expression()
PUGI__FN bool strequalrange(const char_t *lhs, const char_t *rhs, size_t count)
char_t * parse_question(char_t *s, xml_node_struct *&ref_cursor, unsigned int optmsk, char_t endch)
const unsigned int parse_wconv_attribute
PUGI__FN strconv_attribute_t get_strconv_attribute(unsigned int optmask)
void write(char_t d0, char_t d1, char_t d2, char_t d3)
PUGI__FN char_t * translate(char_t *buffer, const char_t *from, const char_t *to, size_t to_length)
xpath_query & operator=(const xpath_query &)
void prepend_attribute(xml_attribute_struct *attr, xml_node_struct *node)
xml_attribute * operator->() const
xml_text & operator=(const char_t *rhs)
static value_type low(value_type result, uint32_t ch)
PUGI__FN xml_encoding get_write_native_encoding()
xml_attribute_struct * next_attribute
size_t hash_value() const
bool set(const char_t *name, bool value)
PUGI__FN bool set_value_bool(String &dest, Header &header, uintptr_t header_mask, bool value)
static xml_stream_chunk * create()
const char_t * name() const
xml_allocator & get_allocator(const Object *object)
static Traits::value_type process(const uint8_t *data, size_t size, typename Traits::value_type result, Traits)
static bool eval_once(xpath_node_set::type_t type, nodeset_eval_t eval)
static const unsigned char chartype_table[256]
bool as_bool(bool def=false) const
bool remove_child(const xml_node &n)
const xml_attribute_iterator & operator--()
static PUGI__FN void unspecified_bool_xpath_query(xpath_query ***)
PUGI__FN double round_nearest(double value)
void * allocate(size_t size)
xml_attribute & operator*() const
static char_t * parse_wnorm(char_t *s, char_t end_quote)
xml_node_struct * allocate_node(xml_allocator &alloc, xml_node_type type)
void sort(I begin, I end, const Pred &pred)
PUGI__FN void node_copy_tree(xml_node_struct *dn, xml_node_struct *sn)
const xml_attribute_iterator & operator++()
xml_parser(xml_allocator *alloc_)
void revert(const xpath_allocator &state)
PUGI__FN xml_encoding get_write_encoding(xml_encoding encoding)
xpath_parser(const char_t *query, xpath_variable_set *variables, xpath_allocator *alloc, xpath_parse_result *result)
void push_back(const xpath_node &node, xpath_allocator *alloc)
xpath_ast_node * alloc_node(ast_type_t type, xpath_value_type rettype, xpath_ast_node *left=0, xpath_ast_node *right=0)
xpath_value_type type() const
bool set_name(const char_t *rhs)
static const uintptr_t xml_memory_page_type_mask
static value_type low(value_type result, uint32_t ch)
xpath_memory_block * _root
static char_t * duplicate_string(const char_t *string, size_t length, xpath_allocator *alloc)
void save(xml_writer &writer, const char_t *indent=PUGIXML_TEXT("\), unsigned int flags=format_default, xml_encoding encoding=encoding_auto) const
xpath_parse_result _result
static const uintptr_t xml_memory_page_name_allocated_mask
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 set_value_convert(String &dest, Header &header, uintptr_t header_mask, float value)
const unsigned int parse_cdata
xml_object_range< xml_node_iterator > children() const
static PUGI__FN void unspecified_bool_xpath_node(xpath_node ***)
PUGI__FN double get_value_double(const char_t *value)
bool eval_boolean(const xpath_context &c, const xpath_stack &stack)
unsigned int as_uint(unsigned int def=0) const
PUGI__FN void node_copy_contents(xml_node_struct *dn, xml_node_struct *sn, xml_allocator *shared_alloc)
xpath_exception(const xpath_parse_result &result)
const unsigned int format_indent_attributes
virtual void write(const void *data, size_t size) PUGIXML_OVERRIDE
PUGI__FN_NO_INLINE xml_attribute_struct * append_new_attribute(xml_node_struct *node, xml_allocator &alloc)
xml_writer_stream(std::basic_ostream< char, std::char_traits< char > > &stream)
PUGI__FN void default_deallocate(void *ptr)
xpath_ast_node(ast_type_t type, xpath_value_type rettype_, const char_t *value)
#define PUGI__GETPAGE_IMPL(header)