Pull the new r369476 of base library from Chromium The merge was done against r369476 which corresponds to git commit 0471d0e2e2ef4a544a63481a389e1df33ea7c00a of Jan 14, 2016 Change-Id: Ie6894cf65424cc5ad115110faccd51602b2d1234 Reviewed-on: https://weave-review.googlesource.com/2225 Reviewed-by: Alex Vakulenko <avakulenko@google.com>
diff --git a/third_party/chromium/base/strings/string_number_conversions.cc b/third_party/chromium/base/strings/string_number_conversions.cc index b5463fb..ac0fd46 100644 --- a/third_party/chromium/base/strings/string_number_conversions.cc +++ b/third_party/chromium/base/strings/string_number_conversions.cc
@@ -12,84 +12,44 @@ #include <limits> #include "base/logging.h" -#include "base/scoped_clear_errno.h" -#include "base/third_party/dmg_fp/dmg_fp.h" +#include "base/numerics/safe_conversions.h" +#include "base/numerics/safe_math.h" namespace base { namespace { -template <typename STR, typename INT, typename UINT, bool NEG> +template <typename STR, typename INT> struct IntToStringT { - // This is to avoid a compiler warning about unary minus on unsigned type. - // For example, say you had the following code: - // template <typename INT> - // INT abs(INT value) { return value < 0 ? -value : value; } - // Even though if INT is unsigned, it's impossible for value < 0, so the - // unary minus will never be taken, the compiler will still generate a - // warning. We do a little specialization dance... - template <typename INT2, typename UINT2, bool NEG2> - struct ToUnsignedT {}; - - template <typename INT2, typename UINT2> - struct ToUnsignedT<INT2, UINT2, false> { - static UINT2 ToUnsigned(INT2 value) { - return static_cast<UINT2>(value); - } - }; - - template <typename INT2, typename UINT2> - struct ToUnsignedT<INT2, UINT2, true> { - static UINT2 ToUnsigned(INT2 value) { - return static_cast<UINT2>(value < 0 ? -value : value); - } - }; - - // This set of templates is very similar to the above templates, but - // for testing whether an integer is negative. - template <typename INT2, bool NEG2> - struct TestNegT {}; - template <typename INT2> - struct TestNegT<INT2, false> { - static bool TestNeg(INT2 value) { - // value is unsigned, and can never be negative. - return false; - } - }; - template <typename INT2> - struct TestNegT<INT2, true> { - static bool TestNeg(INT2 value) { - return value < 0; - } - }; - static STR IntToString(INT value) { // log10(2) ~= 0.3 bytes needed per bit or per byte log10(2**8) ~= 2.4. // So round up to allocate 3 output characters per byte, plus 1 for '-'. - const int kOutputBufSize = 3 * sizeof(INT) + 1; + const size_t kOutputBufSize = + 3 * sizeof(INT) + std::numeric_limits<INT>::is_signed; - // Allocate the whole string right away, we will right back to front, and + // Create the string in a temporary buffer, write it back to front, and // then return the substr of what we ended up using. - STR outbuf(kOutputBufSize, 0); + using CHR = typename STR::value_type; + CHR outbuf[kOutputBufSize]; - bool is_neg = TestNegT<INT, NEG>::TestNeg(value); - // Even though is_neg will never be true when INT is parameterized as - // unsigned, even the presence of the unary operation causes a warning. - UINT res = ToUnsignedT<INT, UINT, NEG>::ToUnsigned(value); + // The ValueOrDie call below can never fail, because UnsignedAbs is valid + // for all valid inputs. + auto res = CheckedNumeric<INT>(value).UnsignedAbs().ValueOrDie(); - typename STR::iterator it(outbuf.end()); + CHR* end = outbuf + kOutputBufSize; + CHR* i = end; do { - --it; - DCHECK(it != outbuf.begin()); - *it = static_cast<typename STR::value_type>((res % 10) + '0'); + --i; + DCHECK(i != outbuf); + *i = static_cast<CHR>((res % 10) + '0'); res /= 10; } while (res != 0); - if (is_neg) { - --it; - DCHECK(it != outbuf.begin()); - *it = static_cast<typename STR::value_type>('-'); + if (IsValueNegative(value)) { + --i; + DCHECK(i != outbuf); + *i = static_cast<CHR>('-'); } - return STR(it, outbuf.end()); + return STR(i, end); } }; @@ -100,9 +60,9 @@ // Faster specialization for bases <= 10 template<typename CHAR, int BASE> class BaseCharToDigit<CHAR, BASE, true> { public: - static bool Convert(CHAR c, uint8* digit) { + static bool Convert(CHAR c, uint8_t* digit) { if (c >= '0' && c < '0' + BASE) { - *digit = static_cast<uint8>(c - '0'); + *digit = static_cast<uint8_t>(c - '0'); return true; } return false; @@ -112,7 +72,7 @@ // Specialization for bases where 10 < base <= 36 template<typename CHAR, int BASE> class BaseCharToDigit<CHAR, BASE, false> { public: - static bool Convert(CHAR c, uint8* digit) { + static bool Convert(CHAR c, uint8_t* digit) { if (c >= '0' && c <= '9') { *digit = c - '0'; } else if (c >= 'a' && c < 'a' + BASE - 10) { @@ -126,14 +86,15 @@ } }; -template<int BASE, typename CHAR> bool CharToDigit(CHAR c, uint8* digit) { +template <int BASE, typename CHAR> +bool CharToDigit(CHAR c, uint8_t* digit) { return BaseCharToDigit<CHAR, BASE, BASE <= 10>::Convert(c, digit); } -// There is an IsWhitespace for wchars defined in string_util.h, but it is -// locale independent, whereas the functions we are replacing were -// locale-dependent. TBD what is desired, but for the moment let's not introduce -// a change in behaviour. +// There is an IsUnicodeWhitespace for wchars defined in string_util.h, but it +// is locale independent, whereas the functions we are replacing were +// locale-dependent. TBD what is desired, but for the moment let's not +// introduce a change in behaviour. template<typename CHAR> class WhitespaceHelper { }; @@ -216,7 +177,7 @@ } for (const_iterator current = begin; current != end; ++current) { - uint8 new_digit = 0; + uint8_t new_digit = 0; if (!CharToDigit<traits::kBase>(*current, &new_digit)) { return false; @@ -237,7 +198,7 @@ class Positive : public Base<Positive> { public: - static bool CheckBounds(value_type* output, uint8 new_digit) { + static bool CheckBounds(value_type* output, uint8_t new_digit) { if (*output > static_cast<value_type>(traits::max() / traits::kBase) || (*output == static_cast<value_type>(traits::max() / traits::kBase) && new_digit > traits::max() % traits::kBase)) { @@ -246,14 +207,14 @@ } return true; } - static void Increment(uint8 increment, value_type* output) { + static void Increment(uint8_t increment, value_type* output) { *output += increment; } }; class Negative : public Base<Negative> { public: - static bool CheckBounds(value_type* output, uint8 new_digit) { + static bool CheckBounds(value_type* output, uint8_t new_digit) { if (*output < traits::min() / traits::kBase || (*output == traits::min() / traits::kBase && new_digit > 0 - traits::min() % traits::kBase)) { @@ -262,7 +223,7 @@ } return true; } - static void Increment(uint8 increment, value_type* output) { + static void Increment(uint8_t increment, value_type* output) { *output -= increment; } }; @@ -287,20 +248,17 @@ : public BaseIteratorRangeToNumberTraits<ITERATOR, int, 16> { }; -template<typename ITERATOR> +template <typename ITERATOR> class BaseHexIteratorRangeToUIntTraits - : public BaseIteratorRangeToNumberTraits<ITERATOR, uint32, 16> { -}; + : public BaseIteratorRangeToNumberTraits<ITERATOR, uint32_t, 16> {}; -template<typename ITERATOR> +template <typename ITERATOR> class BaseHexIteratorRangeToInt64Traits - : public BaseIteratorRangeToNumberTraits<ITERATOR, int64, 16> { -}; + : public BaseIteratorRangeToNumberTraits<ITERATOR, int64_t, 16> {}; -template<typename ITERATOR> +template <typename ITERATOR> class BaseHexIteratorRangeToUInt64Traits - : public BaseIteratorRangeToNumberTraits<ITERATOR, uint64, 16> { -}; + : public BaseIteratorRangeToNumberTraits<ITERATOR, uint64_t, 16> {}; typedef BaseHexIteratorRangeToIntTraits<StringPiece::const_iterator> HexIteratorRangeToIntTraits; @@ -314,15 +272,15 @@ typedef BaseHexIteratorRangeToUInt64Traits<StringPiece::const_iterator> HexIteratorRangeToUInt64Traits; -template<typename STR> -bool HexStringToBytesT(const STR& input, std::vector<uint8>* output) { +template <typename STR> +bool HexStringToBytesT(const STR& input, std::vector<uint8_t>* output) { DCHECK_EQ(output->size(), 0u); size_t count = input.size(); if (count == 0 || (count % 2) != 0) return false; for (uintptr_t i = 0; i < count / 2; ++i) { - uint8 msb = 0; // most significant 4 bits - uint8 lsb = 0; // least significant 4 bits + uint8_t msb = 0; // most significant 4 bits + uint8_t lsb = 0; // least significant 4 bits if (!CharToDigit<16>(input[i * 2], &msb) || !CharToDigit<16>(input[i * 2 + 1], &lsb)) return false; @@ -347,32 +305,38 @@ } // namespace std::string IntToString(int value) { - return IntToStringT<std::string, int, unsigned int, true>:: - IntToString(value); + return IntToStringT<std::string, int>::IntToString(value); } std::string UintToString(unsigned int value) { - return IntToStringT<std::string, unsigned int, unsigned int, false>:: - IntToString(value); + return IntToStringT<std::string, unsigned int>::IntToString(value); } -std::string Int64ToString(int64 value) { - return IntToStringT<std::string, int64, uint64, true>::IntToString(value); +std::string Int64ToString(int64_t value) { + return IntToStringT<std::string, int64_t>::IntToString(value); } -std::string Uint64ToString(uint64 value) { - return IntToStringT<std::string, uint64, uint64, false>::IntToString(value); +std::string Uint64ToString(uint64_t value) { + return IntToStringT<std::string, uint64_t>::IntToString(value); } std::string SizeTToString(size_t value) { - return IntToStringT<std::string, size_t, size_t, false>::IntToString(value); + return IntToStringT<std::string, size_t>::IntToString(value); } std::string DoubleToString(double value) { - // According to g_fmt.cc, it is sufficient to declare a buffer of size 32. - char buffer[32]; - dmg_fp::g_fmt(buffer, value); - return std::string(buffer); + auto ret = std::to_string(value); + // If this returned an integer, don't do anything. + if (ret.find('.') == std::string::npos) { + return ret; + } + // Otherwise, it has an annoying tendency to leave trailing zeros. + size_t len = ret.size(); + while (len >= 2 && ret[len - 1] == '0' && ret[len - 2] != '.') { + --len; + } + ret.erase(len); + return ret; } bool StringToInt(const StringPiece& input, int* output) { @@ -383,11 +347,11 @@ return StringToIntImpl(input, output); } -bool StringToInt64(const StringPiece& input, int64* output) { +bool StringToInt64(const StringPiece& input, int64_t* output) { return StringToIntImpl(input, output); } -bool StringToUint64(const StringPiece& input, uint64* output) { +bool StringToUint64(const StringPiece& input, uint64_t* output) { return StringToIntImpl(input, output); } @@ -396,14 +360,10 @@ } bool StringToDouble(const std::string& input, double* output) { - // Thread-safe? It is on at least Mac, Linux, and Windows. - ScopedClearErrno clear_errno; - - char* endptr = NULL; - *output = dmg_fp::strtod(input.c_str(), &endptr); + char* endptr = nullptr; + *output = strtod(input.c_str(), &endptr); // Cases to return false: - // - If errno is ERANGE, there was an overflow or underflow. // - If the input string is empty, there was nothing to parse. // - If endptr does not point to the end of the string, there are either // characters remaining in the string after a parsed number, or the string @@ -411,10 +371,11 @@ // expected end given the string's stated length to correctly catch cases // where the string contains embedded NUL characters. // - If the first character is a space, there was leading whitespace - return errno == 0 && - !input.empty() && + return !input.empty() && input.c_str() + input.length() == endptr && - !isspace(input[0]); + !isspace(input[0]) && + *output != std::numeric_limits<double>::infinity() && + *output != -std::numeric_limits<double>::infinity(); } // Note: if you need to add String16ToDouble, first ask yourself if it's @@ -444,22 +405,22 @@ input.begin(), input.end(), output); } -bool HexStringToUInt(const StringPiece& input, uint32* output) { +bool HexStringToUInt(const StringPiece& input, uint32_t* output) { return IteratorRangeToNumber<HexIteratorRangeToUIntTraits>::Invoke( input.begin(), input.end(), output); } -bool HexStringToInt64(const StringPiece& input, int64* output) { +bool HexStringToInt64(const StringPiece& input, int64_t* output) { return IteratorRangeToNumber<HexIteratorRangeToInt64Traits>::Invoke( input.begin(), input.end(), output); } -bool HexStringToUInt64(const StringPiece& input, uint64* output) { +bool HexStringToUInt64(const StringPiece& input, uint64_t* output) { return IteratorRangeToNumber<HexIteratorRangeToUInt64Traits>::Invoke( input.begin(), input.end(), output); } -bool HexStringToBytes(const std::string& input, std::vector<uint8>* output) { +bool HexStringToBytes(const std::string& input, std::vector<uint8_t>* output) { return HexStringToBytesT(input, output); }
diff --git a/third_party/chromium/base/strings/string_number_conversions.h b/third_party/chromium/base/strings/string_number_conversions.h index c68d0af..af0faa6 100644 --- a/third_party/chromium/base/strings/string_number_conversions.h +++ b/third_party/chromium/base/strings/string_number_conversions.h
@@ -5,11 +5,13 @@ #ifndef BASE_STRINGS_STRING_NUMBER_CONVERSIONS_H_ #define BASE_STRINGS_STRING_NUMBER_CONVERSIONS_H_ +#include <stddef.h> +#include <stdint.h> + #include <string> #include <vector> #include "base/base_export.h" -#include "base/basictypes.h" #include "base/strings/string_piece.h" // ---------------------------------------------------------------------------- @@ -32,12 +34,13 @@ std::string UintToString(unsigned value); -std::string Int64ToString(int64 value); +std::string Int64ToString(int64_t value); -std::string Uint64ToString(uint64 value); +std::string Uint64ToString(uint64_t value); std::string SizeTToString(size_t value); +// Deprecated: prefer std::to_string(double) instead. // DoubleToString converts the double to a string format that ignores the // locale. If you want to use locale specific formatting, use ICU. std::string DoubleToString(double value); @@ -58,22 +61,27 @@ // - No characters parseable as a number at the beginning of the string. // |*output| will be set to 0. // - Empty string. |*output| will be set to 0. +// WARNING: Will write to |output| even when returning false. +// Read the comments above carefully. bool StringToInt(const StringPiece& input, int* output); bool StringToUint(const StringPiece& input, unsigned* output); -bool StringToInt64(const StringPiece& input, int64* output); +bool StringToInt64(const StringPiece& input, int64_t* output); -bool StringToUint64(const StringPiece& input, uint64* output); +bool StringToUint64(const StringPiece& input, uint64_t* output); bool StringToSizeT(const StringPiece& input, size_t* output); +// Deprecated: prefer std::stod() instead. // For floating-point conversions, only conversions of input strings in decimal // form are defined to work. Behavior with strings representing floating-point -// numbers in hexadecimal, and strings representing non-fininte values (such as +// numbers in hexadecimal, and strings representing non-finite values (such as // NaN and inf) is undefined. Otherwise, these behave the same as the integral // variants. This expects the input string to NOT be specific to the locale. // If your input is locale specific, use ICU to read the number. +// WARNING: Will write to |output| even when returning false. +// Read the comments here and above StringToInt() carefully. bool StringToDouble(const std::string& input, double* output); // Hex encoding ---------------------------------------------------------------- @@ -95,24 +103,25 @@ // Will only successful parse hex values that will fit into |output|, i.e. // 0x00000000 < |input| < 0xFFFFFFFF. // The string is not required to start with 0x. -bool HexStringToUInt(const StringPiece& input, uint32* output); +bool HexStringToUInt(const StringPiece& input, uint32_t* output); // Best effort conversion, see StringToInt above for restrictions. // Will only successful parse hex values that will fit into |output|, i.e. // -0x8000000000000000 < |input| < 0x7FFFFFFFFFFFFFFF. -bool HexStringToInt64(const StringPiece& input, int64* output); +bool HexStringToInt64(const StringPiece& input, int64_t* output); // Best effort conversion, see StringToInt above for restrictions. // Will only successful parse hex values that will fit into |output|, i.e. // 0x0000000000000000 < |input| < 0xFFFFFFFFFFFFFFFF. // The string is not required to start with 0x. -bool HexStringToUInt64(const StringPiece& input, uint64* output); +bool HexStringToUInt64(const StringPiece& input, uint64_t* output); // Similar to the previous functions, except that output is a vector of bytes. // |*output| will contain as many bytes as were successfully parsed prior to the // error. There is no overflow, but input.size() must be evenly divisible by 2. // Leading 0x or +/- are not allowed. -bool HexStringToBytes(const std::string& input, std::vector<uint8>* output); +bool HexStringToBytes(const std::string& input, + std::vector<uint8_t>* output); } // namespace base
diff --git a/third_party/chromium/base/strings/string_number_conversions_unittest.cc b/third_party/chromium/base/strings/string_number_conversions_unittest.cc index 80d1471..1cfb2c8 100644 --- a/third_party/chromium/base/strings/string_number_conversions_unittest.cc +++ b/third_party/chromium/base/strings/string_number_conversions_unittest.cc
@@ -5,6 +5,8 @@ #include "base/strings/string_number_conversions.h" #include <errno.h> +#include <limits.h> +#include <stddef.h> #include <stdint.h> #include <stdio.h> @@ -13,6 +15,7 @@ #include <gtest/gtest.h> +#include "base/macros.h" #include "base/strings/stringprintf.h" #include "base/strings/utf_string_conversion_utils.h" @@ -36,15 +39,15 @@ { std::numeric_limits<int>::max(), "2147483647", "2147483647" }, { std::numeric_limits<int>::min(), "-2147483648", "2147483648" }, }; - static const IntToStringTest<int64> int64_tests[] = { - { 0, "0", "0" }, - { -1, "-1", "18446744073709551615" }, - { std::numeric_limits<int64>::max(), - "9223372036854775807", - "9223372036854775807", }, - { std::numeric_limits<int64>::min(), - "-9223372036854775808", - "9223372036854775808" }, + static const IntToStringTest<int64_t> int64_tests[] = { + {0, "0", "0"}, + {-1, "-1", "18446744073709551615"}, + { + std::numeric_limits<int64_t>::max(), "9223372036854775807", + "9223372036854775807", + }, + {std::numeric_limits<int64_t>::min(), "-9223372036854775808", + "9223372036854775808"}, }; for (size_t i = 0; i < arraysize(int_tests); ++i) { @@ -53,7 +56,7 @@ EXPECT_EQ(UintToString(test->num), test->uexpected); } for (size_t i = 0; i < arraysize(int64_tests); ++i) { - const IntToStringTest<int64>* test = &int64_tests[i]; + const IntToStringTest<int64_t>* test = &int64_tests[i]; EXPECT_EQ(Int64ToString(test->num), test->sexpected); EXPECT_EQ(Uint64ToString(test->num), test->uexpected); } @@ -61,13 +64,13 @@ TEST(StringNumberConversionsTest, Uint64ToString) { static const struct { - uint64 input; + uint64_t input; std::string output; } cases[] = { - {0, "0"}, - {42, "42"}, - {INT_MAX, "2147483647"}, - {kuint64max, "18446744073709551615"}, + {0, "0"}, + {42, "42"}, + {INT_MAX, "2147483647"}, + {std::numeric_limits<uint64_t>::max(), "18446744073709551615"}, }; for (size_t i = 0; i < arraysize(cases); ++i) @@ -197,44 +200,44 @@ TEST(StringNumberConversionsTest, StringToInt64) { static const struct { std::string input; - int64 output; + int64_t output; bool success; } cases[] = { - {"0", 0, true}, - {"42", 42, true}, - {"-2147483648", INT_MIN, true}, - {"2147483647", INT_MAX, true}, - {"-2147483649", INT64_C(-2147483649), true}, - {"-99999999999", INT64_C(-99999999999), true}, - {"2147483648", INT64_C(2147483648), true}, - {"99999999999", INT64_C(99999999999), true}, - {"9223372036854775807", kint64max, true}, - {"-9223372036854775808", kint64min, true}, - {"09", 9, true}, - {"-09", -9, true}, - {"", 0, false}, - {" 42", 42, false}, - {"42 ", 42, false}, - {"0x42", 0, false}, - {"\t\n\v\f\r 42", 42, false}, - {"blah42", 0, false}, - {"42blah", 42, false}, - {"blah42blah", 0, false}, - {"-273.15", -273, false}, - {"+98.6", 98, false}, - {"--123", 0, false}, - {"++123", 0, false}, - {"-+123", 0, false}, - {"+-123", 0, false}, - {"-", 0, false}, - {"-9223372036854775809", kint64min, false}, - {"-99999999999999999999", kint64min, false}, - {"9223372036854775808", kint64max, false}, - {"99999999999999999999", kint64max, false}, + {"0", 0, true}, + {"42", 42, true}, + {"-2147483648", INT_MIN, true}, + {"2147483647", INT_MAX, true}, + {"-2147483649", INT64_C(-2147483649), true}, + {"-99999999999", INT64_C(-99999999999), true}, + {"2147483648", INT64_C(2147483648), true}, + {"99999999999", INT64_C(99999999999), true}, + {"9223372036854775807", std::numeric_limits<int64_t>::max(), true}, + {"-9223372036854775808", std::numeric_limits<int64_t>::min(), true}, + {"09", 9, true}, + {"-09", -9, true}, + {"", 0, false}, + {" 42", 42, false}, + {"42 ", 42, false}, + {"0x42", 0, false}, + {"\t\n\v\f\r 42", 42, false}, + {"blah42", 0, false}, + {"42blah", 42, false}, + {"blah42blah", 0, false}, + {"-273.15", -273, false}, + {"+98.6", 98, false}, + {"--123", 0, false}, + {"++123", 0, false}, + {"-+123", 0, false}, + {"+-123", 0, false}, + {"-", 0, false}, + {"-9223372036854775809", std::numeric_limits<int64_t>::min(), false}, + {"-99999999999999999999", std::numeric_limits<int64_t>::min(), false}, + {"9223372036854775808", std::numeric_limits<int64_t>::max(), false}, + {"99999999999999999999", std::numeric_limits<int64_t>::max(), false}, }; for (size_t i = 0; i < arraysize(cases); ++i) { - int64 output = 0; + int64_t output = 0; EXPECT_EQ(cases[i].success, StringToInt64(cases[i].input, &output)); EXPECT_EQ(cases[i].output, output); } @@ -244,7 +247,7 @@ // interpreted as junk after the number. const char input[] = "6\06"; std::string input_string(input, arraysize(input) - 1); - int64 output; + int64_t output; EXPECT_FALSE(StringToInt64(input_string, &output)); EXPECT_EQ(6, output); } @@ -252,46 +255,46 @@ TEST(StringNumberConversionsTest, StringToUint64) { static const struct { std::string input; - uint64 output; + uint64_t output; bool success; } cases[] = { - {"0", 0, true}, - {"42", 42, true}, - {"-2147483648", 0, false}, - {"2147483647", INT_MAX, true}, - {"-2147483649", 0, false}, - {"-99999999999", 0, false}, - {"2147483648", UINT64_C(2147483648), true}, - {"99999999999", UINT64_C(99999999999), true}, - {"9223372036854775807", kint64max, true}, - {"-9223372036854775808", 0, false}, - {"09", 9, true}, - {"-09", 0, false}, - {"", 0, false}, - {" 42", 42, false}, - {"42 ", 42, false}, - {"0x42", 0, false}, - {"\t\n\v\f\r 42", 42, false}, - {"blah42", 0, false}, - {"42blah", 42, false}, - {"blah42blah", 0, false}, - {"-273.15", 0, false}, - {"+98.6", 98, false}, - {"--123", 0, false}, - {"++123", 0, false}, - {"-+123", 0, false}, - {"+-123", 0, false}, - {"-", 0, false}, - {"-9223372036854775809", 0, false}, - {"-99999999999999999999", 0, false}, - {"9223372036854775808", UINT64_C(9223372036854775808), true}, - {"99999999999999999999", kuint64max, false}, - {"18446744073709551615", kuint64max, true}, - {"18446744073709551616", kuint64max, false}, + {"0", 0, true}, + {"42", 42, true}, + {"-2147483648", 0, false}, + {"2147483647", INT_MAX, true}, + {"-2147483649", 0, false}, + {"-99999999999", 0, false}, + {"2147483648", UINT64_C(2147483648), true}, + {"99999999999", UINT64_C(99999999999), true}, + {"9223372036854775807", std::numeric_limits<int64_t>::max(), true}, + {"-9223372036854775808", 0, false}, + {"09", 9, true}, + {"-09", 0, false}, + {"", 0, false}, + {" 42", 42, false}, + {"42 ", 42, false}, + {"0x42", 0, false}, + {"\t\n\v\f\r 42", 42, false}, + {"blah42", 0, false}, + {"42blah", 42, false}, + {"blah42blah", 0, false}, + {"-273.15", 0, false}, + {"+98.6", 98, false}, + {"--123", 0, false}, + {"++123", 0, false}, + {"-+123", 0, false}, + {"+-123", 0, false}, + {"-", 0, false}, + {"-9223372036854775809", 0, false}, + {"-99999999999999999999", 0, false}, + {"9223372036854775808", UINT64_C(9223372036854775808), true}, + {"99999999999999999999", std::numeric_limits<uint64_t>::max(), false}, + {"18446744073709551615", std::numeric_limits<uint64_t>::max(), true}, + {"18446744073709551616", std::numeric_limits<uint64_t>::max(), false}, }; for (size_t i = 0; i < arraysize(cases); ++i) { - uint64 output = 0; + uint64_t output = 0; EXPECT_EQ(cases[i].success, StringToUint64(cases[i].input, &output)); EXPECT_EQ(cases[i].output, output); } @@ -301,7 +304,7 @@ // interpreted as junk after the number. const char input[] = "6\06"; std::string input_string(input, arraysize(input) - 1); - uint64 output; + uint64_t output; EXPECT_FALSE(StringToUint64(input_string, &output)); EXPECT_EQ(6U, output); } @@ -368,7 +371,7 @@ TEST(StringNumberConversionsTest, HexStringToInt) { static const struct { std::string input; - int64 output; + int64_t output; bool success; } cases[] = { {"0", 0, true}, @@ -420,50 +423,55 @@ TEST(StringNumberConversionsTest, HexStringToUInt) { static const struct { std::string input; - uint32 output; + uint32_t output; bool success; } cases[] = { - {"0", 0, true}, - {"42", 0x42, true}, - {"-42", 0, false}, - {"+42", 0x42, true}, - {"7fffffff", INT_MAX, true}, - {"-80000000", 0, false}, - {"ffffffff", 0xffffffff, true}, - {"DeadBeef", 0xdeadbeef, true}, - {"0x42", 0x42, true}, - {"-0x42", 0, false}, - {"+0x42", 0x42, true}, - {"0x7fffffff", INT_MAX, true}, - {"-0x80000000", 0, false}, - {"0xffffffff", kuint32max, true}, - {"0XDeadBeef", 0xdeadbeef, true}, - {"0x7fffffffffffffff", kuint32max, false}, // Overflow test. - {"-0x8000000000000000", 0, false}, - {"0x8000000000000000", kuint32max, false}, // Overflow test. - {"-0x8000000000000001", 0, false}, - {"0xFFFFFFFFFFFFFFFF", kuint32max, false}, // Overflow test. - {"FFFFFFFFFFFFFFFF", kuint32max, false}, // Overflow test. - {"0x0000000000000000", 0, true}, - {"0000000000000000", 0, true}, - {"1FFFFFFFFFFFFFFFF", kuint32max, false}, // Overflow test. - {"0x0f", 0x0f, true}, - {"0f", 0x0f, true}, - {" 45", 0x45, false}, - {"\t\n\v\f\r 0x45", 0x45, false}, - {" 45", 0x45, false}, - {"45 ", 0x45, false}, - {"45:", 0x45, false}, - {"efgh", 0xef, false}, - {"0xefgh", 0xef, false}, - {"hgfe", 0, false}, - {"-", 0, false}, - {"", 0, false}, - {"0x", 0, false}, + {"0", 0, true}, + {"42", 0x42, true}, + {"-42", 0, false}, + {"+42", 0x42, true}, + {"7fffffff", INT_MAX, true}, + {"-80000000", 0, false}, + {"ffffffff", 0xffffffff, true}, + {"DeadBeef", 0xdeadbeef, true}, + {"0x42", 0x42, true}, + {"-0x42", 0, false}, + {"+0x42", 0x42, true}, + {"0x7fffffff", INT_MAX, true}, + {"-0x80000000", 0, false}, + {"0xffffffff", std::numeric_limits<uint32_t>::max(), true}, + {"0XDeadBeef", 0xdeadbeef, true}, + {"0x7fffffffffffffff", std::numeric_limits<uint32_t>::max(), + false}, // Overflow test. + {"-0x8000000000000000", 0, false}, + {"0x8000000000000000", std::numeric_limits<uint32_t>::max(), + false}, // Overflow test. + {"-0x8000000000000001", 0, false}, + {"0xFFFFFFFFFFFFFFFF", std::numeric_limits<uint32_t>::max(), + false}, // Overflow test. + {"FFFFFFFFFFFFFFFF", std::numeric_limits<uint32_t>::max(), + false}, // Overflow test. + {"0x0000000000000000", 0, true}, + {"0000000000000000", 0, true}, + {"1FFFFFFFFFFFFFFFF", std::numeric_limits<uint32_t>::max(), + false}, // Overflow test. + {"0x0f", 0x0f, true}, + {"0f", 0x0f, true}, + {" 45", 0x45, false}, + {"\t\n\v\f\r 0x45", 0x45, false}, + {" 45", 0x45, false}, + {"45 ", 0x45, false}, + {"45:", 0x45, false}, + {"efgh", 0xef, false}, + {"0xefgh", 0xef, false}, + {"hgfe", 0, false}, + {"-", 0, false}, + {"", 0, false}, + {"0x", 0, false}, }; for (size_t i = 0; i < arraysize(cases); ++i) { - uint32 output = 0; + uint32_t output = 0; EXPECT_EQ(cases[i].success, HexStringToUInt(cases[i].input, &output)); EXPECT_EQ(cases[i].output, output); } @@ -472,7 +480,7 @@ // interpreted as junk after the number. const char input[] = "0xc0ffee\0" "9"; std::string input_string(input, arraysize(input) - 1); - uint32 output; + uint32_t output; EXPECT_FALSE(HexStringToUInt(input_string, &output)); EXPECT_EQ(0xc0ffeeU, output); } @@ -480,47 +488,49 @@ TEST(StringNumberConversionsTest, HexStringToInt64) { static const struct { std::string input; - int64 output; + int64_t output; bool success; } cases[] = { - {"0", 0, true}, - {"42", 66, true}, - {"-42", -66, true}, - {"+42", 66, true}, - {"40acd88557b", INT64_C(4444444448123), true}, - {"7fffffff", INT_MAX, true}, - {"-80000000", INT_MIN, true}, - {"ffffffff", 0xffffffff, true}, - {"DeadBeef", 0xdeadbeef, true}, - {"0x42", 66, true}, - {"-0x42", -66, true}, - {"+0x42", 66, true}, - {"0x40acd88557b", INT64_C(4444444448123), true}, - {"0x7fffffff", INT_MAX, true}, - {"-0x80000000", INT_MIN, true}, - {"0xffffffff", 0xffffffff, true}, - {"0XDeadBeef", 0xdeadbeef, true}, - {"0x7fffffffffffffff", kint64max, true}, - {"-0x8000000000000000", kint64min, true}, - {"0x8000000000000000", kint64max, false}, // Overflow test. - {"-0x8000000000000001", kint64min, false}, // Underflow test. - {"0x0f", 15, true}, - {"0f", 15, true}, - {" 45", 0x45, false}, - {"\t\n\v\f\r 0x45", 0x45, false}, - {" 45", 0x45, false}, - {"45 ", 0x45, false}, - {"45:", 0x45, false}, - {"efgh", 0xef, false}, - {"0xefgh", 0xef, false}, - {"hgfe", 0, false}, - {"-", 0, false}, - {"", 0, false}, - {"0x", 0, false}, + {"0", 0, true}, + {"42", 66, true}, + {"-42", -66, true}, + {"+42", 66, true}, + {"40acd88557b", INT64_C(4444444448123), true}, + {"7fffffff", INT_MAX, true}, + {"-80000000", INT_MIN, true}, + {"ffffffff", 0xffffffff, true}, + {"DeadBeef", 0xdeadbeef, true}, + {"0x42", 66, true}, + {"-0x42", -66, true}, + {"+0x42", 66, true}, + {"0x40acd88557b", INT64_C(4444444448123), true}, + {"0x7fffffff", INT_MAX, true}, + {"-0x80000000", INT_MIN, true}, + {"0xffffffff", 0xffffffff, true}, + {"0XDeadBeef", 0xdeadbeef, true}, + {"0x7fffffffffffffff", std::numeric_limits<int64_t>::max(), true}, + {"-0x8000000000000000", std::numeric_limits<int64_t>::min(), true}, + {"0x8000000000000000", std::numeric_limits<int64_t>::max(), + false}, // Overflow test. + {"-0x8000000000000001", std::numeric_limits<int64_t>::min(), + false}, // Underflow test. + {"0x0f", 15, true}, + {"0f", 15, true}, + {" 45", 0x45, false}, + {"\t\n\v\f\r 0x45", 0x45, false}, + {" 45", 0x45, false}, + {"45 ", 0x45, false}, + {"45:", 0x45, false}, + {"efgh", 0xef, false}, + {"0xefgh", 0xef, false}, + {"hgfe", 0, false}, + {"-", 0, false}, + {"", 0, false}, + {"0x", 0, false}, }; for (size_t i = 0; i < arraysize(cases); ++i) { - int64 output = 0; + int64_t output = 0; EXPECT_EQ(cases[i].success, HexStringToInt64(cases[i].input, &output)); EXPECT_EQ(cases[i].output, output); } @@ -529,7 +539,7 @@ // interpreted as junk after the number. const char input[] = "0xc0ffee\0" "9"; std::string input_string(input, arraysize(input) - 1); - int64 output; + int64_t output; EXPECT_FALSE(HexStringToInt64(input_string, &output)); EXPECT_EQ(0xc0ffee, output); } @@ -537,52 +547,53 @@ TEST(StringNumberConversionsTest, HexStringToUInt64) { static const struct { std::string input; - uint64 output; + uint64_t output; bool success; } cases[] = { - {"0", 0, true}, - {"42", 66, true}, - {"-42", 0, false}, - {"+42", 66, true}, - {"40acd88557b", INT64_C(4444444448123), true}, - {"7fffffff", INT_MAX, true}, - {"-80000000", 0, false}, - {"ffffffff", 0xffffffff, true}, - {"DeadBeef", 0xdeadbeef, true}, - {"0x42", 66, true}, - {"-0x42", 0, false}, - {"+0x42", 66, true}, - {"0x40acd88557b", INT64_C(4444444448123), true}, - {"0x7fffffff", INT_MAX, true}, - {"-0x80000000", 0, false}, - {"0xffffffff", 0xffffffff, true}, - {"0XDeadBeef", 0xdeadbeef, true}, - {"0x7fffffffffffffff", kint64max, true}, - {"-0x8000000000000000", 0, false}, - {"0x8000000000000000", UINT64_C(0x8000000000000000), true}, - {"-0x8000000000000001", 0, false}, - {"0xFFFFFFFFFFFFFFFF", kuint64max, true}, - {"FFFFFFFFFFFFFFFF", kuint64max, true}, - {"0x0000000000000000", 0, true}, - {"0000000000000000", 0, true}, - {"1FFFFFFFFFFFFFFFF", kuint64max, false}, // Overflow test. - {"0x0f", 15, true}, - {"0f", 15, true}, - {" 45", 0x45, false}, - {"\t\n\v\f\r 0x45", 0x45, false}, - {" 45", 0x45, false}, - {"45 ", 0x45, false}, - {"45:", 0x45, false}, - {"efgh", 0xef, false}, - {"0xefgh", 0xef, false}, - {"hgfe", 0, false}, - {"-", 0, false}, - {"", 0, false}, - {"0x", 0, false}, + {"0", 0, true}, + {"42", 66, true}, + {"-42", 0, false}, + {"+42", 66, true}, + {"40acd88557b", INT64_C(4444444448123), true}, + {"7fffffff", INT_MAX, true}, + {"-80000000", 0, false}, + {"ffffffff", 0xffffffff, true}, + {"DeadBeef", 0xdeadbeef, true}, + {"0x42", 66, true}, + {"-0x42", 0, false}, + {"+0x42", 66, true}, + {"0x40acd88557b", INT64_C(4444444448123), true}, + {"0x7fffffff", INT_MAX, true}, + {"-0x80000000", 0, false}, + {"0xffffffff", 0xffffffff, true}, + {"0XDeadBeef", 0xdeadbeef, true}, + {"0x7fffffffffffffff", std::numeric_limits<int64_t>::max(), true}, + {"-0x8000000000000000", 0, false}, + {"0x8000000000000000", UINT64_C(0x8000000000000000), true}, + {"-0x8000000000000001", 0, false}, + {"0xFFFFFFFFFFFFFFFF", std::numeric_limits<uint64_t>::max(), true}, + {"FFFFFFFFFFFFFFFF", std::numeric_limits<uint64_t>::max(), true}, + {"0x0000000000000000", 0, true}, + {"0000000000000000", 0, true}, + {"1FFFFFFFFFFFFFFFF", std::numeric_limits<uint64_t>::max(), + false}, // Overflow test. + {"0x0f", 15, true}, + {"0f", 15, true}, + {" 45", 0x45, false}, + {"\t\n\v\f\r 0x45", 0x45, false}, + {" 45", 0x45, false}, + {"45 ", 0x45, false}, + {"45:", 0x45, false}, + {"efgh", 0xef, false}, + {"0xefgh", 0xef, false}, + {"hgfe", 0, false}, + {"-", 0, false}, + {"", 0, false}, + {"0x", 0, false}, }; for (size_t i = 0; i < arraysize(cases); ++i) { - uint64 output = 0; + uint64_t output = 0; EXPECT_EQ(cases[i].success, HexStringToUInt64(cases[i].input, &output)); EXPECT_EQ(cases[i].output, output); } @@ -591,7 +602,7 @@ // interpreted as junk after the number. const char input[] = "0xc0ffee\0" "9"; std::string input_string(input, arraysize(input) - 1); - uint64 output; + uint64_t output; EXPECT_FALSE(HexStringToUInt64(input_string, &output)); EXPECT_EQ(0xc0ffeeU, output); } @@ -624,12 +635,12 @@ for (size_t i = 0; i < arraysize(cases); ++i) { - std::vector<uint8> output; - std::vector<uint8> compare; + std::vector<uint8_t> output; + std::vector<uint8_t> compare; EXPECT_EQ(cases[i].success, HexStringToBytes(cases[i].input, &output)) << i << ": " << cases[i].input; for (size_t j = 0; j < cases[i].output_len; ++j) - compare.push_back(static_cast<uint8>(cases[i].output[j])); + compare.push_back(static_cast<uint8_t>(cases[i].output[j])); ASSERT_EQ(output.size(), compare.size()) << i << ": " << cases[i].input; EXPECT_TRUE(std::equal(output.begin(), output.end(), compare.begin())) << i << ": " << cases[i].input; @@ -651,8 +662,10 @@ {"2.99792458e8", 299792458.0, true}, {"149597870.691E+3", 149597870691.0, true}, {"6.", 6.0, true}, - {"9e99999999999999999999", HUGE_VAL, false}, - {"-9e99999999999999999999", -HUGE_VAL, false}, + {"9e99999999999999999999", std::numeric_limits<double>::infinity(), + false}, + {"-9e99999999999999999999", -std::numeric_limits<double>::infinity(), + false}, {"1e-2", 0.01, true}, {"42 ", 42.0, false}, {" 1e-2", 0.01, false}, @@ -675,7 +688,8 @@ for (size_t i = 0; i < arraysize(cases); ++i) { double output; errno = 1; - EXPECT_EQ(cases[i].success, StringToDouble(cases[i].input, &output)); + EXPECT_EQ(cases[i].success, StringToDouble(cases[i].input, &output)) + << "for input=" << cases[i].input << "got output=" << output; if (cases[i].success) EXPECT_EQ(1, errno) << i; // confirm that errno is unchanged. EXPECT_DOUBLE_EQ(cases[i].output, output); @@ -696,13 +710,13 @@ double input; const char* expected; } cases[] = { - {0.0, "0"}, + {0.0, "0.0"}, {1.25, "1.25"}, - {1.33518e+012, "1.33518e+12"}, - {1.33489e+012, "1.33489e+12"}, - {1.33505e+012, "1.33505e+12"}, - {1.33545e+009, "1335450000"}, - {1.33503e+009, "1335030000"}, + {1.33518e+012, "1335180000000.0"}, + {1.33489e+012, "1334890000000.0"}, + {1.33505e+012, "1335050000000.0"}, + {1.33545e+009, "1335450000.0"}, + {1.33503e+009, "1335030000.0"}, }; for (size_t i = 0; i < arraysize(cases); ++i) { @@ -713,12 +727,12 @@ const char input_bytes[8] = {0, 0, 0, 0, '\xee', '\x6d', '\x73', '\x42'}; double input = 0; memcpy(&input, input_bytes, arraysize(input_bytes)); - EXPECT_EQ("1335179083776", DoubleToString(input)); + EXPECT_EQ("1335179083776.0", DoubleToString(input)); const char input_bytes2[8] = {0, 0, 0, '\xa0', '\xda', '\x6c', '\x73', '\x42'}; input = 0; memcpy(&input, input_bytes2, arraysize(input_bytes2)); - EXPECT_EQ("1334890332160", DoubleToString(input)); + EXPECT_EQ("1334890332160.0", DoubleToString(input)); } TEST(StringNumberConversionsTest, HexEncode) {
diff --git a/third_party/chromium/base/strings/string_piece.cc b/third_party/chromium/base/strings/string_piece.cc index aa0695d..482c9fc 100644 --- a/third_party/chromium/base/strings/string_piece.cc +++ b/third_party/chromium/base/strings/string_piece.cc
@@ -5,9 +5,13 @@ #include "base/strings/string_piece.h" +#include <limits.h> + #include <algorithm> #include <ostream> +#include "base/logging.h" + namespace base { namespace {
diff --git a/third_party/chromium/base/strings/string_piece.h b/third_party/chromium/base/strings/string_piece.h index 14ee635..c79d9fa 100644 --- a/third_party/chromium/base/strings/string_piece.h +++ b/third_party/chromium/base/strings/string_piece.h
@@ -28,7 +28,7 @@ #include <string> #include "base/base_export.h" -#include "base/basictypes.h" +#include "base/logging.h" namespace base { @@ -112,9 +112,13 @@ BasicStringPiece(const value_type* offset, size_type len) : ptr_(offset), length_(len) {} BasicStringPiece(const typename STRING_TYPE::const_iterator& begin, - const typename STRING_TYPE::const_iterator& end) - : ptr_((end > begin) ? &(*begin) : NULL), - length_((end > begin) ? (size_type)(end - begin) : 0) {} + const typename STRING_TYPE::const_iterator& end) { + length_ = static_cast<size_t>(std::distance(begin, end)); + + // The length test before assignment is to avoid dereferencing an iterator + // that may point to the end() of a string. + ptr_ = length_ > 0 ? &*begin : nullptr; + } // data() may return a pointer to a buffer with embedded NULs, and the // returned buffer may or may not be null terminated. Therefore it is @@ -283,12 +287,12 @@ // MSVC doesn't like complex extern templates and DLLs. #if !defined(COMPILER_MSVC) -extern template class BasicStringPiece<std::string>; +extern template class BASE_EXPORT BasicStringPiece<std::string>; #endif // StingPiece operators -------------------------------------------------------- -bool operator==(const StringPiece& x, const StringPiece& y); +BASE_EXPORT bool operator==(const StringPiece& x, const StringPiece& y); inline bool operator!=(const StringPiece& x, const StringPiece& y) { return !(x == y);
diff --git a/third_party/chromium/base/strings/string_piece_unittest.cc b/third_party/chromium/base/strings/string_piece_unittest.cc index 2c2b0a6..5772acd 100644 --- a/third_party/chromium/base/strings/string_piece_unittest.cc +++ b/third_party/chromium/base/strings/string_piece_unittest.cc
@@ -2,6 +2,8 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. +#include <stddef.h> + #include <string> #include <gtest/gtest.h>
diff --git a/third_party/chromium/base/strings/string_util.cc b/third_party/chromium/base/strings/string_util.cc index 4042b39..eb0c546 100644 --- a/third_party/chromium/base/strings/string_util.cc +++ b/third_party/chromium/base/strings/string_util.cc
@@ -4,9 +4,14 @@ #include "base/strings/string_util.h" +#include <stdint.h> +#include <limits> +#include "base/macros.h" #include "base/strings/utf_string_conversion_utils.h" #include "base/third_party/icu/icu_utf.h" +namespace base { + namespace { typedef uintptr_t MachineWord; @@ -30,8 +35,72 @@ }; } // namespace +namespace { -namespace base { +template<typename StringType> +StringType ToLowerASCIIImpl(BasicStringPiece<StringType> str) { + StringType ret; + ret.reserve(str.size()); + for (size_t i = 0; i < str.size(); i++) + ret.push_back(ToLowerASCII(str[i])); + return ret; +} + +template<typename StringType> +StringType ToUpperASCIIImpl(BasicStringPiece<StringType> str) { + StringType ret; + ret.reserve(str.size()); + for (size_t i = 0; i < str.size(); i++) + ret.push_back(ToUpperASCII(str[i])); + return ret; +} + +} // namespace + +std::string ToLowerASCII(StringPiece str) { + return ToLowerASCIIImpl<std::string>(str); +} + +std::string ToUpperASCII(StringPiece str) { + return ToUpperASCIIImpl<std::string>(str); +} + +template<class StringType> +int CompareCaseInsensitiveASCIIT(BasicStringPiece<StringType> a, + BasicStringPiece<StringType> b) { + // Find the first characters that aren't equal and compare them. If the end + // of one of the strings is found before a nonequal character, the lengths + // of the strings are compared. + size_t i = 0; + while (i < a.length() && i < b.length()) { + typename StringType::value_type lower_a = ToLowerASCII(a[i]); + typename StringType::value_type lower_b = ToLowerASCII(b[i]); + if (lower_a < lower_b) + return -1; + if (lower_a > lower_b) + return 1; + i++; + } + + // End of one string hit before finding a different character. Expect the + // common case to be "strings equal" at this point so check that first. + if (a.length() == b.length()) + return 0; + + if (a.length() < b.length()) + return -1; + return 1; +} + +int CompareCaseInsensitiveASCII(StringPiece a, StringPiece b) { + return CompareCaseInsensitiveASCIIT<std::string>(a, b); +} + +bool EqualsCaseInsensitiveASCII(StringPiece a, StringPiece b) { + if (a.length() != b.length()) + return false; + return CompareCaseInsensitiveASCIIT<std::string>(a, b) == 0; +} template<typename STR> bool ReplaceCharsT(const STR& input, @@ -54,7 +123,7 @@ } bool ReplaceChars(const std::string& input, - const base::StringPiece& replace_chars, + const StringPiece& replace_chars, const std::string& replace_with, std::string* output) { return ReplaceCharsT(input, replace_chars.as_string(), replace_with, output); @@ -97,7 +166,7 @@ } bool TrimString(const std::string& input, - base::StringPiece trim_chars, + StringPiece trim_chars, std::string* output) { return TrimStringT(input, trim_chars, TRIM_ALL, output) != TRIM_NONE; } @@ -114,7 +183,7 @@ } StringPiece TrimString(StringPiece input, - const base::StringPiece& trim_chars, + const StringPiece& trim_chars, TrimPositions positions) { return TrimStringPieceT(input, trim_chars, positions); } @@ -161,11 +230,11 @@ bool IsStringUTF8(const StringPiece& str) { const char *src = str.data(); - int32 src_len = static_cast<int32>(str.length()); - int32 char_index = 0; + int32_t src_len = static_cast<int32_t>(str.length()); + int32_t char_index = 0; while (char_index < src_len) { - int32 code_point; + int32_t code_point; CBU8_NEXT(src, char_index, src_len, code_point); if (!IsValidCharacter(code_point)) return false;
diff --git a/third_party/chromium/base/strings/string_util.h b/third_party/chromium/base/strings/string_util.h index 4b41357..d6b6e10 100644 --- a/third_party/chromium/base/strings/string_util.h +++ b/third_party/chromium/base/strings/string_util.h
@@ -9,14 +9,15 @@ #include <ctype.h> #include <stdarg.h> // va_list +#include <stddef.h> +#include <stdint.h> #include <string> #include <vector> -#include "base/base_export.h" -#include "base/basictypes.h" #include "base/compiler_specific.h" #include "base/strings/string_piece.h" // For implicit conversions. +#include "build/build_config.h" // On Android, bionic's stdio.h defines an snprintf macro when being built with // clang. Undefine it here so it won't collide with base::snprintf(). @@ -24,10 +25,10 @@ namespace base { -// C standard-library functions like "strncasecmp" and "snprintf" that aren't -// cross-platform are provided as "base::strncasecmp", and their prototypes -// are listed below. These functions are then implemented as inline calls -// to the platform-specific equivalents in the platform-specific headers. +// C standard-library functions that aren't cross-platform are provided as +// "base::...", and their prototypes are listed below. These functions are +// then implemented as inline calls to the platform-specific equivalents in the +// platform-specific headers. // Wrapper for vsnprintf that always null-terminates and always returns the // number of characters that would be in an untruncated formatted @@ -39,9 +40,14 @@ // We separate the declaration from the implementation of this inline // function just so the PRINTF_FORMAT works. -inline int snprintf(char* buffer, size_t size, const char* format, ...) - PRINTF_FORMAT(3, 4); -inline int snprintf(char* buffer, size_t size, const char* format, ...) { +inline int snprintf(char* buffer, + size_t size, + _Printf_format_string_ const char* format, + ...) PRINTF_FORMAT(3, 4); +inline int snprintf(char* buffer, + size_t size, + _Printf_format_string_ const char* format, + ...) { va_list arguments; va_start(arguments, format); int result = vsnprintf(buffer, size, format, arguments); @@ -49,6 +55,59 @@ return result; } +// BSD-style safe and consistent string copy functions. +// Copies |src| to |dst|, where |dst_size| is the total allocated size of |dst|. +// Copies at most |dst_size|-1 characters, and always NULL terminates |dst|, as +// long as |dst_size| is not 0. Returns the length of |src| in characters. +// If the return value is >= dst_size, then the output was truncated. +// NOTE: All sizes are in number of characters, NOT in bytes. +size_t strlcpy(char* dst, const char* src, size_t dst_size); + +// ASCII-specific tolower. The standard library's tolower is locale sensitive, +// so we don't want to use it here. +inline char ToLowerASCII(char c) { + return (c >= 'A' && c <= 'Z') ? (c + ('a' - 'A')) : c; +} + +// ASCII-specific toupper. The standard library's toupper is locale sensitive, +// so we don't want to use it here. +inline char ToUpperASCII(char c) { + return (c >= 'a' && c <= 'z') ? (c + ('A' - 'a')) : c; +} +// Converts the given string to it's ASCII-lowercase equivalent. +std::string ToLowerASCII(StringPiece str); +// Converts the given string to it's ASCII-uppercase equivalent. +std::string ToUpperASCII(StringPiece str); + +// Functor for case-insensitive ASCII comparisons for STL algorithms like +// std::search. +// +// Note that a full Unicode version of this functor is not possible to write +// because case mappings might change the number of characters, depend on +// context (combining accents), and require handling UTF-16. If you need +// proper Unicode support, use base::i18n::ToLower/FoldCase and then just +// use a normal operator== on the result. +template<typename Char> struct CaseInsensitiveCompareASCII { + public: + bool operator()(Char x, Char y) const { + return ToLowerASCII(x) == ToLowerASCII(y); + } +}; + +// Like strcasecmp for case-insensitive ASCII characters only. Returns: +// -1 (a < b) +// 0 (a == b) +// 1 (a > b) +// (unlike strcasecmp which can return values greater or less than 1/-1). For +// full Unicode support, use base::i18n::ToLower or base::i18h::FoldCase +// and then just call the normal string operators on the result. +int CompareCaseInsensitiveASCII(StringPiece a, StringPiece b); + +// Equality for ASCII case-insensitive comparisons. For full Unicode support, +// use base::i18n::ToLower or base::i18h::FoldCase and then compare with either +// == or !=. +bool EqualsCaseInsensitiveASCII(StringPiece a, StringPiece b); + // Contains the set of characters representing whitespace in the corresponding // encoding. Null-terminated. The ASCII versions are the whitespaces as defined // by HTML5, and don't include control characters. @@ -60,7 +119,7 @@ // |replace_chars| must be null-terminated. // NOTE: Safe to use the same variable for both |input| and |output|. bool ReplaceChars(const std::string& input, - const base::StringPiece& replace_chars, + const StringPiece& replace_chars, const std::string& replace_with, std::string* output); @@ -77,32 +136,26 @@ // It is safe to use the same variable for both |input| and |output| (this is // the normal usage to trim in-place). bool TrimString(const std::string& input, - base::StringPiece trim_chars, + StringPiece trim_chars, std::string* output); // StringPiece versions of the above. The returned pieces refer to the original // buffer. StringPiece TrimString(StringPiece input, - const base::StringPiece& trim_chars, + const StringPiece& trim_chars, TrimPositions positions); -// Trims any whitespace from either end of the input string. Returns where -// whitespace was found. -// The non-wide version has two functions: -// * TrimWhitespaceASCII() -// This function is for ASCII strings and only looks for ASCII whitespace; -// Please choose the best one according to your usage. +// Trims any whitespace from either end of the input string. +// +// The StringPiece versions return a substring referencing the input buffer. +// The ASCII versions look only for ASCII whitespace. +// +// The std::string versions return where whitespace was found. // NOTE: Safe to use the same variable for both input and output. TrimPositions TrimWhitespaceASCII(const std::string& input, TrimPositions positions, std::string* output); -// Deprecated. This function is only for backward compatibility and calls -// TrimWhitespaceASCII(). -TrimPositions TrimWhitespace(const std::string& input, - TrimPositions positions, - std::string* output); - // Returns true if the specified string matches the criteria. How can a wide // string be 8-bit or UTF8? It contains only characters that are < 256 (in the // first case) or characters that use only 8-bits and whose 8-bit
diff --git a/third_party/chromium/base/strings/string_util_posix.h b/third_party/chromium/base/strings/string_util_posix.h index ccfff10..07a89e4 100644 --- a/third_party/chromium/base/strings/string_util_posix.h +++ b/third_party/chromium/base/strings/string_util_posix.h
@@ -6,6 +6,7 @@ #define BASE_STRINGS_STRING_UTIL_POSIX_H_ #include <stdarg.h> +#include <stddef.h> #include <stdio.h> #include <string.h> #include <wchar.h> @@ -18,7 +19,6 @@ const char* format, va_list arguments) { return ::vsnprintf(buffer, size, format, arguments); } - } // namespace base #endif // BASE_STRINGS_STRING_UTIL_POSIX_H_
diff --git a/third_party/chromium/base/strings/string_util_unittest.cc b/third_party/chromium/base/strings/string_util_unittest.cc index 1a75218..451fbd8 100644 --- a/third_party/chromium/base/strings/string_util_unittest.cc +++ b/third_party/chromium/base/strings/string_util_unittest.cc
@@ -6,13 +6,15 @@ #include <math.h> #include <stdarg.h> +#include <stddef.h> +#include <stdint.h> #include <algorithm> #include <gmock/gmock.h> #include <gtest/gtest.h> -#include "base/basictypes.h" +#include "base/macros.h" #include "base/strings/utf_string_conversion_utils.h" using ::testing::ElementsAre;
diff --git a/third_party/chromium/base/strings/stringprintf.cc b/third_party/chromium/base/strings/stringprintf.cc index 5f1ad9b..8147ed3 100644 --- a/third_party/chromium/base/strings/stringprintf.cc +++ b/third_party/chromium/base/strings/stringprintf.cc
@@ -5,12 +5,13 @@ #include "base/strings/stringprintf.h" #include <errno.h> +#include <stddef.h> #include <vector> -#include "base/logging.h" #include "base/scoped_clear_errno.h" #include "base/strings/string_util.h" +#include "build/build_config.h" namespace base {
diff --git a/third_party/chromium/base/strings/stringprintf.h b/third_party/chromium/base/strings/stringprintf.h index 06962b7..4c81400 100644 --- a/third_party/chromium/base/strings/stringprintf.h +++ b/third_party/chromium/base/strings/stringprintf.h
@@ -11,6 +11,7 @@ #include "base/base_export.h" #include "base/compiler_specific.h" +#include "build/build_config.h" namespace base {
diff --git a/third_party/chromium/base/strings/stringprintf_unittest.cc b/third_party/chromium/base/strings/stringprintf_unittest.cc index 88a9675..e70499d 100644 --- a/third_party/chromium/base/strings/stringprintf_unittest.cc +++ b/third_party/chromium/base/strings/stringprintf_unittest.cc
@@ -5,10 +5,12 @@ #include "base/strings/stringprintf.h" #include <errno.h> +#include <stddef.h> #include <gtest/gtest.h> -#include "base/basictypes.h" +#include "base/macros.h" +#include "build/build_config.h" namespace base { @@ -145,10 +147,10 @@ EXPECT_STREQ(src, out.c_str()); } -// TODO(evanm): what's the proper cross-platform test here? #if defined(OS_WIN) -// sprintf in Visual Studio fails when given U+FFFF. This tests that the -// failure case is gracefuly handled. +// vswprintf in Visual Studio 2013 fails when given U+FFFF. This tests that the +// failure case is gracefuly handled. In Visual Studio 2015 the bad character +// is passed through. TEST(StringPrintfTest, Invalid) { wchar_t invalid[2]; invalid[0] = 0xffff; @@ -156,7 +158,11 @@ std::wstring out; SStringPrintf(&out, L"%ls", invalid); +#if _MSC_VER >= 1900 + EXPECT_STREQ(invalid, out.c_str()); +#else EXPECT_STREQ(L"", out.c_str()); +#endif } #endif
diff --git a/third_party/chromium/base/strings/utf_string_conversion_utils.cc b/third_party/chromium/base/strings/utf_string_conversion_utils.cc index 05bd122..3091241 100644 --- a/third_party/chromium/base/strings/utf_string_conversion_utils.cc +++ b/third_party/chromium/base/strings/utf_string_conversion_utils.cc
@@ -11,15 +11,15 @@ // ReadUnicodeCharacter -------------------------------------------------------- bool ReadUnicodeCharacter(const char* src, - int32 src_len, - int32* char_index, - uint32* code_point_out) { + int32_t src_len, + int32_t* char_index, + uint32_t* code_point_out) { // U8_NEXT expects to be able to use -1 to signal an error, so we must // use a signed type for code_point. But this function returns false // on error anyway, so code_point_out is unsigned. - int32 code_point; + int32_t code_point; CBU8_NEXT(src, *char_index, src_len, code_point); - *code_point_out = static_cast<uint32>(code_point); + *code_point_out = static_cast<uint32_t>(code_point); // The ICU macro above moves to the next char, we want to point to the last // char consumed. @@ -31,7 +31,7 @@ // WriteUnicodeCharacter ------------------------------------------------------- -size_t WriteUnicodeCharacter(uint32 code_point, std::string* output) { +size_t WriteUnicodeCharacter(uint32_t code_point, std::string* output) { if (code_point <= 0x7f) { // Fast path the common case of one byte. output->push_back(static_cast<char>(code_point));
diff --git a/third_party/chromium/base/strings/utf_string_conversion_utils.h b/third_party/chromium/base/strings/utf_string_conversion_utils.h index d932d9f..a29b181 100644 --- a/third_party/chromium/base/strings/utf_string_conversion_utils.h +++ b/third_party/chromium/base/strings/utf_string_conversion_utils.h
@@ -9,12 +9,14 @@ // This should only be used by the various UTF string conversion files. +#include <stddef.h> +#include <stdint.h> + #include "base/base_export.h" -#include "base/basictypes.h" namespace base { -inline bool IsValidCodepoint(uint32 code_point) { +inline bool IsValidCodepoint(uint32_t code_point) { // Excludes the surrogate code points ([0xD800, 0xDFFF]) and // codepoints larger than 0x10FFFF (the highest codepoint allowed). // Non-characters and unassigned codepoints are allowed. @@ -22,7 +24,7 @@ (code_point >= 0xE000u && code_point <= 0x10FFFFu); } -inline bool IsValidCharacter(uint32 code_point) { +inline bool IsValidCharacter(uint32_t code_point) { // Excludes non-characters (U+FDD0..U+FDEF, and all codepoints ending in // 0xFFFE or 0xFFFF) from the set of valid code points. return code_point < 0xD800u || (code_point >= 0xE000u && @@ -40,16 +42,16 @@ // // Returns true on success. On false, |*code_point| will be invalid. bool ReadUnicodeCharacter(const char* src, - int32 src_len, - int32* char_index, - uint32* code_point_out); + int32_t src_len, + int32_t* char_index, + uint32_t* code_point_out); #if defined(WCHAR_T_IS_UTF32) // Reads UTF-32 character. The usage is the same as the 8-bit version above. bool ReadUnicodeCharacter(const wchar_t* src, - int32 src_len, - int32* char_index, - uint32* code_point); + int32_t src_len, + int32_t* char_index, + uint32_t* code_point); #endif // defined(WCHAR_T_IS_UTF32) // WriteUnicodeCharacter ------------------------------------------------------- @@ -57,12 +59,12 @@ // Appends a UTF-8 character to the given 8-bit string. Returns the number of // bytes written. // TODO(brettw) Bug 79631: This function should not be exposed. -size_t WriteUnicodeCharacter(uint32 code_point, std::string* output); +size_t WriteUnicodeCharacter(uint32_t code_point, std::string* output); #if defined(WCHAR_T_IS_UTF32) // Appends the given UTF-32 character to the given 32-bit string. Returns the // number of 32-bit values written. -inline size_t WriteUnicodeCharacter(uint32 code_point, std::wstring* output) { +inline size_t WriteUnicodeCharacter(uint32_t code_point, std::wstring* output) { // This is the easy case, just append the character. output->push_back(code_point); return 1;