// Copyright 2010 the V8 project authors. All rights reserved.
// Redistribution and use in source and binary forms, with or without
// modification, are permitted provided that the following conditions are
// met:
//
//     * Redistributions of source code must retain the above copyright
//       notice, this list of conditions and the following disclaimer.
//     * Redistributions in binary form must reproduce the above
//       copyright notice, this list of conditions and the following
//       disclaimer in the documentation and/or other materials provided
//       with the distribution.
//     * Neither the name of Google Inc. nor the names of its
//       contributors may be used to endorse or promote products derived
//       from this software without specific prior written permission.
//
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.

#include "config.h"

#include <limits.h>
#include <math.h>

#include "double-conversion.h"

#include "bignum-dtoa.h"
#include "double.h"
#include "fast-dtoa.h"
#include "fixed-dtoa.h"
#include "strtod.h"
#include "utils.h"

namespace WTF {

namespace double_conversion {

    const DoubleToStringConverter& DoubleToStringConverter::EcmaScriptConverter() {
        int flags = UNIQUE_ZERO | EMIT_POSITIVE_EXPONENT_SIGN;
        static DoubleToStringConverter converter(flags,
                                                 "Infinity",
                                                 "NaN",
                                                 'e',
                                                 -6, 21,
                                                 6, 0);
        return converter;
    }


    bool DoubleToStringConverter::HandleSpecialValues(
                                                      double value,
                                                      StringBuilder* result_builder) const {
        Double double_inspect(value);
        if (double_inspect.IsInfinite()) {
            if (infinity_symbol_ == NULL) return false;
            if (value < 0) {
                result_builder->AddCharacter('-');
            }
            result_builder->AddString(infinity_symbol_);
            return true;
        }
        if (double_inspect.IsNan()) {
            if (nan_symbol_ == NULL) return false;
            result_builder->AddString(nan_symbol_);
            return true;
        }
        return false;
    }


    void DoubleToStringConverter::CreateExponentialRepresentation(
                                                                  const char* decimal_digits,
                                                                  int length,
                                                                  int exponent,
                                                                  StringBuilder* result_builder) const {
        ASSERT(length != 0);
        result_builder->AddCharacter(decimal_digits[0]);
        if (length != 1) {
            result_builder->AddCharacter('.');
            result_builder->AddSubstring(&decimal_digits[1], length-1);
        }
        result_builder->AddCharacter(exponent_character_);
        if (exponent < 0) {
            result_builder->AddCharacter('-');
            exponent = -exponent;
        } else {
            if ((flags_ & EMIT_POSITIVE_EXPONENT_SIGN) != 0) {
                result_builder->AddCharacter('+');
            }
        }
        if (exponent == 0) {
            result_builder->AddCharacter('0');
            return;
        }
        ASSERT(exponent < 1e4);
        const int kMaxExponentLength = 5;
        char buffer[kMaxExponentLength + 1];
        int first_char_pos = kMaxExponentLength;
        buffer[first_char_pos] = '\0';
        while (exponent > 0) {
            buffer[--first_char_pos] = '0' + (exponent % 10);
            exponent /= 10;
        }
        result_builder->AddSubstring(&buffer[first_char_pos],
                                     kMaxExponentLength - first_char_pos);
    }


    void DoubleToStringConverter::CreateDecimalRepresentation(
                                                              const char* decimal_digits,
                                                              int length,
                                                              int decimal_point,
                                                              int digits_after_point,
                                                              StringBuilder* result_builder) const {
        // Create a representation that is padded with zeros if needed.
        if (decimal_point <= 0) {
            // "0.00000decimal_rep".
            result_builder->AddCharacter('0');
            if (digits_after_point > 0) {
                result_builder->AddCharacter('.');
                result_builder->AddPadding('0', -decimal_point);
                ASSERT(length <= digits_after_point - (-decimal_point));
                result_builder->AddSubstring(decimal_digits, length);
                int remaining_digits = digits_after_point - (-decimal_point) - length;
                result_builder->AddPadding('0', remaining_digits);
            }
        } else if (decimal_point >= length) {
            // "decimal_rep0000.00000" or "decimal_rep.0000"
            result_builder->AddSubstring(decimal_digits, length);
            result_builder->AddPadding('0', decimal_point - length);
            if (digits_after_point > 0) {
                result_builder->AddCharacter('.');
                result_builder->AddPadding('0', digits_after_point);
            }
        } else {
            // "decima.l_rep000"
            ASSERT(digits_after_point > 0);
            result_builder->AddSubstring(decimal_digits, decimal_point);
            result_builder->AddCharacter('.');
            ASSERT(length - decimal_point <= digits_after_point);
            result_builder->AddSubstring(&decimal_digits[decimal_point],
                                         length - decimal_point);
            int remaining_digits = digits_after_point - (length - decimal_point);
            result_builder->AddPadding('0', remaining_digits);
        }
        if (digits_after_point == 0) {
            if ((flags_ & EMIT_TRAILING_DECIMAL_POINT) != 0) {
                result_builder->AddCharacter('.');
            }
            if ((flags_ & EMIT_TRAILING_ZERO_AFTER_POINT) != 0) {
                result_builder->AddCharacter('0');
            }
        }
    }


    bool DoubleToStringConverter::ToShortest(double value,
                                             StringBuilder* result_builder) const {
        if (Double(value).IsSpecial()) {
            return HandleSpecialValues(value, result_builder);
        }

        int decimal_point;
        bool sign;
        const int kDecimalRepCapacity = kBase10MaximalLength + 1;
        char decimal_rep[kDecimalRepCapacity];
        int decimal_rep_length;

        DoubleToAscii(value, SHORTEST, 0, decimal_rep, kDecimalRepCapacity,
                      &sign, &decimal_rep_length, &decimal_point);

        bool unique_zero = (flags_ & UNIQUE_ZERO) != 0;
        if (sign && (value != 0.0 || !unique_zero)) {
            result_builder->AddCharacter('-');
        }

        int exponent = decimal_point - 1;
        if ((decimal_in_shortest_low_ <= exponent) &&
            (exponent < decimal_in_shortest_high_)) {
            CreateDecimalRepresentation(decimal_rep, decimal_rep_length,
                                        decimal_point,
                                        Max(0, decimal_rep_length - decimal_point),
                                        result_builder);
        } else {
            CreateExponentialRepresentation(decimal_rep, decimal_rep_length, exponent,
                                            result_builder);
        }
        return true;
    }


    bool DoubleToStringConverter::ToFixed(double value,
                                          int requested_digits,
                                          StringBuilder* result_builder) const {
        ASSERT(kMaxFixedDigitsBeforePoint == 60);
        const double kFirstNonFixed = 1e60;

        if (Double(value).IsSpecial()) {
            return HandleSpecialValues(value, result_builder);
        }

        if (requested_digits > kMaxFixedDigitsAfterPoint) return false;
        if (value >= kFirstNonFixed || value <= -kFirstNonFixed) return false;

        // Find a sufficiently precise decimal representation of n.
        int decimal_point;
        bool sign;
        // Add space for the '\0' byte.
        const int kDecimalRepCapacity =
        kMaxFixedDigitsBeforePoint + kMaxFixedDigitsAfterPoint + 1;
        char decimal_rep[kDecimalRepCapacity];
        int decimal_rep_length;
        DoubleToAscii(value, FIXED, requested_digits,
                      decimal_rep, kDecimalRepCapacity,
                      &sign, &decimal_rep_length, &decimal_point);

        bool unique_zero = ((flags_ & UNIQUE_ZERO) != 0);
        if (sign && (value != 0.0 || !unique_zero)) {
            result_builder->AddCharacter('-');
        }

        CreateDecimalRepresentation(decimal_rep, decimal_rep_length, decimal_point,
                                    requested_digits, result_builder);
        return true;
    }


    bool DoubleToStringConverter::ToExponential(
                                                double value,
                                                int requested_digits,
                                                StringBuilder* result_builder) const {
        if (Double(value).IsSpecial()) {
            return HandleSpecialValues(value, result_builder);
        }

        if (requested_digits < -1) return false;
        if (requested_digits > kMaxExponentialDigits) return false;

        int decimal_point;
        bool sign;
        // Add space for digit before the decimal point and the '\0' character.
        const int kDecimalRepCapacity = kMaxExponentialDigits + 2;
        ASSERT(kDecimalRepCapacity > kBase10MaximalLength);
        char decimal_rep[kDecimalRepCapacity];
        int decimal_rep_length;

        if (requested_digits == -1) {
            DoubleToAscii(value, SHORTEST, 0,
                          decimal_rep, kDecimalRepCapacity,
                          &sign, &decimal_rep_length, &decimal_point);
        } else {
            DoubleToAscii(value, PRECISION, requested_digits + 1,
                          decimal_rep, kDecimalRepCapacity,
                          &sign, &decimal_rep_length, &decimal_point);
            ASSERT(decimal_rep_length <= requested_digits + 1);

            for (int i = decimal_rep_length; i < requested_digits + 1; ++i) {
                decimal_rep[i] = '0';
            }
            decimal_rep_length = requested_digits + 1;
        }

        bool unique_zero = ((flags_ & UNIQUE_ZERO) != 0);
        if (sign && (value != 0.0 || !unique_zero)) {
            result_builder->AddCharacter('-');
        }

        int exponent = decimal_point - 1;
        CreateExponentialRepresentation(decimal_rep,
                                        decimal_rep_length,
                                        exponent,
                                        result_builder);
        return true;
    }


    bool DoubleToStringConverter::ToPrecision(double value,
                                              int precision,
                                              StringBuilder* result_builder) const {
        if (Double(value).IsSpecial()) {
            return HandleSpecialValues(value, result_builder);
        }

        if (precision < kMinPrecisionDigits || precision > kMaxPrecisionDigits) {
            return false;
        }

        // Find a sufficiently precise decimal representation of n.
        int decimal_point;
        bool sign;
        // Add one for the terminating null character.
        const int kDecimalRepCapacity = kMaxPrecisionDigits + 1;
        char decimal_rep[kDecimalRepCapacity];
        int decimal_rep_length;

        DoubleToAscii(value, PRECISION, precision,
                      decimal_rep, kDecimalRepCapacity,
                      &sign, &decimal_rep_length, &decimal_point);
        ASSERT(decimal_rep_length <= precision);

        bool unique_zero = ((flags_ & UNIQUE_ZERO) != 0);
        if (sign && (value != 0.0 || !unique_zero)) {
            result_builder->AddCharacter('-');
        }

        // The exponent if we print the number as x.xxeyyy. That is with the
        // decimal point after the first digit.
        int exponent = decimal_point - 1;

        int extra_zero = ((flags_ & EMIT_TRAILING_ZERO_AFTER_POINT) != 0) ? 1 : 0;
        if ((-decimal_point + 1 > max_leading_padding_zeroes_in_precision_mode_) ||
            (decimal_point - precision + extra_zero >
             max_trailing_padding_zeroes_in_precision_mode_)) {
                // Fill buffer to contain 'precision' digits.
                // Usually the buffer is already at the correct length, but 'DoubleToAscii'
                // is allowed to return less characters.
                for (int i = decimal_rep_length; i < precision; ++i) {
                    decimal_rep[i] = '0';
                }

                CreateExponentialRepresentation(decimal_rep,
                                                precision,
                                                exponent,
                                                result_builder);
            } else {
                CreateDecimalRepresentation(decimal_rep, decimal_rep_length, decimal_point,
                                            Max(0, precision - decimal_point),
                                            result_builder);
            }
        return true;
    }


    static BignumDtoaMode DtoaToBignumDtoaMode(
                                               DoubleToStringConverter::DtoaMode dtoa_mode) {
        switch (dtoa_mode) {
            case DoubleToStringConverter::SHORTEST:  return BIGNUM_DTOA_SHORTEST;
            case DoubleToStringConverter::FIXED:     return BIGNUM_DTOA_FIXED;
            case DoubleToStringConverter::PRECISION: return BIGNUM_DTOA_PRECISION;
            default:
                UNREACHABLE();
                return BIGNUM_DTOA_SHORTEST;  // To silence compiler.
        }
    }


    void DoubleToStringConverter::DoubleToAscii(double v,
                                                DtoaMode mode,
                                                int requested_digits,
                                                char* buffer,
                                                int buffer_length,
                                                bool* sign,
                                                int* length,
                                                int* point) {
        Vector<char> vector(buffer, buffer_length);
        ASSERT(!Double(v).IsSpecial());
        ASSERT(mode == SHORTEST || requested_digits >= 0);

        if (Double(v).Sign() < 0) {
            *sign = true;
            v = -v;
        } else {
            *sign = false;
        }

        if (mode == PRECISION && requested_digits == 0) {
            vector[0] = '\0';
            *length = 0;
            return;
        }

        if (v == 0) {
            vector[0] = '0';
            vector[1] = '\0';
            *length = 1;
            *point = 1;
            return;
        }

        bool fast_worked;
        switch (mode) {
            case SHORTEST:
                fast_worked = FastDtoa(v, FAST_DTOA_SHORTEST, 0, vector, length, point);
                break;
            case FIXED:
                fast_worked = FastFixedDtoa(v, requested_digits, vector, length, point);
                break;
            case PRECISION:
                fast_worked = FastDtoa(v, FAST_DTOA_PRECISION, requested_digits,
                                       vector, length, point);
                break;
            default:
                UNREACHABLE();
                fast_worked = false;
        }
        if (fast_worked) return;

        // If the fast dtoa didn't succeed use the slower bignum version.
        BignumDtoaMode bignum_mode = DtoaToBignumDtoaMode(mode);
        BignumDtoa(v, bignum_mode, requested_digits, vector, length, point);
        vector[*length] = '\0';
    }


    // Maximum number of significant digits in decimal representation.
    // The longest possible double in decimal representation is
    // (2^53 - 1) * 2 ^ -1074 that is (2 ^ 53 - 1) * 5 ^ 1074 / 10 ^ 1074
    // (768 digits). If we parse a number whose first digits are equal to a
    // mean of 2 adjacent doubles (that could have up to 769 digits) the result
    // must be rounded to the bigger one unless the tail consists of zeros, so
    // we don't need to preserve all the digits.
    const int kMaxSignificantDigits = 772;


    static double SignedZero(bool sign) {
        return sign ? -0.0 : 0.0;
    }


    double StringToDoubleConverter::StringToDouble(
                                                   const char* input,
                                                   size_t length,
                                                   size_t* processed_characters_count) {
        const char* current = input;
        const char* end = input + length;

        *processed_characters_count = 0;

        // To make sure that iterator dereferencing is valid the following
        // convention is used:
        // 1. Each '++current' statement is followed by check for equality to 'end'.
        // 3. If 'current' becomes equal to 'end' the function returns or goes to
        // 'parsing_done'.
        // 4. 'current' is not dereferenced after the 'parsing_done' label.
        // 5. Code before 'parsing_done' may rely on 'current != end'.
        if (current == end) return 0.0;

        // The longest form of simplified number is: "-<significant digits>.1eXXX\0".
        const int kBufferSize = kMaxSignificantDigits + 10;
        char buffer[kBufferSize];  // NOLINT: size is known at compile time.
        int buffer_pos = 0;

        // Exponent will be adjusted if insignificant digits of the integer part
        // or insignificant leading zeros of the fractional part are dropped.
        int exponent = 0;
        int significant_digits = 0;
        int insignificant_digits = 0;
        bool nonzero_digit_dropped = false;
        bool sign = false;

        if (*current == '+' || *current == '-') {
            sign = (*current == '-');
            ++current;
            if (current == end) return 0.0;
        }

        bool leading_zero = false;
        if (*current == '0') {
            ++current;
            if (current == end) {
                *processed_characters_count = current - input;
                return SignedZero(sign);
            }

            leading_zero = true;

            // Ignore leading zeros in the integer part.
            while (*current == '0') {
                ++current;
                if (current == end) {
                    *processed_characters_count = current - input;
                    return SignedZero(sign);
                }
            }
        }

        // Copy significant digits of the integer part (if any) to the buffer.
        while (*current >= '0' && *current <= '9') {
            if (significant_digits < kMaxSignificantDigits) {
                ASSERT(buffer_pos < kBufferSize);
                buffer[buffer_pos++] = static_cast<char>(*current);
                significant_digits++;
            } else {
                insignificant_digits++;  // Move the digit into the exponential part.
                nonzero_digit_dropped = nonzero_digit_dropped || *current != '0';
            }
            ++current;
            if (current == end) goto parsing_done;
        }

        if (*current == '.') {
            ++current;
            if (current == end) {
                if (significant_digits == 0 && !leading_zero) {
                    return 0.0;
                } else {
                    goto parsing_done;
                }
            }

            if (significant_digits == 0) {
                // Integer part consists of 0 or is absent. Significant digits start after
                // leading zeros (if any).
                while (*current == '0') {
                    ++current;
                    if (current == end) {
                        *processed_characters_count = current - input;
                        return SignedZero(sign);
                    }
                    exponent--;  // Move this 0 into the exponent.
                }
            }

            // There is a fractional part.
            while (*current >= '0' && *current <= '9') {
                if (significant_digits < kMaxSignificantDigits) {
                    ASSERT(buffer_pos < kBufferSize);
                    buffer[buffer_pos++] = static_cast<char>(*current);
                    significant_digits++;
                    exponent--;
                } else {
                    // Ignore insignificant digits in the fractional part.
                    nonzero_digit_dropped = nonzero_digit_dropped || *current != '0';
                }
                ++current;
                if (current == end) goto parsing_done;
            }
        }

        if (!leading_zero && exponent == 0 && significant_digits == 0) {
            // If leading_zeros is true then the string contains zeros.
            // If exponent < 0 then string was [+-]\.0*...
            // If significant_digits != 0 the string is not equal to 0.
            // Otherwise there are no digits in the string.
            return 0.0;
        }

        // Parse exponential part.
        if (*current == 'e' || *current == 'E') {
            ++current;
            if (current == end) {
                --current;
                goto parsing_done;
            }
            char sign = 0;
            if (*current == '+' || *current == '-') {
                sign = static_cast<char>(*current);
                ++current;
                if (current == end) {
                    current -= 2;
                    goto parsing_done;
                }
            }

            if (*current < '0' || *current > '9') {
                if (sign)
                    --current;
                --current;
                goto parsing_done;
            }

            const int max_exponent = INT_MAX / 2;
            ASSERT(-max_exponent / 2 <= exponent && exponent <= max_exponent / 2);
            int num = 0;
            do {
                // Check overflow.
                int digit = *current - '0';
                if (num >= max_exponent / 10
                    && !(num == max_exponent / 10 && digit <= max_exponent % 10)) {
                    num = max_exponent;
                } else {
                    num = num * 10 + digit;
                }
                ++current;
            } while (current != end && *current >= '0' && *current <= '9');

            exponent += (sign == '-' ? -num : num);
        }

    parsing_done:
        exponent += insignificant_digits;

        if (nonzero_digit_dropped) {
            buffer[buffer_pos++] = '1';
            exponent--;
        }

        ASSERT(buffer_pos < kBufferSize);
        buffer[buffer_pos] = '\0';

        double converted = Strtod(Vector<const char>(buffer, buffer_pos), exponent);
        *processed_characters_count = current - input;
        return sign? -converted: converted;
    }

}  // namespace double_conversion

} // namespace WTF
