comparison dep/pugixml/src/pugixml.cpp @ 123:a45edd073f9e

deps/pugixml: update to v1.14.0
author Paper <mrpapersonic@gmail.com>
date Wed, 08 Nov 2023 21:40:02 -0500
parents d10b6c6b432e
children
comparison
equal deleted inserted replaced
122:bc218c9d2ea6 123:a45edd073f9e
1 /** 1 /**
2 * pugixml parser - version 1.13 2 * pugixml parser - version 1.14
3 * -------------------------------------------------------- 3 * --------------------------------------------------------
4 * Copyright (C) 2006-2022, by Arseny Kapoulkine (arseny.kapoulkine@gmail.com) 4 * Copyright (C) 2006-2023, by Arseny Kapoulkine (arseny.kapoulkine@gmail.com)
5 * Report bugs and download new versions at https://pugixml.org/ 5 * Report bugs and download new versions at https://pugixml.org/
6 * 6 *
7 * This library is distributed under the MIT License. See notice at the end 7 * This library is distributed under the MIT License. See notice at the end
8 * of this file. 8 * of this file.
9 * 9 *
38 #endif 38 #endif
39 39
40 // For placement new 40 // For placement new
41 #include <new> 41 #include <new>
42 42
43 // For load_file
44 #if defined(__linux__) || defined(__APPLE__)
45 #include <sys/stat.h>
46 #endif
47
43 #ifdef _MSC_VER 48 #ifdef _MSC_VER
44 # pragma warning(push) 49 # pragma warning(push)
45 # pragma warning(disable: 4127) // conditional expression is constant 50 # pragma warning(disable: 4127) // conditional expression is constant
46 # pragma warning(disable: 4324) // structure was padded due to __declspec(align()) 51 # pragma warning(disable: 4324) // structure was padded due to __declspec(align())
47 # pragma warning(disable: 4702) // unreachable code 52 # pragma warning(disable: 4702) // unreachable code
80 # pragma diag_suppress 179 // function was declared but never referenced 85 # pragma diag_suppress 179 // function was declared but never referenced
81 #endif 86 #endif
82 87
83 // Inlining controls 88 // Inlining controls
84 #if defined(_MSC_VER) && _MSC_VER >= 1300 89 #if defined(_MSC_VER) && _MSC_VER >= 1300
85 # define PUGI__NO_INLINE __declspec(noinline) 90 # define PUGI_IMPL_NO_INLINE __declspec(noinline)
86 #elif defined(__GNUC__) 91 #elif defined(__GNUC__)
87 # define PUGI__NO_INLINE __attribute__((noinline)) 92 # define PUGI_IMPL_NO_INLINE __attribute__((noinline))
88 #else 93 #else
89 # define PUGI__NO_INLINE 94 # define PUGI_IMPL_NO_INLINE
90 #endif 95 #endif
91 96
92 // Branch weight controls 97 // Branch weight controls
93 #if defined(__GNUC__) && !defined(__c2__) 98 #if defined(__GNUC__) && !defined(__c2__)
94 # define PUGI__UNLIKELY(cond) __builtin_expect(cond, 0) 99 # define PUGI_IMPL_UNLIKELY(cond) __builtin_expect(cond, 0)
95 #else 100 #else
96 # define PUGI__UNLIKELY(cond) (cond) 101 # define PUGI_IMPL_UNLIKELY(cond) (cond)
97 #endif 102 #endif
98 103
99 // Simple static assertion 104 // Simple static assertion
100 #define PUGI__STATIC_ASSERT(cond) { static const char condition_failed[(cond) ? 1 : -1] = {0}; (void)condition_failed[0]; } 105 #define PUGI_IMPL_STATIC_ASSERT(cond) { static const char condition_failed[(cond) ? 1 : -1] = {0}; (void)condition_failed[0]; }
101 106
102 // Digital Mars C++ bug workaround for passing char loaded from memory via stack 107 // Digital Mars C++ bug workaround for passing char loaded from memory via stack
103 #ifdef __DMC__ 108 #ifdef __DMC__
104 # define PUGI__DMC_VOLATILE volatile 109 # define PUGI_IMPL_DMC_VOLATILE volatile
105 #else 110 #else
106 # define PUGI__DMC_VOLATILE 111 # define PUGI_IMPL_DMC_VOLATILE
107 #endif 112 #endif
108 113
109 // Integer sanitizer workaround; we only apply this for clang since gcc8 has no_sanitize but not unsigned-integer-overflow and produces "attribute directive ignored" warnings 114 // Integer sanitizer workaround; we only apply this for clang since gcc8 has no_sanitize but not unsigned-integer-overflow and produces "attribute directive ignored" warnings
110 #if defined(__clang__) && defined(__has_attribute) 115 #if defined(__clang__) && defined(__has_attribute)
111 # if __has_attribute(no_sanitize) 116 # if __has_attribute(no_sanitize)
112 # define PUGI__UNSIGNED_OVERFLOW __attribute__((no_sanitize("unsigned-integer-overflow"))) 117 # define PUGI_IMPL_UNSIGNED_OVERFLOW __attribute__((no_sanitize("unsigned-integer-overflow")))
113 # else 118 # else
114 # define PUGI__UNSIGNED_OVERFLOW 119 # define PUGI_IMPL_UNSIGNED_OVERFLOW
115 # endif 120 # endif
116 #else 121 #else
117 # define PUGI__UNSIGNED_OVERFLOW 122 # define PUGI_IMPL_UNSIGNED_OVERFLOW
118 #endif 123 #endif
119 124
120 // Borland C++ bug workaround for not defining ::memcpy depending on header include order (can't always use std::memcpy because some compilers don't have it at all) 125 // Borland C++ bug workaround for not defining ::memcpy depending on header include order (can't always use std::memcpy because some compilers don't have it at all)
121 #if defined(__BORLANDC__) && !defined(__MEM_H_USING_LIST) 126 #if defined(__BORLANDC__) && !defined(__MEM_H_USING_LIST)
122 using std::memcpy; 127 using std::memcpy;
123 using std::memmove; 128 using std::memmove;
124 using std::memset; 129 using std::memset;
125 #endif 130 #endif
126 131
132 // Old versions of GCC do not define ::malloc and ::free depending on header include order
133 #if defined(__GNUC__) && (__GNUC__ < 3 || (__GNUC__ == 3 && __GNUC_MINOR__ < 4))
134 using std::malloc;
135 using std::free;
136 #endif
137
127 // Some MinGW/GCC versions have headers that erroneously omit LLONG_MIN/LLONG_MAX/ULLONG_MAX definitions from limits.h in some configurations 138 // Some MinGW/GCC versions have headers that erroneously omit LLONG_MIN/LLONG_MAX/ULLONG_MAX definitions from limits.h in some configurations
128 #if defined(PUGIXML_HAS_LONG_LONG) && defined(__GNUC__) && !defined(LLONG_MAX) && !defined(LLONG_MIN) && !defined(ULLONG_MAX) 139 #if defined(PUGIXML_HAS_LONG_LONG) && defined(__GNUC__) && !defined(LLONG_MAX) && !defined(LLONG_MIN) && !defined(ULLONG_MAX)
129 # define LLONG_MIN (-LLONG_MAX - 1LL) 140 # define LLONG_MIN (-LLONG_MAX - 1LL)
130 # define LLONG_MAX __LONG_LONG_MAX__ 141 # define LLONG_MAX __LONG_LONG_MAX__
131 # define ULLONG_MAX (LLONG_MAX * 2ULL + 1ULL) 142 # define ULLONG_MAX (LLONG_MAX * 2ULL + 1ULL)
132 #endif 143 #endif
133 144
134 // In some environments MSVC is a compiler but the CRT lacks certain MSVC-specific features 145 // In some environments MSVC is a compiler but the CRT lacks certain MSVC-specific features
135 #if defined(_MSC_VER) && !defined(__S3E__) && !defined(_WIN32_WCE) 146 #if defined(_MSC_VER) && !defined(__S3E__) && !defined(_WIN32_WCE)
136 # define PUGI__MSVC_CRT_VERSION _MSC_VER 147 # define PUGI_IMPL_MSVC_CRT_VERSION _MSC_VER
137 #elif defined(_WIN32_WCE) 148 #elif defined(_WIN32_WCE)
138 # define PUGI__MSVC_CRT_VERSION 1310 // MSVC7.1 149 # define PUGI_IMPL_MSVC_CRT_VERSION 1310 // MSVC7.1
139 #endif 150 #endif
140 151
141 // Not all platforms have snprintf; we define a wrapper that uses snprintf if possible. This only works with buffers with a known size. 152 // Not all platforms have snprintf; we define a wrapper that uses snprintf if possible. This only works with buffers with a known size.
142 #if __cplusplus >= 201103 153 #if __cplusplus >= 201103
143 # define PUGI__SNPRINTF(buf, ...) snprintf(buf, sizeof(buf), __VA_ARGS__) 154 # define PUGI_IMPL_SNPRINTF(buf, ...) snprintf(buf, sizeof(buf), __VA_ARGS__)
144 #elif defined(PUGI__MSVC_CRT_VERSION) && PUGI__MSVC_CRT_VERSION >= 1400 155 #elif defined(PUGI_IMPL_MSVC_CRT_VERSION) && PUGI_IMPL_MSVC_CRT_VERSION >= 1400
145 # define PUGI__SNPRINTF(buf, ...) _snprintf_s(buf, _countof(buf), _TRUNCATE, __VA_ARGS__) 156 # define PUGI_IMPL_SNPRINTF(buf, ...) _snprintf_s(buf, _countof(buf), _TRUNCATE, __VA_ARGS__)
157 #elif defined(__APPLE__) && __clang_major__ >= 14 // Xcode 14 marks sprintf as deprecated while still using C++98 by default
158 # define PUGI_IMPL_SNPRINTF(buf, fmt, arg1, arg2) snprintf(buf, sizeof(buf), fmt, arg1, arg2)
146 #else 159 #else
147 # define PUGI__SNPRINTF sprintf 160 # define PUGI_IMPL_SNPRINTF sprintf
148 #endif 161 #endif
149 162
150 // We put implementation details into an anonymous namespace in source mode, but have to keep it in non-anonymous namespace in header-only mode to prevent binary bloat. 163 // We put implementation details into an anonymous namespace in source mode, but have to keep it in non-anonymous namespace in header-only mode to prevent binary bloat.
151 #ifdef PUGIXML_HEADER_ONLY 164 #ifdef PUGIXML_HEADER_ONLY
152 # define PUGI__NS_BEGIN namespace pugi { namespace impl { 165 # define PUGI_IMPL_NS_BEGIN namespace pugi { namespace impl {
153 # define PUGI__NS_END } } 166 # define PUGI_IMPL_NS_END } }
154 # define PUGI__FN inline 167 # define PUGI_IMPL_FN inline
155 # define PUGI__FN_NO_INLINE inline 168 # define PUGI_IMPL_FN_NO_INLINE inline
156 #else 169 #else
157 # if defined(_MSC_VER) && _MSC_VER < 1300 // MSVC6 seems to have an amusing bug with anonymous namespaces inside namespaces 170 # if defined(_MSC_VER) && _MSC_VER < 1300 // MSVC6 seems to have an amusing bug with anonymous namespaces inside namespaces
158 # define PUGI__NS_BEGIN namespace pugi { namespace impl { 171 # define PUGI_IMPL_NS_BEGIN namespace pugi { namespace impl {
159 # define PUGI__NS_END } } 172 # define PUGI_IMPL_NS_END } }
160 # else 173 # else
161 # define PUGI__NS_BEGIN namespace pugi { namespace impl { namespace { 174 # define PUGI_IMPL_NS_BEGIN namespace pugi { namespace impl { namespace {
162 # define PUGI__NS_END } } } 175 # define PUGI_IMPL_NS_END } } }
163 # endif 176 # endif
164 # define PUGI__FN 177 # define PUGI_IMPL_FN
165 # define PUGI__FN_NO_INLINE PUGI__NO_INLINE 178 # define PUGI_IMPL_FN_NO_INLINE PUGI_IMPL_NO_INLINE
166 #endif 179 #endif
167 180
168 // uintptr_t 181 // uintptr_t
169 #if (defined(_MSC_VER) && _MSC_VER < 1600) || (defined(__BORLANDC__) && __BORLANDC__ < 0x561) 182 #if (defined(_MSC_VER) && _MSC_VER < 1600) || (defined(__BORLANDC__) && __BORLANDC__ < 0x561)
170 namespace pugi 183 namespace pugi
180 #else 193 #else
181 # include <stdint.h> 194 # include <stdint.h>
182 #endif 195 #endif
183 196
184 // Memory allocation 197 // Memory allocation
185 PUGI__NS_BEGIN 198 PUGI_IMPL_NS_BEGIN
186 PUGI__FN void* default_allocate(size_t size) 199 PUGI_IMPL_FN void* default_allocate(size_t size)
187 { 200 {
188 return malloc(size); 201 return malloc(size);
189 } 202 }
190 203
191 PUGI__FN void default_deallocate(void* ptr) 204 PUGI_IMPL_FN void default_deallocate(void* ptr)
192 { 205 {
193 free(ptr); 206 free(ptr);
194 } 207 }
195 208
196 template <typename T> 209 template <typename T>
204 // Without a template<> we'll get multiple definitions of the same static 217 // Without a template<> we'll get multiple definitions of the same static
205 template <typename T> allocation_function xml_memory_management_function_storage<T>::allocate = default_allocate; 218 template <typename T> allocation_function xml_memory_management_function_storage<T>::allocate = default_allocate;
206 template <typename T> deallocation_function xml_memory_management_function_storage<T>::deallocate = default_deallocate; 219 template <typename T> deallocation_function xml_memory_management_function_storage<T>::deallocate = default_deallocate;
207 220
208 typedef xml_memory_management_function_storage<int> xml_memory; 221 typedef xml_memory_management_function_storage<int> xml_memory;
209 PUGI__NS_END 222 PUGI_IMPL_NS_END
210 223
211 // String utilities 224 // String utilities
212 PUGI__NS_BEGIN 225 PUGI_IMPL_NS_BEGIN
213 // Get string length 226 // Get string length
214 PUGI__FN size_t strlength(const char_t* s) 227 PUGI_IMPL_FN size_t strlength(const char_t* s)
215 { 228 {
216 assert(s); 229 assert(s);
217 230
218 #ifdef PUGIXML_WCHAR_MODE 231 #ifdef PUGIXML_WCHAR_MODE
219 return wcslen(s); 232 return wcslen(s);
221 return strlen(s); 234 return strlen(s);
222 #endif 235 #endif
223 } 236 }
224 237
225 // Compare two strings 238 // Compare two strings
226 PUGI__FN bool strequal(const char_t* src, const char_t* dst) 239 PUGI_IMPL_FN bool strequal(const char_t* src, const char_t* dst)
227 { 240 {
228 assert(src && dst); 241 assert(src && dst);
229 242
230 #ifdef PUGIXML_WCHAR_MODE 243 #ifdef PUGIXML_WCHAR_MODE
231 return wcscmp(src, dst) == 0; 244 return wcscmp(src, dst) == 0;
233 return strcmp(src, dst) == 0; 246 return strcmp(src, dst) == 0;
234 #endif 247 #endif
235 } 248 }
236 249
237 // Compare lhs with [rhs_begin, rhs_end) 250 // Compare lhs with [rhs_begin, rhs_end)
238 PUGI__FN bool strequalrange(const char_t* lhs, const char_t* rhs, size_t count) 251 PUGI_IMPL_FN bool strequalrange(const char_t* lhs, const char_t* rhs, size_t count)
239 { 252 {
240 for (size_t i = 0; i < count; ++i) 253 for (size_t i = 0; i < count; ++i)
241 if (lhs[i] != rhs[i]) 254 if (lhs[i] != rhs[i])
242 return false; 255 return false;
243 256
244 return lhs[count] == 0; 257 return lhs[count] == 0;
245 } 258 }
246 259
247 // Get length of wide string, even if CRT lacks wide character support 260 // Get length of wide string, even if CRT lacks wide character support
248 PUGI__FN size_t strlength_wide(const wchar_t* s) 261 PUGI_IMPL_FN size_t strlength_wide(const wchar_t* s)
249 { 262 {
250 assert(s); 263 assert(s);
251 264
252 #ifdef PUGIXML_WCHAR_MODE 265 #ifdef PUGIXML_WCHAR_MODE
253 return wcslen(s); 266 return wcslen(s);
255 const wchar_t* end = s; 268 const wchar_t* end = s;
256 while (*end) end++; 269 while (*end) end++;
257 return static_cast<size_t>(end - s); 270 return static_cast<size_t>(end - s);
258 #endif 271 #endif
259 } 272 }
260 PUGI__NS_END 273 PUGI_IMPL_NS_END
261 274
262 // auto_ptr-like object for exception recovery 275 // auto_ptr-like object for exception recovery
263 PUGI__NS_BEGIN 276 PUGI_IMPL_NS_BEGIN
264 template <typename T> struct auto_deleter 277 template <typename T> struct auto_deleter
265 { 278 {
266 typedef void (*D)(T*); 279 typedef void (*D)(T*);
267 280
268 T* data; 281 T* data;
282 T* result = data; 295 T* result = data;
283 data = 0; 296 data = 0;
284 return result; 297 return result;
285 } 298 }
286 }; 299 };
287 PUGI__NS_END 300 PUGI_IMPL_NS_END
288 301
289 #ifdef PUGIXML_COMPACT 302 #ifdef PUGIXML_COMPACT
290 PUGI__NS_BEGIN 303 PUGI_IMPL_NS_BEGIN
291 class compact_hash_table 304 class compact_hash_table
292 { 305 {
293 public: 306 public:
294 compact_hash_table(): _items(0), _capacity(0), _count(0) 307 compact_hash_table(): _items(0), _capacity(0), _count(0)
295 { 308 {
376 389
377 assert(false && "Hash table is full"); // unreachable 390 assert(false && "Hash table is full"); // unreachable
378 return 0; 391 return 0;
379 } 392 }
380 393
381 static PUGI__UNSIGNED_OVERFLOW unsigned int hash(const void* key) 394 static PUGI_IMPL_UNSIGNED_OVERFLOW unsigned int hash(const void* key)
382 { 395 {
383 unsigned int h = static_cast<unsigned int>(reinterpret_cast<uintptr_t>(key) & 0xffffffff); 396 unsigned int h = static_cast<unsigned int>(reinterpret_cast<uintptr_t>(key) & 0xffffffff);
384 397
385 // MurmurHash3 32-bit finalizer 398 // MurmurHash3 32-bit finalizer
386 h ^= h >> 16; 399 h ^= h >> 16;
391 404
392 return h; 405 return h;
393 } 406 }
394 }; 407 };
395 408
396 PUGI__FN_NO_INLINE bool compact_hash_table::rehash(size_t count) 409 PUGI_IMPL_FN_NO_INLINE bool compact_hash_table::rehash(size_t count)
397 { 410 {
398 size_t capacity = 32; 411 size_t capacity = 32;
399 while (count >= capacity - capacity / 4) 412 while (count >= capacity - capacity / 4)
400 capacity *= 2; 413 capacity *= 2;
401 414
421 assert(_count == rt._count); 434 assert(_count == rt._count);
422 435
423 return true; 436 return true;
424 } 437 }
425 438
426 PUGI__NS_END 439 PUGI_IMPL_NS_END
427 #endif 440 #endif
428 441
429 PUGI__NS_BEGIN 442 PUGI_IMPL_NS_BEGIN
430 #ifdef PUGIXML_COMPACT 443 #ifdef PUGIXML_COMPACT
431 static const uintptr_t xml_memory_block_alignment = 4; 444 static const uintptr_t xml_memory_block_alignment = 4;
432 #else 445 #else
433 static const uintptr_t xml_memory_block_alignment = sizeof(void*); 446 static const uintptr_t xml_memory_block_alignment = sizeof(void*);
434 #endif 447 #endif
442 // combined masks for string uniqueness 455 // combined masks for string uniqueness
443 static const uintptr_t xml_memory_page_name_allocated_or_shared_mask = xml_memory_page_name_allocated_mask | xml_memory_page_contents_shared_mask; 456 static const uintptr_t xml_memory_page_name_allocated_or_shared_mask = xml_memory_page_name_allocated_mask | xml_memory_page_contents_shared_mask;
444 static const uintptr_t xml_memory_page_value_allocated_or_shared_mask = xml_memory_page_value_allocated_mask | xml_memory_page_contents_shared_mask; 457 static const uintptr_t xml_memory_page_value_allocated_or_shared_mask = xml_memory_page_value_allocated_mask | xml_memory_page_contents_shared_mask;
445 458
446 #ifdef PUGIXML_COMPACT 459 #ifdef PUGIXML_COMPACT
447 #define PUGI__GETHEADER_IMPL(object, page, flags) // unused 460 #define PUGI_IMPL_GETHEADER_IMPL(object, page, flags) // unused
448 #define PUGI__GETPAGE_IMPL(header) (header).get_page() 461 #define PUGI_IMPL_GETPAGE_IMPL(header) (header).get_page()
449 #else 462 #else
450 #define PUGI__GETHEADER_IMPL(object, page, flags) (((reinterpret_cast<char*>(object) - reinterpret_cast<char*>(page)) << 8) | (flags)) 463 #define PUGI_IMPL_GETHEADER_IMPL(object, page, flags) (((reinterpret_cast<char*>(object) - reinterpret_cast<char*>(page)) << 8) | (flags))
451 // this macro casts pointers through void* to avoid 'cast increases required alignment of target type' warnings 464 // this macro casts pointers through void* to avoid 'cast increases required alignment of target type' warnings
452 #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)))) 465 #define PUGI_IMPL_GETPAGE_IMPL(header) static_cast<impl::xml_memory_page*>(const_cast<void*>(static_cast<const void*>(reinterpret_cast<const char*>(&header) - (header >> 8))))
453 #endif 466 #endif
454 467
455 #define PUGI__GETPAGE(n) PUGI__GETPAGE_IMPL((n)->header) 468 #define PUGI_IMPL_GETPAGE(n) PUGI_IMPL_GETPAGE_IMPL((n)->header)
456 #define PUGI__NODETYPE(n) static_cast<xml_node_type>((n)->header & impl::xml_memory_page_type_mask) 469 #define PUGI_IMPL_NODETYPE(n) static_cast<xml_node_type>((n)->header & impl::xml_memory_page_type_mask)
457 470
458 struct xml_allocator; 471 struct xml_allocator;
459 472
460 struct xml_memory_page 473 struct xml_memory_page
461 { 474 {
541 554
542 void* allocate_memory_oob(size_t size, xml_memory_page*& out_page); 555 void* allocate_memory_oob(size_t size, xml_memory_page*& out_page);
543 556
544 void* allocate_memory(size_t size, xml_memory_page*& out_page) 557 void* allocate_memory(size_t size, xml_memory_page*& out_page)
545 { 558 {
546 if (PUGI__UNLIKELY(_busy_size + size > xml_memory_page_size)) 559 if (PUGI_IMPL_UNLIKELY(_busy_size + size > xml_memory_page_size))
547 return allocate_memory_oob(size, out_page); 560 return allocate_memory_oob(size, out_page);
548 561
549 void* buf = reinterpret_cast<char*>(_root) + sizeof(xml_memory_page) + _busy_size; 562 void* buf = reinterpret_cast<char*>(_root) + sizeof(xml_memory_page) + _busy_size;
550 563
551 _busy_size += size; 564 _busy_size += size;
562 if (!result) return 0; 575 if (!result) return 0;
563 576
564 // adjust for marker 577 // adjust for marker
565 ptrdiff_t offset = static_cast<char*>(result) - reinterpret_cast<char*>(out_page->compact_page_marker); 578 ptrdiff_t offset = static_cast<char*>(result) - reinterpret_cast<char*>(out_page->compact_page_marker);
566 579
567 if (PUGI__UNLIKELY(static_cast<uintptr_t>(offset) >= 256 * xml_memory_block_alignment)) 580 if (PUGI_IMPL_UNLIKELY(static_cast<uintptr_t>(offset) >= 256 * xml_memory_block_alignment))
568 { 581 {
569 // insert new marker 582 // insert new marker
570 uint32_t* marker = static_cast<uint32_t*>(result); 583 uint32_t* marker = static_cast<uint32_t*>(result);
571 584
572 *marker = static_cast<uint32_t>(reinterpret_cast<char*>(marker) - reinterpret_cast<char*>(out_page)); 585 *marker = static_cast<uint32_t>(reinterpret_cast<char*>(marker) - reinterpret_cast<char*>(out_page));
639 652
640 char_t* allocate_string(size_t length) 653 char_t* allocate_string(size_t length)
641 { 654 {
642 static const size_t max_encoded_offset = (1 << 16) * xml_memory_block_alignment; 655 static const size_t max_encoded_offset = (1 << 16) * xml_memory_block_alignment;
643 656
644 PUGI__STATIC_ASSERT(xml_memory_page_size <= max_encoded_offset); 657 PUGI_IMPL_STATIC_ASSERT(xml_memory_page_size <= max_encoded_offset);
645 658
646 // allocate memory for string and header block 659 // allocate memory for string and header block
647 size_t size = sizeof(xml_memory_string_header) + length * sizeof(char_t); 660 size_t size = sizeof(xml_memory_string_header) + length * sizeof(char_t);
648 661
649 // round size up to block alignment boundary 662 // round size up to block alignment boundary
705 #ifdef PUGIXML_COMPACT 718 #ifdef PUGIXML_COMPACT
706 compact_hash_table* _hash; 719 compact_hash_table* _hash;
707 #endif 720 #endif
708 }; 721 };
709 722
710 PUGI__FN_NO_INLINE void* xml_allocator::allocate_memory_oob(size_t size, xml_memory_page*& out_page) 723 PUGI_IMPL_FN_NO_INLINE void* xml_allocator::allocate_memory_oob(size_t size, xml_memory_page*& out_page)
711 { 724 {
712 const size_t large_allocation_threshold = xml_memory_page_size / 4; 725 const size_t large_allocation_threshold = xml_memory_page_size / 4;
713 726
714 xml_memory_page* page = allocate_page(size <= large_allocation_threshold ? xml_memory_page_size : size); 727 xml_memory_page* page = allocate_page(size <= large_allocation_threshold ? xml_memory_page_size : size);
715 out_page = page; 728 out_page = page;
742 page->busy_size = size; 755 page->busy_size = size;
743 } 756 }
744 757
745 return reinterpret_cast<char*>(page) + sizeof(xml_memory_page); 758 return reinterpret_cast<char*>(page) + sizeof(xml_memory_page);
746 } 759 }
747 PUGI__NS_END 760 PUGI_IMPL_NS_END
748 761
749 #ifdef PUGIXML_COMPACT 762 #ifdef PUGIXML_COMPACT
750 PUGI__NS_BEGIN 763 PUGI_IMPL_NS_BEGIN
751 static const uintptr_t compact_alignment_log2 = 2; 764 static const uintptr_t compact_alignment_log2 = 2;
752 static const uintptr_t compact_alignment = 1 << compact_alignment_log2; 765 static const uintptr_t compact_alignment = 1 << compact_alignment_log2;
753 766
754 class compact_header 767 class compact_header
755 { 768 {
756 public: 769 public:
757 compact_header(xml_memory_page* page, unsigned int flags) 770 compact_header(xml_memory_page* page, unsigned int flags)
758 { 771 {
759 PUGI__STATIC_ASSERT(xml_memory_block_alignment == compact_alignment); 772 PUGI_IMPL_STATIC_ASSERT(xml_memory_block_alignment == compact_alignment);
760 773
761 ptrdiff_t offset = (reinterpret_cast<char*>(this) - reinterpret_cast<char*>(page->compact_page_marker)); 774 ptrdiff_t offset = (reinterpret_cast<char*>(this) - reinterpret_cast<char*>(page->compact_page_marker));
762 assert(offset % compact_alignment == 0 && static_cast<uintptr_t>(offset) < 256 * compact_alignment); 775 assert(offset % compact_alignment == 0 && static_cast<uintptr_t>(offset) < 256 * compact_alignment);
763 776
764 _page = static_cast<unsigned char>(offset >> compact_alignment_log2); 777 _page = static_cast<unsigned char>(offset >> compact_alignment_log2);
792 private: 805 private:
793 unsigned char _page; 806 unsigned char _page;
794 unsigned char _flags; 807 unsigned char _flags;
795 }; 808 };
796 809
797 PUGI__FN xml_memory_page* compact_get_page(const void* object, int header_offset) 810 PUGI_IMPL_FN xml_memory_page* compact_get_page(const void* object, int header_offset)
798 { 811 {
799 const compact_header* header = reinterpret_cast<const compact_header*>(static_cast<const char*>(object) - header_offset); 812 const compact_header* header = reinterpret_cast<const compact_header*>(static_cast<const char*>(object) - header_offset);
800 813
801 return header->get_page(); 814 return header->get_page();
802 } 815 }
803 816
804 template <int header_offset, typename T> PUGI__FN_NO_INLINE T* compact_get_value(const void* object) 817 template <int header_offset, typename T> PUGI_IMPL_FN_NO_INLINE T* compact_get_value(const void* object)
805 { 818 {
806 return static_cast<T*>(compact_get_page(object, header_offset)->allocator->_hash->find(object)); 819 return static_cast<T*>(compact_get_page(object, header_offset)->allocator->_hash->find(object));
807 } 820 }
808 821
809 template <int header_offset, typename T> PUGI__FN_NO_INLINE void compact_set_value(const void* object, T* value) 822 template <int header_offset, typename T> PUGI_IMPL_FN_NO_INLINE void compact_set_value(const void* object, T* value)
810 { 823 {
811 compact_get_page(object, header_offset)->allocator->_hash->insert(object, value); 824 compact_get_page(object, header_offset)->allocator->_hash->insert(object, value);
812 } 825 }
813 826
814 template <typename T, int header_offset, int start = -126> class compact_pointer 827 template <typename T, int header_offset, int start = -126> class compact_pointer
902 } 915 }
903 else 916 else
904 { 917 {
905 xml_memory_page* page = compact_get_page(this, header_offset); 918 xml_memory_page* page = compact_get_page(this, header_offset);
906 919
907 if (PUGI__UNLIKELY(page->compact_shared_parent == 0)) 920 if (PUGI_IMPL_UNLIKELY(page->compact_shared_parent == 0))
908 page->compact_shared_parent = value; 921 page->compact_shared_parent = value;
909 922
910 if (page->compact_shared_parent == value) 923 if (page->compact_shared_parent == value)
911 { 924 {
912 _data = 65534; 925 _data = 65534;
969 { 982 {
970 if (value) 983 if (value)
971 { 984 {
972 xml_memory_page* page = compact_get_page(this, header_offset); 985 xml_memory_page* page = compact_get_page(this, header_offset);
973 986
974 if (PUGI__UNLIKELY(page->compact_string_base == 0)) 987 if (PUGI_IMPL_UNLIKELY(page->compact_string_base == 0))
975 page->compact_string_base = value; 988 page->compact_string_base = value;
976 989
977 ptrdiff_t offset = value - page->compact_string_base; 990 ptrdiff_t offset = value - page->compact_string_base;
978 991
979 if (static_cast<uintptr_t>(offset) < (65535 << 7)) 992 if (static_cast<uintptr_t>(offset) < (65535 << 7))
1041 } 1054 }
1042 1055
1043 private: 1056 private:
1044 unsigned char _data; 1057 unsigned char _data;
1045 }; 1058 };
1046 PUGI__NS_END 1059 PUGI_IMPL_NS_END
1047 #endif 1060 #endif
1048 1061
1049 #ifdef PUGIXML_COMPACT 1062 #ifdef PUGIXML_COMPACT
1050 namespace pugi 1063 namespace pugi
1051 { 1064 {
1052 struct xml_attribute_struct 1065 struct xml_attribute_struct
1053 { 1066 {
1054 xml_attribute_struct(impl::xml_memory_page* page): header(page, 0), namevalue_base(0) 1067 xml_attribute_struct(impl::xml_memory_page* page): header(page, 0), namevalue_base(0)
1055 { 1068 {
1056 PUGI__STATIC_ASSERT(sizeof(xml_attribute_struct) == 8); 1069 PUGI_IMPL_STATIC_ASSERT(sizeof(xml_attribute_struct) == 8);
1057 } 1070 }
1058 1071
1059 impl::compact_header header; 1072 impl::compact_header header;
1060 1073
1061 uint16_t namevalue_base; 1074 uint16_t namevalue_base;
1069 1082
1070 struct xml_node_struct 1083 struct xml_node_struct
1071 { 1084 {
1072 xml_node_struct(impl::xml_memory_page* page, xml_node_type type): header(page, type), namevalue_base(0) 1085 xml_node_struct(impl::xml_memory_page* page, xml_node_type type): header(page, type), namevalue_base(0)
1073 { 1086 {
1074 PUGI__STATIC_ASSERT(sizeof(xml_node_struct) == 12); 1087 PUGI_IMPL_STATIC_ASSERT(sizeof(xml_node_struct) == 12);
1075 } 1088 }
1076 1089
1077 impl::compact_header header; 1090 impl::compact_header header;
1078 1091
1079 uint16_t namevalue_base; 1092 uint16_t namevalue_base;
1096 { 1109 {
1097 struct xml_attribute_struct 1110 struct xml_attribute_struct
1098 { 1111 {
1099 xml_attribute_struct(impl::xml_memory_page* page): name(0), value(0), prev_attribute_c(0), next_attribute(0) 1112 xml_attribute_struct(impl::xml_memory_page* page): name(0), value(0), prev_attribute_c(0), next_attribute(0)
1100 { 1113 {
1101 header = PUGI__GETHEADER_IMPL(this, page, 0); 1114 header = PUGI_IMPL_GETHEADER_IMPL(this, page, 0);
1102 } 1115 }
1103 1116
1104 uintptr_t header; 1117 uintptr_t header;
1105 1118
1106 char_t* name; 1119 char_t* name;
1112 1125
1113 struct xml_node_struct 1126 struct xml_node_struct
1114 { 1127 {
1115 xml_node_struct(impl::xml_memory_page* page, xml_node_type type): name(0), value(0), parent(0), first_child(0), prev_sibling_c(0), next_sibling(0), first_attribute(0) 1128 xml_node_struct(impl::xml_memory_page* page, xml_node_type type): name(0), value(0), parent(0), first_child(0), prev_sibling_c(0), next_sibling(0), first_attribute(0)
1116 { 1129 {
1117 header = PUGI__GETHEADER_IMPL(this, page, type); 1130 header = PUGI_IMPL_GETHEADER_IMPL(this, page, type);
1118 } 1131 }
1119 1132
1120 uintptr_t header; 1133 uintptr_t header;
1121 1134
1122 char_t* name; 1135 char_t* name;
1132 xml_attribute_struct* first_attribute; 1145 xml_attribute_struct* first_attribute;
1133 }; 1146 };
1134 } 1147 }
1135 #endif 1148 #endif
1136 1149
1137 PUGI__NS_BEGIN 1150 PUGI_IMPL_NS_BEGIN
1138 struct xml_extra_buffer 1151 struct xml_extra_buffer
1139 { 1152 {
1140 char_t* buffer; 1153 char_t* buffer;
1141 xml_extra_buffer* next; 1154 xml_extra_buffer* next;
1142 }; 1155 };
1158 1171
1159 template <typename Object> inline xml_allocator& get_allocator(const Object* object) 1172 template <typename Object> inline xml_allocator& get_allocator(const Object* object)
1160 { 1173 {
1161 assert(object); 1174 assert(object);
1162 1175
1163 return *PUGI__GETPAGE(object)->allocator; 1176 return *PUGI_IMPL_GETPAGE(object)->allocator;
1164 } 1177 }
1165 1178
1166 template <typename Object> inline xml_document_struct& get_document(const Object* object) 1179 template <typename Object> inline xml_document_struct& get_document(const Object* object)
1167 { 1180 {
1168 assert(object); 1181 assert(object);
1169 1182
1170 return *static_cast<xml_document_struct*>(PUGI__GETPAGE(object)->allocator); 1183 return *static_cast<xml_document_struct*>(PUGI_IMPL_GETPAGE(object)->allocator);
1171 } 1184 }
1172 PUGI__NS_END 1185 PUGI_IMPL_NS_END
1173 1186
1174 // Low-level DOM operations 1187 // Low-level DOM operations
1175 PUGI__NS_BEGIN 1188 PUGI_IMPL_NS_BEGIN
1176 inline xml_attribute_struct* allocate_attribute(xml_allocator& alloc) 1189 inline xml_attribute_struct* allocate_attribute(xml_allocator& alloc)
1177 { 1190 {
1178 xml_memory_page* page; 1191 xml_memory_page* page;
1179 void* memory = alloc.allocate_object(sizeof(xml_attribute_struct), page); 1192 void* memory = alloc.allocate_object(sizeof(xml_attribute_struct), page);
1180 if (!memory) return 0; 1193 if (!memory) return 0;
1197 alloc.deallocate_string(a->name); 1210 alloc.deallocate_string(a->name);
1198 1211
1199 if (a->header & impl::xml_memory_page_value_allocated_mask) 1212 if (a->header & impl::xml_memory_page_value_allocated_mask)
1200 alloc.deallocate_string(a->value); 1213 alloc.deallocate_string(a->value);
1201 1214
1202 alloc.deallocate_memory(a, sizeof(xml_attribute_struct), PUGI__GETPAGE(a)); 1215 alloc.deallocate_memory(a, sizeof(xml_attribute_struct), PUGI_IMPL_GETPAGE(a));
1203 } 1216 }
1204 1217
1205 inline void destroy_node(xml_node_struct* n, xml_allocator& alloc) 1218 inline void destroy_node(xml_node_struct* n, xml_allocator& alloc)
1206 { 1219 {
1207 if (n->header & impl::xml_memory_page_name_allocated_mask) 1220 if (n->header & impl::xml_memory_page_name_allocated_mask)
1226 destroy_node(child, alloc); 1239 destroy_node(child, alloc);
1227 1240
1228 child = next; 1241 child = next;
1229 } 1242 }
1230 1243
1231 alloc.deallocate_memory(n, sizeof(xml_node_struct), PUGI__GETPAGE(n)); 1244 alloc.deallocate_memory(n, sizeof(xml_node_struct), PUGI_IMPL_GETPAGE(n));
1232 } 1245 }
1233 1246
1234 inline void append_node(xml_node_struct* child, xml_node_struct* node) 1247 inline void append_node(xml_node_struct* child, xml_node_struct* node)
1235 { 1248 {
1236 child->parent = node; 1249 child->parent = node;
1410 1423
1411 attr->prev_attribute_c = 0; 1424 attr->prev_attribute_c = 0;
1412 attr->next_attribute = 0; 1425 attr->next_attribute = 0;
1413 } 1426 }
1414 1427
1415 PUGI__FN_NO_INLINE xml_node_struct* append_new_node(xml_node_struct* node, xml_allocator& alloc, xml_node_type type = node_element) 1428 PUGI_IMPL_FN_NO_INLINE xml_node_struct* append_new_node(xml_node_struct* node, xml_allocator& alloc, xml_node_type type = node_element)
1416 { 1429 {
1417 if (!alloc.reserve()) return 0; 1430 if (!alloc.reserve()) return 0;
1418 1431
1419 xml_node_struct* child = allocate_node(alloc, type); 1432 xml_node_struct* child = allocate_node(alloc, type);
1420 if (!child) return 0; 1433 if (!child) return 0;
1422 append_node(child, node); 1435 append_node(child, node);
1423 1436
1424 return child; 1437 return child;
1425 } 1438 }
1426 1439
1427 PUGI__FN_NO_INLINE xml_attribute_struct* append_new_attribute(xml_node_struct* node, xml_allocator& alloc) 1440 PUGI_IMPL_FN_NO_INLINE xml_attribute_struct* append_new_attribute(xml_node_struct* node, xml_allocator& alloc)
1428 { 1441 {
1429 if (!alloc.reserve()) return 0; 1442 if (!alloc.reserve()) return 0;
1430 1443
1431 xml_attribute_struct* attr = allocate_attribute(alloc); 1444 xml_attribute_struct* attr = allocate_attribute(alloc);
1432 if (!attr) return 0; 1445 if (!attr) return 0;
1433 1446
1434 append_attribute(attr, node); 1447 append_attribute(attr, node);
1435 1448
1436 return attr; 1449 return attr;
1437 } 1450 }
1438 PUGI__NS_END 1451 PUGI_IMPL_NS_END
1439 1452
1440 // Helper classes for code generation 1453 // Helper classes for code generation
1441 PUGI__NS_BEGIN 1454 PUGI_IMPL_NS_BEGIN
1442 struct opt_false 1455 struct opt_false
1443 { 1456 {
1444 enum { value = 0 }; 1457 enum { value = 0 };
1445 }; 1458 };
1446 1459
1447 struct opt_true 1460 struct opt_true
1448 { 1461 {
1449 enum { value = 1 }; 1462 enum { value = 1 };
1450 }; 1463 };
1451 PUGI__NS_END 1464 PUGI_IMPL_NS_END
1452 1465
1453 // Unicode utilities 1466 // Unicode utilities
1454 PUGI__NS_BEGIN 1467 PUGI_IMPL_NS_BEGIN
1455 inline uint16_t endian_swap(uint16_t value) 1468 inline uint16_t endian_swap(uint16_t value)
1456 { 1469 {
1457 return static_cast<uint16_t>(((value & 0xff) << 8) | (value >> 8)); 1470 return static_cast<uint16_t>(((value & 0xff) << 8) | (value >> 8));
1458 } 1471 }
1459 1472
1831 return decoder::process(reinterpret_cast<const typename decoder::type*>(data), size, result, traits); 1844 return decoder::process(reinterpret_cast<const typename decoder::type*>(data), size, result, traits);
1832 } 1845 }
1833 }; 1846 };
1834 1847
1835 #ifdef PUGIXML_WCHAR_MODE 1848 #ifdef PUGIXML_WCHAR_MODE
1836 PUGI__FN void convert_wchar_endian_swap(wchar_t* result, const wchar_t* data, size_t length) 1849 PUGI_IMPL_FN void convert_wchar_endian_swap(wchar_t* result, const wchar_t* data, size_t length)
1837 { 1850 {
1838 for (size_t i = 0; i < length; ++i) 1851 for (size_t i = 0; i < length; ++i)
1839 result[i] = static_cast<wchar_t>(endian_swap(static_cast<wchar_selector<sizeof(wchar_t)>::type>(data[i]))); 1852 result[i] = static_cast<wchar_t>(endian_swap(static_cast<wchar_selector<sizeof(wchar_t)>::type>(data[i])));
1840 } 1853 }
1841 #endif 1854 #endif
1842 PUGI__NS_END 1855 PUGI_IMPL_NS_END
1843 1856
1844 PUGI__NS_BEGIN 1857 PUGI_IMPL_NS_BEGIN
1845 enum chartype_t 1858 enum chartype_t
1846 { 1859 {
1847 ct_parse_pcdata = 1, // \0, &, \r, < 1860 ct_parse_pcdata = 1, // \0, &, \r, <
1848 ct_parse_attr = 2, // \0, &, \r, ', " 1861 ct_parse_attr = 2, // \0, &, \r, ', "
1849 ct_parse_attr_ws = 4, // \0, &, \r, ', ", \n, tab 1862 ct_parse_attr_ws = 4, // \0, &, \r, ', ", \n, tab
1905 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 1918 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20,
1906 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20 1919 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20
1907 }; 1920 };
1908 1921
1909 #ifdef PUGIXML_WCHAR_MODE 1922 #ifdef PUGIXML_WCHAR_MODE
1910 #define PUGI__IS_CHARTYPE_IMPL(c, ct, table) ((static_cast<unsigned int>(c) < 128 ? table[static_cast<unsigned int>(c)] : table[128]) & (ct)) 1923 #define PUGI_IMPL_IS_CHARTYPE_IMPL(c, ct, table) ((static_cast<unsigned int>(c) < 128 ? table[static_cast<unsigned int>(c)] : table[128]) & (ct))
1911 #else 1924 #else
1912 #define PUGI__IS_CHARTYPE_IMPL(c, ct, table) (table[static_cast<unsigned char>(c)] & (ct)) 1925 #define PUGI_IMPL_IS_CHARTYPE_IMPL(c, ct, table) (table[static_cast<unsigned char>(c)] & (ct))
1913 #endif 1926 #endif
1914 1927
1915 #define PUGI__IS_CHARTYPE(c, ct) PUGI__IS_CHARTYPE_IMPL(c, ct, chartype_table) 1928 #define PUGI_IMPL_IS_CHARTYPE(c, ct) PUGI_IMPL_IS_CHARTYPE_IMPL(c, ct, chartype_table)
1916 #define PUGI__IS_CHARTYPEX(c, ct) PUGI__IS_CHARTYPE_IMPL(c, ct, chartypex_table) 1929 #define PUGI_IMPL_IS_CHARTYPEX(c, ct) PUGI_IMPL_IS_CHARTYPE_IMPL(c, ct, chartypex_table)
1917 1930
1918 PUGI__FN bool is_little_endian() 1931 PUGI_IMPL_FN bool is_little_endian()
1919 { 1932 {
1920 unsigned int ui = 1; 1933 unsigned int ui = 1;
1921 1934
1922 return *reinterpret_cast<unsigned char*>(&ui) == 1; 1935 return *reinterpret_cast<unsigned char*>(&ui) == 1;
1923 } 1936 }
1924 1937
1925 PUGI__FN xml_encoding get_wchar_encoding() 1938 PUGI_IMPL_FN xml_encoding get_wchar_encoding()
1926 { 1939 {
1927 PUGI__STATIC_ASSERT(sizeof(wchar_t) == 2 || sizeof(wchar_t) == 4); 1940 PUGI_IMPL_STATIC_ASSERT(sizeof(wchar_t) == 2 || sizeof(wchar_t) == 4);
1928 1941
1929 if (sizeof(wchar_t) == 2) 1942 if (sizeof(wchar_t) == 2)
1930 return is_little_endian() ? encoding_utf16_le : encoding_utf16_be; 1943 return is_little_endian() ? encoding_utf16_le : encoding_utf16_be;
1931 else 1944 else
1932 return is_little_endian() ? encoding_utf32_le : encoding_utf32_be; 1945 return is_little_endian() ? encoding_utf32_le : encoding_utf32_be;
1933 } 1946 }
1934 1947
1935 PUGI__FN bool parse_declaration_encoding(const uint8_t* data, size_t size, const uint8_t*& out_encoding, size_t& out_length) 1948 PUGI_IMPL_FN bool parse_declaration_encoding(const uint8_t* data, size_t size, const uint8_t*& out_encoding, size_t& out_length)
1936 { 1949 {
1937 #define PUGI__SCANCHAR(ch) { if (offset >= size || data[offset] != ch) return false; offset++; } 1950 #define PUGI_IMPL_SCANCHAR(ch) { if (offset >= size || data[offset] != ch) return false; offset++; }
1938 #define PUGI__SCANCHARTYPE(ct) { while (offset < size && PUGI__IS_CHARTYPE(data[offset], ct)) offset++; } 1951 #define PUGI_IMPL_SCANCHARTYPE(ct) { while (offset < size && PUGI_IMPL_IS_CHARTYPE(data[offset], ct)) offset++; }
1939 1952
1940 // check if we have a non-empty XML declaration 1953 // check if we have a non-empty XML declaration
1941 if (size < 6 || !((data[0] == '<') & (data[1] == '?') & (data[2] == 'x') & (data[3] == 'm') & (data[4] == 'l') && PUGI__IS_CHARTYPE(data[5], ct_space))) 1954 if (size < 6 || !((data[0] == '<') & (data[1] == '?') & (data[2] == 'x') & (data[3] == 'm') & (data[4] == 'l') && PUGI_IMPL_IS_CHARTYPE(data[5], ct_space)))
1942 return false; 1955 return false;
1943 1956
1944 // scan XML declaration until the encoding field 1957 // scan XML declaration until the encoding field
1945 for (size_t i = 6; i + 1 < size; ++i) 1958 for (size_t i = 6; i + 1 < size; ++i)
1946 { 1959 {
1951 if (data[i] == 'e' && data[i + 1] == 'n') 1964 if (data[i] == 'e' && data[i + 1] == 'n')
1952 { 1965 {
1953 size_t offset = i; 1966 size_t offset = i;
1954 1967
1955 // encoding follows the version field which can't contain 'en' so this has to be the encoding if XML is well formed 1968 // encoding follows the version field which can't contain 'en' so this has to be the encoding if XML is well formed
1956 PUGI__SCANCHAR('e'); PUGI__SCANCHAR('n'); PUGI__SCANCHAR('c'); PUGI__SCANCHAR('o'); 1969 PUGI_IMPL_SCANCHAR('e'); PUGI_IMPL_SCANCHAR('n'); PUGI_IMPL_SCANCHAR('c'); PUGI_IMPL_SCANCHAR('o');
1957 PUGI__SCANCHAR('d'); PUGI__SCANCHAR('i'); PUGI__SCANCHAR('n'); PUGI__SCANCHAR('g'); 1970 PUGI_IMPL_SCANCHAR('d'); PUGI_IMPL_SCANCHAR('i'); PUGI_IMPL_SCANCHAR('n'); PUGI_IMPL_SCANCHAR('g');
1958 1971
1959 // S? = S? 1972 // S? = S?
1960 PUGI__SCANCHARTYPE(ct_space); 1973 PUGI_IMPL_SCANCHARTYPE(ct_space);
1961 PUGI__SCANCHAR('='); 1974 PUGI_IMPL_SCANCHAR('=');
1962 PUGI__SCANCHARTYPE(ct_space); 1975 PUGI_IMPL_SCANCHARTYPE(ct_space);
1963 1976
1964 // the only two valid delimiters are ' and " 1977 // the only two valid delimiters are ' and "
1965 uint8_t delimiter = (offset < size && data[offset] == '"') ? '"' : '\''; 1978 uint8_t delimiter = (offset < size && data[offset] == '"') ? '"' : '\'';
1966 1979
1967 PUGI__SCANCHAR(delimiter); 1980 PUGI_IMPL_SCANCHAR(delimiter);
1968 1981
1969 size_t start = offset; 1982 size_t start = offset;
1970 1983
1971 out_encoding = data + offset; 1984 out_encoding = data + offset;
1972 1985
1973 PUGI__SCANCHARTYPE(ct_symbol); 1986 PUGI_IMPL_SCANCHARTYPE(ct_symbol);
1974 1987
1975 out_length = offset - start; 1988 out_length = offset - start;
1976 1989
1977 PUGI__SCANCHAR(delimiter); 1990 PUGI_IMPL_SCANCHAR(delimiter);
1978 1991
1979 return true; 1992 return true;
1980 } 1993 }
1981 } 1994 }
1982 1995
1983 return false; 1996 return false;
1984 1997
1985 #undef PUGI__SCANCHAR 1998 #undef PUGI_IMPL_SCANCHAR
1986 #undef PUGI__SCANCHARTYPE 1999 #undef PUGI_IMPL_SCANCHARTYPE
1987 } 2000 }
1988 2001
1989 PUGI__FN xml_encoding guess_buffer_encoding(const uint8_t* data, size_t size) 2002 PUGI_IMPL_FN xml_encoding guess_buffer_encoding(const uint8_t* data, size_t size)
1990 { 2003 {
1991 // skip encoding autodetection if input buffer is too small 2004 // skip encoding autodetection if input buffer is too small
1992 if (size < 4) return encoding_utf8; 2005 if (size < 4) return encoding_utf8;
1993 2006
1994 uint8_t d0 = data[0], d1 = data[1], d2 = data[2], d3 = data[3]; 2007 uint8_t d0 = data[0], d1 = data[1], d2 = data[2], d3 = data[3];
2032 } 2045 }
2033 2046
2034 return encoding_utf8; 2047 return encoding_utf8;
2035 } 2048 }
2036 2049
2037 PUGI__FN xml_encoding get_buffer_encoding(xml_encoding encoding, const void* contents, size_t size) 2050 PUGI_IMPL_FN xml_encoding get_buffer_encoding(xml_encoding encoding, const void* contents, size_t size)
2038 { 2051 {
2039 // replace wchar encoding with utf implementation 2052 // replace wchar encoding with utf implementation
2040 if (encoding == encoding_wchar) return get_wchar_encoding(); 2053 if (encoding == encoding_wchar) return get_wchar_encoding();
2041 2054
2042 // replace utf16 encoding with utf16 with specific endianness 2055 // replace utf16 encoding with utf16 with specific endianness
2052 const uint8_t* data = static_cast<const uint8_t*>(contents); 2065 const uint8_t* data = static_cast<const uint8_t*>(contents);
2053 2066
2054 return guess_buffer_encoding(data, size); 2067 return guess_buffer_encoding(data, size);
2055 } 2068 }
2056 2069
2057 PUGI__FN bool get_mutable_buffer(char_t*& out_buffer, size_t& out_length, const void* contents, size_t size, bool is_mutable) 2070 PUGI_IMPL_FN bool get_mutable_buffer(char_t*& out_buffer, size_t& out_length, const void* contents, size_t size, bool is_mutable)
2058 { 2071 {
2059 size_t length = size / sizeof(char_t); 2072 size_t length = size / sizeof(char_t);
2060 2073
2061 if (is_mutable) 2074 if (is_mutable)
2062 { 2075 {
2081 2094
2082 return true; 2095 return true;
2083 } 2096 }
2084 2097
2085 #ifdef PUGIXML_WCHAR_MODE 2098 #ifdef PUGIXML_WCHAR_MODE
2086 PUGI__FN bool need_endian_swap_utf(xml_encoding le, xml_encoding re) 2099 PUGI_IMPL_FN bool need_endian_swap_utf(xml_encoding le, xml_encoding re)
2087 { 2100 {
2088 return (le == encoding_utf16_be && re == encoding_utf16_le) || (le == encoding_utf16_le && re == encoding_utf16_be) || 2101 return (le == encoding_utf16_be && re == encoding_utf16_le) || (le == encoding_utf16_le && re == encoding_utf16_be) ||
2089 (le == encoding_utf32_be && re == encoding_utf32_le) || (le == encoding_utf32_le && re == encoding_utf32_be); 2102 (le == encoding_utf32_be && re == encoding_utf32_le) || (le == encoding_utf32_le && re == encoding_utf32_be);
2090 } 2103 }
2091 2104
2092 PUGI__FN bool convert_buffer_endian_swap(char_t*& out_buffer, size_t& out_length, const void* contents, size_t size, bool is_mutable) 2105 PUGI_IMPL_FN bool convert_buffer_endian_swap(char_t*& out_buffer, size_t& out_length, const void* contents, size_t size, bool is_mutable)
2093 { 2106 {
2094 const char_t* data = static_cast<const char_t*>(contents); 2107 const char_t* data = static_cast<const char_t*>(contents);
2095 size_t length = size / sizeof(char_t); 2108 size_t length = size / sizeof(char_t);
2096 2109
2097 if (is_mutable) 2110 if (is_mutable)
2116 } 2129 }
2117 2130
2118 return true; 2131 return true;
2119 } 2132 }
2120 2133
2121 template <typename D> PUGI__FN bool convert_buffer_generic(char_t*& out_buffer, size_t& out_length, const void* contents, size_t size, D) 2134 template <typename D> PUGI_IMPL_FN bool convert_buffer_generic(char_t*& out_buffer, size_t& out_length, const void* contents, size_t size, D)
2122 { 2135 {
2123 const typename D::type* data = static_cast<const typename D::type*>(contents); 2136 const typename D::type* data = static_cast<const typename D::type*>(contents);
2124 size_t data_length = size / sizeof(typename D::type); 2137 size_t data_length = size / sizeof(typename D::type);
2125 2138
2126 // first pass: get length in wchar_t units 2139 // first pass: get length in wchar_t units
2141 out_length = length + 1; 2154 out_length = length + 1;
2142 2155
2143 return true; 2156 return true;
2144 } 2157 }
2145 2158
2146 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) 2159 PUGI_IMPL_FN bool convert_buffer(char_t*& out_buffer, size_t& out_length, xml_encoding encoding, const void* contents, size_t size, bool is_mutable)
2147 { 2160 {
2148 // get native encoding 2161 // get native encoding
2149 xml_encoding wchar_encoding = get_wchar_encoding(); 2162 xml_encoding wchar_encoding = get_wchar_encoding();
2150 2163
2151 // fast path: no conversion required 2164 // fast path: no conversion required
2186 2199
2187 assert(false && "Invalid encoding"); // unreachable 2200 assert(false && "Invalid encoding"); // unreachable
2188 return false; 2201 return false;
2189 } 2202 }
2190 #else 2203 #else
2191 template <typename D> PUGI__FN bool convert_buffer_generic(char_t*& out_buffer, size_t& out_length, const void* contents, size_t size, D) 2204 template <typename D> PUGI_IMPL_FN bool convert_buffer_generic(char_t*& out_buffer, size_t& out_length, const void* contents, size_t size, D)
2192 { 2205 {
2193 const typename D::type* data = static_cast<const typename D::type*>(contents); 2206 const typename D::type* data = static_cast<const typename D::type*>(contents);
2194 size_t data_length = size / sizeof(typename D::type); 2207 size_t data_length = size / sizeof(typename D::type);
2195 2208
2196 // first pass: get length in utf8 units 2209 // first pass: get length in utf8 units
2211 out_length = length + 1; 2224 out_length = length + 1;
2212 2225
2213 return true; 2226 return true;
2214 } 2227 }
2215 2228
2216 PUGI__FN size_t get_latin1_7bit_prefix_length(const uint8_t* data, size_t size) 2229 PUGI_IMPL_FN size_t get_latin1_7bit_prefix_length(const uint8_t* data, size_t size)
2217 { 2230 {
2218 for (size_t i = 0; i < size; ++i) 2231 for (size_t i = 0; i < size; ++i)
2219 if (data[i] > 127) 2232 if (data[i] > 127)
2220 return i; 2233 return i;
2221 2234
2222 return size; 2235 return size;
2223 } 2236 }
2224 2237
2225 PUGI__FN bool convert_buffer_latin1(char_t*& out_buffer, size_t& out_length, const void* contents, size_t size, bool is_mutable) 2238 PUGI_IMPL_FN bool convert_buffer_latin1(char_t*& out_buffer, size_t& out_length, const void* contents, size_t size, bool is_mutable)
2226 { 2239 {
2227 const uint8_t* data = static_cast<const uint8_t*>(contents); 2240 const uint8_t* data = static_cast<const uint8_t*>(contents);
2228 size_t data_length = size; 2241 size_t data_length = size;
2229 2242
2230 // get size of prefix that does not need utf8 conversion 2243 // get size of prefix that does not need utf8 conversion
2257 out_length = length + 1; 2270 out_length = length + 1;
2258 2271
2259 return true; 2272 return true;
2260 } 2273 }
2261 2274
2262 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) 2275 PUGI_IMPL_FN bool convert_buffer(char_t*& out_buffer, size_t& out_length, xml_encoding encoding, const void* contents, size_t size, bool is_mutable)
2263 { 2276 {
2264 // fast path: no conversion required 2277 // fast path: no conversion required
2265 if (encoding == encoding_utf8) 2278 if (encoding == encoding_utf8)
2266 return get_mutable_buffer(out_buffer, out_length, contents, size, is_mutable); 2279 return get_mutable_buffer(out_buffer, out_length, contents, size, is_mutable);
2267 2280
2292 assert(false && "Invalid encoding"); // unreachable 2305 assert(false && "Invalid encoding"); // unreachable
2293 return false; 2306 return false;
2294 } 2307 }
2295 #endif 2308 #endif
2296 2309
2297 PUGI__FN size_t as_utf8_begin(const wchar_t* str, size_t length) 2310 PUGI_IMPL_FN size_t as_utf8_begin(const wchar_t* str, size_t length)
2298 { 2311 {
2299 // get length in utf8 characters 2312 // get length in utf8 characters
2300 return wchar_decoder::process(str, length, 0, utf8_counter()); 2313 return wchar_decoder::process(str, length, 0, utf8_counter());
2301 } 2314 }
2302 2315
2303 PUGI__FN void as_utf8_end(char* buffer, size_t size, const wchar_t* str, size_t length) 2316 PUGI_IMPL_FN void as_utf8_end(char* buffer, size_t size, const wchar_t* str, size_t length)
2304 { 2317 {
2305 // convert to utf8 2318 // convert to utf8
2306 uint8_t* begin = reinterpret_cast<uint8_t*>(buffer); 2319 uint8_t* begin = reinterpret_cast<uint8_t*>(buffer);
2307 uint8_t* end = wchar_decoder::process(str, length, begin, utf8_writer()); 2320 uint8_t* end = wchar_decoder::process(str, length, begin, utf8_writer());
2308 2321
2310 (void)!end; 2323 (void)!end;
2311 (void)!size; 2324 (void)!size;
2312 } 2325 }
2313 2326
2314 #ifndef PUGIXML_NO_STL 2327 #ifndef PUGIXML_NO_STL
2315 PUGI__FN std::string as_utf8_impl(const wchar_t* str, size_t length) 2328 PUGI_IMPL_FN std::string as_utf8_impl(const wchar_t* str, size_t length)
2316 { 2329 {
2317 // first pass: get length in utf8 characters 2330 // first pass: get length in utf8 characters
2318 size_t size = as_utf8_begin(str, length); 2331 size_t size = as_utf8_begin(str, length);
2319 2332
2320 // allocate resulting string 2333 // allocate resulting string
2325 if (size > 0) as_utf8_end(&result[0], size, str, length); 2338 if (size > 0) as_utf8_end(&result[0], size, str, length);
2326 2339
2327 return result; 2340 return result;
2328 } 2341 }
2329 2342
2330 PUGI__FN std::basic_string<wchar_t> as_wide_impl(const char* str, size_t size) 2343 PUGI_IMPL_FN std::basic_string<wchar_t> as_wide_impl(const char* str, size_t size)
2331 { 2344 {
2332 const uint8_t* data = reinterpret_cast<const uint8_t*>(str); 2345 const uint8_t* data = reinterpret_cast<const uint8_t*>(str);
2333 2346
2334 // first pass: get length in wchar_t units 2347 // first pass: get length in wchar_t units
2335 size_t length = utf8_decoder::process(data, size, 0, wchar_counter()); 2348 size_t length = utf8_decoder::process(data, size, 0, wchar_counter());
2368 2381
2369 return target_length >= length && (target_length < reuse_threshold || target_length - length < target_length / 2); 2382 return target_length >= length && (target_length < reuse_threshold || target_length - length < target_length / 2);
2370 } 2383 }
2371 2384
2372 template <typename String, typename Header> 2385 template <typename String, typename Header>
2373 PUGI__FN bool strcpy_insitu(String& dest, Header& header, uintptr_t header_mask, const char_t* source, size_t source_length) 2386 PUGI_IMPL_FN bool strcpy_insitu(String& dest, Header& header, uintptr_t header_mask, const char_t* source, size_t source_length)
2374 { 2387 {
2388 assert((header & header_mask) == 0 || dest); // header bit indicates whether dest was previously allocated
2389
2375 if (source_length == 0) 2390 if (source_length == 0)
2376 { 2391 {
2377 // empty string and null pointer are equivalent, so just deallocate old memory 2392 // empty string and null pointer are equivalent, so just deallocate old memory
2378 xml_allocator* alloc = PUGI__GETPAGE_IMPL(header)->allocator; 2393 xml_allocator* alloc = PUGI_IMPL_GETPAGE_IMPL(header)->allocator;
2379 2394
2380 if (header & header_mask) alloc->deallocate_string(dest); 2395 if (header & header_mask) alloc->deallocate_string(dest);
2381 2396
2382 // mark the string as not allocated 2397 // mark the string as not allocated
2383 dest = 0; 2398 dest = 0;
2393 2408
2394 return true; 2409 return true;
2395 } 2410 }
2396 else 2411 else
2397 { 2412 {
2398 xml_allocator* alloc = PUGI__GETPAGE_IMPL(header)->allocator; 2413 xml_allocator* alloc = PUGI_IMPL_GETPAGE_IMPL(header)->allocator;
2399 2414
2400 if (!alloc->reserve()) return false; 2415 if (!alloc->reserve()) return false;
2401 2416
2402 // allocate new buffer 2417 // allocate new buffer
2403 char_t* buf = alloc->allocate_string(source_length + 1); 2418 char_t* buf = alloc->allocate_string(source_length + 1);
2458 } 2473 }
2459 else return s; 2474 else return s;
2460 } 2475 }
2461 }; 2476 };
2462 2477
2463 PUGI__FN char_t* strconv_escape(char_t* s, gap& g) 2478 PUGI_IMPL_FN char_t* strconv_escape(char_t* s, gap& g)
2464 { 2479 {
2465 char_t* stre = s + 1; 2480 char_t* stre = s + 1;
2466 2481
2467 switch (*stre) 2482 switch (*stre)
2468 { 2483 {
2599 2614
2600 return stre; 2615 return stre;
2601 } 2616 }
2602 2617
2603 // Parser utilities 2618 // Parser utilities
2604 #define PUGI__ENDSWITH(c, e) ((c) == (e) || ((c) == 0 && endch == (e))) 2619 #define PUGI_IMPL_ENDSWITH(c, e) ((c) == (e) || ((c) == 0 && endch == (e)))
2605 #define PUGI__SKIPWS() { while (PUGI__IS_CHARTYPE(*s, ct_space)) ++s; } 2620 #define PUGI_IMPL_SKIPWS() { while (PUGI_IMPL_IS_CHARTYPE(*s, ct_space)) ++s; }
2606 #define PUGI__OPTSET(OPT) ( optmsk & (OPT) ) 2621 #define PUGI_IMPL_OPTSET(OPT) ( optmsk & (OPT) )
2607 #define PUGI__PUSHNODE(TYPE) { cursor = append_new_node(cursor, *alloc, TYPE); if (!cursor) PUGI__THROW_ERROR(status_out_of_memory, s); } 2622 #define PUGI_IMPL_PUSHNODE(TYPE) { cursor = append_new_node(cursor, *alloc, TYPE); if (!cursor) PUGI_IMPL_THROW_ERROR(status_out_of_memory, s); }
2608 #define PUGI__POPNODE() { cursor = cursor->parent; } 2623 #define PUGI_IMPL_POPNODE() { cursor = cursor->parent; }
2609 #define PUGI__SCANFOR(X) { while (*s != 0 && !(X)) ++s; } 2624 #define PUGI_IMPL_SCANFOR(X) { while (*s != 0 && !(X)) ++s; }
2610 #define PUGI__SCANWHILE(X) { while (X) ++s; } 2625 #define PUGI_IMPL_SCANWHILE(X) { while (X) ++s; }
2611 #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; } } 2626 #define PUGI_IMPL_SCANWHILE_UNROLL(X) { for (;;) { char_t ss = s[0]; if (PUGI_IMPL_UNLIKELY(!(X))) { break; } ss = s[1]; if (PUGI_IMPL_UNLIKELY(!(X))) { s += 1; break; } ss = s[2]; if (PUGI_IMPL_UNLIKELY(!(X))) { s += 2; break; } ss = s[3]; if (PUGI_IMPL_UNLIKELY(!(X))) { s += 3; break; } s += 4; } }
2612 #define PUGI__ENDSEG() { ch = *s; *s = 0; ++s; } 2627 #define PUGI_IMPL_ENDSEG() { ch = *s; *s = 0; ++s; }
2613 #define PUGI__THROW_ERROR(err, m) return error_offset = m, error_status = err, static_cast<char_t*>(0) 2628 #define PUGI_IMPL_THROW_ERROR(err, m) return error_offset = m, error_status = err, static_cast<char_t*>(0)
2614 #define PUGI__CHECK_ERROR(err, m) { if (*s == 0) PUGI__THROW_ERROR(err, m); } 2629 #define PUGI_IMPL_CHECK_ERROR(err, m) { if (*s == 0) PUGI_IMPL_THROW_ERROR(err, m); }
2615 2630
2616 PUGI__FN char_t* strconv_comment(char_t* s, char_t endch) 2631 PUGI_IMPL_FN char_t* strconv_comment(char_t* s, char_t endch)
2617 { 2632 {
2618 gap g; 2633 gap g;
2619 2634
2620 while (true) 2635 while (true)
2621 { 2636 {
2622 PUGI__SCANWHILE_UNROLL(!PUGI__IS_CHARTYPE(ss, ct_parse_comment)); 2637 PUGI_IMPL_SCANWHILE_UNROLL(!PUGI_IMPL_IS_CHARTYPE(ss, ct_parse_comment));
2623 2638
2624 if (*s == '\r') // Either a single 0x0d or 0x0d 0x0a pair 2639 if (*s == '\r') // Either a single 0x0d or 0x0d 0x0a pair
2625 { 2640 {
2626 *s++ = '\n'; // replace first one with 0x0a 2641 *s++ = '\n'; // replace first one with 0x0a
2627 2642
2628 if (*s == '\n') g.push(s, 1); 2643 if (*s == '\n') g.push(s, 1);
2629 } 2644 }
2630 else if (s[0] == '-' && s[1] == '-' && PUGI__ENDSWITH(s[2], '>')) // comment ends here 2645 else if (s[0] == '-' && s[1] == '-' && PUGI_IMPL_ENDSWITH(s[2], '>')) // comment ends here
2631 { 2646 {
2632 *g.flush(s) = 0; 2647 *g.flush(s) = 0;
2633 2648
2634 return s + (s[2] == '>' ? 3 : 2); 2649 return s + (s[2] == '>' ? 3 : 2);
2635 } 2650 }
2639 } 2654 }
2640 else ++s; 2655 else ++s;
2641 } 2656 }
2642 } 2657 }
2643 2658
2644 PUGI__FN char_t* strconv_cdata(char_t* s, char_t endch) 2659 PUGI_IMPL_FN char_t* strconv_cdata(char_t* s, char_t endch)
2645 { 2660 {
2646 gap g; 2661 gap g;
2647 2662
2648 while (true) 2663 while (true)
2649 { 2664 {
2650 PUGI__SCANWHILE_UNROLL(!PUGI__IS_CHARTYPE(ss, ct_parse_cdata)); 2665 PUGI_IMPL_SCANWHILE_UNROLL(!PUGI_IMPL_IS_CHARTYPE(ss, ct_parse_cdata));
2651 2666
2652 if (*s == '\r') // Either a single 0x0d or 0x0d 0x0a pair 2667 if (*s == '\r') // Either a single 0x0d or 0x0d 0x0a pair
2653 { 2668 {
2654 *s++ = '\n'; // replace first one with 0x0a 2669 *s++ = '\n'; // replace first one with 0x0a
2655 2670
2656 if (*s == '\n') g.push(s, 1); 2671 if (*s == '\n') g.push(s, 1);
2657 } 2672 }
2658 else if (s[0] == ']' && s[1] == ']' && PUGI__ENDSWITH(s[2], '>')) // CDATA ends here 2673 else if (s[0] == ']' && s[1] == ']' && PUGI_IMPL_ENDSWITH(s[2], '>')) // CDATA ends here
2659 { 2674 {
2660 *g.flush(s) = 0; 2675 *g.flush(s) = 0;
2661 2676
2662 return s + 1; 2677 return s + 1;
2663 } 2678 }
2679 2694
2680 char_t* begin = s; 2695 char_t* begin = s;
2681 2696
2682 while (true) 2697 while (true)
2683 { 2698 {
2684 PUGI__SCANWHILE_UNROLL(!PUGI__IS_CHARTYPE(ss, ct_parse_pcdata)); 2699 PUGI_IMPL_SCANWHILE_UNROLL(!PUGI_IMPL_IS_CHARTYPE(ss, ct_parse_pcdata));
2685 2700
2686 if (*s == '<') // PCDATA ends here 2701 if (*s == '<') // PCDATA ends here
2687 { 2702 {
2688 char_t* end = g.flush(s); 2703 char_t* end = g.flush(s);
2689 2704
2690 if (opt_trim::value) 2705 if (opt_trim::value)
2691 while (end > begin && PUGI__IS_CHARTYPE(end[-1], ct_space)) 2706 while (end > begin && PUGI_IMPL_IS_CHARTYPE(end[-1], ct_space))
2692 --end; 2707 --end;
2693 2708
2694 *end = 0; 2709 *end = 0;
2695 2710
2696 return s + 1; 2711 return s + 1;
2708 else if (*s == 0) 2723 else if (*s == 0)
2709 { 2724 {
2710 char_t* end = g.flush(s); 2725 char_t* end = g.flush(s);
2711 2726
2712 if (opt_trim::value) 2727 if (opt_trim::value)
2713 while (end > begin && PUGI__IS_CHARTYPE(end[-1], ct_space)) 2728 while (end > begin && PUGI_IMPL_IS_CHARTYPE(end[-1], ct_space))
2714 --end; 2729 --end;
2715 2730
2716 *end = 0; 2731 *end = 0;
2717 2732
2718 return s; 2733 return s;
2720 else ++s; 2735 else ++s;
2721 } 2736 }
2722 } 2737 }
2723 }; 2738 };
2724 2739
2725 PUGI__FN strconv_pcdata_t get_strconv_pcdata(unsigned int optmask) 2740 PUGI_IMPL_FN strconv_pcdata_t get_strconv_pcdata(unsigned int optmask)
2726 { 2741 {
2727 PUGI__STATIC_ASSERT(parse_escapes == 0x10 && parse_eol == 0x20 && parse_trim_pcdata == 0x0800); 2742 PUGI_IMPL_STATIC_ASSERT(parse_escapes == 0x10 && parse_eol == 0x20 && parse_trim_pcdata == 0x0800);
2728 2743
2729 switch (((optmask >> 4) & 3) | ((optmask >> 9) & 4)) // get bitmask for flags (trim eol escapes); this simultaneously checks 3 options from assertion above 2744 switch (((optmask >> 4) & 3) | ((optmask >> 9) & 4)) // get bitmask for flags (trim eol escapes); this simultaneously checks 3 options from assertion above
2730 { 2745 {
2731 case 0: return strconv_pcdata_impl<opt_false, opt_false, opt_false>::parse; 2746 case 0: return strconv_pcdata_impl<opt_false, opt_false, opt_false>::parse;
2732 case 1: return strconv_pcdata_impl<opt_false, opt_false, opt_true>::parse; 2747 case 1: return strconv_pcdata_impl<opt_false, opt_false, opt_true>::parse;
2747 static char_t* parse_wnorm(char_t* s, char_t end_quote) 2762 static char_t* parse_wnorm(char_t* s, char_t end_quote)
2748 { 2763 {
2749 gap g; 2764 gap g;
2750 2765
2751 // trim leading whitespaces 2766 // trim leading whitespaces
2752 if (PUGI__IS_CHARTYPE(*s, ct_space)) 2767 if (PUGI_IMPL_IS_CHARTYPE(*s, ct_space))
2753 { 2768 {
2754 char_t* str = s; 2769 char_t* str = s;
2755 2770
2756 do ++str; 2771 do ++str;
2757 while (PUGI__IS_CHARTYPE(*str, ct_space)); 2772 while (PUGI_IMPL_IS_CHARTYPE(*str, ct_space));
2758 2773
2759 g.push(s, str - s); 2774 g.push(s, str - s);
2760 } 2775 }
2761 2776
2762 while (true) 2777 while (true)
2763 { 2778 {
2764 PUGI__SCANWHILE_UNROLL(!PUGI__IS_CHARTYPE(ss, ct_parse_attr_ws | ct_space)); 2779 PUGI_IMPL_SCANWHILE_UNROLL(!PUGI_IMPL_IS_CHARTYPE(ss, ct_parse_attr_ws | ct_space));
2765 2780
2766 if (*s == end_quote) 2781 if (*s == end_quote)
2767 { 2782 {
2768 char_t* str = g.flush(s); 2783 char_t* str = g.flush(s);
2769 2784
2770 do *str-- = 0; 2785 do *str-- = 0;
2771 while (PUGI__IS_CHARTYPE(*str, ct_space)); 2786 while (PUGI_IMPL_IS_CHARTYPE(*str, ct_space));
2772 2787
2773 return s + 1; 2788 return s + 1;
2774 } 2789 }
2775 else if (PUGI__IS_CHARTYPE(*s, ct_space)) 2790 else if (PUGI_IMPL_IS_CHARTYPE(*s, ct_space))
2776 { 2791 {
2777 *s++ = ' '; 2792 *s++ = ' ';
2778 2793
2779 if (PUGI__IS_CHARTYPE(*s, ct_space)) 2794 if (PUGI_IMPL_IS_CHARTYPE(*s, ct_space))
2780 { 2795 {
2781 char_t* str = s + 1; 2796 char_t* str = s + 1;
2782 while (PUGI__IS_CHARTYPE(*str, ct_space)) ++str; 2797 while (PUGI_IMPL_IS_CHARTYPE(*str, ct_space)) ++str;
2783 2798
2784 g.push(s, str - s); 2799 g.push(s, str - s);
2785 } 2800 }
2786 } 2801 }
2787 else if (opt_escape::value && *s == '&') 2802 else if (opt_escape::value && *s == '&')
2800 { 2815 {
2801 gap g; 2816 gap g;
2802 2817
2803 while (true) 2818 while (true)
2804 { 2819 {
2805 PUGI__SCANWHILE_UNROLL(!PUGI__IS_CHARTYPE(ss, ct_parse_attr_ws)); 2820 PUGI_IMPL_SCANWHILE_UNROLL(!PUGI_IMPL_IS_CHARTYPE(ss, ct_parse_attr_ws));
2806 2821
2807 if (*s == end_quote) 2822 if (*s == end_quote)
2808 { 2823 {
2809 *g.flush(s) = 0; 2824 *g.flush(s) = 0;
2810 2825
2811 return s + 1; 2826 return s + 1;
2812 } 2827 }
2813 else if (PUGI__IS_CHARTYPE(*s, ct_space)) 2828 else if (PUGI_IMPL_IS_CHARTYPE(*s, ct_space))
2814 { 2829 {
2815 if (*s == '\r') 2830 if (*s == '\r')
2816 { 2831 {
2817 *s++ = ' '; 2832 *s++ = ' ';
2818 2833
2836 { 2851 {
2837 gap g; 2852 gap g;
2838 2853
2839 while (true) 2854 while (true)
2840 { 2855 {
2841 PUGI__SCANWHILE_UNROLL(!PUGI__IS_CHARTYPE(ss, ct_parse_attr)); 2856 PUGI_IMPL_SCANWHILE_UNROLL(!PUGI_IMPL_IS_CHARTYPE(ss, ct_parse_attr));
2842 2857
2843 if (*s == end_quote) 2858 if (*s == end_quote)
2844 { 2859 {
2845 *g.flush(s) = 0; 2860 *g.flush(s) = 0;
2846 2861
2868 { 2883 {
2869 gap g; 2884 gap g;
2870 2885
2871 while (true) 2886 while (true)
2872 { 2887 {
2873 PUGI__SCANWHILE_UNROLL(!PUGI__IS_CHARTYPE(ss, ct_parse_attr)); 2888 PUGI_IMPL_SCANWHILE_UNROLL(!PUGI_IMPL_IS_CHARTYPE(ss, ct_parse_attr));
2874 2889
2875 if (*s == end_quote) 2890 if (*s == end_quote)
2876 { 2891 {
2877 *g.flush(s) = 0; 2892 *g.flush(s) = 0;
2878 2893
2889 else ++s; 2904 else ++s;
2890 } 2905 }
2891 } 2906 }
2892 }; 2907 };
2893 2908
2894 PUGI__FN strconv_attribute_t get_strconv_attribute(unsigned int optmask) 2909 PUGI_IMPL_FN strconv_attribute_t get_strconv_attribute(unsigned int optmask)
2895 { 2910 {
2896 PUGI__STATIC_ASSERT(parse_escapes == 0x10 && parse_eol == 0x20 && parse_wconv_attribute == 0x40 && parse_wnorm_attribute == 0x80); 2911 PUGI_IMPL_STATIC_ASSERT(parse_escapes == 0x10 && parse_eol == 0x20 && parse_wconv_attribute == 0x40 && parse_wnorm_attribute == 0x80);
2897 2912
2898 switch ((optmask >> 4) & 15) // get bitmask for flags (wnorm wconv eol escapes); this simultaneously checks 4 options from assertion above 2913 switch ((optmask >> 4) & 15) // get bitmask for flags (wnorm wconv eol escapes); this simultaneously checks 4 options from assertion above
2899 { 2914 {
2900 case 0: return strconv_attribute_impl<opt_false>::parse_simple; 2915 case 0: return strconv_attribute_impl<opt_false>::parse_simple;
2901 case 1: return strconv_attribute_impl<opt_true>::parse_simple; 2916 case 1: return strconv_attribute_impl<opt_true>::parse_simple;
2947 { 2962 {
2948 if (*s == '"' || *s == '\'') 2963 if (*s == '"' || *s == '\'')
2949 { 2964 {
2950 // quoted string 2965 // quoted string
2951 char_t ch = *s++; 2966 char_t ch = *s++;
2952 PUGI__SCANFOR(*s == ch); 2967 PUGI_IMPL_SCANFOR(*s == ch);
2953 if (!*s) PUGI__THROW_ERROR(status_bad_doctype, s); 2968 if (!*s) PUGI_IMPL_THROW_ERROR(status_bad_doctype, s);
2954 2969
2955 s++; 2970 s++;
2956 } 2971 }
2957 else if (s[0] == '<' && s[1] == '?') 2972 else if (s[0] == '<' && s[1] == '?')
2958 { 2973 {
2959 // <? ... ?> 2974 // <? ... ?>
2960 s += 2; 2975 s += 2;
2961 PUGI__SCANFOR(s[0] == '?' && s[1] == '>'); // no need for ENDSWITH because ?> can't terminate proper doctype 2976 PUGI_IMPL_SCANFOR(s[0] == '?' && s[1] == '>'); // no need for ENDSWITH because ?> can't terminate proper doctype
2962 if (!*s) PUGI__THROW_ERROR(status_bad_doctype, s); 2977 if (!*s) PUGI_IMPL_THROW_ERROR(status_bad_doctype, s);
2963 2978
2964 s += 2; 2979 s += 2;
2965 } 2980 }
2966 else if (s[0] == '<' && s[1] == '!' && s[2] == '-' && s[3] == '-') 2981 else if (s[0] == '<' && s[1] == '!' && s[2] == '-' && s[3] == '-')
2967 { 2982 {
2968 s += 4; 2983 s += 4;
2969 PUGI__SCANFOR(s[0] == '-' && s[1] == '-' && s[2] == '>'); // no need for ENDSWITH because --> can't terminate proper doctype 2984 PUGI_IMPL_SCANFOR(s[0] == '-' && s[1] == '-' && s[2] == '>'); // no need for ENDSWITH because --> can't terminate proper doctype
2970 if (!*s) PUGI__THROW_ERROR(status_bad_doctype, s); 2985 if (!*s) PUGI_IMPL_THROW_ERROR(status_bad_doctype, s);
2971 2986
2972 s += 3; 2987 s += 3;
2973 } 2988 }
2974 else PUGI__THROW_ERROR(status_bad_doctype, s); 2989 else PUGI_IMPL_THROW_ERROR(status_bad_doctype, s);
2975 2990
2976 return s; 2991 return s;
2977 } 2992 }
2978 2993
2979 char_t* parse_doctype_ignore(char_t* s) 2994 char_t* parse_doctype_ignore(char_t* s)
3002 depth--; 3017 depth--;
3003 } 3018 }
3004 else s++; 3019 else s++;
3005 } 3020 }
3006 3021
3007 PUGI__THROW_ERROR(status_bad_doctype, s); 3022 PUGI_IMPL_THROW_ERROR(status_bad_doctype, s);
3008 } 3023 }
3009 3024
3010 char_t* parse_doctype_group(char_t* s, char_t endch) 3025 char_t* parse_doctype_group(char_t* s, char_t endch)
3011 { 3026 {
3012 size_t depth = 0; 3027 size_t depth = 0;
3046 s++; 3061 s++;
3047 } 3062 }
3048 else s++; 3063 else s++;
3049 } 3064 }
3050 3065
3051 if (depth != 0 || endch != '>') PUGI__THROW_ERROR(status_bad_doctype, s); 3066 if (depth != 0 || endch != '>') PUGI_IMPL_THROW_ERROR(status_bad_doctype, s);
3052 3067
3053 return s; 3068 return s;
3054 } 3069 }
3055 3070
3056 char_t* parse_exclamation(char_t* s, xml_node_struct* cursor, unsigned int optmsk, char_t endch) 3071 char_t* parse_exclamation(char_t* s, xml_node_struct* cursor, unsigned int optmsk, char_t endch)
3064 3079
3065 if (*s == '-') // '<!--...' 3080 if (*s == '-') // '<!--...'
3066 { 3081 {
3067 ++s; 3082 ++s;
3068 3083
3069 if (PUGI__OPTSET(parse_comments)) 3084 if (PUGI_IMPL_OPTSET(parse_comments))
3070 { 3085 {
3071 PUGI__PUSHNODE(node_comment); // Append a new node on the tree. 3086 PUGI_IMPL_PUSHNODE(node_comment); // Append a new node on the tree.
3072 cursor->value = s; // Save the offset. 3087 cursor->value = s; // Save the offset.
3073 } 3088 }
3074 3089
3075 if (PUGI__OPTSET(parse_eol) && PUGI__OPTSET(parse_comments)) 3090 if (PUGI_IMPL_OPTSET(parse_eol) && PUGI_IMPL_OPTSET(parse_comments))
3076 { 3091 {
3077 s = strconv_comment(s, endch); 3092 s = strconv_comment(s, endch);
3078 3093
3079 if (!s) PUGI__THROW_ERROR(status_bad_comment, cursor->value); 3094 if (!s) PUGI_IMPL_THROW_ERROR(status_bad_comment, cursor->value);
3080 } 3095 }
3081 else 3096 else
3082 { 3097 {
3083 // Scan for terminating '-->'. 3098 // Scan for terminating '-->'.
3084 PUGI__SCANFOR(s[0] == '-' && s[1] == '-' && PUGI__ENDSWITH(s[2], '>')); 3099 PUGI_IMPL_SCANFOR(s[0] == '-' && s[1] == '-' && PUGI_IMPL_ENDSWITH(s[2], '>'));
3085 PUGI__CHECK_ERROR(status_bad_comment, s); 3100 PUGI_IMPL_CHECK_ERROR(status_bad_comment, s);
3086 3101
3087 if (PUGI__OPTSET(parse_comments)) 3102 if (PUGI_IMPL_OPTSET(parse_comments))
3088 *s = 0; // Zero-terminate this segment at the first terminating '-'. 3103 *s = 0; // Zero-terminate this segment at the first terminating '-'.
3089 3104
3090 s += (s[2] == '>' ? 3 : 2); // Step over the '\0->'. 3105 s += (s[2] == '>' ? 3 : 2); // Step over the '\0->'.
3091 } 3106 }
3092 } 3107 }
3093 else PUGI__THROW_ERROR(status_bad_comment, s); 3108 else PUGI_IMPL_THROW_ERROR(status_bad_comment, s);
3094 } 3109 }
3095 else if (*s == '[') 3110 else if (*s == '[')
3096 { 3111 {
3097 // '<![CDATA[...' 3112 // '<![CDATA[...'
3098 if (*++s=='C' && *++s=='D' && *++s=='A' && *++s=='T' && *++s=='A' && *++s == '[') 3113 if (*++s=='C' && *++s=='D' && *++s=='A' && *++s=='T' && *++s=='A' && *++s == '[')
3099 { 3114 {
3100 ++s; 3115 ++s;
3101 3116
3102 if (PUGI__OPTSET(parse_cdata)) 3117 if (PUGI_IMPL_OPTSET(parse_cdata))
3103 { 3118 {
3104 PUGI__PUSHNODE(node_cdata); // Append a new node on the tree. 3119 PUGI_IMPL_PUSHNODE(node_cdata); // Append a new node on the tree.
3105 cursor->value = s; // Save the offset. 3120 cursor->value = s; // Save the offset.
3106 3121
3107 if (PUGI__OPTSET(parse_eol)) 3122 if (PUGI_IMPL_OPTSET(parse_eol))
3108 { 3123 {
3109 s = strconv_cdata(s, endch); 3124 s = strconv_cdata(s, endch);
3110 3125
3111 if (!s) PUGI__THROW_ERROR(status_bad_cdata, cursor->value); 3126 if (!s) PUGI_IMPL_THROW_ERROR(status_bad_cdata, cursor->value);
3112 } 3127 }
3113 else 3128 else
3114 { 3129 {
3115 // Scan for terminating ']]>'. 3130 // Scan for terminating ']]>'.
3116 PUGI__SCANFOR(s[0] == ']' && s[1] == ']' && PUGI__ENDSWITH(s[2], '>')); 3131 PUGI_IMPL_SCANFOR(s[0] == ']' && s[1] == ']' && PUGI_IMPL_ENDSWITH(s[2], '>'));
3117 PUGI__CHECK_ERROR(status_bad_cdata, s); 3132 PUGI_IMPL_CHECK_ERROR(status_bad_cdata, s);
3118 3133
3119 *s++ = 0; // Zero-terminate this segment. 3134 *s++ = 0; // Zero-terminate this segment.
3120 } 3135 }
3121 } 3136 }
3122 else // Flagged for discard, but we still have to scan for the terminator. 3137 else // Flagged for discard, but we still have to scan for the terminator.
3123 { 3138 {
3124 // Scan for terminating ']]>'. 3139 // Scan for terminating ']]>'.
3125 PUGI__SCANFOR(s[0] == ']' && s[1] == ']' && PUGI__ENDSWITH(s[2], '>')); 3140 PUGI_IMPL_SCANFOR(s[0] == ']' && s[1] == ']' && PUGI_IMPL_ENDSWITH(s[2], '>'));
3126 PUGI__CHECK_ERROR(status_bad_cdata, s); 3141 PUGI_IMPL_CHECK_ERROR(status_bad_cdata, s);
3127 3142
3128 ++s; 3143 ++s;
3129 } 3144 }
3130 3145
3131 s += (s[1] == '>' ? 2 : 1); // Step over the last ']>'. 3146 s += (s[1] == '>' ? 2 : 1); // Step over the last ']>'.
3132 } 3147 }
3133 else PUGI__THROW_ERROR(status_bad_cdata, s); 3148 else PUGI_IMPL_THROW_ERROR(status_bad_cdata, s);
3134 } 3149 }
3135 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')) 3150 else if (s[0] == 'D' && s[1] == 'O' && s[2] == 'C' && s[3] == 'T' && s[4] == 'Y' && s[5] == 'P' && PUGI_IMPL_ENDSWITH(s[6], 'E'))
3136 { 3151 {
3137 s -= 2; 3152 s -= 2;
3138 3153
3139 if (cursor->parent) PUGI__THROW_ERROR(status_bad_doctype, s); 3154 if (cursor->parent) PUGI_IMPL_THROW_ERROR(status_bad_doctype, s);
3140 3155
3141 char_t* mark = s + 9; 3156 char_t* mark = s + 9;
3142 3157
3143 s = parse_doctype_group(s, endch); 3158 s = parse_doctype_group(s, endch);
3144 if (!s) return s; 3159 if (!s) return s;
3145 3160
3146 assert((*s == 0 && endch == '>') || *s == '>'); 3161 assert((*s == 0 && endch == '>') || *s == '>');
3147 if (*s) *s++ = 0; 3162 if (*s) *s++ = 0;
3148 3163
3149 if (PUGI__OPTSET(parse_doctype)) 3164 if (PUGI_IMPL_OPTSET(parse_doctype))
3150 { 3165 {
3151 while (PUGI__IS_CHARTYPE(*mark, ct_space)) ++mark; 3166 while (PUGI_IMPL_IS_CHARTYPE(*mark, ct_space)) ++mark;
3152 3167
3153 PUGI__PUSHNODE(node_doctype); 3168 PUGI_IMPL_PUSHNODE(node_doctype);
3154 3169
3155 cursor->value = mark; 3170 cursor->value = mark;
3156 } 3171 }
3157 } 3172 }
3158 else if (*s == 0 && endch == '-') PUGI__THROW_ERROR(status_bad_comment, s); 3173 else if (*s == 0 && endch == '-') PUGI_IMPL_THROW_ERROR(status_bad_comment, s);
3159 else if (*s == 0 && endch == '[') PUGI__THROW_ERROR(status_bad_cdata, s); 3174 else if (*s == 0 && endch == '[') PUGI_IMPL_THROW_ERROR(status_bad_cdata, s);
3160 else PUGI__THROW_ERROR(status_unrecognized_tag, s); 3175 else PUGI_IMPL_THROW_ERROR(status_unrecognized_tag, s);
3161 3176
3162 return s; 3177 return s;
3163 } 3178 }
3164 3179
3165 char_t* parse_question(char_t* s, xml_node_struct*& ref_cursor, unsigned int optmsk, char_t endch) 3180 char_t* parse_question(char_t* s, xml_node_struct*& ref_cursor, unsigned int optmsk, char_t endch)
3172 ++s; 3187 ++s;
3173 3188
3174 // read PI target 3189 // read PI target
3175 char_t* target = s; 3190 char_t* target = s;
3176 3191
3177 if (!PUGI__IS_CHARTYPE(*s, ct_start_symbol)) PUGI__THROW_ERROR(status_bad_pi, s); 3192 if (!PUGI_IMPL_IS_CHARTYPE(*s, ct_start_symbol)) PUGI_IMPL_THROW_ERROR(status_bad_pi, s);
3178 3193
3179 PUGI__SCANWHILE(PUGI__IS_CHARTYPE(*s, ct_symbol)); 3194 PUGI_IMPL_SCANWHILE(PUGI_IMPL_IS_CHARTYPE(*s, ct_symbol));
3180 PUGI__CHECK_ERROR(status_bad_pi, s); 3195 PUGI_IMPL_CHECK_ERROR(status_bad_pi, s);
3181 3196
3182 // determine node type; stricmp / strcasecmp is not portable 3197 // determine node type; stricmp / strcasecmp is not portable
3183 bool declaration = (target[0] | ' ') == 'x' && (target[1] | ' ') == 'm' && (target[2] | ' ') == 'l' && target + 3 == s; 3198 bool declaration = (target[0] | ' ') == 'x' && (target[1] | ' ') == 'm' && (target[2] | ' ') == 'l' && target + 3 == s;
3184 3199
3185 if (declaration ? PUGI__OPTSET(parse_declaration) : PUGI__OPTSET(parse_pi)) 3200 if (declaration ? PUGI_IMPL_OPTSET(parse_declaration) : PUGI_IMPL_OPTSET(parse_pi))
3186 { 3201 {
3187 if (declaration) 3202 if (declaration)
3188 { 3203 {
3189 // disallow non top-level declarations 3204 // disallow non top-level declarations
3190 if (cursor->parent) PUGI__THROW_ERROR(status_bad_pi, s); 3205 if (cursor->parent) PUGI_IMPL_THROW_ERROR(status_bad_pi, s);
3191 3206
3192 PUGI__PUSHNODE(node_declaration); 3207 PUGI_IMPL_PUSHNODE(node_declaration);
3193 } 3208 }
3194 else 3209 else
3195 { 3210 {
3196 PUGI__PUSHNODE(node_pi); 3211 PUGI_IMPL_PUSHNODE(node_pi);
3197 } 3212 }
3198 3213
3199 cursor->name = target; 3214 cursor->name = target;
3200 3215
3201 PUGI__ENDSEG(); 3216 PUGI_IMPL_ENDSEG();
3202 3217
3203 // parse value/attributes 3218 // parse value/attributes
3204 if (ch == '?') 3219 if (ch == '?')
3205 { 3220 {
3206 // empty node 3221 // empty node
3207 if (!PUGI__ENDSWITH(*s, '>')) PUGI__THROW_ERROR(status_bad_pi, s); 3222 if (!PUGI_IMPL_ENDSWITH(*s, '>')) PUGI_IMPL_THROW_ERROR(status_bad_pi, s);
3208 s += (*s == '>'); 3223 s += (*s == '>');
3209 3224
3210 PUGI__POPNODE(); 3225 PUGI_IMPL_POPNODE();
3211 } 3226 }
3212 else if (PUGI__IS_CHARTYPE(ch, ct_space)) 3227 else if (PUGI_IMPL_IS_CHARTYPE(ch, ct_space))
3213 { 3228 {
3214 PUGI__SKIPWS(); 3229 PUGI_IMPL_SKIPWS();
3215 3230
3216 // scan for tag end 3231 // scan for tag end
3217 char_t* value = s; 3232 char_t* value = s;
3218 3233
3219 PUGI__SCANFOR(s[0] == '?' && PUGI__ENDSWITH(s[1], '>')); 3234 PUGI_IMPL_SCANFOR(s[0] == '?' && PUGI_IMPL_ENDSWITH(s[1], '>'));
3220 PUGI__CHECK_ERROR(status_bad_pi, s); 3235 PUGI_IMPL_CHECK_ERROR(status_bad_pi, s);
3221 3236
3222 if (declaration) 3237 if (declaration)
3223 { 3238 {
3224 // replace ending ? with / so that 'element' terminates properly 3239 // replace ending ? with / so that 'element' terminates properly
3225 *s = '/'; 3240 *s = '/';
3230 else 3245 else
3231 { 3246 {
3232 // store value and step over > 3247 // store value and step over >
3233 cursor->value = value; 3248 cursor->value = value;
3234 3249
3235 PUGI__POPNODE(); 3250 PUGI_IMPL_POPNODE();
3236 3251
3237 PUGI__ENDSEG(); 3252 PUGI_IMPL_ENDSEG();
3238 3253
3239 s += (*s == '>'); 3254 s += (*s == '>');
3240 } 3255 }
3241 } 3256 }
3242 else PUGI__THROW_ERROR(status_bad_pi, s); 3257 else PUGI_IMPL_THROW_ERROR(status_bad_pi, s);
3243 } 3258 }
3244 else 3259 else
3245 { 3260 {
3246 // scan for tag end 3261 // scan for tag end
3247 PUGI__SCANFOR(s[0] == '?' && PUGI__ENDSWITH(s[1], '>')); 3262 PUGI_IMPL_SCANFOR(s[0] == '?' && PUGI_IMPL_ENDSWITH(s[1], '>'));
3248 PUGI__CHECK_ERROR(status_bad_pi, s); 3263 PUGI_IMPL_CHECK_ERROR(status_bad_pi, s);
3249 3264
3250 s += (s[1] == '>' ? 2 : 1); 3265 s += (s[1] == '>' ? 2 : 1);
3251 } 3266 }
3252 3267
3253 // store from registers 3268 // store from registers
3262 strconv_pcdata_t strconv_pcdata = get_strconv_pcdata(optmsk); 3277 strconv_pcdata_t strconv_pcdata = get_strconv_pcdata(optmsk);
3263 3278
3264 char_t ch = 0; 3279 char_t ch = 0;
3265 xml_node_struct* cursor = root; 3280 xml_node_struct* cursor = root;
3266 char_t* mark = s; 3281 char_t* mark = s;
3282 char_t* merged_pcdata = s;
3267 3283
3268 while (*s != 0) 3284 while (*s != 0)
3269 { 3285 {
3270 if (*s == '<') 3286 if (*s == '<')
3271 { 3287 {
3272 ++s; 3288 ++s;
3273 3289
3274 LOC_TAG: 3290 LOC_TAG:
3275 if (PUGI__IS_CHARTYPE(*s, ct_start_symbol)) // '<#...' 3291 if (PUGI_IMPL_IS_CHARTYPE(*s, ct_start_symbol)) // '<#...'
3276 { 3292 {
3277 PUGI__PUSHNODE(node_element); // Append a new node to the tree. 3293 PUGI_IMPL_PUSHNODE(node_element); // Append a new node to the tree.
3278 3294
3279 cursor->name = s; 3295 cursor->name = s;
3280 3296
3281 PUGI__SCANWHILE_UNROLL(PUGI__IS_CHARTYPE(ss, ct_symbol)); // Scan for a terminator. 3297 PUGI_IMPL_SCANWHILE_UNROLL(PUGI_IMPL_IS_CHARTYPE(ss, ct_symbol)); // Scan for a terminator.
3282 PUGI__ENDSEG(); // Save char in 'ch', terminate & step over. 3298 PUGI_IMPL_ENDSEG(); // Save char in 'ch', terminate & step over.
3283 3299
3284 if (ch == '>') 3300 if (ch == '>')
3285 { 3301 {
3286 // end of tag 3302 // end of tag
3287 } 3303 }
3288 else if (PUGI__IS_CHARTYPE(ch, ct_space)) 3304 else if (PUGI_IMPL_IS_CHARTYPE(ch, ct_space))
3289 { 3305 {
3290 LOC_ATTRIBUTES: 3306 LOC_ATTRIBUTES:
3291 while (true) 3307 while (true)
3292 { 3308 {
3293 PUGI__SKIPWS(); // Eat any whitespace. 3309 PUGI_IMPL_SKIPWS(); // Eat any whitespace.
3294 3310
3295 if (PUGI__IS_CHARTYPE(*s, ct_start_symbol)) // <... #... 3311 if (PUGI_IMPL_IS_CHARTYPE(*s, ct_start_symbol)) // <... #...
3296 { 3312 {
3297 xml_attribute_struct* a = append_new_attribute(cursor, *alloc); // Make space for this attribute. 3313 xml_attribute_struct* a = append_new_attribute(cursor, *alloc); // Make space for this attribute.
3298 if (!a) PUGI__THROW_ERROR(status_out_of_memory, s); 3314 if (!a) PUGI_IMPL_THROW_ERROR(status_out_of_memory, s);
3299 3315
3300 a->name = s; // Save the offset. 3316 a->name = s; // Save the offset.
3301 3317
3302 PUGI__SCANWHILE_UNROLL(PUGI__IS_CHARTYPE(ss, ct_symbol)); // Scan for a terminator. 3318 PUGI_IMPL_SCANWHILE_UNROLL(PUGI_IMPL_IS_CHARTYPE(ss, ct_symbol)); // Scan for a terminator.
3303 PUGI__ENDSEG(); // Save char in 'ch', terminate & step over. 3319 PUGI_IMPL_ENDSEG(); // Save char in 'ch', terminate & step over.
3304 3320
3305 if (PUGI__IS_CHARTYPE(ch, ct_space)) 3321 if (PUGI_IMPL_IS_CHARTYPE(ch, ct_space))
3306 { 3322 {
3307 PUGI__SKIPWS(); // Eat any whitespace. 3323 PUGI_IMPL_SKIPWS(); // Eat any whitespace.
3308 3324
3309 ch = *s; 3325 ch = *s;
3310 ++s; 3326 ++s;
3311 } 3327 }
3312 3328
3313 if (ch == '=') // '<... #=...' 3329 if (ch == '=') // '<... #=...'
3314 { 3330 {
3315 PUGI__SKIPWS(); // Eat any whitespace. 3331 PUGI_IMPL_SKIPWS(); // Eat any whitespace.
3316 3332
3317 if (*s == '"' || *s == '\'') // '<... #="...' 3333 if (*s == '"' || *s == '\'') // '<... #="...'
3318 { 3334 {
3319 ch = *s; // Save quote char to avoid breaking on "''" -or- '""'. 3335 ch = *s; // Save quote char to avoid breaking on "''" -or- '""'.
3320 ++s; // Step over the quote. 3336 ++s; // Step over the quote.
3321 a->value = s; // Save the offset. 3337 a->value = s; // Save the offset.
3322 3338
3323 s = strconv_attribute(s, ch); 3339 s = strconv_attribute(s, ch);
3324 3340
3325 if (!s) PUGI__THROW_ERROR(status_bad_attribute, a->value); 3341 if (!s) PUGI_IMPL_THROW_ERROR(status_bad_attribute, a->value);
3326 3342
3327 // After this line the loop continues from the start; 3343 // After this line the loop continues from the start;
3328 // Whitespaces, / and > are ok, symbols and EOF are wrong, 3344 // Whitespaces, / and > are ok, symbols and EOF are wrong,
3329 // everything else will be detected 3345 // everything else will be detected
3330 if (PUGI__IS_CHARTYPE(*s, ct_start_symbol)) PUGI__THROW_ERROR(status_bad_attribute, s); 3346 if (PUGI_IMPL_IS_CHARTYPE(*s, ct_start_symbol)) PUGI_IMPL_THROW_ERROR(status_bad_attribute, s);
3331 } 3347 }
3332 else PUGI__THROW_ERROR(status_bad_attribute, s); 3348 else PUGI_IMPL_THROW_ERROR(status_bad_attribute, s);
3333 } 3349 }
3334 else PUGI__THROW_ERROR(status_bad_attribute, s); 3350 else PUGI_IMPL_THROW_ERROR(status_bad_attribute, s);
3335 } 3351 }
3336 else if (*s == '/') 3352 else if (*s == '/')
3337 { 3353 {
3338 ++s; 3354 ++s;
3339 3355
3340 if (*s == '>') 3356 if (*s == '>')
3341 { 3357 {
3342 PUGI__POPNODE(); 3358 PUGI_IMPL_POPNODE();
3343 s++; 3359 s++;
3344 break; 3360 break;
3345 } 3361 }
3346 else if (*s == 0 && endch == '>') 3362 else if (*s == 0 && endch == '>')
3347 { 3363 {
3348 PUGI__POPNODE(); 3364 PUGI_IMPL_POPNODE();
3349 break; 3365 break;
3350 } 3366 }
3351 else PUGI__THROW_ERROR(status_bad_start_element, s); 3367 else PUGI_IMPL_THROW_ERROR(status_bad_start_element, s);
3352 } 3368 }
3353 else if (*s == '>') 3369 else if (*s == '>')
3354 { 3370 {
3355 ++s; 3371 ++s;
3356 3372
3358 } 3374 }
3359 else if (*s == 0 && endch == '>') 3375 else if (*s == 0 && endch == '>')
3360 { 3376 {
3361 break; 3377 break;
3362 } 3378 }
3363 else PUGI__THROW_ERROR(status_bad_start_element, s); 3379 else PUGI_IMPL_THROW_ERROR(status_bad_start_element, s);
3364 } 3380 }
3365 3381
3366 // !!! 3382 // !!!
3367 } 3383 }
3368 else if (ch == '/') // '<#.../' 3384 else if (ch == '/') // '<#.../'
3369 { 3385 {
3370 if (!PUGI__ENDSWITH(*s, '>')) PUGI__THROW_ERROR(status_bad_start_element, s); 3386 if (!PUGI_IMPL_ENDSWITH(*s, '>')) PUGI_IMPL_THROW_ERROR(status_bad_start_element, s);
3371 3387
3372 PUGI__POPNODE(); // Pop. 3388 PUGI_IMPL_POPNODE(); // Pop.
3373 3389
3374 s += (*s == '>'); 3390 s += (*s == '>');
3375 } 3391 }
3376 else if (ch == 0) 3392 else if (ch == 0)
3377 { 3393 {
3378 // we stepped over null terminator, backtrack & handle closing tag 3394 // we stepped over null terminator, backtrack & handle closing tag
3379 --s; 3395 --s;
3380 3396
3381 if (endch != '>') PUGI__THROW_ERROR(status_bad_start_element, s); 3397 if (endch != '>') PUGI_IMPL_THROW_ERROR(status_bad_start_element, s);
3382 } 3398 }
3383 else PUGI__THROW_ERROR(status_bad_start_element, s); 3399 else PUGI_IMPL_THROW_ERROR(status_bad_start_element, s);
3384 } 3400 }
3385 else if (*s == '/') 3401 else if (*s == '/')
3386 { 3402 {
3387 ++s; 3403 ++s;
3388 3404
3389 mark = s; 3405 mark = s;
3390 3406
3391 char_t* name = cursor->name; 3407 char_t* name = cursor->name;
3392 if (!name) PUGI__THROW_ERROR(status_end_element_mismatch, mark); 3408 if (!name) PUGI_IMPL_THROW_ERROR(status_end_element_mismatch, mark);
3393 3409
3394 while (PUGI__IS_CHARTYPE(*s, ct_symbol)) 3410 while (PUGI_IMPL_IS_CHARTYPE(*s, ct_symbol))
3395 { 3411 {
3396 if (*s++ != *name++) PUGI__THROW_ERROR(status_end_element_mismatch, mark); 3412 if (*s++ != *name++) PUGI_IMPL_THROW_ERROR(status_end_element_mismatch, mark);
3397 } 3413 }
3398 3414
3399 if (*name) 3415 if (*name)
3400 { 3416 {
3401 if (*s == 0 && name[0] == endch && name[1] == 0) PUGI__THROW_ERROR(status_bad_end_element, s); 3417 if (*s == 0 && name[0] == endch && name[1] == 0) PUGI_IMPL_THROW_ERROR(status_bad_end_element, s);
3402 else PUGI__THROW_ERROR(status_end_element_mismatch, mark); 3418 else PUGI_IMPL_THROW_ERROR(status_end_element_mismatch, mark);
3403 } 3419 }
3404 3420
3405 PUGI__POPNODE(); // Pop. 3421 PUGI_IMPL_POPNODE(); // Pop.
3406 3422
3407 PUGI__SKIPWS(); 3423 PUGI_IMPL_SKIPWS();
3408 3424
3409 if (*s == 0) 3425 if (*s == 0)
3410 { 3426 {
3411 if (endch != '>') PUGI__THROW_ERROR(status_bad_end_element, s); 3427 if (endch != '>') PUGI_IMPL_THROW_ERROR(status_bad_end_element, s);
3412 } 3428 }
3413 else 3429 else
3414 { 3430 {
3415 if (*s != '>') PUGI__THROW_ERROR(status_bad_end_element, s); 3431 if (*s != '>') PUGI_IMPL_THROW_ERROR(status_bad_end_element, s);
3416 ++s; 3432 ++s;
3417 } 3433 }
3418 } 3434 }
3419 else if (*s == '?') // '<?...' 3435 else if (*s == '?') // '<?...'
3420 { 3436 {
3421 s = parse_question(s, cursor, optmsk, endch); 3437 s = parse_question(s, cursor, optmsk, endch);
3422 if (!s) return s; 3438 if (!s) return s;
3423 3439
3424 assert(cursor); 3440 assert(cursor);
3425 if (PUGI__NODETYPE(cursor) == node_declaration) goto LOC_ATTRIBUTES; 3441 if (PUGI_IMPL_NODETYPE(cursor) == node_declaration) goto LOC_ATTRIBUTES;
3426 } 3442 }
3427 else if (*s == '!') // '<!...' 3443 else if (*s == '!') // '<!...'
3428 { 3444 {
3429 s = parse_exclamation(s, cursor, optmsk, endch); 3445 s = parse_exclamation(s, cursor, optmsk, endch);
3430 if (!s) return s; 3446 if (!s) return s;
3431 } 3447 }
3432 else if (*s == 0 && endch == '?') PUGI__THROW_ERROR(status_bad_pi, s); 3448 else if (*s == 0 && endch == '?') PUGI_IMPL_THROW_ERROR(status_bad_pi, s);
3433 else PUGI__THROW_ERROR(status_unrecognized_tag, s); 3449 else PUGI_IMPL_THROW_ERROR(status_unrecognized_tag, s);
3434 } 3450 }
3435 else 3451 else
3436 { 3452 {
3437 mark = s; // Save this offset while searching for a terminator. 3453 mark = s; // Save this offset while searching for a terminator.
3438 3454
3439 PUGI__SKIPWS(); // Eat whitespace if no genuine PCDATA here. 3455 PUGI_IMPL_SKIPWS(); // Eat whitespace if no genuine PCDATA here.
3440 3456
3441 if (*s == '<' || !*s) 3457 if (*s == '<' || !*s)
3442 { 3458 {
3443 // We skipped some whitespace characters because otherwise we would take the tag branch instead of PCDATA one 3459 // We skipped some whitespace characters because otherwise we would take the tag branch instead of PCDATA one
3444 assert(mark != s); 3460 assert(mark != s);
3445 3461
3446 if (!PUGI__OPTSET(parse_ws_pcdata | parse_ws_pcdata_single) || PUGI__OPTSET(parse_trim_pcdata)) 3462 if (!PUGI_IMPL_OPTSET(parse_ws_pcdata | parse_ws_pcdata_single) || PUGI_IMPL_OPTSET(parse_trim_pcdata))
3447 { 3463 {
3448 continue; 3464 continue;
3449 } 3465 }
3450 else if (PUGI__OPTSET(parse_ws_pcdata_single)) 3466 else if (PUGI_IMPL_OPTSET(parse_ws_pcdata_single))
3451 { 3467 {
3452 if (s[0] != '<' || s[1] != '/' || cursor->first_child) continue; 3468 if (s[0] != '<' || s[1] != '/' || cursor->first_child) continue;
3453 } 3469 }
3454 } 3470 }
3455 3471
3456 if (!PUGI__OPTSET(parse_trim_pcdata)) 3472 if (!PUGI_IMPL_OPTSET(parse_trim_pcdata))
3457 s = mark; 3473 s = mark;
3458 3474
3459 if (cursor->parent || PUGI__OPTSET(parse_fragment)) 3475 if (cursor->parent || PUGI_IMPL_OPTSET(parse_fragment))
3460 { 3476 {
3461 if (PUGI__OPTSET(parse_embed_pcdata) && cursor->parent && !cursor->first_child && !cursor->value) 3477 char_t* parsed_pcdata = s;
3478
3479 s = strconv_pcdata(s);
3480
3481 if (PUGI_IMPL_OPTSET(parse_embed_pcdata) && cursor->parent && !cursor->first_child && !cursor->value)
3462 { 3482 {
3463 cursor->value = s; // Save the offset. 3483 cursor->value = parsed_pcdata; // Save the offset.
3484 }
3485 else if (PUGI_IMPL_OPTSET(parse_merge_pcdata) && cursor->first_child && PUGI_IMPL_NODETYPE(cursor->first_child->prev_sibling_c) == node_pcdata)
3486 {
3487 assert(merged_pcdata >= cursor->first_child->prev_sibling_c->value);
3488
3489 // Catch up to the end of last parsed value; only needed for the first fragment.
3490 merged_pcdata += strlength(merged_pcdata);
3491
3492 size_t length = strlength(parsed_pcdata);
3493
3494 // Must use memmove instead of memcpy as this move may overlap
3495 memmove(merged_pcdata, parsed_pcdata, (length + 1) * sizeof(char_t));
3496 merged_pcdata += length;
3464 } 3497 }
3465 else 3498 else
3466 { 3499 {
3467 PUGI__PUSHNODE(node_pcdata); // Append a new node on the tree. 3500 xml_node_struct* prev_cursor = cursor;
3468 3501 PUGI_IMPL_PUSHNODE(node_pcdata); // Append a new node on the tree.
3469 cursor->value = s; // Save the offset. 3502
3470 3503 cursor->value = parsed_pcdata; // Save the offset.
3471 PUGI__POPNODE(); // Pop since this is a standalone. 3504 merged_pcdata = parsed_pcdata; // Used for parse_merge_pcdata above, cheaper to save unconditionally
3505
3506 cursor = prev_cursor; // Pop since this is a standalone.
3472 } 3507 }
3473
3474 s = strconv_pcdata(s);
3475 3508
3476 if (!*s) break; 3509 if (!*s) break;
3477 } 3510 }
3478 else 3511 else
3479 { 3512 {
3480 PUGI__SCANFOR(*s == '<'); // '...<' 3513 PUGI_IMPL_SCANFOR(*s == '<'); // '...<'
3481 if (!*s) break; 3514 if (!*s) break;
3482 3515
3483 ++s; 3516 ++s;
3484 } 3517 }
3485 3518
3487 goto LOC_TAG; 3520 goto LOC_TAG;
3488 } 3521 }
3489 } 3522 }
3490 3523
3491 // check that last tag is closed 3524 // check that last tag is closed
3492 if (cursor != root) PUGI__THROW_ERROR(status_end_element_mismatch, s); 3525 if (cursor != root) PUGI_IMPL_THROW_ERROR(status_end_element_mismatch, s);
3493 3526
3494 return s; 3527 return s;
3495 } 3528 }
3496 3529
3497 #ifdef PUGIXML_WCHAR_MODE 3530 #ifdef PUGIXML_WCHAR_MODE
3509 3542
3510 static bool has_element_node_siblings(xml_node_struct* node) 3543 static bool has_element_node_siblings(xml_node_struct* node)
3511 { 3544 {
3512 while (node) 3545 while (node)
3513 { 3546 {
3514 if (PUGI__NODETYPE(node) == node_element) return true; 3547 if (PUGI_IMPL_NODETYPE(node) == node_element) return true;
3515 3548
3516 node = node->next_sibling; 3549 node = node->next_sibling;
3517 } 3550 }
3518 3551
3519 return false; 3552 return false;
3521 3554
3522 static xml_parse_result parse(char_t* buffer, size_t length, xml_document_struct* xmldoc, xml_node_struct* root, unsigned int optmsk) 3555 static xml_parse_result parse(char_t* buffer, size_t length, xml_document_struct* xmldoc, xml_node_struct* root, unsigned int optmsk)
3523 { 3556 {
3524 // early-out for empty documents 3557 // early-out for empty documents
3525 if (length == 0) 3558 if (length == 0)
3526 return make_parse_result(PUGI__OPTSET(parse_fragment) ? status_ok : status_no_document_element); 3559 return make_parse_result(PUGI_IMPL_OPTSET(parse_fragment) ? status_ok : status_no_document_element);
3527 3560
3528 // get last child of the root before parsing 3561 // get last child of the root before parsing
3529 xml_node_struct* last_root_child = root->first_child ? root->first_child->prev_sibling_c + 0 : 0; 3562 xml_node_struct* last_root_child = root->first_child ? root->first_child->prev_sibling_c + 0 : 0;
3530 3563
3531 // create parser on stack 3564 // create parser on stack
3549 // since we removed last character, we have to handle the only possible false positive (stray <) 3582 // since we removed last character, we have to handle the only possible false positive (stray <)
3550 if (endch == '<') 3583 if (endch == '<')
3551 return make_parse_result(status_unrecognized_tag, length - 1); 3584 return make_parse_result(status_unrecognized_tag, length - 1);
3552 3585
3553 // check if there are any element nodes parsed 3586 // check if there are any element nodes parsed
3554 xml_node_struct* first_root_child_parsed = last_root_child ? last_root_child->next_sibling + 0 : root->first_child+ 0; 3587 xml_node_struct* first_root_child_parsed = last_root_child ? last_root_child->next_sibling + 0 : root->first_child + 0;
3555 3588
3556 if (!PUGI__OPTSET(parse_fragment) && !has_element_node_siblings(first_root_child_parsed)) 3589 if (!PUGI_IMPL_OPTSET(parse_fragment) && !has_element_node_siblings(first_root_child_parsed))
3557 return make_parse_result(status_no_document_element, length - 1); 3590 return make_parse_result(status_no_document_element, length - 1);
3558 } 3591 }
3559 else 3592 else
3560 { 3593 {
3561 // roll back offset if it occurs on a null terminator in the source buffer 3594 // roll back offset if it occurs on a null terminator in the source buffer
3566 return result; 3599 return result;
3567 } 3600 }
3568 }; 3601 };
3569 3602
3570 // Output facilities 3603 // Output facilities
3571 PUGI__FN xml_encoding get_write_native_encoding() 3604 PUGI_IMPL_FN xml_encoding get_write_native_encoding()
3572 { 3605 {
3573 #ifdef PUGIXML_WCHAR_MODE 3606 #ifdef PUGIXML_WCHAR_MODE
3574 return get_wchar_encoding(); 3607 return get_wchar_encoding();
3575 #else 3608 #else
3576 return encoding_utf8; 3609 return encoding_utf8;
3577 #endif 3610 #endif
3578 } 3611 }
3579 3612
3580 PUGI__FN xml_encoding get_write_encoding(xml_encoding encoding) 3613 PUGI_IMPL_FN xml_encoding get_write_encoding(xml_encoding encoding)
3581 { 3614 {
3582 // replace wchar encoding with utf implementation 3615 // replace wchar encoding with utf implementation
3583 if (encoding == encoding_wchar) return get_wchar_encoding(); 3616 if (encoding == encoding_wchar) return get_wchar_encoding();
3584 3617
3585 // replace utf16 encoding with utf16 with specific endianness 3618 // replace utf16 encoding with utf16 with specific endianness
3593 3626
3594 // assume utf8 encoding 3627 // assume utf8 encoding
3595 return encoding_utf8; 3628 return encoding_utf8;
3596 } 3629 }
3597 3630
3598 template <typename D, typename T> PUGI__FN size_t convert_buffer_output_generic(typename T::value_type dest, const char_t* data, size_t length, D, T) 3631 template <typename D, typename T> PUGI_IMPL_FN size_t convert_buffer_output_generic(typename T::value_type dest, const char_t* data, size_t length, D, T)
3599 { 3632 {
3600 PUGI__STATIC_ASSERT(sizeof(char_t) == sizeof(typename D::type)); 3633 PUGI_IMPL_STATIC_ASSERT(sizeof(char_t) == sizeof(typename D::type));
3601 3634
3602 typename T::value_type end = D::process(reinterpret_cast<const typename D::type*>(data), length, dest, T()); 3635 typename T::value_type end = D::process(reinterpret_cast<const typename D::type*>(data), length, dest, T());
3603 3636
3604 return static_cast<size_t>(end - dest) * sizeof(*dest); 3637 return static_cast<size_t>(end - dest) * sizeof(*dest);
3605 } 3638 }
3606 3639
3607 template <typename D, typename T> PUGI__FN size_t convert_buffer_output_generic(typename T::value_type dest, const char_t* data, size_t length, D, T, bool opt_swap) 3640 template <typename D, typename T> PUGI_IMPL_FN size_t convert_buffer_output_generic(typename T::value_type dest, const char_t* data, size_t length, D, T, bool opt_swap)
3608 { 3641 {
3609 PUGI__STATIC_ASSERT(sizeof(char_t) == sizeof(typename D::type)); 3642 PUGI_IMPL_STATIC_ASSERT(sizeof(char_t) == sizeof(typename D::type));
3610 3643
3611 typename T::value_type end = D::process(reinterpret_cast<const typename D::type*>(data), length, dest, T()); 3644 typename T::value_type end = D::process(reinterpret_cast<const typename D::type*>(data), length, dest, T());
3612 3645
3613 if (opt_swap) 3646 if (opt_swap)
3614 { 3647 {
3618 3651
3619 return static_cast<size_t>(end - dest) * sizeof(*dest); 3652 return static_cast<size_t>(end - dest) * sizeof(*dest);
3620 } 3653 }
3621 3654
3622 #ifdef PUGIXML_WCHAR_MODE 3655 #ifdef PUGIXML_WCHAR_MODE
3623 PUGI__FN size_t get_valid_length(const char_t* data, size_t length) 3656 PUGI_IMPL_FN size_t get_valid_length(const char_t* data, size_t length)
3624 { 3657 {
3625 if (length < 1) return 0; 3658 if (length < 1) return 0;
3626 3659
3627 // discard last character if it's the lead of a surrogate pair 3660 // discard last character if it's the lead of a surrogate pair
3628 return (sizeof(wchar_t) == 2 && static_cast<unsigned int>(static_cast<uint16_t>(data[length - 1]) - 0xD800) < 0x400) ? length - 1 : length; 3661 return (sizeof(wchar_t) == 2 && static_cast<unsigned int>(static_cast<uint16_t>(data[length - 1]) - 0xD800) < 0x400) ? length - 1 : length;
3629 } 3662 }
3630 3663
3631 PUGI__FN size_t convert_buffer_output(char_t* r_char, uint8_t* r_u8, uint16_t* r_u16, uint32_t* r_u32, const char_t* data, size_t length, xml_encoding encoding) 3664 PUGI_IMPL_FN size_t convert_buffer_output(char_t* r_char, uint8_t* r_u8, uint16_t* r_u16, uint32_t* r_u32, const char_t* data, size_t length, xml_encoding encoding)
3632 { 3665 {
3633 // only endian-swapping is required 3666 // only endian-swapping is required
3634 if (need_endian_swap_utf(encoding, get_wchar_encoding())) 3667 if (need_endian_swap_utf(encoding, get_wchar_encoding()))
3635 { 3668 {
3636 convert_wchar_endian_swap(r_char, data, length); 3669 convert_wchar_endian_swap(r_char, data, length);
3664 3697
3665 assert(false && "Invalid encoding"); // unreachable 3698 assert(false && "Invalid encoding"); // unreachable
3666 return 0; 3699 return 0;
3667 } 3700 }
3668 #else 3701 #else
3669 PUGI__FN size_t get_valid_length(const char_t* data, size_t length) 3702 PUGI_IMPL_FN size_t get_valid_length(const char_t* data, size_t length)
3670 { 3703 {
3671 if (length < 5) return 0; 3704 if (length < 5) return 0;
3672 3705
3673 for (size_t i = 1; i <= 4; ++i) 3706 for (size_t i = 1; i <= 4; ++i)
3674 { 3707 {
3680 3713
3681 // there are four non-leading characters at the end, sequence tail is broken so might as well process the whole chunk 3714 // there are four non-leading characters at the end, sequence tail is broken so might as well process the whole chunk
3682 return length; 3715 return length;
3683 } 3716 }
3684 3717
3685 PUGI__FN size_t convert_buffer_output(char_t* /* r_char */, uint8_t* r_u8, uint16_t* r_u16, uint32_t* r_u32, const char_t* data, size_t length, xml_encoding encoding) 3718 PUGI_IMPL_FN size_t convert_buffer_output(char_t* /* r_char */, uint8_t* r_u8, uint16_t* r_u16, uint32_t* r_u32, const char_t* data, size_t length, xml_encoding encoding)
3686 { 3719 {
3687 if (encoding == encoding_utf16_be || encoding == encoding_utf16_le) 3720 if (encoding == encoding_utf16_be || encoding == encoding_utf16_le)
3688 { 3721 {
3689 xml_encoding native_encoding = is_little_endian() ? encoding_utf16_le : encoding_utf16_be; 3722 xml_encoding native_encoding = is_little_endian() ? encoding_utf16_le : encoding_utf16_be;
3690 3723
3712 xml_buffered_writer& operator=(const xml_buffered_writer&); 3745 xml_buffered_writer& operator=(const xml_buffered_writer&);
3713 3746
3714 public: 3747 public:
3715 xml_buffered_writer(xml_writer& writer_, xml_encoding user_encoding): writer(writer_), bufsize(0), encoding(get_write_encoding(user_encoding)) 3748 xml_buffered_writer(xml_writer& writer_, xml_encoding user_encoding): writer(writer_), bufsize(0), encoding(get_write_encoding(user_encoding))
3716 { 3749 {
3717 PUGI__STATIC_ASSERT(bufcapacity >= 8); 3750 PUGI_IMPL_STATIC_ASSERT(bufcapacity >= 8);
3718 } 3751 }
3719 3752
3720 size_t flush() 3753 size_t flush()
3721 { 3754 {
3722 flush(buffer, bufsize); 3755 flush(buffer, bufsize);
3918 xml_writer& writer; 3951 xml_writer& writer;
3919 size_t bufsize; 3952 size_t bufsize;
3920 xml_encoding encoding; 3953 xml_encoding encoding;
3921 }; 3954 };
3922 3955
3923 PUGI__FN void text_output_escaped(xml_buffered_writer& writer, const char_t* s, chartypex_t type, unsigned int flags) 3956 PUGI_IMPL_FN void text_output_escaped(xml_buffered_writer& writer, const char_t* s, chartypex_t type, unsigned int flags)
3924 { 3957 {
3925 while (*s) 3958 while (*s)
3926 { 3959 {
3927 const char_t* prev = s; 3960 const char_t* prev = s;
3928 3961
3929 // While *s is a usual symbol 3962 // While *s is a usual symbol
3930 PUGI__SCANWHILE_UNROLL(!PUGI__IS_CHARTYPEX(ss, type)); 3963 PUGI_IMPL_SCANWHILE_UNROLL(!PUGI_IMPL_IS_CHARTYPEX(ss, type));
3931 3964
3932 writer.write_buffer(prev, static_cast<size_t>(s - prev)); 3965 writer.write_buffer(prev, static_cast<size_t>(s - prev));
3933 3966
3934 switch (*s) 3967 switch (*s)
3935 { 3968 {
3970 } 4003 }
3971 } 4004 }
3972 } 4005 }
3973 } 4006 }
3974 4007
3975 PUGI__FN void text_output(xml_buffered_writer& writer, const char_t* s, chartypex_t type, unsigned int flags) 4008 PUGI_IMPL_FN void text_output(xml_buffered_writer& writer, const char_t* s, chartypex_t type, unsigned int flags)
3976 { 4009 {
3977 if (flags & format_no_escapes) 4010 if (flags & format_no_escapes)
3978 writer.write_string(s); 4011 writer.write_string(s);
3979 else 4012 else
3980 text_output_escaped(writer, s, type, flags); 4013 text_output_escaped(writer, s, type, flags);
3981 } 4014 }
3982 4015
3983 PUGI__FN void text_output_cdata(xml_buffered_writer& writer, const char_t* s) 4016 PUGI_IMPL_FN void text_output_cdata(xml_buffered_writer& writer, const char_t* s)
3984 { 4017 {
3985 do 4018 do
3986 { 4019 {
3987 writer.write('<', '!', '[', 'C', 'D'); 4020 writer.write('<', '!', '[', 'C', 'D');
3988 writer.write('A', 'T', 'A', '['); 4021 writer.write('A', 'T', 'A', '[');
4000 writer.write(']', ']', '>'); 4033 writer.write(']', ']', '>');
4001 } 4034 }
4002 while (*s); 4035 while (*s);
4003 } 4036 }
4004 4037
4005 PUGI__FN void text_output_indent(xml_buffered_writer& writer, const char_t* indent, size_t indent_length, unsigned int depth) 4038 PUGI_IMPL_FN void text_output_indent(xml_buffered_writer& writer, const char_t* indent, size_t indent_length, unsigned int depth)
4006 { 4039 {
4007 switch (indent_length) 4040 switch (indent_length)
4008 { 4041 {
4009 case 1: 4042 case 1:
4010 { 4043 {
4040 writer.write_buffer(indent, indent_length); 4073 writer.write_buffer(indent, indent_length);
4041 } 4074 }
4042 } 4075 }
4043 } 4076 }
4044 4077
4045 PUGI__FN void node_output_comment(xml_buffered_writer& writer, const char_t* s) 4078 PUGI_IMPL_FN void node_output_comment(xml_buffered_writer& writer, const char_t* s)
4046 { 4079 {
4047 writer.write('<', '!', '-', '-'); 4080 writer.write('<', '!', '-', '-');
4048 4081
4049 while (*s) 4082 while (*s)
4050 { 4083 {
4065 } 4098 }
4066 4099
4067 writer.write('-', '-', '>'); 4100 writer.write('-', '-', '>');
4068 } 4101 }
4069 4102
4070 PUGI__FN void node_output_pi_value(xml_buffered_writer& writer, const char_t* s) 4103 PUGI_IMPL_FN void node_output_pi_value(xml_buffered_writer& writer, const char_t* s)
4071 { 4104 {
4072 while (*s) 4105 while (*s)
4073 { 4106 {
4074 const char_t* prev = s; 4107 const char_t* prev = s;
4075 4108
4086 s += 2; 4119 s += 2;
4087 } 4120 }
4088 } 4121 }
4089 } 4122 }
4090 4123
4091 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) 4124 PUGI_IMPL_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)
4092 { 4125 {
4093 const char_t* default_name = PUGIXML_TEXT(":anonymous"); 4126 const char_t* default_name = PUGIXML_TEXT(":anonymous");
4094 const char_t enquotation_char = (flags & format_attribute_single_quote) ? '\'' : '"'; 4127 const char_t enquotation_char = (flags & format_attribute_single_quote) ? '\'' : '"';
4095 4128
4096 for (xml_attribute_struct* a = node->first_attribute; a; a = a->next_attribute) 4129 for (xml_attribute_struct* a = node->first_attribute; a; a = a->next_attribute)
4114 4147
4115 writer.write(enquotation_char); 4148 writer.write(enquotation_char);
4116 } 4149 }
4117 } 4150 }
4118 4151
4119 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) 4152 PUGI_IMPL_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)
4120 { 4153 {
4121 const char_t* default_name = PUGIXML_TEXT(":anonymous"); 4154 const char_t* default_name = PUGIXML_TEXT(":anonymous");
4122 const char_t* name = node->name ? node->name + 0 : default_name; 4155 const char_t* name = node->name ? node->name + 0 : default_name;
4123 4156
4124 writer.write('<'); 4157 writer.write('<');
4176 return true; 4209 return true;
4177 } 4210 }
4178 } 4211 }
4179 } 4212 }
4180 4213
4181 PUGI__FN void node_output_end(xml_buffered_writer& writer, xml_node_struct* node) 4214 PUGI_IMPL_FN void node_output_end(xml_buffered_writer& writer, xml_node_struct* node)
4182 { 4215 {
4183 const char_t* default_name = PUGIXML_TEXT(":anonymous"); 4216 const char_t* default_name = PUGIXML_TEXT(":anonymous");
4184 const char_t* name = node->name ? node->name + 0 : default_name; 4217 const char_t* name = node->name ? node->name + 0 : default_name;
4185 4218
4186 writer.write('<', '/'); 4219 writer.write('<', '/');
4187 writer.write_string(name); 4220 writer.write_string(name);
4188 writer.write('>'); 4221 writer.write('>');
4189 } 4222 }
4190 4223
4191 PUGI__FN void node_output_simple(xml_buffered_writer& writer, xml_node_struct* node, unsigned int flags) 4224 PUGI_IMPL_FN void node_output_simple(xml_buffered_writer& writer, xml_node_struct* node, unsigned int flags)
4192 { 4225 {
4193 const char_t* default_name = PUGIXML_TEXT(":anonymous"); 4226 const char_t* default_name = PUGIXML_TEXT(":anonymous");
4194 4227
4195 switch (PUGI__NODETYPE(node)) 4228 switch (PUGI_IMPL_NODETYPE(node))
4196 { 4229 {
4197 case node_pcdata: 4230 case node_pcdata:
4198 text_output(writer, node->value ? node->value + 0 : PUGIXML_TEXT(""), ctx_special_pcdata, flags); 4231 text_output(writer, node->value ? node->value + 0 : PUGIXML_TEXT(""), ctx_special_pcdata, flags);
4199 break; 4232 break;
4200 4233
4248 { 4281 {
4249 indent_newline = 1, 4282 indent_newline = 1,
4250 indent_indent = 2 4283 indent_indent = 2
4251 }; 4284 };
4252 4285
4253 PUGI__FN void node_output(xml_buffered_writer& writer, xml_node_struct* root, const char_t* indent, unsigned int flags, unsigned int depth) 4286 PUGI_IMPL_FN void node_output(xml_buffered_writer& writer, xml_node_struct* root, const char_t* indent, unsigned int flags, unsigned int depth)
4254 { 4287 {
4255 size_t indent_length = ((flags & (format_indent | format_indent_attributes)) && (flags & format_raw) == 0) ? strlength(indent) : 0; 4288 size_t indent_length = ((flags & (format_indent | format_indent_attributes)) && (flags & format_raw) == 0) ? strlength(indent) : 0;
4256 unsigned int indent_flags = indent_indent; 4289 unsigned int indent_flags = indent_indent;
4257 4290
4258 xml_node_struct* node = root; 4291 xml_node_struct* node = root;
4260 do 4293 do
4261 { 4294 {
4262 assert(node); 4295 assert(node);
4263 4296
4264 // begin writing current node 4297 // begin writing current node
4265 if (PUGI__NODETYPE(node) == node_pcdata || PUGI__NODETYPE(node) == node_cdata) 4298 if (PUGI_IMPL_NODETYPE(node) == node_pcdata || PUGI_IMPL_NODETYPE(node) == node_cdata)
4266 { 4299 {
4267 node_output_simple(writer, node, flags); 4300 node_output_simple(writer, node, flags);
4268 4301
4269 indent_flags = 0; 4302 indent_flags = 0;
4270 } 4303 }
4274 writer.write('\n'); 4307 writer.write('\n');
4275 4308
4276 if ((indent_flags & indent_indent) && indent_length) 4309 if ((indent_flags & indent_indent) && indent_length)
4277 text_output_indent(writer, indent, indent_length, depth); 4310 text_output_indent(writer, indent, indent_length, depth);
4278 4311
4279 if (PUGI__NODETYPE(node) == node_element) 4312 if (PUGI_IMPL_NODETYPE(node) == node_element)
4280 { 4313 {
4281 indent_flags = indent_newline | indent_indent; 4314 indent_flags = indent_newline | indent_indent;
4282 4315
4283 if (node_output_start(writer, node, indent, indent_length, flags, depth)) 4316 if (node_output_start(writer, node, indent, indent_length, flags, depth))
4284 { 4317 {
4289 node = node->first_child; 4322 node = node->first_child;
4290 depth++; 4323 depth++;
4291 continue; 4324 continue;
4292 } 4325 }
4293 } 4326 }
4294 else if (PUGI__NODETYPE(node) == node_document) 4327 else if (PUGI_IMPL_NODETYPE(node) == node_document)
4295 { 4328 {
4296 indent_flags = indent_indent; 4329 indent_flags = indent_indent;
4297 4330
4298 if (node->first_child) 4331 if (node->first_child)
4299 { 4332 {
4319 } 4352 }
4320 4353
4321 node = node->parent; 4354 node = node->parent;
4322 4355
4323 // write closing node 4356 // write closing node
4324 if (PUGI__NODETYPE(node) == node_element) 4357 if (PUGI_IMPL_NODETYPE(node) == node_element)
4325 { 4358 {
4326 depth--; 4359 depth--;
4327 4360
4328 if ((indent_flags & indent_newline) && (flags & format_raw) == 0) 4361 if ((indent_flags & indent_newline) && (flags & format_raw) == 0)
4329 writer.write('\n'); 4362 writer.write('\n');
4341 4374
4342 if ((indent_flags & indent_newline) && (flags & format_raw) == 0) 4375 if ((indent_flags & indent_newline) && (flags & format_raw) == 0)
4343 writer.write('\n'); 4376 writer.write('\n');
4344 } 4377 }
4345 4378
4346 PUGI__FN bool has_declaration(xml_node_struct* node) 4379 PUGI_IMPL_FN bool has_declaration(xml_node_struct* node)
4347 { 4380 {
4348 for (xml_node_struct* child = node->first_child; child; child = child->next_sibling) 4381 for (xml_node_struct* child = node->first_child; child; child = child->next_sibling)
4349 { 4382 {
4350 xml_node_type type = PUGI__NODETYPE(child); 4383 xml_node_type type = PUGI_IMPL_NODETYPE(child);
4351 4384
4352 if (type == node_declaration) return true; 4385 if (type == node_declaration) return true;
4353 if (type == node_element) return false; 4386 if (type == node_element) return false;
4354 } 4387 }
4355 4388
4356 return false; 4389 return false;
4357 } 4390 }
4358 4391
4359 PUGI__FN bool is_attribute_of(xml_attribute_struct* attr, xml_node_struct* node) 4392 PUGI_IMPL_FN bool is_attribute_of(xml_attribute_struct* attr, xml_node_struct* node)
4360 { 4393 {
4361 for (xml_attribute_struct* a = node->first_attribute; a; a = a->next_attribute) 4394 for (xml_attribute_struct* a = node->first_attribute; a; a = a->next_attribute)
4362 if (a == attr) 4395 if (a == attr)
4363 return true; 4396 return true;
4364 4397
4365 return false; 4398 return false;
4366 } 4399 }
4367 4400
4368 PUGI__FN bool allow_insert_attribute(xml_node_type parent) 4401 PUGI_IMPL_FN bool allow_insert_attribute(xml_node_type parent)
4369 { 4402 {
4370 return parent == node_element || parent == node_declaration; 4403 return parent == node_element || parent == node_declaration;
4371 } 4404 }
4372 4405
4373 PUGI__FN bool allow_insert_child(xml_node_type parent, xml_node_type child) 4406 PUGI_IMPL_FN bool allow_insert_child(xml_node_type parent, xml_node_type child)
4374 { 4407 {
4375 if (parent != node_document && parent != node_element) return false; 4408 if (parent != node_document && parent != node_element) return false;
4376 if (child == node_document || child == node_null) return false; 4409 if (child == node_document || child == node_null) return false;
4377 if (parent != node_document && (child == node_declaration || child == node_doctype)) return false; 4410 if (parent != node_document && (child == node_declaration || child == node_doctype)) return false;
4378 4411
4379 return true; 4412 return true;
4380 } 4413 }
4381 4414
4382 PUGI__FN bool allow_move(xml_node parent, xml_node child) 4415 PUGI_IMPL_FN bool allow_move(xml_node parent, xml_node child)
4383 { 4416 {
4384 // check that child can be a child of parent 4417 // check that child can be a child of parent
4385 if (!allow_insert_child(parent.type(), child.type())) 4418 if (!allow_insert_child(parent.type(), child.type()))
4386 return false; 4419 return false;
4387 4420
4402 4435
4403 return true; 4436 return true;
4404 } 4437 }
4405 4438
4406 template <typename String, typename Header> 4439 template <typename String, typename Header>
4407 PUGI__FN void node_copy_string(String& dest, Header& header, uintptr_t header_mask, char_t* source, Header& source_header, xml_allocator* alloc) 4440 PUGI_IMPL_FN void node_copy_string(String& dest, Header& header, uintptr_t header_mask, char_t* source, Header& source_header, xml_allocator* alloc)
4408 { 4441 {
4409 assert(!dest && (header & header_mask) == 0); 4442 assert(!dest && (header & header_mask) == 0); // copies are performed into fresh nodes
4410 4443
4411 if (source) 4444 if (source)
4412 { 4445 {
4413 if (alloc && (source_header & header_mask) == 0) 4446 if (alloc && (source_header & header_mask) == 0)
4414 { 4447 {
4421 else 4454 else
4422 strcpy_insitu(dest, header, header_mask, source, strlength(source)); 4455 strcpy_insitu(dest, header, header_mask, source, strlength(source));
4423 } 4456 }
4424 } 4457 }
4425 4458
4426 PUGI__FN void node_copy_contents(xml_node_struct* dn, xml_node_struct* sn, xml_allocator* shared_alloc) 4459 PUGI_IMPL_FN void node_copy_contents(xml_node_struct* dn, xml_node_struct* sn, xml_allocator* shared_alloc)
4427 { 4460 {
4428 node_copy_string(dn->name, dn->header, xml_memory_page_name_allocated_mask, sn->name, sn->header, shared_alloc); 4461 node_copy_string(dn->name, dn->header, xml_memory_page_name_allocated_mask, sn->name, sn->header, shared_alloc);
4429 node_copy_string(dn->value, dn->header, xml_memory_page_value_allocated_mask, sn->value, sn->header, shared_alloc); 4462 node_copy_string(dn->value, dn->header, xml_memory_page_value_allocated_mask, sn->value, sn->header, shared_alloc);
4430 4463
4431 for (xml_attribute_struct* sa = sn->first_attribute; sa; sa = sa->next_attribute) 4464 for (xml_attribute_struct* sa = sn->first_attribute; sa; sa = sa->next_attribute)
4438 node_copy_string(da->value, da->header, xml_memory_page_value_allocated_mask, sa->value, sa->header, shared_alloc); 4471 node_copy_string(da->value, da->header, xml_memory_page_value_allocated_mask, sa->value, sa->header, shared_alloc);
4439 } 4472 }
4440 } 4473 }
4441 } 4474 }
4442 4475
4443 PUGI__FN void node_copy_tree(xml_node_struct* dn, xml_node_struct* sn) 4476 PUGI_IMPL_FN void node_copy_tree(xml_node_struct* dn, xml_node_struct* sn)
4444 { 4477 {
4445 xml_allocator& alloc = get_allocator(dn); 4478 xml_allocator& alloc = get_allocator(dn);
4446 xml_allocator* shared_alloc = (&alloc == &get_allocator(sn)) ? &alloc : 0; 4479 xml_allocator* shared_alloc = (&alloc == &get_allocator(sn)) ? &alloc : 0;
4447 4480
4448 node_copy_contents(dn, sn, shared_alloc); 4481 node_copy_contents(dn, sn, shared_alloc);
4456 assert(dit); 4489 assert(dit);
4457 4490
4458 // when a tree is copied into one of the descendants, we need to skip that subtree to avoid an infinite loop 4491 // when a tree is copied into one of the descendants, we need to skip that subtree to avoid an infinite loop
4459 if (sit != dn) 4492 if (sit != dn)
4460 { 4493 {
4461 xml_node_struct* copy = append_new_node(dit, alloc, PUGI__NODETYPE(sit)); 4494 xml_node_struct* copy = append_new_node(dit, alloc, PUGI_IMPL_NODETYPE(sit));
4462 4495
4463 if (copy) 4496 if (copy)
4464 { 4497 {
4465 node_copy_contents(copy, sit, shared_alloc); 4498 node_copy_contents(copy, sit, shared_alloc);
4466 4499
4492 } 4525 }
4493 4526
4494 assert(!sit || dit == dn->parent); 4527 assert(!sit || dit == dn->parent);
4495 } 4528 }
4496 4529
4497 PUGI__FN void node_copy_attribute(xml_attribute_struct* da, xml_attribute_struct* sa) 4530 PUGI_IMPL_FN void node_copy_attribute(xml_attribute_struct* da, xml_attribute_struct* sa)
4498 { 4531 {
4499 xml_allocator& alloc = get_allocator(da); 4532 xml_allocator& alloc = get_allocator(da);
4500 xml_allocator* shared_alloc = (&alloc == &get_allocator(sa)) ? &alloc : 0; 4533 xml_allocator* shared_alloc = (&alloc == &get_allocator(sa)) ? &alloc : 0;
4501 4534
4502 node_copy_string(da->name, da->header, xml_memory_page_name_allocated_mask, sa->name, sa->header, shared_alloc); 4535 node_copy_string(da->name, da->header, xml_memory_page_name_allocated_mask, sa->name, sa->header, shared_alloc);
4503 node_copy_string(da->value, da->header, xml_memory_page_value_allocated_mask, sa->value, sa->header, shared_alloc); 4536 node_copy_string(da->value, da->header, xml_memory_page_value_allocated_mask, sa->value, sa->header, shared_alloc);
4504 } 4537 }
4505 4538
4506 inline bool is_text_node(xml_node_struct* node) 4539 inline bool is_text_node(xml_node_struct* node)
4507 { 4540 {
4508 xml_node_type type = PUGI__NODETYPE(node); 4541 xml_node_type type = PUGI_IMPL_NODETYPE(node);
4509 4542
4510 return type == node_pcdata || type == node_cdata; 4543 return type == node_pcdata || type == node_cdata;
4511 } 4544 }
4512 4545
4513 // get value with conversion functions 4546 // get value with conversion functions
4514 template <typename U> PUGI__FN PUGI__UNSIGNED_OVERFLOW U string_to_integer(const char_t* value, U minv, U maxv) 4547 template <typename U> PUGI_IMPL_FN PUGI_IMPL_UNSIGNED_OVERFLOW U string_to_integer(const char_t* value, U minv, U maxv)
4515 { 4548 {
4516 U result = 0; 4549 U result = 0;
4517 const char_t* s = value; 4550 const char_t* s = value;
4518 4551
4519 while (PUGI__IS_CHARTYPE(*s, ct_space)) 4552 while (PUGI_IMPL_IS_CHARTYPE(*s, ct_space))
4520 s++; 4553 s++;
4521 4554
4522 bool negative = (*s == '-'); 4555 bool negative = (*s == '-');
4523 4556
4524 s += (*s == '+' || *s == '-'); 4557 s += (*s == '+' || *s == '-');
4569 s++; 4602 s++;
4570 } 4603 }
4571 4604
4572 size_t digits = static_cast<size_t>(s - start); 4605 size_t digits = static_cast<size_t>(s - start);
4573 4606
4574 PUGI__STATIC_ASSERT(sizeof(U) == 8 || sizeof(U) == 4 || sizeof(U) == 2); 4607 PUGI_IMPL_STATIC_ASSERT(sizeof(U) == 8 || sizeof(U) == 4 || sizeof(U) == 2);
4575 4608
4576 const size_t max_digits10 = sizeof(U) == 8 ? 20 : sizeof(U) == 4 ? 10 : 5; 4609 const size_t max_digits10 = sizeof(U) == 8 ? 20 : sizeof(U) == 4 ? 10 : 5;
4577 const char_t max_lead = sizeof(U) == 8 ? '1' : sizeof(U) == 4 ? '4' : '6'; 4610 const char_t max_lead = sizeof(U) == 8 ? '1' : sizeof(U) == 4 ? '4' : '6';
4578 const size_t high_bit = sizeof(U) * 8 - 1; 4611 const size_t high_bit = sizeof(U) * 8 - 1;
4579 4612
4591 } 4624 }
4592 else 4625 else
4593 return (overflow || result > maxv) ? maxv : result; 4626 return (overflow || result > maxv) ? maxv : result;
4594 } 4627 }
4595 4628
4596 PUGI__FN int get_value_int(const char_t* value) 4629 PUGI_IMPL_FN int get_value_int(const char_t* value)
4597 { 4630 {
4598 return string_to_integer<unsigned int>(value, static_cast<unsigned int>(INT_MIN), INT_MAX); 4631 return string_to_integer<unsigned int>(value, static_cast<unsigned int>(INT_MIN), INT_MAX);
4599 } 4632 }
4600 4633
4601 PUGI__FN unsigned int get_value_uint(const char_t* value) 4634 PUGI_IMPL_FN unsigned int get_value_uint(const char_t* value)
4602 { 4635 {
4603 return string_to_integer<unsigned int>(value, 0, UINT_MAX); 4636 return string_to_integer<unsigned int>(value, 0, UINT_MAX);
4604 } 4637 }
4605 4638
4606 PUGI__FN double get_value_double(const char_t* value) 4639 PUGI_IMPL_FN double get_value_double(const char_t* value)
4607 { 4640 {
4608 #ifdef PUGIXML_WCHAR_MODE 4641 #ifdef PUGIXML_WCHAR_MODE
4609 return wcstod(value, 0); 4642 return wcstod(value, 0);
4610 #else 4643 #else
4611 return strtod(value, 0); 4644 return strtod(value, 0);
4612 #endif 4645 #endif
4613 } 4646 }
4614 4647
4615 PUGI__FN float get_value_float(const char_t* value) 4648 PUGI_IMPL_FN float get_value_float(const char_t* value)
4616 { 4649 {
4617 #ifdef PUGIXML_WCHAR_MODE 4650 #ifdef PUGIXML_WCHAR_MODE
4618 return static_cast<float>(wcstod(value, 0)); 4651 return static_cast<float>(wcstod(value, 0));
4619 #else 4652 #else
4620 return static_cast<float>(strtod(value, 0)); 4653 return static_cast<float>(strtod(value, 0));
4621 #endif 4654 #endif
4622 } 4655 }
4623 4656
4624 PUGI__FN bool get_value_bool(const char_t* value) 4657 PUGI_IMPL_FN bool get_value_bool(const char_t* value)
4625 { 4658 {
4626 // only look at first char 4659 // only look at first char
4627 char_t first = *value; 4660 char_t first = *value;
4628 4661
4629 // 1*, t* (true), T* (True), y* (yes), Y* (YES) 4662 // 1*, t* (true), T* (True), y* (yes), Y* (YES)
4630 return (first == '1' || first == 't' || first == 'T' || first == 'y' || first == 'Y'); 4663 return (first == '1' || first == 't' || first == 'T' || first == 'y' || first == 'Y');
4631 } 4664 }
4632 4665
4633 #ifdef PUGIXML_HAS_LONG_LONG 4666 #ifdef PUGIXML_HAS_LONG_LONG
4634 PUGI__FN long long get_value_llong(const char_t* value) 4667 PUGI_IMPL_FN long long get_value_llong(const char_t* value)
4635 { 4668 {
4636 return string_to_integer<unsigned long long>(value, static_cast<unsigned long long>(LLONG_MIN), LLONG_MAX); 4669 return string_to_integer<unsigned long long>(value, static_cast<unsigned long long>(LLONG_MIN), LLONG_MAX);
4637 } 4670 }
4638 4671
4639 PUGI__FN unsigned long long get_value_ullong(const char_t* value) 4672 PUGI_IMPL_FN unsigned long long get_value_ullong(const char_t* value)
4640 { 4673 {
4641 return string_to_integer<unsigned long long>(value, 0, ULLONG_MAX); 4674 return string_to_integer<unsigned long long>(value, 0, ULLONG_MAX);
4642 } 4675 }
4643 #endif 4676 #endif
4644 4677
4645 template <typename U> PUGI__FN PUGI__UNSIGNED_OVERFLOW char_t* integer_to_string(char_t* begin, char_t* end, U value, bool negative) 4678 template <typename U> PUGI_IMPL_FN PUGI_IMPL_UNSIGNED_OVERFLOW char_t* integer_to_string(char_t* begin, char_t* end, U value, bool negative)
4646 { 4679 {
4647 char_t* result = end - 1; 4680 char_t* result = end - 1;
4648 U rest = negative ? 0 - value : value; 4681 U rest = negative ? 0 - value : value;
4649 4682
4650 do 4683 do
4662 return result + !negative; 4695 return result + !negative;
4663 } 4696 }
4664 4697
4665 // set value with conversion functions 4698 // set value with conversion functions
4666 template <typename String, typename Header> 4699 template <typename String, typename Header>
4667 PUGI__FN bool set_value_ascii(String& dest, Header& header, uintptr_t header_mask, char* buf) 4700 PUGI_IMPL_FN bool set_value_ascii(String& dest, Header& header, uintptr_t header_mask, char* buf)
4668 { 4701 {
4669 #ifdef PUGIXML_WCHAR_MODE 4702 #ifdef PUGIXML_WCHAR_MODE
4670 char_t wbuf[128]; 4703 char_t wbuf[128];
4671 assert(strlen(buf) < sizeof(wbuf) / sizeof(wbuf[0])); 4704 assert(strlen(buf) < sizeof(wbuf) / sizeof(wbuf[0]));
4672 4705
4678 return strcpy_insitu(dest, header, header_mask, buf, strlen(buf)); 4711 return strcpy_insitu(dest, header, header_mask, buf, strlen(buf));
4679 #endif 4712 #endif
4680 } 4713 }
4681 4714
4682 template <typename U, typename String, typename Header> 4715 template <typename U, typename String, typename Header>
4683 PUGI__FN bool set_value_integer(String& dest, Header& header, uintptr_t header_mask, U value, bool negative) 4716 PUGI_IMPL_FN bool set_value_integer(String& dest, Header& header, uintptr_t header_mask, U value, bool negative)
4684 { 4717 {
4685 char_t buf[64]; 4718 char_t buf[64];
4686 char_t* end = buf + sizeof(buf) / sizeof(buf[0]); 4719 char_t* end = buf + sizeof(buf) / sizeof(buf[0]);
4687 char_t* begin = integer_to_string(buf, end, value, negative); 4720 char_t* begin = integer_to_string(buf, end, value, negative);
4688 4721
4689 return strcpy_insitu(dest, header, header_mask, begin, end - begin); 4722 return strcpy_insitu(dest, header, header_mask, begin, end - begin);
4690 } 4723 }
4691 4724
4692 template <typename String, typename Header> 4725 template <typename String, typename Header>
4693 PUGI__FN bool set_value_convert(String& dest, Header& header, uintptr_t header_mask, float value, int precision) 4726 PUGI_IMPL_FN bool set_value_convert(String& dest, Header& header, uintptr_t header_mask, float value, int precision)
4694 { 4727 {
4695 char buf[128]; 4728 char buf[128];
4696 PUGI__SNPRINTF(buf, "%.*g", precision, double(value)); 4729 PUGI_IMPL_SNPRINTF(buf, "%.*g", precision, double(value));
4697 4730
4698 return set_value_ascii(dest, header, header_mask, buf); 4731 return set_value_ascii(dest, header, header_mask, buf);
4699 } 4732 }
4700 4733
4701 template <typename String, typename Header> 4734 template <typename String, typename Header>
4702 PUGI__FN bool set_value_convert(String& dest, Header& header, uintptr_t header_mask, double value, int precision) 4735 PUGI_IMPL_FN bool set_value_convert(String& dest, Header& header, uintptr_t header_mask, double value, int precision)
4703 { 4736 {
4704 char buf[128]; 4737 char buf[128];
4705 PUGI__SNPRINTF(buf, "%.*g", precision, value); 4738 PUGI_IMPL_SNPRINTF(buf, "%.*g", precision, value);
4706 4739
4707 return set_value_ascii(dest, header, header_mask, buf); 4740 return set_value_ascii(dest, header, header_mask, buf);
4708 } 4741 }
4709 4742
4710 template <typename String, typename Header> 4743 template <typename String, typename Header>
4711 PUGI__FN bool set_value_bool(String& dest, Header& header, uintptr_t header_mask, bool value) 4744 PUGI_IMPL_FN bool set_value_bool(String& dest, Header& header, uintptr_t header_mask, bool value)
4712 { 4745 {
4713 return strcpy_insitu(dest, header, header_mask, value ? PUGIXML_TEXT("true") : PUGIXML_TEXT("false"), value ? 4 : 5); 4746 return strcpy_insitu(dest, header, header_mask, value ? PUGIXML_TEXT("true") : PUGIXML_TEXT("false"), value ? 4 : 5);
4714 } 4747 }
4715 4748
4716 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) 4749 PUGI_IMPL_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)
4717 { 4750 {
4718 // check input buffer 4751 // check input buffer
4719 if (!contents && size) return make_parse_result(status_io_error); 4752 if (!contents && size) return make_parse_result(status_io_error);
4720 4753
4721 // get actual encoding 4754 // get actual encoding
4751 4784
4752 return res; 4785 return res;
4753 } 4786 }
4754 4787
4755 // we need to get length of entire file to load it in memory; the only (relatively) sane way to do it is via seek/tell trick 4788 // we need to get length of entire file to load it in memory; the only (relatively) sane way to do it is via seek/tell trick
4756 PUGI__FN xml_parse_status get_file_size(FILE* file, size_t& out_result) 4789 PUGI_IMPL_FN xml_parse_status get_file_size(FILE* file, size_t& out_result)
4757 { 4790 {
4758 #if defined(PUGI__MSVC_CRT_VERSION) && PUGI__MSVC_CRT_VERSION >= 1400 4791 #if defined(__linux__) || defined(__APPLE__)
4792 // this simultaneously retrieves the file size and file mode (to guard against loading non-files)
4793 struct stat st;
4794 if (fstat(fileno(file), &st) != 0) return status_io_error;
4795
4796 // anything that's not a regular file doesn't have a coherent length
4797 if (!S_ISREG(st.st_mode)) return status_io_error;
4798
4799 typedef off_t length_type;
4800 length_type length = st.st_size;
4801 #elif defined(PUGI_IMPL_MSVC_CRT_VERSION) && PUGI_IMPL_MSVC_CRT_VERSION >= 1400
4759 // there are 64-bit versions of fseek/ftell, let's use them 4802 // there are 64-bit versions of fseek/ftell, let's use them
4760 typedef __int64 length_type; 4803 typedef __int64 length_type;
4761 4804
4762 _fseeki64(file, 0, SEEK_END); 4805 _fseeki64(file, 0, SEEK_END);
4763 length_type length = _ftelli64(file); 4806 length_type length = _ftelli64(file);
4791 4834
4792 return status_ok; 4835 return status_ok;
4793 } 4836 }
4794 4837
4795 // This function assumes that buffer has extra sizeof(char_t) writable bytes after size 4838 // This function assumes that buffer has extra sizeof(char_t) writable bytes after size
4796 PUGI__FN size_t zero_terminate_buffer(void* buffer, size_t size, xml_encoding encoding) 4839 PUGI_IMPL_FN size_t zero_terminate_buffer(void* buffer, size_t size, xml_encoding encoding)
4797 { 4840 {
4798 // We only need to zero-terminate if encoding conversion does not do it for us 4841 // We only need to zero-terminate if encoding conversion does not do it for us
4799 #ifdef PUGIXML_WCHAR_MODE 4842 #ifdef PUGIXML_WCHAR_MODE
4800 xml_encoding wchar_encoding = get_wchar_encoding(); 4843 xml_encoding wchar_encoding = get_wchar_encoding();
4801 4844
4815 #endif 4858 #endif
4816 4859
4817 return size; 4860 return size;
4818 } 4861 }
4819 4862
4820 PUGI__FN xml_parse_result load_file_impl(xml_document_struct* doc, FILE* file, unsigned int options, xml_encoding encoding, char_t** out_buffer) 4863 PUGI_IMPL_FN xml_parse_result load_file_impl(xml_document_struct* doc, FILE* file, unsigned int options, xml_encoding encoding, char_t** out_buffer)
4821 { 4864 {
4822 if (!file) return make_parse_result(status_file_not_found); 4865 if (!file) return make_parse_result(status_file_not_found);
4823 4866
4824 // get file size (can result in I/O errors) 4867 // get file size (can result in I/O errors)
4825 size_t size = 0; 4868 size_t size = 0;
4844 xml_encoding real_encoding = get_buffer_encoding(encoding, contents, size); 4887 xml_encoding real_encoding = get_buffer_encoding(encoding, contents, size);
4845 4888
4846 return load_buffer_impl(doc, doc, contents, zero_terminate_buffer(contents, size, real_encoding), options, real_encoding, true, true, out_buffer); 4889 return load_buffer_impl(doc, doc, contents, zero_terminate_buffer(contents, size, real_encoding), options, real_encoding, true, true, out_buffer);
4847 } 4890 }
4848 4891
4849 PUGI__FN void close_file(FILE* file) 4892 PUGI_IMPL_FN void close_file(FILE* file)
4850 { 4893 {
4851 fclose(file); 4894 fclose(file);
4852 } 4895 }
4853 4896
4854 #ifndef PUGIXML_NO_STL 4897 #ifndef PUGIXML_NO_STL
4883 size_t size; 4926 size_t size;
4884 4927
4885 T data[xml_memory_page_size / sizeof(T)]; 4928 T data[xml_memory_page_size / sizeof(T)];
4886 }; 4929 };
4887 4930
4888 template <typename T> PUGI__FN xml_parse_status load_stream_data_noseek(std::basic_istream<T>& stream, void** out_buffer, size_t* out_size) 4931 template <typename T> PUGI_IMPL_FN xml_parse_status load_stream_data_noseek(std::basic_istream<T>& stream, void** out_buffer, size_t* out_size)
4889 { 4932 {
4890 auto_deleter<xml_stream_chunk<T> > chunks(0, xml_stream_chunk<T>::destroy); 4933 auto_deleter<xml_stream_chunk<T> > chunks(0, xml_stream_chunk<T>::destroy);
4891 4934
4892 // read file to a chunk list 4935 // read file to a chunk list
4893 size_t total = 0; 4936 size_t total = 0;
4937 *out_size = total; 4980 *out_size = total;
4938 4981
4939 return status_ok; 4982 return status_ok;
4940 } 4983 }
4941 4984
4942 template <typename T> PUGI__FN xml_parse_status load_stream_data_seek(std::basic_istream<T>& stream, void** out_buffer, size_t* out_size) 4985 template <typename T> PUGI_IMPL_FN xml_parse_status load_stream_data_seek(std::basic_istream<T>& stream, void** out_buffer, size_t* out_size)
4943 { 4986 {
4944 // get length of remaining data in stream 4987 // get length of remaining data in stream
4945 typename std::basic_istream<T>::pos_type pos = stream.tellg(); 4988 typename std::basic_istream<T>::pos_type pos = stream.tellg();
4946 stream.seekg(0, std::ios::end); 4989 stream.seekg(0, std::ios::end);
4947 std::streamoff length = stream.tellg() - pos; 4990 std::streamoff length = stream.tellg() - pos;
4973 *out_size = actual_length * sizeof(T); 5016 *out_size = actual_length * sizeof(T);
4974 5017
4975 return status_ok; 5018 return status_ok;
4976 } 5019 }
4977 5020
4978 template <typename T> 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) 5021 template <typename T> PUGI_IMPL_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)
4979 { 5022 {
4980 void* buffer = 0; 5023 void* buffer = 0;
4981 size_t size = 0; 5024 size_t size = 0;
4982 xml_parse_status status = status_ok; 5025 xml_parse_status status = status_ok;
4983 5026
4999 5042
5000 return load_buffer_impl(doc, doc, buffer, zero_terminate_buffer(buffer, size, real_encoding), options, real_encoding, true, true, out_buffer); 5043 return load_buffer_impl(doc, doc, buffer, zero_terminate_buffer(buffer, size, real_encoding), options, real_encoding, true, true, out_buffer);
5001 } 5044 }
5002 #endif 5045 #endif
5003 5046
5004 #if defined(PUGI__MSVC_CRT_VERSION) || defined(__BORLANDC__) || (defined(__MINGW32__) && (!defined(__STRICT_ANSI__) || defined(__MINGW64_VERSION_MAJOR))) 5047 #if defined(PUGI_IMPL_MSVC_CRT_VERSION) || defined(__BORLANDC__) || (defined(__MINGW32__) && (!defined(__STRICT_ANSI__) || defined(__MINGW64_VERSION_MAJOR)))
5005 PUGI__FN FILE* open_file_wide(const wchar_t* path, const wchar_t* mode) 5048 PUGI_IMPL_FN FILE* open_file_wide(const wchar_t* path, const wchar_t* mode)
5006 { 5049 {
5007 #if defined(PUGI__MSVC_CRT_VERSION) && PUGI__MSVC_CRT_VERSION >= 1400 5050 #if defined(PUGI_IMPL_MSVC_CRT_VERSION) && PUGI_IMPL_MSVC_CRT_VERSION >= 1400
5008 FILE* file = 0; 5051 FILE* file = 0;
5009 return _wfopen_s(&file, path, mode) == 0 ? file : 0; 5052 return _wfopen_s(&file, path, mode) == 0 ? file : 0;
5010 #else 5053 #else
5011 return _wfopen(path, mode); 5054 return _wfopen(path, mode);
5012 #endif 5055 #endif
5013 } 5056 }
5014 #else 5057 #else
5015 PUGI__FN char* convert_path_heap(const wchar_t* str) 5058 PUGI_IMPL_FN char* convert_path_heap(const wchar_t* str)
5016 { 5059 {
5017 assert(str); 5060 assert(str);
5018 5061
5019 // first pass: get length in utf8 characters 5062 // first pass: get length in utf8 characters
5020 size_t length = strlength_wide(str); 5063 size_t length = strlength_wide(str);
5031 result[size] = 0; 5074 result[size] = 0;
5032 5075
5033 return result; 5076 return result;
5034 } 5077 }
5035 5078
5036 PUGI__FN FILE* open_file_wide(const wchar_t* path, const wchar_t* mode) 5079 PUGI_IMPL_FN FILE* open_file_wide(const wchar_t* path, const wchar_t* mode)
5037 { 5080 {
5038 // there is no standard function to open wide paths, so our best bet is to try utf8 path 5081 // there is no standard function to open wide paths, so our best bet is to try utf8 path
5039 char* path_utf8 = convert_path_heap(path); 5082 char* path_utf8 = convert_path_heap(path);
5040 if (!path_utf8) return 0; 5083 if (!path_utf8) return 0;
5041 5084
5051 5094
5052 return result; 5095 return result;
5053 } 5096 }
5054 #endif 5097 #endif
5055 5098
5056 PUGI__FN FILE* open_file(const char* path, const char* mode) 5099 PUGI_IMPL_FN FILE* open_file(const char* path, const char* mode)
5057 { 5100 {
5058 #if defined(PUGI__MSVC_CRT_VERSION) && PUGI__MSVC_CRT_VERSION >= 1400 5101 #if defined(PUGI_IMPL_MSVC_CRT_VERSION) && PUGI_IMPL_MSVC_CRT_VERSION >= 1400
5059 FILE* file = 0; 5102 FILE* file = 0;
5060 return fopen_s(&file, path, mode) == 0 ? file : 0; 5103 return fopen_s(&file, path, mode) == 0 ? file : 0;
5061 #else 5104 #else
5062 return fopen(path, mode); 5105 return fopen(path, mode);
5063 #endif 5106 #endif
5064 } 5107 }
5065 5108
5066 PUGI__FN bool save_file_impl(const xml_document& doc, FILE* file, const char_t* indent, unsigned int flags, xml_encoding encoding) 5109 PUGI_IMPL_FN bool save_file_impl(const xml_document& doc, FILE* file, const char_t* indent, unsigned int flags, xml_encoding encoding)
5067 { 5110 {
5068 if (!file) return false; 5111 if (!file) return false;
5069 5112
5070 xml_writer_file writer(file); 5113 xml_writer_file writer(file);
5071 doc.save(writer, indent, flags, encoding); 5114 doc.save(writer, indent, flags, encoding);
5086 ~name_null_sentry() 5129 ~name_null_sentry()
5087 { 5130 {
5088 node->name = name; 5131 node->name = name;
5089 } 5132 }
5090 }; 5133 };
5091 PUGI__NS_END 5134 PUGI_IMPL_NS_END
5092 5135
5093 namespace pugi 5136 namespace pugi
5094 { 5137 {
5095 PUGI__FN xml_writer_file::xml_writer_file(void* file_): file(file_) 5138 PUGI_IMPL_FN xml_writer::~xml_writer()
5096 { 5139 {
5097 } 5140 }
5098 5141
5099 PUGI__FN void xml_writer_file::write(const void* data, size_t size) 5142 PUGI_IMPL_FN xml_writer_file::xml_writer_file(void* file_): file(file_)
5143 {
5144 }
5145
5146 PUGI_IMPL_FN void xml_writer_file::write(const void* data, size_t size)
5100 { 5147 {
5101 size_t result = fwrite(data, 1, size, static_cast<FILE*>(file)); 5148 size_t result = fwrite(data, 1, size, static_cast<FILE*>(file));
5102 (void)!result; // unfortunately we can't do proper error handling here 5149 (void)!result; // unfortunately we can't do proper error handling here
5103 } 5150 }
5104 5151
5105 #ifndef PUGIXML_NO_STL 5152 #ifndef PUGIXML_NO_STL
5106 PUGI__FN xml_writer_stream::xml_writer_stream(std::basic_ostream<char, std::char_traits<char> >& stream): narrow_stream(&stream), wide_stream(0) 5153 PUGI_IMPL_FN xml_writer_stream::xml_writer_stream(std::basic_ostream<char, std::char_traits<char> >& stream): narrow_stream(&stream), wide_stream(0)
5107 { 5154 {
5108 } 5155 }
5109 5156
5110 PUGI__FN xml_writer_stream::xml_writer_stream(std::basic_ostream<wchar_t, std::char_traits<wchar_t> >& stream): narrow_stream(0), wide_stream(&stream) 5157 PUGI_IMPL_FN xml_writer_stream::xml_writer_stream(std::basic_ostream<wchar_t, std::char_traits<wchar_t> >& stream): narrow_stream(0), wide_stream(&stream)
5111 { 5158 {
5112 } 5159 }
5113 5160
5114 PUGI__FN void xml_writer_stream::write(const void* data, size_t size) 5161 PUGI_IMPL_FN void xml_writer_stream::write(const void* data, size_t size)
5115 { 5162 {
5116 if (narrow_stream) 5163 if (narrow_stream)
5117 { 5164 {
5118 assert(!wide_stream); 5165 assert(!wide_stream);
5119 narrow_stream->write(reinterpret_cast<const char*>(data), static_cast<std::streamsize>(size)); 5166 narrow_stream->write(reinterpret_cast<const char*>(data), static_cast<std::streamsize>(size));
5126 wide_stream->write(reinterpret_cast<const wchar_t*>(data), static_cast<std::streamsize>(size / sizeof(wchar_t))); 5173 wide_stream->write(reinterpret_cast<const wchar_t*>(data), static_cast<std::streamsize>(size / sizeof(wchar_t)));
5127 } 5174 }
5128 } 5175 }
5129 #endif 5176 #endif
5130 5177
5131 PUGI__FN xml_tree_walker::xml_tree_walker(): _depth(0) 5178 PUGI_IMPL_FN xml_tree_walker::xml_tree_walker(): _depth(0)
5132 { 5179 {
5133 } 5180 }
5134 5181
5135 PUGI__FN xml_tree_walker::~xml_tree_walker() 5182 PUGI_IMPL_FN xml_tree_walker::~xml_tree_walker()
5136 { 5183 {
5137 } 5184 }
5138 5185
5139 PUGI__FN int xml_tree_walker::depth() const 5186 PUGI_IMPL_FN int xml_tree_walker::depth() const
5140 { 5187 {
5141 return _depth; 5188 return _depth;
5142 } 5189 }
5143 5190
5144 PUGI__FN bool xml_tree_walker::begin(xml_node&) 5191 PUGI_IMPL_FN bool xml_tree_walker::begin(xml_node&)
5145 { 5192 {
5146 return true; 5193 return true;
5147 } 5194 }
5148 5195
5149 PUGI__FN bool xml_tree_walker::end(xml_node&) 5196 PUGI_IMPL_FN bool xml_tree_walker::end(xml_node&)
5150 { 5197 {
5151 return true; 5198 return true;
5152 } 5199 }
5153 5200
5154 PUGI__FN xml_attribute::xml_attribute(): _attr(0) 5201 PUGI_IMPL_FN xml_attribute::xml_attribute(): _attr(0)
5155 { 5202 {
5156 } 5203 }
5157 5204
5158 PUGI__FN xml_attribute::xml_attribute(xml_attribute_struct* attr): _attr(attr) 5205 PUGI_IMPL_FN xml_attribute::xml_attribute(xml_attribute_struct* attr): _attr(attr)
5159 { 5206 {
5160 } 5207 }
5161 5208
5162 PUGI__FN static void unspecified_bool_xml_attribute(xml_attribute***) 5209 PUGI_IMPL_FN static void unspecified_bool_xml_attribute(xml_attribute***)
5163 { 5210 {
5164 } 5211 }
5165 5212
5166 PUGI__FN xml_attribute::operator xml_attribute::unspecified_bool_type() const 5213 PUGI_IMPL_FN xml_attribute::operator xml_attribute::unspecified_bool_type() const
5167 { 5214 {
5168 return _attr ? unspecified_bool_xml_attribute : 0; 5215 return _attr ? unspecified_bool_xml_attribute : 0;
5169 } 5216 }
5170 5217
5171 PUGI__FN bool xml_attribute::operator!() const 5218 PUGI_IMPL_FN bool xml_attribute::operator!() const
5172 { 5219 {
5173 return !_attr; 5220 return !_attr;
5174 } 5221 }
5175 5222
5176 PUGI__FN bool xml_attribute::operator==(const xml_attribute& r) const 5223 PUGI_IMPL_FN bool xml_attribute::operator==(const xml_attribute& r) const
5177 { 5224 {
5178 return (_attr == r._attr); 5225 return (_attr == r._attr);
5179 } 5226 }
5180 5227
5181 PUGI__FN bool xml_attribute::operator!=(const xml_attribute& r) const 5228 PUGI_IMPL_FN bool xml_attribute::operator!=(const xml_attribute& r) const
5182 { 5229 {
5183 return (_attr != r._attr); 5230 return (_attr != r._attr);
5184 } 5231 }
5185 5232
5186 PUGI__FN bool xml_attribute::operator<(const xml_attribute& r) const 5233 PUGI_IMPL_FN bool xml_attribute::operator<(const xml_attribute& r) const
5187 { 5234 {
5188 return (_attr < r._attr); 5235 return (_attr < r._attr);
5189 } 5236 }
5190 5237
5191 PUGI__FN bool xml_attribute::operator>(const xml_attribute& r) const 5238 PUGI_IMPL_FN bool xml_attribute::operator>(const xml_attribute& r) const
5192 { 5239 {
5193 return (_attr > r._attr); 5240 return (_attr > r._attr);
5194 } 5241 }
5195 5242
5196 PUGI__FN bool xml_attribute::operator<=(const xml_attribute& r) const 5243 PUGI_IMPL_FN bool xml_attribute::operator<=(const xml_attribute& r) const
5197 { 5244 {
5198 return (_attr <= r._attr); 5245 return (_attr <= r._attr);
5199 } 5246 }
5200 5247
5201 PUGI__FN bool xml_attribute::operator>=(const xml_attribute& r) const 5248 PUGI_IMPL_FN bool xml_attribute::operator>=(const xml_attribute& r) const
5202 { 5249 {
5203 return (_attr >= r._attr); 5250 return (_attr >= r._attr);
5204 } 5251 }
5205 5252
5206 PUGI__FN xml_attribute xml_attribute::next_attribute() const 5253 PUGI_IMPL_FN xml_attribute xml_attribute::next_attribute() const
5207 { 5254 {
5208 if (!_attr) return xml_attribute(); 5255 if (!_attr) return xml_attribute();
5209 return xml_attribute(_attr->next_attribute); 5256 return xml_attribute(_attr->next_attribute);
5210 } 5257 }
5211 5258
5212 PUGI__FN xml_attribute xml_attribute::previous_attribute() const 5259 PUGI_IMPL_FN xml_attribute xml_attribute::previous_attribute() const
5213 { 5260 {
5214 if (!_attr) return xml_attribute(); 5261 if (!_attr) return xml_attribute();
5215 xml_attribute_struct* prev = _attr->prev_attribute_c; 5262 xml_attribute_struct* prev = _attr->prev_attribute_c;
5216 return prev->next_attribute ? xml_attribute(prev) : xml_attribute(); 5263 return prev->next_attribute ? xml_attribute(prev) : xml_attribute();
5217 } 5264 }
5218 5265
5219 PUGI__FN const char_t* xml_attribute::as_string(const char_t* def) const 5266 PUGI_IMPL_FN const char_t* xml_attribute::as_string(const char_t* def) const
5220 { 5267 {
5221 if (!_attr) return def; 5268 if (!_attr) return def;
5222 const char_t* value = _attr->value; 5269 const char_t* value = _attr->value;
5223 return value ? value : def; 5270 return value ? value : def;
5224 } 5271 }
5225 5272
5226 PUGI__FN int xml_attribute::as_int(int def) const 5273 PUGI_IMPL_FN int xml_attribute::as_int(int def) const
5227 { 5274 {
5228 if (!_attr) return def; 5275 if (!_attr) return def;
5229 const char_t* value = _attr->value; 5276 const char_t* value = _attr->value;
5230 return value ? impl::get_value_int(value) : def; 5277 return value ? impl::get_value_int(value) : def;
5231 } 5278 }
5232 5279
5233 PUGI__FN unsigned int xml_attribute::as_uint(unsigned int def) const 5280 PUGI_IMPL_FN unsigned int xml_attribute::as_uint(unsigned int def) const
5234 { 5281 {
5235 if (!_attr) return def; 5282 if (!_attr) return def;
5236 const char_t* value = _attr->value; 5283 const char_t* value = _attr->value;
5237 return value ? impl::get_value_uint(value) : def; 5284 return value ? impl::get_value_uint(value) : def;
5238 } 5285 }
5239 5286
5240 PUGI__FN double xml_attribute::as_double(double def) const 5287 PUGI_IMPL_FN double xml_attribute::as_double(double def) const
5241 { 5288 {
5242 if (!_attr) return def; 5289 if (!_attr) return def;
5243 const char_t* value = _attr->value; 5290 const char_t* value = _attr->value;
5244 return value ? impl::get_value_double(value) : def; 5291 return value ? impl::get_value_double(value) : def;
5245 } 5292 }
5246 5293
5247 PUGI__FN float xml_attribute::as_float(float def) const 5294 PUGI_IMPL_FN float xml_attribute::as_float(float def) const
5248 { 5295 {
5249 if (!_attr) return def; 5296 if (!_attr) return def;
5250 const char_t* value = _attr->value; 5297 const char_t* value = _attr->value;
5251 return value ? impl::get_value_float(value) : def; 5298 return value ? impl::get_value_float(value) : def;
5252 } 5299 }
5253 5300
5254 PUGI__FN bool xml_attribute::as_bool(bool def) const 5301 PUGI_IMPL_FN bool xml_attribute::as_bool(bool def) const
5255 { 5302 {
5256 if (!_attr) return def; 5303 if (!_attr) return def;
5257 const char_t* value = _attr->value; 5304 const char_t* value = _attr->value;
5258 return value ? impl::get_value_bool(value) : def; 5305 return value ? impl::get_value_bool(value) : def;
5259 } 5306 }
5260 5307
5261 #ifdef PUGIXML_HAS_LONG_LONG 5308 #ifdef PUGIXML_HAS_LONG_LONG
5262 PUGI__FN long long xml_attribute::as_llong(long long def) const 5309 PUGI_IMPL_FN long long xml_attribute::as_llong(long long def) const
5263 { 5310 {
5264 if (!_attr) return def; 5311 if (!_attr) return def;
5265 const char_t* value = _attr->value; 5312 const char_t* value = _attr->value;
5266 return value ? impl::get_value_llong(value) : def; 5313 return value ? impl::get_value_llong(value) : def;
5267 } 5314 }
5268 5315
5269 PUGI__FN unsigned long long xml_attribute::as_ullong(unsigned long long def) const 5316 PUGI_IMPL_FN unsigned long long xml_attribute::as_ullong(unsigned long long def) const
5270 { 5317 {
5271 if (!_attr) return def; 5318 if (!_attr) return def;
5272 const char_t* value = _attr->value; 5319 const char_t* value = _attr->value;
5273 return value ? impl::get_value_ullong(value) : def; 5320 return value ? impl::get_value_ullong(value) : def;
5274 } 5321 }
5275 #endif 5322 #endif
5276 5323
5277 PUGI__FN bool xml_attribute::empty() const 5324 PUGI_IMPL_FN bool xml_attribute::empty() const
5278 { 5325 {
5279 return !_attr; 5326 return !_attr;
5280 } 5327 }
5281 5328
5282 PUGI__FN const char_t* xml_attribute::name() const 5329 PUGI_IMPL_FN const char_t* xml_attribute::name() const
5283 { 5330 {
5284 if (!_attr) return PUGIXML_TEXT(""); 5331 if (!_attr) return PUGIXML_TEXT("");
5285 const char_t* name = _attr->name; 5332 const char_t* name = _attr->name;
5286 return name ? name : PUGIXML_TEXT(""); 5333 return name ? name : PUGIXML_TEXT("");
5287 } 5334 }
5288 5335
5289 PUGI__FN const char_t* xml_attribute::value() const 5336 PUGI_IMPL_FN const char_t* xml_attribute::value() const
5290 { 5337 {
5291 if (!_attr) return PUGIXML_TEXT(""); 5338 if (!_attr) return PUGIXML_TEXT("");
5292 const char_t* value = _attr->value; 5339 const char_t* value = _attr->value;
5293 return value ? value : PUGIXML_TEXT(""); 5340 return value ? value : PUGIXML_TEXT("");
5294 } 5341 }
5295 5342
5296 PUGI__FN size_t xml_attribute::hash_value() const 5343 PUGI_IMPL_FN size_t xml_attribute::hash_value() const
5297 { 5344 {
5298 return static_cast<size_t>(reinterpret_cast<uintptr_t>(_attr) / sizeof(xml_attribute_struct)); 5345 return static_cast<size_t>(reinterpret_cast<uintptr_t>(_attr) / sizeof(xml_attribute_struct));
5299 } 5346 }
5300 5347
5301 PUGI__FN xml_attribute_struct* xml_attribute::internal_object() const 5348 PUGI_IMPL_FN xml_attribute_struct* xml_attribute::internal_object() const
5302 { 5349 {
5303 return _attr; 5350 return _attr;
5304 } 5351 }
5305 5352
5306 PUGI__FN xml_attribute& xml_attribute::operator=(const char_t* rhs) 5353 PUGI_IMPL_FN xml_attribute& xml_attribute::operator=(const char_t* rhs)
5307 { 5354 {
5308 set_value(rhs); 5355 set_value(rhs);
5309 return *this; 5356 return *this;
5310 } 5357 }
5311 5358
5312 PUGI__FN xml_attribute& xml_attribute::operator=(int rhs) 5359 PUGI_IMPL_FN xml_attribute& xml_attribute::operator=(int rhs)
5313 { 5360 {
5314 set_value(rhs); 5361 set_value(rhs);
5315 return *this; 5362 return *this;
5316 } 5363 }
5317 5364
5318 PUGI__FN xml_attribute& xml_attribute::operator=(unsigned int rhs) 5365 PUGI_IMPL_FN xml_attribute& xml_attribute::operator=(unsigned int rhs)
5319 { 5366 {
5320 set_value(rhs); 5367 set_value(rhs);
5321 return *this; 5368 return *this;
5322 } 5369 }
5323 5370
5324 PUGI__FN xml_attribute& xml_attribute::operator=(long rhs) 5371 PUGI_IMPL_FN xml_attribute& xml_attribute::operator=(long rhs)
5325 { 5372 {
5326 set_value(rhs); 5373 set_value(rhs);
5327 return *this; 5374 return *this;
5328 } 5375 }
5329 5376
5330 PUGI__FN xml_attribute& xml_attribute::operator=(unsigned long rhs) 5377 PUGI_IMPL_FN xml_attribute& xml_attribute::operator=(unsigned long rhs)
5331 { 5378 {
5332 set_value(rhs); 5379 set_value(rhs);
5333 return *this; 5380 return *this;
5334 } 5381 }
5335 5382
5336 PUGI__FN xml_attribute& xml_attribute::operator=(double rhs) 5383 PUGI_IMPL_FN xml_attribute& xml_attribute::operator=(double rhs)
5337 { 5384 {
5338 set_value(rhs); 5385 set_value(rhs);
5339 return *this; 5386 return *this;
5340 } 5387 }
5341 5388
5342 PUGI__FN xml_attribute& xml_attribute::operator=(float rhs) 5389 PUGI_IMPL_FN xml_attribute& xml_attribute::operator=(float rhs)
5343 { 5390 {
5344 set_value(rhs); 5391 set_value(rhs);
5345 return *this; 5392 return *this;
5346 } 5393 }
5347 5394
5348 PUGI__FN xml_attribute& xml_attribute::operator=(bool rhs) 5395 PUGI_IMPL_FN xml_attribute& xml_attribute::operator=(bool rhs)
5349 { 5396 {
5350 set_value(rhs); 5397 set_value(rhs);
5351 return *this; 5398 return *this;
5352 } 5399 }
5353 5400
5354 #ifdef PUGIXML_HAS_LONG_LONG 5401 #ifdef PUGIXML_HAS_LONG_LONG
5355 PUGI__FN xml_attribute& xml_attribute::operator=(long long rhs) 5402 PUGI_IMPL_FN xml_attribute& xml_attribute::operator=(long long rhs)
5356 { 5403 {
5357 set_value(rhs); 5404 set_value(rhs);
5358 return *this; 5405 return *this;
5359 } 5406 }
5360 5407
5361 PUGI__FN xml_attribute& xml_attribute::operator=(unsigned long long rhs) 5408 PUGI_IMPL_FN xml_attribute& xml_attribute::operator=(unsigned long long rhs)
5362 { 5409 {
5363 set_value(rhs); 5410 set_value(rhs);
5364 return *this; 5411 return *this;
5365 } 5412 }
5366 #endif 5413 #endif
5367 5414
5368 PUGI__FN bool xml_attribute::set_name(const char_t* rhs) 5415 PUGI_IMPL_FN bool xml_attribute::set_name(const char_t* rhs)
5369 { 5416 {
5370 if (!_attr) return false; 5417 if (!_attr) return false;
5371 5418
5372 return impl::strcpy_insitu(_attr->name, _attr->header, impl::xml_memory_page_name_allocated_mask, rhs, impl::strlength(rhs)); 5419 return impl::strcpy_insitu(_attr->name, _attr->header, impl::xml_memory_page_name_allocated_mask, rhs, impl::strlength(rhs));
5373 } 5420 }
5374 5421
5375 PUGI__FN bool xml_attribute::set_value(const char_t* rhs, size_t sz) 5422 PUGI_IMPL_FN bool xml_attribute::set_name(const char_t* rhs, size_t size)
5376 { 5423 {
5377 if (!_attr) return false; 5424 if (!_attr) return false;
5378 5425
5379 return impl::strcpy_insitu(_attr->value, _attr->header, impl::xml_memory_page_value_allocated_mask, rhs, sz); 5426 return impl::strcpy_insitu(_attr->name, _attr->header, impl::xml_memory_page_name_allocated_mask, rhs, size);
5380 } 5427 }
5381 5428
5382 PUGI__FN bool xml_attribute::set_value(const char_t* rhs) 5429 PUGI_IMPL_FN bool xml_attribute::set_value(const char_t* rhs)
5383 { 5430 {
5384 if (!_attr) return false; 5431 if (!_attr) return false;
5385 5432
5386 return impl::strcpy_insitu(_attr->value, _attr->header, impl::xml_memory_page_value_allocated_mask, rhs, impl::strlength(rhs)); 5433 return impl::strcpy_insitu(_attr->value, _attr->header, impl::xml_memory_page_value_allocated_mask, rhs, impl::strlength(rhs));
5387 } 5434 }
5388 5435
5389 PUGI__FN bool xml_attribute::set_value(int rhs) 5436 PUGI_IMPL_FN bool xml_attribute::set_value(const char_t* rhs, size_t size)
5390 { 5437 {
5391 if (!_attr) return false; 5438 if (!_attr) return false;
5392 5439
5440 return impl::strcpy_insitu(_attr->value, _attr->header, impl::xml_memory_page_value_allocated_mask, rhs, size);
5441 }
5442
5443 PUGI_IMPL_FN bool xml_attribute::set_value(int rhs)
5444 {
5445 if (!_attr) return false;
5446
5393 return impl::set_value_integer<unsigned int>(_attr->value, _attr->header, impl::xml_memory_page_value_allocated_mask, rhs, rhs < 0); 5447 return impl::set_value_integer<unsigned int>(_attr->value, _attr->header, impl::xml_memory_page_value_allocated_mask, rhs, rhs < 0);
5394 } 5448 }
5395 5449
5396 PUGI__FN bool xml_attribute::set_value(unsigned int rhs) 5450 PUGI_IMPL_FN bool xml_attribute::set_value(unsigned int rhs)
5397 { 5451 {
5398 if (!_attr) return false; 5452 if (!_attr) return false;
5399 5453
5400 return impl::set_value_integer<unsigned int>(_attr->value, _attr->header, impl::xml_memory_page_value_allocated_mask, rhs, false); 5454 return impl::set_value_integer<unsigned int>(_attr->value, _attr->header, impl::xml_memory_page_value_allocated_mask, rhs, false);
5401 } 5455 }
5402 5456
5403 PUGI__FN bool xml_attribute::set_value(long rhs) 5457 PUGI_IMPL_FN bool xml_attribute::set_value(long rhs)
5404 { 5458 {
5405 if (!_attr) return false; 5459 if (!_attr) return false;
5406 5460
5407 return impl::set_value_integer<unsigned long>(_attr->value, _attr->header, impl::xml_memory_page_value_allocated_mask, rhs, rhs < 0); 5461 return impl::set_value_integer<unsigned long>(_attr->value, _attr->header, impl::xml_memory_page_value_allocated_mask, rhs, rhs < 0);
5408 } 5462 }
5409 5463
5410 PUGI__FN bool xml_attribute::set_value(unsigned long rhs) 5464 PUGI_IMPL_FN bool xml_attribute::set_value(unsigned long rhs)
5411 { 5465 {
5412 if (!_attr) return false; 5466 if (!_attr) return false;
5413 5467
5414 return impl::set_value_integer<unsigned long>(_attr->value, _attr->header, impl::xml_memory_page_value_allocated_mask, rhs, false); 5468 return impl::set_value_integer<unsigned long>(_attr->value, _attr->header, impl::xml_memory_page_value_allocated_mask, rhs, false);
5415 } 5469 }
5416 5470
5417 PUGI__FN bool xml_attribute::set_value(double rhs) 5471 PUGI_IMPL_FN bool xml_attribute::set_value(double rhs)
5418 { 5472 {
5419 if (!_attr) return false; 5473 if (!_attr) return false;
5420 5474
5421 return impl::set_value_convert(_attr->value, _attr->header, impl::xml_memory_page_value_allocated_mask, rhs, default_double_precision); 5475 return impl::set_value_convert(_attr->value, _attr->header, impl::xml_memory_page_value_allocated_mask, rhs, default_double_precision);
5422 } 5476 }
5423 5477
5424 PUGI__FN bool xml_attribute::set_value(double rhs, int precision) 5478 PUGI_IMPL_FN bool xml_attribute::set_value(double rhs, int precision)
5425 { 5479 {
5426 if (!_attr) return false; 5480 if (!_attr) return false;
5427 5481
5428 return impl::set_value_convert(_attr->value, _attr->header, impl::xml_memory_page_value_allocated_mask, rhs, precision); 5482 return impl::set_value_convert(_attr->value, _attr->header, impl::xml_memory_page_value_allocated_mask, rhs, precision);
5429 } 5483 }
5430 5484
5431 PUGI__FN bool xml_attribute::set_value(float rhs) 5485 PUGI_IMPL_FN bool xml_attribute::set_value(float rhs)
5432 { 5486 {
5433 if (!_attr) return false; 5487 if (!_attr) return false;
5434 5488
5435 return impl::set_value_convert(_attr->value, _attr->header, impl::xml_memory_page_value_allocated_mask, rhs, default_float_precision); 5489 return impl::set_value_convert(_attr->value, _attr->header, impl::xml_memory_page_value_allocated_mask, rhs, default_float_precision);
5436 } 5490 }
5437 5491
5438 PUGI__FN bool xml_attribute::set_value(float rhs, int precision) 5492 PUGI_IMPL_FN bool xml_attribute::set_value(float rhs, int precision)
5439 { 5493 {
5440 if (!_attr) return false; 5494 if (!_attr) return false;
5441 5495
5442 return impl::set_value_convert(_attr->value, _attr->header, impl::xml_memory_page_value_allocated_mask, rhs, precision); 5496 return impl::set_value_convert(_attr->value, _attr->header, impl::xml_memory_page_value_allocated_mask, rhs, precision);
5443 } 5497 }
5444 5498
5445 PUGI__FN bool xml_attribute::set_value(bool rhs) 5499 PUGI_IMPL_FN bool xml_attribute::set_value(bool rhs)
5446 { 5500 {
5447 if (!_attr) return false; 5501 if (!_attr) return false;
5448 5502
5449 return impl::set_value_bool(_attr->value, _attr->header, impl::xml_memory_page_value_allocated_mask, rhs); 5503 return impl::set_value_bool(_attr->value, _attr->header, impl::xml_memory_page_value_allocated_mask, rhs);
5450 } 5504 }
5451 5505
5452 #ifdef PUGIXML_HAS_LONG_LONG 5506 #ifdef PUGIXML_HAS_LONG_LONG
5453 PUGI__FN bool xml_attribute::set_value(long long rhs) 5507 PUGI_IMPL_FN bool xml_attribute::set_value(long long rhs)
5454 { 5508 {
5455 if (!_attr) return false; 5509 if (!_attr) return false;
5456 5510
5457 return impl::set_value_integer<unsigned long long>(_attr->value, _attr->header, impl::xml_memory_page_value_allocated_mask, rhs, rhs < 0); 5511 return impl::set_value_integer<unsigned long long>(_attr->value, _attr->header, impl::xml_memory_page_value_allocated_mask, rhs, rhs < 0);
5458 } 5512 }
5459 5513
5460 PUGI__FN bool xml_attribute::set_value(unsigned long long rhs) 5514 PUGI_IMPL_FN bool xml_attribute::set_value(unsigned long long rhs)
5461 { 5515 {
5462 if (!_attr) return false; 5516 if (!_attr) return false;
5463 5517
5464 return impl::set_value_integer<unsigned long long>(_attr->value, _attr->header, impl::xml_memory_page_value_allocated_mask, rhs, false); 5518 return impl::set_value_integer<unsigned long long>(_attr->value, _attr->header, impl::xml_memory_page_value_allocated_mask, rhs, false);
5465 } 5519 }
5466 #endif 5520 #endif
5467 5521
5468 #ifdef __BORLANDC__ 5522 #ifdef __BORLANDC__
5469 PUGI__FN bool operator&&(const xml_attribute& lhs, bool rhs) 5523 PUGI_IMPL_FN bool operator&&(const xml_attribute& lhs, bool rhs)
5470 { 5524 {
5471 return (bool)lhs && rhs; 5525 return (bool)lhs && rhs;
5472 } 5526 }
5473 5527
5474 PUGI__FN bool operator||(const xml_attribute& lhs, bool rhs) 5528 PUGI_IMPL_FN bool operator||(const xml_attribute& lhs, bool rhs)
5475 { 5529 {
5476 return (bool)lhs || rhs; 5530 return (bool)lhs || rhs;
5477 } 5531 }
5478 #endif 5532 #endif
5479 5533
5480 PUGI__FN xml_node::xml_node(): _root(0) 5534 PUGI_IMPL_FN xml_node::xml_node(): _root(0)
5481 { 5535 {
5482 } 5536 }
5483 5537
5484 PUGI__FN xml_node::xml_node(xml_node_struct* p): _root(p) 5538 PUGI_IMPL_FN xml_node::xml_node(xml_node_struct* p): _root(p)
5485 { 5539 {
5486 } 5540 }
5487 5541
5488 PUGI__FN static void unspecified_bool_xml_node(xml_node***) 5542 PUGI_IMPL_FN static void unspecified_bool_xml_node(xml_node***)
5489 { 5543 {
5490 } 5544 }
5491 5545
5492 PUGI__FN xml_node::operator xml_node::unspecified_bool_type() const 5546 PUGI_IMPL_FN xml_node::operator xml_node::unspecified_bool_type() const
5493 { 5547 {
5494 return _root ? unspecified_bool_xml_node : 0; 5548 return _root ? unspecified_bool_xml_node : 0;
5495 } 5549 }
5496 5550
5497 PUGI__FN bool xml_node::operator!() const 5551 PUGI_IMPL_FN bool xml_node::operator!() const
5498 { 5552 {
5499 return !_root; 5553 return !_root;
5500 } 5554 }
5501 5555
5502 PUGI__FN xml_node::iterator xml_node::begin() const 5556 PUGI_IMPL_FN xml_node::iterator xml_node::begin() const
5503 { 5557 {
5504 return iterator(_root ? _root->first_child + 0 : 0, _root); 5558 return iterator(_root ? _root->first_child + 0 : 0, _root);
5505 } 5559 }
5506 5560
5507 PUGI__FN xml_node::iterator xml_node::end() const 5561 PUGI_IMPL_FN xml_node::iterator xml_node::end() const
5508 { 5562 {
5509 return iterator(0, _root); 5563 return iterator(0, _root);
5510 } 5564 }
5511 5565
5512 PUGI__FN xml_node::attribute_iterator xml_node::attributes_begin() const 5566 PUGI_IMPL_FN xml_node::attribute_iterator xml_node::attributes_begin() const
5513 { 5567 {
5514 return attribute_iterator(_root ? _root->first_attribute + 0 : 0, _root); 5568 return attribute_iterator(_root ? _root->first_attribute + 0 : 0, _root);
5515 } 5569 }
5516 5570
5517 PUGI__FN xml_node::attribute_iterator xml_node::attributes_end() const 5571 PUGI_IMPL_FN xml_node::attribute_iterator xml_node::attributes_end() const
5518 { 5572 {
5519 return attribute_iterator(0, _root); 5573 return attribute_iterator(0, _root);
5520 } 5574 }
5521 5575
5522 PUGI__FN xml_object_range<xml_node_iterator> xml_node::children() const 5576 PUGI_IMPL_FN xml_object_range<xml_node_iterator> xml_node::children() const
5523 { 5577 {
5524 return xml_object_range<xml_node_iterator>(begin(), end()); 5578 return xml_object_range<xml_node_iterator>(begin(), end());
5525 } 5579 }
5526 5580
5527 PUGI__FN xml_object_range<xml_named_node_iterator> xml_node::children(const char_t* name_) const 5581 PUGI_IMPL_FN xml_object_range<xml_named_node_iterator> xml_node::children(const char_t* name_) const
5528 { 5582 {
5529 return xml_object_range<xml_named_node_iterator>(xml_named_node_iterator(child(name_)._root, _root, name_), xml_named_node_iterator(0, _root, name_)); 5583 return xml_object_range<xml_named_node_iterator>(xml_named_node_iterator(child(name_)._root, _root, name_), xml_named_node_iterator(0, _root, name_));
5530 } 5584 }
5531 5585
5532 PUGI__FN xml_object_range<xml_attribute_iterator> xml_node::attributes() const 5586 PUGI_IMPL_FN xml_object_range<xml_attribute_iterator> xml_node::attributes() const
5533 { 5587 {
5534 return xml_object_range<xml_attribute_iterator>(attributes_begin(), attributes_end()); 5588 return xml_object_range<xml_attribute_iterator>(attributes_begin(), attributes_end());
5535 } 5589 }
5536 5590
5537 PUGI__FN bool xml_node::operator==(const xml_node& r) const 5591 PUGI_IMPL_FN bool xml_node::operator==(const xml_node& r) const
5538 { 5592 {
5539 return (_root == r._root); 5593 return (_root == r._root);
5540 } 5594 }
5541 5595
5542 PUGI__FN bool xml_node::operator!=(const xml_node& r) const 5596 PUGI_IMPL_FN bool xml_node::operator!=(const xml_node& r) const
5543 { 5597 {
5544 return (_root != r._root); 5598 return (_root != r._root);
5545 } 5599 }
5546 5600
5547 PUGI__FN bool xml_node::operator<(const xml_node& r) const 5601 PUGI_IMPL_FN bool xml_node::operator<(const xml_node& r) const
5548 { 5602 {
5549 return (_root < r._root); 5603 return (_root < r._root);
5550 } 5604 }
5551 5605
5552 PUGI__FN bool xml_node::operator>(const xml_node& r) const 5606 PUGI_IMPL_FN bool xml_node::operator>(const xml_node& r) const
5553 { 5607 {
5554 return (_root > r._root); 5608 return (_root > r._root);
5555 } 5609 }
5556 5610
5557 PUGI__FN bool xml_node::operator<=(const xml_node& r) const 5611 PUGI_IMPL_FN bool xml_node::operator<=(const xml_node& r) const
5558 { 5612 {
5559 return (_root <= r._root); 5613 return (_root <= r._root);
5560 } 5614 }
5561 5615
5562 PUGI__FN bool xml_node::operator>=(const xml_node& r) const 5616 PUGI_IMPL_FN bool xml_node::operator>=(const xml_node& r) const
5563 { 5617 {
5564 return (_root >= r._root); 5618 return (_root >= r._root);
5565 } 5619 }
5566 5620
5567 PUGI__FN bool xml_node::empty() const 5621 PUGI_IMPL_FN bool xml_node::empty() const
5568 { 5622 {
5569 return !_root; 5623 return !_root;
5570 } 5624 }
5571 5625
5572 PUGI__FN const char_t* xml_node::name() const 5626 PUGI_IMPL_FN const char_t* xml_node::name() const
5573 { 5627 {
5574 if (!_root) return PUGIXML_TEXT(""); 5628 if (!_root) return PUGIXML_TEXT("");
5575 const char_t* name = _root->name; 5629 const char_t* name = _root->name;
5576 return name ? name : PUGIXML_TEXT(""); 5630 return name ? name : PUGIXML_TEXT("");
5577 } 5631 }
5578 5632
5579 PUGI__FN xml_node_type xml_node::type() const 5633 PUGI_IMPL_FN xml_node_type xml_node::type() const
5580 { 5634 {
5581 return _root ? PUGI__NODETYPE(_root) : node_null; 5635 return _root ? PUGI_IMPL_NODETYPE(_root) : node_null;
5582 } 5636 }
5583 5637
5584 PUGI__FN const char_t* xml_node::value() const 5638 PUGI_IMPL_FN const char_t* xml_node::value() const
5585 { 5639 {
5586 if (!_root) return PUGIXML_TEXT(""); 5640 if (!_root) return PUGIXML_TEXT("");
5587 const char_t* value = _root->value; 5641 const char_t* value = _root->value;
5588 return value ? value : PUGIXML_TEXT(""); 5642 return value ? value : PUGIXML_TEXT("");
5589 } 5643 }
5590 5644
5591 PUGI__FN xml_node xml_node::child(const char_t* name_) const 5645 PUGI_IMPL_FN xml_node xml_node::child(const char_t* name_) const
5592 { 5646 {
5593 if (!_root) return xml_node(); 5647 if (!_root) return xml_node();
5594 5648
5595 for (xml_node_struct* i = _root->first_child; i; i = i->next_sibling) 5649 for (xml_node_struct* i = _root->first_child; i; i = i->next_sibling)
5596 { 5650 {
5600 } 5654 }
5601 5655
5602 return xml_node(); 5656 return xml_node();
5603 } 5657 }
5604 5658
5605 PUGI__FN xml_attribute xml_node::attribute(const char_t* name_) const 5659 PUGI_IMPL_FN xml_attribute xml_node::attribute(const char_t* name_) const
5606 { 5660 {
5607 if (!_root) return xml_attribute(); 5661 if (!_root) return xml_attribute();
5608 5662
5609 for (xml_attribute_struct* i = _root->first_attribute; i; i = i->next_attribute) 5663 for (xml_attribute_struct* i = _root->first_attribute; i; i = i->next_attribute)
5610 { 5664 {
5614 } 5668 }
5615 5669
5616 return xml_attribute(); 5670 return xml_attribute();
5617 } 5671 }
5618 5672
5619 PUGI__FN xml_node xml_node::next_sibling(const char_t* name_) const 5673 PUGI_IMPL_FN xml_node xml_node::next_sibling(const char_t* name_) const
5620 { 5674 {
5621 if (!_root) return xml_node(); 5675 if (!_root) return xml_node();
5622 5676
5623 for (xml_node_struct* i = _root->next_sibling; i; i = i->next_sibling) 5677 for (xml_node_struct* i = _root->next_sibling; i; i = i->next_sibling)
5624 { 5678 {
5628 } 5682 }
5629 5683
5630 return xml_node(); 5684 return xml_node();
5631 } 5685 }
5632 5686
5633 PUGI__FN xml_node xml_node::next_sibling() const 5687 PUGI_IMPL_FN xml_node xml_node::next_sibling() const
5634 { 5688 {
5635 return _root ? xml_node(_root->next_sibling) : xml_node(); 5689 return _root ? xml_node(_root->next_sibling) : xml_node();
5636 } 5690 }
5637 5691
5638 PUGI__FN xml_node xml_node::previous_sibling(const char_t* name_) const 5692 PUGI_IMPL_FN xml_node xml_node::previous_sibling(const char_t* name_) const
5639 { 5693 {
5640 if (!_root) return xml_node(); 5694 if (!_root) return xml_node();
5641 5695
5642 for (xml_node_struct* i = _root->prev_sibling_c; i->next_sibling; i = i->prev_sibling_c) 5696 for (xml_node_struct* i = _root->prev_sibling_c; i->next_sibling; i = i->prev_sibling_c)
5643 { 5697 {
5647 } 5701 }
5648 5702
5649 return xml_node(); 5703 return xml_node();
5650 } 5704 }
5651 5705
5652 PUGI__FN xml_attribute xml_node::attribute(const char_t* name_, xml_attribute& hint_) const 5706 PUGI_IMPL_FN xml_attribute xml_node::attribute(const char_t* name_, xml_attribute& hint_) const
5653 { 5707 {
5654 xml_attribute_struct* hint = hint_._attr; 5708 xml_attribute_struct* hint = hint_._attr;
5655 5709
5656 // if hint is not an attribute of node, behavior is not defined 5710 // if hint is not an attribute of node, behavior is not defined
5657 assert(!hint || (_root && impl::is_attribute_of(hint, _root))); 5711 assert(!hint || (_root && impl::is_attribute_of(hint, _root)));
5686 } 5740 }
5687 5741
5688 return xml_attribute(); 5742 return xml_attribute();
5689 } 5743 }
5690 5744
5691 PUGI__FN xml_node xml_node::previous_sibling() const 5745 PUGI_IMPL_FN xml_node xml_node::previous_sibling() const
5692 { 5746 {
5693 if (!_root) return xml_node(); 5747 if (!_root) return xml_node();
5694 xml_node_struct* prev = _root->prev_sibling_c; 5748 xml_node_struct* prev = _root->prev_sibling_c;
5695 return prev->next_sibling ? xml_node(prev) : xml_node(); 5749 return prev->next_sibling ? xml_node(prev) : xml_node();
5696 } 5750 }
5697 5751
5698 PUGI__FN xml_node xml_node::parent() const 5752 PUGI_IMPL_FN xml_node xml_node::parent() const
5699 { 5753 {
5700 return _root ? xml_node(_root->parent) : xml_node(); 5754 return _root ? xml_node(_root->parent) : xml_node();
5701 } 5755 }
5702 5756
5703 PUGI__FN xml_node xml_node::root() const 5757 PUGI_IMPL_FN xml_node xml_node::root() const
5704 { 5758 {
5705 return _root ? xml_node(&impl::get_document(_root)) : xml_node(); 5759 return _root ? xml_node(&impl::get_document(_root)) : xml_node();
5706 } 5760 }
5707 5761
5708 PUGI__FN xml_text xml_node::text() const 5762 PUGI_IMPL_FN xml_text xml_node::text() const
5709 { 5763 {
5710 return xml_text(_root); 5764 return xml_text(_root);
5711 } 5765 }
5712 5766
5713 PUGI__FN const char_t* xml_node::child_value() const 5767 PUGI_IMPL_FN const char_t* xml_node::child_value() const
5714 { 5768 {
5715 if (!_root) return PUGIXML_TEXT(""); 5769 if (!_root) return PUGIXML_TEXT("");
5716 5770
5717 // element nodes can have value if parse_embed_pcdata was used 5771 // element nodes can have value if parse_embed_pcdata was used
5718 if (PUGI__NODETYPE(_root) == node_element && _root->value) 5772 if (PUGI_IMPL_NODETYPE(_root) == node_element && _root->value)
5719 return _root->value; 5773 return _root->value;
5720 5774
5721 for (xml_node_struct* i = _root->first_child; i; i = i->next_sibling) 5775 for (xml_node_struct* i = _root->first_child; i; i = i->next_sibling)
5722 { 5776 {
5723 const char_t* ivalue = i->value; 5777 const char_t* ivalue = i->value;
5726 } 5780 }
5727 5781
5728 return PUGIXML_TEXT(""); 5782 return PUGIXML_TEXT("");
5729 } 5783 }
5730 5784
5731 PUGI__FN const char_t* xml_node::child_value(const char_t* name_) const 5785 PUGI_IMPL_FN const char_t* xml_node::child_value(const char_t* name_) const
5732 { 5786 {
5733 return child(name_).child_value(); 5787 return child(name_).child_value();
5734 } 5788 }
5735 5789
5736 PUGI__FN xml_attribute xml_node::first_attribute() const 5790 PUGI_IMPL_FN xml_attribute xml_node::first_attribute() const
5737 { 5791 {
5738 if (!_root) return xml_attribute(); 5792 if (!_root) return xml_attribute();
5739 return xml_attribute(_root->first_attribute); 5793 return xml_attribute(_root->first_attribute);
5740 } 5794 }
5741 5795
5742 PUGI__FN xml_attribute xml_node::last_attribute() const 5796 PUGI_IMPL_FN xml_attribute xml_node::last_attribute() const
5743 { 5797 {
5744 if (!_root) return xml_attribute(); 5798 if (!_root) return xml_attribute();
5745 xml_attribute_struct* first = _root->first_attribute; 5799 xml_attribute_struct* first = _root->first_attribute;
5746 return first ? xml_attribute(first->prev_attribute_c) : xml_attribute(); 5800 return first ? xml_attribute(first->prev_attribute_c) : xml_attribute();
5747 } 5801 }
5748 5802
5749 PUGI__FN xml_node xml_node::first_child() const 5803 PUGI_IMPL_FN xml_node xml_node::first_child() const
5750 { 5804 {
5751 if (!_root) return xml_node(); 5805 if (!_root) return xml_node();
5752 return xml_node(_root->first_child); 5806 return xml_node(_root->first_child);
5753 } 5807 }
5754 5808
5755 PUGI__FN xml_node xml_node::last_child() const 5809 PUGI_IMPL_FN xml_node xml_node::last_child() const
5756 { 5810 {
5757 if (!_root) return xml_node(); 5811 if (!_root) return xml_node();
5758 xml_node_struct* first = _root->first_child; 5812 xml_node_struct* first = _root->first_child;
5759 return first ? xml_node(first->prev_sibling_c) : xml_node(); 5813 return first ? xml_node(first->prev_sibling_c) : xml_node();
5760 } 5814 }
5761 5815
5762 PUGI__FN bool xml_node::set_name(const char_t* rhs) 5816 PUGI_IMPL_FN bool xml_node::set_name(const char_t* rhs)
5763 { 5817 {
5764 xml_node_type type_ = _root ? PUGI__NODETYPE(_root) : node_null; 5818 xml_node_type type_ = _root ? PUGI_IMPL_NODETYPE(_root) : node_null;
5765 5819
5766 if (type_ != node_element && type_ != node_pi && type_ != node_declaration) 5820 if (type_ != node_element && type_ != node_pi && type_ != node_declaration)
5767 return false; 5821 return false;
5768 5822
5769 return impl::strcpy_insitu(_root->name, _root->header, impl::xml_memory_page_name_allocated_mask, rhs, impl::strlength(rhs)); 5823 return impl::strcpy_insitu(_root->name, _root->header, impl::xml_memory_page_name_allocated_mask, rhs, impl::strlength(rhs));
5770 } 5824 }
5771 5825
5772 PUGI__FN bool xml_node::set_value(const char_t* rhs, size_t sz) 5826 PUGI_IMPL_FN bool xml_node::set_name(const char_t* rhs, size_t size)
5773 { 5827 {
5774 xml_node_type type_ = _root ? PUGI__NODETYPE(_root) : node_null; 5828 xml_node_type type_ = _root ? PUGI_IMPL_NODETYPE(_root) : node_null;
5829
5830 if (type_ != node_element && type_ != node_pi && type_ != node_declaration)
5831 return false;
5832
5833 return impl::strcpy_insitu(_root->name, _root->header, impl::xml_memory_page_name_allocated_mask, rhs, size);
5834 }
5835
5836 PUGI_IMPL_FN bool xml_node::set_value(const char_t* rhs)
5837 {
5838 xml_node_type type_ = _root ? PUGI_IMPL_NODETYPE(_root) : node_null;
5775 5839
5776 if (type_ != node_pcdata && type_ != node_cdata && type_ != node_comment && type_ != node_pi && type_ != node_doctype) 5840 if (type_ != node_pcdata && type_ != node_cdata && type_ != node_comment && type_ != node_pi && type_ != node_doctype)
5777 return false; 5841 return false;
5778 5842
5779 return impl::strcpy_insitu(_root->value, _root->header, impl::xml_memory_page_value_allocated_mask, rhs, sz); 5843 return impl::strcpy_insitu(_root->value, _root->header, impl::xml_memory_page_value_allocated_mask, rhs, impl::strlength(rhs));
5780 } 5844 }
5781 5845
5782 PUGI__FN bool xml_node::set_value(const char_t* rhs) 5846 PUGI_IMPL_FN bool xml_node::set_value(const char_t* rhs, size_t size)
5783 { 5847 {
5784 xml_node_type type_ = _root ? PUGI__NODETYPE(_root) : node_null; 5848 xml_node_type type_ = _root ? PUGI_IMPL_NODETYPE(_root) : node_null;
5785 5849
5786 if (type_ != node_pcdata && type_ != node_cdata && type_ != node_comment && type_ != node_pi && type_ != node_doctype) 5850 if (type_ != node_pcdata && type_ != node_cdata && type_ != node_comment && type_ != node_pi && type_ != node_doctype)
5787 return false; 5851 return false;
5788 5852
5789 return impl::strcpy_insitu(_root->value, _root->header, impl::xml_memory_page_value_allocated_mask, rhs, impl::strlength(rhs)); 5853 return impl::strcpy_insitu(_root->value, _root->header, impl::xml_memory_page_value_allocated_mask, rhs, size);
5790 } 5854 }
5791 5855
5792 PUGI__FN xml_attribute xml_node::append_attribute(const char_t* name_) 5856 PUGI_IMPL_FN xml_attribute xml_node::append_attribute(const char_t* name_)
5793 { 5857 {
5794 if (!impl::allow_insert_attribute(type())) return xml_attribute(); 5858 if (!impl::allow_insert_attribute(type())) return xml_attribute();
5795 5859
5796 impl::xml_allocator& alloc = impl::get_allocator(_root); 5860 impl::xml_allocator& alloc = impl::get_allocator(_root);
5797 if (!alloc.reserve()) return xml_attribute(); 5861 if (!alloc.reserve()) return xml_attribute();
5804 a.set_name(name_); 5868 a.set_name(name_);
5805 5869
5806 return a; 5870 return a;
5807 } 5871 }
5808 5872
5809 PUGI__FN xml_attribute xml_node::prepend_attribute(const char_t* name_) 5873 PUGI_IMPL_FN xml_attribute xml_node::prepend_attribute(const char_t* name_)
5810 { 5874 {
5811 if (!impl::allow_insert_attribute(type())) return xml_attribute(); 5875 if (!impl::allow_insert_attribute(type())) return xml_attribute();
5812 5876
5813 impl::xml_allocator& alloc = impl::get_allocator(_root); 5877 impl::xml_allocator& alloc = impl::get_allocator(_root);
5814 if (!alloc.reserve()) return xml_attribute(); 5878 if (!alloc.reserve()) return xml_attribute();
5821 a.set_name(name_); 5885 a.set_name(name_);
5822 5886
5823 return a; 5887 return a;
5824 } 5888 }
5825 5889
5826 PUGI__FN xml_attribute xml_node::insert_attribute_after(const char_t* name_, const xml_attribute& attr) 5890 PUGI_IMPL_FN xml_attribute xml_node::insert_attribute_after(const char_t* name_, const xml_attribute& attr)
5827 { 5891 {
5828 if (!impl::allow_insert_attribute(type())) return xml_attribute(); 5892 if (!impl::allow_insert_attribute(type())) return xml_attribute();
5829 if (!attr || !impl::is_attribute_of(attr._attr, _root)) return xml_attribute(); 5893 if (!attr || !impl::is_attribute_of(attr._attr, _root)) return xml_attribute();
5830 5894
5831 impl::xml_allocator& alloc = impl::get_allocator(_root); 5895 impl::xml_allocator& alloc = impl::get_allocator(_root);
5839 a.set_name(name_); 5903 a.set_name(name_);
5840 5904
5841 return a; 5905 return a;
5842 } 5906 }
5843 5907
5844 PUGI__FN xml_attribute xml_node::insert_attribute_before(const char_t* name_, const xml_attribute& attr) 5908 PUGI_IMPL_FN xml_attribute xml_node::insert_attribute_before(const char_t* name_, const xml_attribute& attr)
5845 { 5909 {
5846 if (!impl::allow_insert_attribute(type())) return xml_attribute(); 5910 if (!impl::allow_insert_attribute(type())) return xml_attribute();
5847 if (!attr || !impl::is_attribute_of(attr._attr, _root)) return xml_attribute(); 5911 if (!attr || !impl::is_attribute_of(attr._attr, _root)) return xml_attribute();
5848 5912
5849 impl::xml_allocator& alloc = impl::get_allocator(_root); 5913 impl::xml_allocator& alloc = impl::get_allocator(_root);
5857 a.set_name(name_); 5921 a.set_name(name_);
5858 5922
5859 return a; 5923 return a;
5860 } 5924 }
5861 5925
5862 PUGI__FN xml_attribute xml_node::append_copy(const xml_attribute& proto) 5926 PUGI_IMPL_FN xml_attribute xml_node::append_copy(const xml_attribute& proto)
5863 { 5927 {
5864 if (!proto) return xml_attribute(); 5928 if (!proto) return xml_attribute();
5865 if (!impl::allow_insert_attribute(type())) return xml_attribute(); 5929 if (!impl::allow_insert_attribute(type())) return xml_attribute();
5866 5930
5867 impl::xml_allocator& alloc = impl::get_allocator(_root); 5931 impl::xml_allocator& alloc = impl::get_allocator(_root);
5874 impl::node_copy_attribute(a._attr, proto._attr); 5938 impl::node_copy_attribute(a._attr, proto._attr);
5875 5939
5876 return a; 5940 return a;
5877 } 5941 }
5878 5942
5879 PUGI__FN xml_attribute xml_node::prepend_copy(const xml_attribute& proto) 5943 PUGI_IMPL_FN xml_attribute xml_node::prepend_copy(const xml_attribute& proto)
5880 { 5944 {
5881 if (!proto) return xml_attribute(); 5945 if (!proto) return xml_attribute();
5882 if (!impl::allow_insert_attribute(type())) return xml_attribute(); 5946 if (!impl::allow_insert_attribute(type())) return xml_attribute();
5883 5947
5884 impl::xml_allocator& alloc = impl::get_allocator(_root); 5948 impl::xml_allocator& alloc = impl::get_allocator(_root);
5891 impl::node_copy_attribute(a._attr, proto._attr); 5955 impl::node_copy_attribute(a._attr, proto._attr);
5892 5956
5893 return a; 5957 return a;
5894 } 5958 }
5895 5959
5896 PUGI__FN xml_attribute xml_node::insert_copy_after(const xml_attribute& proto, const xml_attribute& attr) 5960 PUGI_IMPL_FN xml_attribute xml_node::insert_copy_after(const xml_attribute& proto, const xml_attribute& attr)
5897 { 5961 {
5898 if (!proto) return xml_attribute(); 5962 if (!proto) return xml_attribute();
5899 if (!impl::allow_insert_attribute(type())) return xml_attribute(); 5963 if (!impl::allow_insert_attribute(type())) return xml_attribute();
5900 if (!attr || !impl::is_attribute_of(attr._attr, _root)) return xml_attribute(); 5964 if (!attr || !impl::is_attribute_of(attr._attr, _root)) return xml_attribute();
5901 5965
5909 impl::node_copy_attribute(a._attr, proto._attr); 5973 impl::node_copy_attribute(a._attr, proto._attr);
5910 5974
5911 return a; 5975 return a;
5912 } 5976 }
5913 5977
5914 PUGI__FN xml_attribute xml_node::insert_copy_before(const xml_attribute& proto, const xml_attribute& attr) 5978 PUGI_IMPL_FN xml_attribute xml_node::insert_copy_before(const xml_attribute& proto, const xml_attribute& attr)
5915 { 5979 {
5916 if (!proto) return xml_attribute(); 5980 if (!proto) return xml_attribute();
5917 if (!impl::allow_insert_attribute(type())) return xml_attribute(); 5981 if (!impl::allow_insert_attribute(type())) return xml_attribute();
5918 if (!attr || !impl::is_attribute_of(attr._attr, _root)) return xml_attribute(); 5982 if (!attr || !impl::is_attribute_of(attr._attr, _root)) return xml_attribute();
5919 5983
5927 impl::node_copy_attribute(a._attr, proto._attr); 5991 impl::node_copy_attribute(a._attr, proto._attr);
5928 5992
5929 return a; 5993 return a;
5930 } 5994 }
5931 5995
5932 PUGI__FN xml_node xml_node::append_child(xml_node_type type_) 5996 PUGI_IMPL_FN xml_node xml_node::append_child(xml_node_type type_)
5933 { 5997 {
5934 if (!impl::allow_insert_child(type(), type_)) return xml_node(); 5998 if (!impl::allow_insert_child(type(), type_)) return xml_node();
5935 5999
5936 impl::xml_allocator& alloc = impl::get_allocator(_root); 6000 impl::xml_allocator& alloc = impl::get_allocator(_root);
5937 if (!alloc.reserve()) return xml_node(); 6001 if (!alloc.reserve()) return xml_node();
5944 if (type_ == node_declaration) n.set_name(PUGIXML_TEXT("xml")); 6008 if (type_ == node_declaration) n.set_name(PUGIXML_TEXT("xml"));
5945 6009
5946 return n; 6010 return n;
5947 } 6011 }
5948 6012
5949 PUGI__FN xml_node xml_node::prepend_child(xml_node_type type_) 6013 PUGI_IMPL_FN xml_node xml_node::prepend_child(xml_node_type type_)
5950 { 6014 {
5951 if (!impl::allow_insert_child(type(), type_)) return xml_node(); 6015 if (!impl::allow_insert_child(type(), type_)) return xml_node();
5952 6016
5953 impl::xml_allocator& alloc = impl::get_allocator(_root); 6017 impl::xml_allocator& alloc = impl::get_allocator(_root);
5954 if (!alloc.reserve()) return xml_node(); 6018 if (!alloc.reserve()) return xml_node();
5961 if (type_ == node_declaration) n.set_name(PUGIXML_TEXT("xml")); 6025 if (type_ == node_declaration) n.set_name(PUGIXML_TEXT("xml"));
5962 6026
5963 return n; 6027 return n;
5964 } 6028 }
5965 6029
5966 PUGI__FN xml_node xml_node::insert_child_before(xml_node_type type_, const xml_node& node) 6030 PUGI_IMPL_FN xml_node xml_node::insert_child_before(xml_node_type type_, const xml_node& node)
5967 { 6031 {
5968 if (!impl::allow_insert_child(type(), type_)) return xml_node(); 6032 if (!impl::allow_insert_child(type(), type_)) return xml_node();
5969 if (!node._root || node._root->parent != _root) return xml_node(); 6033 if (!node._root || node._root->parent != _root) return xml_node();
5970 6034
5971 impl::xml_allocator& alloc = impl::get_allocator(_root); 6035 impl::xml_allocator& alloc = impl::get_allocator(_root);
5979 if (type_ == node_declaration) n.set_name(PUGIXML_TEXT("xml")); 6043 if (type_ == node_declaration) n.set_name(PUGIXML_TEXT("xml"));
5980 6044
5981 return n; 6045 return n;
5982 } 6046 }
5983 6047
5984 PUGI__FN xml_node xml_node::insert_child_after(xml_node_type type_, const xml_node& node) 6048 PUGI_IMPL_FN xml_node xml_node::insert_child_after(xml_node_type type_, const xml_node& node)
5985 { 6049 {
5986 if (!impl::allow_insert_child(type(), type_)) return xml_node(); 6050 if (!impl::allow_insert_child(type(), type_)) return xml_node();
5987 if (!node._root || node._root->parent != _root) return xml_node(); 6051 if (!node._root || node._root->parent != _root) return xml_node();
5988 6052
5989 impl::xml_allocator& alloc = impl::get_allocator(_root); 6053 impl::xml_allocator& alloc = impl::get_allocator(_root);
5997 if (type_ == node_declaration) n.set_name(PUGIXML_TEXT("xml")); 6061 if (type_ == node_declaration) n.set_name(PUGIXML_TEXT("xml"));
5998 6062
5999 return n; 6063 return n;
6000 } 6064 }
6001 6065
6002 PUGI__FN xml_node xml_node::append_child(const char_t* name_) 6066 PUGI_IMPL_FN xml_node xml_node::append_child(const char_t* name_)
6003 { 6067 {
6004 xml_node result = append_child(node_element); 6068 xml_node result = append_child(node_element);
6005 6069
6006 result.set_name(name_); 6070 result.set_name(name_);
6007 6071
6008 return result; 6072 return result;
6009 } 6073 }
6010 6074
6011 PUGI__FN xml_node xml_node::prepend_child(const char_t* name_) 6075 PUGI_IMPL_FN xml_node xml_node::prepend_child(const char_t* name_)
6012 { 6076 {
6013 xml_node result = prepend_child(node_element); 6077 xml_node result = prepend_child(node_element);
6014 6078
6015 result.set_name(name_); 6079 result.set_name(name_);
6016 6080
6017 return result; 6081 return result;
6018 } 6082 }
6019 6083
6020 PUGI__FN xml_node xml_node::insert_child_after(const char_t* name_, const xml_node& node) 6084 PUGI_IMPL_FN xml_node xml_node::insert_child_after(const char_t* name_, const xml_node& node)
6021 { 6085 {
6022 xml_node result = insert_child_after(node_element, node); 6086 xml_node result = insert_child_after(node_element, node);
6023 6087
6024 result.set_name(name_); 6088 result.set_name(name_);
6025 6089
6026 return result; 6090 return result;
6027 } 6091 }
6028 6092
6029 PUGI__FN xml_node xml_node::insert_child_before(const char_t* name_, const xml_node& node) 6093 PUGI_IMPL_FN xml_node xml_node::insert_child_before(const char_t* name_, const xml_node& node)
6030 { 6094 {
6031 xml_node result = insert_child_before(node_element, node); 6095 xml_node result = insert_child_before(node_element, node);
6032 6096
6033 result.set_name(name_); 6097 result.set_name(name_);
6034 6098
6035 return result; 6099 return result;
6036 } 6100 }
6037 6101
6038 PUGI__FN xml_node xml_node::append_copy(const xml_node& proto) 6102 PUGI_IMPL_FN xml_node xml_node::append_copy(const xml_node& proto)
6039 { 6103 {
6040 xml_node_type type_ = proto.type(); 6104 xml_node_type type_ = proto.type();
6041 if (!impl::allow_insert_child(type(), type_)) return xml_node(); 6105 if (!impl::allow_insert_child(type(), type_)) return xml_node();
6042 6106
6043 impl::xml_allocator& alloc = impl::get_allocator(_root); 6107 impl::xml_allocator& alloc = impl::get_allocator(_root);
6050 impl::node_copy_tree(n._root, proto._root); 6114 impl::node_copy_tree(n._root, proto._root);
6051 6115
6052 return n; 6116 return n;
6053 } 6117 }
6054 6118
6055 PUGI__FN xml_node xml_node::prepend_copy(const xml_node& proto) 6119 PUGI_IMPL_FN xml_node xml_node::prepend_copy(const xml_node& proto)
6056 { 6120 {
6057 xml_node_type type_ = proto.type(); 6121 xml_node_type type_ = proto.type();
6058 if (!impl::allow_insert_child(type(), type_)) return xml_node(); 6122 if (!impl::allow_insert_child(type(), type_)) return xml_node();
6059 6123
6060 impl::xml_allocator& alloc = impl::get_allocator(_root); 6124 impl::xml_allocator& alloc = impl::get_allocator(_root);
6067 impl::node_copy_tree(n._root, proto._root); 6131 impl::node_copy_tree(n._root, proto._root);
6068 6132
6069 return n; 6133 return n;
6070 } 6134 }
6071 6135
6072 PUGI__FN xml_node xml_node::insert_copy_after(const xml_node& proto, const xml_node& node) 6136 PUGI_IMPL_FN xml_node xml_node::insert_copy_after(const xml_node& proto, const xml_node& node)
6073 { 6137 {
6074 xml_node_type type_ = proto.type(); 6138 xml_node_type type_ = proto.type();
6075 if (!impl::allow_insert_child(type(), type_)) return xml_node(); 6139 if (!impl::allow_insert_child(type(), type_)) return xml_node();
6076 if (!node._root || node._root->parent != _root) return xml_node(); 6140 if (!node._root || node._root->parent != _root) return xml_node();
6077 6141
6085 impl::node_copy_tree(n._root, proto._root); 6149 impl::node_copy_tree(n._root, proto._root);
6086 6150
6087 return n; 6151 return n;
6088 } 6152 }
6089 6153
6090 PUGI__FN xml_node xml_node::insert_copy_before(const xml_node& proto, const xml_node& node) 6154 PUGI_IMPL_FN xml_node xml_node::insert_copy_before(const xml_node& proto, const xml_node& node)
6091 { 6155 {
6092 xml_node_type type_ = proto.type(); 6156 xml_node_type type_ = proto.type();
6093 if (!impl::allow_insert_child(type(), type_)) return xml_node(); 6157 if (!impl::allow_insert_child(type(), type_)) return xml_node();
6094 if (!node._root || node._root->parent != _root) return xml_node(); 6158 if (!node._root || node._root->parent != _root) return xml_node();
6095 6159
6103 impl::node_copy_tree(n._root, proto._root); 6167 impl::node_copy_tree(n._root, proto._root);
6104 6168
6105 return n; 6169 return n;
6106 } 6170 }
6107 6171
6108 PUGI__FN xml_node xml_node::append_move(const xml_node& moved) 6172 PUGI_IMPL_FN xml_node xml_node::append_move(const xml_node& moved)
6109 { 6173 {
6110 if (!impl::allow_move(*this, moved)) return xml_node(); 6174 if (!impl::allow_move(*this, moved)) return xml_node();
6111 6175
6112 impl::xml_allocator& alloc = impl::get_allocator(_root); 6176 impl::xml_allocator& alloc = impl::get_allocator(_root);
6113 if (!alloc.reserve()) return xml_node(); 6177 if (!alloc.reserve()) return xml_node();
6119 impl::append_node(moved._root, _root); 6183 impl::append_node(moved._root, _root);
6120 6184
6121 return moved; 6185 return moved;
6122 } 6186 }
6123 6187
6124 PUGI__FN xml_node xml_node::prepend_move(const xml_node& moved) 6188 PUGI_IMPL_FN xml_node xml_node::prepend_move(const xml_node& moved)
6125 { 6189 {
6126 if (!impl::allow_move(*this, moved)) return xml_node(); 6190 if (!impl::allow_move(*this, moved)) return xml_node();
6127 6191
6128 impl::xml_allocator& alloc = impl::get_allocator(_root); 6192 impl::xml_allocator& alloc = impl::get_allocator(_root);
6129 if (!alloc.reserve()) return xml_node(); 6193 if (!alloc.reserve()) return xml_node();
6135 impl::prepend_node(moved._root, _root); 6199 impl::prepend_node(moved._root, _root);
6136 6200
6137 return moved; 6201 return moved;
6138 } 6202 }
6139 6203
6140 PUGI__FN xml_node xml_node::insert_move_after(const xml_node& moved, const xml_node& node) 6204 PUGI_IMPL_FN xml_node xml_node::insert_move_after(const xml_node& moved, const xml_node& node)
6141 { 6205 {
6142 if (!impl::allow_move(*this, moved)) return xml_node(); 6206 if (!impl::allow_move(*this, moved)) return xml_node();
6143 if (!node._root || node._root->parent != _root) return xml_node(); 6207 if (!node._root || node._root->parent != _root) return xml_node();
6144 if (moved._root == node._root) return xml_node(); 6208 if (moved._root == node._root) return xml_node();
6145 6209
6153 impl::insert_node_after(moved._root, node._root); 6217 impl::insert_node_after(moved._root, node._root);
6154 6218
6155 return moved; 6219 return moved;
6156 } 6220 }
6157 6221
6158 PUGI__FN xml_node xml_node::insert_move_before(const xml_node& moved, const xml_node& node) 6222 PUGI_IMPL_FN xml_node xml_node::insert_move_before(const xml_node& moved, const xml_node& node)
6159 { 6223 {
6160 if (!impl::allow_move(*this, moved)) return xml_node(); 6224 if (!impl::allow_move(*this, moved)) return xml_node();
6161 if (!node._root || node._root->parent != _root) return xml_node(); 6225 if (!node._root || node._root->parent != _root) return xml_node();
6162 if (moved._root == node._root) return xml_node(); 6226 if (moved._root == node._root) return xml_node();
6163 6227
6171 impl::insert_node_before(moved._root, node._root); 6235 impl::insert_node_before(moved._root, node._root);
6172 6236
6173 return moved; 6237 return moved;
6174 } 6238 }
6175 6239
6176 PUGI__FN bool xml_node::remove_attribute(const char_t* name_) 6240 PUGI_IMPL_FN bool xml_node::remove_attribute(const char_t* name_)
6177 { 6241 {
6178 return remove_attribute(attribute(name_)); 6242 return remove_attribute(attribute(name_));
6179 } 6243 }
6180 6244
6181 PUGI__FN bool xml_node::remove_attribute(const xml_attribute& a) 6245 PUGI_IMPL_FN bool xml_node::remove_attribute(const xml_attribute& a)
6182 { 6246 {
6183 if (!_root || !a._attr) return false; 6247 if (!_root || !a._attr) return false;
6184 if (!impl::is_attribute_of(a._attr, _root)) return false; 6248 if (!impl::is_attribute_of(a._attr, _root)) return false;
6185 6249
6186 impl::xml_allocator& alloc = impl::get_allocator(_root); 6250 impl::xml_allocator& alloc = impl::get_allocator(_root);
6190 impl::destroy_attribute(a._attr, alloc); 6254 impl::destroy_attribute(a._attr, alloc);
6191 6255
6192 return true; 6256 return true;
6193 } 6257 }
6194 6258
6195 PUGI__FN bool xml_node::remove_attributes() 6259 PUGI_IMPL_FN bool xml_node::remove_attributes()
6196 { 6260 {
6197 if (!_root) return false; 6261 if (!_root) return false;
6198 6262
6199 impl::xml_allocator& alloc = impl::get_allocator(_root); 6263 impl::xml_allocator& alloc = impl::get_allocator(_root);
6200 if (!alloc.reserve()) return false; 6264 if (!alloc.reserve()) return false;
6211 _root->first_attribute = 0; 6275 _root->first_attribute = 0;
6212 6276
6213 return true; 6277 return true;
6214 } 6278 }
6215 6279
6216 PUGI__FN bool xml_node::remove_child(const char_t* name_) 6280 PUGI_IMPL_FN bool xml_node::remove_child(const char_t* name_)
6217 { 6281 {
6218 return remove_child(child(name_)); 6282 return remove_child(child(name_));
6219 } 6283 }
6220 6284
6221 PUGI__FN bool xml_node::remove_child(const xml_node& n) 6285 PUGI_IMPL_FN bool xml_node::remove_child(const xml_node& n)
6222 { 6286 {
6223 if (!_root || !n._root || n._root->parent != _root) return false; 6287 if (!_root || !n._root || n._root->parent != _root) return false;
6224 6288
6225 impl::xml_allocator& alloc = impl::get_allocator(_root); 6289 impl::xml_allocator& alloc = impl::get_allocator(_root);
6226 if (!alloc.reserve()) return false; 6290 if (!alloc.reserve()) return false;
6229 impl::destroy_node(n._root, alloc); 6293 impl::destroy_node(n._root, alloc);
6230 6294
6231 return true; 6295 return true;
6232 } 6296 }
6233 6297
6234 PUGI__FN bool xml_node::remove_children() 6298 PUGI_IMPL_FN bool xml_node::remove_children()
6235 { 6299 {
6236 if (!_root) return false; 6300 if (!_root) return false;
6237 6301
6238 impl::xml_allocator& alloc = impl::get_allocator(_root); 6302 impl::xml_allocator& alloc = impl::get_allocator(_root);
6239 if (!alloc.reserve()) return false; 6303 if (!alloc.reserve()) return false;
6250 _root->first_child = 0; 6314 _root->first_child = 0;
6251 6315
6252 return true; 6316 return true;
6253 } 6317 }
6254 6318
6255 PUGI__FN xml_parse_result xml_node::append_buffer(const void* contents, size_t size, unsigned int options, xml_encoding encoding) 6319 PUGI_IMPL_FN xml_parse_result xml_node::append_buffer(const void* contents, size_t size, unsigned int options, xml_encoding encoding)
6256 { 6320 {
6257 // append_buffer is only valid for elements/documents 6321 // append_buffer is only valid for elements/documents
6258 if (!impl::allow_insert_child(type(), node_element)) return impl::make_parse_result(status_append_invalid_root); 6322 if (!impl::allow_insert_child(type(), node_element)) return impl::make_parse_result(status_append_invalid_root);
6323
6324 // append buffer can not merge PCDATA into existing PCDATA nodes
6325 if ((options & parse_merge_pcdata) != 0 && last_child().type() == node_pcdata) return impl::make_parse_result(status_append_invalid_root);
6259 6326
6260 // get document node 6327 // get document node
6261 impl::xml_document_struct* doc = &impl::get_document(_root); 6328 impl::xml_document_struct* doc = &impl::get_document(_root);
6262 6329
6263 // disable document_buffer_order optimization since in a document with multiple buffers comparing buffer pointers does not make sense 6330 // disable document_buffer_order optimization since in a document with multiple buffers comparing buffer pointers does not make sense
6285 impl::name_null_sentry sentry(_root); 6352 impl::name_null_sentry sentry(_root);
6286 6353
6287 return impl::load_buffer_impl(doc, _root, const_cast<void*>(contents), size, options, encoding, false, false, &extra->buffer); 6354 return impl::load_buffer_impl(doc, _root, const_cast<void*>(contents), size, options, encoding, false, false, &extra->buffer);
6288 } 6355 }
6289 6356
6290 PUGI__FN xml_node xml_node::find_child_by_attribute(const char_t* name_, const char_t* attr_name, const char_t* attr_value) const 6357 PUGI_IMPL_FN xml_node xml_node::find_child_by_attribute(const char_t* name_, const char_t* attr_name, const char_t* attr_value) const
6291 { 6358 {
6292 if (!_root) return xml_node(); 6359 if (!_root) return xml_node();
6293 6360
6294 for (xml_node_struct* i = _root->first_child; i; i = i->next_sibling) 6361 for (xml_node_struct* i = _root->first_child; i; i = i->next_sibling)
6295 { 6362 {
6310 } 6377 }
6311 6378
6312 return xml_node(); 6379 return xml_node();
6313 } 6380 }
6314 6381
6315 PUGI__FN xml_node xml_node::find_child_by_attribute(const char_t* attr_name, const char_t* attr_value) const 6382 PUGI_IMPL_FN xml_node xml_node::find_child_by_attribute(const char_t* attr_name, const char_t* attr_value) const
6316 { 6383 {
6317 if (!_root) return xml_node(); 6384 if (!_root) return xml_node();
6318 6385
6319 for (xml_node_struct* i = _root->first_child; i; i = i->next_sibling) 6386 for (xml_node_struct* i = _root->first_child; i; i = i->next_sibling)
6320 for (xml_attribute_struct* a = i->first_attribute; a; a = a->next_attribute) 6387 for (xml_attribute_struct* a = i->first_attribute; a; a = a->next_attribute)
6330 6397
6331 return xml_node(); 6398 return xml_node();
6332 } 6399 }
6333 6400
6334 #ifndef PUGIXML_NO_STL 6401 #ifndef PUGIXML_NO_STL
6335 PUGI__FN string_t xml_node::path(char_t delimiter) const 6402 PUGI_IMPL_FN string_t xml_node::path(char_t delimiter) const
6336 { 6403 {
6337 if (!_root) return string_t(); 6404 if (!_root) return string_t();
6338 6405
6339 size_t offset = 0; 6406 size_t offset = 0;
6340 6407
6367 6434
6368 return result; 6435 return result;
6369 } 6436 }
6370 #endif 6437 #endif
6371 6438
6372 PUGI__FN xml_node xml_node::first_element_by_path(const char_t* path_, char_t delimiter) const 6439 PUGI_IMPL_FN xml_node xml_node::first_element_by_path(const char_t* path_, char_t delimiter) const
6373 { 6440 {
6374 xml_node context = path_[0] == delimiter ? root() : *this; 6441 xml_node context = path_[0] == delimiter ? root() : *this;
6375 6442
6376 if (!context._root) return xml_node(); 6443 if (!context._root) return xml_node();
6377 6444
6408 6475
6409 return xml_node(); 6476 return xml_node();
6410 } 6477 }
6411 } 6478 }
6412 6479
6413 PUGI__FN bool xml_node::traverse(xml_tree_walker& walker) 6480 PUGI_IMPL_FN bool xml_node::traverse(xml_tree_walker& walker)
6414 { 6481 {
6415 walker._depth = -1; 6482 walker._depth = -1;
6416 6483
6417 xml_node arg_begin(_root); 6484 xml_node arg_begin(_root);
6418 if (!walker.begin(arg_begin)) return false; 6485 if (!walker.begin(arg_begin)) return false;
6455 6522
6456 xml_node arg_end(_root); 6523 xml_node arg_end(_root);
6457 return walker.end(arg_end); 6524 return walker.end(arg_end);
6458 } 6525 }
6459 6526
6460 PUGI__FN size_t xml_node::hash_value() const 6527 PUGI_IMPL_FN size_t xml_node::hash_value() const
6461 { 6528 {
6462 return static_cast<size_t>(reinterpret_cast<uintptr_t>(_root) / sizeof(xml_node_struct)); 6529 return static_cast<size_t>(reinterpret_cast<uintptr_t>(_root) / sizeof(xml_node_struct));
6463 } 6530 }
6464 6531
6465 PUGI__FN xml_node_struct* xml_node::internal_object() const 6532 PUGI_IMPL_FN xml_node_struct* xml_node::internal_object() const
6466 { 6533 {
6467 return _root; 6534 return _root;
6468 } 6535 }
6469 6536
6470 PUGI__FN void xml_node::print(xml_writer& writer, const char_t* indent, unsigned int flags, xml_encoding encoding, unsigned int depth) const 6537 PUGI_IMPL_FN void xml_node::print(xml_writer& writer, const char_t* indent, unsigned int flags, xml_encoding encoding, unsigned int depth) const
6471 { 6538 {
6472 if (!_root) return; 6539 if (!_root) return;
6473 6540
6474 impl::xml_buffered_writer buffered_writer(writer, encoding); 6541 impl::xml_buffered_writer buffered_writer(writer, encoding);
6475 6542
6477 6544
6478 buffered_writer.flush(); 6545 buffered_writer.flush();
6479 } 6546 }
6480 6547
6481 #ifndef PUGIXML_NO_STL 6548 #ifndef PUGIXML_NO_STL
6482 PUGI__FN void xml_node::print(std::basic_ostream<char, std::char_traits<char> >& stream, const char_t* indent, unsigned int flags, xml_encoding encoding, unsigned int depth) const 6549 PUGI_IMPL_FN void xml_node::print(std::basic_ostream<char, std::char_traits<char> >& stream, const char_t* indent, unsigned int flags, xml_encoding encoding, unsigned int depth) const
6483 { 6550 {
6484 xml_writer_stream writer(stream); 6551 xml_writer_stream writer(stream);
6485 6552
6486 print(writer, indent, flags, encoding, depth); 6553 print(writer, indent, flags, encoding, depth);
6487 } 6554 }
6488 6555
6489 PUGI__FN void xml_node::print(std::basic_ostream<wchar_t, std::char_traits<wchar_t> >& stream, const char_t* indent, unsigned int flags, unsigned int depth) const 6556 PUGI_IMPL_FN void xml_node::print(std::basic_ostream<wchar_t, std::char_traits<wchar_t> >& stream, const char_t* indent, unsigned int flags, unsigned int depth) const
6490 { 6557 {
6491 xml_writer_stream writer(stream); 6558 xml_writer_stream writer(stream);
6492 6559
6493 print(writer, indent, flags, encoding_wchar, depth); 6560 print(writer, indent, flags, encoding_wchar, depth);
6494 } 6561 }
6495 #endif 6562 #endif
6496 6563
6497 PUGI__FN ptrdiff_t xml_node::offset_debug() const 6564 PUGI_IMPL_FN ptrdiff_t xml_node::offset_debug() const
6498 { 6565 {
6499 if (!_root) return -1; 6566 if (!_root) return -1;
6500 6567
6501 impl::xml_document_struct& doc = impl::get_document(_root); 6568 impl::xml_document_struct& doc = impl::get_document(_root);
6502 6569
6524 return -1; 6591 return -1;
6525 } 6592 }
6526 } 6593 }
6527 6594
6528 #ifdef __BORLANDC__ 6595 #ifdef __BORLANDC__
6529 PUGI__FN bool operator&&(const xml_node& lhs, bool rhs) 6596 PUGI_IMPL_FN bool operator&&(const xml_node& lhs, bool rhs)
6530 { 6597 {
6531 return (bool)lhs && rhs; 6598 return (bool)lhs && rhs;
6532 } 6599 }
6533 6600
6534 PUGI__FN bool operator||(const xml_node& lhs, bool rhs) 6601 PUGI_IMPL_FN bool operator||(const xml_node& lhs, bool rhs)
6535 { 6602 {
6536 return (bool)lhs || rhs; 6603 return (bool)lhs || rhs;
6537 } 6604 }
6538 #endif 6605 #endif
6539 6606
6540 PUGI__FN xml_text::xml_text(xml_node_struct* root): _root(root) 6607 PUGI_IMPL_FN xml_text::xml_text(xml_node_struct* root): _root(root)
6541 { 6608 {
6542 } 6609 }
6543 6610
6544 PUGI__FN xml_node_struct* xml_text::_data() const 6611 PUGI_IMPL_FN xml_node_struct* xml_text::_data() const
6545 { 6612 {
6546 if (!_root || impl::is_text_node(_root)) return _root; 6613 if (!_root || impl::is_text_node(_root)) return _root;
6547 6614
6548 // element nodes can have value if parse_embed_pcdata was used 6615 // element nodes can have value if parse_embed_pcdata was used
6549 if (PUGI__NODETYPE(_root) == node_element && _root->value) 6616 if (PUGI_IMPL_NODETYPE(_root) == node_element && _root->value)
6550 return _root; 6617 return _root;
6551 6618
6552 for (xml_node_struct* node = _root->first_child; node; node = node->next_sibling) 6619 for (xml_node_struct* node = _root->first_child; node; node = node->next_sibling)
6553 if (impl::is_text_node(node)) 6620 if (impl::is_text_node(node))
6554 return node; 6621 return node;
6555 6622
6556 return 0; 6623 return 0;
6557 } 6624 }
6558 6625
6559 PUGI__FN xml_node_struct* xml_text::_data_new() 6626 PUGI_IMPL_FN xml_node_struct* xml_text::_data_new()
6560 { 6627 {
6561 xml_node_struct* d = _data(); 6628 xml_node_struct* d = _data();
6562 if (d) return d; 6629 if (d) return d;
6563 6630
6564 return xml_node(_root).append_child(node_pcdata).internal_object(); 6631 return xml_node(_root).append_child(node_pcdata).internal_object();
6565 } 6632 }
6566 6633
6567 PUGI__FN xml_text::xml_text(): _root(0) 6634 PUGI_IMPL_FN xml_text::xml_text(): _root(0)
6568 { 6635 {
6569 } 6636 }
6570 6637
6571 PUGI__FN static void unspecified_bool_xml_text(xml_text***) 6638 PUGI_IMPL_FN static void unspecified_bool_xml_text(xml_text***)
6572 { 6639 {
6573 } 6640 }
6574 6641
6575 PUGI__FN xml_text::operator xml_text::unspecified_bool_type() const 6642 PUGI_IMPL_FN xml_text::operator xml_text::unspecified_bool_type() const
6576 { 6643 {
6577 return _data() ? unspecified_bool_xml_text : 0; 6644 return _data() ? unspecified_bool_xml_text : 0;
6578 } 6645 }
6579 6646
6580 PUGI__FN bool xml_text::operator!() const 6647 PUGI_IMPL_FN bool xml_text::operator!() const
6581 { 6648 {
6582 return !_data(); 6649 return !_data();
6583 } 6650 }
6584 6651
6585 PUGI__FN bool xml_text::empty() const 6652 PUGI_IMPL_FN bool xml_text::empty() const
6586 { 6653 {
6587 return _data() == 0; 6654 return _data() == 0;
6588 } 6655 }
6589 6656
6590 PUGI__FN const char_t* xml_text::get() const 6657 PUGI_IMPL_FN const char_t* xml_text::get() const
6591 { 6658 {
6592 xml_node_struct* d = _data(); 6659 xml_node_struct* d = _data();
6593 if (!d) return PUGIXML_TEXT(""); 6660 if (!d) return PUGIXML_TEXT("");
6594 const char_t* value = d->value; 6661 const char_t* value = d->value;
6595 return value ? value : PUGIXML_TEXT(""); 6662 return value ? value : PUGIXML_TEXT("");
6596 } 6663 }
6597 6664
6598 PUGI__FN const char_t* xml_text::as_string(const char_t* def) const 6665 PUGI_IMPL_FN const char_t* xml_text::as_string(const char_t* def) const
6599 { 6666 {
6600 xml_node_struct* d = _data(); 6667 xml_node_struct* d = _data();
6601 if (!d) return def; 6668 if (!d) return def;
6602 const char_t* value = d->value; 6669 const char_t* value = d->value;
6603 return value ? value : def; 6670 return value ? value : def;
6604 } 6671 }
6605 6672
6606 PUGI__FN int xml_text::as_int(int def) const 6673 PUGI_IMPL_FN int xml_text::as_int(int def) const
6607 { 6674 {
6608 xml_node_struct* d = _data(); 6675 xml_node_struct* d = _data();
6609 if (!d) return def; 6676 if (!d) return def;
6610 const char_t* value = d->value; 6677 const char_t* value = d->value;
6611 return value ? impl::get_value_int(value) : def; 6678 return value ? impl::get_value_int(value) : def;
6612 } 6679 }
6613 6680
6614 PUGI__FN unsigned int xml_text::as_uint(unsigned int def) const 6681 PUGI_IMPL_FN unsigned int xml_text::as_uint(unsigned int def) const
6615 { 6682 {
6616 xml_node_struct* d = _data(); 6683 xml_node_struct* d = _data();
6617 if (!d) return def; 6684 if (!d) return def;
6618 const char_t* value = d->value; 6685 const char_t* value = d->value;
6619 return value ? impl::get_value_uint(value) : def; 6686 return value ? impl::get_value_uint(value) : def;
6620 } 6687 }
6621 6688
6622 PUGI__FN double xml_text::as_double(double def) const 6689 PUGI_IMPL_FN double xml_text::as_double(double def) const
6623 { 6690 {
6624 xml_node_struct* d = _data(); 6691 xml_node_struct* d = _data();
6625 if (!d) return def; 6692 if (!d) return def;
6626 const char_t* value = d->value; 6693 const char_t* value = d->value;
6627 return value ? impl::get_value_double(value) : def; 6694 return value ? impl::get_value_double(value) : def;
6628 } 6695 }
6629 6696
6630 PUGI__FN float xml_text::as_float(float def) const 6697 PUGI_IMPL_FN float xml_text::as_float(float def) const
6631 { 6698 {
6632 xml_node_struct* d = _data(); 6699 xml_node_struct* d = _data();
6633 if (!d) return def; 6700 if (!d) return def;
6634 const char_t* value = d->value; 6701 const char_t* value = d->value;
6635 return value ? impl::get_value_float(value) : def; 6702 return value ? impl::get_value_float(value) : def;
6636 } 6703 }
6637 6704
6638 PUGI__FN bool xml_text::as_bool(bool def) const 6705 PUGI_IMPL_FN bool xml_text::as_bool(bool def) const
6639 { 6706 {
6640 xml_node_struct* d = _data(); 6707 xml_node_struct* d = _data();
6641 if (!d) return def; 6708 if (!d) return def;
6642 const char_t* value = d->value; 6709 const char_t* value = d->value;
6643 return value ? impl::get_value_bool(value) : def; 6710 return value ? impl::get_value_bool(value) : def;
6644 } 6711 }
6645 6712
6646 #ifdef PUGIXML_HAS_LONG_LONG 6713 #ifdef PUGIXML_HAS_LONG_LONG
6647 PUGI__FN long long xml_text::as_llong(long long def) const 6714 PUGI_IMPL_FN long long xml_text::as_llong(long long def) const
6648 { 6715 {
6649 xml_node_struct* d = _data(); 6716 xml_node_struct* d = _data();
6650 if (!d) return def; 6717 if (!d) return def;
6651 const char_t* value = d->value; 6718 const char_t* value = d->value;
6652 return value ? impl::get_value_llong(value) : def; 6719 return value ? impl::get_value_llong(value) : def;
6653 } 6720 }
6654 6721
6655 PUGI__FN unsigned long long xml_text::as_ullong(unsigned long long def) const 6722 PUGI_IMPL_FN unsigned long long xml_text::as_ullong(unsigned long long def) const
6656 { 6723 {
6657 xml_node_struct* d = _data(); 6724 xml_node_struct* d = _data();
6658 if (!d) return def; 6725 if (!d) return def;
6659 const char_t* value = d->value; 6726 const char_t* value = d->value;
6660 return value ? impl::get_value_ullong(value) : def; 6727 return value ? impl::get_value_ullong(value) : def;
6661 } 6728 }
6662 #endif 6729 #endif
6663 6730
6664 PUGI__FN bool xml_text::set(const char_t* rhs, size_t sz) 6731 PUGI_IMPL_FN bool xml_text::set(const char_t* rhs)
6665 { 6732 {
6666 xml_node_struct* dn = _data_new(); 6733 xml_node_struct* dn = _data_new();
6667 6734
6668 return dn ? impl::strcpy_insitu(dn->value, dn->header, impl::xml_memory_page_value_allocated_mask, rhs, sz) : false; 6735 return dn ? impl::strcpy_insitu(dn->value, dn->header, impl::xml_memory_page_value_allocated_mask, rhs, impl::strlength(rhs)) : false;
6669 } 6736 }
6670 6737
6671 PUGI__FN bool xml_text::set(const char_t* rhs) 6738 PUGI_IMPL_FN bool xml_text::set(const char_t* rhs, size_t size)
6672 { 6739 {
6673 xml_node_struct* dn = _data_new(); 6740 xml_node_struct* dn = _data_new();
6674 6741
6675 return dn ? impl::strcpy_insitu(dn->value, dn->header, impl::xml_memory_page_value_allocated_mask, rhs, impl::strlength(rhs)) : false; 6742 return dn ? impl::strcpy_insitu(dn->value, dn->header, impl::xml_memory_page_value_allocated_mask, rhs, size) : false;
6676 } 6743 }
6677 6744
6678 PUGI__FN bool xml_text::set(int rhs) 6745 PUGI_IMPL_FN bool xml_text::set(int rhs)
6679 { 6746 {
6680 xml_node_struct* dn = _data_new(); 6747 xml_node_struct* dn = _data_new();
6681 6748
6682 return dn ? impl::set_value_integer<unsigned int>(dn->value, dn->header, impl::xml_memory_page_value_allocated_mask, rhs, rhs < 0) : false; 6749 return dn ? impl::set_value_integer<unsigned int>(dn->value, dn->header, impl::xml_memory_page_value_allocated_mask, rhs, rhs < 0) : false;
6683 } 6750 }
6684 6751
6685 PUGI__FN bool xml_text::set(unsigned int rhs) 6752 PUGI_IMPL_FN bool xml_text::set(unsigned int rhs)
6686 { 6753 {
6687 xml_node_struct* dn = _data_new(); 6754 xml_node_struct* dn = _data_new();
6688 6755
6689 return dn ? impl::set_value_integer<unsigned int>(dn->value, dn->header, impl::xml_memory_page_value_allocated_mask, rhs, false) : false; 6756 return dn ? impl::set_value_integer<unsigned int>(dn->value, dn->header, impl::xml_memory_page_value_allocated_mask, rhs, false) : false;
6690 } 6757 }
6691 6758
6692 PUGI__FN bool xml_text::set(long rhs) 6759 PUGI_IMPL_FN bool xml_text::set(long rhs)
6693 { 6760 {
6694 xml_node_struct* dn = _data_new(); 6761 xml_node_struct* dn = _data_new();
6695 6762
6696 return dn ? impl::set_value_integer<unsigned long>(dn->value, dn->header, impl::xml_memory_page_value_allocated_mask, rhs, rhs < 0) : false; 6763 return dn ? impl::set_value_integer<unsigned long>(dn->value, dn->header, impl::xml_memory_page_value_allocated_mask, rhs, rhs < 0) : false;
6697 } 6764 }
6698 6765
6699 PUGI__FN bool xml_text::set(unsigned long rhs) 6766 PUGI_IMPL_FN bool xml_text::set(unsigned long rhs)
6700 { 6767 {
6701 xml_node_struct* dn = _data_new(); 6768 xml_node_struct* dn = _data_new();
6702 6769
6703 return dn ? impl::set_value_integer<unsigned long>(dn->value, dn->header, impl::xml_memory_page_value_allocated_mask, rhs, false) : false; 6770 return dn ? impl::set_value_integer<unsigned long>(dn->value, dn->header, impl::xml_memory_page_value_allocated_mask, rhs, false) : false;
6704 } 6771 }
6705 6772
6706 PUGI__FN bool xml_text::set(float rhs) 6773 PUGI_IMPL_FN bool xml_text::set(float rhs)
6707 { 6774 {
6708 xml_node_struct* dn = _data_new(); 6775 xml_node_struct* dn = _data_new();
6709 6776
6710 return dn ? impl::set_value_convert(dn->value, dn->header, impl::xml_memory_page_value_allocated_mask, rhs, default_float_precision) : false; 6777 return dn ? impl::set_value_convert(dn->value, dn->header, impl::xml_memory_page_value_allocated_mask, rhs, default_float_precision) : false;
6711 } 6778 }
6712 6779
6713 PUGI__FN bool xml_text::set(float rhs, int precision) 6780 PUGI_IMPL_FN bool xml_text::set(float rhs, int precision)
6714 { 6781 {
6715 xml_node_struct* dn = _data_new(); 6782 xml_node_struct* dn = _data_new();
6716 6783
6717 return dn ? impl::set_value_convert(dn->value, dn->header, impl::xml_memory_page_value_allocated_mask, rhs, precision) : false; 6784 return dn ? impl::set_value_convert(dn->value, dn->header, impl::xml_memory_page_value_allocated_mask, rhs, precision) : false;
6718 } 6785 }
6719 6786
6720 PUGI__FN bool xml_text::set(double rhs) 6787 PUGI_IMPL_FN bool xml_text::set(double rhs)
6721 { 6788 {
6722 xml_node_struct* dn = _data_new(); 6789 xml_node_struct* dn = _data_new();
6723 6790
6724 return dn ? impl::set_value_convert(dn->value, dn->header, impl::xml_memory_page_value_allocated_mask, rhs, default_double_precision) : false; 6791 return dn ? impl::set_value_convert(dn->value, dn->header, impl::xml_memory_page_value_allocated_mask, rhs, default_double_precision) : false;
6725 } 6792 }
6726 6793
6727 PUGI__FN bool xml_text::set(double rhs, int precision) 6794 PUGI_IMPL_FN bool xml_text::set(double rhs, int precision)
6728 { 6795 {
6729 xml_node_struct* dn = _data_new(); 6796 xml_node_struct* dn = _data_new();
6730 6797
6731 return dn ? impl::set_value_convert(dn->value, dn->header, impl::xml_memory_page_value_allocated_mask, rhs, precision) : false; 6798 return dn ? impl::set_value_convert(dn->value, dn->header, impl::xml_memory_page_value_allocated_mask, rhs, precision) : false;
6732 } 6799 }
6733 6800
6734 PUGI__FN bool xml_text::set(bool rhs) 6801 PUGI_IMPL_FN bool xml_text::set(bool rhs)
6735 { 6802 {
6736 xml_node_struct* dn = _data_new(); 6803 xml_node_struct* dn = _data_new();
6737 6804
6738 return dn ? impl::set_value_bool(dn->value, dn->header, impl::xml_memory_page_value_allocated_mask, rhs) : false; 6805 return dn ? impl::set_value_bool(dn->value, dn->header, impl::xml_memory_page_value_allocated_mask, rhs) : false;
6739 } 6806 }
6740 6807
6741 #ifdef PUGIXML_HAS_LONG_LONG 6808 #ifdef PUGIXML_HAS_LONG_LONG
6742 PUGI__FN bool xml_text::set(long long rhs) 6809 PUGI_IMPL_FN bool xml_text::set(long long rhs)
6743 { 6810 {
6744 xml_node_struct* dn = _data_new(); 6811 xml_node_struct* dn = _data_new();
6745 6812
6746 return dn ? impl::set_value_integer<unsigned long long>(dn->value, dn->header, impl::xml_memory_page_value_allocated_mask, rhs, rhs < 0) : false; 6813 return dn ? impl::set_value_integer<unsigned long long>(dn->value, dn->header, impl::xml_memory_page_value_allocated_mask, rhs, rhs < 0) : false;
6747 } 6814 }
6748 6815
6749 PUGI__FN bool xml_text::set(unsigned long long rhs) 6816 PUGI_IMPL_FN bool xml_text::set(unsigned long long rhs)
6750 { 6817 {
6751 xml_node_struct* dn = _data_new(); 6818 xml_node_struct* dn = _data_new();
6752 6819
6753 return dn ? impl::set_value_integer<unsigned long long>(dn->value, dn->header, impl::xml_memory_page_value_allocated_mask, rhs, false) : false; 6820 return dn ? impl::set_value_integer<unsigned long long>(dn->value, dn->header, impl::xml_memory_page_value_allocated_mask, rhs, false) : false;
6754 } 6821 }
6755 #endif 6822 #endif
6756 6823
6757 PUGI__FN xml_text& xml_text::operator=(const char_t* rhs) 6824 PUGI_IMPL_FN xml_text& xml_text::operator=(const char_t* rhs)
6758 { 6825 {
6759 set(rhs); 6826 set(rhs);
6760 return *this; 6827 return *this;
6761 } 6828 }
6762 6829
6763 PUGI__FN xml_text& xml_text::operator=(int rhs) 6830 PUGI_IMPL_FN xml_text& xml_text::operator=(int rhs)
6764 { 6831 {
6765 set(rhs); 6832 set(rhs);
6766 return *this; 6833 return *this;
6767 } 6834 }
6768 6835
6769 PUGI__FN xml_text& xml_text::operator=(unsigned int rhs) 6836 PUGI_IMPL_FN xml_text& xml_text::operator=(unsigned int rhs)
6770 { 6837 {
6771 set(rhs); 6838 set(rhs);
6772 return *this; 6839 return *this;
6773 } 6840 }
6774 6841
6775 PUGI__FN xml_text& xml_text::operator=(long rhs) 6842 PUGI_IMPL_FN xml_text& xml_text::operator=(long rhs)
6776 { 6843 {
6777 set(rhs); 6844 set(rhs);
6778 return *this; 6845 return *this;
6779 } 6846 }
6780 6847
6781 PUGI__FN xml_text& xml_text::operator=(unsigned long rhs) 6848 PUGI_IMPL_FN xml_text& xml_text::operator=(unsigned long rhs)
6782 { 6849 {
6783 set(rhs); 6850 set(rhs);
6784 return *this; 6851 return *this;
6785 } 6852 }
6786 6853
6787 PUGI__FN xml_text& xml_text::operator=(double rhs) 6854 PUGI_IMPL_FN xml_text& xml_text::operator=(double rhs)
6788 { 6855 {
6789 set(rhs); 6856 set(rhs);
6790 return *this; 6857 return *this;
6791 } 6858 }
6792 6859
6793 PUGI__FN xml_text& xml_text::operator=(float rhs) 6860 PUGI_IMPL_FN xml_text& xml_text::operator=(float rhs)
6794 { 6861 {
6795 set(rhs); 6862 set(rhs);
6796 return *this; 6863 return *this;
6797 } 6864 }
6798 6865
6799 PUGI__FN xml_text& xml_text::operator=(bool rhs) 6866 PUGI_IMPL_FN xml_text& xml_text::operator=(bool rhs)
6800 { 6867 {
6801 set(rhs); 6868 set(rhs);
6802 return *this; 6869 return *this;
6803 } 6870 }
6804 6871
6805 #ifdef PUGIXML_HAS_LONG_LONG 6872 #ifdef PUGIXML_HAS_LONG_LONG
6806 PUGI__FN xml_text& xml_text::operator=(long long rhs) 6873 PUGI_IMPL_FN xml_text& xml_text::operator=(long long rhs)
6807 { 6874 {
6808 set(rhs); 6875 set(rhs);
6809 return *this; 6876 return *this;
6810 } 6877 }
6811 6878
6812 PUGI__FN xml_text& xml_text::operator=(unsigned long long rhs) 6879 PUGI_IMPL_FN xml_text& xml_text::operator=(unsigned long long rhs)
6813 { 6880 {
6814 set(rhs); 6881 set(rhs);
6815 return *this; 6882 return *this;
6816 } 6883 }
6817 #endif 6884 #endif
6818 6885
6819 PUGI__FN xml_node xml_text::data() const 6886 PUGI_IMPL_FN xml_node xml_text::data() const
6820 { 6887 {
6821 return xml_node(_data()); 6888 return xml_node(_data());
6822 } 6889 }
6823 6890
6824 #ifdef __BORLANDC__ 6891 #ifdef __BORLANDC__
6825 PUGI__FN bool operator&&(const xml_text& lhs, bool rhs) 6892 PUGI_IMPL_FN bool operator&&(const xml_text& lhs, bool rhs)
6826 { 6893 {
6827 return (bool)lhs && rhs; 6894 return (bool)lhs && rhs;
6828 } 6895 }
6829 6896
6830 PUGI__FN bool operator||(const xml_text& lhs, bool rhs) 6897 PUGI_IMPL_FN bool operator||(const xml_text& lhs, bool rhs)
6831 { 6898 {
6832 return (bool)lhs || rhs; 6899 return (bool)lhs || rhs;
6833 } 6900 }
6834 #endif 6901 #endif
6835 6902
6836 PUGI__FN xml_node_iterator::xml_node_iterator() 6903 PUGI_IMPL_FN xml_node_iterator::xml_node_iterator()
6837 { 6904 {
6838 } 6905 }
6839 6906
6840 PUGI__FN xml_node_iterator::xml_node_iterator(const xml_node& node): _wrap(node), _parent(node.parent()) 6907 PUGI_IMPL_FN xml_node_iterator::xml_node_iterator(const xml_node& node): _wrap(node), _parent(node.parent())
6841 { 6908 {
6842 } 6909 }
6843 6910
6844 PUGI__FN xml_node_iterator::xml_node_iterator(xml_node_struct* ref, xml_node_struct* parent): _wrap(ref), _parent(parent) 6911 PUGI_IMPL_FN xml_node_iterator::xml_node_iterator(xml_node_struct* ref, xml_node_struct* parent): _wrap(ref), _parent(parent)
6845 { 6912 {
6846 } 6913 }
6847 6914
6848 PUGI__FN bool xml_node_iterator::operator==(const xml_node_iterator& rhs) const 6915 PUGI_IMPL_FN bool xml_node_iterator::operator==(const xml_node_iterator& rhs) const
6849 { 6916 {
6850 return _wrap._root == rhs._wrap._root && _parent._root == rhs._parent._root; 6917 return _wrap._root == rhs._wrap._root && _parent._root == rhs._parent._root;
6851 } 6918 }
6852 6919
6853 PUGI__FN bool xml_node_iterator::operator!=(const xml_node_iterator& rhs) const 6920 PUGI_IMPL_FN bool xml_node_iterator::operator!=(const xml_node_iterator& rhs) const
6854 { 6921 {
6855 return _wrap._root != rhs._wrap._root || _parent._root != rhs._parent._root; 6922 return _wrap._root != rhs._wrap._root || _parent._root != rhs._parent._root;
6856 } 6923 }
6857 6924
6858 PUGI__FN xml_node& xml_node_iterator::operator*() const 6925 PUGI_IMPL_FN xml_node& xml_node_iterator::operator*() const
6859 { 6926 {
6860 assert(_wrap._root); 6927 assert(_wrap._root);
6861 return _wrap; 6928 return _wrap;
6862 } 6929 }
6863 6930
6864 PUGI__FN xml_node* xml_node_iterator::operator->() const 6931 PUGI_IMPL_FN xml_node* xml_node_iterator::operator->() const
6865 { 6932 {
6866 assert(_wrap._root); 6933 assert(_wrap._root);
6867 return const_cast<xml_node*>(&_wrap); // BCC5 workaround 6934 return const_cast<xml_node*>(&_wrap); // BCC5 workaround
6868 } 6935 }
6869 6936
6870 PUGI__FN xml_node_iterator& xml_node_iterator::operator++() 6937 PUGI_IMPL_FN xml_node_iterator& xml_node_iterator::operator++()
6871 { 6938 {
6872 assert(_wrap._root); 6939 assert(_wrap._root);
6873 _wrap._root = _wrap._root->next_sibling; 6940 _wrap._root = _wrap._root->next_sibling;
6874 return *this; 6941 return *this;
6875 } 6942 }
6876 6943
6877 PUGI__FN xml_node_iterator xml_node_iterator::operator++(int) 6944 PUGI_IMPL_FN xml_node_iterator xml_node_iterator::operator++(int)
6878 { 6945 {
6879 xml_node_iterator temp = *this; 6946 xml_node_iterator temp = *this;
6880 ++*this; 6947 ++*this;
6881 return temp; 6948 return temp;
6882 } 6949 }
6883 6950
6884 PUGI__FN xml_node_iterator& xml_node_iterator::operator--() 6951 PUGI_IMPL_FN xml_node_iterator& xml_node_iterator::operator--()
6885 { 6952 {
6886 _wrap = _wrap._root ? _wrap.previous_sibling() : _parent.last_child(); 6953 _wrap = _wrap._root ? _wrap.previous_sibling() : _parent.last_child();
6887 return *this; 6954 return *this;
6888 } 6955 }
6889 6956
6890 PUGI__FN xml_node_iterator xml_node_iterator::operator--(int) 6957 PUGI_IMPL_FN xml_node_iterator xml_node_iterator::operator--(int)
6891 { 6958 {
6892 xml_node_iterator temp = *this; 6959 xml_node_iterator temp = *this;
6893 --*this; 6960 --*this;
6894 return temp; 6961 return temp;
6895 } 6962 }
6896 6963
6897 PUGI__FN xml_attribute_iterator::xml_attribute_iterator() 6964 PUGI_IMPL_FN xml_attribute_iterator::xml_attribute_iterator()
6898 { 6965 {
6899 } 6966 }
6900 6967
6901 PUGI__FN xml_attribute_iterator::xml_attribute_iterator(const xml_attribute& attr, const xml_node& parent): _wrap(attr), _parent(parent) 6968 PUGI_IMPL_FN xml_attribute_iterator::xml_attribute_iterator(const xml_attribute& attr, const xml_node& parent): _wrap(attr), _parent(parent)
6902 { 6969 {
6903 } 6970 }
6904 6971
6905 PUGI__FN xml_attribute_iterator::xml_attribute_iterator(xml_attribute_struct* ref, xml_node_struct* parent): _wrap(ref), _parent(parent) 6972 PUGI_IMPL_FN xml_attribute_iterator::xml_attribute_iterator(xml_attribute_struct* ref, xml_node_struct* parent): _wrap(ref), _parent(parent)
6906 { 6973 {
6907 } 6974 }
6908 6975
6909 PUGI__FN bool xml_attribute_iterator::operator==(const xml_attribute_iterator& rhs) const 6976 PUGI_IMPL_FN bool xml_attribute_iterator::operator==(const xml_attribute_iterator& rhs) const
6910 { 6977 {
6911 return _wrap._attr == rhs._wrap._attr && _parent._root == rhs._parent._root; 6978 return _wrap._attr == rhs._wrap._attr && _parent._root == rhs._parent._root;
6912 } 6979 }
6913 6980
6914 PUGI__FN bool xml_attribute_iterator::operator!=(const xml_attribute_iterator& rhs) const 6981 PUGI_IMPL_FN bool xml_attribute_iterator::operator!=(const xml_attribute_iterator& rhs) const
6915 { 6982 {
6916 return _wrap._attr != rhs._wrap._attr || _parent._root != rhs._parent._root; 6983 return _wrap._attr != rhs._wrap._attr || _parent._root != rhs._parent._root;
6917 } 6984 }
6918 6985
6919 PUGI__FN xml_attribute& xml_attribute_iterator::operator*() const 6986 PUGI_IMPL_FN xml_attribute& xml_attribute_iterator::operator*() const
6920 { 6987 {
6921 assert(_wrap._attr); 6988 assert(_wrap._attr);
6922 return _wrap; 6989 return _wrap;
6923 } 6990 }
6924 6991
6925 PUGI__FN xml_attribute* xml_attribute_iterator::operator->() const 6992 PUGI_IMPL_FN xml_attribute* xml_attribute_iterator::operator->() const
6926 { 6993 {
6927 assert(_wrap._attr); 6994 assert(_wrap._attr);
6928 return const_cast<xml_attribute*>(&_wrap); // BCC5 workaround 6995 return const_cast<xml_attribute*>(&_wrap); // BCC5 workaround
6929 } 6996 }
6930 6997
6931 PUGI__FN xml_attribute_iterator& xml_attribute_iterator::operator++() 6998 PUGI_IMPL_FN xml_attribute_iterator& xml_attribute_iterator::operator++()
6932 { 6999 {
6933 assert(_wrap._attr); 7000 assert(_wrap._attr);
6934 _wrap._attr = _wrap._attr->next_attribute; 7001 _wrap._attr = _wrap._attr->next_attribute;
6935 return *this; 7002 return *this;
6936 } 7003 }
6937 7004
6938 PUGI__FN xml_attribute_iterator xml_attribute_iterator::operator++(int) 7005 PUGI_IMPL_FN xml_attribute_iterator xml_attribute_iterator::operator++(int)
6939 { 7006 {
6940 xml_attribute_iterator temp = *this; 7007 xml_attribute_iterator temp = *this;
6941 ++*this; 7008 ++*this;
6942 return temp; 7009 return temp;
6943 } 7010 }
6944 7011
6945 PUGI__FN xml_attribute_iterator& xml_attribute_iterator::operator--() 7012 PUGI_IMPL_FN xml_attribute_iterator& xml_attribute_iterator::operator--()
6946 { 7013 {
6947 _wrap = _wrap._attr ? _wrap.previous_attribute() : _parent.last_attribute(); 7014 _wrap = _wrap._attr ? _wrap.previous_attribute() : _parent.last_attribute();
6948 return *this; 7015 return *this;
6949 } 7016 }
6950 7017
6951 PUGI__FN xml_attribute_iterator xml_attribute_iterator::operator--(int) 7018 PUGI_IMPL_FN xml_attribute_iterator xml_attribute_iterator::operator--(int)
6952 { 7019 {
6953 xml_attribute_iterator temp = *this; 7020 xml_attribute_iterator temp = *this;
6954 --*this; 7021 --*this;
6955 return temp; 7022 return temp;
6956 } 7023 }
6957 7024
6958 PUGI__FN xml_named_node_iterator::xml_named_node_iterator(): _name(0) 7025 PUGI_IMPL_FN xml_named_node_iterator::xml_named_node_iterator(): _name(0)
6959 { 7026 {
6960 } 7027 }
6961 7028
6962 PUGI__FN xml_named_node_iterator::xml_named_node_iterator(const xml_node& node, const char_t* name): _wrap(node), _parent(node.parent()), _name(name) 7029 PUGI_IMPL_FN xml_named_node_iterator::xml_named_node_iterator(const xml_node& node, const char_t* name): _wrap(node), _parent(node.parent()), _name(name)
6963 { 7030 {
6964 } 7031 }
6965 7032
6966 PUGI__FN xml_named_node_iterator::xml_named_node_iterator(xml_node_struct* ref, xml_node_struct* parent, const char_t* name): _wrap(ref), _parent(parent), _name(name) 7033 PUGI_IMPL_FN xml_named_node_iterator::xml_named_node_iterator(xml_node_struct* ref, xml_node_struct* parent, const char_t* name): _wrap(ref), _parent(parent), _name(name)
6967 { 7034 {
6968 } 7035 }
6969 7036
6970 PUGI__FN bool xml_named_node_iterator::operator==(const xml_named_node_iterator& rhs) const 7037 PUGI_IMPL_FN bool xml_named_node_iterator::operator==(const xml_named_node_iterator& rhs) const
6971 { 7038 {
6972 return _wrap._root == rhs._wrap._root && _parent._root == rhs._parent._root; 7039 return _wrap._root == rhs._wrap._root && _parent._root == rhs._parent._root;
6973 } 7040 }
6974 7041
6975 PUGI__FN bool xml_named_node_iterator::operator!=(const xml_named_node_iterator& rhs) const 7042 PUGI_IMPL_FN bool xml_named_node_iterator::operator!=(const xml_named_node_iterator& rhs) const
6976 { 7043 {
6977 return _wrap._root != rhs._wrap._root || _parent._root != rhs._parent._root; 7044 return _wrap._root != rhs._wrap._root || _parent._root != rhs._parent._root;
6978 } 7045 }
6979 7046
6980 PUGI__FN xml_node& xml_named_node_iterator::operator*() const 7047 PUGI_IMPL_FN xml_node& xml_named_node_iterator::operator*() const
6981 { 7048 {
6982 assert(_wrap._root); 7049 assert(_wrap._root);
6983 return _wrap; 7050 return _wrap;
6984 } 7051 }
6985 7052
6986 PUGI__FN xml_node* xml_named_node_iterator::operator->() const 7053 PUGI_IMPL_FN xml_node* xml_named_node_iterator::operator->() const
6987 { 7054 {
6988 assert(_wrap._root); 7055 assert(_wrap._root);
6989 return const_cast<xml_node*>(&_wrap); // BCC5 workaround 7056 return const_cast<xml_node*>(&_wrap); // BCC5 workaround
6990 } 7057 }
6991 7058
6992 PUGI__FN xml_named_node_iterator& xml_named_node_iterator::operator++() 7059 PUGI_IMPL_FN xml_named_node_iterator& xml_named_node_iterator::operator++()
6993 { 7060 {
6994 assert(_wrap._root); 7061 assert(_wrap._root);
6995 _wrap = _wrap.next_sibling(_name); 7062 _wrap = _wrap.next_sibling(_name);
6996 return *this; 7063 return *this;
6997 } 7064 }
6998 7065
6999 PUGI__FN xml_named_node_iterator xml_named_node_iterator::operator++(int) 7066 PUGI_IMPL_FN xml_named_node_iterator xml_named_node_iterator::operator++(int)
7000 { 7067 {
7001 xml_named_node_iterator temp = *this; 7068 xml_named_node_iterator temp = *this;
7002 ++*this; 7069 ++*this;
7003 return temp; 7070 return temp;
7004 } 7071 }
7005 7072
7006 PUGI__FN xml_named_node_iterator& xml_named_node_iterator::operator--() 7073 PUGI_IMPL_FN xml_named_node_iterator& xml_named_node_iterator::operator--()
7007 { 7074 {
7008 if (_wrap._root) 7075 if (_wrap._root)
7009 _wrap = _wrap.previous_sibling(_name); 7076 _wrap = _wrap.previous_sibling(_name);
7010 else 7077 else
7011 { 7078 {
7016 } 7083 }
7017 7084
7018 return *this; 7085 return *this;
7019 } 7086 }
7020 7087
7021 PUGI__FN xml_named_node_iterator xml_named_node_iterator::operator--(int) 7088 PUGI_IMPL_FN xml_named_node_iterator xml_named_node_iterator::operator--(int)
7022 { 7089 {
7023 xml_named_node_iterator temp = *this; 7090 xml_named_node_iterator temp = *this;
7024 --*this; 7091 --*this;
7025 return temp; 7092 return temp;
7026 } 7093 }
7027 7094
7028 PUGI__FN xml_parse_result::xml_parse_result(): status(status_internal_error), offset(0), encoding(encoding_auto) 7095 PUGI_IMPL_FN xml_parse_result::xml_parse_result(): status(status_internal_error), offset(0), encoding(encoding_auto)
7029 { 7096 {
7030 } 7097 }
7031 7098
7032 PUGI__FN xml_parse_result::operator bool() const 7099 PUGI_IMPL_FN xml_parse_result::operator bool() const
7033 { 7100 {
7034 return status == status_ok; 7101 return status == status_ok;
7035 } 7102 }
7036 7103
7037 PUGI__FN const char* xml_parse_result::description() const 7104 PUGI_IMPL_FN const char* xml_parse_result::description() const
7038 { 7105 {
7039 switch (status) 7106 switch (status)
7040 { 7107 {
7041 case status_ok: return "No error"; 7108 case status_ok: return "No error";
7042 7109
7063 7130
7064 default: return "Unknown error"; 7131 default: return "Unknown error";
7065 } 7132 }
7066 } 7133 }
7067 7134
7068 PUGI__FN xml_document::xml_document(): _buffer(0) 7135 PUGI_IMPL_FN xml_document::xml_document(): _buffer(0)
7069 { 7136 {
7070 _create(); 7137 _create();
7071 } 7138 }
7072 7139
7073 PUGI__FN xml_document::~xml_document() 7140 PUGI_IMPL_FN xml_document::~xml_document()
7074 { 7141 {
7075 _destroy(); 7142 _destroy();
7076 } 7143 }
7077 7144
7078 #ifdef PUGIXML_HAS_MOVE 7145 #ifdef PUGIXML_HAS_MOVE
7079 PUGI__FN xml_document::xml_document(xml_document&& rhs) PUGIXML_NOEXCEPT_IF_NOT_COMPACT: _buffer(0) 7146 PUGI_IMPL_FN xml_document::xml_document(xml_document&& rhs) PUGIXML_NOEXCEPT_IF_NOT_COMPACT: _buffer(0)
7080 { 7147 {
7081 _create(); 7148 _create();
7082 _move(rhs); 7149 _move(rhs);
7083 } 7150 }
7084 7151
7085 PUGI__FN xml_document& xml_document::operator=(xml_document&& rhs) PUGIXML_NOEXCEPT_IF_NOT_COMPACT 7152 PUGI_IMPL_FN xml_document& xml_document::operator=(xml_document&& rhs) PUGIXML_NOEXCEPT_IF_NOT_COMPACT
7086 { 7153 {
7087 if (this == &rhs) return *this; 7154 if (this == &rhs) return *this;
7088 7155
7089 _destroy(); 7156 _destroy();
7090 _create(); 7157 _create();
7092 7159
7093 return *this; 7160 return *this;
7094 } 7161 }
7095 #endif 7162 #endif
7096 7163
7097 PUGI__FN void xml_document::reset() 7164 PUGI_IMPL_FN void xml_document::reset()
7098 { 7165 {
7099 _destroy(); 7166 _destroy();
7100 _create(); 7167 _create();
7101 } 7168 }
7102 7169
7103 PUGI__FN void xml_document::reset(const xml_document& proto) 7170 PUGI_IMPL_FN void xml_document::reset(const xml_document& proto)
7104 { 7171 {
7105 reset(); 7172 reset();
7106 7173
7107 impl::node_copy_tree(_root, proto._root); 7174 impl::node_copy_tree(_root, proto._root);
7108 } 7175 }
7109 7176
7110 PUGI__FN void xml_document::_create() 7177 PUGI_IMPL_FN void xml_document::_create()
7111 { 7178 {
7112 assert(!_root); 7179 assert(!_root);
7113 7180
7114 #ifdef PUGIXML_COMPACT 7181 #ifdef PUGIXML_COMPACT
7115 // space for page marker for the first page (uint32_t), rounded up to pointer size; assumes pointers are at least 32-bit 7182 // space for page marker for the first page (uint32_t), rounded up to pointer size; assumes pointers are at least 32-bit
7117 #else 7184 #else
7118 const size_t page_offset = 0; 7185 const size_t page_offset = 0;
7119 #endif 7186 #endif
7120 7187
7121 // initialize sentinel page 7188 // initialize sentinel page
7122 PUGI__STATIC_ASSERT(sizeof(impl::xml_memory_page) + sizeof(impl::xml_document_struct) + page_offset <= sizeof(_memory)); 7189 PUGI_IMPL_STATIC_ASSERT(sizeof(impl::xml_memory_page) + sizeof(impl::xml_document_struct) + page_offset <= sizeof(_memory));
7123 7190
7124 // prepare page structure 7191 // prepare page structure
7125 impl::xml_memory_page* page = impl::xml_memory_page::construct(_memory); 7192 impl::xml_memory_page* page = impl::xml_memory_page::construct(_memory);
7126 assert(page); 7193 assert(page);
7127 7194
7148 7215
7149 // verify the document allocation 7216 // verify the document allocation
7150 assert(reinterpret_cast<char*>(_root) + sizeof(impl::xml_document_struct) <= _memory + sizeof(_memory)); 7217 assert(reinterpret_cast<char*>(_root) + sizeof(impl::xml_document_struct) <= _memory + sizeof(_memory));
7151 } 7218 }
7152 7219
7153 PUGI__FN void xml_document::_destroy() 7220 PUGI_IMPL_FN void xml_document::_destroy()
7154 { 7221 {
7155 assert(_root); 7222 assert(_root);
7156 7223
7157 // destroy static storage 7224 // destroy static storage
7158 if (_buffer) 7225 if (_buffer)
7166 { 7233 {
7167 if (extra->buffer) impl::xml_memory::deallocate(extra->buffer); 7234 if (extra->buffer) impl::xml_memory::deallocate(extra->buffer);
7168 } 7235 }
7169 7236
7170 // destroy dynamic storage, leave sentinel page (it's in static memory) 7237 // destroy dynamic storage, leave sentinel page (it's in static memory)
7171 impl::xml_memory_page* root_page = PUGI__GETPAGE(_root); 7238 impl::xml_memory_page* root_page = PUGI_IMPL_GETPAGE(_root);
7172 assert(root_page && !root_page->prev); 7239 assert(root_page && !root_page->prev);
7173 assert(reinterpret_cast<char*>(root_page) >= _memory && reinterpret_cast<char*>(root_page) < _memory + sizeof(_memory)); 7240 assert(reinterpret_cast<char*>(root_page) >= _memory && reinterpret_cast<char*>(root_page) < _memory + sizeof(_memory));
7174 7241
7175 for (impl::xml_memory_page* page = root_page->next; page; ) 7242 for (impl::xml_memory_page* page = root_page->next; page; )
7176 { 7243 {
7188 7255
7189 _root = 0; 7256 _root = 0;
7190 } 7257 }
7191 7258
7192 #ifdef PUGIXML_HAS_MOVE 7259 #ifdef PUGIXML_HAS_MOVE
7193 PUGI__FN void xml_document::_move(xml_document& rhs) PUGIXML_NOEXCEPT_IF_NOT_COMPACT 7260 PUGI_IMPL_FN void xml_document::_move(xml_document& rhs) PUGIXML_NOEXCEPT_IF_NOT_COMPACT
7194 { 7261 {
7195 impl::xml_document_struct* doc = static_cast<impl::xml_document_struct*>(_root); 7262 impl::xml_document_struct* doc = static_cast<impl::xml_document_struct*>(_root);
7196 impl::xml_document_struct* other = static_cast<impl::xml_document_struct*>(rhs._root); 7263 impl::xml_document_struct* other = static_cast<impl::xml_document_struct*>(rhs._root);
7197 7264
7198 // save first child pointer for later; this needs hash access 7265 // save first child pointer for later; this needs hash access
7222 } 7289 }
7223 #endif 7290 #endif
7224 7291
7225 // move allocation state 7292 // move allocation state
7226 // note that other->_root may point to the embedded document page, in which case we should keep original (empty) state 7293 // note that other->_root may point to the embedded document page, in which case we should keep original (empty) state
7227 if (other->_root != PUGI__GETPAGE(other)) 7294 if (other->_root != PUGI_IMPL_GETPAGE(other))
7228 { 7295 {
7229 doc->_root = other->_root; 7296 doc->_root = other->_root;
7230 doc->_busy_size = other->_busy_size; 7297 doc->_busy_size = other->_busy_size;
7231 } 7298 }
7232 7299
7243 // make sure we don't access other hash up until the end when we reinitialize other document 7310 // make sure we don't access other hash up until the end when we reinitialize other document
7244 other->_hash = 0; 7311 other->_hash = 0;
7245 #endif 7312 #endif
7246 7313
7247 // move page structure 7314 // move page structure
7248 impl::xml_memory_page* doc_page = PUGI__GETPAGE(doc); 7315 impl::xml_memory_page* doc_page = PUGI_IMPL_GETPAGE(doc);
7249 assert(doc_page && !doc_page->prev && !doc_page->next); 7316 assert(doc_page && !doc_page->prev && !doc_page->next);
7250 7317
7251 impl::xml_memory_page* other_page = PUGI__GETPAGE(other); 7318 impl::xml_memory_page* other_page = PUGI_IMPL_GETPAGE(other);
7252 assert(other_page && !other_page->prev); 7319 assert(other_page && !other_page->prev);
7253 7320
7254 // relink pages since root page is embedded into xml_document 7321 // relink pages since root page is embedded into xml_document
7255 if (impl::xml_memory_page* page = other_page->next) 7322 if (impl::xml_memory_page* page = other_page->next)
7256 { 7323 {
7293 node->parent = doc; 7360 node->parent = doc;
7294 #endif 7361 #endif
7295 } 7362 }
7296 7363
7297 // reset other document 7364 // reset other document
7298 new (other) impl::xml_document_struct(PUGI__GETPAGE(other)); 7365 new (other) impl::xml_document_struct(PUGI_IMPL_GETPAGE(other));
7299 rhs._buffer = 0; 7366 rhs._buffer = 0;
7300 } 7367 }
7301 #endif 7368 #endif
7302 7369
7303 #ifndef PUGIXML_NO_STL 7370 #ifndef PUGIXML_NO_STL
7304 PUGI__FN xml_parse_result xml_document::load(std::basic_istream<char, std::char_traits<char> >& stream, unsigned int options, xml_encoding encoding) 7371 PUGI_IMPL_FN xml_parse_result xml_document::load(std::basic_istream<char, std::char_traits<char> >& stream, unsigned int options, xml_encoding encoding)
7305 { 7372 {
7306 reset(); 7373 reset();
7307 7374
7308 return impl::load_stream_impl(static_cast<impl::xml_document_struct*>(_root), stream, options, encoding, &_buffer); 7375 return impl::load_stream_impl(static_cast<impl::xml_document_struct*>(_root), stream, options, encoding, &_buffer);
7309 } 7376 }
7310 7377
7311 PUGI__FN xml_parse_result xml_document::load(std::basic_istream<wchar_t, std::char_traits<wchar_t> >& stream, unsigned int options) 7378 PUGI_IMPL_FN xml_parse_result xml_document::load(std::basic_istream<wchar_t, std::char_traits<wchar_t> >& stream, unsigned int options)
7312 { 7379 {
7313 reset(); 7380 reset();
7314 7381
7315 return impl::load_stream_impl(static_cast<impl::xml_document_struct*>(_root), stream, options, encoding_wchar, &_buffer); 7382 return impl::load_stream_impl(static_cast<impl::xml_document_struct*>(_root), stream, options, encoding_wchar, &_buffer);
7316 } 7383 }
7317 #endif 7384 #endif
7318 7385
7319 PUGI__FN xml_parse_result xml_document::load_string(const char_t* contents, unsigned int options) 7386 PUGI_IMPL_FN xml_parse_result xml_document::load_string(const char_t* contents, unsigned int options)
7320 { 7387 {
7321 // Force native encoding (skip autodetection) 7388 // Force native encoding (skip autodetection)
7322 #ifdef PUGIXML_WCHAR_MODE 7389 #ifdef PUGIXML_WCHAR_MODE
7323 xml_encoding encoding = encoding_wchar; 7390 xml_encoding encoding = encoding_wchar;
7324 #else 7391 #else
7326 #endif 7393 #endif
7327 7394
7328 return load_buffer(contents, impl::strlength(contents) * sizeof(char_t), options, encoding); 7395 return load_buffer(contents, impl::strlength(contents) * sizeof(char_t), options, encoding);
7329 } 7396 }
7330 7397
7331 PUGI__FN xml_parse_result xml_document::load(const char_t* contents, unsigned int options) 7398 PUGI_IMPL_FN xml_parse_result xml_document::load(const char_t* contents, unsigned int options)
7332 { 7399 {
7333 return load_string(contents, options); 7400 return load_string(contents, options);
7334 } 7401 }
7335 7402
7336 PUGI__FN xml_parse_result xml_document::load_file(const char* path_, unsigned int options, xml_encoding encoding) 7403 PUGI_IMPL_FN xml_parse_result xml_document::load_file(const char* path_, unsigned int options, xml_encoding encoding)
7337 { 7404 {
7338 reset(); 7405 reset();
7339 7406
7340 using impl::auto_deleter; // MSVC7 workaround 7407 using impl::auto_deleter; // MSVC7 workaround
7341 auto_deleter<FILE> file(impl::open_file(path_, "rb"), impl::close_file); 7408 auto_deleter<FILE> file(impl::open_file(path_, "rb"), impl::close_file);
7342 7409
7343 return impl::load_file_impl(static_cast<impl::xml_document_struct*>(_root), file.data, options, encoding, &_buffer); 7410 return impl::load_file_impl(static_cast<impl::xml_document_struct*>(_root), file.data, options, encoding, &_buffer);
7344 } 7411 }
7345 7412
7346 PUGI__FN xml_parse_result xml_document::load_file(const wchar_t* path_, unsigned int options, xml_encoding encoding) 7413 PUGI_IMPL_FN xml_parse_result xml_document::load_file(const wchar_t* path_, unsigned int options, xml_encoding encoding)
7347 { 7414 {
7348 reset(); 7415 reset();
7349 7416
7350 using impl::auto_deleter; // MSVC7 workaround 7417 using impl::auto_deleter; // MSVC7 workaround
7351 auto_deleter<FILE> file(impl::open_file_wide(path_, L"rb"), impl::close_file); 7418 auto_deleter<FILE> file(impl::open_file_wide(path_, L"rb"), impl::close_file);
7352 7419
7353 return impl::load_file_impl(static_cast<impl::xml_document_struct*>(_root), file.data, options, encoding, &_buffer); 7420 return impl::load_file_impl(static_cast<impl::xml_document_struct*>(_root), file.data, options, encoding, &_buffer);
7354 } 7421 }
7355 7422
7356 PUGI__FN xml_parse_result xml_document::load_buffer(const void* contents, size_t size, unsigned int options, xml_encoding encoding) 7423 PUGI_IMPL_FN xml_parse_result xml_document::load_buffer(const void* contents, size_t size, unsigned int options, xml_encoding encoding)
7357 { 7424 {
7358 reset(); 7425 reset();
7359 7426
7360 return impl::load_buffer_impl(static_cast<impl::xml_document_struct*>(_root), _root, const_cast<void*>(contents), size, options, encoding, false, false, &_buffer); 7427 return impl::load_buffer_impl(static_cast<impl::xml_document_struct*>(_root), _root, const_cast<void*>(contents), size, options, encoding, false, false, &_buffer);
7361 } 7428 }
7362 7429
7363 PUGI__FN xml_parse_result xml_document::load_buffer_inplace(void* contents, size_t size, unsigned int options, xml_encoding encoding) 7430 PUGI_IMPL_FN xml_parse_result xml_document::load_buffer_inplace(void* contents, size_t size, unsigned int options, xml_encoding encoding)
7364 { 7431 {
7365 reset(); 7432 reset();
7366 7433
7367 return impl::load_buffer_impl(static_cast<impl::xml_document_struct*>(_root), _root, contents, size, options, encoding, true, false, &_buffer); 7434 return impl::load_buffer_impl(static_cast<impl::xml_document_struct*>(_root), _root, contents, size, options, encoding, true, false, &_buffer);
7368 } 7435 }
7369 7436
7370 PUGI__FN xml_parse_result xml_document::load_buffer_inplace_own(void* contents, size_t size, unsigned int options, xml_encoding encoding) 7437 PUGI_IMPL_FN xml_parse_result xml_document::load_buffer_inplace_own(void* contents, size_t size, unsigned int options, xml_encoding encoding)
7371 { 7438 {
7372 reset(); 7439 reset();
7373 7440
7374 return impl::load_buffer_impl(static_cast<impl::xml_document_struct*>(_root), _root, contents, size, options, encoding, true, true, &_buffer); 7441 return impl::load_buffer_impl(static_cast<impl::xml_document_struct*>(_root), _root, contents, size, options, encoding, true, true, &_buffer);
7375 } 7442 }
7376 7443
7377 PUGI__FN void xml_document::save(xml_writer& writer, const char_t* indent, unsigned int flags, xml_encoding encoding) const 7444 PUGI_IMPL_FN void xml_document::save(xml_writer& writer, const char_t* indent, unsigned int flags, xml_encoding encoding) const
7378 { 7445 {
7379 impl::xml_buffered_writer buffered_writer(writer, encoding); 7446 impl::xml_buffered_writer buffered_writer(writer, encoding);
7380 7447
7381 if ((flags & format_write_bom) && encoding != encoding_latin1) 7448 if ((flags & format_write_bom) && encoding != encoding_latin1)
7382 { 7449 {
7401 7468
7402 buffered_writer.flush(); 7469 buffered_writer.flush();
7403 } 7470 }
7404 7471
7405 #ifndef PUGIXML_NO_STL 7472 #ifndef PUGIXML_NO_STL
7406 PUGI__FN void xml_document::save(std::basic_ostream<char, std::char_traits<char> >& stream, const char_t* indent, unsigned int flags, xml_encoding encoding) const 7473 PUGI_IMPL_FN void xml_document::save(std::basic_ostream<char, std::char_traits<char> >& stream, const char_t* indent, unsigned int flags, xml_encoding encoding) const
7407 { 7474 {
7408 xml_writer_stream writer(stream); 7475 xml_writer_stream writer(stream);
7409 7476
7410 save(writer, indent, flags, encoding); 7477 save(writer, indent, flags, encoding);
7411 } 7478 }
7412 7479
7413 PUGI__FN void xml_document::save(std::basic_ostream<wchar_t, std::char_traits<wchar_t> >& stream, const char_t* indent, unsigned int flags) const 7480 PUGI_IMPL_FN void xml_document::save(std::basic_ostream<wchar_t, std::char_traits<wchar_t> >& stream, const char_t* indent, unsigned int flags) const
7414 { 7481 {
7415 xml_writer_stream writer(stream); 7482 xml_writer_stream writer(stream);
7416 7483
7417 save(writer, indent, flags, encoding_wchar); 7484 save(writer, indent, flags, encoding_wchar);
7418 } 7485 }
7419 #endif 7486 #endif
7420 7487
7421 PUGI__FN bool xml_document::save_file(const char* path_, const char_t* indent, unsigned int flags, xml_encoding encoding) const 7488 PUGI_IMPL_FN bool xml_document::save_file(const char* path_, const char_t* indent, unsigned int flags, xml_encoding encoding) const
7422 { 7489 {
7423 using impl::auto_deleter; // MSVC7 workaround 7490 using impl::auto_deleter; // MSVC7 workaround
7424 auto_deleter<FILE> file(impl::open_file(path_, (flags & format_save_file_text) ? "w" : "wb"), impl::close_file); 7491 auto_deleter<FILE> file(impl::open_file(path_, (flags & format_save_file_text) ? "w" : "wb"), impl::close_file);
7425 7492
7426 return impl::save_file_impl(*this, file.data, indent, flags, encoding) && fclose(file.release()) == 0; 7493 return impl::save_file_impl(*this, file.data, indent, flags, encoding) && fclose(file.release()) == 0;
7427 } 7494 }
7428 7495
7429 PUGI__FN bool xml_document::save_file(const wchar_t* path_, const char_t* indent, unsigned int flags, xml_encoding encoding) const 7496 PUGI_IMPL_FN bool xml_document::save_file(const wchar_t* path_, const char_t* indent, unsigned int flags, xml_encoding encoding) const
7430 { 7497 {
7431 using impl::auto_deleter; // MSVC7 workaround 7498 using impl::auto_deleter; // MSVC7 workaround
7432 auto_deleter<FILE> file(impl::open_file_wide(path_, (flags & format_save_file_text) ? L"w" : L"wb"), impl::close_file); 7499 auto_deleter<FILE> file(impl::open_file_wide(path_, (flags & format_save_file_text) ? L"w" : L"wb"), impl::close_file);
7433 7500
7434 return impl::save_file_impl(*this, file.data, indent, flags, encoding) && fclose(file.release()) == 0; 7501 return impl::save_file_impl(*this, file.data, indent, flags, encoding) && fclose(file.release()) == 0;
7435 } 7502 }
7436 7503
7437 PUGI__FN xml_node xml_document::document_element() const 7504 PUGI_IMPL_FN xml_node xml_document::document_element() const
7438 { 7505 {
7439 assert(_root); 7506 assert(_root);
7440 7507
7441 for (xml_node_struct* i = _root->first_child; i; i = i->next_sibling) 7508 for (xml_node_struct* i = _root->first_child; i; i = i->next_sibling)
7442 if (PUGI__NODETYPE(i) == node_element) 7509 if (PUGI_IMPL_NODETYPE(i) == node_element)
7443 return xml_node(i); 7510 return xml_node(i);
7444 7511
7445 return xml_node(); 7512 return xml_node();
7446 } 7513 }
7447 7514
7448 #ifndef PUGIXML_NO_STL 7515 #ifndef PUGIXML_NO_STL
7449 PUGI__FN std::string PUGIXML_FUNCTION as_utf8(const wchar_t* str) 7516 PUGI_IMPL_FN std::string PUGIXML_FUNCTION as_utf8(const wchar_t* str)
7450 { 7517 {
7451 assert(str); 7518 assert(str);
7452 7519
7453 return impl::as_utf8_impl(str, impl::strlength_wide(str)); 7520 return impl::as_utf8_impl(str, impl::strlength_wide(str));
7454 } 7521 }
7455 7522
7456 PUGI__FN std::string PUGIXML_FUNCTION as_utf8(const std::basic_string<wchar_t>& str) 7523 PUGI_IMPL_FN std::string PUGIXML_FUNCTION as_utf8(const std::basic_string<wchar_t>& str)
7457 { 7524 {
7458 return impl::as_utf8_impl(str.c_str(), str.size()); 7525 return impl::as_utf8_impl(str.c_str(), str.size());
7459 } 7526 }
7460 7527
7461 PUGI__FN std::basic_string<wchar_t> PUGIXML_FUNCTION as_wide(const char* str) 7528 PUGI_IMPL_FN std::basic_string<wchar_t> PUGIXML_FUNCTION as_wide(const char* str)
7462 { 7529 {
7463 assert(str); 7530 assert(str);
7464 7531
7465 return impl::as_wide_impl(str, strlen(str)); 7532 return impl::as_wide_impl(str, strlen(str));
7466 } 7533 }
7467 7534
7468 PUGI__FN std::basic_string<wchar_t> PUGIXML_FUNCTION as_wide(const std::string& str) 7535 PUGI_IMPL_FN std::basic_string<wchar_t> PUGIXML_FUNCTION as_wide(const std::string& str)
7469 { 7536 {
7470 return impl::as_wide_impl(str.c_str(), str.size()); 7537 return impl::as_wide_impl(str.c_str(), str.size());
7471 } 7538 }
7472 #endif 7539 #endif
7473 7540
7474 PUGI__FN void PUGIXML_FUNCTION set_memory_management_functions(allocation_function allocate, deallocation_function deallocate) 7541 PUGI_IMPL_FN void PUGIXML_FUNCTION set_memory_management_functions(allocation_function allocate, deallocation_function deallocate)
7475 { 7542 {
7476 impl::xml_memory::allocate = allocate; 7543 impl::xml_memory::allocate = allocate;
7477 impl::xml_memory::deallocate = deallocate; 7544 impl::xml_memory::deallocate = deallocate;
7478 } 7545 }
7479 7546
7480 PUGI__FN allocation_function PUGIXML_FUNCTION get_memory_allocation_function() 7547 PUGI_IMPL_FN allocation_function PUGIXML_FUNCTION get_memory_allocation_function()
7481 { 7548 {
7482 return impl::xml_memory::allocate; 7549 return impl::xml_memory::allocate;
7483 } 7550 }
7484 7551
7485 PUGI__FN deallocation_function PUGIXML_FUNCTION get_memory_deallocation_function() 7552 PUGI_IMPL_FN deallocation_function PUGIXML_FUNCTION get_memory_deallocation_function()
7486 { 7553 {
7487 return impl::xml_memory::deallocate; 7554 return impl::xml_memory::deallocate;
7488 } 7555 }
7489 } 7556 }
7490 7557
7491 #if !defined(PUGIXML_NO_STL) && (defined(_MSC_VER) || defined(__ICC)) 7558 #if !defined(PUGIXML_NO_STL) && (defined(_MSC_VER) || defined(__ICC))
7492 namespace std 7559 namespace std
7493 { 7560 {
7494 // Workarounds for (non-standard) iterator category detection for older versions (MSVC7/IC8 and earlier) 7561 // Workarounds for (non-standard) iterator category detection for older versions (MSVC7/IC8 and earlier)
7495 PUGI__FN std::bidirectional_iterator_tag _Iter_cat(const pugi::xml_node_iterator&) 7562 PUGI_IMPL_FN std::bidirectional_iterator_tag _Iter_cat(const pugi::xml_node_iterator&)
7496 { 7563 {
7497 return std::bidirectional_iterator_tag(); 7564 return std::bidirectional_iterator_tag();
7498 } 7565 }
7499 7566
7500 PUGI__FN std::bidirectional_iterator_tag _Iter_cat(const pugi::xml_attribute_iterator&) 7567 PUGI_IMPL_FN std::bidirectional_iterator_tag _Iter_cat(const pugi::xml_attribute_iterator&)
7501 { 7568 {
7502 return std::bidirectional_iterator_tag(); 7569 return std::bidirectional_iterator_tag();
7503 } 7570 }
7504 7571
7505 PUGI__FN std::bidirectional_iterator_tag _Iter_cat(const pugi::xml_named_node_iterator&) 7572 PUGI_IMPL_FN std::bidirectional_iterator_tag _Iter_cat(const pugi::xml_named_node_iterator&)
7506 { 7573 {
7507 return std::bidirectional_iterator_tag(); 7574 return std::bidirectional_iterator_tag();
7508 } 7575 }
7509 } 7576 }
7510 #endif 7577 #endif
7511 7578
7512 #if !defined(PUGIXML_NO_STL) && defined(__SUNPRO_CC) 7579 #if !defined(PUGIXML_NO_STL) && defined(__SUNPRO_CC)
7513 namespace std 7580 namespace std
7514 { 7581 {
7515 // Workarounds for (non-standard) iterator category detection 7582 // Workarounds for (non-standard) iterator category detection
7516 PUGI__FN std::bidirectional_iterator_tag __iterator_category(const pugi::xml_node_iterator&) 7583 PUGI_IMPL_FN std::bidirectional_iterator_tag __iterator_category(const pugi::xml_node_iterator&)
7517 { 7584 {
7518 return std::bidirectional_iterator_tag(); 7585 return std::bidirectional_iterator_tag();
7519 } 7586 }
7520 7587
7521 PUGI__FN std::bidirectional_iterator_tag __iterator_category(const pugi::xml_attribute_iterator&) 7588 PUGI_IMPL_FN std::bidirectional_iterator_tag __iterator_category(const pugi::xml_attribute_iterator&)
7522 { 7589 {
7523 return std::bidirectional_iterator_tag(); 7590 return std::bidirectional_iterator_tag();
7524 } 7591 }
7525 7592
7526 PUGI__FN std::bidirectional_iterator_tag __iterator_category(const pugi::xml_named_node_iterator&) 7593 PUGI_IMPL_FN std::bidirectional_iterator_tag __iterator_category(const pugi::xml_named_node_iterator&)
7527 { 7594 {
7528 return std::bidirectional_iterator_tag(); 7595 return std::bidirectional_iterator_tag();
7529 } 7596 }
7530 } 7597 }
7531 #endif 7598 #endif
7532 7599
7533 #ifndef PUGIXML_NO_XPATH 7600 #ifndef PUGIXML_NO_XPATH
7534 // STL replacements 7601 // STL replacements
7535 PUGI__NS_BEGIN 7602 PUGI_IMPL_NS_BEGIN
7536 struct equal_to 7603 struct equal_to
7537 { 7604 {
7538 template <typename T> bool operator()(const T& lhs, const T& rhs) const 7605 template <typename T> bool operator()(const T& lhs, const T& rhs) const
7539 { 7606 {
7540 return lhs == rhs; 7607 return lhs == rhs;
7570 T temp = lhs; 7637 T temp = lhs;
7571 lhs = rhs; 7638 lhs = rhs;
7572 rhs = temp; 7639 rhs = temp;
7573 } 7640 }
7574 7641
7575 template <typename I, typename Pred> PUGI__FN I min_element(I begin, I end, const Pred& pred) 7642 template <typename I, typename Pred> PUGI_IMPL_FN I min_element(I begin, I end, const Pred& pred)
7576 { 7643 {
7577 I result = begin; 7644 I result = begin;
7578 7645
7579 for (I it = begin + 1; it != end; ++it) 7646 for (I it = begin + 1; it != end; ++it)
7580 if (pred(*it, *result)) 7647 if (pred(*it, *result))
7581 result = it; 7648 result = it;
7582 7649
7583 return result; 7650 return result;
7584 } 7651 }
7585 7652
7586 template <typename I> PUGI__FN void reverse(I begin, I end) 7653 template <typename I> PUGI_IMPL_FN void reverse(I begin, I end)
7587 { 7654 {
7588 while (end - begin > 1) 7655 while (end - begin > 1)
7589 swap(*begin++, *--end); 7656 swap(*begin++, *--end);
7590 } 7657 }
7591 7658
7592 template <typename I> PUGI__FN I unique(I begin, I end) 7659 template <typename I> PUGI_IMPL_FN I unique(I begin, I end)
7593 { 7660 {
7594 // fast skip head 7661 // fast skip head
7595 while (end - begin > 1 && *begin != *(begin + 1)) 7662 while (end - begin > 1 && *begin != *(begin + 1))
7596 begin++; 7663 begin++;
7597 7664
7612 7679
7613 // past-the-end (write points to live element) 7680 // past-the-end (write points to live element)
7614 return write + 1; 7681 return write + 1;
7615 } 7682 }
7616 7683
7617 template <typename T, typename Pred> PUGI__FN void insertion_sort(T* begin, T* end, const Pred& pred) 7684 template <typename T, typename Pred> PUGI_IMPL_FN void insertion_sort(T* begin, T* end, const Pred& pred)
7618 { 7685 {
7619 if (begin == end) 7686 if (begin == end)
7620 return; 7687 return;
7621 7688
7622 for (T* it = begin + 1; it != end; ++it) 7689 for (T* it = begin + 1; it != end; ++it)
7646 swap(middle, first); 7713 swap(middle, first);
7647 7714
7648 return middle; 7715 return middle;
7649 } 7716 }
7650 7717
7651 template <typename T, typename Pred> PUGI__FN void partition3(T* begin, T* end, T pivot, const Pred& pred, T** out_eqbeg, T** out_eqend) 7718 template <typename T, typename Pred> PUGI_IMPL_FN void partition3(T* begin, T* end, T pivot, const Pred& pred, T** out_eqbeg, T** out_eqend)
7652 { 7719 {
7653 // invariant: array is split into 4 groups: = < ? > (each variable denotes the boundary between the groups) 7720 // invariant: array is split into 4 groups: = < ? > (each variable denotes the boundary between the groups)
7654 T* eq = begin; 7721 T* eq = begin;
7655 T* lt = begin; 7722 T* lt = begin;
7656 T* gt = end; 7723 T* gt = end;
7673 7740
7674 *out_eqbeg = eqbeg; 7741 *out_eqbeg = eqbeg;
7675 *out_eqend = gt; 7742 *out_eqend = gt;
7676 } 7743 }
7677 7744
7678 template <typename I, typename Pred> PUGI__FN void sort(I begin, I end, const Pred& pred) 7745 template <typename I, typename Pred> PUGI_IMPL_FN void sort(I begin, I end, const Pred& pred)
7679 { 7746 {
7680 // sort large chunks 7747 // sort large chunks
7681 while (end - begin > 16) 7748 while (end - begin > 16)
7682 { 7749 {
7683 // find median element 7750 // find median element
7703 7770
7704 // insertion sort small chunk 7771 // insertion sort small chunk
7705 insertion_sort(begin, end, pred); 7772 insertion_sort(begin, end, pred);
7706 } 7773 }
7707 7774
7708 PUGI__FN bool hash_insert(const void** table, size_t size, const void* key) 7775 PUGI_IMPL_FN bool hash_insert(const void** table, size_t size, const void* key)
7709 { 7776 {
7710 assert(key); 7777 assert(key);
7711 7778
7712 unsigned int h = static_cast<unsigned int>(reinterpret_cast<uintptr_t>(key)); 7779 unsigned int h = static_cast<unsigned int>(reinterpret_cast<uintptr_t>(key));
7713 7780
7737 } 7804 }
7738 7805
7739 assert(false && "Hash table is full"); // unreachable 7806 assert(false && "Hash table is full"); // unreachable
7740 return false; 7807 return false;
7741 } 7808 }
7742 PUGI__NS_END 7809 PUGI_IMPL_NS_END
7743 7810
7744 // Allocator used for AST and evaluation stacks 7811 // Allocator used for AST and evaluation stacks
7745 PUGI__NS_BEGIN 7812 PUGI_IMPL_NS_BEGIN
7746 static const size_t xpath_memory_page_size = 7813 static const size_t xpath_memory_page_size =
7747 #ifdef PUGIXML_MEMORY_XPATH_PAGE_SIZE 7814 #ifdef PUGIXML_MEMORY_XPATH_PAGE_SIZE
7748 PUGIXML_MEMORY_XPATH_PAGE_SIZE 7815 PUGIXML_MEMORY_XPATH_PAGE_SIZE
7749 #else 7816 #else
7750 4096 7817 4096
7936 { 8003 {
7937 result.release(); 8004 result.release();
7938 temp.release(); 8005 temp.release();
7939 } 8006 }
7940 }; 8007 };
7941 PUGI__NS_END 8008 PUGI_IMPL_NS_END
7942 8009
7943 // String class 8010 // String class
7944 PUGI__NS_BEGIN 8011 PUGI_IMPL_NS_BEGIN
7945 class xpath_string 8012 class xpath_string
7946 { 8013 {
7947 const char_t* _buffer; 8014 const char_t* _buffer;
7948 bool _uses_heap; 8015 bool _uses_heap;
7949 size_t _length_heap; 8016 size_t _length_heap;
8074 bool uses_heap() const 8141 bool uses_heap() const
8075 { 8142 {
8076 return _uses_heap; 8143 return _uses_heap;
8077 } 8144 }
8078 }; 8145 };
8079 PUGI__NS_END 8146 PUGI_IMPL_NS_END
8080 8147
8081 PUGI__NS_BEGIN 8148 PUGI_IMPL_NS_BEGIN
8082 PUGI__FN bool starts_with(const char_t* string, const char_t* pattern) 8149 PUGI_IMPL_FN bool starts_with(const char_t* string, const char_t* pattern)
8083 { 8150 {
8084 while (*pattern && *string == *pattern) 8151 while (*pattern && *string == *pattern)
8085 { 8152 {
8086 string++; 8153 string++;
8087 pattern++; 8154 pattern++;
8088 } 8155 }
8089 8156
8090 return *pattern == 0; 8157 return *pattern == 0;
8091 } 8158 }
8092 8159
8093 PUGI__FN const char_t* find_char(const char_t* s, char_t c) 8160 PUGI_IMPL_FN const char_t* find_char(const char_t* s, char_t c)
8094 { 8161 {
8095 #ifdef PUGIXML_WCHAR_MODE 8162 #ifdef PUGIXML_WCHAR_MODE
8096 return wcschr(s, c); 8163 return wcschr(s, c);
8097 #else 8164 #else
8098 return strchr(s, c); 8165 return strchr(s, c);
8099 #endif 8166 #endif
8100 } 8167 }
8101 8168
8102 PUGI__FN const char_t* find_substring(const char_t* s, const char_t* p) 8169 PUGI_IMPL_FN const char_t* find_substring(const char_t* s, const char_t* p)
8103 { 8170 {
8104 #ifdef PUGIXML_WCHAR_MODE 8171 #ifdef PUGIXML_WCHAR_MODE
8105 // MSVC6 wcsstr bug workaround (if s is empty it always returns 0) 8172 // MSVC6 wcsstr bug workaround (if s is empty it always returns 0)
8106 return (*p == 0) ? s : wcsstr(s, p); 8173 return (*p == 0) ? s : wcsstr(s, p);
8107 #else 8174 #else
8108 return strstr(s, p); 8175 return strstr(s, p);
8109 #endif 8176 #endif
8110 } 8177 }
8111 8178
8112 // Converts symbol to lower case, if it is an ASCII one 8179 // Converts symbol to lower case, if it is an ASCII one
8113 PUGI__FN char_t tolower_ascii(char_t ch) 8180 PUGI_IMPL_FN char_t tolower_ascii(char_t ch)
8114 { 8181 {
8115 return static_cast<unsigned int>(ch - 'A') < 26 ? static_cast<char_t>(ch | ' ') : ch; 8182 return static_cast<unsigned int>(ch - 'A') < 26 ? static_cast<char_t>(ch | ' ') : ch;
8116 } 8183 }
8117 8184
8118 PUGI__FN xpath_string string_value(const xpath_node& na, xpath_allocator* alloc) 8185 PUGI_IMPL_FN xpath_string string_value(const xpath_node& na, xpath_allocator* alloc)
8119 { 8186 {
8120 if (na.attribute()) 8187 if (na.attribute())
8121 return xpath_string::from_const(na.attribute().value()); 8188 return xpath_string::from_const(na.attribute().value());
8122 else 8189 else
8123 { 8190 {
8167 return xpath_string(); 8234 return xpath_string();
8168 } 8235 }
8169 } 8236 }
8170 } 8237 }
8171 8238
8172 PUGI__FN bool node_is_before_sibling(xml_node_struct* ln, xml_node_struct* rn) 8239 PUGI_IMPL_FN bool node_is_before_sibling(xml_node_struct* ln, xml_node_struct* rn)
8173 { 8240 {
8174 assert(ln->parent == rn->parent); 8241 assert(ln->parent == rn->parent);
8175 8242
8176 // there is no common ancestor (the shared parent is null), nodes are from different documents 8243 // there is no common ancestor (the shared parent is null), nodes are from different documents
8177 if (!ln->parent) return ln < rn; 8244 if (!ln->parent) return ln < rn;
8191 8258
8192 // if rn sibling chain ended ln must be before rn 8259 // if rn sibling chain ended ln must be before rn
8193 return !rs; 8260 return !rs;
8194 } 8261 }
8195 8262
8196 PUGI__FN bool node_is_before(xml_node_struct* ln, xml_node_struct* rn) 8263 PUGI_IMPL_FN bool node_is_before(xml_node_struct* ln, xml_node_struct* rn)
8197 { 8264 {
8198 // find common ancestor at the same depth, if any 8265 // find common ancestor at the same depth, if any
8199 xml_node_struct* lp = ln; 8266 xml_node_struct* lp = ln;
8200 xml_node_struct* rp = rn; 8267 xml_node_struct* rp = rn;
8201 8268
8234 } 8301 }
8235 8302
8236 return node_is_before_sibling(ln, rn); 8303 return node_is_before_sibling(ln, rn);
8237 } 8304 }
8238 8305
8239 PUGI__FN bool node_is_ancestor(xml_node_struct* parent, xml_node_struct* node) 8306 PUGI_IMPL_FN bool node_is_ancestor(xml_node_struct* parent, xml_node_struct* node)
8240 { 8307 {
8241 while (node && node != parent) node = node->parent; 8308 while (node && node != parent) node = node->parent;
8242 8309
8243 return parent && node == parent; 8310 return parent && node == parent;
8244 } 8311 }
8245 8312
8246 PUGI__FN const void* document_buffer_order(const xpath_node& xnode) 8313 PUGI_IMPL_FN const void* document_buffer_order(const xpath_node& xnode)
8247 { 8314 {
8248 xml_node_struct* node = xnode.node().internal_object(); 8315 xml_node_struct* node = xnode.node().internal_object();
8249 8316
8250 if (node) 8317 if (node)
8251 { 8318 {
8326 8393
8327 return node_is_before(ln.internal_object(), rn.internal_object()); 8394 return node_is_before(ln.internal_object(), rn.internal_object());
8328 } 8395 }
8329 }; 8396 };
8330 8397
8331 PUGI__FN double gen_nan() 8398 PUGI_IMPL_FN double gen_nan()
8332 { 8399 {
8333 #if defined(__STDC_IEC_559__) || ((FLT_RADIX - 0 == 2) && (FLT_MAX_EXP - 0 == 128) && (FLT_MANT_DIG - 0 == 24)) 8400 #if defined(__STDC_IEC_559__) || ((FLT_RADIX - 0 == 2) && (FLT_MAX_EXP - 0 == 128) && (FLT_MANT_DIG - 0 == 24))
8334 PUGI__STATIC_ASSERT(sizeof(float) == sizeof(uint32_t)); 8401 PUGI_IMPL_STATIC_ASSERT(sizeof(float) == sizeof(uint32_t));
8335 typedef uint32_t UI; // BCC5 workaround 8402 typedef uint32_t UI; // BCC5 workaround
8336 union { float f; UI i; } u; 8403 union { float f; UI i; } u;
8337 u.i = 0x7fc00000; 8404 u.i = 0x7fc00000;
8338 return double(u.f); 8405 return double(u.f);
8339 #else 8406 #else
8341 const volatile double zero = 0.0; 8408 const volatile double zero = 0.0;
8342 return zero / zero; 8409 return zero / zero;
8343 #endif 8410 #endif
8344 } 8411 }
8345 8412
8346 PUGI__FN bool is_nan(double value) 8413 PUGI_IMPL_FN bool is_nan(double value)
8347 { 8414 {
8348 #if defined(PUGI__MSVC_CRT_VERSION) || defined(__BORLANDC__) 8415 #if defined(PUGI_IMPL_MSVC_CRT_VERSION) || defined(__BORLANDC__)
8349 return !!_isnan(value); 8416 return !!_isnan(value);
8350 #elif defined(fpclassify) && defined(FP_NAN) 8417 #elif defined(fpclassify) && defined(FP_NAN)
8351 return fpclassify(value) == FP_NAN; 8418 return fpclassify(value) == FP_NAN;
8352 #else 8419 #else
8353 // fallback 8420 // fallback
8354 const volatile double v = value; 8421 const volatile double v = value;
8355 return v != v; 8422 return v != v;
8356 #endif 8423 #endif
8357 } 8424 }
8358 8425
8359 PUGI__FN const char_t* convert_number_to_string_special(double value) 8426 PUGI_IMPL_FN const char_t* convert_number_to_string_special(double value)
8360 { 8427 {
8361 #if defined(PUGI__MSVC_CRT_VERSION) || defined(__BORLANDC__) 8428 #if defined(PUGI_IMPL_MSVC_CRT_VERSION) || defined(__BORLANDC__)
8362 if (_finite(value)) return (value == 0) ? PUGIXML_TEXT("0") : 0; 8429 if (_finite(value)) return (value == 0) ? PUGIXML_TEXT("0") : 0;
8363 if (_isnan(value)) return PUGIXML_TEXT("NaN"); 8430 if (_isnan(value)) return PUGIXML_TEXT("NaN");
8364 return value > 0 ? PUGIXML_TEXT("Infinity") : PUGIXML_TEXT("-Infinity"); 8431 return value > 0 ? PUGIXML_TEXT("Infinity") : PUGIXML_TEXT("-Infinity");
8365 #elif defined(fpclassify) && defined(FP_NAN) && defined(FP_INFINITE) && defined(FP_ZERO) 8432 #elif defined(fpclassify) && defined(FP_NAN) && defined(FP_INFINITE) && defined(FP_ZERO)
8366 switch (fpclassify(value)) 8433 switch (fpclassify(value))
8386 if (v * 2 == v) return value > 0 ? PUGIXML_TEXT("Infinity") : PUGIXML_TEXT("-Infinity"); 8453 if (v * 2 == v) return value > 0 ? PUGIXML_TEXT("Infinity") : PUGIXML_TEXT("-Infinity");
8387 return 0; 8454 return 0;
8388 #endif 8455 #endif
8389 } 8456 }
8390 8457
8391 PUGI__FN bool convert_number_to_boolean(double value) 8458 PUGI_IMPL_FN bool convert_number_to_boolean(double value)
8392 { 8459 {
8393 return (value != 0 && !is_nan(value)); 8460 return (value != 0 && !is_nan(value));
8394 } 8461 }
8395 8462
8396 PUGI__FN void truncate_zeros(char* begin, char* end) 8463 PUGI_IMPL_FN void truncate_zeros(char* begin, char* end)
8397 { 8464 {
8398 while (begin != end && end[-1] == '0') end--; 8465 while (begin != end && end[-1] == '0') end--;
8399 8466
8400 *end = 0; 8467 *end = 0;
8401 } 8468 }
8402 8469
8403 // gets mantissa digits in the form of 0.xxxxx with 0. implied and the exponent 8470 // gets mantissa digits in the form of 0.xxxxx with 0. implied and the exponent
8404 #if defined(PUGI__MSVC_CRT_VERSION) && PUGI__MSVC_CRT_VERSION >= 1400 8471 #if defined(PUGI_IMPL_MSVC_CRT_VERSION) && PUGI_IMPL_MSVC_CRT_VERSION >= 1400
8405 PUGI__FN void convert_number_to_mantissa_exponent(double value, char (&buffer)[32], char** out_mantissa, int* out_exponent) 8472 PUGI_IMPL_FN void convert_number_to_mantissa_exponent(double value, char (&buffer)[32], char** out_mantissa, int* out_exponent)
8406 { 8473 {
8407 // get base values 8474 // get base values
8408 int sign, exponent; 8475 int sign, exponent;
8409 _ecvt_s(buffer, sizeof(buffer), value, DBL_DIG + 1, &exponent, &sign); 8476 _ecvt_s(buffer, sizeof(buffer), value, DBL_DIG + 1, &exponent, &sign);
8410 8477
8414 // fill results 8481 // fill results
8415 *out_mantissa = buffer; 8482 *out_mantissa = buffer;
8416 *out_exponent = exponent; 8483 *out_exponent = exponent;
8417 } 8484 }
8418 #else 8485 #else
8419 PUGI__FN void convert_number_to_mantissa_exponent(double value, char (&buffer)[32], char** out_mantissa, int* out_exponent) 8486 PUGI_IMPL_FN void convert_number_to_mantissa_exponent(double value, char (&buffer)[32], char** out_mantissa, int* out_exponent)
8420 { 8487 {
8421 // get a scientific notation value with IEEE DBL_DIG decimals 8488 // get a scientific notation value with IEEE DBL_DIG decimals
8422 PUGI__SNPRINTF(buffer, "%.*e", DBL_DIG, value); 8489 PUGI_IMPL_SNPRINTF(buffer, "%.*e", DBL_DIG, value);
8423 8490
8424 // get the exponent (possibly negative) 8491 // get the exponent (possibly negative)
8425 char* exponent_string = strchr(buffer, 'e'); 8492 char* exponent_string = strchr(buffer, 'e');
8426 assert(exponent_string); 8493 assert(exponent_string);
8427 8494
8428 int exponent = atoi(exponent_string + 1); 8495 int exponent = atoi(exponent_string + 1);
8429 8496
8430 // extract mantissa string: skip sign 8497 // extract mantissa string: skip sign
8431 char* mantissa = buffer[0] == '-' ? buffer + 1 : buffer; 8498 char* mantissa = buffer[0] == '-' ? buffer + 1 : buffer;
8432 assert(mantissa[0] != '0' && mantissa[1] == '.'); 8499 assert(mantissa[0] != '0' && (mantissa[1] == '.' || mantissa[1] == ','));
8433 8500
8434 // divide mantissa by 10 to eliminate integer part 8501 // divide mantissa by 10 to eliminate integer part
8435 mantissa[1] = mantissa[0]; 8502 mantissa[1] = mantissa[0];
8436 mantissa++; 8503 mantissa++;
8437 exponent++; 8504 exponent++;
8443 *out_mantissa = mantissa; 8510 *out_mantissa = mantissa;
8444 *out_exponent = exponent; 8511 *out_exponent = exponent;
8445 } 8512 }
8446 #endif 8513 #endif
8447 8514
8448 PUGI__FN xpath_string convert_number_to_string(double value, xpath_allocator* alloc) 8515 PUGI_IMPL_FN xpath_string convert_number_to_string(double value, xpath_allocator* alloc)
8449 { 8516 {
8450 // try special number conversion 8517 // try special number conversion
8451 const char_t* special = convert_number_to_string_special(value); 8518 const char_t* special = convert_number_to_string_special(value);
8452 if (special) return xpath_string::from_const(special); 8519 if (special) return xpath_string::from_const(special);
8453 8520
8510 *s = 0; 8577 *s = 0;
8511 8578
8512 return xpath_string::from_heap_preallocated(result, s); 8579 return xpath_string::from_heap_preallocated(result, s);
8513 } 8580 }
8514 8581
8515 PUGI__FN bool check_string_to_number_format(const char_t* string) 8582 PUGI_IMPL_FN bool check_string_to_number_format(const char_t* string)
8516 { 8583 {
8517 // parse leading whitespace 8584 // parse leading whitespace
8518 while (PUGI__IS_CHARTYPE(*string, ct_space)) ++string; 8585 while (PUGI_IMPL_IS_CHARTYPE(*string, ct_space)) ++string;
8519 8586
8520 // parse sign 8587 // parse sign
8521 if (*string == '-') ++string; 8588 if (*string == '-') ++string;
8522 8589
8523 if (!*string) return false; 8590 if (!*string) return false;
8524 8591
8525 // if there is no integer part, there should be a decimal part with at least one digit 8592 // if there is no integer part, there should be a decimal part with at least one digit
8526 if (!PUGI__IS_CHARTYPEX(string[0], ctx_digit) && (string[0] != '.' || !PUGI__IS_CHARTYPEX(string[1], ctx_digit))) return false; 8593 if (!PUGI_IMPL_IS_CHARTYPEX(string[0], ctx_digit) && (string[0] != '.' || !PUGI_IMPL_IS_CHARTYPEX(string[1], ctx_digit))) return false;
8527 8594
8528 // parse integer part 8595 // parse integer part
8529 while (PUGI__IS_CHARTYPEX(*string, ctx_digit)) ++string; 8596 while (PUGI_IMPL_IS_CHARTYPEX(*string, ctx_digit)) ++string;
8530 8597
8531 // parse decimal part 8598 // parse decimal part
8532 if (*string == '.') 8599 if (*string == '.')
8533 { 8600 {
8534 ++string; 8601 ++string;
8535 8602
8536 while (PUGI__IS_CHARTYPEX(*string, ctx_digit)) ++string; 8603 while (PUGI_IMPL_IS_CHARTYPEX(*string, ctx_digit)) ++string;
8537 } 8604 }
8538 8605
8539 // parse trailing whitespace 8606 // parse trailing whitespace
8540 while (PUGI__IS_CHARTYPE(*string, ct_space)) ++string; 8607 while (PUGI_IMPL_IS_CHARTYPE(*string, ct_space)) ++string;
8541 8608
8542 return *string == 0; 8609 return *string == 0;
8543 } 8610 }
8544 8611
8545 PUGI__FN double convert_string_to_number(const char_t* string) 8612 PUGI_IMPL_FN double convert_string_to_number(const char_t* string)
8546 { 8613 {
8547 // check string format 8614 // check string format
8548 if (!check_string_to_number_format(string)) return gen_nan(); 8615 if (!check_string_to_number_format(string)) return gen_nan();
8549 8616
8550 // parse string 8617 // parse string
8553 #else 8620 #else
8554 return strtod(string, 0); 8621 return strtod(string, 0);
8555 #endif 8622 #endif
8556 } 8623 }
8557 8624
8558 PUGI__FN bool convert_string_to_number_scratch(char_t (&buffer)[32], const char_t* begin, const char_t* end, double* out_result) 8625 PUGI_IMPL_FN bool convert_string_to_number_scratch(char_t (&buffer)[32], const char_t* begin, const char_t* end, double* out_result)
8559 { 8626 {
8560 size_t length = static_cast<size_t>(end - begin); 8627 size_t length = static_cast<size_t>(end - begin);
8561 char_t* scratch = buffer; 8628 char_t* scratch = buffer;
8562 8629
8563 if (length >= sizeof(buffer) / sizeof(buffer[0])) 8630 if (length >= sizeof(buffer) / sizeof(buffer[0]))
8577 if (scratch != buffer) xml_memory::deallocate(scratch); 8644 if (scratch != buffer) xml_memory::deallocate(scratch);
8578 8645
8579 return true; 8646 return true;
8580 } 8647 }
8581 8648
8582 PUGI__FN double round_nearest(double value) 8649 PUGI_IMPL_FN double round_nearest(double value)
8583 { 8650 {
8584 return floor(value + 0.5); 8651 return floor(value + 0.5);
8585 } 8652 }
8586 8653
8587 PUGI__FN double round_nearest_nzero(double value) 8654 PUGI_IMPL_FN double round_nearest_nzero(double value)
8588 { 8655 {
8589 // same as round_nearest, but returns -0 for [-0.5, -0] 8656 // same as round_nearest, but returns -0 for [-0.5, -0]
8590 // ceil is used to differentiate between +0 and -0 (we return -0 for [-0.5, -0] and +0 for +0) 8657 // ceil is used to differentiate between +0 and -0 (we return -0 for [-0.5, -0] and +0 for +0)
8591 return (value >= -0.5 && value <= 0) ? ceil(value) : floor(value + 0.5); 8658 return (value >= -0.5 && value <= 0) ? ceil(value) : floor(value + 0.5);
8592 } 8659 }
8593 8660
8594 PUGI__FN const char_t* qualified_name(const xpath_node& node) 8661 PUGI_IMPL_FN const char_t* qualified_name(const xpath_node& node)
8595 { 8662 {
8596 return node.attribute() ? node.attribute().name() : node.node().name(); 8663 return node.attribute() ? node.attribute().name() : node.node().name();
8597 } 8664 }
8598 8665
8599 PUGI__FN const char_t* local_name(const xpath_node& node) 8666 PUGI_IMPL_FN const char_t* local_name(const xpath_node& node)
8600 { 8667 {
8601 const char_t* name = qualified_name(node); 8668 const char_t* name = qualified_name(node);
8602 const char_t* p = find_char(name, ':'); 8669 const char_t* p = find_char(name, ':');
8603 8670
8604 return p ? p + 1 : name; 8671 return p ? p + 1 : name;
8625 8692
8626 return prefix ? name[5] == ':' && strequalrange(name + 6, prefix, prefix_length) : name[5] == 0; 8693 return prefix ? name[5] == ':' && strequalrange(name + 6, prefix, prefix_length) : name[5] == 0;
8627 } 8694 }
8628 }; 8695 };
8629 8696
8630 PUGI__FN const char_t* namespace_uri(xml_node node) 8697 PUGI_IMPL_FN const char_t* namespace_uri(xml_node node)
8631 { 8698 {
8632 namespace_uri_predicate pred = node.name(); 8699 namespace_uri_predicate pred = node.name();
8633 8700
8634 xml_node p = node; 8701 xml_node p = node;
8635 8702
8643 } 8710 }
8644 8711
8645 return PUGIXML_TEXT(""); 8712 return PUGIXML_TEXT("");
8646 } 8713 }
8647 8714
8648 PUGI__FN const char_t* namespace_uri(xml_attribute attr, xml_node parent) 8715 PUGI_IMPL_FN const char_t* namespace_uri(xml_attribute attr, xml_node parent)
8649 { 8716 {
8650 namespace_uri_predicate pred = attr.name(); 8717 namespace_uri_predicate pred = attr.name();
8651 8718
8652 // Default namespace does not apply to attributes 8719 // Default namespace does not apply to attributes
8653 if (!pred.prefix) return PUGIXML_TEXT(""); 8720 if (!pred.prefix) return PUGIXML_TEXT("");
8664 } 8731 }
8665 8732
8666 return PUGIXML_TEXT(""); 8733 return PUGIXML_TEXT("");
8667 } 8734 }
8668 8735
8669 PUGI__FN const char_t* namespace_uri(const xpath_node& node) 8736 PUGI_IMPL_FN const char_t* namespace_uri(const xpath_node& node)
8670 { 8737 {
8671 return node.attribute() ? namespace_uri(node.attribute(), node.parent()) : namespace_uri(node.node()); 8738 return node.attribute() ? namespace_uri(node.attribute(), node.parent()) : namespace_uri(node.node());
8672 } 8739 }
8673 8740
8674 PUGI__FN char_t* normalize_space(char_t* buffer) 8741 PUGI_IMPL_FN char_t* normalize_space(char_t* buffer)
8675 { 8742 {
8676 char_t* write = buffer; 8743 char_t* write = buffer;
8677 8744
8678 for (char_t* it = buffer; *it; ) 8745 for (char_t* it = buffer; *it; )
8679 { 8746 {
8680 char_t ch = *it++; 8747 char_t ch = *it++;
8681 8748
8682 if (PUGI__IS_CHARTYPE(ch, ct_space)) 8749 if (PUGI_IMPL_IS_CHARTYPE(ch, ct_space))
8683 { 8750 {
8684 // replace whitespace sequence with single space 8751 // replace whitespace sequence with single space
8685 while (PUGI__IS_CHARTYPE(*it, ct_space)) it++; 8752 while (PUGI_IMPL_IS_CHARTYPE(*it, ct_space)) it++;
8686 8753
8687 // avoid leading spaces 8754 // avoid leading spaces
8688 if (write != buffer) *write++ = ' '; 8755 if (write != buffer) *write++ = ' ';
8689 } 8756 }
8690 else *write++ = ch; 8757 else *write++ = ch;
8691 } 8758 }
8692 8759
8693 // remove trailing space 8760 // remove trailing space
8694 if (write != buffer && PUGI__IS_CHARTYPE(write[-1], ct_space)) write--; 8761 if (write != buffer && PUGI_IMPL_IS_CHARTYPE(write[-1], ct_space)) write--;
8695 8762
8696 // zero-terminate 8763 // zero-terminate
8697 *write = 0; 8764 *write = 0;
8698 8765
8699 return write; 8766 return write;
8700 } 8767 }
8701 8768
8702 PUGI__FN char_t* translate(char_t* buffer, const char_t* from, const char_t* to, size_t to_length) 8769 PUGI_IMPL_FN char_t* translate(char_t* buffer, const char_t* from, const char_t* to, size_t to_length)
8703 { 8770 {
8704 char_t* write = buffer; 8771 char_t* write = buffer;
8705 8772
8706 while (*buffer) 8773 while (*buffer)
8707 { 8774 {
8708 PUGI__DMC_VOLATILE char_t ch = *buffer++; 8775 PUGI_IMPL_DMC_VOLATILE char_t ch = *buffer++;
8709 8776
8710 const char_t* pos = find_char(from, ch); 8777 const char_t* pos = find_char(from, ch);
8711 8778
8712 if (!pos) 8779 if (!pos)
8713 *write++ = ch; // do not process 8780 *write++ = ch; // do not process
8719 *write = 0; 8786 *write = 0;
8720 8787
8721 return write; 8788 return write;
8722 } 8789 }
8723 8790
8724 PUGI__FN unsigned char* translate_table_generate(xpath_allocator* alloc, const char_t* from, const char_t* to) 8791 PUGI_IMPL_FN unsigned char* translate_table_generate(xpath_allocator* alloc, const char_t* from, const char_t* to)
8725 { 8792 {
8726 unsigned char table[128] = {0}; 8793 unsigned char table[128] = {0};
8727 8794
8728 while (*from) 8795 while (*from)
8729 { 8796 {
8751 memcpy(result, table, sizeof(table)); 8818 memcpy(result, table, sizeof(table));
8752 8819
8753 return static_cast<unsigned char*>(result); 8820 return static_cast<unsigned char*>(result);
8754 } 8821 }
8755 8822
8756 PUGI__FN char_t* translate_table(char_t* buffer, const unsigned char* table) 8823 PUGI_IMPL_FN char_t* translate_table(char_t* buffer, const unsigned char* table)
8757 { 8824 {
8758 char_t* write = buffer; 8825 char_t* write = buffer;
8759 8826
8760 while (*buffer) 8827 while (*buffer)
8761 { 8828 {
8833 char_t name[1]; 8900 char_t name[1];
8834 }; 8901 };
8835 8902
8836 static const xpath_node_set dummy_node_set; 8903 static const xpath_node_set dummy_node_set;
8837 8904
8838 PUGI__FN PUGI__UNSIGNED_OVERFLOW unsigned int hash_string(const char_t* str) 8905 PUGI_IMPL_FN PUGI_IMPL_UNSIGNED_OVERFLOW unsigned int hash_string(const char_t* str)
8839 { 8906 {
8840 // Jenkins one-at-a-time hash (http://en.wikipedia.org/wiki/Jenkins_hash_function#one-at-a-time) 8907 // Jenkins one-at-a-time hash (http://en.wikipedia.org/wiki/Jenkins_hash_function#one-at-a-time)
8841 unsigned int result = 0; 8908 unsigned int result = 0;
8842 8909
8843 while (*str) 8910 while (*str)
8852 result += result << 15; 8919 result += result << 15;
8853 8920
8854 return result; 8921 return result;
8855 } 8922 }
8856 8923
8857 template <typename T> PUGI__FN T* new_xpath_variable(const char_t* name) 8924 template <typename T> PUGI_IMPL_FN T* new_xpath_variable(const char_t* name)
8858 { 8925 {
8859 size_t length = strlength(name); 8926 size_t length = strlength(name);
8860 if (length == 0) return 0; // empty variable names are invalid 8927 if (length == 0) return 0; // empty variable names are invalid
8861 8928
8862 // $$ we can't use offsetof(T, name) because T is non-POD, so we just allocate additional length characters 8929 // $$ we can't use offsetof(T, name) because T is non-POD, so we just allocate additional length characters
8868 memcpy(result->name, name, (length + 1) * sizeof(char_t)); 8935 memcpy(result->name, name, (length + 1) * sizeof(char_t));
8869 8936
8870 return result; 8937 return result;
8871 } 8938 }
8872 8939
8873 PUGI__FN xpath_variable* new_xpath_variable(xpath_value_type type, const char_t* name) 8940 PUGI_IMPL_FN xpath_variable* new_xpath_variable(xpath_value_type type, const char_t* name)
8874 { 8941 {
8875 switch (type) 8942 switch (type)
8876 { 8943 {
8877 case xpath_type_node_set: 8944 case xpath_type_node_set:
8878 return new_xpath_variable<xpath_variable_node_set>(name); 8945 return new_xpath_variable<xpath_variable_node_set>(name);
8889 default: 8956 default:
8890 return 0; 8957 return 0;
8891 } 8958 }
8892 } 8959 }
8893 8960
8894 template <typename T> PUGI__FN void delete_xpath_variable(T* var) 8961 template <typename T> PUGI_IMPL_FN void delete_xpath_variable(T* var)
8895 { 8962 {
8896 var->~T(); 8963 var->~T();
8897 xml_memory::deallocate(var); 8964 xml_memory::deallocate(var);
8898 } 8965 }
8899 8966
8900 PUGI__FN void delete_xpath_variable(xpath_value_type type, xpath_variable* var) 8967 PUGI_IMPL_FN void delete_xpath_variable(xpath_value_type type, xpath_variable* var)
8901 { 8968 {
8902 switch (type) 8969 switch (type)
8903 { 8970 {
8904 case xpath_type_node_set: 8971 case xpath_type_node_set:
8905 delete_xpath_variable(static_cast<xpath_variable_node_set*>(var)); 8972 delete_xpath_variable(static_cast<xpath_variable_node_set*>(var));
8920 default: 8987 default:
8921 assert(false && "Invalid variable type"); // unreachable 8988 assert(false && "Invalid variable type"); // unreachable
8922 } 8989 }
8923 } 8990 }
8924 8991
8925 PUGI__FN bool copy_xpath_variable(xpath_variable* lhs, const xpath_variable* rhs) 8992 PUGI_IMPL_FN bool copy_xpath_variable(xpath_variable* lhs, const xpath_variable* rhs)
8926 { 8993 {
8927 switch (rhs->type()) 8994 switch (rhs->type())
8928 { 8995 {
8929 case xpath_type_node_set: 8996 case xpath_type_node_set:
8930 return lhs->set(static_cast<const xpath_variable_node_set*>(rhs)->value); 8997 return lhs->set(static_cast<const xpath_variable_node_set*>(rhs)->value);
8942 assert(false && "Invalid variable type"); // unreachable 9009 assert(false && "Invalid variable type"); // unreachable
8943 return false; 9010 return false;
8944 } 9011 }
8945 } 9012 }
8946 9013
8947 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) 9014 PUGI_IMPL_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)
8948 { 9015 {
8949 size_t length = static_cast<size_t>(end - begin); 9016 size_t length = static_cast<size_t>(end - begin);
8950 char_t* scratch = buffer; 9017 char_t* scratch = buffer;
8951 9018
8952 if (length >= sizeof(buffer) / sizeof(buffer[0])) 9019 if (length >= sizeof(buffer) / sizeof(buffer[0]))
8965 // free dummy buffer 9032 // free dummy buffer
8966 if (scratch != buffer) xml_memory::deallocate(scratch); 9033 if (scratch != buffer) xml_memory::deallocate(scratch);
8967 9034
8968 return true; 9035 return true;
8969 } 9036 }
8970 PUGI__NS_END 9037 PUGI_IMPL_NS_END
8971 9038
8972 // Internal node set class 9039 // Internal node set class
8973 PUGI__NS_BEGIN 9040 PUGI_IMPL_NS_BEGIN
8974 PUGI__FN xpath_node_set::type_t xpath_get_order(const xpath_node* begin, const xpath_node* end) 9041 PUGI_IMPL_FN xpath_node_set::type_t xpath_get_order(const xpath_node* begin, const xpath_node* end)
8975 { 9042 {
8976 if (end - begin < 2) 9043 if (end - begin < 2)
8977 return xpath_node_set::type_sorted; 9044 return xpath_node_set::type_sorted;
8978 9045
8979 document_order_comparator cmp; 9046 document_order_comparator cmp;
8985 return xpath_node_set::type_unsorted; 9052 return xpath_node_set::type_unsorted;
8986 9053
8987 return first ? xpath_node_set::type_sorted : xpath_node_set::type_sorted_reverse; 9054 return first ? xpath_node_set::type_sorted : xpath_node_set::type_sorted_reverse;
8988 } 9055 }
8989 9056
8990 PUGI__FN xpath_node_set::type_t xpath_sort(xpath_node* begin, xpath_node* end, xpath_node_set::type_t type, bool rev) 9057 PUGI_IMPL_FN xpath_node_set::type_t xpath_sort(xpath_node* begin, xpath_node* end, xpath_node_set::type_t type, bool rev)
8991 { 9058 {
8992 xpath_node_set::type_t order = rev ? xpath_node_set::type_sorted_reverse : xpath_node_set::type_sorted; 9059 xpath_node_set::type_t order = rev ? xpath_node_set::type_sorted_reverse : xpath_node_set::type_sorted;
8993 9060
8994 if (type == xpath_node_set::type_unsorted) 9061 if (type == xpath_node_set::type_unsorted)
8995 { 9062 {
9008 if (type != order) reverse(begin, end); 9075 if (type != order) reverse(begin, end);
9009 9076
9010 return order; 9077 return order;
9011 } 9078 }
9012 9079
9013 PUGI__FN xpath_node xpath_first(const xpath_node* begin, const xpath_node* end, xpath_node_set::type_t type) 9080 PUGI_IMPL_FN xpath_node xpath_first(const xpath_node* begin, const xpath_node* end, xpath_node_set::type_t type)
9014 { 9081 {
9015 if (begin == end) return xpath_node(); 9082 if (begin == end) return xpath_node();
9016 9083
9017 switch (type) 9084 switch (type)
9018 { 9085 {
9162 { 9229 {
9163 _type = value; 9230 _type = value;
9164 } 9231 }
9165 }; 9232 };
9166 9233
9167 PUGI__FN_NO_INLINE void xpath_node_set_raw::push_back_grow(const xpath_node& node, xpath_allocator* alloc) 9234 PUGI_IMPL_FN_NO_INLINE void xpath_node_set_raw::push_back_grow(const xpath_node& node, xpath_allocator* alloc)
9168 { 9235 {
9169 size_t capacity = static_cast<size_t>(_eos - _begin); 9236 size_t capacity = static_cast<size_t>(_eos - _begin);
9170 9237
9171 // get new capacity (1.5x rule) 9238 // get new capacity (1.5x rule)
9172 size_t new_capacity = capacity + capacity / 2 + 1; 9239 size_t new_capacity = capacity + capacity / 2 + 1;
9181 _eos = data + new_capacity; 9248 _eos = data + new_capacity;
9182 9249
9183 // push 9250 // push
9184 *_end++ = node; 9251 *_end++ = node;
9185 } 9252 }
9186 PUGI__NS_END 9253 PUGI_IMPL_NS_END
9187 9254
9188 PUGI__NS_BEGIN 9255 PUGI_IMPL_NS_BEGIN
9189 struct xpath_context 9256 struct xpath_context
9190 { 9257 {
9191 xpath_node n; 9258 xpath_node n;
9192 size_t position, size; 9259 size_t position, size;
9193 9260
9265 9332
9266 void next() 9333 void next()
9267 { 9334 {
9268 const char_t* cur = _cur; 9335 const char_t* cur = _cur;
9269 9336
9270 while (PUGI__IS_CHARTYPE(*cur, ct_space)) ++cur; 9337 while (PUGI_IMPL_IS_CHARTYPE(*cur, ct_space)) ++cur;
9271 9338
9272 // save lexeme position for error reporting 9339 // save lexeme position for error reporting
9273 _cur_lexeme_pos = cur; 9340 _cur_lexeme_pos = cur;
9274 9341
9275 switch (*cur) 9342 switch (*cur)
9347 break; 9414 break;
9348 9415
9349 case '$': 9416 case '$':
9350 cur += 1; 9417 cur += 1;
9351 9418
9352 if (PUGI__IS_CHARTYPEX(*cur, ctx_start_symbol)) 9419 if (PUGI_IMPL_IS_CHARTYPEX(*cur, ctx_start_symbol))
9353 { 9420 {
9354 _cur_lexeme_contents.begin = cur; 9421 _cur_lexeme_contents.begin = cur;
9355 9422
9356 while (PUGI__IS_CHARTYPEX(*cur, ctx_symbol)) cur++; 9423 while (PUGI_IMPL_IS_CHARTYPEX(*cur, ctx_symbol)) cur++;
9357 9424
9358 if (cur[0] == ':' && PUGI__IS_CHARTYPEX(cur[1], ctx_symbol)) // qname 9425 if (cur[0] == ':' && PUGI_IMPL_IS_CHARTYPEX(cur[1], ctx_symbol)) // qname
9359 { 9426 {
9360 cur++; // : 9427 cur++; // :
9361 9428
9362 while (PUGI__IS_CHARTYPEX(*cur, ctx_symbol)) cur++; 9429 while (PUGI_IMPL_IS_CHARTYPEX(*cur, ctx_symbol)) cur++;
9363 } 9430 }
9364 9431
9365 _cur_lexeme_contents.end = cur; 9432 _cur_lexeme_contents.end = cur;
9366 9433
9367 _cur_lexeme = lex_var_ref; 9434 _cur_lexeme = lex_var_ref;
9420 if (*(cur+1) == '.') 9487 if (*(cur+1) == '.')
9421 { 9488 {
9422 cur += 2; 9489 cur += 2;
9423 _cur_lexeme = lex_double_dot; 9490 _cur_lexeme = lex_double_dot;
9424 } 9491 }
9425 else if (PUGI__IS_CHARTYPEX(*(cur+1), ctx_digit)) 9492 else if (PUGI_IMPL_IS_CHARTYPEX(*(cur+1), ctx_digit))
9426 { 9493 {
9427 _cur_lexeme_contents.begin = cur; // . 9494 _cur_lexeme_contents.begin = cur; // .
9428 9495
9429 ++cur; 9496 ++cur;
9430 9497
9431 while (PUGI__IS_CHARTYPEX(*cur, ctx_digit)) cur++; 9498 while (PUGI_IMPL_IS_CHARTYPEX(*cur, ctx_digit)) cur++;
9432 9499
9433 _cur_lexeme_contents.end = cur; 9500 _cur_lexeme_contents.end = cur;
9434 9501
9435 _cur_lexeme = lex_number; 9502 _cur_lexeme = lex_number;
9436 } 9503 }
9480 _cur_lexeme = lex_none; 9547 _cur_lexeme = lex_none;
9481 } 9548 }
9482 break; 9549 break;
9483 9550
9484 default: 9551 default:
9485 if (PUGI__IS_CHARTYPEX(*cur, ctx_digit)) 9552 if (PUGI_IMPL_IS_CHARTYPEX(*cur, ctx_digit))
9486 { 9553 {
9487 _cur_lexeme_contents.begin = cur; 9554 _cur_lexeme_contents.begin = cur;
9488 9555
9489 while (PUGI__IS_CHARTYPEX(*cur, ctx_digit)) cur++; 9556 while (PUGI_IMPL_IS_CHARTYPEX(*cur, ctx_digit)) cur++;
9490 9557
9491 if (*cur == '.') 9558 if (*cur == '.')
9492 { 9559 {
9493 cur++; 9560 cur++;
9494 9561
9495 while (PUGI__IS_CHARTYPEX(*cur, ctx_digit)) cur++; 9562 while (PUGI_IMPL_IS_CHARTYPEX(*cur, ctx_digit)) cur++;
9496 } 9563 }
9497 9564
9498 _cur_lexeme_contents.end = cur; 9565 _cur_lexeme_contents.end = cur;
9499 9566
9500 _cur_lexeme = lex_number; 9567 _cur_lexeme = lex_number;
9501 } 9568 }
9502 else if (PUGI__IS_CHARTYPEX(*cur, ctx_start_symbol)) 9569 else if (PUGI_IMPL_IS_CHARTYPEX(*cur, ctx_start_symbol))
9503 { 9570 {
9504 _cur_lexeme_contents.begin = cur; 9571 _cur_lexeme_contents.begin = cur;
9505 9572
9506 while (PUGI__IS_CHARTYPEX(*cur, ctx_symbol)) cur++; 9573 while (PUGI_IMPL_IS_CHARTYPEX(*cur, ctx_symbol)) cur++;
9507 9574
9508 if (cur[0] == ':') 9575 if (cur[0] == ':')
9509 { 9576 {
9510 if (cur[1] == '*') // namespace test ncname:* 9577 if (cur[1] == '*') // namespace test ncname:*
9511 { 9578 {
9512 cur += 2; // :* 9579 cur += 2; // :*
9513 } 9580 }
9514 else if (PUGI__IS_CHARTYPEX(cur[1], ctx_symbol)) // namespace test qname 9581 else if (PUGI_IMPL_IS_CHARTYPEX(cur[1], ctx_symbol)) // namespace test qname
9515 { 9582 {
9516 cur++; // : 9583 cur++; // :
9517 9584
9518 while (PUGI__IS_CHARTYPEX(*cur, ctx_symbol)) cur++; 9585 while (PUGI_IMPL_IS_CHARTYPEX(*cur, ctx_symbol)) cur++;
9519 } 9586 }
9520 } 9587 }
9521 9588
9522 _cur_lexeme_contents.end = cur; 9589 _cur_lexeme_contents.end = cur;
9523 9590
9925 9992
9926 size_t size = ns.size() - first; 9993 size_t size = ns.size() - first;
9927 9994
9928 xpath_node* last = ns.begin() + first; 9995 xpath_node* last = ns.begin() + first;
9929 9996
9930 xpath_context c(xpath_node(), 1, size); 9997 xpath_node cn;
9998 xpath_context c(cn, 1, size);
9931 9999
9932 double er = expr->eval_number(c, stack); 10000 double er = expr->eval_number(c, stack);
9933 10001
9934 if (er >= 1.0 && er <= static_cast<double>(size)) 10002 if (er >= 1.0 && er <= static_cast<double>(size))
9935 { 10003 {
10012 10080
10013 bool step_push(xpath_node_set_raw& ns, xml_node_struct* n, xpath_allocator* alloc) 10081 bool step_push(xpath_node_set_raw& ns, xml_node_struct* n, xpath_allocator* alloc)
10014 { 10082 {
10015 assert(n); 10083 assert(n);
10016 10084
10017 xml_node_type type = PUGI__NODETYPE(n); 10085 xml_node_type type = PUGI_IMPL_NODETYPE(n);
10018 10086
10019 switch (_test) 10087 switch (_test)
10020 { 10088 {
10021 case nodetest_name: 10089 case nodetest_name:
10022 if (type == node_element && n->name && strequal(n->name, _data.nodetest)) 10090 if (type == node_element && n->name && strequal(n->name, _data.nodetest))
12035 if (_lexer.current() == lex_string) 12103 if (_lexer.current() == lex_string)
12036 { 12104 {
12037 // This is either a function call, or not - if not, we shall proceed with location path 12105 // This is either a function call, or not - if not, we shall proceed with location path
12038 const char_t* state = _lexer.state(); 12106 const char_t* state = _lexer.state();
12039 12107
12040 while (PUGI__IS_CHARTYPE(*state, ct_space)) ++state; 12108 while (PUGI_IMPL_IS_CHARTYPE(*state, ct_space)) ++state;
12041 12109
12042 if (*state != '(') 12110 if (*state != '(')
12043 return parse_location_path(); 12111 return parse_location_path();
12044 12112
12045 // This looks like a function call; however this still can be a node-test. Check it. 12113 // This looks like a function call; however this still can be a node-test. Check it.
12278 xpath_allocator alloc; 12346 xpath_allocator alloc;
12279 xpath_memory_block block; 12347 xpath_memory_block block;
12280 bool oom; 12348 bool oom;
12281 }; 12349 };
12282 12350
12283 PUGI__FN impl::xpath_ast_node* evaluate_node_set_prepare(xpath_query_impl* impl) 12351 PUGI_IMPL_FN impl::xpath_ast_node* evaluate_node_set_prepare(xpath_query_impl* impl)
12284 { 12352 {
12285 if (!impl) return 0; 12353 if (!impl) return 0;
12286 12354
12287 if (impl->root->rettype() != xpath_type_node_set) 12355 if (impl->root->rettype() != xpath_type_node_set)
12288 { 12356 {
12296 #endif 12364 #endif
12297 } 12365 }
12298 12366
12299 return impl->root; 12367 return impl->root;
12300 } 12368 }
12301 PUGI__NS_END 12369 PUGI_IMPL_NS_END
12302 12370
12303 namespace pugi 12371 namespace pugi
12304 { 12372 {
12305 #ifndef PUGIXML_NO_EXCEPTIONS 12373 #ifndef PUGIXML_NO_EXCEPTIONS
12306 PUGI__FN xpath_exception::xpath_exception(const xpath_parse_result& result_): _result(result_) 12374 PUGI_IMPL_FN xpath_exception::xpath_exception(const xpath_parse_result& result_): _result(result_)
12307 { 12375 {
12308 assert(_result.error); 12376 assert(_result.error);
12309 } 12377 }
12310 12378
12311 PUGI__FN const char* xpath_exception::what() const throw() 12379 PUGI_IMPL_FN const char* xpath_exception::what() const throw()
12312 { 12380 {
12313 return _result.error; 12381 return _result.error;
12314 } 12382 }
12315 12383
12316 PUGI__FN const xpath_parse_result& xpath_exception::result() const 12384 PUGI_IMPL_FN const xpath_parse_result& xpath_exception::result() const
12317 { 12385 {
12318 return _result; 12386 return _result;
12319 } 12387 }
12320 #endif 12388 #endif
12321 12389
12322 PUGI__FN xpath_node::xpath_node() 12390 PUGI_IMPL_FN xpath_node::xpath_node()
12323 { 12391 {
12324 } 12392 }
12325 12393
12326 PUGI__FN xpath_node::xpath_node(const xml_node& node_): _node(node_) 12394 PUGI_IMPL_FN xpath_node::xpath_node(const xml_node& node_): _node(node_)
12327 { 12395 {
12328 } 12396 }
12329 12397
12330 PUGI__FN xpath_node::xpath_node(const xml_attribute& attribute_, const xml_node& parent_): _node(attribute_ ? parent_ : xml_node()), _attribute(attribute_) 12398 PUGI_IMPL_FN xpath_node::xpath_node(const xml_attribute& attribute_, const xml_node& parent_): _node(attribute_ ? parent_ : xml_node()), _attribute(attribute_)
12331 { 12399 {
12332 } 12400 }
12333 12401
12334 PUGI__FN xml_node xpath_node::node() const 12402 PUGI_IMPL_FN xml_node xpath_node::node() const
12335 { 12403 {
12336 return _attribute ? xml_node() : _node; 12404 return _attribute ? xml_node() : _node;
12337 } 12405 }
12338 12406
12339 PUGI__FN xml_attribute xpath_node::attribute() const 12407 PUGI_IMPL_FN xml_attribute xpath_node::attribute() const
12340 { 12408 {
12341 return _attribute; 12409 return _attribute;
12342 } 12410 }
12343 12411
12344 PUGI__FN xml_node xpath_node::parent() const 12412 PUGI_IMPL_FN xml_node xpath_node::parent() const
12345 { 12413 {
12346 return _attribute ? _node : _node.parent(); 12414 return _attribute ? _node : _node.parent();
12347 } 12415 }
12348 12416
12349 PUGI__FN static void unspecified_bool_xpath_node(xpath_node***) 12417 PUGI_IMPL_FN static void unspecified_bool_xpath_node(xpath_node***)
12350 { 12418 {
12351 } 12419 }
12352 12420
12353 PUGI__FN xpath_node::operator xpath_node::unspecified_bool_type() const 12421 PUGI_IMPL_FN xpath_node::operator xpath_node::unspecified_bool_type() const
12354 { 12422 {
12355 return (_node || _attribute) ? unspecified_bool_xpath_node : 0; 12423 return (_node || _attribute) ? unspecified_bool_xpath_node : 0;
12356 } 12424 }
12357 12425
12358 PUGI__FN bool xpath_node::operator!() const 12426 PUGI_IMPL_FN bool xpath_node::operator!() const
12359 { 12427 {
12360 return !(_node || _attribute); 12428 return !(_node || _attribute);
12361 } 12429 }
12362 12430
12363 PUGI__FN bool xpath_node::operator==(const xpath_node& n) const 12431 PUGI_IMPL_FN bool xpath_node::operator==(const xpath_node& n) const
12364 { 12432 {
12365 return _node == n._node && _attribute == n._attribute; 12433 return _node == n._node && _attribute == n._attribute;
12366 } 12434 }
12367 12435
12368 PUGI__FN bool xpath_node::operator!=(const xpath_node& n) const 12436 PUGI_IMPL_FN bool xpath_node::operator!=(const xpath_node& n) const
12369 { 12437 {
12370 return _node != n._node || _attribute != n._attribute; 12438 return _node != n._node || _attribute != n._attribute;
12371 } 12439 }
12372 12440
12373 #ifdef __BORLANDC__ 12441 #ifdef __BORLANDC__
12374 PUGI__FN bool operator&&(const xpath_node& lhs, bool rhs) 12442 PUGI_IMPL_FN bool operator&&(const xpath_node& lhs, bool rhs)
12375 { 12443 {
12376 return (bool)lhs && rhs; 12444 return (bool)lhs && rhs;
12377 } 12445 }
12378 12446
12379 PUGI__FN bool operator||(const xpath_node& lhs, bool rhs) 12447 PUGI_IMPL_FN bool operator||(const xpath_node& lhs, bool rhs)
12380 { 12448 {
12381 return (bool)lhs || rhs; 12449 return (bool)lhs || rhs;
12382 } 12450 }
12383 #endif 12451 #endif
12384 12452
12385 PUGI__FN void xpath_node_set::_assign(const_iterator begin_, const_iterator end_, type_t type_) 12453 PUGI_IMPL_FN void xpath_node_set::_assign(const_iterator begin_, const_iterator end_, type_t type_)
12386 { 12454 {
12387 assert(begin_ <= end_); 12455 assert(begin_ <= end_);
12388 12456
12389 size_t size_ = static_cast<size_t>(end_ - begin_); 12457 size_t size_ = static_cast<size_t>(end_ - begin_);
12390 12458
12412 _end = storage + size_; 12480 _end = storage + size_;
12413 _type = type_; 12481 _type = type_;
12414 } 12482 }
12415 12483
12416 #ifdef PUGIXML_HAS_MOVE 12484 #ifdef PUGIXML_HAS_MOVE
12417 PUGI__FN void xpath_node_set::_move(xpath_node_set& rhs) PUGIXML_NOEXCEPT 12485 PUGI_IMPL_FN void xpath_node_set::_move(xpath_node_set& rhs) PUGIXML_NOEXCEPT
12418 { 12486 {
12419 _type = rhs._type; 12487 _type = rhs._type;
12420 _storage[0] = rhs._storage[0]; 12488 _storage[0] = rhs._storage[0];
12421 _begin = (rhs._begin == rhs._storage) ? _storage : rhs._begin; 12489 _begin = (rhs._begin == rhs._storage) ? _storage : rhs._begin;
12422 _end = _begin + (rhs._end - rhs._begin); 12490 _end = _begin + (rhs._end - rhs._begin);
12425 rhs._begin = rhs._storage; 12493 rhs._begin = rhs._storage;
12426 rhs._end = rhs._storage; 12494 rhs._end = rhs._storage;
12427 } 12495 }
12428 #endif 12496 #endif
12429 12497
12430 PUGI__FN xpath_node_set::xpath_node_set(): _type(type_unsorted), _begin(_storage), _end(_storage) 12498 PUGI_IMPL_FN xpath_node_set::xpath_node_set(): _type(type_unsorted), _begin(_storage), _end(_storage)
12431 { 12499 {
12432 } 12500 }
12433 12501
12434 PUGI__FN xpath_node_set::xpath_node_set(const_iterator begin_, const_iterator end_, type_t type_): _type(type_unsorted), _begin(_storage), _end(_storage) 12502 PUGI_IMPL_FN xpath_node_set::xpath_node_set(const_iterator begin_, const_iterator end_, type_t type_): _type(type_unsorted), _begin(_storage), _end(_storage)
12435 { 12503 {
12436 _assign(begin_, end_, type_); 12504 _assign(begin_, end_, type_);
12437 } 12505 }
12438 12506
12439 PUGI__FN xpath_node_set::~xpath_node_set() 12507 PUGI_IMPL_FN xpath_node_set::~xpath_node_set()
12440 { 12508 {
12441 if (_begin != _storage) 12509 if (_begin != _storage)
12442 impl::xml_memory::deallocate(_begin); 12510 impl::xml_memory::deallocate(_begin);
12443 } 12511 }
12444 12512
12445 PUGI__FN xpath_node_set::xpath_node_set(const xpath_node_set& ns): _type(type_unsorted), _begin(_storage), _end(_storage) 12513 PUGI_IMPL_FN xpath_node_set::xpath_node_set(const xpath_node_set& ns): _type(type_unsorted), _begin(_storage), _end(_storage)
12446 { 12514 {
12447 _assign(ns._begin, ns._end, ns._type); 12515 _assign(ns._begin, ns._end, ns._type);
12448 } 12516 }
12449 12517
12450 PUGI__FN xpath_node_set& xpath_node_set::operator=(const xpath_node_set& ns) 12518 PUGI_IMPL_FN xpath_node_set& xpath_node_set::operator=(const xpath_node_set& ns)
12451 { 12519 {
12452 if (this == &ns) return *this; 12520 if (this == &ns) return *this;
12453 12521
12454 _assign(ns._begin, ns._end, ns._type); 12522 _assign(ns._begin, ns._end, ns._type);
12455 12523
12456 return *this; 12524 return *this;
12457 } 12525 }
12458 12526
12459 #ifdef PUGIXML_HAS_MOVE 12527 #ifdef PUGIXML_HAS_MOVE
12460 PUGI__FN xpath_node_set::xpath_node_set(xpath_node_set&& rhs) PUGIXML_NOEXCEPT: _type(type_unsorted), _begin(_storage), _end(_storage) 12528 PUGI_IMPL_FN xpath_node_set::xpath_node_set(xpath_node_set&& rhs) PUGIXML_NOEXCEPT: _type(type_unsorted), _begin(_storage), _end(_storage)
12461 { 12529 {
12462 _move(rhs); 12530 _move(rhs);
12463 } 12531 }
12464 12532
12465 PUGI__FN xpath_node_set& xpath_node_set::operator=(xpath_node_set&& rhs) PUGIXML_NOEXCEPT 12533 PUGI_IMPL_FN xpath_node_set& xpath_node_set::operator=(xpath_node_set&& rhs) PUGIXML_NOEXCEPT
12466 { 12534 {
12467 if (this == &rhs) return *this; 12535 if (this == &rhs) return *this;
12468 12536
12469 if (_begin != _storage) 12537 if (_begin != _storage)
12470 impl::xml_memory::deallocate(_begin); 12538 impl::xml_memory::deallocate(_begin);
12473 12541
12474 return *this; 12542 return *this;
12475 } 12543 }
12476 #endif 12544 #endif
12477 12545
12478 PUGI__FN xpath_node_set::type_t xpath_node_set::type() const 12546 PUGI_IMPL_FN xpath_node_set::type_t xpath_node_set::type() const
12479 { 12547 {
12480 return _type; 12548 return _type;
12481 } 12549 }
12482 12550
12483 PUGI__FN size_t xpath_node_set::size() const 12551 PUGI_IMPL_FN size_t xpath_node_set::size() const
12484 { 12552 {
12485 return _end - _begin; 12553 return _end - _begin;
12486 } 12554 }
12487 12555
12488 PUGI__FN bool xpath_node_set::empty() const 12556 PUGI_IMPL_FN bool xpath_node_set::empty() const
12489 { 12557 {
12490 return _begin == _end; 12558 return _begin == _end;
12491 } 12559 }
12492 12560
12493 PUGI__FN const xpath_node& xpath_node_set::operator[](size_t index) const 12561 PUGI_IMPL_FN const xpath_node& xpath_node_set::operator[](size_t index) const
12494 { 12562 {
12495 assert(index < size()); 12563 assert(index < size());
12496 return _begin[index]; 12564 return _begin[index];
12497 } 12565 }
12498 12566
12499 PUGI__FN xpath_node_set::const_iterator xpath_node_set::begin() const 12567 PUGI_IMPL_FN xpath_node_set::const_iterator xpath_node_set::begin() const
12500 { 12568 {
12501 return _begin; 12569 return _begin;
12502 } 12570 }
12503 12571
12504 PUGI__FN xpath_node_set::const_iterator xpath_node_set::end() const 12572 PUGI_IMPL_FN xpath_node_set::const_iterator xpath_node_set::end() const
12505 { 12573 {
12506 return _end; 12574 return _end;
12507 } 12575 }
12508 12576
12509 PUGI__FN void xpath_node_set::sort(bool reverse) 12577 PUGI_IMPL_FN void xpath_node_set::sort(bool reverse)
12510 { 12578 {
12511 _type = impl::xpath_sort(_begin, _end, _type, reverse); 12579 _type = impl::xpath_sort(_begin, _end, _type, reverse);
12512 } 12580 }
12513 12581
12514 PUGI__FN xpath_node xpath_node_set::first() const 12582 PUGI_IMPL_FN xpath_node xpath_node_set::first() const
12515 { 12583 {
12516 return impl::xpath_first(_begin, _end, _type); 12584 return impl::xpath_first(_begin, _end, _type);
12517 } 12585 }
12518 12586
12519 PUGI__FN xpath_parse_result::xpath_parse_result(): error("Internal error"), offset(0) 12587 PUGI_IMPL_FN xpath_parse_result::xpath_parse_result(): error("Internal error"), offset(0)
12520 { 12588 {
12521 } 12589 }
12522 12590
12523 PUGI__FN xpath_parse_result::operator bool() const 12591 PUGI_IMPL_FN xpath_parse_result::operator bool() const
12524 { 12592 {
12525 return error == 0; 12593 return error == 0;
12526 } 12594 }
12527 12595
12528 PUGI__FN const char* xpath_parse_result::description() const 12596 PUGI_IMPL_FN const char* xpath_parse_result::description() const
12529 { 12597 {
12530 return error ? error : "No error"; 12598 return error ? error : "No error";
12531 } 12599 }
12532 12600
12533 PUGI__FN xpath_variable::xpath_variable(xpath_value_type type_): _type(type_), _next(0) 12601 PUGI_IMPL_FN xpath_variable::xpath_variable(xpath_value_type type_): _type(type_), _next(0)
12534 { 12602 {
12535 } 12603 }
12536 12604
12537 PUGI__FN const char_t* xpath_variable::name() const 12605 PUGI_IMPL_FN const char_t* xpath_variable::name() const
12538 { 12606 {
12539 switch (_type) 12607 switch (_type)
12540 { 12608 {
12541 case xpath_type_node_set: 12609 case xpath_type_node_set:
12542 return static_cast<const impl::xpath_variable_node_set*>(this)->name; 12610 return static_cast<const impl::xpath_variable_node_set*>(this)->name;
12554 assert(false && "Invalid variable type"); // unreachable 12622 assert(false && "Invalid variable type"); // unreachable
12555 return 0; 12623 return 0;
12556 } 12624 }
12557 } 12625 }
12558 12626
12559 PUGI__FN xpath_value_type xpath_variable::type() const 12627 PUGI_IMPL_FN xpath_value_type xpath_variable::type() const
12560 { 12628 {
12561 return _type; 12629 return _type;
12562 } 12630 }
12563 12631
12564 PUGI__FN bool xpath_variable::get_boolean() const 12632 PUGI_IMPL_FN bool xpath_variable::get_boolean() const
12565 { 12633 {
12566 return (_type == xpath_type_boolean) ? static_cast<const impl::xpath_variable_boolean*>(this)->value : false; 12634 return (_type == xpath_type_boolean) ? static_cast<const impl::xpath_variable_boolean*>(this)->value : false;
12567 } 12635 }
12568 12636
12569 PUGI__FN double xpath_variable::get_number() const 12637 PUGI_IMPL_FN double xpath_variable::get_number() const
12570 { 12638 {
12571 return (_type == xpath_type_number) ? static_cast<const impl::xpath_variable_number*>(this)->value : impl::gen_nan(); 12639 return (_type == xpath_type_number) ? static_cast<const impl::xpath_variable_number*>(this)->value : impl::gen_nan();
12572 } 12640 }
12573 12641
12574 PUGI__FN const char_t* xpath_variable::get_string() const 12642 PUGI_IMPL_FN const char_t* xpath_variable::get_string() const
12575 { 12643 {
12576 const char_t* value = (_type == xpath_type_string) ? static_cast<const impl::xpath_variable_string*>(this)->value : 0; 12644 const char_t* value = (_type == xpath_type_string) ? static_cast<const impl::xpath_variable_string*>(this)->value : 0;
12577 return value ? value : PUGIXML_TEXT(""); 12645 return value ? value : PUGIXML_TEXT("");
12578 } 12646 }
12579 12647
12580 PUGI__FN const xpath_node_set& xpath_variable::get_node_set() const 12648 PUGI_IMPL_FN const xpath_node_set& xpath_variable::get_node_set() const
12581 { 12649 {
12582 return (_type == xpath_type_node_set) ? static_cast<const impl::xpath_variable_node_set*>(this)->value : impl::dummy_node_set; 12650 return (_type == xpath_type_node_set) ? static_cast<const impl::xpath_variable_node_set*>(this)->value : impl::dummy_node_set;
12583 } 12651 }
12584 12652
12585 PUGI__FN bool xpath_variable::set(bool value) 12653 PUGI_IMPL_FN bool xpath_variable::set(bool value)
12586 { 12654 {
12587 if (_type != xpath_type_boolean) return false; 12655 if (_type != xpath_type_boolean) return false;
12588 12656
12589 static_cast<impl::xpath_variable_boolean*>(this)->value = value; 12657 static_cast<impl::xpath_variable_boolean*>(this)->value = value;
12590 return true; 12658 return true;
12591 } 12659 }
12592 12660
12593 PUGI__FN bool xpath_variable::set(double value) 12661 PUGI_IMPL_FN bool xpath_variable::set(double value)
12594 { 12662 {
12595 if (_type != xpath_type_number) return false; 12663 if (_type != xpath_type_number) return false;
12596 12664
12597 static_cast<impl::xpath_variable_number*>(this)->value = value; 12665 static_cast<impl::xpath_variable_number*>(this)->value = value;
12598 return true; 12666 return true;
12599 } 12667 }
12600 12668
12601 PUGI__FN bool xpath_variable::set(const char_t* value) 12669 PUGI_IMPL_FN bool xpath_variable::set(const char_t* value)
12602 { 12670 {
12603 if (_type != xpath_type_string) return false; 12671 if (_type != xpath_type_string) return false;
12604 12672
12605 impl::xpath_variable_string* var = static_cast<impl::xpath_variable_string*>(this); 12673 impl::xpath_variable_string* var = static_cast<impl::xpath_variable_string*>(this);
12606 12674
12617 var->value = copy; 12685 var->value = copy;
12618 12686
12619 return true; 12687 return true;
12620 } 12688 }
12621 12689
12622 PUGI__FN bool xpath_variable::set(const xpath_node_set& value) 12690 PUGI_IMPL_FN bool xpath_variable::set(const xpath_node_set& value)
12623 { 12691 {
12624 if (_type != xpath_type_node_set) return false; 12692 if (_type != xpath_type_node_set) return false;
12625 12693
12626 static_cast<impl::xpath_variable_node_set*>(this)->value = value; 12694 static_cast<impl::xpath_variable_node_set*>(this)->value = value;
12627 return true; 12695 return true;
12628 } 12696 }
12629 12697
12630 PUGI__FN xpath_variable_set::xpath_variable_set() 12698 PUGI_IMPL_FN xpath_variable_set::xpath_variable_set()
12631 { 12699 {
12632 for (size_t i = 0; i < sizeof(_data) / sizeof(_data[0]); ++i) 12700 for (size_t i = 0; i < sizeof(_data) / sizeof(_data[0]); ++i)
12633 _data[i] = 0; 12701 _data[i] = 0;
12634 } 12702 }
12635 12703
12636 PUGI__FN xpath_variable_set::~xpath_variable_set() 12704 PUGI_IMPL_FN xpath_variable_set::~xpath_variable_set()
12637 { 12705 {
12638 for (size_t i = 0; i < sizeof(_data) / sizeof(_data[0]); ++i) 12706 for (size_t i = 0; i < sizeof(_data) / sizeof(_data[0]); ++i)
12639 _destroy(_data[i]); 12707 _destroy(_data[i]);
12640 } 12708 }
12641 12709
12642 PUGI__FN xpath_variable_set::xpath_variable_set(const xpath_variable_set& rhs) 12710 PUGI_IMPL_FN xpath_variable_set::xpath_variable_set(const xpath_variable_set& rhs)
12643 { 12711 {
12644 for (size_t i = 0; i < sizeof(_data) / sizeof(_data[0]); ++i) 12712 for (size_t i = 0; i < sizeof(_data) / sizeof(_data[0]); ++i)
12645 _data[i] = 0; 12713 _data[i] = 0;
12646 12714
12647 _assign(rhs); 12715 _assign(rhs);
12648 } 12716 }
12649 12717
12650 PUGI__FN xpath_variable_set& xpath_variable_set::operator=(const xpath_variable_set& rhs) 12718 PUGI_IMPL_FN xpath_variable_set& xpath_variable_set::operator=(const xpath_variable_set& rhs)
12651 { 12719 {
12652 if (this == &rhs) return *this; 12720 if (this == &rhs) return *this;
12653 12721
12654 _assign(rhs); 12722 _assign(rhs);
12655 12723
12656 return *this; 12724 return *this;
12657 } 12725 }
12658 12726
12659 #ifdef PUGIXML_HAS_MOVE 12727 #ifdef PUGIXML_HAS_MOVE
12660 PUGI__FN xpath_variable_set::xpath_variable_set(xpath_variable_set&& rhs) PUGIXML_NOEXCEPT 12728 PUGI_IMPL_FN xpath_variable_set::xpath_variable_set(xpath_variable_set&& rhs) PUGIXML_NOEXCEPT
12661 { 12729 {
12662 for (size_t i = 0; i < sizeof(_data) / sizeof(_data[0]); ++i) 12730 for (size_t i = 0; i < sizeof(_data) / sizeof(_data[0]); ++i)
12663 { 12731 {
12664 _data[i] = rhs._data[i]; 12732 _data[i] = rhs._data[i];
12665 rhs._data[i] = 0; 12733 rhs._data[i] = 0;
12666 } 12734 }
12667 } 12735 }
12668 12736
12669 PUGI__FN xpath_variable_set& xpath_variable_set::operator=(xpath_variable_set&& rhs) PUGIXML_NOEXCEPT 12737 PUGI_IMPL_FN xpath_variable_set& xpath_variable_set::operator=(xpath_variable_set&& rhs) PUGIXML_NOEXCEPT
12670 { 12738 {
12671 for (size_t i = 0; i < sizeof(_data) / sizeof(_data[0]); ++i) 12739 for (size_t i = 0; i < sizeof(_data) / sizeof(_data[0]); ++i)
12672 { 12740 {
12673 _destroy(_data[i]); 12741 _destroy(_data[i]);
12674 12742
12678 12746
12679 return *this; 12747 return *this;
12680 } 12748 }
12681 #endif 12749 #endif
12682 12750
12683 PUGI__FN void xpath_variable_set::_assign(const xpath_variable_set& rhs) 12751 PUGI_IMPL_FN void xpath_variable_set::_assign(const xpath_variable_set& rhs)
12684 { 12752 {
12685 xpath_variable_set temp; 12753 xpath_variable_set temp;
12686 12754
12687 for (size_t i = 0; i < sizeof(_data) / sizeof(_data[0]); ++i) 12755 for (size_t i = 0; i < sizeof(_data) / sizeof(_data[0]); ++i)
12688 if (rhs._data[i] && !_clone(rhs._data[i], &temp._data[i])) 12756 if (rhs._data[i] && !_clone(rhs._data[i], &temp._data[i]))
12689 return; 12757 return;
12690 12758
12691 _swap(temp); 12759 _swap(temp);
12692 } 12760 }
12693 12761
12694 PUGI__FN void xpath_variable_set::_swap(xpath_variable_set& rhs) 12762 PUGI_IMPL_FN void xpath_variable_set::_swap(xpath_variable_set& rhs)
12695 { 12763 {
12696 for (size_t i = 0; i < sizeof(_data) / sizeof(_data[0]); ++i) 12764 for (size_t i = 0; i < sizeof(_data) / sizeof(_data[0]); ++i)
12697 { 12765 {
12698 xpath_variable* chain = _data[i]; 12766 xpath_variable* chain = _data[i];
12699 12767
12700 _data[i] = rhs._data[i]; 12768 _data[i] = rhs._data[i];
12701 rhs._data[i] = chain; 12769 rhs._data[i] = chain;
12702 } 12770 }
12703 } 12771 }
12704 12772
12705 PUGI__FN xpath_variable* xpath_variable_set::_find(const char_t* name) const 12773 PUGI_IMPL_FN xpath_variable* xpath_variable_set::_find(const char_t* name) const
12706 { 12774 {
12707 const size_t hash_size = sizeof(_data) / sizeof(_data[0]); 12775 const size_t hash_size = sizeof(_data) / sizeof(_data[0]);
12708 size_t hash = impl::hash_string(name) % hash_size; 12776 size_t hash = impl::hash_string(name) % hash_size;
12709 12777
12710 // look for existing variable 12778 // look for existing variable
12713 return var; 12781 return var;
12714 12782
12715 return 0; 12783 return 0;
12716 } 12784 }
12717 12785
12718 PUGI__FN bool xpath_variable_set::_clone(xpath_variable* var, xpath_variable** out_result) 12786 PUGI_IMPL_FN bool xpath_variable_set::_clone(xpath_variable* var, xpath_variable** out_result)
12719 { 12787 {
12720 xpath_variable* last = 0; 12788 xpath_variable* last = 0;
12721 12789
12722 while (var) 12790 while (var)
12723 { 12791 {
12740 } 12808 }
12741 12809
12742 return true; 12810 return true;
12743 } 12811 }
12744 12812
12745 PUGI__FN void xpath_variable_set::_destroy(xpath_variable* var) 12813 PUGI_IMPL_FN void xpath_variable_set::_destroy(xpath_variable* var)
12746 { 12814 {
12747 while (var) 12815 while (var)
12748 { 12816 {
12749 xpath_variable* next = var->_next; 12817 xpath_variable* next = var->_next;
12750 12818
12752 12820
12753 var = next; 12821 var = next;
12754 } 12822 }
12755 } 12823 }
12756 12824
12757 PUGI__FN xpath_variable* xpath_variable_set::add(const char_t* name, xpath_value_type type) 12825 PUGI_IMPL_FN xpath_variable* xpath_variable_set::add(const char_t* name, xpath_value_type type)
12758 { 12826 {
12759 const size_t hash_size = sizeof(_data) / sizeof(_data[0]); 12827 const size_t hash_size = sizeof(_data) / sizeof(_data[0]);
12760 size_t hash = impl::hash_string(name) % hash_size; 12828 size_t hash = impl::hash_string(name) % hash_size;
12761 12829
12762 // look for existing variable 12830 // look for existing variable
12775 } 12843 }
12776 12844
12777 return result; 12845 return result;
12778 } 12846 }
12779 12847
12780 PUGI__FN bool xpath_variable_set::set(const char_t* name, bool value) 12848 PUGI_IMPL_FN bool xpath_variable_set::set(const char_t* name, bool value)
12781 { 12849 {
12782 xpath_variable* var = add(name, xpath_type_boolean); 12850 xpath_variable* var = add(name, xpath_type_boolean);
12783 return var ? var->set(value) : false; 12851 return var ? var->set(value) : false;
12784 } 12852 }
12785 12853
12786 PUGI__FN bool xpath_variable_set::set(const char_t* name, double value) 12854 PUGI_IMPL_FN bool xpath_variable_set::set(const char_t* name, double value)
12787 { 12855 {
12788 xpath_variable* var = add(name, xpath_type_number); 12856 xpath_variable* var = add(name, xpath_type_number);
12789 return var ? var->set(value) : false; 12857 return var ? var->set(value) : false;
12790 } 12858 }
12791 12859
12792 PUGI__FN bool xpath_variable_set::set(const char_t* name, const char_t* value) 12860 PUGI_IMPL_FN bool xpath_variable_set::set(const char_t* name, const char_t* value)
12793 { 12861 {
12794 xpath_variable* var = add(name, xpath_type_string); 12862 xpath_variable* var = add(name, xpath_type_string);
12795 return var ? var->set(value) : false; 12863 return var ? var->set(value) : false;
12796 } 12864 }
12797 12865
12798 PUGI__FN bool xpath_variable_set::set(const char_t* name, const xpath_node_set& value) 12866 PUGI_IMPL_FN bool xpath_variable_set::set(const char_t* name, const xpath_node_set& value)
12799 { 12867 {
12800 xpath_variable* var = add(name, xpath_type_node_set); 12868 xpath_variable* var = add(name, xpath_type_node_set);
12801 return var ? var->set(value) : false; 12869 return var ? var->set(value) : false;
12802 } 12870 }
12803 12871
12804 PUGI__FN xpath_variable* xpath_variable_set::get(const char_t* name) 12872 PUGI_IMPL_FN xpath_variable* xpath_variable_set::get(const char_t* name)
12805 { 12873 {
12806 return _find(name); 12874 return _find(name);
12807 } 12875 }
12808 12876
12809 PUGI__FN const xpath_variable* xpath_variable_set::get(const char_t* name) const 12877 PUGI_IMPL_FN const xpath_variable* xpath_variable_set::get(const char_t* name) const
12810 { 12878 {
12811 return _find(name); 12879 return _find(name);
12812 } 12880 }
12813 12881
12814 PUGI__FN xpath_query::xpath_query(const char_t* query, xpath_variable_set* variables): _impl(0) 12882 PUGI_IMPL_FN xpath_query::xpath_query(const char_t* query, xpath_variable_set* variables): _impl(0)
12815 { 12883 {
12816 impl::xpath_query_impl* qimpl = impl::xpath_query_impl::create(); 12884 impl::xpath_query_impl* qimpl = impl::xpath_query_impl::create();
12817 12885
12818 if (!qimpl) 12886 if (!qimpl)
12819 { 12887 {
12847 #endif 12915 #endif
12848 } 12916 }
12849 } 12917 }
12850 } 12918 }
12851 12919
12852 PUGI__FN xpath_query::xpath_query(): _impl(0) 12920 PUGI_IMPL_FN xpath_query::xpath_query(): _impl(0)
12853 { 12921 {
12854 } 12922 }
12855 12923
12856 PUGI__FN xpath_query::~xpath_query() 12924 PUGI_IMPL_FN xpath_query::~xpath_query()
12857 { 12925 {
12858 if (_impl) 12926 if (_impl)
12859 impl::xpath_query_impl::destroy(static_cast<impl::xpath_query_impl*>(_impl)); 12927 impl::xpath_query_impl::destroy(static_cast<impl::xpath_query_impl*>(_impl));
12860 } 12928 }
12861 12929
12862 #ifdef PUGIXML_HAS_MOVE 12930 #ifdef PUGIXML_HAS_MOVE
12863 PUGI__FN xpath_query::xpath_query(xpath_query&& rhs) PUGIXML_NOEXCEPT 12931 PUGI_IMPL_FN xpath_query::xpath_query(xpath_query&& rhs) PUGIXML_NOEXCEPT
12864 { 12932 {
12865 _impl = rhs._impl; 12933 _impl = rhs._impl;
12866 _result = rhs._result; 12934 _result = rhs._result;
12867 rhs._impl = 0; 12935 rhs._impl = 0;
12868 rhs._result = xpath_parse_result(); 12936 rhs._result = xpath_parse_result();
12869 } 12937 }
12870 12938
12871 PUGI__FN xpath_query& xpath_query::operator=(xpath_query&& rhs) PUGIXML_NOEXCEPT 12939 PUGI_IMPL_FN xpath_query& xpath_query::operator=(xpath_query&& rhs) PUGIXML_NOEXCEPT
12872 { 12940 {
12873 if (this == &rhs) return *this; 12941 if (this == &rhs) return *this;
12874 12942
12875 if (_impl) 12943 if (_impl)
12876 impl::xpath_query_impl::destroy(static_cast<impl::xpath_query_impl*>(_impl)); 12944 impl::xpath_query_impl::destroy(static_cast<impl::xpath_query_impl*>(_impl));
12882 12950
12883 return *this; 12951 return *this;
12884 } 12952 }
12885 #endif 12953 #endif
12886 12954
12887 PUGI__FN xpath_value_type xpath_query::return_type() const 12955 PUGI_IMPL_FN xpath_value_type xpath_query::return_type() const
12888 { 12956 {
12889 if (!_impl) return xpath_type_none; 12957 if (!_impl) return xpath_type_none;
12890 12958
12891 return static_cast<impl::xpath_query_impl*>(_impl)->root->rettype(); 12959 return static_cast<impl::xpath_query_impl*>(_impl)->root->rettype();
12892 } 12960 }
12893 12961
12894 PUGI__FN bool xpath_query::evaluate_boolean(const xpath_node& n) const 12962 PUGI_IMPL_FN bool xpath_query::evaluate_boolean(const xpath_node& n) const
12895 { 12963 {
12896 if (!_impl) return false; 12964 if (!_impl) return false;
12897 12965
12898 impl::xpath_context c(n, 1, 1); 12966 impl::xpath_context c(n, 1, 1);
12899 impl::xpath_stack_data sd; 12967 impl::xpath_stack_data sd;
12910 } 12978 }
12911 12979
12912 return r; 12980 return r;
12913 } 12981 }
12914 12982
12915 PUGI__FN double xpath_query::evaluate_number(const xpath_node& n) const 12983 PUGI_IMPL_FN double xpath_query::evaluate_number(const xpath_node& n) const
12916 { 12984 {
12917 if (!_impl) return impl::gen_nan(); 12985 if (!_impl) return impl::gen_nan();
12918 12986
12919 impl::xpath_context c(n, 1, 1); 12987 impl::xpath_context c(n, 1, 1);
12920 impl::xpath_stack_data sd; 12988 impl::xpath_stack_data sd;
12932 13000
12933 return r; 13001 return r;
12934 } 13002 }
12935 13003
12936 #ifndef PUGIXML_NO_STL 13004 #ifndef PUGIXML_NO_STL
12937 PUGI__FN string_t xpath_query::evaluate_string(const xpath_node& n) const 13005 PUGI_IMPL_FN string_t xpath_query::evaluate_string(const xpath_node& n) const
12938 { 13006 {
12939 if (!_impl) return string_t(); 13007 if (!_impl) return string_t();
12940 13008
12941 impl::xpath_context c(n, 1, 1); 13009 impl::xpath_context c(n, 1, 1);
12942 impl::xpath_stack_data sd; 13010 impl::xpath_stack_data sd;
12954 13022
12955 return string_t(r.c_str(), r.length()); 13023 return string_t(r.c_str(), r.length());
12956 } 13024 }
12957 #endif 13025 #endif
12958 13026
12959 PUGI__FN size_t xpath_query::evaluate_string(char_t* buffer, size_t capacity, const xpath_node& n) const 13027 PUGI_IMPL_FN size_t xpath_query::evaluate_string(char_t* buffer, size_t capacity, const xpath_node& n) const
12960 { 13028 {
12961 impl::xpath_context c(n, 1, 1); 13029 impl::xpath_context c(n, 1, 1);
12962 impl::xpath_stack_data sd; 13030 impl::xpath_stack_data sd;
12963 13031
12964 impl::xpath_string r = _impl ? static_cast<impl::xpath_query_impl*>(_impl)->root->eval_string(c, sd.stack) : impl::xpath_string(); 13032 impl::xpath_string r = _impl ? static_cast<impl::xpath_query_impl*>(_impl)->root->eval_string(c, sd.stack) : impl::xpath_string();
12984 } 13052 }
12985 13053
12986 return full_size; 13054 return full_size;
12987 } 13055 }
12988 13056
12989 PUGI__FN xpath_node_set xpath_query::evaluate_node_set(const xpath_node& n) const 13057 PUGI_IMPL_FN xpath_node_set xpath_query::evaluate_node_set(const xpath_node& n) const
12990 { 13058 {
12991 impl::xpath_ast_node* root = impl::evaluate_node_set_prepare(static_cast<impl::xpath_query_impl*>(_impl)); 13059 impl::xpath_ast_node* root = impl::evaluate_node_set_prepare(static_cast<impl::xpath_query_impl*>(_impl));
12992 if (!root) return xpath_node_set(); 13060 if (!root) return xpath_node_set();
12993 13061
12994 impl::xpath_context c(n, 1, 1); 13062 impl::xpath_context c(n, 1, 1);
13006 } 13074 }
13007 13075
13008 return xpath_node_set(r.begin(), r.end(), r.type()); 13076 return xpath_node_set(r.begin(), r.end(), r.type());
13009 } 13077 }
13010 13078
13011 PUGI__FN xpath_node xpath_query::evaluate_node(const xpath_node& n) const 13079 PUGI_IMPL_FN xpath_node xpath_query::evaluate_node(const xpath_node& n) const
13012 { 13080 {
13013 impl::xpath_ast_node* root = impl::evaluate_node_set_prepare(static_cast<impl::xpath_query_impl*>(_impl)); 13081 impl::xpath_ast_node* root = impl::evaluate_node_set_prepare(static_cast<impl::xpath_query_impl*>(_impl));
13014 if (!root) return xpath_node(); 13082 if (!root) return xpath_node();
13015 13083
13016 impl::xpath_context c(n, 1, 1); 13084 impl::xpath_context c(n, 1, 1);
13028 } 13096 }
13029 13097
13030 return r.first(); 13098 return r.first();
13031 } 13099 }
13032 13100
13033 PUGI__FN const xpath_parse_result& xpath_query::result() const 13101 PUGI_IMPL_FN const xpath_parse_result& xpath_query::result() const
13034 { 13102 {
13035 return _result; 13103 return _result;
13036 } 13104 }
13037 13105
13038 PUGI__FN static void unspecified_bool_xpath_query(xpath_query***) 13106 PUGI_IMPL_FN static void unspecified_bool_xpath_query(xpath_query***)
13039 { 13107 {
13040 } 13108 }
13041 13109
13042 PUGI__FN xpath_query::operator xpath_query::unspecified_bool_type() const 13110 PUGI_IMPL_FN xpath_query::operator xpath_query::unspecified_bool_type() const
13043 { 13111 {
13044 return _impl ? unspecified_bool_xpath_query : 0; 13112 return _impl ? unspecified_bool_xpath_query : 0;
13045 } 13113 }
13046 13114
13047 PUGI__FN bool xpath_query::operator!() const 13115 PUGI_IMPL_FN bool xpath_query::operator!() const
13048 { 13116 {
13049 return !_impl; 13117 return !_impl;
13050 } 13118 }
13051 13119
13052 PUGI__FN xpath_node xml_node::select_node(const char_t* query, xpath_variable_set* variables) const 13120 PUGI_IMPL_FN xpath_node xml_node::select_node(const char_t* query, xpath_variable_set* variables) const
13053 { 13121 {
13054 xpath_query q(query, variables); 13122 xpath_query q(query, variables);
13055 return q.evaluate_node(*this); 13123 return q.evaluate_node(*this);
13056 } 13124 }
13057 13125
13058 PUGI__FN xpath_node xml_node::select_node(const xpath_query& query) const 13126 PUGI_IMPL_FN xpath_node xml_node::select_node(const xpath_query& query) const
13059 { 13127 {
13060 return query.evaluate_node(*this); 13128 return query.evaluate_node(*this);
13061 } 13129 }
13062 13130
13063 PUGI__FN xpath_node_set xml_node::select_nodes(const char_t* query, xpath_variable_set* variables) const 13131 PUGI_IMPL_FN xpath_node_set xml_node::select_nodes(const char_t* query, xpath_variable_set* variables) const
13064 { 13132 {
13065 xpath_query q(query, variables); 13133 xpath_query q(query, variables);
13066 return q.evaluate_node_set(*this); 13134 return q.evaluate_node_set(*this);
13067 } 13135 }
13068 13136
13069 PUGI__FN xpath_node_set xml_node::select_nodes(const xpath_query& query) const 13137 PUGI_IMPL_FN xpath_node_set xml_node::select_nodes(const xpath_query& query) const
13070 { 13138 {
13071 return query.evaluate_node_set(*this); 13139 return query.evaluate_node_set(*this);
13072 } 13140 }
13073 13141
13074 PUGI__FN xpath_node xml_node::select_single_node(const char_t* query, xpath_variable_set* variables) const 13142 PUGI_IMPL_FN xpath_node xml_node::select_single_node(const char_t* query, xpath_variable_set* variables) const
13075 { 13143 {
13076 xpath_query q(query, variables); 13144 xpath_query q(query, variables);
13077 return q.evaluate_node(*this); 13145 return q.evaluate_node(*this);
13078 } 13146 }
13079 13147
13080 PUGI__FN xpath_node xml_node::select_single_node(const xpath_query& query) const 13148 PUGI_IMPL_FN xpath_node xml_node::select_single_node(const xpath_query& query) const
13081 { 13149 {
13082 return query.evaluate_node(*this); 13150 return query.evaluate_node(*this);
13083 } 13151 }
13084 } 13152 }
13085 13153
13098 #if defined(_MSC_VER) && defined(__c2__) 13166 #if defined(_MSC_VER) && defined(__c2__)
13099 # pragma clang diagnostic pop 13167 # pragma clang diagnostic pop
13100 #endif 13168 #endif
13101 13169
13102 // Undefine all local macros (makes sure we're not leaking macros in header-only mode) 13170 // Undefine all local macros (makes sure we're not leaking macros in header-only mode)
13103 #undef PUGI__NO_INLINE 13171 #undef PUGI_IMPL_NO_INLINE
13104 #undef PUGI__UNLIKELY 13172 #undef PUGI_IMPL_UNLIKELY
13105 #undef PUGI__STATIC_ASSERT 13173 #undef PUGI_IMPL_STATIC_ASSERT
13106 #undef PUGI__DMC_VOLATILE 13174 #undef PUGI_IMPL_DMC_VOLATILE
13107 #undef PUGI__UNSIGNED_OVERFLOW 13175 #undef PUGI_IMPL_UNSIGNED_OVERFLOW
13108 #undef PUGI__MSVC_CRT_VERSION 13176 #undef PUGI_IMPL_MSVC_CRT_VERSION
13109 #undef PUGI__SNPRINTF 13177 #undef PUGI_IMPL_SNPRINTF
13110 #undef PUGI__NS_BEGIN 13178 #undef PUGI_IMPL_NS_BEGIN
13111 #undef PUGI__NS_END 13179 #undef PUGI_IMPL_NS_END
13112 #undef PUGI__FN 13180 #undef PUGI_IMPL_FN
13113 #undef PUGI__FN_NO_INLINE 13181 #undef PUGI_IMPL_FN_NO_INLINE
13114 #undef PUGI__GETHEADER_IMPL 13182 #undef PUGI_IMPL_GETHEADER_IMPL
13115 #undef PUGI__GETPAGE_IMPL 13183 #undef PUGI_IMPL_GETPAGE_IMPL
13116 #undef PUGI__GETPAGE 13184 #undef PUGI_IMPL_GETPAGE
13117 #undef PUGI__NODETYPE 13185 #undef PUGI_IMPL_NODETYPE
13118 #undef PUGI__IS_CHARTYPE_IMPL 13186 #undef PUGI_IMPL_IS_CHARTYPE_IMPL
13119 #undef PUGI__IS_CHARTYPE 13187 #undef PUGI_IMPL_IS_CHARTYPE
13120 #undef PUGI__IS_CHARTYPEX 13188 #undef PUGI_IMPL_IS_CHARTYPEX
13121 #undef PUGI__ENDSWITH 13189 #undef PUGI_IMPL_ENDSWITH
13122 #undef PUGI__SKIPWS 13190 #undef PUGI_IMPL_SKIPWS
13123 #undef PUGI__OPTSET 13191 #undef PUGI_IMPL_OPTSET
13124 #undef PUGI__PUSHNODE 13192 #undef PUGI_IMPL_PUSHNODE
13125 #undef PUGI__POPNODE 13193 #undef PUGI_IMPL_POPNODE
13126 #undef PUGI__SCANFOR 13194 #undef PUGI_IMPL_SCANFOR
13127 #undef PUGI__SCANWHILE 13195 #undef PUGI_IMPL_SCANWHILE
13128 #undef PUGI__SCANWHILE_UNROLL 13196 #undef PUGI_IMPL_SCANWHILE_UNROLL
13129 #undef PUGI__ENDSEG 13197 #undef PUGI_IMPL_ENDSEG
13130 #undef PUGI__THROW_ERROR 13198 #undef PUGI_IMPL_THROW_ERROR
13131 #undef PUGI__CHECK_ERROR 13199 #undef PUGI_IMPL_CHECK_ERROR
13132 13200
13133 #endif 13201 #endif
13134 13202
13135 /** 13203 /**
13136 * Copyright (c) 2006-2022 Arseny Kapoulkine 13204 * Copyright (c) 2006-2023 Arseny Kapoulkine
13137 * 13205 *
13138 * Permission is hereby granted, free of charge, to any person 13206 * Permission is hereby granted, free of charge, to any person
13139 * obtaining a copy of this software and associated documentation 13207 * obtaining a copy of this software and associated documentation
13140 * files (the "Software"), to deal in the Software without 13208 * files (the "Software"), to deal in the Software without
13141 * restriction, including without limitation the rights to use, 13209 * restriction, including without limitation the rights to use,