From 131c1a159c672ee651fa14efe41ee6ea6fd7ebf8 Mon Sep 17 00:00:00 2001 From: Arseny Kapoulkine Date: Sun, 20 Sep 2015 00:03:02 -0700 Subject: Implement integer to string conversion manually 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. --- src/pugixml.cpp | 52 +++++++++++++++++++++++++++++++++++++--------------- 1 file changed, 37 insertions(+), 15 deletions(-) (limited to 'src') diff --git a/src/pugixml.cpp b/src/pugixml.cpp index 2ad2f15..e817690 100644 --- a/src/pugixml.cpp +++ b/src/pugixml.cpp @@ -4540,6 +4540,28 @@ PUGI__NS_BEGIN } #endif + template + PUGI__FN char_t* integer_to_string(char_t (&buf)[64], U value, bool negative) + { + char_t* end = buf + sizeof(buf) / sizeof(buf[0]) - 1; + U rest = negative ? 0 - value : value; + + *end-- = 0; + + do + { + *end-- = static_cast('0' + (rest % 10)); + rest /= 10; + } + while (rest); + + assert(end >= buf); + + *end = '-'; + + return end + !negative; + } + // set value with conversion functions template PUGI__FN bool set_value_buffer(String& dest, Header& header, uintptr_t header_mask, char (&buf)[128]) @@ -4557,19 +4579,19 @@ PUGI__NS_BEGIN template PUGI__FN bool set_value_convert(String& dest, Header& header, uintptr_t header_mask, int value) { - char buf[128]; - sprintf(buf, "%d", value); - - return set_value_buffer(dest, header, header_mask, buf); + char_t buf[64]; + char_t* begin = integer_to_string(buf, value, value < 0); + + return strcpy_insitu(dest, header, header_mask, begin); } template PUGI__FN bool set_value_convert(String& dest, Header& header, uintptr_t header_mask, unsigned int value) { - char buf[128]; - sprintf(buf, "%u", value); + char_t buf[64]; + char_t* begin = integer_to_string(buf, value, false); - return set_value_buffer(dest, header, header_mask, buf); + return strcpy_insitu(dest, header, header_mask, begin); } template @@ -4600,19 +4622,19 @@ PUGI__NS_BEGIN template PUGI__FN bool set_value_convert(String& dest, Header& header, uintptr_t header_mask, long long value) { - char buf[128]; - sprintf(buf, "%lld", value); - - return set_value_buffer(dest, header, header_mask, buf); + char_t buf[64]; + char_t* begin = integer_to_string(buf, value, value < 0); + + return strcpy_insitu(dest, header, header_mask, begin); } template PUGI__FN bool set_value_convert(String& dest, Header& header, uintptr_t header_mask, unsigned long long value) { - char buf[128]; - sprintf(buf, "%llu", value); - - return set_value_buffer(dest, header, header_mask, buf); + char_t buf[64]; + char_t* begin = integer_to_string(buf, value, false); + + return strcpy_insitu(dest, header, header_mask, begin); } #endif -- cgit v1.2.3