Skip to content
This repository was archived by the owner on Feb 25, 2025. It is now read-only.
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions third_party/accessibility/base/BUILD.gn
Original file line number Diff line number Diff line change
Expand Up @@ -53,5 +53,6 @@ source_set("base") {
public_deps = [
"numerics",
"//flutter/third_party/accessibility/ax_build",
"//third_party/dart/runtime/third_party/double-conversion/src:libdouble_conversion",
]
}
53 changes: 47 additions & 6 deletions third_party/accessibility/base/string_utils.cc
Original file line number Diff line number Diff line change
Expand Up @@ -4,12 +4,15 @@

#include "string_utils.h"

#include <array>
#include <cctype>
#include <codecvt>
#include <locale>
#include <regex>
#include <sstream>

#include "third_party/dart/runtime/third_party/double-conversion/src/double-conversion.h"

#if defined(_WIN32)
#include "base/win/string_conversion.h"
#endif
Expand All @@ -18,6 +21,48 @@

namespace base {

using double_conversion::DoubleToStringConverter;
using double_conversion::StringBuilder;

namespace {
constexpr char kExponentChar = 'e';
constexpr char kInfinitySymbol[] = "Infinity";
constexpr char kNaNSymbol[] = "NaN";

// The number of digits after the decimal we allow before switching to
// exponential representation.
constexpr int kDecimalInShortestLow = -6;
// The number of digits before the decimal we allow before switching to
// exponential representation.
constexpr int kDecimalInShortestHigh = 12;
constexpr int kConversionFlags =
DoubleToStringConverter::EMIT_POSITIVE_EXPONENT_SIGN;

const DoubleToStringConverter& GetDoubleToStringConverter() {
static DoubleToStringConverter converter(
kConversionFlags, kInfinitySymbol, kNaNSymbol, kExponentChar,
kDecimalInShortestLow, kDecimalInShortestHigh, 0, 0);
return converter;
}

std::string NumberToStringImpl(double number, bool is_single_precision) {
if (number == 0.0) {
return "0";
}

constexpr int kBufferSize = 128;
std::array<char, kBufferSize> char_buffer;
StringBuilder builder(char_buffer.data(), char_buffer.size());
if (is_single_precision) {
GetDoubleToStringConverter().ToShortestSingle(static_cast<float>(number),
&builder);
} else {
GetDoubleToStringConverter().ToShortest(number, &builder);
}
return std::string(char_buffer.data(), builder.position());
}
} // namespace

std::u16string ASCIIToUTF16(std::string src) {
return std::u16string(src.begin(), src.end());
}
Expand Down Expand Up @@ -73,15 +118,11 @@ std::string NumberToString(unsigned int number) {
}

std::string NumberToString(float number) {
// TODO(gw280): Format decimals to the shortest reasonable representation.
// See: https://github.com/flutter/flutter/issues/78460
return std::to_string(number);
return NumberToStringImpl(number, true);
}

std::string NumberToString(double number) {
// TODO(gw280): Format decimals to the shortest reasonable representation.
// See: https://github.com/flutter/flutter/issues/78460
return std::to_string(number);
return NumberToStringImpl(number, false);
}

std::string JoinString(std::vector<std::string> tokens, std::string delimiter) {
Expand Down
2 changes: 1 addition & 1 deletion third_party/accessibility/base/string_utils.h
Original file line number Diff line number Diff line change
Expand Up @@ -29,9 +29,9 @@ std::string UTF16ToUTF8(std::u16string src);
std::u16string WideToUTF16(const std::wstring& src);
std::wstring UTF16ToWide(const std::u16string& src);

std::u16string NumberToString16(float number);
std::u16string NumberToString16(unsigned int number);
std::u16string NumberToString16(int32_t number);
std::u16string NumberToString16(float number);
std::u16string NumberToString16(double number);

std::string NumberToString(unsigned int number);
Expand Down
40 changes: 31 additions & 9 deletions third_party/accessibility/base/string_utils_unittest.cc
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@

#include <cerrno>
#include <cstddef>
#include <string>

#include "base/logging.h"
#include "gtest/gtest.h"
Expand Down Expand Up @@ -42,17 +43,38 @@ TEST(StringUtilsTest, canUTF16ToUTF8) {
}

TEST(StringUtilsTest, canNumberToString16) {
float number = 1.123;
EXPECT_EQ(NumberToString16(number).compare(u"1.123000"), 0);
EXPECT_EQ(NumberToString16(1.123f), std::u16string(u"1.123"));
}

TEST(StringUtilsTest, canNumberToString) {
float f = 1.123;
EXPECT_EQ(NumberToString(f).compare("1.123000"), 0);
unsigned int s = 11;
EXPECT_EQ(NumberToString(s).compare("11"), 0);
int32_t i = -23;
EXPECT_EQ(NumberToString(i).compare("-23"), 0);
TEST(StringUtilsTest, numberToStringSimplifiesOutput) {
EXPECT_STREQ(NumberToString(0.0).c_str(), "0");
EXPECT_STREQ(NumberToString(0.0f).c_str(), "0");
EXPECT_STREQ(NumberToString(1.123).c_str(), "1.123");
EXPECT_STREQ(NumberToString(1.123f).c_str(), "1.123");
EXPECT_STREQ(NumberToString(-1.123).c_str(), "-1.123");
EXPECT_STREQ(NumberToString(-1.123f).c_str(), "-1.123");
EXPECT_STREQ(NumberToString(1.00001).c_str(), "1.00001");
EXPECT_STREQ(NumberToString(1.00001f).c_str(), "1.00001");
EXPECT_STREQ(NumberToString(1000.000001).c_str(), "1000.000001");
EXPECT_STREQ(NumberToString(10.00001f).c_str(), "10.00001");
EXPECT_STREQ(NumberToString(1.0 + 1e-8).c_str(), "1.00000001");
EXPECT_STREQ(NumberToString(1.0f + 1e-8f).c_str(), "1");
EXPECT_STREQ(NumberToString(1e-6).c_str(), "0.000001");
EXPECT_STREQ(NumberToString(1e-6f).c_str(), "0.000001");
EXPECT_STREQ(NumberToString(1e-8).c_str(), "1e-8");
EXPECT_STREQ(NumberToString(1e-8f).c_str(), "1e-8");
EXPECT_STREQ(NumberToString(100.0).c_str(), "100");
EXPECT_STREQ(NumberToString(100.0f).c_str(), "100");
EXPECT_STREQ(NumberToString(-1.0 - 1e-7).c_str(), "-1.0000001");
EXPECT_STREQ(NumberToString(-1.0f - 1e-7f).c_str(), "-1.0000001");
EXPECT_STREQ(NumberToString(0.00000012345678).c_str(), "1.2345678e-7");
// Difference in output is due to differences in double and float precision.
EXPECT_STREQ(NumberToString(0.00000012345678f).c_str(), "1.2345679e-7");
EXPECT_STREQ(NumberToString(-0.00000012345678).c_str(), "-1.2345678e-7");
// Difference in output is due to differences in double and float precision.
EXPECT_STREQ(NumberToString(-0.00000012345678f).c_str(), "-1.2345679e-7");
EXPECT_STREQ(NumberToString(static_cast<unsigned int>(11)).c_str(), "11");
EXPECT_STREQ(NumberToString(static_cast<int32_t>(-23)).c_str(), "-23");
}

} // namespace base