// 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 "sky/engine/config.h"

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

#include "double-conversion.h"

#include "bignum-dtoa.h"
#include "sky/engine/wtf/dtoa/double.h"
#include "fast-dtoa.h"
#include "fixed-dtoa.h"
#include "sky/engine/wtf/dtoa/strtod.h"
#include "sky/engine/wtf/dtoa/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
