Changeset 33a694 for src/Parser/pugixml/pugixml.hpp
- Timestamp:
- May 5, 2017, 2:17:23 PM (8 years ago)
- Branches:
- Action_Thermostats, Add_AtomRandomPerturbation, Add_RotateAroundBondAction, Add_SelectAtomByNameAction, Adding_Graph_to_ChangeBondActions, Adding_MD_integration_tests, Adding_StructOpt_integration_tests, AutomationFragmentation_failures, Candidate_v1.6.1, ChangeBugEmailaddress, ChangingTestPorts, ChemicalSpaceEvaluator, Docu_Python_wait, EmpiricalPotential_contain_HomologyGraph_documentation, Enhance_userguide, Enhanced_StructuralOptimization, Enhanced_StructuralOptimization_continued, Example_ManyWaysToTranslateAtom, Exclude_Hydrogens_annealWithBondGraph, Fix_ChronosMutex, Fix_StatusMsg, Fix_StepWorldTime_single_argument, Fix_Verbose_Codepatterns, ForceAnnealing_goodresults, ForceAnnealing_oldresults, ForceAnnealing_tocheck, ForceAnnealing_with_BondGraph, ForceAnnealing_with_BondGraph_continued, ForceAnnealing_with_BondGraph_continued_betteresults, ForceAnnealing_with_BondGraph_contraction-expansion, GeometryObjects, Gui_displays_atomic_force_velocity, IndependentFragmentGrids_IntegrationTest, JobMarket_RobustOnKillsSegFaults, JobMarket_StableWorkerPool, PythonUI_with_named_parameters, QtGui_reactivate_TimeChanged_changes, Recreated_GuiChecks, RotateToPrincipalAxisSystem_UndoRedo, StoppableMakroAction, TremoloParser_IncreasedPrecision, TremoloParser_MultipleTimesteps, Ubuntu_1604_changes
- Children:
- dde50d
- Parents:
- 6798a5
- git-author:
- Frederik Heber <heber@…> (04/05/17 17:17:45)
- git-committer:
- Frederik Heber <frederik.heber@…> (05/05/17 14:17:23)
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
src/Parser/pugixml/pugixml.hpp
r6798a5 r33a694 1 1 /** 2 * pugixml parser - version 1. 02 * pugixml parser - version 1.8 3 3 * -------------------------------------------------------- 4 * Copyright (C) 2006-201 0, by Arseny Kapoulkine (arseny.kapoulkine@gmail.com)4 * Copyright (C) 2006-2016, by Arseny Kapoulkine (arseny.kapoulkine@gmail.com) 5 5 * Report bugs and download new versions at http://pugixml.org/ 6 6 * … … 12 12 */ 13 13 14 #ifndef PUGIXML_VERSION 15 // Define version macro; evaluates to major * 100 + minor so that it's safe to use in less-than comparisons 16 # define PUGIXML_VERSION 180 17 #endif 18 19 // Include user configuration file (this can define various configuration macros) 20 #include "pugiconfig.hpp" 21 14 22 #ifndef HEADER_PUGIXML_HPP 15 23 #define HEADER_PUGIXML_HPP 16 24 17 #include "pugiconfig.hpp" 18 25 // Include stddef.h for size_t and ptrdiff_t 26 #include <stddef.h> 27 28 // Include exception header for XPath 29 #if !defined(PUGIXML_NO_XPATH) && !defined(PUGIXML_NO_EXCEPTIONS) 30 # include <exception> 31 #endif 32 33 // Include STL headers 19 34 #ifndef PUGIXML_NO_STL 20 namespace std 21 { 22 struct bidirectional_iterator_tag; 23 24 #ifdef __SUNPRO_CC 25 // Sun C++ compiler has a bug which forces template argument names in forward declarations to be the same as in actual definitions 26 template <class _T> class allocator; 27 template <class _charT> struct char_traits; 28 template <class _charT, class _Traits> class basic_istream; 29 template <class _charT, class _Traits> class basic_ostream; 30 template <class _charT, class _Traits, class _Allocator> class basic_string; 31 #else 32 // Borland C++ compiler has a bug which forces template argument names in forward declarations to be the same as in actual definitions 33 template <class _Ty> class allocator; 34 template <class _Ty> struct char_traits; 35 template <class _Elem, class _Traits> class basic_istream; 36 template <class _Elem, class _Traits> class basic_ostream; 37 template <class _Elem, class _Traits, class _Ax> class basic_string; 38 #endif 39 40 // Digital Mars compiler has a bug which requires a forward declaration for explicit instantiation (otherwise type selection is messed up later, producing link errors) 41 // Also note that we have to declare char_traits as a class here, since it's defined that way 42 #ifdef __DMC__ 43 template <> class char_traits<char>; 44 #endif 45 } 35 # include <iterator> 36 # include <iosfwd> 37 # include <string> 46 38 #endif 47 39 … … 57 49 #endif 58 50 59 // Include exception header for XPath60 #if !defined(PUGIXML_NO_XPATH) && !defined(PUGIXML_NO_EXCEPTIONS)61 # include <exception>62 #endif63 64 51 // If no API is defined, assume default 65 52 #ifndef PUGIXML_API 66 # 53 # define PUGIXML_API 67 54 #endif 68 55 69 56 // If no API for classes is defined, assume default 70 57 #ifndef PUGIXML_CLASS 71 # 58 # define PUGIXML_CLASS PUGIXML_API 72 59 #endif 73 60 74 61 // If no API for functions is defined, assume default 75 62 #ifndef PUGIXML_FUNCTION 76 # define PUGIXML_FUNCTION PUGIXML_API 77 #endif 78 79 #include <stddef.h> 63 # define PUGIXML_FUNCTION PUGIXML_API 64 #endif 65 66 // If the platform is known to have long long support, enable long long functions 67 #ifndef PUGIXML_HAS_LONG_LONG 68 # if __cplusplus >= 201103 69 # define PUGIXML_HAS_LONG_LONG 70 # elif defined(_MSC_VER) && _MSC_VER >= 1400 71 # define PUGIXML_HAS_LONG_LONG 72 # endif 73 #endif 74 75 // If the platform is known to have move semantics support, compile move ctor/operator implementation 76 #ifndef PUGIXML_HAS_MOVE 77 # if __cplusplus >= 201103 78 # define PUGIXML_HAS_MOVE 79 # elif defined(_MSC_VER) && _MSC_VER >= 1600 80 # define PUGIXML_HAS_MOVE 81 # endif 82 #endif 83 84 // If C++ is 2011 or higher, add 'override' qualifiers 85 #ifndef PUGIXML_OVERRIDE 86 # if __cplusplus >= 201103 87 # define PUGIXML_OVERRIDE override 88 # else 89 # define PUGIXML_OVERRIDE 90 # endif 91 #endif 80 92 81 93 // Character interface macros … … 105 117 enum xml_node_type 106 118 { 107 node_null, 119 node_null, // Empty (null) node handle 108 120 node_document, // A document tree's absolute root 109 121 node_element, // Element tag, i.e. '<node/>' … … 113 125 node_pi, // Processing instruction, i.e. '<?name?>' 114 126 node_declaration, // Document declaration, i.e. '<?xml version="1.0"?>' 115 node_doctype// Document type declaration, i.e. '<!DOCTYPE doc>'127 node_doctype // Document type declaration, i.e. '<!DOCTYPE doc>' 116 128 }; 117 129 … … 119 131 120 132 // Minimal parsing mode (equivalent to turning all other flags off). 121 133 // Only elements and PCDATA sections are added to the DOM tree, no text conversions are performed. 122 134 const unsigned int parse_minimal = 0x0000; 123 135 … … 132 144 133 145 // This flag determines if plain character data (node_pcdata) that consist only of whitespace are added to the DOM tree. 134 146 // This flag is off by default; turning it on usually results in slower parsing and more memory consumption. 135 147 const unsigned int parse_ws_pcdata = 0x0008; 136 148 … … 140 152 // This flag determines if EOL characters are normalized (converted to #xA) during parsing. This flag is on by default. 141 153 const unsigned int parse_eol = 0x0020; 142 143 144 145 146 147 148 149 154 155 // This flag determines if attribute values are normalized using CDATA normalization rules during parsing. This flag is on by default. 156 const unsigned int parse_wconv_attribute = 0x0040; 157 158 // This flag determines if attribute values are normalized using NMTOKENS normalization rules during parsing. This flag is off by default. 159 const unsigned int parse_wnorm_attribute = 0x0080; 160 161 // This flag determines if document declaration (node_declaration) is added to the DOM tree. This flag is off by default. 150 162 const unsigned int parse_declaration = 0x0100; 151 163 152 164 // This flag determines if document type declaration (node_doctype) is added to the DOM tree. This flag is off by default. 153 165 const unsigned int parse_doctype = 0x0200; 154 166 167 // This flag determines if plain character data (node_pcdata) that is the only child of the parent node and that consists only 168 // of whitespace is added to the DOM tree. 169 // This flag is off by default; turning it on may result in slower parsing and more memory consumption. 170 const unsigned int parse_ws_pcdata_single = 0x0400; 171 172 // This flag determines if leading and trailing whitespace is to be removed from plain character data. This flag is off by default. 173 const unsigned int parse_trim_pcdata = 0x0800; 174 175 // This flag determines if plain character data that does not have a parent node is added to the DOM tree, and if an empty document 176 // is a valid document. This flag is off by default. 177 const unsigned int parse_fragment = 0x1000; 178 179 // This flag determines if plain character data is be stored in the parent element's value. This significantly changes the structure of 180 // the document; this flag is only recommended for parsing documents with many PCDATA nodes in memory-constrained environments. 181 // This flag is off by default. 182 const unsigned int parse_embed_pcdata = 0x2000; 183 155 184 // The default parsing mode. 156 157 185 // Elements, PCDATA and CDATA sections are added to the DOM tree, character/reference entities are expanded, 186 // End-of-Line characters are normalized, attribute values are normalized using CDATA normalization rules. 158 187 const unsigned int parse_default = parse_cdata | parse_escapes | parse_wconv_attribute | parse_eol; 159 188 160 161 162 163 189 // The full parsing mode. 190 // Nodes of all types are added to the DOM tree, character/reference entities are expanded, 191 // End-of-Line characters are normalized, attribute values are normalized using CDATA normalization rules. 192 const unsigned int parse_full = parse_default | parse_pi | parse_comments | parse_declaration | parse_doctype; 164 193 165 194 // These flags determine the encoding of input data for XML document 166 195 enum xml_encoding 167 196 { 168 encoding_auto, // Auto-detect input encoding using BOM or < / <? detection; use UTF8 if BOM is not found 169 encoding_utf8, // UTF8 encoding 170 encoding_utf16_le, // Little-endian UTF16 171 encoding_utf16_be, // Big-endian UTF16 172 encoding_utf16, // UTF16 with native endianness 173 encoding_utf32_le, // Little-endian UTF32 174 encoding_utf32_be, // Big-endian UTF32 175 encoding_utf32, // UTF32 with native endianness 176 encoding_wchar // The same encoding wchar_t has (either UTF16 or UTF32) 197 encoding_auto, // Auto-detect input encoding using BOM or < / <? detection; use UTF8 if BOM is not found 198 encoding_utf8, // UTF8 encoding 199 encoding_utf16_le, // Little-endian UTF16 200 encoding_utf16_be, // Big-endian UTF16 201 encoding_utf16, // UTF16 with native endianness 202 encoding_utf32_le, // Little-endian UTF32 203 encoding_utf32_be, // Big-endian UTF32 204 encoding_utf32, // UTF32 with native endianness 205 encoding_wchar, // The same encoding wchar_t has (either UTF16 or UTF32) 206 encoding_latin1 177 207 }; 178 208 179 209 // Formatting flags 180 210 181 211 // Indent the nodes that are written to output stream with as many indentation strings as deep the node is in DOM tree. This flag is on by default. 182 212 const unsigned int format_indent = 0x01; 183 213 184 214 // Write encoding-specific BOM to the output stream. This flag is off by default. 185 215 const unsigned int format_write_bom = 0x02; … … 187 217 // Use raw output mode (no indentation and no line breaks are written). This flag is off by default. 188 218 const unsigned int format_raw = 0x04; 189 219 190 220 // Omit default XML declaration even if there is no declaration in the document. This flag is off by default. 191 221 const unsigned int format_no_declaration = 0x08; 192 222 223 // Don't escape attribute values and PCDATA contents. This flag is off by default. 224 const unsigned int format_no_escapes = 0x10; 225 226 // Open file using text mode in xml_document::save_file. This enables special character (i.e. new-line) conversions on some systems. This flag is off by default. 227 const unsigned int format_save_file_text = 0x20; 228 229 // Write every attribute on a new line with appropriate indentation. This flag is off by default. 230 const unsigned int format_indent_attributes = 0x40; 231 232 // Don't output empty element tags, instead writing an explicit start and end tag even if there are no children. This flag is off by default. 233 const unsigned int format_no_empty_element_tags = 0x80; 234 193 235 // The default set of formatting flags. 194 236 // Nodes are indented depending on their depth in DOM tree, a default declaration is output if document has none. 195 237 const unsigned int format_default = format_indent; 196 238 197 239 // Forward declarations 198 240 struct xml_attribute_struct; … … 201 243 class xml_node_iterator; 202 244 class xml_attribute_iterator; 245 class xml_named_node_iterator; 203 246 204 247 class xml_tree_walker; 205 248 249 struct xml_parse_result; 250 206 251 class xml_node; 252 253 class xml_text; 207 254 208 255 #ifndef PUGIXML_NO_XPATH … … 213 260 #endif 214 261 262 // Range-based for loop support 263 template <typename It> class xml_object_range 264 { 265 public: 266 typedef It const_iterator; 267 typedef It iterator; 268 269 xml_object_range(It b, It e): _begin(b), _end(e) 270 { 271 } 272 273 It begin() const { return _begin; } 274 It end() const { return _end; } 275 276 private: 277 It _begin, _end; 278 }; 279 215 280 // Writer interface for node printing (see xml_node::print) 216 281 class PUGIXML_CLASS xml_writer … … 227 292 { 228 293 public: 229 294 // Construct writer from a FILE* object; void* is used to avoid header dependencies on stdio 230 295 xml_writer_file(void* file); 231 296 232 virtual void write(const void* data, size_t size) ;297 virtual void write(const void* data, size_t size) PUGIXML_OVERRIDE; 233 298 234 299 private: … … 241 306 { 242 307 public: 243 308 // Construct writer from an output stream object 244 309 xml_writer_stream(std::basic_ostream<char, std::char_traits<char> >& stream); 245 310 xml_writer_stream(std::basic_ostream<wchar_t, std::char_traits<wchar_t> >& stream); 246 311 247 virtual void write(const void* data, size_t size) ;312 virtual void write(const void* data, size_t size) PUGIXML_OVERRIDE; 248 313 249 314 private: … … 261 326 private: 262 327 xml_attribute_struct* _attr; 263 264 typedef xml_attribute_struct* xml_attribute::*unspecified_bool_type;265 266 public: 267 328 329 typedef void (*unspecified_bool_type)(xml_attribute***); 330 331 public: 332 // Default constructor. Constructs an empty attribute. 268 333 xml_attribute(); 269 270 334 335 // Constructs attribute from internal pointer 271 336 explicit xml_attribute(xml_attribute_struct* attr); 272 337 273 274 275 276 277 338 // Safe bool conversion operator 339 operator unspecified_bool_type() const; 340 341 // Borland C++ workaround 342 bool operator!() const; 278 343 279 344 // Comparison operators (compares wrapped attribute pointers) … … 292 357 const char_t* value() const; 293 358 294 // Get attribute value as a number, or 0 if conversion did not succeed or attribute is empty 295 int as_int() const; 296 unsigned int as_uint() const; 297 double as_double() const; 298 float as_float() const; 299 300 // Get attribute value as bool (returns true if first character is in '1tTyY' set), or false if attribute is empty 301 bool as_bool() const; 302 303 // Set attribute name/value (returns false if attribute is empty or there is not enough memory) 359 // Get attribute value, or the default value if attribute is empty 360 const char_t* as_string(const char_t* def = PUGIXML_TEXT("")) const; 361 362 // Get attribute value as a number, or the default value if conversion did not succeed or attribute is empty 363 int as_int(int def = 0) const; 364 unsigned int as_uint(unsigned int def = 0) const; 365 double as_double(double def = 0) const; 366 float as_float(float def = 0) const; 367 368 #ifdef PUGIXML_HAS_LONG_LONG 369 long long as_llong(long long def = 0) const; 370 unsigned long long as_ullong(unsigned long long def = 0) const; 371 #endif 372 373 // Get attribute value as bool (returns true if first character is in '1tTyY' set), or the default value if attribute is empty 374 bool as_bool(bool def = false) const; 375 376 // Set attribute name/value (returns false if attribute is empty or there is not enough memory) 304 377 bool set_name(const char_t* rhs); 305 378 bool set_value(const char_t* rhs); 306 379 307 380 // Set attribute value with type conversion (numbers are converted to strings, boolean is converted to "true"/"false") 308 381 bool set_value(int rhs); 309 382 bool set_value(unsigned int rhs); 383 bool set_value(long rhs); 384 bool set_value(unsigned long rhs); 310 385 bool set_value(double rhs); 386 bool set_value(float rhs); 311 387 bool set_value(bool rhs); 388 389 #ifdef PUGIXML_HAS_LONG_LONG 390 bool set_value(long long rhs); 391 bool set_value(unsigned long long rhs); 392 #endif 312 393 313 394 // Set attribute value (equivalent to set_value without error checking) … … 315 396 xml_attribute& operator=(int rhs); 316 397 xml_attribute& operator=(unsigned int rhs); 398 xml_attribute& operator=(long rhs); 399 xml_attribute& operator=(unsigned long rhs); 317 400 xml_attribute& operator=(double rhs); 401 xml_attribute& operator=(float rhs); 318 402 xml_attribute& operator=(bool rhs); 319 403 320 // Get next/previous attribute in the attribute list of the parent node 321 xml_attribute next_attribute() const; 322 xml_attribute previous_attribute() const; 323 324 // Get hash value (unique for handles to the same object) 325 size_t hash_value() const; 404 #ifdef PUGIXML_HAS_LONG_LONG 405 xml_attribute& operator=(long long rhs); 406 xml_attribute& operator=(unsigned long long rhs); 407 #endif 408 409 // Get next/previous attribute in the attribute list of the parent node 410 xml_attribute next_attribute() const; 411 xml_attribute previous_attribute() const; 412 413 // Get hash value (unique for handles to the same object) 414 size_t hash_value() const; 326 415 327 416 // Get internal pointer … … 340 429 friend class xml_attribute_iterator; 341 430 friend class xml_node_iterator; 431 friend class xml_named_node_iterator; 342 432 343 433 protected: 344 434 xml_node_struct* _root; 345 435 346 typedef xml_node_struct* xml_node::*unspecified_bool_type;436 typedef void (*unspecified_bool_type)(xml_node***); 347 437 348 438 public: … … 350 440 xml_node(); 351 441 352 442 // Constructs node from internal pointer 353 443 explicit xml_node(xml_node_struct* p); 354 444 355 445 // Safe bool conversion operator 356 446 operator unspecified_bool_type() const; 357 447 358 448 // Borland C++ workaround 359 449 bool operator!() const; 360 450 361 451 // Comparison operators (compares wrapped node pointers) 362 452 bool operator==(const xml_node& r) const; … … 373 463 xml_node_type type() const; 374 464 375 // Get node name /value, or "" if node is empty or it has no name/value465 // Get node name, or "" if node is empty or it has no name 376 466 const char_t* name() const; 467 468 // Get node value, or "" if node is empty or it has no value 469 // Note: For <node>text</node> node.value() does not return "text"! Use child_value() or text() methods to access text inside nodes. 377 470 const char_t* value() const; 378 471 379 472 // Get attribute list 380 473 xml_attribute first_attribute() const; 381 382 383 474 xml_attribute last_attribute() const; 475 476 // Get children list 384 477 xml_node first_child() const; 385 386 387 478 xml_node last_child() const; 479 480 // Get next/previous sibling in the children list of the parent node 388 481 xml_node next_sibling() const; 389 482 xml_node previous_sibling() const; 390 391 483 484 // Get parent node 392 485 xml_node parent() const; 393 486 394 487 // Get root of DOM tree this node belongs to 395 488 xml_node root() const; 489 490 // Get text object for the current node 491 xml_text text() const; 396 492 397 493 // Get child, attribute or next/previous sibling with the specified name … … 401 497 xml_node previous_sibling(const char_t* name) const; 402 498 499 // Get attribute, starting the search from a hint (and updating hint so that searching for a sequence of attributes is fast) 500 xml_attribute attribute(const char_t* name, xml_attribute& hint) const; 501 403 502 // Get child value of current node; that is, value of the first child node of type PCDATA/CDATA 404 503 const char_t* child_value() const; … … 410 509 bool set_name(const char_t* rhs); 411 510 bool set_value(const char_t* rhs); 412 511 413 512 // Add attribute with specified name. Returns added attribute, or empty attribute on errors. 414 513 xml_attribute append_attribute(const char_t* name); … … 441 540 xml_node insert_copy_before(const xml_node& proto, const xml_node& node); 442 541 542 // Move the specified node to become a child of this node. Returns moved node, or empty node on errors. 543 xml_node append_move(const xml_node& moved); 544 xml_node prepend_move(const xml_node& moved); 545 xml_node insert_move_after(const xml_node& moved, const xml_node& node); 546 xml_node insert_move_before(const xml_node& moved, const xml_node& node); 547 443 548 // Remove specified attribute 444 549 bool remove_attribute(const xml_attribute& a); … … 448 553 bool remove_child(const xml_node& n); 449 554 bool remove_child(const char_t* name); 555 556 // Parses buffer as an XML document fragment and appends all nodes as children of the current node. 557 // Copies/converts the buffer, so it may be deleted or changed after the function returns. 558 // Note: append_buffer allocates memory that has the lifetime of the owning document; removing the appended nodes does not immediately reclaim that memory. 559 xml_parse_result append_buffer(const void* contents, size_t size, unsigned int options = parse_default, xml_encoding encoding = encoding_auto); 450 560 451 561 // Find attribute using predicate. Returns first attribute for which predicate returned true. … … 453 563 { 454 564 if (!_root) return xml_attribute(); 455 565 456 566 for (xml_attribute attrib = first_attribute(); attrib; attrib = attrib.next_attribute()) 457 567 if (pred(attrib)) 458 568 return attrib; 459 569 460 570 return xml_attribute(); 461 571 } … … 465 575 { 466 576 if (!_root) return xml_node(); 467 577 468 578 for (xml_node node = first_child(); node; node = node.next_sibling()) 469 579 if (pred(node)) 470 580 return node; 471 472 581 582 return xml_node(); 473 583 } 474 584 … … 479 589 480 590 xml_node cur = first_child(); 481 591 482 592 while (cur._root && cur._root != _root) 483 593 { … … 511 621 // Recursively traverse subtree with xml_tree_walker 512 622 bool traverse(xml_tree_walker& walker); 513 623 514 624 #ifndef PUGIXML_NO_XPATH 515 625 // Select single node by evaluating XPath query. Returns first node from the resulting node set. 516 xpath_node select_ single_node(const char_t* query, xpath_variable_set* variables = 0) const;517 xpath_node select_ single_node(const xpath_query& query) const;626 xpath_node select_node(const char_t* query, xpath_variable_set* variables = 0) const; 627 xpath_node select_node(const xpath_query& query) const; 518 628 519 629 // Select node set by evaluating XPath query 520 630 xpath_node_set select_nodes(const char_t* query, xpath_variable_set* variables = 0) const; 521 631 xpath_node_set select_nodes(const xpath_query& query) const; 522 #endif 523 632 633 // (deprecated: use select_node instead) Select single node by evaluating XPath query. 634 xpath_node select_single_node(const char_t* query, xpath_variable_set* variables = 0) const; 635 xpath_node select_single_node(const xpath_query& query) const; 636 637 #endif 638 524 639 // Print subtree using a writer object 525 640 void print(xml_writer& writer, const char_t* indent = PUGIXML_TEXT("\t"), unsigned int flags = format_default, xml_encoding encoding = encoding_auto, unsigned int depth = 0) const; … … 543 658 attribute_iterator attributes_end() const; 544 659 660 // Range-based for support 661 xml_object_range<xml_node_iterator> children() const; 662 xml_object_range<xml_named_node_iterator> children(const char_t* name) const; 663 xml_object_range<xml_attribute_iterator> attributes() const; 664 545 665 // Get node offset in parsed file/string (in char_t units) for debugging purposes 546 666 ptrdiff_t offset_debug() const; 547 667 548 549 668 // Get hash value (unique for handles to the same object) 669 size_t hash_value() const; 550 670 551 671 // Get internal pointer … … 559 679 #endif 560 680 681 // A helper for working with text inside PCDATA nodes 682 class PUGIXML_CLASS xml_text 683 { 684 friend class xml_node; 685 686 xml_node_struct* _root; 687 688 typedef void (*unspecified_bool_type)(xml_text***); 689 690 explicit xml_text(xml_node_struct* root); 691 692 xml_node_struct* _data_new(); 693 xml_node_struct* _data() const; 694 695 public: 696 // Default constructor. Constructs an empty object. 697 xml_text(); 698 699 // Safe bool conversion operator 700 operator unspecified_bool_type() const; 701 702 // Borland C++ workaround 703 bool operator!() const; 704 705 // Check if text object is empty 706 bool empty() const; 707 708 // Get text, or "" if object is empty 709 const char_t* get() const; 710 711 // Get text, or the default value if object is empty 712 const char_t* as_string(const char_t* def = PUGIXML_TEXT("")) const; 713 714 // Get text as a number, or the default value if conversion did not succeed or object is empty 715 int as_int(int def = 0) const; 716 unsigned int as_uint(unsigned int def = 0) const; 717 double as_double(double def = 0) const; 718 float as_float(float def = 0) const; 719 720 #ifdef PUGIXML_HAS_LONG_LONG 721 long long as_llong(long long def = 0) const; 722 unsigned long long as_ullong(unsigned long long def = 0) const; 723 #endif 724 725 // Get text as bool (returns true if first character is in '1tTyY' set), or the default value if object is empty 726 bool as_bool(bool def = false) const; 727 728 // Set text (returns false if object is empty or there is not enough memory) 729 bool set(const char_t* rhs); 730 731 // Set text with type conversion (numbers are converted to strings, boolean is converted to "true"/"false") 732 bool set(int rhs); 733 bool set(unsigned int rhs); 734 bool set(long rhs); 735 bool set(unsigned long rhs); 736 bool set(double rhs); 737 bool set(float rhs); 738 bool set(bool rhs); 739 740 #ifdef PUGIXML_HAS_LONG_LONG 741 bool set(long long rhs); 742 bool set(unsigned long long rhs); 743 #endif 744 745 // Set text (equivalent to set without error checking) 746 xml_text& operator=(const char_t* rhs); 747 xml_text& operator=(int rhs); 748 xml_text& operator=(unsigned int rhs); 749 xml_text& operator=(long rhs); 750 xml_text& operator=(unsigned long rhs); 751 xml_text& operator=(double rhs); 752 xml_text& operator=(float rhs); 753 xml_text& operator=(bool rhs); 754 755 #ifdef PUGIXML_HAS_LONG_LONG 756 xml_text& operator=(long long rhs); 757 xml_text& operator=(unsigned long long rhs); 758 #endif 759 760 // Get the data node (node_pcdata or node_cdata) for this object 761 xml_node data() const; 762 }; 763 764 #ifdef __BORLANDC__ 765 // Borland C++ workaround 766 bool PUGIXML_FUNCTION operator&&(const xml_text& lhs, bool rhs); 767 bool PUGIXML_FUNCTION operator||(const xml_text& lhs, bool rhs); 768 #endif 769 561 770 // Child node iterator (a bidirectional iterator over a collection of xml_node) 562 771 class PUGIXML_CLASS xml_node_iterator … … 565 774 566 775 private: 567 xml_node _wrap;776 mutable xml_node _wrap; 568 777 xml_node _parent; 569 778 … … 581 790 #endif 582 791 583 792 // Default constructor 584 793 xml_node_iterator(); 585 794 586 795 // Construct an iterator which points to the specified node 587 796 xml_node_iterator(const xml_node& node); 588 797 589 798 // Iterator operators 590 799 bool operator==(const xml_node_iterator& rhs) const; 591 800 bool operator!=(const xml_node_iterator& rhs) const; 592 801 593 xml_node& operator*() ;594 xml_node* operator->() ;802 xml_node& operator*() const; 803 xml_node* operator->() const; 595 804 596 805 const xml_node_iterator& operator++(); … … 607 816 608 817 private: 609 xml_attribute _wrap;818 mutable xml_attribute _wrap; 610 819 xml_node _parent; 611 820 … … 623 832 #endif 624 833 625 834 // Default constructor 626 835 xml_attribute_iterator(); 627 836 628 837 // Construct an iterator which points to the specified attribute 629 838 xml_attribute_iterator(const xml_attribute& attr, const xml_node& parent); 630 839 … … 633 842 bool operator!=(const xml_attribute_iterator& rhs) const; 634 843 635 xml_attribute& operator*() ;636 xml_attribute* operator->() ;844 xml_attribute& operator*() const; 845 xml_attribute* operator->() const; 637 846 638 847 const xml_attribute_iterator& operator++(); … … 643 852 }; 644 853 854 // Named node range helper 855 class PUGIXML_CLASS xml_named_node_iterator 856 { 857 friend class xml_node; 858 859 public: 860 // Iterator traits 861 typedef ptrdiff_t difference_type; 862 typedef xml_node value_type; 863 typedef xml_node* pointer; 864 typedef xml_node& reference; 865 866 #ifndef PUGIXML_NO_STL 867 typedef std::bidirectional_iterator_tag iterator_category; 868 #endif 869 870 // Default constructor 871 xml_named_node_iterator(); 872 873 // Construct an iterator which points to the specified node 874 xml_named_node_iterator(const xml_node& node, const char_t* name); 875 876 // Iterator operators 877 bool operator==(const xml_named_node_iterator& rhs) const; 878 bool operator!=(const xml_named_node_iterator& rhs) const; 879 880 xml_node& operator*() const; 881 xml_node* operator->() const; 882 883 const xml_named_node_iterator& operator++(); 884 xml_named_node_iterator operator++(int); 885 886 const xml_named_node_iterator& operator--(); 887 xml_named_node_iterator operator--(int); 888 889 private: 890 mutable xml_node _wrap; 891 xml_node _parent; 892 const char_t* _name; 893 894 xml_named_node_iterator(xml_node_struct* ref, xml_node_struct* parent, const char_t* name); 895 }; 896 645 897 // Abstract tree walker class (see xml_node::traverse) 646 898 class PUGIXML_CLASS xml_tree_walker … … 650 902 private: 651 903 int _depth; 652 904 653 905 protected: 654 906 // Get current traversal depth 655 907 int depth() const; 656 908 657 909 public: 658 910 xml_tree_walker(); … … 672 924 enum xml_parse_status 673 925 { 674 status_ok = 0, // No error 675 676 status_file_not_found, // File was not found during load_file() 677 status_io_error, // Error reading from file/stream 678 status_out_of_memory, // Could not allocate memory 679 status_internal_error, // Internal error occurred 680 681 status_unrecognized_tag, // Parser could not determine tag type 682 683 status_bad_pi, // Parsing error occurred while parsing document declaration/processing instruction 684 status_bad_comment, // Parsing error occurred while parsing comment 685 status_bad_cdata, // Parsing error occurred while parsing CDATA section 686 status_bad_doctype, // Parsing error occurred while parsing document type declaration 687 status_bad_pcdata, // Parsing error occurred while parsing PCDATA section 688 status_bad_start_element, // Parsing error occurred while parsing start element tag 689 status_bad_attribute, // Parsing error occurred while parsing element attribute 690 status_bad_end_element, // Parsing error occurred while parsing end element tag 691 status_end_element_mismatch // There was a mismatch of start-end tags (closing tag had incorrect name, some tag was not closed or there was an excessive closing tag) 926 status_ok = 0, // No error 927 928 status_file_not_found, // File was not found during load_file() 929 status_io_error, // Error reading from file/stream 930 status_out_of_memory, // Could not allocate memory 931 status_internal_error, // Internal error occurred 932 933 status_unrecognized_tag, // Parser could not determine tag type 934 935 status_bad_pi, // Parsing error occurred while parsing document declaration/processing instruction 936 status_bad_comment, // Parsing error occurred while parsing comment 937 status_bad_cdata, // Parsing error occurred while parsing CDATA section 938 status_bad_doctype, // Parsing error occurred while parsing document type declaration 939 status_bad_pcdata, // Parsing error occurred while parsing PCDATA section 940 status_bad_start_element, // Parsing error occurred while parsing start element tag 941 status_bad_attribute, // Parsing error occurred while parsing element attribute 942 status_bad_end_element, // Parsing error occurred while parsing end element tag 943 status_end_element_mismatch,// There was a mismatch of start-end tags (closing tag had incorrect name, some tag was not closed or there was an excessive closing tag) 944 945 status_append_invalid_root, // Unable to append nodes since root type is not node_element or node_document (exclusive to xml_node::append_buffer) 946 947 status_no_document_element // Parsing resulted in a document without element nodes 692 948 }; 693 949 … … 704 960 xml_encoding encoding; 705 961 706 962 // Default constructor, initializes object to failed state 707 963 xml_parse_result(); 708 964 … … 721 977 722 978 char _memory[192]; 723 979 724 980 // Non-copyable semantics 725 981 xml_document(const xml_document&); 726 const xml_document& operator=(const xml_document&); 727 728 void create(); 729 void destroy(); 730 731 xml_parse_result load_buffer_impl(void* contents, size_t size, unsigned int options, xml_encoding encoding, bool is_mutable, bool own); 982 xml_document& operator=(const xml_document&); 983 984 void _create(); 985 void _destroy(); 732 986 733 987 public: … … 738 992 ~xml_document(); 739 993 740 994 // Removes all nodes, leaving the empty document 741 995 void reset(); 742 996 743 997 // Removes all nodes, then copies the entire contents of the specified document 744 998 void reset(const xml_document& proto); 745 999 … … 750 1004 #endif 751 1005 1006 // (deprecated: use load_string instead) Load document from zero-terminated string. No encoding conversions are applied. 1007 xml_parse_result load(const char_t* contents, unsigned int options = parse_default); 1008 752 1009 // Load document from zero-terminated string. No encoding conversions are applied. 753 xml_parse_result load (const char_t* contents, unsigned int options = parse_default);1010 xml_parse_result load_string(const char_t* contents, unsigned int options = parse_default); 754 1011 755 1012 // Load document from file … … 761 1018 762 1019 // Load document from buffer, using the buffer for in-place parsing (the buffer is modified and used for storage of document data). 763 1020 // You should ensure that buffer data will persist throughout the document's lifetime, and free the buffer memory manually once document is destroyed. 764 1021 xml_parse_result load_buffer_inplace(void* contents, size_t size, unsigned int options = parse_default, xml_encoding encoding = encoding_auto); 765 1022 766 1023 // Load document from buffer, using the buffer for in-place parsing (the buffer is modified and used for storage of document data). 767 1024 // You should allocate the buffer with pugixml allocation function; document will free the buffer when it is no longer needed (you can't use it anymore). 768 1025 xml_parse_result load_buffer_inplace_own(void* contents, size_t size, unsigned int options = parse_default, xml_encoding encoding = encoding_auto); 769 1026 … … 781 1038 bool save_file(const wchar_t* path, const char_t* indent = PUGIXML_TEXT("\t"), unsigned int flags = format_default, xml_encoding encoding = encoding_auto) const; 782 1039 783 784 1040 // Get document element 1041 xml_node document_element() const; 785 1042 }; 786 1043 … … 789 1046 enum xpath_value_type 790 1047 { 791 xpath_type_none, 1048 xpath_type_none, // Unknown type (query failed to compile) 792 1049 xpath_type_node_set, // Node set (xpath_node_set) 793 xpath_type_number, 794 xpath_type_string, 795 xpath_type_boolean 796 }; 797 798 1050 xpath_type_number, // Number 1051 xpath_type_string, // String 1052 xpath_type_boolean // Boolean 1053 }; 1054 1055 // XPath parsing result 799 1056 struct PUGIXML_CLASS xpath_parse_result 800 1057 { … … 805 1062 ptrdiff_t offset; 806 1063 807 1064 // Default constructor, initializes object to failed state 808 1065 xpath_parse_result(); 809 1066 … … 824 1081 xpath_variable* _next; 825 1082 826 xpath_variable( );1083 xpath_variable(xpath_value_type type); 827 1084 828 1085 // Non-copyable semantics 829 1086 xpath_variable(const xpath_variable&); 830 1087 xpath_variable& operator=(const xpath_variable&); 831 832 public: 833 1088 1089 public: 1090 // Get variable name 834 1091 const char_t* name() const; 835 1092 836 1093 // Get variable type 837 1094 xpath_value_type type() const; 838 1095 839 1096 // Get variable value; no type conversion is performed, default value (false, NaN, empty string, empty node set) is returned on type mismatch error 840 1097 bool get_boolean() const; 841 1098 double get_number() const; … … 843 1100 const xpath_node_set& get_node_set() const; 844 1101 845 1102 // Set variable value; no type conversion is performed, false is returned on type mismatch error 846 1103 bool set(bool value); 847 1104 bool set(double value); … … 856 1113 xpath_variable* _data[64]; 857 1114 858 // Non-copyable semantics 859 xpath_variable_set(const xpath_variable_set&); 860 xpath_variable_set& operator=(const xpath_variable_set&); 861 862 xpath_variable* find(const char_t* name) const; 863 864 public: 865 // Default constructor/destructor 1115 void _assign(const xpath_variable_set& rhs); 1116 void _swap(xpath_variable_set& rhs); 1117 1118 xpath_variable* _find(const char_t* name) const; 1119 1120 static bool _clone(xpath_variable* var, xpath_variable** out_result); 1121 static void _destroy(xpath_variable* var); 1122 1123 public: 1124 // Default constructor/destructor 866 1125 xpath_variable_set(); 867 1126 ~xpath_variable_set(); 868 1127 869 // Add a new variable or get the existing one, if the types match 1128 // Copy constructor/assignment operator 1129 xpath_variable_set(const xpath_variable_set& rhs); 1130 xpath_variable_set& operator=(const xpath_variable_set& rhs); 1131 1132 #ifdef PUGIXML_HAS_MOVE 1133 // Move semantics support 1134 xpath_variable_set(xpath_variable_set&& rhs); 1135 xpath_variable_set& operator=(xpath_variable_set&& rhs); 1136 #endif 1137 1138 // Add a new variable or get the existing one, if the types match 870 1139 xpath_variable* add(const char_t* name, xpath_value_type type); 871 1140 872 1141 // Set value of an existing variable; no type conversion is performed, false is returned if there is no such variable or if types mismatch 873 1142 bool set(const char_t* name, bool value); 874 1143 bool set(const char_t* name, double value); … … 876 1145 bool set(const char_t* name, const xpath_node_set& value); 877 1146 878 1147 // Get existing variable by name 879 1148 xpath_variable* get(const char_t* name); 880 1149 const xpath_variable* get(const char_t* name) const; … … 888 1157 xpath_parse_result _result; 889 1158 890 typedef void* xpath_query::*unspecified_bool_type;1159 typedef void (*unspecified_bool_type)(xpath_query***); 891 1160 892 1161 // Non-copyable semantics … … 895 1164 896 1165 public: 897 898 1166 // Construct a compiled object from XPath expression. 1167 // If PUGIXML_NO_EXCEPTIONS is not defined, throws xpath_exception on compilation errors. 899 1168 explicit xpath_query(const char_t* query, xpath_variable_set* variables = 0); 1169 1170 // Constructor 1171 xpath_query(); 900 1172 901 1173 // Destructor 902 1174 ~xpath_query(); 903 1175 1176 #ifdef PUGIXML_HAS_MOVE 1177 // Move semantics support 1178 xpath_query(xpath_query&& rhs); 1179 xpath_query& operator=(xpath_query&& rhs); 1180 #endif 1181 904 1182 // Get query expression return type 905 1183 xpath_value_type return_type() const; 906 1184 907 1185 // Evaluate expression as boolean value in the specified context; performs type conversion if necessary. 908 1186 // If PUGIXML_NO_EXCEPTIONS is not defined, throws std::bad_alloc on out of memory errors. 909 1187 bool evaluate_boolean(const xpath_node& n) const; 910 1188 911 1189 // Evaluate expression as double value in the specified context; performs type conversion if necessary. 912 1190 // If PUGIXML_NO_EXCEPTIONS is not defined, throws std::bad_alloc on out of memory errors. 913 1191 double evaluate_number(const xpath_node& n) const; 914 1192 915 1193 #ifndef PUGIXML_NO_STL 916 1194 // Evaluate expression as string value in the specified context; performs type conversion if necessary. 917 1195 // If PUGIXML_NO_EXCEPTIONS is not defined, throws std::bad_alloc on out of memory errors. 918 1196 string_t evaluate_string(const xpath_node& n) const; 919 1197 #endif 920 1198 921 1199 // Evaluate expression as string value in the specified context; performs type conversion if necessary. 922 923 924 1200 // At most capacity characters are written to the destination buffer, full result size is returned (includes terminating zero). 1201 // If PUGIXML_NO_EXCEPTIONS is not defined, throws std::bad_alloc on out of memory errors. 1202 // If PUGIXML_NO_EXCEPTIONS is defined, returns empty set instead. 925 1203 size_t evaluate_string(char_t* buffer, size_t capacity, const xpath_node& n) const; 926 1204 927 1205 // Evaluate expression as node set in the specified context. 928 929 1206 // If PUGIXML_NO_EXCEPTIONS is not defined, throws xpath_exception on type mismatch and std::bad_alloc on out of memory errors. 1207 // If PUGIXML_NO_EXCEPTIONS is defined, returns empty node set instead. 930 1208 xpath_node_set evaluate_node_set(const xpath_node& n) const; 1209 1210 // Evaluate expression as node set in the specified context. 1211 // Return first node in document order, or empty node if node set is empty. 1212 // If PUGIXML_NO_EXCEPTIONS is not defined, throws xpath_exception on type mismatch and std::bad_alloc on out of memory errors. 1213 // If PUGIXML_NO_EXCEPTIONS is defined, returns empty node instead. 1214 xpath_node evaluate_node(const xpath_node& n) const; 931 1215 932 1216 // Get parsing result (used to get compilation errors in PUGIXML_NO_EXCEPTIONS mode) … … 936 1220 operator unspecified_bool_type() const; 937 1221 938 1222 // Borland C++ workaround 939 1223 bool operator!() const; 940 1224 }; 941 1225 942 1226 #ifndef PUGIXML_NO_EXCEPTIONS 943 1227 // XPath exception class … … 952 1236 953 1237 // Get error message 954 virtual const char* what() const throw() ;955 956 1238 virtual const char* what() const throw() PUGIXML_OVERRIDE; 1239 1240 // Get parse result 957 1241 const xpath_parse_result& result() const; 958 1242 }; 959 1243 #endif 960 1244 961 1245 // XPath node class (either xml_node or xml_attribute) 962 1246 class PUGIXML_CLASS xpath_node … … 965 1249 xml_node _node; 966 1250 xml_attribute _attribute; 967 968 typedef xml_node xpath_node::*unspecified_bool_type;1251 1252 typedef void (*unspecified_bool_type)(xpath_node***); 969 1253 970 1254 public: 971 1255 // Default constructor; constructs empty XPath node 972 1256 xpath_node(); 973 1257 974 1258 // Construct XPath node from XML node/attribute 975 1259 xpath_node(const xml_node& node); … … 979 1263 xml_node node() const; 980 1264 xml_attribute attribute() const; 981 1265 982 1266 // Get parent of contained node/attribute 983 1267 xml_node parent() const; 984 1268 985 1269 // Safe bool conversion operator 986 1270 operator unspecified_bool_type() const; 987 988 989 1271 1272 // Borland C++ workaround 1273 bool operator!() const; 990 1274 991 1275 // Comparison operators … … 1011 1295 type_sorted_reverse // Sorted by document order (descending) 1012 1296 }; 1013 1297 1014 1298 // Constant iterator type 1015 1299 typedef const xpath_node* const_iterator; 1016 1300 1301 // We define non-constant iterator to be the same as constant iterator so that various generic algorithms (i.e. boost foreach) work 1302 typedef const xpath_node* iterator; 1303 1017 1304 // Default constructor. Constructs empty set. 1018 1305 xpath_node_set(); … … 1023 1310 // Destructor 1024 1311 ~xpath_node_set(); 1025 1312 1026 1313 // Copy constructor/assignment operator 1027 1314 xpath_node_set(const xpath_node_set& ns); 1028 1315 xpath_node_set& operator=(const xpath_node_set& ns); 1029 1316 1317 #ifdef PUGIXML_HAS_MOVE 1318 // Move semantics support 1319 xpath_node_set(xpath_node_set&& rhs); 1320 xpath_node_set& operator=(xpath_node_set&& rhs); 1321 #endif 1322 1030 1323 // Get collection type 1031 1324 type_t type() const; 1032 1325 1033 1326 // Get collection size 1034 1327 size_t size() const; 1035 1328 1036 1329 // Indexing operator 1037 1330 const xpath_node& operator[](size_t index) const; 1038 1331 1039 1332 // Collection iterators 1040 1333 const_iterator begin() const; … … 1043 1336 // Sort the collection in ascending/descending order by document order 1044 1337 void sort(bool reverse = false); 1045 1338 1046 1339 // Get first node in the collection by document order 1047 1340 xpath_node first() const; 1048 1341 1049 1342 // Check if collection is empty 1050 1343 bool empty() const; 1051 1344 1052 1345 private: 1053 1346 type_t _type; 1054 1347 1055 1348 xpath_node _storage; 1056 1349 1057 1350 xpath_node* _begin; 1058 1351 xpath_node* _end; 1059 1352 1060 void _assign(const_iterator begin, const_iterator end); 1353 void _assign(const_iterator begin, const_iterator end, type_t type); 1354 void _move(xpath_node_set& rhs); 1061 1355 }; 1062 1356 #endif … … 1066 1360 std::basic_string<char, std::char_traits<char>, std::allocator<char> > PUGIXML_FUNCTION as_utf8(const wchar_t* str); 1067 1361 std::basic_string<char, std::char_traits<char>, std::allocator<char> > PUGIXML_FUNCTION as_utf8(const std::basic_string<wchar_t, std::char_traits<wchar_t>, std::allocator<wchar_t> >& str); 1068 1362 1069 1363 // Convert UTF8 to wide string 1070 1364 std::basic_string<wchar_t, std::char_traits<wchar_t>, std::allocator<wchar_t> > PUGIXML_FUNCTION as_wide(const char* str); … … 1074 1368 // Memory allocation function interface; returns pointer to allocated memory or NULL on failure 1075 1369 typedef void* (*allocation_function)(size_t size); 1076 1370 1077 1371 // Memory deallocation function interface 1078 1079 1080 1081 1082 1083 1084 1085 1372 typedef void (*deallocation_function)(void* ptr); 1373 1374 // Override default memory management functions. All subsequent allocations/deallocations will be performed via supplied functions. 1375 void PUGIXML_FUNCTION set_memory_management_functions(allocation_function allocate, deallocation_function deallocate); 1376 1377 // Get current memory management functions 1378 allocation_function PUGIXML_FUNCTION get_memory_allocation_function(); 1379 deallocation_function PUGIXML_FUNCTION get_memory_deallocation_function(); 1086 1380 } 1087 1381 … … 1092 1386 std::bidirectional_iterator_tag PUGIXML_FUNCTION _Iter_cat(const pugi::xml_node_iterator&); 1093 1387 std::bidirectional_iterator_tag PUGIXML_FUNCTION _Iter_cat(const pugi::xml_attribute_iterator&); 1388 std::bidirectional_iterator_tag PUGIXML_FUNCTION _Iter_cat(const pugi::xml_named_node_iterator&); 1094 1389 } 1095 1390 #endif … … 1101 1396 std::bidirectional_iterator_tag PUGIXML_FUNCTION __iterator_category(const pugi::xml_node_iterator&); 1102 1397 std::bidirectional_iterator_tag PUGIXML_FUNCTION __iterator_category(const pugi::xml_attribute_iterator&); 1398 std::bidirectional_iterator_tag PUGIXML_FUNCTION __iterator_category(const pugi::xml_named_node_iterator&); 1103 1399 } 1104 1400 #endif … … 1106 1402 #endif 1107 1403 1404 // Make sure implementation is included in header-only mode 1405 // Use macro expansion in #include to work around QMake (QTBUG-11923) 1406 #if defined(PUGIXML_HEADER_ONLY) && !defined(PUGIXML_SOURCE) 1407 # define PUGIXML_SOURCE "pugixml.cpp" 1408 # include PUGIXML_SOURCE 1409 #endif 1410 1108 1411 /** 1109 * Copyright (c) 2006-201 0Arseny Kapoulkine1412 * Copyright (c) 2006-2016 Arseny Kapoulkine 1110 1413 * 1111 1414 * Permission is hereby granted, free of charge, to any person … … 1120 1423 * The above copyright notice and this permission notice shall be 1121 1424 * included in all copies or substantial portions of the Software. 1122 * 1425 * 1123 1426 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, 1124 1427 * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
Note:
See TracChangeset
for help on using the changeset viewer.