Index: runtime/vm/double_conversion.cc |
diff --git a/runtime/vm/double_conversion.cc b/runtime/vm/double_conversion.cc |
index 41cec22002d9df43d1da768f9391c86c30901a9e..6d1d3c7270b608832c1ef2bc5ec0d8f82854ccfa 100644 |
--- a/runtime/vm/double_conversion.cc |
+++ b/runtime/vm/double_conversion.cc |
@@ -16,24 +16,25 @@ static const char kDoubleToStringCommonExponentChar = 'e'; |
static const char* kDoubleToStringCommonInfinitySymbol = "Infinity"; |
static const char* kDoubleToStringCommonNaNSymbol = "NaN"; |
-bool DoubleToString(double d, String& result) { |
+void DoubleToCString(double d, char* buffer, int buffer_size) { |
static const int kDecimalLow = -6; |
static const int kDecimalHigh = 21; |
- static const int kConversionFlags = |
- double_conversion::DoubleToStringConverter::EMIT_POSITIVE_EXPONENT_SIGN | |
- double_conversion::DoubleToStringConverter::EMIT_TRAILING_DECIMAL_POINT | |
- double_conversion::DoubleToStringConverter::EMIT_TRAILING_ZERO_AFTER_POINT; |
- const int kBufferSize = 128; |
+ |
// The output contains the sign, at most kDecimalHigh - 1 digits, |
// the decimal point followed by a 0 plus the \0. |
- ASSERT(kBufferSize >= 1 + (kDecimalHigh - 1) + 1 + 1 + 1); |
+ ASSERT(buffer_size >= 1 + (kDecimalHigh - 1) + 1 + 1 + 1); |
// Or it contains the sign, a 0, the decimal point, kDecimalLow '0's, |
// 17 digits (the precision needed for doubles), plus the \0. |
- ASSERT(kBufferSize >= 1 + 1 + 1 + kDecimalLow + 17 + 1); |
+ ASSERT(buffer_size >= 1 + 1 + 1 + kDecimalLow + 17 + 1); |
// Alternatively it contains a sign, at most 17 digits (precision needed for |
// any double), the decimal point, the exponent character, the exponent's |
// sign, at most three exponent digits, plus the \0. |
- ASSERT(kBufferSize >= 1 + 17 + 1 + 1 + 1 + 3 + 1); |
+ ASSERT(buffer_size >= 1 + 17 + 1 + 1 + 1 + 3 + 1); |
+ |
+ static const int kConversionFlags = |
+ double_conversion::DoubleToStringConverter::EMIT_POSITIVE_EXPONENT_SIGN | |
+ double_conversion::DoubleToStringConverter::EMIT_TRAILING_DECIMAL_POINT | |
+ double_conversion::DoubleToStringConverter::EMIT_TRAILING_ZERO_AFTER_POINT; |
const double_conversion::DoubleToStringConverter converter( |
kConversionFlags, |
@@ -44,11 +45,14 @@ bool DoubleToString(double d, String& result) { |
kDecimalHigh, |
0, 0); // Last two values are ignored in shortest mode. |
- UNIMPLEMENTED(); |
- return false; |
+ double_conversion::StringBuilder builder(buffer, buffer_size); |
+ bool status = converter.ToShortest(d, &builder); |
+ ASSERT(status); |
+ char* result = builder.Finalize(); |
+ ASSERT(result == buffer); |
} |
-bool DoubleToStringAsFixed(double d, int fraction_digits, String& result) { |
+RawString* DoubleToStringAsFixed(double d, int fraction_digits) { |
static const int kMinFractionDigits = 0; |
static const int kMaxFractionDigits = 20; |
static const int kMaxDigitsBeforePoint = 20; |
@@ -57,19 +61,23 @@ bool DoubleToStringAsFixed(double d, int fraction_digits, String& result) { |
static const double kUpperBoundary = 1e21; |
// TODO(floitsch): remove the UNIQUE_ZERO flag when the test is updated. |
static const int kConversionFlags = |
- double_conversion::DoubleToStringConverter::UNIQUE_ZERO; |
+ double_conversion::DoubleToStringConverter::NO_FLAGS; |
const int kBufferSize = 128; |
+ |
+ USE(kMaxDigitsBeforePoint); |
+ USE(kMaxFractionDigits); |
+ USE(kLowerBoundary); |
+ USE(kUpperBoundary); |
+ USE(kMinFractionDigits); |
+ USE(kMaxFractionDigits); |
// The output contains the sign, at most kMaxDigitsBeforePoint digits, |
// the decimal point followed by at most fraction_digits digits plus the \0. |
ASSERT(kBufferSize >= 1 + kMaxDigitsBeforePoint + 1 + kMaxFractionDigits + 1); |
- if (d <= kLowerBoundary || d >= kUpperBoundary) { |
- return false; |
- } |
- if (fraction_digits < kMinFractionDigits || |
- fraction_digits > kMaxFractionDigits) { |
- return false; |
- } |
+ ASSERT(kLowerBoundary < d && d < kUpperBoundary); |
+ |
+ ASSERT(kMinFractionDigits <= fraction_digits && |
+ fraction_digits <= kMaxFractionDigits); |
const double_conversion::DoubleToStringConverter converter( |
kConversionFlags, |
@@ -78,33 +86,33 @@ bool DoubleToStringAsFixed(double d, int fraction_digits, String& result) { |
kDoubleToStringCommonExponentChar, |
0, 0, 0, 0); // Last four values are ignored in fixed mode. |
- char buffer[kBufferSize]; |
+ char* buffer = reinterpret_cast<char*>( |
+ Isolate::Current()->current_zone()->Allocate(kBufferSize)); |
+ buffer[kBufferSize - 1] = '\0'; |
double_conversion::StringBuilder builder(buffer, kBufferSize); |
bool status = converter.ToFixed(d, fraction_digits, &builder); |
- if (!status) return false; |
+ ASSERT(status); |
int length = builder.position(); |
- result ^= String::New(reinterpret_cast<uint8_t*>(builder.Finalize()), length); |
- return true; |
+ return String::New(reinterpret_cast<uint8_t*>(builder.Finalize()), length); |
} |
-bool DoubleToStringAsExponential(double d, |
- int fraction_digits, |
- String& result) { |
- static const int kMinFractionDigits = 0; |
+RawString* DoubleToStringAsExponential(double d, int fraction_digits) { |
+ static const int kMinFractionDigits = -1; // -1 represents shortest mode. |
static const int kMaxFractionDigits = 20; |
static const int kConversionFlags = |
double_conversion::DoubleToStringConverter::EMIT_POSITIVE_EXPONENT_SIGN; |
const int kBufferSize = 128; |
+ |
+ USE(kMinFractionDigits); |
+ USE(kMaxFractionDigits); |
// The output contains the sign, at most 1 digits, the decimal point followed |
// by at most kMaxFractionDigits digits, the exponent-character, the |
// exponent-sign and three exponent digits plus \0. |
ASSERT(kBufferSize >= 1 + 1 + kMaxFractionDigits + 1 + 1 + 3 + 1); |
- if (!(kMinFractionDigits <= fraction_digits && |
- fraction_digits <= kMaxFractionDigits)) { |
- return false; |
- } |
+ ASSERT(kMinFractionDigits <= fraction_digits && |
+ fraction_digits <= kMaxFractionDigits); |
const double_conversion::DoubleToStringConverter converter( |
kConversionFlags, |
@@ -113,12 +121,18 @@ bool DoubleToStringAsExponential(double d, |
kDoubleToStringCommonExponentChar, |
0, 0, 0, 0); // Last four values are ignored in exponential mode. |
- UNIMPLEMENTED(); |
- return false; |
+ char* buffer = reinterpret_cast<char*>( |
+ Isolate::Current()->current_zone()->Allocate(kBufferSize)); |
+ buffer[kBufferSize - 1] = '\0'; |
+ double_conversion::StringBuilder builder(buffer, kBufferSize); |
+ bool status = converter.ToExponential(d, fraction_digits, &builder); |
+ ASSERT(status); |
+ int length = builder.position(); |
+ return String::New(reinterpret_cast<uint8_t*>(builder.Finalize()), length); |
} |
-bool DoubleToStringAsPrecision(double d, int precision, String& result) { |
+RawString* DoubleToStringAsPrecision(double d, int precision) { |
static const int kMinPrecisionDigits = 1; |
static const int kMaxPrecisionDigits = 21; |
static const int kMaxLeadingPaddingZeroes = 6; |
@@ -126,14 +140,18 @@ bool DoubleToStringAsPrecision(double d, int precision, String& result) { |
static const int kConversionFlags = |
double_conversion::DoubleToStringConverter::EMIT_POSITIVE_EXPONENT_SIGN; |
const int kBufferSize = 128; |
- // The output contains the sign, the decimal point, precision digits, |
+ |
+ USE(kMinPrecisionDigits); |
+ USE(kMaxPrecisionDigits); |
+ // The output contains the sign, a potential leading 0, the decimal point, |
+ // at most kMax{Leading|Trailing} padding zeroes, precision digits, |
// the exponent-character, the exponent-sign, three exponent digits |
// plus the \0. |
- ASSERT(kBufferSize >= 1 + 1 + kMaxPrecisionDigits + 1 + 1 + 3 + 1); |
+ // Note that padding and exponent are exclusive. We still add them up. |
+ ASSERT(kBufferSize >= 1 + 1 + 1 + kMaxLeadingPaddingZeroes + |
+ kMaxTrailingPaddingZeroes + kMaxPrecisionDigits + 1 + 1 + 3 + 1); |
- if (!(kMinPrecisionDigits <= precision && precision <= kMaxPrecisionDigits)) { |
- return false; |
- } |
+ ASSERT(kMinPrecisionDigits <= precision && precision <= kMaxPrecisionDigits); |
const double_conversion::DoubleToStringConverter converter( |
kConversionFlags, |
@@ -144,8 +162,14 @@ bool DoubleToStringAsPrecision(double d, int precision, String& result) { |
kMaxLeadingPaddingZeroes, |
kMaxTrailingPaddingZeroes); |
- UNIMPLEMENTED(); |
- return false; |
+ char* buffer = reinterpret_cast<char*>( |
+ Isolate::Current()->current_zone()->Allocate(kBufferSize)); |
+ buffer[kBufferSize - 1] = '\0'; |
+ double_conversion::StringBuilder builder(buffer, kBufferSize); |
+ bool status = converter.ToPrecision(d, precision, &builder); |
+ ASSERT(status); |
+ int length = builder.position(); |
+ return String::New(reinterpret_cast<uint8_t*>(builder.Finalize()), length); |
} |
} // namespace dart |