15 #ifndef SOURCE_PUGIXML_CPP
16 #define SOURCE_PUGIXML_CPP
26 #ifdef PUGIXML_WCHAR_MODE
30 #ifndef PUGIXML_NO_XPATH
35 #ifndef PUGIXML_NO_STL
45 # pragma warning(push)
46 # pragma warning(disable: 4127) // conditional expression is constant
47 # pragma warning(disable: 4324) // structure was padded due to __declspec(align())
48 # pragma warning(disable: 4702) // unreachable code
49 # pragma warning(disable: 4996) // this function or variable may be unsafe
52 #if defined(_MSC_VER) && defined(__c2__)
53 # pragma clang diagnostic push
54 # pragma clang diagnostic ignored "-Wdeprecated" // this function or variable may be unsafe
57 #ifdef __INTEL_COMPILER
58 # pragma warning(disable: 177) // function was declared but never referenced
59 # pragma warning(disable: 279) // controlling expression is constant
60 # pragma warning(disable: 1478 1786) // function was declared "deprecated"
61 # pragma warning(disable: 1684) // conversion from pointer to same-sized integral type
64 #if defined(__BORLANDC__) && defined(PUGIXML_HEADER_ONLY)
65 # pragma warn -8080 // symbol is declared but never used; disabling this inside push/pop bracket does not make the warning go away
70 # pragma warn -8008 // condition is always false
71 # pragma warn -8066 // unreachable code
76 # pragma diag_suppress=178 // function was declared but never referenced
77 # pragma diag_suppress=237 // controlling expression is constant
80 #ifdef __TI_COMPILER_VERSION__
81 # pragma diag_suppress 179 // function was declared but never referenced
85 #if defined(_MSC_VER) && _MSC_VER >= 1300
86 # define PUGI__NO_INLINE __declspec(noinline)
87 #elif defined(__GNUC__)
88 # define PUGI__NO_INLINE __attribute__((noinline))
90 # define PUGI__NO_INLINE
94 #if defined(__GNUC__) && !defined(__c2__)
95 # define PUGI__UNLIKELY(cond) __builtin_expect(cond, 0)
97 # define PUGI__UNLIKELY(cond) (cond)
101 #define PUGI__STATIC_ASSERT(cond) { static const char condition_failed[(cond) ? 1 : -1] = {0}; (void)condition_failed[0]; }
105 # define PUGI__DMC_VOLATILE volatile
107 # define PUGI__DMC_VOLATILE
111 #if defined(__clang__) && defined(__has_attribute)
112 # if __has_attribute(no_sanitize)
113 # define PUGI__UNSIGNED_OVERFLOW __attribute__((no_sanitize("unsigned-integer-overflow")))
115 # define PUGI__UNSIGNED_OVERFLOW
118 # define PUGI__UNSIGNED_OVERFLOW
122 #if defined(__BORLANDC__) && !defined(__MEM_H_USING_LIST)
129 #if defined(PUGIXML_HAS_LONG_LONG) && defined(__GNUC__) && !defined(LLONG_MAX) && !defined(LLONG_MIN) && !defined(ULLONG_MAX)
130 # define LLONG_MIN (-LLONG_MAX - 1LL)
131 # define LLONG_MAX __LONG_LONG_MAX__
132 # define ULLONG_MAX (LLONG_MAX * 2ULL + 1ULL)
136 #if defined(_MSC_VER) && !defined(__S3E__) && !defined(_WIN32_WCE)
137 # define PUGI__MSVC_CRT_VERSION _MSC_VER
138 #elif defined(_WIN32_WCE)
139 # define PUGI__MSVC_CRT_VERSION 1310 // MSVC7.1
143 #if __cplusplus >= 201103
144 # define PUGI__SNPRINTF(buf, ...) snprintf(buf, sizeof(buf), __VA_ARGS__)
145 #elif defined(PUGI__MSVC_CRT_VERSION) && PUGI__MSVC_CRT_VERSION >= 1400
146 # define PUGI__SNPRINTF(buf, ...) _snprintf_s(buf, _countof(buf), _TRUNCATE, __VA_ARGS__)
148 # define PUGI__SNPRINTF sprintf
152 #ifdef PUGIXML_HEADER_ONLY
153 # define PUGI__NS_BEGIN OIIO_NAMESPACE_BEGIN namespace pugi { namespace impl {
154 # define PUGI__NS_END } } OIIO_NAMESPACE_END
155 # define PUGI__FN inline
156 # define PUGI__FN_NO_INLINE inline
158 # if defined(_MSC_VER) && _MSC_VER < 1300 // MSVC6 seems to have an amusing bug with anonymous namespaces inside namespaces
159 # define PUGI__NS_BEGIN OIIO_NAMESPACE_BEGIN namespace pugi { namespace impl {
160 # define PUGI__NS_END } } OIIO_NAMESPACE_END
162 # define PUGI__NS_BEGIN OIIO_NAMESPACE_BEGIN namespace pugi { namespace impl { namespace {
163 # define PUGI__NS_END } } } OIIO_NAMESPACE_END
166 # define PUGI__FN_NO_INLINE PUGI__NO_INLINE
170 #if (defined(_MSC_VER) && _MSC_VER < 1600) || (defined(__BORLANDC__) && __BORLANDC__ < 0x561)
173 # ifndef _UINTPTR_T_DEFINED
177 typedef unsigned __int8 uint8_t;
178 typedef unsigned __int16 uint16_t;
179 typedef unsigned __int32 uint32_t;
197 template <
typename T>
219 #ifdef PUGIXML_WCHAR_MODE
231 #ifdef PUGIXML_WCHAR_MODE
232 return wcscmp(src, dst) == 0;
234 return strcmp(src, dst) == 0;
241 for (
size_t i = 0; i <
count; ++i)
242 if (lhs[i] != rhs[i])
245 return lhs[
count] == 0;
253 #ifdef PUGIXML_WCHAR_MODE
256 const wchar_t*
end =
s;
258 return static_cast<size_t>(end -
s);
290 #ifdef PUGIXML_COMPACT
292 class compact_hash_table
295 compact_hash_table(): _items(0), _capacity(0), _count(0)
310 void*
find(
const void* key)
312 if (_capacity == 0)
return 0;
314 item_t* item = get_item(key);
316 assert(item->key == key || (item->key == 0 && item->value == 0));
323 assert(_capacity != 0 && _count < _capacity - _capacity / 4);
325 item_t* item = get_item(key);
337 bool reserve(
size_t extra = 16)
339 if (_count + extra >= _capacity - _capacity / 4)
340 return rehash(_count + extra);
357 bool rehash(
size_t count);
359 item_t* get_item(
const void* key)
362 assert(_capacity > 0);
364 size_t hashmod = _capacity - 1;
365 size_t bucket =
hash(key) & hashmod;
367 for (
size_t probe = 0; probe <= hashmod; ++probe)
369 item_t& probe_item = _items[bucket];
371 if (probe_item.key == key || probe_item.key == 0)
375 bucket = (bucket + probe + 1) & hashmod;
378 assert(
false &&
"Hash table is full");
384 unsigned int h =
static_cast<unsigned int>(
reinterpret_cast<uintptr_t>(key) & 0xffffffff);
399 size_t capacity = 32;
400 while (count >= capacity - capacity / 4)
403 compact_hash_table rt;
404 rt._capacity = capacity;
410 memset(rt._items, 0,
sizeof(item_t) * capacity);
412 for (
size_t i = 0; i < _capacity; ++i)
414 rt.insert(_items[i].key, _items[i].value);
419 _capacity = capacity;
422 assert(_count == rt._count);
431 #ifdef PUGIXML_COMPACT
432 static const uintptr_t xml_memory_block_alignment = 4;
434 static const uintptr_t xml_memory_block_alignment =
sizeof(
void*);
438 static const uintptr_t xml_memory_page_contents_shared_mask = 64;
439 static const uintptr_t xml_memory_page_name_allocated_mask = 32;
440 static const uintptr_t xml_memory_page_value_allocated_mask = 16;
441 static const uintptr_t xml_memory_page_type_mask = 15;
444 static const uintptr_t xml_memory_page_name_allocated_or_shared_mask = xml_memory_page_name_allocated_mask | xml_memory_page_contents_shared_mask;
445 static const uintptr_t xml_memory_page_value_allocated_or_shared_mask = xml_memory_page_value_allocated_mask | xml_memory_page_contents_shared_mask;
447 #ifdef PUGIXML_COMPACT
448 #define PUGI__GETHEADER_IMPL(object, page, flags) // unused
449 #define PUGI__GETPAGE_IMPL(header) (header).get_page()
451 #define PUGI__GETHEADER_IMPL(object, page, flags) (((reinterpret_cast<char*>(object) - reinterpret_cast<char*>(page)) << 8) | (flags))
453 #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))))
456 #define PUGI__GETPAGE(n) PUGI__GETPAGE_IMPL((n)->header)
457 #define PUGI__NODETYPE(n) static_cast<xml_node_type>((n)->header & impl::xml_memory_page_type_mask)
473 #ifdef PUGIXML_COMPACT
474 result->compact_string_base = 0;
475 result->compact_shared_parent = 0;
476 result->compact_page_marker = 0;
490 #ifdef PUGIXML_COMPACT
491 char_t* compact_string_base;
492 void* compact_shared_parent;
493 uint32_t* compact_page_marker;
497 static const size_t xml_memory_page_size =
498 #ifdef PUGIXML_MEMORY_PAGE_SIZE
499 (PUGIXML_MEMORY_PAGE_SIZE)
515 #ifdef PUGIXML_COMPACT
526 if (!memory)
return 0;
559 #ifdef PUGIXML_COMPACT
563 if (!result)
return 0;
566 ptrdiff_t
offset =
static_cast<char*
>(
result) - reinterpret_cast<char*>(out_page->compact_page_marker);
568 if (
PUGI__UNLIKELY(static_cast<uintptr_t>(offset) >= 256 * xml_memory_block_alignment))
571 uint32_t* marker =
static_cast<uint32_t*
>(
result);
573 *marker =
static_cast<uint32_t
>(
reinterpret_cast<char*
>(marker) - reinterpret_cast<char*>(out_page));
574 out_page->compact_page_marker = marker;
611 assert(
_root == page);
617 #ifdef PUGIXML_COMPACT
619 page->compact_string_base = 0;
620 page->compact_shared_parent = 0;
621 page->compact_page_marker = 0;
628 assert(
_root != page);
643 static const size_t max_encoded_offset = (1 << 16) * xml_memory_block_alignment;
651 size_t full_size = (size + (xml_memory_block_alignment - 1)) & ~(xml_memory_block_alignment - 1);
656 if (!header)
return 0;
659 ptrdiff_t page_offset =
reinterpret_cast<char*
>(header) - reinterpret_cast<char*>(page) -
sizeof(
xml_memory_page);
661 assert(page_offset % xml_memory_block_alignment == 0);
662 assert(page_offset >= 0 && static_cast<size_t>(page_offset) < max_encoded_offset);
663 header->
page_offset =
static_cast<uint16_t
>(
static_cast<size_t>(page_offset) / xml_memory_block_alignment);
666 assert(full_size % xml_memory_block_alignment == 0);
667 assert(full_size < max_encoded_offset || (page->
busy_size == full_size && page_offset == 0));
668 header->
full_size =
static_cast<uint16_t
>(full_size < max_encoded_offset ? full_size / xml_memory_block_alignment : 0);
672 return static_cast<char_t*
>(
static_cast<void*
>(header + 1));
686 xml_memory_page* page = reinterpret_cast<xml_memory_page*>(static_cast<void*>(reinterpret_cast<char*>(header) - page_offset));
689 size_t full_size = header->
full_size == 0 ? page->busy_size : header->
full_size * xml_memory_block_alignment;
696 #ifdef PUGIXML_COMPACT
697 return _hash->reserve();
706 #ifdef PUGIXML_COMPACT
707 compact_hash_table* _hash;
713 const size_t large_allocation_threshold = xml_memory_page_size / 4;
720 if (size <= large_allocation_threshold)
750 #ifdef PUGIXML_COMPACT
752 static const uintptr_t compact_alignment_log2 = 2;
753 static const uintptr_t compact_alignment = 1 << compact_alignment_log2;
762 ptrdiff_t offset = (
reinterpret_cast<char*
>(
this) - reinterpret_cast<char*>(page->compact_page_marker));
763 assert(offset % compact_alignment == 0 && static_cast<uintptr_t>(offset) < 256 * compact_alignment);
765 _page =
static_cast<unsigned char>(offset >> compact_alignment_log2);
766 _flags =
static_cast<unsigned char>(
flags);
771 _flags &=
static_cast<unsigned char>(
mod);
776 _flags |=
static_cast<unsigned char>(
mod);
787 const char* page_marker =
reinterpret_cast<const char*
>(
this) - (_page << compact_alignment_log2);
788 const char* page = page_marker - *
reinterpret_cast<const uint32_t*
>(
static_cast<const void*
>(page_marker));
795 unsigned char _flags;
800 const compact_header* header =
reinterpret_cast<const compact_header*
>(
static_cast<const char*
>(
object) - header_offset);
802 return header->get_page();
805 template <
int header_offset,
typename T>
PUGI__FN_NO_INLINE T* compact_get_value(
const void*
object)
807 return static_cast<T*
>(compact_get_page(
object, header_offset)->allocator->_hash->find(
object));
810 template <
int header_offset,
typename T>
PUGI__FN_NO_INLINE void compact_set_value(
const void*
object, T* value)
812 compact_get_page(
object, header_offset)->allocator->_hash->insert(
object, value);
815 template <
typename T,
int header_offset,
int start = -126>
class compact_pointer
818 compact_pointer(): _data(0)
822 void operator=(
const compact_pointer& rhs)
835 ptrdiff_t diff =
reinterpret_cast<char*
>(
value) - reinterpret_cast<char*>(
this);
836 ptrdiff_t offset = ((diff +
int(compact_alignment - 1)) >> compact_alignment_log2) -
start;
838 if (static_cast<uintptr_t>(offset) <= 253)
839 _data = static_cast<unsigned char>(offset + 1);
842 compact_set_value<header_offset>(
this,
value);
859 return reinterpret_cast<T*
>(base + (_data - 1 +
start) * compact_alignment);
862 return compact_get_value<header_offset, T>(
this);
868 T* operator->()
const
877 template <
typename T,
int header_offset>
class compact_pointer_parent
880 compact_pointer_parent(): _data(0)
884 void operator=(
const compact_pointer_parent& rhs)
897 ptrdiff_t diff =
reinterpret_cast<char*
>(
value) - reinterpret_cast<char*>(
this);
898 ptrdiff_t offset = ((diff +
int(compact_alignment - 1)) >> compact_alignment_log2) + 65533;
900 if (static_cast<uintptr_t>(offset) <= 65533)
902 _data =
static_cast<unsigned short>(offset + 1);
909 page->compact_shared_parent =
value;
911 if (page->compact_shared_parent == value)
917 compact_set_value<header_offset>(
this,
value);
937 return reinterpret_cast<T*
>(base + (_data - 1 - 65533) * compact_alignment);
939 else if (_data == 65534)
940 return static_cast<T*
>(compact_get_page(
this, header_offset)->compact_shared_parent);
942 return compact_get_value<header_offset, T>(
this);
948 T* operator->()
const
957 template <
int header_offset,
int base_offset>
class compact_string
960 compact_string(): _data(0)
964 void operator=(
const compact_string& rhs)
976 page->compact_string_base =
value;
978 ptrdiff_t offset = value - page->compact_string_base;
980 if (static_cast<uintptr_t>(offset) < (65535 << 7))
983 uint16_t* base =
reinterpret_cast<uint16_t*
>(
static_cast<void*
>(
reinterpret_cast<char*
>(
this) - base_offset));
987 *base =
static_cast<uint16_t
>((offset >> 7) + 1);
988 _data =
static_cast<unsigned char>((offset & 127) + 1);
992 ptrdiff_t remainder = offset - ((*base - 1) << 7);
994 if (static_cast<uintptr_t>(remainder) <= 253)
996 _data =
static_cast<unsigned char>(remainder + 1);
1000 compact_set_value<header_offset>(
this,
value);
1008 compact_set_value<header_offset>(
this,
value);
1028 const uint16_t* base =
reinterpret_cast<const uint16_t*
>(
static_cast<const void*
>(
reinterpret_cast<const char*
>(
this) - base_offset));
1031 ptrdiff_t offset = ((*base - 1) << 7) + (_data - 1);
1033 return page->compact_string_base +
offset;
1037 return compact_get_value<header_offset, char_t>(
this);
1045 unsigned char _data;
1050 #ifdef PUGIXML_COMPACT
1053 struct xml_attribute_struct
1060 impl::compact_header
header;
1062 uint16_t namevalue_base;
1064 impl::compact_string<4, 2>
name;
1065 impl::compact_string<5, 3>
value;
1068 impl::compact_pointer<xml_attribute_struct, 7, 0>
next_attribute;
1071 struct xml_node_struct
1078 impl::compact_header
header;
1080 uint16_t namevalue_base;
1082 impl::compact_string<4, 2>
name;
1083 impl::compact_string<5, 3>
value;
1085 impl::compact_pointer_parent<xml_node_struct, 6>
parent;
1087 impl::compact_pointer<xml_node_struct, 8, 0>
first_child;
1090 impl::compact_pointer<xml_node_struct, 10, 0>
next_sibling;
1155 #ifdef PUGIXML_COMPACT
1156 compact_hash_table hash;
1181 if (!memory)
return 0;
1183 return new (
memory) xml_attribute_struct(page);
1190 if (!memory)
return 0;
1192 return new (
memory) xml_node_struct(page, type);
1197 if (a->header & impl::xml_memory_page_name_allocated_mask)
1200 if (a->header & impl::xml_memory_page_value_allocated_mask)
1208 if (n->header & impl::xml_memory_page_name_allocated_mask)
1211 if (n->header & impl::xml_memory_page_value_allocated_mask)
1214 for (xml_attribute_struct* attr = n->first_attribute; attr; )
1216 xml_attribute_struct* next = attr->next_attribute;
1223 for (xml_node_struct* child = n->first_child; child; )
1225 xml_node_struct* next = child->next_sibling;
1235 inline void append_node(xml_node_struct* child, xml_node_struct* node)
1237 child->parent = node;
1239 xml_node_struct* head = node->first_child;
1243 xml_node_struct* tail = head->prev_sibling_c;
1245 tail->next_sibling = child;
1246 child->prev_sibling_c = tail;
1247 head->prev_sibling_c = child;
1251 node->first_child = child;
1252 child->prev_sibling_c = child;
1258 child->parent = node;
1260 xml_node_struct* head = node->first_child;
1264 child->prev_sibling_c = head->prev_sibling_c;
1265 head->prev_sibling_c = child;
1268 child->prev_sibling_c = child;
1270 child->next_sibling = head;
1271 node->first_child = child;
1276 xml_node_struct* parent = node->parent;
1278 child->parent = parent;
1280 if (node->next_sibling)
1281 node->next_sibling->prev_sibling_c = child;
1283 parent->first_child->prev_sibling_c = child;
1285 child->next_sibling = node->next_sibling;
1286 child->prev_sibling_c = node;
1288 node->next_sibling = child;
1293 xml_node_struct* parent = node->parent;
1295 child->parent = parent;
1297 if (node->prev_sibling_c->next_sibling)
1298 node->prev_sibling_c->next_sibling = child;
1300 parent->first_child = child;
1302 child->prev_sibling_c = node->prev_sibling_c;
1303 child->next_sibling = node;
1305 node->prev_sibling_c = child;
1310 xml_node_struct* parent = node->parent;
1312 if (node->next_sibling)
1313 node->next_sibling->prev_sibling_c = node->prev_sibling_c;
1315 parent->first_child->prev_sibling_c = node->prev_sibling_c;
1317 if (node->prev_sibling_c->next_sibling)
1318 node->prev_sibling_c->next_sibling = node->next_sibling;
1320 parent->first_child = node->next_sibling;
1323 node->prev_sibling_c = 0;
1324 node->next_sibling = 0;
1329 xml_attribute_struct* head = node->first_attribute;
1333 xml_attribute_struct* tail = head->prev_attribute_c;
1335 tail->next_attribute = attr;
1336 attr->prev_attribute_c = tail;
1337 head->prev_attribute_c = attr;
1341 node->first_attribute = attr;
1342 attr->prev_attribute_c = attr;
1348 xml_attribute_struct* head = node->first_attribute;
1352 attr->prev_attribute_c = head->prev_attribute_c;
1353 head->prev_attribute_c = attr;
1356 attr->prev_attribute_c = attr;
1358 attr->next_attribute = head;
1359 node->first_attribute = attr;
1364 if (place->next_attribute)
1365 place->next_attribute->prev_attribute_c = attr;
1367 node->first_attribute->prev_attribute_c = attr;
1369 attr->next_attribute = place->next_attribute;
1370 attr->prev_attribute_c = place;
1371 place->next_attribute = attr;
1376 if (place->prev_attribute_c->next_attribute)
1377 place->prev_attribute_c->next_attribute = attr;
1379 node->first_attribute = attr;
1381 attr->prev_attribute_c = place->prev_attribute_c;
1382 attr->next_attribute = place;
1383 place->prev_attribute_c = attr;
1388 if (attr->next_attribute)
1389 attr->next_attribute->prev_attribute_c = attr->prev_attribute_c;
1391 node->first_attribute->prev_attribute_c = attr->prev_attribute_c;
1393 if (attr->prev_attribute_c->next_attribute)
1394 attr->prev_attribute_c->next_attribute = attr->next_attribute;
1396 node->first_attribute = attr->next_attribute;
1398 attr->prev_attribute_c = 0;
1399 attr->next_attribute = 0;
1404 if (!alloc.
reserve())
return 0;
1407 if (!child)
return 0;
1416 if (!alloc.
reserve())
return 0;
1419 if (!attr)
return 0;
1444 return static_cast<uint16_t
>(((value & 0xff) << 8) | (value >> 8));
1449 return ((value & 0xff) << 24) | ((value & 0xff00) << 8) | ((value & 0xff0000) >> 8) | (value >> 24);
1459 if (ch < 0x80)
return result + 1;
1461 else if (ch < 0x800)
return result + 2;
1463 else return result + 3;
1482 *result =
static_cast<uint8_t
>(ch);
1486 else if (ch < 0x800)
1488 result[0] =
static_cast<uint8_t
>(0xC0 | (ch >> 6));
1489 result[1] =
static_cast<uint8_t
>(0x80 | (ch & 0x3F));
1495 result[0] =
static_cast<uint8_t
>(0xE0 | (ch >> 12));
1496 result[1] =
static_cast<uint8_t
>(0x80 | ((ch >> 6) & 0x3F));
1497 result[2] =
static_cast<uint8_t
>(0x80 | (ch & 0x3F));
1505 result[0] =
static_cast<uint8_t
>(0xF0 | (ch >> 18));
1506 result[1] =
static_cast<uint8_t
>(0x80 | ((ch >> 12) & 0x3F));
1507 result[2] =
static_cast<uint8_t
>(0x80 | ((ch >> 6) & 0x3F));
1508 result[3] =
static_cast<uint8_t
>(0x80 | (ch & 0x3F));
1514 return (ch < 0x10000) ?
low(result, ch) :
high(result, ch);
1539 *result =
static_cast<uint16_t
>(ch);
1546 uint32_t msh =
static_cast<uint32_t
>(ch - 0x10000) >> 10;
1547 uint32_t lsh =
static_cast<uint32_t
>(ch - 0x10000) & 0x3ff;
1549 result[0] =
static_cast<uint16_t
>(0xD800 + msh);
1550 result[1] =
static_cast<uint16_t
>(0xDC00 + lsh);
1557 return (ch < 0x10000) ?
low(result, ch) :
high(result, ch);
1608 *result =
static_cast<uint8_t
>(ch > 255 ?
'?' : ch);
1629 const uint8_t utf8_byte_mask = 0x3f;
1633 uint8_t lead = *
data;
1638 result = Traits::low(result, lead);
1643 if ((reinterpret_cast<uintptr_t>(data) & 3) == 0)
1646 while (size >= 4 && (*static_cast<const uint32_t*>(static_cast<const void*>(data)) & 0x80808080) == 0)
1648 result = Traits::low(result, data[0]);
1649 result = Traits::low(result, data[1]);
1650 result = Traits::low(result, data[2]);
1651 result = Traits::low(result, data[3]);
1658 else if (static_cast<unsigned int>(lead - 0xC0) < 0x20 && size >= 2 && (data[1] & 0xc0) == 0x80)
1660 result = Traits::low(result, ((lead & ~0xC0) << 6) | (data[1] & utf8_byte_mask));
1665 else if (static_cast<unsigned int>(lead - 0xE0) < 0x10 && size >= 3 && (data[1] & 0xc0) == 0x80 && (data[2] & 0xc0) == 0x80)
1667 result = Traits::low(result, ((lead & ~0xE0) << 12) | ((data[1] & utf8_byte_mask) << 6) | (data[2] & utf8_byte_mask));
1672 else if (static_cast<unsigned int>(lead - 0xF0) < 0x08 && size >= 4 && (data[1] & 0xc0) == 0x80 && (data[2] & 0xc0) == 0x80 && (data[3] & 0xc0) == 0x80)
1674 result = Traits::high(result, ((lead & ~0xF0) << 18) | ((data[1] & utf8_byte_mask) << 12) | ((data[2] & utf8_byte_mask) << 6) | (data[3] & utf8_byte_mask));
1703 result = Traits::low(result, lead);
1708 else if (static_cast<unsigned int>(lead - 0xE000) < 0x2000)
1710 result = Traits::low(result, lead);
1715 else if (static_cast<unsigned int>(lead - 0xD800) < 0x400 && size >= 2)
1719 if (static_cast<unsigned int>(next - 0xDC00) < 0x400)
1721 result = Traits::high(result, 0x10000 + ((lead & 0x3ff) << 10) + (next & 0x3ff));
1755 result = Traits::low(result, lead);
1762 result = Traits::high(result, lead);
1780 result = Traits::low(result, *data);
1818 return decoder::process(reinterpret_cast<const typename decoder::type*>(data), size, result, traits);
1822 #ifdef PUGIXML_WCHAR_MODE
1823 PUGI__FN void convert_wchar_endian_swap(
wchar_t* result,
const wchar_t*
data,
size_t length)
1825 for (
size_t i = 0; i <
length; ++i)
1844 static const unsigned char chartype_table[256] =
1846 55, 0, 0, 0, 0, 0, 0, 0, 0, 12, 12, 0, 0, 63, 0, 0,
1847 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
1848 8, 0, 6, 0, 0, 0, 7, 6, 0, 0, 0, 0, 0, 96, 64, 0,
1849 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 192, 0, 1, 0, 48, 0,
1850 0, 192, 192, 192, 192, 192, 192, 192, 192, 192, 192, 192, 192, 192, 192, 192,
1851 192, 192, 192, 192, 192, 192, 192, 192, 192, 192, 192, 0, 0, 16, 0, 192,
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, 0, 0, 0,
1855 192, 192, 192, 192, 192, 192, 192, 192, 192, 192, 192, 192, 192, 192, 192, 192,
1856 192, 192, 192, 192, 192, 192, 192, 192, 192, 192, 192, 192, 192, 192, 192, 192,
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
1874 static const unsigned char chartypex_table[256] =
1876 3, 3, 3, 3, 3, 3, 3, 3, 3, 2, 2, 3, 3, 2, 3, 3,
1877 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3,
1878 0, 0, 2, 0, 0, 0, 3, 2, 0, 0, 0, 0, 0, 16, 16, 0,
1879 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 0, 0, 3, 0, 1, 0,
1881 0, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20,
1882 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 0, 0, 0, 0, 20,
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, 0,
1886 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20,
1887 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20,
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
1896 #ifdef PUGIXML_WCHAR_MODE
1897 #define PUGI__IS_CHARTYPE_IMPL(c, ct, table) ((static_cast<unsigned int>(c) < 128 ? table[static_cast<unsigned int>(c)] : table[128]) & (ct))
1899 #define PUGI__IS_CHARTYPE_IMPL(c, ct, table) (table[static_cast<unsigned char>(c)] & (ct))
1902 #define PUGI__IS_CHARTYPE(c, ct) PUGI__IS_CHARTYPE_IMPL(c, ct, chartype_table)
1903 #define PUGI__IS_CHARTYPEX(c, ct) PUGI__IS_CHARTYPE_IMPL(c, ct, chartypex_table)
1907 unsigned int ui = 1;
1909 return *
reinterpret_cast<unsigned char*
>(&ui) == 1;
1916 if (
sizeof(
wchar_t) == 2)
1924 #define PUGI__SCANCHAR(ch) { if (offset >= size || data[offset] != ch) return false; offset++; }
1925 #define PUGI__SCANCHARTYPE(ct) { while (offset < size && PUGI__IS_CHARTYPE(data[offset], ct)) offset++; }
1928 if (size < 6 || !((data[0] ==
'<') & (data[1] ==
'?') & (data[2] ==
'x') & (data[3] ==
'm') & (data[4] ==
'l') &&
PUGI__IS_CHARTYPE(data[5],
ct_space)))
1932 for (
size_t i = 6; i + 1 <
size; ++i)
1938 if (data[i] ==
'e' && data[i + 1] ==
'n')
1952 uint8_t delimiter = (offset < size && data[
offset] ==
'"') ?
'"' :
'\'';
1958 out_encoding = data +
offset;
1962 out_length = offset -
start;
1972 #undef PUGI__SCANCHAR
1973 #undef PUGI__SCANCHARTYPE
1981 uint8_t d0 = data[0], d1 = data[1], d2 = data[2], d3 = data[3];
1988 if (d0 == 0xef && d1 == 0xbb && d2 == 0xbf)
return encoding_utf8;
2001 const uint8_t* enc = 0;
2002 size_t enc_length = 0;
2007 if (enc_length == 10
2008 && (enc[0] |
' ') ==
'i' && (enc[1] |
' ') ==
's' && (enc[2] |
' ') ==
'o'
2009 && enc[3] ==
'-' && enc[4] ==
'8' && enc[5] ==
'8' && enc[6] ==
'5' && enc[7] ==
'9'
2010 && enc[8] ==
'-' && enc[9] ==
'1')
2015 && (enc[0] |
' ') ==
'l' && (enc[1] |
' ') ==
'a' && (enc[2] |
' ') ==
't'
2016 && (enc[3] |
' ') ==
'i' && (enc[4] |
' ') ==
'n'
2039 const uint8_t* data =
static_cast<const uint8_t*
>(contents);
2046 size_t length = size /
sizeof(
char_t);
2050 out_buffer =
static_cast<char_t*
>(
const_cast<void*
>(contents));
2056 if (!buffer)
return false;
2059 memcpy(buffer, contents, length *
sizeof(
char_t));
2061 assert(length == 0);
2066 out_length = length + 1;
2072 #ifdef PUGIXML_WCHAR_MODE
2079 PUGI__FN bool convert_buffer_endian_swap(
char_t*& out_buffer,
size_t& out_length,
const void* contents,
size_t size,
bool is_mutable)
2081 const char_t* data =
static_cast<const char_t*
>(contents);
2082 size_t length = size /
sizeof(
char_t);
2088 convert_wchar_endian_swap(buffer, data, length);
2096 if (!buffer)
return false;
2098 convert_wchar_endian_swap(buffer, data, length);
2102 out_length = length + 1;
2110 const typename D::type* data =
static_cast<const typename
D::type*
>(contents);
2111 size_t data_length = size /
sizeof(
typename D::type);
2118 if (!buffer)
return false;
2124 assert(oend == obegin + length);
2128 out_length = length + 1;
2139 if (encoding == wchar_encoding)
2143 if (need_endian_swap_utf(encoding, wchar_encoding))
2144 return convert_buffer_endian_swap(out_buffer, out_length, contents, size, is_mutable);
2155 return (native_encoding == encoding) ?
2165 return (native_encoding == encoding) ?
2174 assert(
false &&
"Invalid encoding");
2180 const typename D::type* data =
static_cast<const typename
D::type*
>(contents);
2181 size_t data_length = size /
sizeof(
typename D::type);
2188 if (!buffer)
return false;
2191 uint8_t* obegin =
reinterpret_cast<uint8_t*
>(
buffer);
2194 assert(oend == obegin + length);
2198 out_length = length + 1;
2205 for (
size_t i = 0; i <
size; ++i)
2214 const uint8_t* data =
static_cast<const uint8_t*
>(contents);
2215 size_t data_length =
size;
2219 assert(prefix_length <= data_length);
2221 const uint8_t* postfix = data + prefix_length;
2222 size_t postfix_length = data_length - prefix_length;
2225 if (postfix_length == 0)
return get_mutable_buffer(out_buffer, out_length, contents, size, is_mutable);
2232 if (!buffer)
return false;
2235 memcpy(buffer, data, prefix_length);
2237 uint8_t* obegin =
reinterpret_cast<uint8_t*
>(
buffer);
2240 assert(oend == obegin + length);
2244 out_length = length + 1;
2260 return (native_encoding == encoding) ?
2270 return (native_encoding == encoding) ?
2279 assert(
false &&
"Invalid encoding");
2293 uint8_t*
begin =
reinterpret_cast<uint8_t*
>(
buffer);
2296 assert(begin + size == end);
2301 #ifndef PUGIXML_NO_STL
2309 result.resize(size);
2312 if (size > 0)
as_utf8_end(&result[0], size, str, length);
2319 const uint8_t* data =
reinterpret_cast<const uint8_t*
>(str);
2326 result.resize(length);
2334 assert(begin + length == end);
2342 template <
typename Header>
2346 if (header & xml_memory_page_contents_shared_mask)
return false;
2348 size_t target_length =
strlength(target);
2351 if ((header & header_mask) == 0)
return target_length >=
length;
2354 const size_t reuse_threshold = 32;
2356 return target_length >= length && (target_length < reuse_threshold || target_length - length < target_length / 2);
2359 template <
typename String,
typename Header>
2362 if (source_length == 0)
2371 header &= ~header_mask;
2378 memcpy(dest, source, source_length *
sizeof(
char_t));
2379 dest[source_length] = 0;
2387 if (!alloc->
reserve())
return false;
2391 if (!buf)
return false;
2394 memcpy(buf, source, source_length *
sizeof(
char_t));
2395 buf[source_length] = 0;
2402 header |= header_mask;
2425 memmove(
end - size,
end, reinterpret_cast<char*>(s) - reinterpret_cast<char*>(
end));
2442 memmove(
end - size,
end, reinterpret_cast<char*>(s) - reinterpret_cast<char*>(
end));
2458 unsigned int ucsc = 0;
2466 if (ch ==
';')
return stre;
2470 if (static_cast<unsigned int>(ch -
'0') <= 9)
2471 ucsc = 16 * ucsc + (ch -
'0');
2472 else if (static_cast<unsigned int>((ch |
' ') -
'a') <= 5)
2473 ucsc = 16 * ucsc + ((ch |
' ') -
'a' + 10);
2488 if (ch ==
';')
return stre;
2492 if (static_cast<unsigned int>(ch -
'0') <= 9)
2493 ucsc = 10 * ucsc + (ch -
'0');
2505 #ifdef PUGIXML_WCHAR_MODE
2511 g.
push(s, stre - s);
2521 if (*++stre ==
'p' && *++stre ==
';')
2526 g.
push(s, stre - s);
2530 else if (*stre ==
'p')
2532 if (*++stre ==
'o' && *++stre ==
's' && *++stre ==
';')
2537 g.
push(s, stre - s);
2546 if (*++stre ==
't' && *++stre ==
';')
2551 g.
push(s, stre - s);
2559 if (*++stre ==
't' && *++stre ==
';')
2564 g.
push(s, stre - s);
2572 if (*++stre ==
'u' && *++stre ==
'o' && *++stre ==
't' && *++stre ==
';')
2577 g.
push(s, stre - s);
2591 #define PUGI__ENDSWITH(c, e) ((c) == (e) || ((c) == 0 && endch == (e)))
2592 #define PUGI__SKIPWS() { while (PUGI__IS_CHARTYPE(*s, ct_space)) ++s; }
2593 #define PUGI__OPTSET(OPT) ( optmsk & (OPT) )
2594 #define PUGI__PUSHNODE(TYPE) { cursor = append_new_node(cursor, *alloc, TYPE); if (!cursor) PUGI__THROW_ERROR(status_out_of_memory, s); }
2595 #define PUGI__POPNODE() { cursor = cursor->parent; }
2596 #define PUGI__SCANFOR(X) { while (*s != 0 && !(X)) ++s; }
2597 #define PUGI__SCANWHILE(X) { while (X) ++s; }
2598 #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; } }
2599 #define PUGI__ENDSEG() { ch = *s; *s = 0; ++s; }
2600 #define PUGI__THROW_ERROR(err, m) return error_offset = m, error_status = err, static_cast<char_t*>(0)
2601 #define PUGI__CHECK_ERROR(err, m) { if (*s == 0) PUGI__THROW_ERROR(err, m); }
2615 if (*s ==
'\n') g.
push(s, 1);
2617 else if (s[0] ==
'-' && s[1] ==
'-' &&
PUGI__ENDSWITH(s[2],
'>'))
2621 return s + (s[2] ==
'>' ? 3 : 2);
2643 if (*s ==
'\n') g.
push(s, 1);
2645 else if (s[0] ==
']' && s[1] ==
']' &&
PUGI__ENDSWITH(s[2],
'>'))
2689 if (*s ==
'\n') g.
push(s, 1);
2716 switch (((optmask >> 4) & 3) | ((optmask >> 9) & 4))
2726 default: assert(
false);
return 0;
2753 if (*s == end_quote)
2755 char_t* str = g.
flush(s);
2768 char_t* str = s + 1;
2794 if (*s == end_quote)
2806 if (*s ==
'\n') g.
push(s, 1);
2830 if (*s == end_quote)
2836 else if (*s ==
'\r')
2840 if (*s ==
'\n') g.
push(s, 1);
2862 if (*s == end_quote)
2885 switch ((optmask >> 4) & 15)
2903 default: assert(
false);
return 0;
2910 result.status = status;
2935 if (*s ==
'"' || *s ==
'\'')
2944 else if (s[0] ==
'<' && s[1] ==
'?')
2953 else if (s[0] ==
'<' && s[1] ==
'!' && s[2] ==
'-' && s[3] ==
'-')
2970 assert(s[0] ==
'<' && s[1] ==
'!' && s[2] ==
'[');
2975 if (s[0] ==
'<' && s[1] ==
'!' && s[2] ==
'[')
2981 else if (s[0] ==
']' && s[1] ==
']' && s[2] ==
'>')
3001 assert((s[0] ==
'<' || s[0] == 0) && s[1] ==
'!');
3006 if (s[0] ==
'<' && s[1] ==
'!' && s[2] !=
'-')
3021 else if (s[0] ==
'<' || s[0] ==
'"' || s[0] ==
'\'')
3077 s += (s[2] ==
'>' ? 3 : 2);
3085 if (*++s==
'C' && *++s==
'D' && *++s==
'A' && *++s==
'T' && *++s==
'A' && *++s ==
'[')
3118 s += (s[1] ==
'>' ? 2 : 1);
3122 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'))
3128 char_t* mark = s + 9;
3133 assert((*s == 0 && endch ==
'>') || *s ==
'>');
3142 cursor->value = mark;
3152 char_t*
parse_question(char_t*
s, xml_node_struct*& ref_cursor,
unsigned int optmsk, char_t endch)
3155 xml_node_struct* cursor = ref_cursor;
3170 bool declaration = (target[0] |
' ') ==
'x' && (target[1] |
' ') ==
'm' && (target[2] |
' ') ==
'l' && target + 3 == s;
3220 cursor->value =
value;
3237 s += (s[1] ==
'>' ? 2 : 1);
3241 ref_cursor = cursor;
3246 char_t*
parse_tree(char_t*
s, xml_node_struct* root,
unsigned int optmsk, char_t endch)
3252 xml_node_struct* cursor = root;
3304 if (*s ==
'"' || *s ==
'\'')
3310 s = strconv_attribute(s, ch);
3333 else if (*s == 0 && endch ==
'>')
3346 else if (*s == 0 && endch ==
'>')
3378 char_t*
name = cursor->name;
3428 if (*s ==
'<' || !*s)
3439 if (s[0] !=
'<' || s[1] !=
'/' || cursor->first_child)
continue;
3461 s = strconv_pcdata(s);
3484 #ifdef PUGIXML_WCHAR_MODE
3487 unsigned int bom = 0xfeff;
3488 return (s[0] == static_cast<wchar_t>(bom)) ? s + 1 :
s;
3493 return (s[0] ==
'\xef' && s[1] ==
'\xbb' && s[2] ==
'\xbf') ? s + 3 :
s;
3503 node = node->next_sibling;
3516 xml_node_struct* last_root_child = root->first_child ? root->first_child->prev_sibling_c + 0 : 0;
3519 xml_parser parser(static_cast<xml_allocator*>(xmldoc));
3522 char_t endch = buffer[length - 1];
3523 buffer[length - 1] = 0;
3529 parser.
parse_tree(buffer_data, root, optmsk, endch);
3532 assert(result.offset >= 0 && static_cast<size_t>(result.offset) <= length);
3541 xml_node_struct* first_root_child_parsed = last_root_child ? last_root_child->next_sibling + 0 : root->first_child+ 0;
3549 if (result.offset > 0 && static_cast<size_t>(result.offset) == length - 1 && endch == 0)
3560 #ifdef PUGIXML_WCHAR_MODE
3591 return static_cast<size_t>(end - dest) *
sizeof(*dest);
3606 return static_cast<size_t>(end - dest) *
sizeof(*dest);
3609 #ifdef PUGIXML_WCHAR_MODE
3612 if (length < 1)
return 0;
3615 return (
sizeof(
wchar_t) == 2 && static_cast<unsigned int>(static_cast<uint16_t>(data[length - 1]) - 0xD800) < 0x400) ? length - 1 :
length;
3623 convert_wchar_endian_swap(r_char, data, length);
3625 return length *
sizeof(
char_t);
3652 assert(
false &&
"Invalid encoding");
3658 if (length < 5)
return 0;
3660 for (
size_t i = 1; i <= 4; ++i)
3662 uint8_t ch =
static_cast<uint8_t
>(data[length - i]);
3665 if ((ch & 0xc0) != 0x80)
return length - i;
3691 assert(
false &&
"Invalid encoding");
3714 void flush(
const char_t* data,
size_t size)
3716 if (size == 0)
return;
3720 writer.write(data, size *
sizeof(char_t));
3725 assert(result <=
sizeof(
scratch));
3743 writer.write(data, length *
sizeof(char_t));
3756 flush(data, chunk_size);
3760 length -= chunk_size;
3767 memcpy(buffer +
bufsize, data, length *
sizeof(char_t));
3777 memcpy(buffer + offset, data, length *
sizeof(char_t));
3792 buffer[offset++] = *data++;
3802 size_t length = offset -
bufsize;
3805 bufsize = offset - extra;
3816 buffer[offset + 0] = d0;
3825 buffer[offset + 0] = d0;
3826 buffer[offset + 1] = d1;
3830 void write(char_t d0, char_t d1, char_t d2)
3835 buffer[offset + 0] = d0;
3836 buffer[offset + 1] = d1;
3837 buffer[offset + 2] = d2;
3841 void write(char_t d0, char_t d1, char_t d2, char_t d3)
3846 buffer[offset + 0] = d0;
3847 buffer[offset + 1] = d1;
3848 buffer[offset + 2] = d2;
3849 buffer[offset + 3] = d3;
3853 void write(char_t d0, char_t d1, char_t d2, char_t d3, char_t d4)
3858 buffer[offset + 0] = d0;
3859 buffer[offset + 1] = d1;
3860 buffer[offset + 2] = d2;
3861 buffer[offset + 3] = d3;
3862 buffer[offset + 4] = d4;
3866 void write(char_t d0, char_t d1, char_t d2, char_t d3, char_t d4, char_t d5)
3871 buffer[offset + 0] = d0;
3872 buffer[offset + 1] = d1;
3873 buffer[offset + 2] = d2;
3874 buffer[offset + 3] = d3;
3875 buffer[offset + 4] = d4;
3876 buffer[offset + 5] = d5;
3886 #ifdef PUGIXML_MEMORY_OUTPUT_STACK
3887 PUGIXML_MEMORY_OUTPUT_STACK
3914 const char_t* prev =
s;
3919 writer.
write_buffer(prev, static_cast<size_t>(s - prev));
3925 writer.
write(
'&',
'a',
'm',
'p',
';');
3929 writer.
write(
'&',
'l',
't',
';');
3933 writer.
write(
'&',
'g',
't',
';');
3940 writer.
write(
'&',
'q',
'u',
'o',
't',
';');
3944 if (flags & format_attribute_single_quote)
3945 writer.
write(
'&',
'a',
'p',
'o',
's',
';');
3952 unsigned int ch =
static_cast<unsigned int>(*s++);
3956 writer.
write(
'&',
'#', static_cast<char_t>((ch / 10) +
'0'), static_cast<char_t>((ch % 10) +
'0'),
';');
3974 writer.
write(
'<',
'!',
'[',
'C',
'D');
3975 writer.
write(
'A',
'T',
'A',
'[');
3977 const char_t* prev =
s;
3980 while (*s && !(s[0] ==
']' && s[1] ==
']' && s[2] ==
'>')) ++
s;
3985 writer.
write_buffer(prev, static_cast<size_t>(s - prev));
3987 writer.
write(
']',
']',
'>');
3994 switch (indent_length)
3998 for (
unsigned int i = 0; i <
depth; ++i)
3999 writer.
write(indent[0]);
4005 for (
unsigned int i = 0; i <
depth; ++i)
4006 writer.
write(indent[0], indent[1]);
4012 for (
unsigned int i = 0; i <
depth; ++i)
4013 writer.
write(indent[0], indent[1], indent[2]);
4019 for (
unsigned int i = 0; i <
depth; ++i)
4020 writer.
write(indent[0], indent[1], indent[2], indent[3]);
4026 for (
unsigned int i = 0; i <
depth; ++i)
4034 writer.
write(
'<',
'!',
'-',
'-');
4038 const char_t* prev =
s;
4041 while (*s && !(s[0] ==
'-' && (s[1] ==
'-' || s[1] == 0))) ++
s;
4043 writer.
write_buffer(prev, static_cast<size_t>(s - prev));
4049 writer.
write(
'-',
' ');
4054 writer.
write(
'-',
'-',
'>');
4061 const char_t* prev =
s;
4064 while (*s && !(s[0] ==
'?' && s[1] ==
'>')) ++
s;
4066 writer.
write_buffer(prev, static_cast<size_t>(s - prev));
4070 assert(s[0] ==
'?' && s[1] ==
'>');
4072 writer.
write(
'?',
' ',
'>');
4080 const char_t* default_name =
PUGIXML_TEXT(
":anonymous");
4083 for (xml_attribute_struct*
a = node->first_attribute;
a;
a =
a->next_attribute)
4097 writer.
write(
'=', enquotation_char);
4102 writer.
write(enquotation_char);
4108 const char_t* default_name =
PUGIXML_TEXT(
":anonymous");
4109 const char_t*
name = node->name ? node->name + 0 : default_name;
4114 if (node->first_attribute)
4120 if (!node->first_child)
4124 writer.
write(
'>',
'<',
'/');
4135 writer.
write(
'/',
'>');
4153 if (!node->first_child)
4155 writer.
write(
'<',
'/');
4170 const char_t* default_name =
PUGIXML_TEXT(
":anonymous");
4171 const char_t*
name = node->name ? node->name + 0 : default_name;
4173 writer.
write(
'<',
'/');
4180 const char_t* default_name =
PUGIXML_TEXT(
":anonymous");
4197 writer.
write(
'<',
'?');
4198 writer.
write_string(node->name ? node->name + 0 : default_name);
4206 writer.
write(
'?',
'>');
4210 writer.
write(
'<',
'?');
4211 writer.
write_string(node->name ? node->name + 0 : default_name);
4213 writer.
write(
'?',
'>');
4217 writer.
write(
'<',
'!',
'D',
'O',
'C');
4218 writer.
write(
'T',
'Y',
'P',
'E');
4230 assert(
false &&
"Invalid node type");
4245 xml_node_struct* node = root;
4276 node = node->first_child;
4285 if (node->first_child)
4287 node = node->first_child;
4300 while (node != root)
4302 if (node->next_sibling)
4304 node = node->next_sibling;
4308 node = node->parent;
4327 while (node != root);
4335 for (xml_node_struct* child = node->first_child; child; child = child->next_sibling)
4348 for (xml_attribute_struct*
a = node->first_attribute;
a;
a =
a->next_attribute)
4376 if (parent.root() != child.root())
4380 xml_node cur = parent;
4393 template <
typename String,
typename Header>
4396 assert(!dest && (header & header_mask) == 0);
4400 if (alloc && (source_header & header_mask) == 0)
4405 header |= xml_memory_page_contents_shared_mask;
4406 source_header |= xml_memory_page_contents_shared_mask;
4415 node_copy_string(dn->name, dn->header, xml_memory_page_name_allocated_mask, sn->name, sn->header, shared_alloc);
4416 node_copy_string(dn->value, dn->header, xml_memory_page_value_allocated_mask, sn->value, sn->header, shared_alloc);
4418 for (xml_attribute_struct* sa = sn->first_attribute; sa; sa = sa->next_attribute)
4424 node_copy_string(da->name, da->header, xml_memory_page_name_allocated_mask, sa->name, sa->header, shared_alloc);
4425 node_copy_string(da->value, da->header, xml_memory_page_value_allocated_mask, sa->value, sa->header, shared_alloc);
4437 xml_node_struct* dit = dn;
4438 xml_node_struct* sit = sn->first_child;
4440 while (sit && sit != sn)
4454 if (sit->first_child)
4457 sit = sit->first_child;
4466 if (sit->next_sibling)
4468 sit = sit->next_sibling;
4476 assert(sit == sn || dit);
4481 assert(!sit || dit == dn->parent);
4489 node_copy_string(da->name, da->header, xml_memory_page_name_allocated_mask, sa->name, sa->header, shared_alloc);
4490 node_copy_string(da->value, da->header, xml_memory_page_value_allocated_mask, sa->value, sa->header, shared_alloc);
4504 const char_t* s =
value;
4511 s += (*s ==
'+' || *s ==
'-');
4513 bool overflow =
false;
4515 if (s[0] ==
'0' && (s[1] |
' ') ==
'x')
4523 const char_t* start =
s;
4527 if (static_cast<unsigned>(*s -
'0') < 10)
4528 result = result * 16 + (*s -
'0');
4529 else if (static_cast<unsigned>((*s |
' ') -
'a') < 6)
4530 result = result * 16 + ((*s |
' ') -
'a' + 10);
4537 size_t digits =
static_cast<size_t>(s -
start);
4539 overflow = digits >
sizeof(U) * 2;
4547 const char_t* start =
s;
4551 if (static_cast<unsigned>(*s -
'0') < 10)
4552 result = result * 10 + (*s -
'0');
4559 size_t digits =
static_cast<size_t>(s -
start);
4563 const size_t max_digits10 =
sizeof(U) == 8 ? 20 :
sizeof(U) == 4 ? 10 : 5;
4564 const char_t max_lead =
sizeof(U) == 8 ?
'1' :
sizeof(U) == 4 ?
'4' :
'6';
4565 const size_t high_bit =
sizeof(U) * 8 - 1;
4574 return (overflow || result > ~minv + 1) ? minv : ~result + 1;
4576 return (overflow || result > 0 - minv) ? minv : 0 -
result;
4580 return (overflow || result > maxv) ? maxv :
result;
4585 return string_to_integer<unsigned int>(
value,
static_cast<unsigned int>(INT_MIN), INT_MAX);
4590 return string_to_integer<unsigned int>(
value, 0, UINT_MAX);
4595 #ifdef PUGIXML_WCHAR_MODE
4596 return wcstod(value, 0);
4604 #ifdef PUGIXML_WCHAR_MODE
4605 return static_cast<float>(wcstod(value, 0));
4607 return static_cast<float>(
strtod(value, 0));
4617 return (first ==
'1' || first ==
't' || first ==
'T' || first ==
'y' || first ==
'Y');
4620 #ifdef PUGIXML_HAS_LONG_LONG
4621 PUGI__FN long long get_value_llong(
const char_t* value)
4623 return string_to_integer<unsigned long long>(
value,
static_cast<unsigned long long>(LLONG_MIN), LLONG_MAX);
4626 PUGI__FN unsigned long long get_value_ullong(
const char_t* value)
4628 return string_to_integer<unsigned long long>(
value, 0, ULLONG_MAX);
4634 char_t* result = end - 1;
4639 *result-- =
static_cast<char_t
>(
'0' + (rest % 10));
4644 assert(result >= begin);
4653 template <
typename String,
typename Header>
4656 #ifdef PUGIXML_WCHAR_MODE
4658 assert(strlen(buf) <
sizeof(wbuf) /
sizeof(wbuf[0]));
4661 for (; buf[
offset]; ++
offset) wbuf[offset] = buf[offset];
4663 return strcpy_insitu(dest, header, header_mask, wbuf, offset);
4665 return strcpy_insitu(dest, header, header_mask, buf, strlen(buf));
4669 template <
typename U,
typename String,
typename Header>
4673 char_t*
end = buf +
sizeof(
buf) /
sizeof(buf[0]);
4676 return strcpy_insitu(dest, header, header_mask, begin, end - begin);
4679 template <
typename String,
typename Header>
4688 template <
typename String,
typename Header>
4697 template <
typename String,
typename Header>
4719 if (own && buffer != contents && contents) impl::xml_memory::deallocate(contents);
4722 if (own || buffer != contents) *out_buffer =
buffer;
4728 xml_parse_result res = impl::xml_parser::parse(buffer, length, doc, root, options);
4731 res.encoding = buffer_encoding;
4739 #if defined(PUGI__MSVC_CRT_VERSION) && PUGI__MSVC_CRT_VERSION >= 1400
4741 typedef __int64 length_type;
4744 length_type length = _ftelli64(file);
4746 #elif defined(__MINGW32__) && !defined(__NO_MINGW_LFS) && (!defined(__STRICT_ANSI__) || defined(__MINGW64_VERSION_MAJOR))
4748 typedef off64_t length_type;
4751 length_type length = ftello64(file);
4755 typedef long length_type;
4758 length_type length =
ftell(file);
4766 size_t result =
static_cast<size_t>(
length);
4780 #ifdef PUGIXML_WCHAR_MODE
4783 if (encoding == wchar_encoding || need_endian_swap_utf(encoding, wchar_encoding))
4785 size_t length = size /
sizeof(
char_t);
4787 static_cast<char_t*
>(
buffer)[length] = 0;
4788 return (length + 1) *
sizeof(
char_t);
4793 static_cast<char*
>(
buffer)[size] = 0;
4810 size_t max_suffix_size =
sizeof(
char_t);
4817 size_t read_size = fread(contents, 1, size, file);
4819 if (read_size != size)
4827 return load_buffer_impl(doc, doc, contents,
zero_terminate_buffer(contents, size, real_encoding), options, real_encoding,
true,
true, out_buffer);
4835 #ifndef PUGIXML_NO_STL
4841 if (!memory)
return 0;
4866 T data[xml_memory_page_size /
sizeof(
T)];
4877 while (!stream.eof())
4884 if (last) last = last->
next = chunk;
4885 else chunks.
data = last = chunk;
4888 stream.read(chunk->
data, static_cast<std::streamsize>(
sizeof(chunk->
data) /
sizeof(
T)));
4889 chunk->
size =
static_cast<size_t>(stream.gcount()) *
sizeof(
T);
4892 if (stream.bad() || (!stream.eof() && stream.fail()))
return status_io_error;
4896 total += chunk->
size;
4899 size_t max_suffix_size =
sizeof(
char_t);
4909 assert(write + chunk->size <= buffer + total);
4910 memcpy(write, chunk->data, chunk->size);
4911 write += chunk->size;
4914 assert(write == buffer + total);
4926 typename std::basic_istream<T>::pos_type pos = stream.tellg();
4928 std::streamoff length = stream.tellg() - pos;
4934 size_t read_length =
static_cast<size_t>(
length);
4936 if (static_cast<std::streamsize>(read_length) != length || length < 0)
return status_out_of_memory;
4938 size_t max_suffix_size =
sizeof(
char_t);
4944 stream.read(static_cast<T*>(buffer.
data), static_cast<std::streamsize>(read_length));
4947 if (stream.bad() || (!stream.eof() && stream.fail()))
return status_io_error;
4950 size_t actual_length =
static_cast<size_t>(stream.gcount());
4951 assert(actual_length <= read_length);
4953 *out_buffer = buffer.
release();
4954 *out_size = actual_length *
sizeof(
T);
4969 if (stream.tellg() < 0)
4981 return load_buffer_impl(doc, doc, buffer,
zero_terminate_buffer(buffer, size, real_encoding), options, real_encoding,
true,
true, out_buffer);
4985 #if defined(PUGI__MSVC_CRT_VERSION) || defined(__BORLANDC__) || (defined(__MINGW32__) && (!defined(__STRICT_ANSI__) || defined(__MINGW64_VERSION_MAJOR)))
4988 #if defined(PUGI__MSVC_CRT_VERSION) && PUGI__MSVC_CRT_VERSION >= 1400
4990 return _wfopen_s(&file, path, mode) == 0 ? file : 0;
4992 return _wfopen(path, mode);
5006 if (!result)
return 0;
5021 if (!path_utf8)
return 0;
5024 char mode_ascii[4] = {0};
5025 for (
size_t i = 0; mode[i]; ++i) mode_ascii[i] = static_cast<char>(mode[i]);
5028 FILE* result =
fopen(path_utf8, mode_ascii);
5039 #if defined(PUGI__MSVC_CRT_VERSION) && PUGI__MSVC_CRT_VERSION >= 1400
5041 return fopen_s(&file, path, mode) == 0 ? file : 0;
5043 return fopen(path, mode);
5049 if (!file)
return false;
5051 xml_writer_file writer(file);
5052 doc.save(writer, indent, flags, encoding);
5054 return ferror(file) == 0;
5082 size_t result = fwrite(data, 1, size, static_cast<FILE*>(file));
5086 #ifndef PUGIXML_NO_STL
5099 assert(!wide_stream);
5100 narrow_stream->write(reinterpret_cast<const char*>(data), static_cast<std::streamsize>(size));
5104 assert(wide_stream);
5105 assert(size %
sizeof(
wchar_t) == 0);
5107 wide_stream->write(reinterpret_cast<const wchar_t*>(data), static_cast<std::streamsize>(size /
sizeof(
wchar_t)));
5147 PUGI__FN xml_attribute::operator xml_attribute::unspecified_bool_type()
const
5149 return _attr ? unspecified_bool_xml_attribute : 0;
5159 return (_attr == r._attr);
5164 return (_attr != r._attr);
5169 return (_attr < r._attr);
5174 return (_attr > r._attr);
5179 return (_attr <= r._attr);
5184 return (_attr >= r._attr);
5199 return (_attr && _attr->
value) ? _attr->
value + 0 : def;
5227 #ifdef PUGIXML_HAS_LONG_LONG
5228 PUGI__FN long long xml_attribute::as_llong(
long long def)
const
5230 return (_attr && _attr->
value) ? impl::get_value_llong(_attr->
value) : def;
5233 PUGI__FN unsigned long long xml_attribute::as_ullong(
unsigned long long def)
const
5235 return (_attr && _attr->
value) ? impl::get_value_ullong(_attr->
value) : def;
5312 #ifdef PUGIXML_HAS_LONG_LONG
5328 if (!_attr)
return false;
5335 if (!_attr)
return false;
5342 if (!_attr)
return false;
5344 return impl::set_value_integer<unsigned int>(_attr->
value, _attr->
header, impl::xml_memory_page_value_allocated_mask, rhs, rhs < 0);
5349 if (!_attr)
return false;
5351 return impl::set_value_integer<unsigned int>(_attr->
value, _attr->
header, impl::xml_memory_page_value_allocated_mask, rhs,
false);
5356 if (!_attr)
return false;
5358 return impl::set_value_integer<unsigned long>(_attr->
value, _attr->
header, impl::xml_memory_page_value_allocated_mask, rhs, rhs < 0);
5363 if (!_attr)
return false;
5365 return impl::set_value_integer<unsigned long>(_attr->
value, _attr->
header, impl::xml_memory_page_value_allocated_mask, rhs,
false);
5370 if (!_attr)
return false;
5377 if (!_attr)
return false;
5384 if (!_attr)
return false;
5391 if (!_attr)
return false;
5398 if (!_attr)
return false;
5403 #ifdef PUGIXML_HAS_LONG_LONG
5406 if (!_attr)
return false;
5408 return impl::set_value_integer<unsigned long long>(_attr->
value, _attr->
header, impl::xml_memory_page_value_allocated_mask, rhs, rhs < 0);
5413 if (!_attr)
return false;
5415 return impl::set_value_integer<unsigned long long>(_attr->
value, _attr->
header, impl::xml_memory_page_value_allocated_mask, rhs,
false);
5422 return (
bool)lhs && rhs;
5427 return (
bool)lhs || rhs;
5445 return _root ? unspecified_bool_xml_node : 0;
5845 if (!alloc.reserve())
return xml_node();
5862 if (!alloc.reserve())
return xml_node();
5880 if (!alloc.reserve())
return xml_node();
5898 if (!alloc.reserve())
return xml_node();
5952 if (!alloc.reserve())
return xml_node();
5969 if (!alloc.reserve())
return xml_node();
5987 if (!alloc.reserve())
return xml_node();
6005 if (!alloc.reserve())
return xml_node();
6021 if (!alloc.reserve())
return xml_node();
6037 if (!alloc.reserve())
return xml_node();
6055 if (!alloc.reserve())
return xml_node();
6073 if (!alloc.reserve())
return xml_node();
6091 if (!
_root || !a._attr)
return false;
6095 if (!alloc.reserve())
return false;
6105 if (!
_root)
return false;
6108 if (!alloc.reserve())
return false;
6134 if (!alloc.reserve())
return false;
6144 if (!
_root)
return false;
6147 if (!alloc.reserve())
return false;
6172 doc->header |= impl::xml_memory_page_contents_shared_mask;
6175 impl::xml_memory_page* page = 0;
6176 impl::xml_extra_buffer* extra =
static_cast<impl::xml_extra_buffer*
>(doc->allocate_memory(
sizeof(impl::xml_extra_buffer) +
sizeof(
void*), page));
6181 #ifdef PUGIXML_COMPACT
6184 extra =
reinterpret_cast<impl::xml_extra_buffer*
>((
reinterpret_cast<uintptr_t>(extra) + (
sizeof(
void*) - 1)) & ~(
sizeof(
void*) - 1));
6189 extra->next = doc->extra_buffers;
6190 doc->extra_buffers = extra;
6193 impl::name_null_sentry sentry(
_root);
6225 #ifndef PUGIXML_NO_STL
6234 offset += (i !=
_root);
6239 result.resize(offset);
6244 result[--
offset] = delimiter;
6251 memcpy(&result[offset],
j->name, length *
sizeof(char_t));
6255 assert(offset == 0);
6263 xml_node context = path_[0] == delimiter ?
root() : *
this;
6267 const char_t* path_segment = path_;
6269 while (*path_segment == delimiter) ++path_segment;
6271 const char_t* path_segment_end = path_segment;
6273 while (*path_segment_end && *path_segment_end != delimiter) ++path_segment_end;
6275 if (path_segment == path_segment_end)
return context;
6277 const char_t* next_segment = path_segment_end;
6279 while (*next_segment == delimiter) ++next_segment;
6281 if (*path_segment ==
'.' && path_segment + 1 == path_segment_end)
6283 else if (*path_segment ==
'.' && *(path_segment+1) ==
'.' && path_segment + 2 == path_segment_end)
6289 if (
j->name &&
impl::strequalrange(
j->name, path_segment, static_cast<size_t>(path_segment_end - path_segment)))
6291 xml_node subsearch =
xml_node(
j).first_element_by_path(next_segment, delimiter);
6293 if (subsearch)
return subsearch;
6306 if (!walker.
begin(arg_begin))
return false;
6317 if (!walker.
for_each(arg_for_each))
6320 if (cur->first_child)
6323 cur = cur->first_child;
6325 else if (cur->next_sibling)
6326 cur = cur->next_sibling;
6329 while (!cur->next_sibling && cur !=
_root && cur->parent)
6336 cur = cur->next_sibling;
6339 while (cur && cur !=
_root);
6342 assert(walker._depth == -1);
6345 return walker.
end(arg_end);
6362 impl::xml_buffered_writer buffered_writer(writer, encoding);
6366 buffered_writer.flush();
6369 #ifndef PUGIXML_NO_STL
6374 print(writer, indent, flags, encoding, depth);
6387 if (!
_root)
return -1;
6392 if (!doc.buffer || doc.extra_buffers)
return -1;
6411 assert(
false &&
"Invalid node type");
6419 return (
bool)lhs && rhs;
6424 return (
bool)lhs || rhs;
6432 PUGI__FN xml_node_struct* xml_text::_data()
const
6447 PUGI__FN xml_node_struct* xml_text::_data_new()
6449 xml_node_struct* d = _data();
6463 PUGI__FN xml_text::operator xml_text::unspecified_bool_type()
const
6465 return _data() ? unspecified_bool_xml_text : 0;
6475 return _data() == 0;
6482 return (d && d->value) ? d->value + 0 :
PUGIXML_TEXT(
"");
6489 return (d && d->value) ? d->value + 0 : def;
6527 #ifdef PUGIXML_HAS_LONG_LONG
6528 PUGI__FN long long xml_text::as_llong(
long long def)
const
6532 return (d && d->value) ? impl::get_value_llong(d->value) : def;
6535 PUGI__FN unsigned long long xml_text::as_ullong(
unsigned long long def)
const
6537 xml_node_struct* d = _data();
6539 return (d && d->value) ? impl::get_value_ullong(d->value) : def;
6554 return dn ? impl::set_value_integer<unsigned int>(dn->value, dn->header, impl::xml_memory_page_value_allocated_mask, rhs, rhs < 0) :
false;
6561 return dn ? impl::set_value_integer<unsigned int>(dn->value, dn->header, impl::xml_memory_page_value_allocated_mask, rhs,
false) :
false;
6568 return dn ? impl::set_value_integer<unsigned long>(dn->value, dn->header, impl::xml_memory_page_value_allocated_mask, rhs, rhs < 0) :
false;
6575 return dn ? impl::set_value_integer<unsigned long>(dn->value, dn->header, impl::xml_memory_page_value_allocated_mask, rhs,
false) :
false;
6589 return dn ?
impl::set_value_convert(dn->value, dn->header, impl::xml_memory_page_value_allocated_mask, rhs, precision) :
false;
6603 return dn ?
impl::set_value_convert(dn->value, dn->header, impl::xml_memory_page_value_allocated_mask, rhs, precision) :
false;
6610 return dn ?
impl::set_value_bool(dn->value, dn->header, impl::xml_memory_page_value_allocated_mask, rhs) :
false;
6613 #ifdef PUGIXML_HAS_LONG_LONG
6618 return dn ? impl::set_value_integer<unsigned long long>(dn->value, dn->header, impl::xml_memory_page_value_allocated_mask, rhs, rhs < 0) :
false;
6623 xml_node_struct* dn = _data_new();
6625 return dn ? impl::set_value_integer<unsigned long long>(dn->value, dn->header, impl::xml_memory_page_value_allocated_mask, rhs,
false) :
false;
6677 #ifdef PUGIXML_HAS_LONG_LONG
6699 return (
bool)lhs && rhs;
6704 return (
bool)lhs || rhs;
6732 assert(_wrap.
_root);
6738 assert(_wrap.
_root);
6739 return const_cast<xml_node*
>(&_wrap);
6744 assert(_wrap.
_root);
6783 return _wrap._attr == rhs._wrap._attr && _parent.
_root == rhs._parent.
_root;
6788 return _wrap._attr != rhs._wrap._attr || _parent.
_root != rhs._parent.
_root;
6793 assert(_wrap._attr);
6799 assert(_wrap._attr);
6805 assert(_wrap._attr);
6854 assert(_wrap.
_root);
6860 assert(_wrap.
_root);
6861 return const_cast<xml_node*
>(&_wrap);
6866 assert(_wrap.
_root);
6922 case status_bad_pi:
return "Error parsing document declaration/processing instruction";
6936 default:
return "Unknown error";
6950 #ifdef PUGIXML_HAS_MOVE
6959 if (
this == &rhs)
return *
this;
6982 PUGI__FN void xml_document::_create()
6986 #ifdef PUGIXML_COMPACT
6988 const size_t page_offset =
sizeof(
void*);
6990 const size_t page_offset = 0;
6994 PUGI__STATIC_ASSERT(
sizeof(impl::xml_memory_page) +
sizeof(impl::xml_document_struct) + page_offset <=
sizeof(_memory));
6997 impl::xml_memory_page* page = impl::xml_memory_page::construct(_memory);
7000 page->busy_size = impl::xml_memory_page_size;
7003 #ifdef PUGIXML_COMPACT
7005 page->compact_page_marker =
reinterpret_cast<uint32_t*
>(
static_cast<void*
>(
reinterpret_cast<char*
>(page) +
sizeof(impl::xml_memory_page)));
7006 *page->compact_page_marker =
sizeof(impl::xml_memory_page);
7010 _root =
new (
reinterpret_cast<char*
>(page) +
sizeof(impl::xml_memory_page) + page_offset) impl::xml_document_struct(page);
7014 page->allocator =
static_cast<impl::xml_document_struct*
>(
_root);
7017 #ifdef PUGIXML_COMPACT
7018 page->allocator->_hash = &
static_cast<impl::xml_document_struct*
>(
_root)->hash;
7022 assert(reinterpret_cast<char*>(
_root) +
sizeof(impl::xml_document_struct) <= _memory +
sizeof(_memory));
7025 PUGI__FN void xml_document::_destroy()
7032 impl::xml_memory::deallocate(_buffer);
7037 for (impl::xml_extra_buffer* extra = static_cast<impl::xml_document_struct*>(
_root)->extra_buffers; extra; extra = extra->next)
7039 if (extra->buffer) impl::xml_memory::deallocate(extra->buffer);
7044 assert(root_page && !root_page->prev);
7045 assert(reinterpret_cast<char*>(root_page) >= _memory && reinterpret_cast<char*>(root_page) < _memory +
sizeof(_memory));
7047 for (impl::xml_memory_page* page = root_page->next; page; )
7049 impl::xml_memory_page* next = page->next;
7051 impl::xml_allocator::deallocate_page(page);
7056 #ifdef PUGIXML_COMPACT
7058 static_cast<impl::xml_document_struct*
>(
_root)->
hash.clear();
7064 #ifdef PUGIXML_HAS_MOVE
7065 PUGI__FN void xml_document::_move(xml_document& rhs) PUGIXML_NOEXCEPT_IF_NOT_COMPACT
7067 impl::xml_document_struct* doc =
static_cast<impl::xml_document_struct*
>(_root);
7068 impl::xml_document_struct* other =
static_cast<impl::xml_document_struct*
>(rhs._root);
7071 xml_node_struct* other_first_child = other->first_child;
7073 #ifdef PUGIXML_COMPACT
7076 if (other_first_child)
7078 size_t other_children = 0;
7079 for (xml_node_struct* node = other_first_child; node; node = node->next_sibling)
7086 if (!other->_hash->reserve(other_children + 1))
7088 #ifdef PUGIXML_NO_EXCEPTIONS
7091 throw std::bad_alloc();
7101 doc->_root = other->_root;
7102 doc->_busy_size = other->_busy_size;
7106 doc->buffer = other->buffer;
7107 doc->extra_buffers = other->extra_buffers;
7108 _buffer = rhs._buffer;
7110 #ifdef PUGIXML_COMPACT
7112 doc->hash = other->hash;
7113 doc->_hash = &doc->hash;
7121 assert(doc_page && !doc_page->prev && !doc_page->next);
7124 assert(other_page && !other_page->prev);
7127 if (impl::xml_memory_page* page = other_page->next)
7129 assert(page->prev == other_page);
7131 page->prev = doc_page;
7133 doc_page->next = page;
7134 other_page->next = 0;
7138 for (impl::xml_memory_page* page = doc_page->next; page; page = page->next)
7140 assert(page->allocator == other);
7142 page->allocator = doc;
7144 #ifdef PUGIXML_COMPACT
7146 if (page->compact_shared_parent == other)
7147 page->compact_shared_parent = doc;
7152 assert(!doc->first_child);
7154 doc->first_child = other_first_child;
7156 for (xml_node_struct* node = other_first_child; node; node = node->next_sibling)
7158 #ifdef PUGIXML_COMPACT
7160 assert(node->parent == other || node->parent == doc);
7164 assert(node->parent == other);
7170 new (other) impl::xml_document_struct(
PUGI__GETPAGE(other));
7175 #ifndef PUGIXML_NO_STL
7194 #ifdef PUGIXML_WCHAR_MODE
7212 using impl::auto_deleter;
7222 using impl::auto_deleter;
7232 return impl::load_buffer_impl(static_cast<impl::xml_document_struct*>(
_root),
_root, const_cast<void*>(contents), size, options, encoding,
false,
false, &_buffer);
7251 impl::xml_buffered_writer buffered_writer(writer, encoding);
7256 #ifdef PUGIXML_WCHAR_MODE
7257 unsigned int bom = 0xfeff;
7258 buffered_writer.write(static_cast<wchar_t>(bom));
7260 buffered_writer.write(
'\xef',
'\xbb',
'\xbf');
7266 buffered_writer.write_string(
PUGIXML_TEXT(
"<?xml version=\"1.0\""));
7268 buffered_writer.write(
'?',
'>');
7269 if (!(flags &
format_raw)) buffered_writer.write(
'\n');
7274 buffered_writer.flush();
7277 #ifndef PUGIXML_NO_STL
7282 save(writer, indent, flags, encoding);
7295 using impl::auto_deleter;
7303 using impl::auto_deleter;
7320 #ifndef PUGIXML_NO_STL
7348 impl::xml_memory::allocate = allocate;
7349 impl::xml_memory::deallocate = deallocate;
7354 return impl::xml_memory::allocate;
7359 return impl::xml_memory::deallocate;
7363 #if !defined(PUGIXML_NO_STL) && (defined(_MSC_VER) || defined(__ICC))
7369 return std::bidirectional_iterator_tag();
7374 return std::bidirectional_iterator_tag();
7379 return std::bidirectional_iterator_tag();
7384 #if !defined(PUGIXML_NO_STL) && defined(__SUNPRO_CC)
7390 return std::bidirectional_iterator_tag();
7395 return std::bidirectional_iterator_tag();
7400 return std::bidirectional_iterator_tag();
7405 #ifndef PUGIXML_NO_XPATH
7440 template <
typename T>
inline void swap(T& lhs, T& rhs)
7451 for (I it = begin + 1; it !=
end; ++it)
7452 if (pred(*it, *result))
7460 while (end - begin > 1)
7461 swap(*begin++, *--end);
7467 while (end - begin > 1 && *begin != *(begin + 1))
7477 while (begin != end)
7479 if (*begin != *write)
7480 *++write = *begin++;
7494 for (
T* it = begin + 1; it !=
end; ++it)
7500 while (hole > begin && pred(val, *(hole - 1)))
7502 *hole = *(hole - 1);
7511 template <
typename I,
typename Pred>
inline I
median3(I
first, I middle, I
last,
const Pred& pred)
7513 if (pred(*middle, *first))
7514 swap(middle, first);
7515 if (pred(*last, *middle))
7517 if (pred(*middle, *first))
7518 swap(middle, first);
7532 if (pred(*lt, pivot))
7534 else if (*lt == pivot)
7543 for (
T* it = begin; it != eq; ++it)
7544 swap(*it, *--eqbeg);
7553 while (end - begin > 16)
7556 I middle = begin + (end -
begin) / 2;
7557 I median =
median3(begin, middle, end - 1, pred);
7561 partition3(begin, end, *median, pred, &eqbeg, &eqend);
7564 if (eqbeg - begin > end - eqend)
7566 sort(eqend, end, pred);
7571 sort(begin, eqbeg, pred);
7584 unsigned int h =
static_cast<unsigned int>(
reinterpret_cast<uintptr_t>(key));
7593 size_t hashmod = size - 1;
7594 size_t bucket = h & hashmod;
7596 for (
size_t probe = 0; probe <= hashmod; ++probe)
7598 if (table[bucket] == 0)
7600 table[bucket] = key;
7604 if (table[bucket] == key)
7608 bucket = (bucket + probe + 1) & hashmod;
7611 assert(
false &&
"Hash table is full");
7618 static const size_t xpath_memory_page_size =
7619 #ifdef PUGIXML_MEMORY_XPATH_PAGE_SIZE
7620 PUGIXML_MEMORY_XPATH_PAGE_SIZE
7626 static const uintptr_t xpath_memory_block_alignment =
sizeof(double) >
sizeof(
void*) ?
sizeof(double) :
sizeof(
void*);
7635 char data[xpath_memory_page_size];
7653 size = (size + xpath_memory_block_alignment - 1) & ~(xpath_memory_block_alignment - 1);
7664 size_t block_capacity_base =
sizeof(
_root->
data);
7665 size_t block_capacity_req = size + block_capacity_base / 4;
7666 size_t block_capacity = (block_capacity_base > block_capacity_req) ? block_capacity_base : block_capacity_req;
7690 old_size = (old_size + xpath_memory_block_alignment - 1) & ~(xpath_memory_block_alignment - 1);
7691 new_size = (new_size + xpath_memory_block_alignment - 1) & ~(xpath_memory_block_alignment - 1);
7697 if (ptr &&
_root_size - old_size + new_size <= _root->capacity)
7705 if (!result)
return 0;
7711 assert(new_size >= old_size);
7712 memcpy(result, ptr, old_size);
7739 while (cur != state.
_root)
7819 const char_t* _buffer;
7821 size_t _length_heap;
7823 static char_t* duplicate_string(
const char_t*
string,
size_t length,
xpath_allocator* alloc)
7825 char_t* result =
static_cast<char_t*
>(alloc->
allocate((length + 1) *
sizeof(char_t)));
7826 if (!result)
return 0;
7828 memcpy(result,
string, length *
sizeof(char_t));
7834 xpath_string(
const char_t* buffer,
bool uses_heap_,
size_t length_heap): _buffer(buffer), _uses_heap(uses_heap_), _length_heap(length_heap)
7846 assert(begin <= end && *end == 0);
7848 return xpath_string(begin,
true, static_cast<size_t>(end - begin));
7853 assert(begin <= end);
7858 size_t length =
static_cast<size_t>(end -
begin);
7859 const char_t* data = duplicate_string(begin, length, alloc);
7871 if (!*o._buffer)
return;
7874 if (!*_buffer && !_uses_heap && !o._uses_heap)
7876 _buffer = o._buffer;
7881 size_t target_length =
length();
7882 size_t source_length = o.
length();
7883 size_t result_length = target_length + source_length;
7886 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)));
7887 if (!result)
return;
7890 if (!_uses_heap) memcpy(result, _buffer, target_length *
sizeof(char_t));
7893 memcpy(result + target_length, o._buffer, source_length *
sizeof(char_t));
7894 result[result_length] = 0;
7899 _length_heap = result_length;
7910 return _uses_heap ? _length_heap :
strlength(_buffer);
7919 const char_t* data_ = duplicate_string(_buffer, length_, alloc);
7921 if (!data_)
return 0;
7925 _length_heap = length_;
7928 return const_cast<char_t*
>(_buffer);
7933 return *_buffer == 0;
7938 return strequal(_buffer, o._buffer);
7943 return !
strequal(_buffer, o._buffer);
7956 while (*pattern && *
string == *pattern)
7962 return *pattern == 0;
7967 #ifdef PUGIXML_WCHAR_MODE
7968 return wcschr(s, c);
7970 return strchr(s, c);
7976 #ifdef PUGIXML_WCHAR_MODE
7978 return (*p == 0) ? s : wcsstr(s, p);
7980 return strstr(s, p);
7987 return static_cast<unsigned int>(ch -
'A') < 26 ? static_cast<char_t>(ch |
' ') : ch;
7996 xml_node
n = na.node();
8015 xml_node cur = n.first_child();
8017 while (cur && cur != n)
8022 if (cur.first_child())
8023 cur = cur.first_child();
8024 else if (cur.next_sibling())
8025 cur = cur.next_sibling();
8028 while (!cur.next_sibling() && cur !=
n)
8031 if (cur != n) cur = cur.next_sibling();
8046 assert(ln->parent == rn->parent);
8049 if (!ln->parent)
return ln < rn;
8052 xml_node_struct* ls = ln;
8053 xml_node_struct* rs = rn;
8057 if (ls == rn)
return true;
8058 if (rs == ln)
return false;
8060 ls = ls->next_sibling;
8061 rs = rs->next_sibling;
8071 xml_node_struct* lp = ln;
8072 xml_node_struct* rp = rn;
8074 while (lp && rp && lp->parent != rp->parent)
8084 bool left_higher = !lp;
8099 if (ln == rn)
return left_higher;
8102 while (ln->parent != rn->parent)
8113 while (node && node != parent) node = node->parent;
8115 return parent && node == parent;
8120 xml_node_struct* node = xnode.node().internal_object();
8124 if ((
get_document(node).header & xml_memory_page_contents_shared_mask) == 0)
8126 if (node->name && (node->header & impl::xml_memory_page_name_allocated_or_shared_mask) == 0)
return node->name;
8127 if (node->value && (node->header & impl::xml_memory_page_value_allocated_or_shared_mask) == 0)
return node->value;
8133 xml_attribute_struct* attr = xnode.attribute().internal_object();
8137 if ((
get_document(attr).header & xml_memory_page_contents_shared_mask) == 0)
8139 if ((attr->header & impl::xml_memory_page_name_allocated_or_shared_mask) == 0)
return attr->name;
8140 if ((attr->header & impl::xml_memory_page_value_allocated_or_shared_mask) == 0)
return attr->value;
8151 bool operator()(
const xpath_node& lhs,
const xpath_node& rhs)
const
8157 if (lo && ro)
return lo < ro;
8160 xml_node ln = lhs.node(), rn = rhs.node();
8163 if (lhs.attribute() && rhs.attribute())
8166 if (lhs.parent() == rhs.parent())
8169 for (xml_attribute
a = lhs.attribute();
a;
a =
a.next_attribute())
8170 if (
a == rhs.attribute())
8180 else if (lhs.attribute())
8183 if (lhs.parent() == rhs.node())
return false;
8187 else if (rhs.attribute())
8190 if (rhs.parent() == lhs.node())
return true;
8195 if (ln == rn)
return false;
8197 if (!ln || !rn)
return ln < rn;
8199 return node_is_before(ln.internal_object(), rn.internal_object());
8205 #if defined(__STDC_IEC_559__) || ((FLT_RADIX - 0 == 2) && (FLT_MAX_EXP - 0 == 128) && (FLT_MANT_DIG - 0 == 24))
8207 typedef uint32_t UI;
8208 union {
float f; UI i; } u;
8213 const volatile double zero = 0.0;
8220 #if defined(PUGI__MSVC_CRT_VERSION) || defined(__BORLANDC__)
8221 return !!_isnan(value);
8222 #elif defined(fpclassify) && defined(FP_NAN)
8223 return fpclassify(value) == FP_NAN;
8226 const volatile double v =
value;
8233 #if defined(PUGI__MSVC_CRT_VERSION) || defined(__BORLANDC__)
8234 if (_finite(value))
return (value == 0) ?
PUGIXML_TEXT(
"0") : 0;
8237 #elif defined(fpclassify) && defined(FP_NAN) && defined(FP_INFINITE) && defined(FP_ZERO)
8238 switch (fpclassify(value))
8254 const volatile double v =
value;
8265 return (value != 0 && !
is_nan(value));
8270 while (begin != end && end[-1] ==
'0') end--;
8276 #if defined(PUGI__MSVC_CRT_VERSION) && PUGI__MSVC_CRT_VERSION >= 1400
8281 _ecvt_s(buffer,
sizeof(buffer), value, DBL_DIG + 1, &exponent, &sign);
8288 *out_exponent = exponent;
8297 char* exponent_string = strchr(buffer,
'e');
8298 assert(exponent_string);
8300 int exponent = atoi(exponent_string + 1);
8303 char* mantissa = buffer[0] ==
'-' ? buffer + 1 :
buffer;
8304 assert(mantissa[0] !=
'0' && mantissa[1] ==
'.');
8307 mantissa[1] = mantissa[0];
8315 *out_mantissa = mantissa;
8316 *out_exponent = exponent;
8327 char mantissa_buffer[32];
8334 size_t result_size = strlen(mantissa_buffer) + (exponent > 0 ? exponent : -exponent) + 4;
8335 char_t* result =
static_cast<char_t*
>(alloc->
allocate(
sizeof(char_t) * result_size));
8342 if (value < 0) *s++ =
'-';
8351 while (exponent > 0)
8353 assert(*mantissa == 0 || static_cast<unsigned int>(*mantissa -
'0') <= 9);
8354 *s++ = *mantissa ? *mantissa++ :
'0';
8366 while (exponent < 0)
8375 assert(static_cast<unsigned int>(*mantissa -
'0') <= 9);
8381 assert(s < result + result_size);
8393 if (*
string ==
'-') ++
string;
8395 if (!*
string)
return false;
8414 return *
string == 0;
8423 #ifdef PUGIXML_WCHAR_MODE
8424 return wcstod(
string, 0);
8426 return strtod(
string, 0);
8432 size_t length =
static_cast<size_t>(end -
begin);
8433 char_t* scratch =
buffer;
8435 if (length >=
sizeof(buffer) /
sizeof(buffer[0]))
8439 if (!scratch)
return false;
8443 memcpy(scratch, begin, length *
sizeof(char_t));
8456 return floor(value + 0.5);
8463 return (value >= -0.5 && value <= 0) ?
ceil(value) :
floor(value + 0.5);
8468 return node.attribute() ? node.attribute().name() : node.node().name();
8476 return p ? p + 1 :
name;
8486 const char_t* pos =
find_char(name,
':');
8494 const char_t*
name = a.name();
8510 xml_attribute
a = p.find_attribute(pred);
8512 if (a)
return a.value();
8527 xml_node p = parent;
8531 xml_attribute
a = p.find_attribute(pred);
8533 if (a)
return a.value();
8550 for (char_t* it = buffer; *it; )
8560 if (write != buffer) *write++ =
' ';
8582 const char_t* pos =
find_char(from, ch);
8586 else if (static_cast<size_t>(pos - from) < to_length)
8587 *write++ = to[pos - from];
8598 unsigned char table[128] = {0};
8602 unsigned int fc =
static_cast<unsigned int>(*from);
8603 unsigned int tc =
static_cast<unsigned int>(*to);
8605 if (fc >= 128 || tc >= 128)
8610 table[fc] =
static_cast<unsigned char>(tc ? tc : 128);
8616 for (
int i = 0; i < 128; ++i)
8618 table[i] =
static_cast<unsigned char>(i);
8620 void* result = alloc->
allocate(
sizeof(table));
8621 if (!result)
return 0;
8623 memcpy(result, table,
sizeof(table));
8625 return static_cast<unsigned char*
>(
result);
8634 char_t ch = *buffer++;
8635 unsigned int index =
static_cast<unsigned int>(ch);
8639 unsigned char code = table[
index];
8643 *write =
static_cast<char_t
>(code);
8644 write += 1 - (code >> 7);
8708 static const xpath_node_set dummy_node_set;
8713 unsigned int result = 0;
8717 result +=
static_cast<unsigned int>(*str++);
8718 result += result << 10;
8719 result ^= result >> 6;
8722 result += result << 3;
8723 result ^= result >> 11;
8724 result += result << 15;
8732 if (length == 0)
return 0;
8736 if (!memory)
return 0;
8740 memcpy(result->name, name, (length + 1) *
sizeof(char_t));
8750 return new_xpath_variable<xpath_variable_node_set>(
name);
8753 return new_xpath_variable<xpath_variable_number>(
name);
8756 return new_xpath_variable<xpath_variable_string>(
name);
8759 return new_xpath_variable<xpath_variable_boolean>(
name);
8793 assert(
false &&
"Invalid variable type");
8799 switch (rhs->type())
8802 return lhs->set(static_cast<const xpath_variable_node_set*>(rhs)->value);
8805 return lhs->set(static_cast<const xpath_variable_number*>(rhs)->value);
8808 return lhs->set(static_cast<const xpath_variable_string*>(rhs)->value);
8811 return lhs->set(static_cast<const xpath_variable_boolean*>(rhs)->value);
8814 assert(
false &&
"Invalid variable type");
8821 size_t length =
static_cast<size_t>(end -
begin);
8822 char_t* scratch =
buffer;
8824 if (length >=
sizeof(buffer) /
sizeof(buffer[0]))
8828 if (!scratch)
return false;
8832 memcpy(scratch, begin, length *
sizeof(char_t));
8835 *out_result = set->get(scratch);
8848 if (end - begin < 2)
8849 return xpath_node_set::type_sorted;
8853 bool first =
cmp(begin[0], begin[1]);
8855 for (
const xpath_node* it = begin + 1; it + 1 <
end; ++it)
8856 if (
cmp(it[0], it[1]) != first)
8857 return xpath_node_set::type_unsorted;
8859 return first ? xpath_node_set::type_sorted : xpath_node_set::type_sorted_reverse;
8864 xpath_node_set::type_t
order = rev ? xpath_node_set::type_sorted_reverse : xpath_node_set::type_sorted;
8866 if (type == xpath_node_set::type_unsorted)
8870 if (sorted == xpath_node_set::type_unsorted)
8874 type = xpath_node_set::type_sorted;
8880 if (type != order)
reverse(begin, end);
8887 if (begin == end)
return xpath_node();
8891 case xpath_node_set::type_sorted:
8894 case xpath_node_set::type_sorted_reverse:
8897 case xpath_node_set::type_unsorted:
8901 assert(
false &&
"Invalid node set type");
8902 return xpath_node();
8908 xpath_node_set::type_t _type;
8931 return _begin == _end;
8936 return static_cast<size_t>(_end - _begin);
8956 if (begin_ == end_)
return;
8958 size_t size_ =
static_cast<size_t>(_end - _begin);
8959 size_t capacity =
static_cast<size_t>(_eos - _begin);
8960 size_t count =
static_cast<size_t>(end_ - begin_);
8962 if (size_ + count > capacity)
8965 xpath_node* data =
static_cast<xpath_node*
>(alloc->
reallocate(_begin, capacity *
sizeof(xpath_node), (size_ + count) *
sizeof(xpath_node)));
8970 _end = data + size_;
8971 _eos = data + size_ +
count;
8974 memcpy(_end, begin_, count *
sizeof(xpath_node));
8980 _type =
xpath_sort(_begin, _end, _type,
false);
8985 assert(_begin <= pos && pos <= _end);
8992 if (_type == xpath_node_set::type_unsorted && _end - _begin > 2)
8996 size_t size_ =
static_cast<size_t>(_end - _begin);
8998 size_t hash_size = 1;
8999 while (hash_size < size_ + size_ / 2) hash_size *= 2;
9001 const void** hash_data =
static_cast<const void**
>(alloc->
allocate(hash_size *
sizeof(
void**)));
9002 if (!hash_data)
return;
9004 memset(hash_data, 0, hash_size *
sizeof(
const void**));
9006 xpath_node* write = _begin;
9008 for (xpath_node* it = _begin; it != _end; ++it)
9010 const void* attr = it->attribute().internal_object();
9011 const void* node = it->node().internal_object();
9012 const void* key = attr ? attr : node;
9014 if (key &&
hash_insert(hash_data, hash_size, key))
9024 _end =
unique(_begin, _end);
9028 xpath_node_set::type_t
type()
const
9041 size_t capacity =
static_cast<size_t>(_eos - _begin);
9044 size_t new_capacity = capacity + capacity / 2 + 1;
9047 xpath_node* data =
static_cast<xpath_node*
>(alloc->
reallocate(_begin, capacity *
sizeof(xpath_node), new_capacity *
sizeof(xpath_node)));
9052 _end = data + capacity;
9053 _eos = data + new_capacity;
9113 size_t length =
static_cast<size_t>(
end -
begin);
9122 const char_t* _cur_lexeme_pos;
9140 const char_t* cur = _cur;
9145 _cur_lexeme_pos = cur;
9154 if (*(cur+1) ==
'=')
9167 if (*(cur+1) ==
'=')
9180 if (*(cur+1) ==
'=')
9226 _cur_lexeme_contents.
begin = cur;
9237 _cur_lexeme_contents.
end = cur;
9279 if (*(cur+1) ==
'/')
9292 if (*(cur+1) ==
'.')
9299 _cur_lexeme_contents.
begin = cur;
9305 _cur_lexeme_contents.
end = cur;
9325 char_t terminator = *cur;
9329 _cur_lexeme_contents.
begin = cur;
9330 while (*cur && *cur != terminator) cur++;
9331 _cur_lexeme_contents.
end = cur;
9345 if (*(cur+1) ==
':')
9359 _cur_lexeme_contents.
begin = cur;
9370 _cur_lexeme_contents.
end = cur;
9376 _cur_lexeme_contents.
begin = cur;
9394 _cur_lexeme_contents.
end = cur;
9414 return _cur_lexeme_pos;
9421 return _cur_lexeme_contents;
9594 return comp(ls, rs);
9604 for (
const xpath_node* li = ls.
begin(); li != ls.
end(); ++li)
9605 for (
const xpath_node* ri = rs.
begin(); ri != rs.
end(); ++ri)
9632 for (
const xpath_node* ri = rs.
begin(); ri != rs.
end(); ++ri)
9649 for (
const xpath_node* ri = rs.
begin(); ri != rs.
end(); ++ri)
9661 assert(
false &&
"Wrong types");
9683 for (
const xpath_node* li = ls.
begin(); li != ls.
end(); ++li)
9689 for (
const xpath_node* ri = rs.
begin(); ri != rs.
end(); ++ri)
9707 for (
const xpath_node* ri = rs.
begin(); ri != rs.
end(); ++ri)
9724 for (
const xpath_node* li = ls.
begin(); li != ls.
end(); ++li)
9736 assert(
false &&
"Wrong types");
9752 for (xpath_node* it = last; it != ns.
end(); ++it, ++i)
9778 for (xpath_node* it = last; it != ns.
end(); ++it, ++i)
9782 if (expr->
eval_number(c, stack) ==
static_cast<double>(i))
9806 if (er >= 1.0 && er <= static_cast<double>(size))
9808 size_t eri =
static_cast<size_t>(er);
9810 if (er == static_cast<double>(eri))
9812 xpath_node r = last[eri - 1];
9828 apply_predicate_number_const(ns, first, _right, stack);
9830 apply_predicate_number(ns, first, _right, stack, once);
9832 apply_predicate_boolean(ns, first, _right, stack, once);
9839 bool last_once = eval_once(ns.
type(),
eval);
9842 pred->apply_predicate(ns, first, stack, !pred->_next && last_once);
9856 ns.
push_back(xpath_node(xml_attribute(a), xml_node(parent)), alloc);
9865 ns.
push_back(xpath_node(xml_attribute(a), xml_node(parent)), alloc);
9873 ns.
push_back(xpath_node(xml_attribute(a), xml_node(parent)), alloc);
9954 assert(
false &&
"Unknown axis");
9962 const axis_t axis = T::axis;
9968 for (xml_attribute_struct* a = n->first_attribute; a; a = a->next_attribute)
9969 if (step_push(ns, a, n, alloc) & once)
9977 for (xml_node_struct* c = n->first_child; c; c = c->next_sibling)
9978 if (step_push(ns, c, alloc) & once)
9988 if (step_push(ns, n, alloc) & once)
9991 xml_node_struct* cur = n->first_child;
9995 if (step_push(ns, cur, alloc) & once)
9998 if (cur->first_child)
9999 cur = cur->first_child;
10002 while (!cur->next_sibling)
10006 if (cur == n)
return;
10009 cur = cur->next_sibling;
10018 for (xml_node_struct* c = n->next_sibling; c; c = c->next_sibling)
10019 if (step_push(ns, c, alloc) & once)
10027 for (xml_node_struct* c = n->prev_sibling_c; c->next_sibling; c = c->prev_sibling_c)
10028 if (step_push(ns, c, alloc) & once)
10036 xml_node_struct* cur =
n;
10039 while (!cur->next_sibling)
10046 cur = cur->next_sibling;
10050 if (step_push(ns, cur, alloc) & once)
10053 if (cur->first_child)
10054 cur = cur->first_child;
10057 while (!cur->next_sibling)
10064 cur = cur->next_sibling;
10073 xml_node_struct* cur =
n;
10076 while (!cur->prev_sibling_c->next_sibling)
10083 cur = cur->prev_sibling_c;
10087 if (cur->first_child)
10088 cur = cur->first_child->prev_sibling_c;
10092 if (step_push(ns, cur, alloc) & once)
10095 while (!cur->prev_sibling_c->next_sibling)
10102 if (step_push(ns, cur, alloc) & once)
10106 cur = cur->prev_sibling_c;
10117 if (step_push(ns, n, alloc) & once)
10120 xml_node_struct* cur = n->parent;
10124 if (step_push(ns, cur, alloc) & once)
10135 step_push(ns, n, alloc);
10143 step_push(ns, n->parent, alloc);
10149 assert(
false &&
"Unimplemented axis");
10155 const axis_t axis = T::axis;
10163 if (step_push(ns, a, p, alloc) & once)
10166 xml_node_struct* cur = p;
10170 if (step_push(ns, cur, alloc) & once)
10183 step_push(ns, a, p, alloc);
10190 xml_node_struct* cur = p;
10194 if (cur->first_child)
10195 cur = cur->first_child;
10198 while (!cur->next_sibling)
10205 cur = cur->next_sibling;
10208 if (step_push(ns, cur, alloc) & once)
10217 step_push(ns, p, alloc);
10225 step_fill(ns, p, alloc, once, v);
10230 assert(
false &&
"Unimplemented axis");
10236 const axis_t axis = T::axis;
10240 step_fill(ns, xn.node().internal_object(), alloc, once,
v);
10241 else if (axis_has_attributes && xn.attribute() && xn.parent())
10242 step_fill(ns, xn.attribute().internal_object(), xn.parent().internal_object(), alloc, once,
v);
10247 const axis_t axis = T::axis;
10249 const xpath_node_set::type_t axis_type = axis_reverse ? xpath_node_set::type_sorted_reverse : xpath_node_set::type_sorted;
10253 (!_right && eval_once(axis_type, eval)) ||
10267 for (
const xpath_node* it = s.
begin(); it != s.
end(); ++it)
10269 size_t size = ns.
size();
10272 if (axis !=
axis_self && size != 0) ns.
set_type(xpath_node_set::type_unsorted);
10274 step_fill(ns, *it, stack.
result, once, v);
10275 if (_right) apply_predicates(ns, size, stack, eval);
10280 step_fill(ns, c.
n, stack.
result, once, v);
10281 if (_right) apply_predicates(ns, 0, stack, eval);
10294 _type(static_cast<char>(type)), _rettype(static_cast<char>(rettype_)), _axis(0), _test(0), _left(0), _right(0), _next(0)
10297 _data.string =
value;
10301 _type(static_cast<char>(type)), _rettype(static_cast<char>(rettype_)), _axis(0), _test(0), _left(0), _right(0), _next(0)
10304 _data.number =
value;
10308 _type(static_cast<char>(type)), _rettype(static_cast<char>(rettype_)), _axis(0), _test(0), _left(0), _right(0), _next(0)
10311 _data.variable =
value;
10315 _type(static_cast<char>(type)), _rettype(static_cast<char>(rettype_)), _axis(0), _test(0), _left(
left), _right(
right), _next(0)
10320 _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)
10323 _data.nodetest = contents;
10327 _type(static_cast<char>(type)), _rettype(
xpath_type_node_set), _axis(0), _test(static_cast<char>(test)), _left(left), _right(right), _next(0)
10353 return compare_eq(_left, _right, c, stack,
equal_to());
10356 return compare_eq(_left, _right, c, stack,
not_equal_to());
10359 return compare_rel(_left, _right, c, stack,
less());
10362 return compare_rel(_right, _left, c, stack,
less());
10365 return compare_rel(_left, _right, c, stack,
less_equal());
10368 return compare_rel(_right, _left, c, stack,
less_equal());
10404 if (c.
n.attribute())
return false;
10410 for (xml_node n = c.
n.node();
n; n = n.parent())
10412 xml_attribute a = n.attribute(
PUGIXML_TEXT(
"xml:lang"));
10416 const char_t* value = a.value();
10419 for (
const char_t* lit = lang.
c_str(); *lit; ++lit)
10425 return *value == 0 || *value ==
'-';
10436 xml_attribute attr = c.
n.node().attribute(_left->_data.
nodetest);
10443 assert(_rettype == _data.variable->type());
10446 return _data.variable->get_boolean();
10477 assert(
false &&
"Wrong expression for return type boolean");
10505 return _data.number;
10508 return static_cast<double>(c.
size);
10511 return static_cast<double>(c.
position);
10552 for (
const xpath_node* it = ns.
begin(); it != ns.
end(); ++it)
10566 return r == r ?
floor(r) :
r;
10573 return r == r ?
ceil(r) :
r;
10581 assert(_rettype == _data.variable->type());
10584 return _data.variable->get_number();
10615 assert(
false &&
"Wrong expression for return type number");
10637 buffer[0] = _left->
eval_string(c, swapped_stack);
10640 for (
xpath_ast_node* n = _right;
n; n = n->_next, ++pos) buffer[pos] = n->eval_string(c, swapped_stack);
10641 assert(pos == count);
10645 for (
size_t i = 0; i <
count; ++i) length += buffer[i].
length();
10648 char_t* result =
static_cast<char_t*
>(stack.
result->
allocate((length + 1) *
sizeof(char_t)));
10653 for (
size_t j = 0;
j <
count; ++
j)
10654 for (
const char_t* bi = buffer[
j].
c_str(); *bi; ++bi)
10671 xpath_node na = c.
n;
10681 xpath_node na = ns.
first();
10688 xpath_node na = c.
n;
10698 xpath_node na = ns.
first();
10705 xpath_node na = c.
n;
10715 xpath_node na = ns.
first();
10755 const char_t* rbegin = pos + p.
length();
10768 size_t s_length = s.
length();
10773 else if (first >= static_cast<double>(s_length + 1))
return xpath_string();
10776 assert(1 <= pos && pos <= s_length + 1);
10778 const char_t* rbegin = s.
c_str() + (pos - 1);
10791 size_t s_length = s.
length();
10797 else if (first >= static_cast<double>(s_length + 1))
return xpath_string();
10802 size_t end = last >=
static_cast<double>(s_length + 1) ? s_length + 1 : static_cast<size_t>(last);
10804 assert(1 <= pos && pos <= end && end <= s_length + 1);
10805 const char_t* rbegin = s.
c_str() + (pos - 1);
10806 const char_t* rend = s.
c_str() + (end - 1);
10867 assert(_rettype == _data.variable->type());
10900 assert(
false &&
"Wrong expression for return type string");
10919 ls.
set_type(xpath_node_set::type_unsorted);
10934 bool once = eval_once(set.
type(),
eval);
10936 apply_predicate(set, 0, stack, once);
10989 assert(
false &&
"Unknown axis");
11000 ns.
set_type(xpath_node_set::type_sorted);
11010 assert(_rettype == _data.variable->type());
11014 const xpath_node_set& s = _data.variable->get_node_set();
11033 assert(
false &&
"Wrong expression for return type node set");
11060 _right = _right->_right;
11089 _left = _left->_left;
11102 _data.table =
table;
11142 if (!n->is_posinv_expr())
return false;
11169 static const size_t xpath_ast_depth_limit =
11170 #ifdef PUGIXML_XPATH_DEPTH_LIMIT
11171 PUGIXML_XPATH_DEPTH_LIMIT
11209 return error(
"Exceeded maximum allowed query depth");
11258 size_t length =
static_cast<size_t>(value.
end - value.
begin);
11260 char_t* c =
static_cast<char_t*
>(
_alloc->
allocate((length + 1) *
sizeof(char_t)));
11263 memcpy(c, value.
begin, length *
sizeof(char_t));
11271 switch (name.
begin[0])
11285 else if (name ==
PUGIXML_TEXT(
"contains") && argc == 2)
11289 else if (name ==
PUGIXML_TEXT(
"ceiling") && argc == 1)
11313 else if (name ==
PUGIXML_TEXT(
"local-name") && argc <= 1)
11315 if (argc == 1 && args[0]->rettype() !=
xpath_type_node_set)
return error(
"Function has to be applied to node set");
11324 if (argc == 1 && args[0]->rettype() !=
xpath_type_node_set)
return error(
"Function has to be applied to node set");
11327 else if (name ==
PUGIXML_TEXT(
"namespace-uri") && argc <= 1)
11329 if (argc == 1 && args[0]->rettype() !=
xpath_type_node_set)
return error(
"Function has to be applied to node set");
11332 else if (name ==
PUGIXML_TEXT(
"normalize-space") && argc <= 1)
11356 else if (name ==
PUGIXML_TEXT(
"string-length") && argc <= 1)
11358 else if (name ==
PUGIXML_TEXT(
"starts-with") && argc == 2)
11360 else if (name ==
PUGIXML_TEXT(
"substring-before") && argc == 2)
11362 else if (name ==
PUGIXML_TEXT(
"substring-after") && argc == 2)
11364 else if (name ==
PUGIXML_TEXT(
"substring") && (argc == 2 || argc == 3))
11386 return error(
"Unrecognized function or wrong parameter count");
11393 switch (name.
begin[0])
11459 switch (name.
begin[0])
11502 return error(
"Unknown variable: variable set is not provided");
11504 xpath_variable* var = 0;
11509 return error(
"Unknown variable: variable set does not contain the given name");
11524 return error(
"Expected ')' to match an opening '('");
11534 if (!value)
return 0;
11564 return error(
"Unrecognized function call");
11567 size_t old_depth =
_depth;
11574 return error(
"No comma between function arguments");
11578 if (++
_depth > xpath_ast_depth_limit)
11584 if (argc < 2) args[argc] =
n;
11599 return error(
"Unrecognizable primary expression");
11611 size_t old_depth =
_depth;
11617 if (++
_depth > xpath_ast_depth_limit)
11621 return error(
"Predicate has to be applied to node set");
11624 if (!expr)
return 0;
11630 return error(
"Expected ']' to match an opening '['");
11648 return error(
"Step has to be applied to node set");
11650 bool axis_specified =
false;
11656 axis_specified =
true;
11665 return error(
"Predicates are not allowed after an abbreviated step");
11674 return error(
"Predicates are not allowed after an abbreviated step");
11692 if (axis_specified)
11693 return error(
"Two axis specifiers in one step");
11697 if (!axis_specified)
11698 return error(
"Unknown axis");
11716 return error(
"Unrecognized node test");
11734 return error(
"Unrecognized node type");
11738 else if (nt_name ==
PUGIXML_TEXT(
"processing-instruction"))
11741 return error(
"Only literals are allowed as arguments to processing-instruction()");
11748 return error(
"Unmatched brace near processing-instruction()");
11753 return error(
"Unmatched brace near node type test");
11759 if (nt_name.
end - nt_name.
begin > 2 && nt_name.
end[-2] ==
':' && nt_name.
end[-1] ==
'*')
11779 return error(
"Unrecognized node test");
11783 if (!nt_name_copy)
return 0;
11788 size_t old_depth =
_depth;
11796 if (++
_depth > xpath_ast_depth_limit)
11800 if (!expr)
return 0;
11803 if (!pred)
return 0;
11806 return error(
"Expected ']' to match an opening '['");
11826 size_t old_depth =
_depth;
11841 if (++
_depth > xpath_ast_depth_limit)
11933 return error(
"Step has to be applied to node set");
12035 if (++
_depth > xpath_ast_depth_limit)
12039 if (!rhs)
return 0;
12046 if (!rhs)
return 0;
12052 return error(
"Union operator has to be applied to node sets");
12055 if (!lhs)
return 0;
12083 size_t old_depth =
_depth;
12085 if (++
_depth > xpath_ast_depth_limit)
12111 return error(
"Incorrect query");
12120 return parser.
parse();
12129 if (!memory)
return 0;
12157 if (!impl)
return 0;
12161 #ifdef PUGIXML_NO_EXCEPTIONS
12164 xpath_parse_result res;
12165 res.error =
"Expression does not evaluate to node set";
12167 throw xpath_exception(res);
12177 #ifndef PUGIXML_NO_EXCEPTIONS
12180 assert(_result.
error);
12185 return _result.
error;
12208 return _attribute ?
xml_node() : _node;
12218 return _attribute ? _node : _node.
parent();
12225 PUGI__FN xpath_node::operator xpath_node::unspecified_bool_type()
const
12227 return (_node || _attribute) ? unspecified_bool_xpath_node : 0;
12232 return !(_node || _attribute);
12237 return _node == n._node && _attribute == n._attribute;
12242 return _node != n._node || _attribute != n._attribute;
12245 #ifdef __BORLANDC__
12248 return (
bool)lhs && rhs;
12253 return (
bool)lhs || rhs;
12257 PUGI__FN void xpath_node_set::_assign(const_iterator begin_, const_iterator end_, type_t type_)
12259 assert(begin_ <= end_);
12261 size_t size_ =
static_cast<size_t>(end_ - begin_);
12264 xpath_node*
storage = (size_ <= 1) ? _storage : static_cast<xpath_node*>(impl::xml_memory::allocate(size_ *
sizeof(xpath_node)));
12268 #ifdef PUGIXML_NO_EXCEPTIONS
12271 throw std::bad_alloc();
12276 if (_begin != _storage)
12277 impl::xml_memory::deallocate(_begin);
12281 memcpy(storage, begin_, size_ *
sizeof(xpath_node));
12284 _end = storage + size_;
12288 #ifdef PUGIXML_HAS_MOVE
12292 _storage[0] = rhs._storage[0];
12293 _begin = (rhs._begin == rhs._storage) ? _storage : rhs._begin;
12294 _end = _begin + (rhs._end - rhs._begin);
12296 rhs._type = type_unsorted;
12297 rhs._begin = rhs._storage;
12298 rhs._end = rhs._storage;
12308 _assign(begin_, end_, type_);
12313 if (_begin != _storage)
12314 impl::xml_memory::deallocate(_begin);
12319 _assign(ns._begin, ns._end, ns._type);
12324 if (
this == &ns)
return *
this;
12326 _assign(ns._begin, ns._end, ns._type);
12331 #ifdef PUGIXML_HAS_MOVE
12339 if (
this == &rhs)
return *
this;
12341 if (_begin != _storage)
12342 impl::xml_memory::deallocate(_begin);
12357 return _end - _begin;
12362 return _begin == _end;
12367 assert(index <
size());
12368 return _begin[index];
12414 return static_cast<const impl::xpath_variable_node_set*
>(
this)->name;
12417 return static_cast<const impl::xpath_variable_number*
>(
this)->name;
12420 return static_cast<const impl::xpath_variable_string*
>(
this)->name;
12423 return static_cast<const impl::xpath_variable_boolean*
>(
this)->name;
12426 assert(
false &&
"Invalid variable type");
12438 return (
_type ==
xpath_type_boolean) ?
static_cast<const impl::xpath_variable_boolean*
>(
this)->value :
false;
12448 const char_t* value = (
_type ==
xpath_type_string) ? static_cast<const impl::xpath_variable_string*>(
this)->value : 0;
12454 return (
_type ==
xpath_type_node_set) ?
static_cast<const impl::xpath_variable_node_set*
>(
this)->value : impl::dummy_node_set;
12461 static_cast<impl::xpath_variable_boolean*
>(
this)->value = value;
12469 static_cast<impl::xpath_variable_number*
>(
this)->value = value;
12477 impl::xpath_variable_string* var =
static_cast<impl::xpath_variable_string*
>(
this);
12482 char_t*
copy =
static_cast<char_t*
>(impl::xml_memory::allocate(size));
12483 if (!copy)
return false;
12485 memcpy(copy, value, size);
12488 if (var->value) impl::xml_memory::deallocate(var->value);
12498 static_cast<impl::xpath_variable_node_set*
>(
this)->value = value;
12504 for (
size_t i = 0; i <
sizeof(_data) /
sizeof(_data[0]); ++i)
12510 for (
size_t i = 0; i <
sizeof(_data) /
sizeof(_data[0]); ++i)
12511 _destroy(_data[i]);
12516 for (
size_t i = 0; i <
sizeof(_data) /
sizeof(_data[0]); ++i)
12524 if (
this == &rhs)
return *
this;
12531 #ifdef PUGIXML_HAS_MOVE
12534 for (
size_t i = 0; i <
sizeof(_data) /
sizeof(_data[0]); ++i)
12536 _data[i] = rhs._data[i];
12543 for (
size_t i = 0; i <
sizeof(_data) /
sizeof(_data[0]); ++i)
12545 _destroy(_data[i]);
12547 _data[i] = rhs._data[i];
12555 PUGI__FN void xpath_variable_set::_assign(
const xpath_variable_set& rhs)
12559 for (
size_t i = 0; i <
sizeof(_data) /
sizeof(_data[0]); ++i)
12560 if (rhs._data[i] && !_clone(rhs._data[i], &temp._data[i]))
12566 PUGI__FN void xpath_variable_set::_swap(xpath_variable_set& rhs)
12568 for (
size_t i = 0; i <
sizeof(_data) /
sizeof(_data[0]); ++i)
12570 xpath_variable* chain = _data[i];
12572 _data[i] = rhs._data[i];
12573 rhs._data[i] = chain;
12577 PUGI__FN xpath_variable* xpath_variable_set::_find(
const char_t* name)
const
12579 const size_t hash_size =
sizeof(_data) /
sizeof(_data[0]);
12583 for (xpath_variable* var = _data[hash]; var; var = var->_next)
12590 PUGI__FN bool xpath_variable_set::_clone(xpath_variable* var, xpath_variable** out_result)
12592 xpath_variable* last = 0;
12598 if (!nvar)
return false;
12602 last->_next = nvar;
12604 *out_result = nvar;
12617 PUGI__FN void xpath_variable_set::_destroy(xpath_variable* var)
12621 xpath_variable* next = var->_next;
12631 const size_t hash_size =
sizeof(_data) /
sizeof(_data[0]);
12637 return var->type() == type ? var : 0;
12644 result->
_next = _data[hash];
12655 return var ? var->
set(value) :
false;
12661 return var ? var->
set(value) :
false;
12667 return var ? var->
set(value) :
false;
12673 return var ? var->
set(value) :
false;
12678 return _find(name);
12683 return _find(name);
12688 impl::xpath_query_impl* qimpl = impl::xpath_query_impl::create();
12692 #ifdef PUGIXML_NO_EXCEPTIONS
12693 _result.
error =
"Out of memory";
12695 throw std::bad_alloc();
12700 using impl::auto_deleter;
12703 qimpl->root = impl::xpath_parser::parse(query, variables, &qimpl->alloc, &_result);
12707 qimpl->root->optimize(&qimpl->alloc);
12714 #ifdef PUGIXML_NO_EXCEPTIONS
12715 if (qimpl->oom) _result.
error =
"Out of memory";
12717 if (qimpl->oom)
throw std::bad_alloc();
12731 impl::xpath_query_impl::destroy(static_cast<impl::xpath_query_impl*>(_impl));
12734 #ifdef PUGIXML_HAS_MOVE
12738 _result = rhs._result;
12743 PUGI__FN xpath_query& xpath_query::operator=(xpath_query&& rhs) PUGIXML_NOEXCEPT
12745 if (
this == &rhs)
return *
this;
12748 impl::xpath_query_impl::destroy(static_cast<impl::xpath_query_impl*>(_impl));
12751 _result = rhs._result;
12753 rhs._result = xpath_parse_result();
12763 return static_cast<impl::xpath_query_impl*
>(_impl)->root->rettype();
12768 if (!_impl)
return false;
12770 impl::xpath_context
c(n, 1, 1);
12771 impl::xpath_stack_data sd;
12773 bool r =
static_cast<impl::xpath_query_impl*
>(_impl)->root->eval_boolean(c, sd.stack);
12777 #ifdef PUGIXML_NO_EXCEPTIONS
12780 throw std::bad_alloc();
12791 impl::xpath_context
c(n, 1, 1);
12792 impl::xpath_stack_data sd;
12794 double r =
static_cast<impl::xpath_query_impl*
>(_impl)->root->eval_number(c, sd.stack);
12798 #ifdef PUGIXML_NO_EXCEPTIONS
12801 throw std::bad_alloc();
12808 #ifndef PUGIXML_NO_STL
12813 impl::xpath_context
c(n, 1, 1);
12814 impl::xpath_stack_data sd;
12816 impl::xpath_string r =
static_cast<impl::xpath_query_impl*
>(_impl)->root->eval_string(c, sd.stack);
12820 #ifdef PUGIXML_NO_EXCEPTIONS
12823 throw std::bad_alloc();
12827 return string_t(r.c_str(), r.length());
12833 impl::xpath_context
c(n, 1, 1);
12834 impl::xpath_stack_data sd;
12836 impl::xpath_string r = _impl ?
static_cast<impl::xpath_query_impl*
>(_impl)->root->eval_string(c, sd.stack) : impl::xpath_string();
12840 #ifdef PUGIXML_NO_EXCEPTIONS
12841 r = impl::xpath_string();
12843 throw std::bad_alloc();
12847 size_t full_size = r.length() + 1;
12851 size_t size = (full_size < capacity) ? full_size : capacity;
12854 memcpy(buffer, r.c_str(), (size - 1) *
sizeof(char_t));
12855 buffer[size - 1] = 0;
12866 impl::xpath_context
c(n, 1, 1);
12867 impl::xpath_stack_data sd;
12873 #ifdef PUGIXML_NO_EXCEPTIONS
12876 throw std::bad_alloc();
12888 impl::xpath_context
c(n, 1, 1);
12889 impl::xpath_stack_data sd;
12895 #ifdef PUGIXML_NO_EXCEPTIONS
12898 throw std::bad_alloc();
12914 PUGI__FN xpath_query::operator xpath_query::unspecified_bool_type()
const
12916 return _impl ? unspecified_bool_xpath_query : 0;
12960 #ifdef __BORLANDC__
12961 # pragma option pop
12966 #if defined(_MSC_VER) && !defined(__INTEL_COMPILER)
12967 # pragma warning(pop)
12970 #if defined(_MSC_VER) && defined(__c2__)
12971 # pragma clang diagnostic pop
12975 #undef PUGI__NO_INLINE
12976 #undef PUGI__UNLIKELY
12977 #undef PUGI__STATIC_ASSERT
12978 #undef PUGI__DMC_VOLATILE
12979 #undef PUGI__UNSIGNED_OVERFLOW
12980 #undef PUGI__MSVC_CRT_VERSION
12981 #undef PUGI__SNPRINTF
12982 #undef PUGI__NS_BEGIN
12983 #undef PUGI__NS_END
12985 #undef PUGI__FN_NO_INLINE
12986 #undef PUGI__GETHEADER_IMPL
12987 #undef PUGI__GETPAGE_IMPL
12988 #undef PUGI__GETPAGE
12989 #undef PUGI__NODETYPE
12990 #undef PUGI__IS_CHARTYPE_IMPL
12991 #undef PUGI__IS_CHARTYPE
12992 #undef PUGI__IS_CHARTYPEX
12993 #undef PUGI__ENDSWITH
12994 #undef PUGI__SKIPWS
12995 #undef PUGI__OPTSET
12996 #undef PUGI__PUSHNODE
12997 #undef PUGI__POPNODE
12998 #undef PUGI__SCANFOR
12999 #undef PUGI__SCANWHILE
13000 #undef PUGI__SCANWHILE_UNROLL
13001 #undef PUGI__ENDSEG
13002 #undef PUGI__THROW_ERROR
13003 #undef PUGI__CHECK_ERROR
GLsizei GLenum GLsizei GLsizei GLuint memory
xpath_ast_node * alloc_node(ast_type_t type, xpath_value_type rettype, xpath_variable *value)
const unsigned int parse_ws_pcdata
virtual bool for_each(xml_node &node)=0
void swap(ArAssetInfo &lhs, ArAssetInfo &rhs)
virtual bool begin(xml_node &node)
bool operator>=(const xml_node &r) const
const unsigned int format_indent_attributes
#define PUGI__NODETYPE(n)
xml_attribute prepend_attribute(const char_t *name)
int as_int(int def=0) 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)
char data[xpath_memory_page_size]
xml_memory_page * allocate_page(size_t data_size)
GLuint GLsizei const GLchar * message
PUGI__FN strconv_pcdata_t get_strconv_pcdata(unsigned int optmask)
float as_float(float def=0) const
xpath_allocator_capture(xpath_allocator *alloc)
typedef int(APIENTRYP RE_PFNGLXSWAPINTERVALSGIPROC)(int)
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_node_iterator iterator
static value_type high(value_type result, uint32_t)
GLenum GLuint GLenum GLsizei const GLchar * buf
bool operator()(const T &lhs, const T &rhs) const
#define PUGI__UNSIGNED_OVERFLOW
xpath_string eval_string(const xpath_context &c, const xpath_stack &stack)
SYS_API double fmod(double x, double y)
PUGI__FN xml_encoding get_buffer_encoding(xml_encoding encoding, const void *contents, size_t size)
#define PUGI__FN_NO_INLINE
cvex test(vector P=0;int unbound=3;export float s=0;export vector Cf=0;)
xml_attribute append_attribute(const char_t *name)
xml_parse_result make_parse_result(xml_parse_status status, ptrdiff_t offset=0)
wchar_selector< sizeof(wchar_t)>::writer wchar_writer
xml_node last_child() const
static void destroy(xml_stream_chunk *chunk)
GLenum GLuint GLsizei bufsize
bool operator==(const xml_attribute &r) const
void append(const xpath_string &o, xpath_allocator *alloc)
PUGI__FN void node_copy_string(String &dest, Header &header, uintptr_t header_mask, char_t *source, Header &source_header, xml_allocator *alloc)
#define PUGI__SCANCHAR(ch)
OCIOEXPORT ConstColorSpaceSetRcPtr operator&&(const ConstColorSpaceSetRcPtr &lcss, const ConstColorSpaceSetRcPtr &rcss)
Perform the intersection of two sets.
xml_node prepend_child(xml_node_type type=node_element)
static xpath_string from_heap_preallocated(const char_t *begin, const char_t *end)
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)
typename detail::char_t_impl< S >::type char_t
~xpath_allocator_capture()
char_t data_char[bufcapacity]
const unsigned int parse_wconv_attribute
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)
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 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)
xpath_node_set::type_t type() const
PUGI__FN char_t * normalize_space(char_t *buffer)
void append_attribute(xml_attribute_struct *attr, xml_node_struct *node)
char_t * parse_doctype_group(char_t *s, char_t endch)
PUGI__FN allocation_function PUGIXML_FUNCTION get_memory_allocation_function()
utf16_decoder< opt_false > decoder
xpath_value_type type() const
PUGI__FN const char_t * local_name(const xpath_node &node)
void deallocate_string(char_t *string)
bool operator==(const xml_node_iterator &rhs) const
xpath_variable_set & operator=(const xpath_variable_set &rhs)
void remove_attribute(xml_attribute_struct *attr, xml_node_struct *node)
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)
uint32_t data_u32[bufcapacity]
bool operator==(const xpath_string &o) const
IMATH_HOSTDEVICE constexpr int floor(T x) IMATH_NOEXCEPT
T negative(const T &val)
Return the unary negation of the given value.
getFileOption("OpenEXR:storage") storage
const unsigned int format_no_empty_element_tags
OIIO_UTIL_API bool copy(string_view from, string_view to, std::string &err)
PUGI__NS_END PUGI__NS_BEGIN uint16_t endian_swap(uint16_t value)
#define PUGI__ENDSWITH(c, e)
virtual const char * what() const PUGIXML_OVERRIDE
bool set_value(const char_t *rhs)
xml_node append_move(const xml_node &moved)
float as_float(float def=0) const
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)
bool set(const char_t *rhs)
GLsizei const GLchar *const * string
bool is_posinv_step() const
GLsizei const GLfloat * value
static void deallocate_page(xml_memory_page *page)
xpath_parse_result * _result
const xpath_node & operator[](size_t index) const
const unsigned int parse_eol
const unsigned int format_no_declaration
size_t hash_value() const
PUGI__FN xml_parse_status get_file_size(FILE *file, size_t &out_result)
double get_number() const
PUGI__FN bool has_declaration(xml_node_struct *node)
xpath_variable_node_set()
xpath_memory_block * next
GLsizei const GLchar *const * path
xpath_ast_node(ast_type_t type, xpath_ast_node *left, xpath_ast_node *right, predicate_t test)
const char_t * as_string(const char_t *def=PUGIXML_TEXT("")) const
xml_attribute_struct(impl::xml_memory_page *page)
I median3(I first, I middle, I last, const Pred &pred)
xpath_value_type rettype() const
bool operator==(const xml_named_node_iterator &rhs) const
static value_type high(value_type result, uint32_t ch)
bool traverse(xml_tree_walker &walker)
xml_parse_result load_file(const char *path, unsigned int options=parse_default, xml_encoding encoding=encoding_auto)
const char_t * child_value() const
namespace_uri_predicate(const char_t *name)
PUGI__FN char_t * strconv_comment(char_t *s, char_t endch)
bool operator()(const T &lhs, const T &rhs) const
PUGI__FN void text_output_indent(xml_buffered_writer &writer, const char_t *indent, size_t indent_length, unsigned int depth)
xml_node * operator->() const
GLboolean GLboolean GLboolean GLboolean a
xml_node first_child() const
const unsigned int format_no_escapes
void swap(T &lhs, T &rhs)
PUGI__FN void reverse(I begin, I end)
const_iterator end() const
GLuint GLsizei GLsizei * length
PUGI__FN std::string as_utf8_impl(const wchar_t *str, size_t length)
static xpath_string from_const(const char_t *str)
PUGI__FN const void * document_buffer_order(const xpath_node &xnode)
static value_type any(value_type result, uint32_t ch)
xml_attribute prepend_copy(const xml_attribute &proto)
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)
xml_attribute last_attribute() const
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)
PUGI__FN void sort(I begin, I end, const Pred &pred)
char_t *(* strconv_attribute_t)(char_t *, char_t)
void insert_attribute_before(xml_attribute_struct *attr, xml_attribute_struct *place, xml_node_struct *node)
xml_attribute next_attribute() const
bool evaluate_boolean(const xpath_node &n) const
const char_t * value() const
bool operator!=(const xml_attribute &r) const
xml_node_type type() const
xpath_context(const xpath_node &n_, size_t position_, size_t size_)
**But if you need a result
xpath_variable_set * _variables
bool operator==(const xml_node &r) const
PUGI__FN size_t strlength_wide(const wchar_t *s)
FMT_CONSTEXPR auto find(Ptr first, Ptr last, T value, Ptr &out) -> bool
xml_memory_management_function_storage< int > xml_memory
GLdouble GLdouble GLdouble q
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)
std::enable_if< UT_EnableBitMask< T >::enable, T & >::type operator&=(T &lhs, T rhs)
#define PUGI__STATIC_ASSERT(cond)
OIIO_FORCEINLINE vbool4 insert(const vbool4 &a, bool val)
Helper: substitute val for a[i].
bool operator<=(const xml_attribute &r) const
#define PUGI__SCANWHILE(X)
double evaluate_number(const xpath_node &n) const
xpath_ast_node(ast_type_t type, xpath_value_type rettype_, xpath_variable *value)
bool set_value(const char_t *rhs)
xpath_ast_node(ast_type_t type, xpath_ast_node *left, axis_t axis, nodetest_t test, const char_t *contents)
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)
xml_node previous_sibling() const
const int default_float_precision
PUGI__FN bool is_little_endian()
xpath_lexer(const char_t *query)
xml_attribute & operator=(const char_t *rhs)
bool operator>(const xml_node &r) const
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)
bool as_bool(bool def=false) 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)
const unsigned int format_write_bom
void destroy_attribute(xml_attribute_struct *a, xml_allocator &alloc)
xpath_node select_node(const char_t *query, xpath_variable_set *variables=PUGIXML_NULL) const
bool as_bool(bool def=false) const
xpath_ast_node * alloc_node(ast_type_t type, xpath_value_type rettype, const char_t *value)
const unsigned int parse_fragment
bool remove_attribute(const xml_attribute &a)
bool operator<=(const xml_node &r) const
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)
IMATH_HOSTDEVICE constexpr int cmp(T a, T b) IMATH_NOEXCEPT
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)
PUGI__FN xml_encoding guess_buffer_encoding(const uint8_t *data, size_t size)
#define PUGIXML_NOEXCEPT_IF_NOT_COMPACT
PUGI__FN deallocation_function PUGIXML_FUNCTION get_memory_deallocation_function()
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_escapes
uint8_t data_u8[4 *bufcapacity]
virtual bool end(xml_node &node)
bool operator!=(const xml_named_node_iterator &rhs) const
xml_node find_child_by_attribute(const char_t *name, const char_t *attr_name, const char_t *attr_value) const
utf32_decoder< opt_false > decoder
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)
xml_attribute append_copy(const xml_attribute &proto)
void set_next(xpath_ast_node *value)
#define PUGI__OPTSET(OPT)
bool operator!=(const xml_node_iterator &rhs) const
nodetest_t parse_node_test_type(const xpath_lexer_string &name)
GLint GLint GLsizei GLint GLenum GLenum type
xpath_ast_node * parse_expression(int limit=0)
xpath_ast_node * parse_location_path()
PUGIXML_DEPRECATED xpath_node select_single_node(const char_t *query, xpath_variable_set *variables=PUGIXML_NULL) const
xml_attribute_struct * prev_attribute_c
OCIOEXPORT ConstColorSpaceSetRcPtr operator||(const ConstColorSpaceSetRcPtr &lcss, const ConstColorSpaceSetRcPtr &rcss)
Perform the union of two sets.
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)
PUGI__NS_END PUGI__NS_BEGIN xml_attribute_struct * allocate_attribute(xml_allocator &alloc)
xml_node insert_move_after(const xml_node &moved, const xml_node &node)
xpath_node_set select_nodes(const char_t *query, xpath_variable_set *variables=PUGIXML_NULL) const
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)
bool is_posinv_expr() const
PUGI__FN char_t * strconv_escape(char_t *s, gap &g)
bool any(const vbool4 &v)
PUGI__FN char_t tolower_ascii(char_t ch)
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_attribute attribute(const char_t *name) const
xml_document_struct & get_document(const Object *object)
const unsigned int parse_pi
static value_type any(value_type result, uint32_t ch)
PUGI__FN void insertion_sort(T *begin, T *end, const Pred &pred)
const unsigned int parse_embed_pcdata
bool strcpy_insitu_allow(size_t length, const Header &header, uintptr_t header_mask, char_t *target)
const unsigned int parse_ws_pcdata_single
const unsigned int parse_declaration
static Traits::value_type process(const uint32_t *data, size_t size, typename Traits::value_type result, Traits)
xml_attribute & operator*() const
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)
xml_node & operator*() const
xml_node append_child(xml_node_type type=node_element)
xml_attribute first_attribute() const
OIIO_UTIL_API FILE * fopen(string_view path, string_view mode)
Version of fopen that can handle UTF-8 paths even on Windows.
PUGI__FN FILE * open_file(const char *path, const char *mode)
wchar_selector< sizeof(wchar_t)>::counter wchar_counter
bool operator!=(const xpath_string &o) const
xpath_ast_node(ast_type_t type, xpath_value_type rettype_, double value)
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)
constexpr auto set(type rhs) -> int
#define PUGI__PUSHNODE(TYPE)
const char_t * get_string() const
#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)
const unsigned int format_skip_control_chars
xml_parse_result load(std::basic_istream< char, std::char_traits< char > > &stream, unsigned int options=parse_default, xml_encoding encoding=encoding_auto)
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)
PUGI__FN void convert_number_to_mantissa_exponent(double value, char(&buffer)[32], char **out_mantissa, int *out_exponent)
xml_object_range< xml_node_iterator > children() const
xpath_variable * add(const char_t *name, xpath_value_type type)
PUGI__FN PUGI__UNSIGNED_OVERFLOW char_t * integer_to_string(char_t *begin, char_t *end, U value, bool negative)
PUGI__FN bool convert_buffer_generic(char_t *&out_buffer, size_t &out_length, const void *contents, size_t size, D)
xpath_ast_node * error_oom()
const unsigned int format_indent
void(* deallocation_function)(void *ptr)
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)
GLsizei GLsizei GLchar * source
void write(char_t d0, char_t d1, char_t d2, char_t d3, char_t d4, char_t d5)
PUGI__FN std::string PUGIXML_FUNCTION as_utf8(const wchar_t *str)
PUGI__FN bool hash_insert(const void **table, size_t size, const void *key)
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)
const char_t * as_string(const char_t *def=PUGIXML_TEXT("")) const
const xpath_parse_result & result() const
static value_type low(value_type result, uint32_t ch)
std::basic_string< PUGIXML_CHAR, std::char_traits< PUGIXML_CHAR >, std::allocator< PUGIXML_CHAR > > string_t
xml_extra_buffer * extra_buffers
void sort(bool reverse=false)
xml_node next_sibling() const
PUGI__FN bool node_output_start(xml_buffered_writer &writer, xml_node_struct *node, const char_t *indent, size_t indent_length, unsigned int flags, unsigned int depth)
PUGI__FN bool set_value_convert(String &dest, Header &header, uintptr_t header_mask, float value, int precision)
xpath_node_set evaluate_node_set(const xpath_node &n) const
static xpath_string from_heap(const char_t *begin, const char_t *end, xpath_allocator *alloc)
bool operator>=(const xml_attribute &r) const
double as_double(double def=0) const
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)
GLdouble GLdouble GLint GLint order
#define PUGI__SCANWHILE_UNROLL(X)
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)
xml_node * operator->() const
PUGI__FN std::basic_string< wchar_t > PUGIXML_FUNCTION as_wide(const char *str)
bool operator!=(const xml_attribute_iterator &rhs) const
PUGI__FN void delete_xpath_variable(T *var)
xml_node & operator*() const
void destroy_node(xml_node_struct *n, xml_allocator &alloc)
void remove_node(xml_node_struct *node)
xpath_ast_node * error_rec()
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)
HUSD_API bool eval(VtValue &val, T &ret_val)
xml_node_struct * first_child
const unsigned int parse_wnorm_attribute
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)
xml_attribute_struct * internal_object() const
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)
void remove_duplicates(xpath_allocator *alloc)
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)
void *(* allocation_function)(size_t size)
xml_node document_element() const
GLuint const GLchar * name
IMATH_HOSTDEVICE constexpr int sign(T a) IMATH_NOEXCEPT
static value_type high(value_type result, uint32_t ch)
string_t path(char_t delimiter= '/') const
PUGI__FN void close_file(FILE *file)
const char_t * state() const
uint16_t data_u16[2 *bufcapacity]
PUGI__FN const char_t * convert_number_to_string_special(double value)
const unsigned int parse_doctype
xpath_string eval_string_concat(const xpath_context &c, const xpath_stack &stack)
bool operator()(const xpath_node &lhs, const xpath_node &rhs) const
void insert_attribute_after(xml_attribute_struct *attr, xml_attribute_struct *place, xml_node_struct *node)
xml_named_node_iterator()
xml_allocator(xml_memory_page *root)
string_t evaluate_string(const xpath_node &n) const
const unsigned int parse_trim_pcdata
GLenum GLenum GLsizei void * table
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)
unsigned int as_uint(unsigned int def=0) const
const char_t * name() const
auto_deleter(T *data_, D deleter_)
PUGI__FN I min_element(I begin, I end, const Pred &pred)
xpath_node evaluate_node(const xpath_node &n) const
const TypeMask operator&(const TypeMask &m1, const TypeMask &m2)
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)
char_t *(* strconv_pcdata_t)(char_t *)
PUGI__FN void text_output(xml_buffered_writer &writer, const char_t *s, chartypex_t type, unsigned int flags)
xml_node insert_child_before(xml_node_type type, const xml_node &node)
char_t * parse_doctype_ignore(char_t *s)
GLint GLint GLsizei GLsizei GLsizei depth
PUGI__FN void node_output(xml_buffered_writer &writer, xml_node_struct *root, const char_t *indent, unsigned int flags, unsigned int depth)
static void destroy(xpath_query_impl *impl)
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)
GLenum GLint GLint * precision
auto reserve(std::back_insert_iterator< Container > it, size_t n) -> checked_ptr< typename Container::value_type >
const char_t * c_str() const
xpath_ast_node * alloc_node(ast_type_t type, xpath_value_type rettype, double value)
bool operator!=(const xml_node &r) const
void prepend_node(xml_node_struct *child, xml_node_struct *node)
PUGI__FN T * new_xpath_variable(const char_t *name)
const unsigned int parse_cdata
PUGI__FN void node_output_comment(xml_buffered_writer &writer, const char_t *s)
const xpath_node_set & get_node_set() const
xml_attribute_iterator & operator++()
void(* unspecified_bool_type)(xml_node ***)
__hostdev__ uint64_t last(uint32_t i) const
union xml_buffered_writer::@203 scratch
#define PUGI__SCANCHARTYPE(ct)
static Traits::value_type process(const uint8_t *data, size_t size, typename Traits::value_type result, Traits)
const char_t * get() const
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)
GLfloat GLfloat GLfloat GLfloat h
xpath_ast_node * parse_function(const xpath_lexer_string &name, size_t argc, xpath_ast_node *args[2])
IMATH_HOSTDEVICE constexpr int ceil(T x) IMATH_NOEXCEPT
OIIO_UTIL_API int fseek(FILE *file, int64_t offset, int whence)
PUGI__FN bool convert_number_to_boolean(double value)
attribute_iterator attributes_begin() const
int as_int(int def=0) const
unsigned int as_uint(unsigned int def=0) 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)
bool operator>(const xml_attribute &r) const
binary_op_t(ast_type_t asttype_, xpath_value_type rettype_, int precedence_)
bool operator!=(const xpath_node &n) const
bool operator==(const xpath_node &n) const
const xpath_lexer_string & contents() const
static char_t * parse_eol(char_t *s, char_t end_quote)
void print(xml_writer &writer, const char_t *indent=PUGIXML_TEXT("\t"), unsigned int flags=format_default, xml_encoding encoding=encoding_auto, unsigned int depth=0) const
xml_attribute_iterator attribute_iterator
PUGI__FN double convert_string_to_number(const char_t *string)
xml_node_iterator & operator--()
const unsigned int format_raw
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)
const_iterator begin() const
xpath_ast_node * parse_path_or_unary_expression()
void set_type(xpath_node_set::type_t value)
xml_node child(const char_t *name) const
#define PUGI__IS_CHARTYPEX(c, ct)
static value_type low(value_type result, uint32_t)
xml_attribute * operator->() const
attribute_iterator attributes_end() const
bool operator<(const xml_attribute &r) const
PUGI__FN void PUGIXML_FUNCTION set_memory_management_functions(allocation_function allocate, deallocation_function deallocate)
bool operator()(xml_attribute a) const
bool operator<(const xml_node &r) const
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)
bool operator()(const T &lhs, const T &rhs) const
xpath_variable(xpath_value_type type)
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)
LeafData & operator=(const LeafData &)=delete
PUGI__FN const char_t * qualified_name(const xpath_node &node)
static deallocation_function deallocate
PUGI__FN bool allow_move(xml_node parent, xml_node child)
const unsigned int format_save_file_text
void * allocate_memory(size_t size, xml_memory_page *&out_page)
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)
xml_object_range< xml_attribute_iterator > attributes() 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)
xpath_ast_node * parse_expression_rec(xpath_ast_node *lhs, int limit)
xpath_ast_node * parse_relative_location_path(xpath_ast_node *set)
void write_buffer(const char_t *data, size_t length)
void optimize_self(xpath_allocator *alloc)
OIIO_UTIL_API int64_t ftell(FILE *file)
Version of ftell that works with 64 bit offsets on all systems.
PUGI__FN unsigned int get_value_uint(const char_t *value)
const char_t * name() const
char_t * parse_tree(char_t *s, xml_node_struct *root, unsigned int optmsk, char_t endch)
xpath_value_type return_type() const
xpath_memory_block blocks[2]
#define PUGI__CHECK_ERROR(err, m)
char_t * parse_doctype_primitive(char_t *s)
GA_API const UT_StringHolder N
xpath_ast_node(ast_type_t type, xpath_value_type rettype_, xpath_ast_node *left=0, xpath_ast_node *right=0)
const char_t * current_pos() const
GA_API const UT_StringHolder pivot
xml_node_struct * internal_object() const
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)
const char_t * value() const
bool process(T &func, UT_WorkBuffer &fullpath, exint fullpath_len, const UT_StringArray &paths, const UT_Array< FS_Stat > &stats)
Utility function to process the contents of the traverse() function.
**If you just want to fire and args
#define PUGI__DMC_VOLATILE
PUGI__FN bool allow_insert_attribute(xml_node_type parent)
PUGI__FN void partition3(T *begin, T *end, T pivot, const Pred &pred, T **out_eqbeg, T **out_eqend)
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)
PUGI__FN bool copy_xpath_variable(xpath_variable *lhs, const xpath_variable *rhs)
OIIO_UTIL_API const char * c_str(string_view str)
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)
xml_node first_element_by_path(const char_t *path, char_t delimiter= '/') const
xml_attribute attribute() const
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)
PUGI__FN impl::xpath_ast_node * evaluate_node_set_prepare(xpath_query_impl *impl)
bool save_file(const char *path, const char_t *indent=PUGIXML_TEXT("\t"), unsigned int flags=format_default, xml_encoding encoding=encoding_auto) const
PUGI__FN bool strequal(const char_t *src, const char_t *dst)
static char_t * parse(char_t *s)
bool operator==(const char_t *other) const
const unsigned char * table
static xpath_query_impl * create()
static value_type high(value_type result, uint32_t ch)
size_t hash_value() const
PUGI__FN double gen_nan()
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)
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)
#define OIIO_NAMESPACE_END
PUGI__FN char_t * translate(char_t *buffer, const char_t *from, const char_t *to, size_t to_length)
xml_node_iterator & operator++()
void prepend_attribute(xml_attribute_struct *attr, xml_node_struct *node)
PUGI__FN I unique(I begin, I end)
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()
PUGI__FN void text_output_escaped(xml_buffered_writer &writer, const char_t *s, chartypex_t type, unsigned int flags)
xml_named_node_iterator & operator--()
xpath_node * begin() const
xml_attribute_struct * next_attribute
bool set(const char_t *name, bool value)
ptrdiff_t offset_debug() const
bool operator()(const T &lhs, const T &rhs) const
PUGI__FN bool set_value_bool(String &dest, Header &header, uintptr_t header_mask, bool value)
static xml_stream_chunk * create()
xml_allocator & get_allocator(const Object *object)
bool operator==(const xml_attribute_iterator &rhs) const
static Traits::value_type process(const uint8_t *data, size_t size, typename Traits::value_type result, Traits)
GA_API const UT_StringHolder rest
bool remove_child(const xml_node &n)
PUGI__FN double round_nearest(double value)
void * allocate(size_t size)
static char_t * parse_wnorm(char_t *s, char_t end_quote)
xml_node_struct * allocate_node(xml_allocator &alloc, xml_node_type type)
PUGI__FN void node_copy_tree(xml_node_struct *dn, xml_node_struct *sn)
xml_parser(xml_allocator *alloc_)
xml_attribute_iterator & operator--()
void revert(const xpath_allocator &state)
PUGI__FN xml_encoding get_write_encoding(xml_encoding encoding)
double as_double(double def=0) const
const int default_double_precision
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)
const unsigned int parse_comments
xml_named_node_iterator & operator++()
bool set_name(const char_t *rhs)
const unsigned int format_attribute_single_quote
const char * description() const
static value_type low(value_type result, uint32_t ch)
xpath_memory_block * _root
const char_t * name() const
void save(xml_writer &writer, const char_t *indent=PUGIXML_TEXT("\t"), unsigned int flags=format_default, xml_encoding encoding=encoding_auto) const
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)
std::enable_if< UT_EnableBitMask< T >::enable, T & >::type operator|=(T &lhs, T rhs)
const char * description() const
xml_attribute previous_attribute() const
const xpath_parse_result & result() const
PUGI__FN double get_value_double(const char_t *value)
bool eval_boolean(const xpath_context &c, const xpath_stack &stack)
#define OIIO_NAMESPACE_BEGIN
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)
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)
double OIIO_UTIL_API strtod(const char *nptr, char **endptr=nullptr) noexcept
PcpNodeRef_ChildrenIterator begin(const PcpNodeRef::child_const_range &r)
Support for range-based for loops for PcpNodeRef children ranges.