diff options
Diffstat (limited to 'core/fxcrt')
-rw-r--r-- | core/fxcrt/fx_basic_gcc.cpp | 215 | ||||
-rw-r--r-- | core/fxcrt/fx_basic_gcc_unittest.cpp | 86 | ||||
-rw-r--r-- | core/fxcrt/fx_system.cpp | 209 | ||||
-rw-r--r-- | core/fxcrt/fx_system_unittest.cpp | 80 |
4 files changed, 286 insertions, 304 deletions
diff --git a/core/fxcrt/fx_basic_gcc.cpp b/core/fxcrt/fx_basic_gcc.cpp deleted file mode 100644 index 12ac399334..0000000000 --- a/core/fxcrt/fx_basic_gcc.cpp +++ /dev/null @@ -1,215 +0,0 @@ -// Copyright 2014 PDFium Authors. All rights reserved. -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -// Original code copyright 2014 Foxit Software Inc. http://www.foxitsoftware.com - -#include <cctype> -#include <cwctype> -#include <limits> - -#include "core/fxcrt/fx_extension.h" -#include "core/fxcrt/fx_string.h" - -namespace { - -template <typename IntType, typename CharType> -IntType FXSYS_StrToInt(const CharType* str) { - if (!str) - return 0; - - // Process the sign. - bool neg = *str == '-'; - if (neg || *str == '+') - str++; - - IntType num = 0; - while (*str && FXSYS_isDecimalDigit(*str)) { - IntType val = FXSYS_DecimalCharToInt(*str); - if (num > (std::numeric_limits<IntType>::max() - val) / 10) { - if (neg && std::numeric_limits<IntType>::is_signed) { - // Return MIN when the represented number is signed type and is smaller - // than the min value. - return std::numeric_limits<IntType>::min(); - } else { - // Return MAX when the represented number is signed type and is larger - // than the max value, or the number is unsigned type and out of range. - return std::numeric_limits<IntType>::max(); - } - } - - num = num * 10 + val; - str++; - } - // When it is a negative value, -num should be returned. Since num may be of - // unsigned type, use ~num + 1 to avoid the warning of applying unary minus - // operator to unsigned type. - return neg ? ~num + 1 : num; -} - -template <typename T, typename UT, typename STR_T> -STR_T FXSYS_IntToStr(T value, STR_T str, int radix) { - if (radix < 2 || radix > 16) { - str[0] = 0; - return str; - } - if (value == 0) { - str[0] = '0'; - str[1] = 0; - return str; - } - int i = 0; - UT uvalue; - if (value < 0) { - str[i++] = '-'; - // Standard trick to avoid undefined behaviour when negating INT_MIN. - uvalue = static_cast<UT>(-(value + 1)) + 1; - } else { - uvalue = value; - } - int digits = 1; - T order = uvalue / radix; - while (order > 0) { - digits++; - order = order / radix; - } - for (int d = digits - 1; d > -1; d--) { - str[d + i] = "0123456789abcdef"[uvalue % radix]; - uvalue /= radix; - } - str[digits + i] = 0; - return str; -} - -} // namespace - -int32_t FXSYS_atoi(const char* str) { - return FXSYS_StrToInt<int32_t, char>(str); -} -uint32_t FXSYS_atoui(const char* str) { - return FXSYS_StrToInt<uint32_t>(str); -} -int32_t FXSYS_wtoi(const wchar_t* str) { - return FXSYS_StrToInt<int32_t, wchar_t>(str); -} -int64_t FXSYS_atoi64(const char* str) { - return FXSYS_StrToInt<int64_t, char>(str); -} -const char* FXSYS_i64toa(int64_t value, char* str, int radix) { - return FXSYS_IntToStr<int64_t, uint64_t, char*>(value, str, radix); -} - -#if _FXM_PLATFORM_ != _FXM_PLATFORM_WINDOWS_ - -int FXSYS_GetACP() { - return 0; -} - -char* FXSYS_strlwr(char* str) { - if (!str) { - return nullptr; - } - char* s = str; - while (*str) { - *str = FXSYS_tolower(*str); - str++; - } - return s; -} -char* FXSYS_strupr(char* str) { - if (!str) { - return nullptr; - } - char* s = str; - while (*str) { - *str = FXSYS_toupper(*str); - str++; - } - return s; -} -wchar_t* FXSYS_wcslwr(wchar_t* str) { - if (!str) { - return nullptr; - } - wchar_t* s = str; - while (*str) { - *str = FXSYS_tolower(*str); - str++; - } - return s; -} -wchar_t* FXSYS_wcsupr(wchar_t* str) { - if (!str) { - return nullptr; - } - wchar_t* s = str; - while (*str) { - *str = FXSYS_toupper(*str); - str++; - } - return s; -} - -int FXSYS_stricmp(const char* dst, const char* src) { - int f; - int l; - do { - f = FXSYS_toupper(*dst); - l = FXSYS_toupper(*src); - ++dst; - ++src; - } while (f && f == l); - return f - l; -} - -int FXSYS_wcsicmp(const wchar_t* dst, const wchar_t* src) { - wchar_t f; - wchar_t l; - do { - f = FXSYS_toupper(*dst); - l = FXSYS_toupper(*src); - ++dst; - ++src; - } while (f && f == l); - return f - l; -} - -char* FXSYS_itoa(int value, char* str, int radix) { - return FXSYS_IntToStr<int32_t, uint32_t, char*>(value, str, radix); -} - -int FXSYS_WideCharToMultiByte(uint32_t codepage, - uint32_t dwFlags, - const wchar_t* wstr, - int wlen, - char* buf, - int buflen, - const char* default_str, - int* pUseDefault) { - int len = 0; - for (int i = 0; i < wlen; i++) { - if (wstr[i] < 0x100) { - if (buf && len < buflen) - buf[len] = static_cast<char>(wstr[i]); - len++; - } - } - return len; -} -int FXSYS_MultiByteToWideChar(uint32_t codepage, - uint32_t dwFlags, - const char* bstr, - int blen, - wchar_t* buf, - int buflen) { - int wlen = 0; - for (int i = 0; i < blen; i++) { - if (buf && wlen < buflen) { - buf[wlen] = bstr[i]; - } - wlen++; - } - return wlen; -} - -#endif // _FXM_PLATFORM_ != _FXM_PLATFORM_WINDOWS_ diff --git a/core/fxcrt/fx_basic_gcc_unittest.cpp b/core/fxcrt/fx_basic_gcc_unittest.cpp deleted file mode 100644 index 2960ee58c0..0000000000 --- a/core/fxcrt/fx_basic_gcc_unittest.cpp +++ /dev/null @@ -1,86 +0,0 @@ -// Copyright 2016 PDFium Authors. All rights reserved. -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -#include "core/fxcrt/fx_system.h" -#include "testing/gtest/include/gtest/gtest.h" - -TEST(fxcrt, FXSYS_atoi) { - EXPECT_EQ(0, FXSYS_atoi("")); - EXPECT_EQ(0, FXSYS_atoi("0")); - EXPECT_EQ(-1, FXSYS_atoi("-1")); - EXPECT_EQ(2345, FXSYS_atoi("2345")); - EXPECT_EQ(-2147483647, FXSYS_atoi("-2147483647")); - // Handle the sign. - EXPECT_EQ(-2345, FXSYS_atoi("-2345")); - EXPECT_EQ(2345, FXSYS_atoi("+2345")); - // The max value. - EXPECT_EQ(2147483647, FXSYS_atoi("2147483647")); - // The min value. Written in -1 format to avoid "unary minus operator applied - // to unsigned type" warning. - EXPECT_EQ(-2147483647 - 1, FXSYS_atoi("-2147483648")); - // With invalid char. - EXPECT_EQ(9, FXSYS_atoi("9x9")); - - // Out of range values. - EXPECT_EQ(2147483647, FXSYS_atoi("2147483623423412348")); - EXPECT_EQ(2147483647, FXSYS_atoi("2147483648")); - EXPECT_EQ(-2147483647 - 1, FXSYS_atoi("-2147483650")); -} - -TEST(fxcrt, FXSYS_atoi64) { - EXPECT_EQ(0, FXSYS_atoi64("")); - EXPECT_EQ(0, FXSYS_atoi64("0")); - EXPECT_EQ(-1, FXSYS_atoi64("-1")); - EXPECT_EQ(2345, FXSYS_atoi64("2345")); - EXPECT_EQ(-9223372036854775807LL, FXSYS_atoi64("-9223372036854775807")); - // Handle the sign. - EXPECT_EQ(-2345, FXSYS_atoi64("-2345")); - EXPECT_EQ(2345, FXSYS_atoi64("+2345")); - // The max value. - EXPECT_EQ(9223372036854775807LL, FXSYS_atoi64("9223372036854775807")); - // The min value. Written in -1 format to avoid implicit unsigned warning. - EXPECT_EQ(-9223372036854775807LL - 1LL, FXSYS_atoi64("-9223372036854775808")); - // With invalid char. - EXPECT_EQ(9, FXSYS_atoi64("9x9")); - - // Out of range values. - EXPECT_EQ(9223372036854775807LL, FXSYS_atoi64("922337203685471234123475807")); - EXPECT_EQ(9223372036854775807LL, FXSYS_atoi64("9223372036854775808")); - EXPECT_EQ(-9223372036854775807LL - 1LL, FXSYS_atoi64("-9223372036854775810")); -} - -TEST(fxcrt, FXSYS_wtoi) { - EXPECT_EQ(0, FXSYS_wtoi(L"")); - EXPECT_EQ(0, FXSYS_wtoi(L"0")); - EXPECT_EQ(-1, FXSYS_wtoi(L"-1")); - EXPECT_EQ(2345, FXSYS_wtoi(L"2345")); - EXPECT_EQ(-2147483647, FXSYS_wtoi(L"-2147483647")); - // The max value. - EXPECT_EQ(2147483647, FXSYS_wtoi(L"2147483647")); - // The min value. - EXPECT_EQ(-2147483647 - 1, FXSYS_wtoi(L"-2147483648")); - - // Out of range values. - EXPECT_EQ(2147483647, FXSYS_wtoi(L"2147483623423412348")); - EXPECT_EQ(2147483647, FXSYS_wtoi(L"2147483648")); - EXPECT_EQ(-2147483647 - 1, FXSYS_wtoi(L"-2147483652")); -} - -TEST(fxcrt, FXSYS_atoui) { - EXPECT_EQ(0u, FXSYS_atoui("")); - EXPECT_EQ(0u, FXSYS_atoui("0")); - EXPECT_EQ(4294967295, FXSYS_atoui("-1")); - EXPECT_EQ(2345u, FXSYS_atoui("2345")); - // Handle the sign. - EXPECT_EQ(4294964951, FXSYS_atoui("-2345")); - EXPECT_EQ(2345u, FXSYS_atoui("+2345")); - // The max value. - EXPECT_EQ(4294967295, FXSYS_atoui("4294967295")); - EXPECT_EQ(9u, FXSYS_atoui("9x9")); - - // Out of range values. - EXPECT_EQ(4294967295, FXSYS_atoui("2147483623423412348")); - EXPECT_EQ(4294967295, FXSYS_atoui("4294967296")); - EXPECT_EQ(4294967295, FXSYS_atoui("-4294967345")); -} diff --git a/core/fxcrt/fx_system.cpp b/core/fxcrt/fx_system.cpp index 83f761ff85..bf13ad2e5e 100644 --- a/core/fxcrt/fx_system.cpp +++ b/core/fxcrt/fx_system.cpp @@ -8,7 +8,81 @@ #include <limits> -extern "C" int FXSYS_round(float d) { +#include "core/fxcrt/fx_extension.h" + +namespace { + +template <typename IntType, typename CharType> +IntType FXSYS_StrToInt(const CharType* str) { + if (!str) + return 0; + + // Process the sign. + bool neg = *str == '-'; + if (neg || *str == '+') + str++; + + IntType num = 0; + while (*str && FXSYS_isDecimalDigit(*str)) { + IntType val = FXSYS_DecimalCharToInt(*str); + if (num > (std::numeric_limits<IntType>::max() - val) / 10) { + if (neg && std::numeric_limits<IntType>::is_signed) { + // Return MIN when the represented number is signed type and is smaller + // than the min value. + return std::numeric_limits<IntType>::min(); + } else { + // Return MAX when the represented number is signed type and is larger + // than the max value, or the number is unsigned type and out of range. + return std::numeric_limits<IntType>::max(); + } + } + + num = num * 10 + val; + str++; + } + // When it is a negative value, -num should be returned. Since num may be of + // unsigned type, use ~num + 1 to avoid the warning of applying unary minus + // operator to unsigned type. + return neg ? ~num + 1 : num; +} + +template <typename T, typename UT, typename STR_T> +STR_T FXSYS_IntToStr(T value, STR_T str, int radix) { + if (radix < 2 || radix > 16) { + str[0] = 0; + return str; + } + if (value == 0) { + str[0] = '0'; + str[1] = 0; + return str; + } + int i = 0; + UT uvalue; + if (value < 0) { + str[i++] = '-'; + // Standard trick to avoid undefined behaviour when negating INT_MIN. + uvalue = static_cast<UT>(-(value + 1)) + 1; + } else { + uvalue = value; + } + int digits = 1; + T order = uvalue / radix; + while (order > 0) { + digits++; + order = order / radix; + } + for (int d = digits - 1; d > -1; d--) { + str[d + i] = "0123456789abcdef"[uvalue % radix]; + uvalue /= radix; + } + str[digits + i] = 0; + return str; +} + +} // namespace + +int FXSYS_round(float d) { if (d < static_cast<float>(std::numeric_limits<int>::min())) return std::numeric_limits<int>::min(); if (d > static_cast<float>(std::numeric_limits<int>::max())) @@ -16,7 +90,136 @@ extern "C" int FXSYS_round(float d) { return static_cast<int>(round(d)); } -#if _FXM_PLATFORM_ == _FXM_PLATFORM_WINDOWS_ +int32_t FXSYS_atoi(const char* str) { + return FXSYS_StrToInt<int32_t, char>(str); +} +uint32_t FXSYS_atoui(const char* str) { + return FXSYS_StrToInt<uint32_t>(str); +} +int32_t FXSYS_wtoi(const wchar_t* str) { + return FXSYS_StrToInt<int32_t, wchar_t>(str); +} +int64_t FXSYS_atoi64(const char* str) { + return FXSYS_StrToInt<int64_t, char>(str); +} +const char* FXSYS_i64toa(int64_t value, char* str, int radix) { + return FXSYS_IntToStr<int64_t, uint64_t, char*>(value, str, radix); +} + +#if _FXM_PLATFORM_ != _FXM_PLATFORM_WINDOWS_ + +int FXSYS_GetACP() { + return 0; +} + +char* FXSYS_strlwr(char* str) { + if (!str) { + return nullptr; + } + char* s = str; + while (*str) { + *str = FXSYS_tolower(*str); + str++; + } + return s; +} +char* FXSYS_strupr(char* str) { + if (!str) { + return nullptr; + } + char* s = str; + while (*str) { + *str = FXSYS_toupper(*str); + str++; + } + return s; +} +wchar_t* FXSYS_wcslwr(wchar_t* str) { + if (!str) { + return nullptr; + } + wchar_t* s = str; + while (*str) { + *str = FXSYS_tolower(*str); + str++; + } + return s; +} +wchar_t* FXSYS_wcsupr(wchar_t* str) { + if (!str) { + return nullptr; + } + wchar_t* s = str; + while (*str) { + *str = FXSYS_toupper(*str); + str++; + } + return s; +} + +int FXSYS_stricmp(const char* dst, const char* src) { + int f; + int l; + do { + f = FXSYS_toupper(*dst); + l = FXSYS_toupper(*src); + ++dst; + ++src; + } while (f && f == l); + return f - l; +} + +int FXSYS_wcsicmp(const wchar_t* dst, const wchar_t* src) { + wchar_t f; + wchar_t l; + do { + f = FXSYS_toupper(*dst); + l = FXSYS_toupper(*src); + ++dst; + ++src; + } while (f && f == l); + return f - l; +} + +char* FXSYS_itoa(int value, char* str, int radix) { + return FXSYS_IntToStr<int32_t, uint32_t, char*>(value, str, radix); +} + +int FXSYS_WideCharToMultiByte(uint32_t codepage, + uint32_t dwFlags, + const wchar_t* wstr, + int wlen, + char* buf, + int buflen, + const char* default_str, + int* pUseDefault) { + int len = 0; + for (int i = 0; i < wlen; i++) { + if (wstr[i] < 0x100) { + if (buf && len < buflen) + buf[len] = static_cast<char>(wstr[i]); + len++; + } + } + return len; +} +int FXSYS_MultiByteToWideChar(uint32_t codepage, + uint32_t dwFlags, + const char* bstr, + int blen, + wchar_t* buf, + int buflen) { + int wlen = 0; + for (int i = 0; i < blen; i++) { + if (buf && wlen < buflen) { + buf[wlen] = bstr[i]; + } + wlen++; + } + return wlen; +} + +#else // _FXM_PLATFORM_ != _FXM_PLATFORM_WINDOWS_ size_t FXSYS_wcsftime(wchar_t* strDest, size_t maxsize, @@ -36,4 +239,4 @@ size_t FXSYS_wcsftime(wchar_t* strDest, return wcsftime(strDest, maxsize, format, timeptr); } -#endif // _FXM_PLATFORM_ == _FXM_PLATFORM_WINDOWS_ +#endif // _FXM_PLATFORM_ != _FXM_PLATFORM_WINDOWS_ diff --git a/core/fxcrt/fx_system_unittest.cpp b/core/fxcrt/fx_system_unittest.cpp index 958d295a24..6a0fe71abe 100644 --- a/core/fxcrt/fx_system_unittest.cpp +++ b/core/fxcrt/fx_system_unittest.cpp @@ -211,3 +211,83 @@ TEST(fxcrt, FXSYS_wcsftime) { FXSYS_wcsftime(buf, FX_ArraySize(buf), L"%y-%m-%dT%H:%M:%S", &feb_time); } + +TEST(fxcrt, FXSYS_atoi) { + EXPECT_EQ(0, FXSYS_atoi("")); + EXPECT_EQ(0, FXSYS_atoi("0")); + EXPECT_EQ(-1, FXSYS_atoi("-1")); + EXPECT_EQ(2345, FXSYS_atoi("2345")); + EXPECT_EQ(-2147483647, FXSYS_atoi("-2147483647")); + // Handle the sign. + EXPECT_EQ(-2345, FXSYS_atoi("-2345")); + EXPECT_EQ(2345, FXSYS_atoi("+2345")); + // The max value. + EXPECT_EQ(2147483647, FXSYS_atoi("2147483647")); + // The min value. Written in -1 format to avoid "unary minus operator applied + // to unsigned type" warning. + EXPECT_EQ(-2147483647 - 1, FXSYS_atoi("-2147483648")); + // With invalid char. + EXPECT_EQ(9, FXSYS_atoi("9x9")); + + // Out of range values. + EXPECT_EQ(2147483647, FXSYS_atoi("2147483623423412348")); + EXPECT_EQ(2147483647, FXSYS_atoi("2147483648")); + EXPECT_EQ(-2147483647 - 1, FXSYS_atoi("-2147483650")); +} + +TEST(fxcrt, FXSYS_atoi64) { + EXPECT_EQ(0, FXSYS_atoi64("")); + EXPECT_EQ(0, FXSYS_atoi64("0")); + EXPECT_EQ(-1, FXSYS_atoi64("-1")); + EXPECT_EQ(2345, FXSYS_atoi64("2345")); + EXPECT_EQ(-9223372036854775807LL, FXSYS_atoi64("-9223372036854775807")); + // Handle the sign. + EXPECT_EQ(-2345, FXSYS_atoi64("-2345")); + EXPECT_EQ(2345, FXSYS_atoi64("+2345")); + // The max value. + EXPECT_EQ(9223372036854775807LL, FXSYS_atoi64("9223372036854775807")); + // The min value. Written in -1 format to avoid implicit unsigned warning. + EXPECT_EQ(-9223372036854775807LL - 1LL, FXSYS_atoi64("-9223372036854775808")); + // With invalid char. + EXPECT_EQ(9, FXSYS_atoi64("9x9")); + + // Out of range values. + EXPECT_EQ(9223372036854775807LL, FXSYS_atoi64("922337203685471234123475807")); + EXPECT_EQ(9223372036854775807LL, FXSYS_atoi64("9223372036854775808")); + EXPECT_EQ(-9223372036854775807LL - 1LL, FXSYS_atoi64("-9223372036854775810")); +} + +TEST(fxcrt, FXSYS_wtoi) { + EXPECT_EQ(0, FXSYS_wtoi(L"")); + EXPECT_EQ(0, FXSYS_wtoi(L"0")); + EXPECT_EQ(-1, FXSYS_wtoi(L"-1")); + EXPECT_EQ(2345, FXSYS_wtoi(L"2345")); + EXPECT_EQ(-2147483647, FXSYS_wtoi(L"-2147483647")); + // The max value. + EXPECT_EQ(2147483647, FXSYS_wtoi(L"2147483647")); + // The min value. + EXPECT_EQ(-2147483647 - 1, FXSYS_wtoi(L"-2147483648")); + + // Out of range values. + EXPECT_EQ(2147483647, FXSYS_wtoi(L"2147483623423412348")); + EXPECT_EQ(2147483647, FXSYS_wtoi(L"2147483648")); + EXPECT_EQ(-2147483647 - 1, FXSYS_wtoi(L"-2147483652")); +} + +TEST(fxcrt, FXSYS_atoui) { + EXPECT_EQ(0u, FXSYS_atoui("")); + EXPECT_EQ(0u, FXSYS_atoui("0")); + EXPECT_EQ(4294967295, FXSYS_atoui("-1")); + EXPECT_EQ(2345u, FXSYS_atoui("2345")); + // Handle the sign. + EXPECT_EQ(4294964951, FXSYS_atoui("-2345")); + EXPECT_EQ(2345u, FXSYS_atoui("+2345")); + // The max value. + EXPECT_EQ(4294967295, FXSYS_atoui("4294967295")); + EXPECT_EQ(9u, FXSYS_atoui("9x9")); + + // Out of range values. + EXPECT_EQ(4294967295, FXSYS_atoui("2147483623423412348")); + EXPECT_EQ(4294967295, FXSYS_atoui("4294967296")); + EXPECT_EQ(4294967295, FXSYS_atoui("-4294967345")); +} |