summaryrefslogtreecommitdiff
path: root/src/pugixml.cpp
AgeCommit message (Collapse)Author
2015-10-17Fix integer overflow detection with leading zerosArseny Kapoulkine
Since they don't contribute to the resulting value just skip them before parsing. This matches the behavior of strtol/strtoll and results in more intuitive behavior.
2015-10-17Use explicit tests in set_Name/set_valueArseny Kapoulkine
Node type enum is not used as an array index anywhere else; the code is not very readable and the value of this "optimization" is questionable. The conditions are arranged so that in all normal cases the first comparison returns true anyway.
2015-10-17Fix argument mismatch in integer parsingArseny Kapoulkine
The minneg argument is supposed to be the absolute value of the minimum negative representable number. In case of two-complement arithmetic, it's the same as the value itself but it's better to be explicit and negate the argument.
2015-10-17Add compact_hash_table assertionsArseny Kapoulkine
2015-10-12Refactor output buffer encodingArseny Kapoulkine
Share the implementation for different encodings. We still need two functions because endian_swap on uint8_t is ambiguous...
2015-10-10Update version to 1.7Arseny Kapoulkine
2015-10-09Refactor utf_decoder classesArseny Kapoulkine
Instead of functions with different names (e.g. decode_utf8_block), split utf_decoder class into multiple classes with ::process static function. This makes it easier to share code for decoding different encodings.
2015-10-07Use correct type for lead in decode_utf16_blockArseny Kapoulkine
This does not affect correctness but makes code more uniform.
2015-10-07Refactor decode_utfN_block and decode_latin1_blockArseny Kapoulkine
Make sure the looping structure is the same as in decode_utf8_block.
2015-10-07Simplify file/stream loading flowArseny Kapoulkine
Instead of calling xml_document public functions just call implementation of load_buffer_inplace_own. This makes it so we only call reset() once during load_file/load.
2015-10-06Fixed missing PUGI__FNA. Breust
2015-09-21Fix parsing of integers that start with +Arseny Kapoulkine
This matches the format strtol supports.
2015-09-20Fix signed/unsigned warnings for MSVCArseny Kapoulkine
2015-09-20Implement custom string to integer conversionArseny Kapoulkine
This makes conversion significantly faster and removes more CRT dependencies; in particular, to support long long pugixml only requires the type itself (and the division operator...). New implementation is up to 3x faster on short decimal numbers. Note that unlike the old implementation, new implementation correctly handles overflow and underflow and clamps the value to the representable range. This means that there are some behavior changes - e.g. previously as_uint on "-1" would return INT_MAX instead of 0. In addition to CRT issues, for platforms with 64-bit long old implementation incorrectly truncated from long to int or unsigned int, so even if CRT clamped the values the result would have been incorrect.
2015-09-20Inline widen_ascii to get rid of an extra strlen callArseny Kapoulkine
Also since this function is only used once and is not defined in regular mode to avoid warnings this simplifies code a bit.
2015-09-20Eliminate redundant strlen calls during set_value/setArseny Kapoulkine
Since we use manual integer conversion we know the length of the string. This makes set_value(int) ~30% faster for 4-digit numbers.
2015-09-20Force callers of strcpy_insitu to compute string lengthArseny Kapoulkine
This makes it possible to avoid calling strlen if we already know the string size.
2015-09-20Implement integer to string conversion manuallyArseny Kapoulkine
This reduces the amount of non-standard C++ functionality pugixml may be using by avoiding sprintf with %lld; additionally this implementation is significantly faster (4-5x) than sprintf, mostly due to avoiding format string parsing and stream setup that commonly happens in CRT implementations. This comes at the expense of requiring long long division/remainder operations if PUGIXML_USE_LONG_LONG is defined which will surely bite me one day.
2015-08-14Minor get_integer_base optimizationArseny Kapoulkine
Remove an extra branch.
2015-07-26Fix two UB sanitizer false positivesArseny Kapoulkine
Change the expression to reference the array element indirectly. The memory block can be bigger than the structure so it's invalid to use static data[] size for bounds checking.
2015-07-25XPath: Increase memory block alignment to 8 bytesArseny Kapoulkine
To be more precise, the memory block is now aligned to be able to reliably allocate objects with both double and pointer fields. If there is a platform with a 4-byte double and a 4-byte pointer, the memory block alignment there will stay the same after this change. Fixes #48.
2015-07-25XPath: Refactor block allocationArseny Kapoulkine
Extract memory page size and block alignment into named constants.
2015-07-22XPath: Split optimize into optimize and optimize_selfArseny Kapoulkine
This makes the code slightly more readable, but more importantly it fixes a false positive in Clang static analyzer. Fixes #47.
2015-06-12Fix Clang 3.7 compatibilityArseny Kapoulkine
Apparently Clang 3.7 implements C++ DR 1748 that makes placement new with null pointer undefined behavior. Which renders all C++ programs that rely on this invalid. Which includes pugixml. This is not very likely to happen in the wild because the allocations that are subject to this in pugixml are relatively small, but tests break because of this. Fix the issue by adding null pointer checks (that are completely redundant in all current compilers except Clang 3.7 but it's not like there is another option).
2015-05-22Fix MSVC7 compilationArseny Kapoulkine
Work around a name lookup bug by pulling auto_deleter name in the local scope. We could also move auto_deleter to pugi:: namespace, but that pollutes it unnecessarily for other compilers.
2015-05-22Move default value handling into as_ functionsArseny Kapoulkine
This makes get_value_* simpler and also works around DMC compilation issue.
2015-05-20XPath: Use strtod instead of atofArseny Kapoulkine
This makes code more consistent between wchar/utf8 mode.
2015-05-14Implement xml_node::attribute with a hintArseny Kapoulkine
Extra argument 'hint' is used to start the attribute lookup; if the attribute is not found the lookup is restarted from the beginning of the attriubte list. This allows to optimize attribute lookups if you need to get many attributes from the node and can make assumptions about the likely ordering. The code is correct regardless of the order, but it is faster than using vanilla lookups if the order matches the calling order. Fixes #30.
2015-05-03Fix NO_STL+NO_XPATH modeArseny Kapoulkine
auto_deleter is now used in all modes so we can't exclude it from compilation.
2015-05-03Cleanup before mergeArseny Kapoulkine
2015-05-03Fix MSVC warningArseny Kapoulkine
2015-05-02Fix MSVC buildArseny Kapoulkine
2015-05-02Reorder conditions in compact_string implementationArseny Kapoulkine
Now compact_string matches compact_pointer_parent. Turns out PUGI__UNLIKELY is good at reordering conditions but usually does not really affect performance. Since MSVC should treat "if" branches as taken and does not support branch probabilities, don't use them if we don't need to.
2015-05-02Minor refactoringArseny Kapoulkine
2015-05-02Revise marker deletion strategyArseny Kapoulkine
Instead of checking if the object being removed allocated a marker, mark the marker block as deleted immediately upon allocation. This simplifies the logic and prevents extra markers from being inserted if we allocate/deallocate the same node indefinitely. Also change marker pointer type to uint32_t*.
2015-05-02Optimize compact_stringArseny Kapoulkine
First assignment uses a fast path; second assignment uses a specialized path as well.
2015-05-02Fix node deallocationArseny Kapoulkine
When we deallocate nodes/attributes that allocated the marker we have to adjust the size accordingly, and dismiss the marker in case it gets overwritten with something else...
2015-05-02Implement efficient compact_header storageArseny Kapoulkine
Header is now just 2 bytes, with optional additonal 4 bytes that are only allocated for every 85 nodes / 128 attributes.
2015-05-01Implement compact_string with shared storageArseny Kapoulkine
2015-05-01Rename compact_string to compact_string_fatArseny Kapoulkine
2015-05-01Revert to name/value storage inside nodeArseny Kapoulkine
This temporarily increases the node size to 16 bytes - we'll bring it back. It allows us to remove the horrible node_pi hack and to reduce the amount of changes against master. This comes at the price of not decreasing basline xml_node_struct size. The compact xml_node_struct is also increased by this change but a followup change will reduce *both* xml_attribute_struct and xml_node_struct (to 8/12 bytes).
2015-04-29Refactor offset_debugArseny Kapoulkine
Split a long line into multiple statements.
2015-04-22Change xml_node_struct field order to match compactArseny Kapoulkine
Also remove useless comments.
2015-04-22Fix node_pi memory leakArseny Kapoulkine
2015-04-22Make xml_node::value() structure consistent with set_*Arseny Kapoulkine
2015-04-22Remove compact_header::operator uintptr_tArseny Kapoulkine
We used this in two cases - to get the page pointer and to test flags. We now use PUGI__GETPAGE for getting the page pointer and operator& to test flags - this makes getting node type significantly faster since it does not require page pointer reconstruction.
2015-04-22Remove redundant has_value checkArseny Kapoulkine
2015-04-22Use has_name/has_value in set_name/set_valueArseny Kapoulkine
2015-04-22Optimize and refactor compact_pointer implementationsArseny Kapoulkine
Clarify the offset applied when encoding the pointer difference. Make decoding diff slightly more clear - no effect on performance. Adjust branch weighting in compact_string encoding - 0.5% faster. Use uint16_t in compact_pointer_parent - 2% faster.
2015-04-21Optimize xml_allocator::reserve()Arseny Kapoulkine
Make sure compact_hash_table::rehash() is not inlined - that way reserve() is inlined so the fast path has no extra function calls. Also use subtraction instead of multiplication when checking capacity.