// 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.

#ifndef SKY_ENGINE_WTF_DTOA_DOUBLE_CONVERSION_H_
#define SKY_ENGINE_WTF_DTOA_DOUBLE_CONVERSION_H_

#include "sky/engine/wtf/dtoa/utils.h"

namespace WTF {

namespace double_conversion {

    class DoubleToStringConverter {
    public:
        // When calling ToFixed with a double > 10^kMaxFixedDigitsBeforePoint
        // or a requested_digits parameter > kMaxFixedDigitsAfterPoint then the
        // function returns false.
        static const int kMaxFixedDigitsBeforePoint = 60;
        static const int kMaxFixedDigitsAfterPoint = 60;

        // When calling ToExponential with a requested_digits
        // parameter > kMaxExponentialDigits then the function returns false.
        static const int kMaxExponentialDigits = 120;

        // When calling ToPrecision with a requested_digits
        // parameter < kMinPrecisionDigits or requested_digits > kMaxPrecisionDigits
        // then the function returns false.
        static const int kMinPrecisionDigits = 1;
        static const int kMaxPrecisionDigits = 120;

        enum Flags {
            NO_FLAGS = 0,
            EMIT_POSITIVE_EXPONENT_SIGN = 1,
            EMIT_TRAILING_DECIMAL_POINT = 2,
            EMIT_TRAILING_ZERO_AFTER_POINT = 4,
            UNIQUE_ZERO = 8
        };

        // Flags should be a bit-or combination of the possible Flags-enum.
        //  - NO_FLAGS: no special flags.
        //  - EMIT_POSITIVE_EXPONENT_SIGN: when the number is converted into exponent
        //    form, emits a '+' for positive exponents. Example: 1.2e+2.
        //  - EMIT_TRAILING_DECIMAL_POINT: when the input number is an integer and is
        //    converted into decimal format then a trailing decimal point is appended.
        //    Example: 2345.0 is converted to "2345.".
        //  - EMIT_TRAILING_ZERO_AFTER_POINT: in addition to a trailing decimal point
        //    emits a trailing '0'-character. This flag requires the
        //    EXMIT_TRAILING_DECIMAL_POINT flag.
        //    Example: 2345.0 is converted to "2345.0".
        //  - UNIQUE_ZERO: "-0.0" is converted to "0.0".
        //
        // Infinity symbol and nan_symbol provide the string representation for these
        // special values. If the string is NULL and the special value is encountered
        // then the conversion functions return false.
        //
        // The exponent_character is used in exponential representations. It is
        // usually 'e' or 'E'.
        //
        // When converting to the shortest representation the converter will
        // represent input numbers in decimal format if they are in the interval
        // [10^decimal_in_shortest_low; 10^decimal_in_shortest_high[
        //    (lower boundary included, greater boundary excluded).
        // Example: with decimal_in_shortest_low = -6 and
        //               decimal_in_shortest_high = 21:
        //   ToShortest(0.000001)  -> "0.000001"
        //   ToShortest(0.0000001) -> "1e-7"
        //   ToShortest(111111111111111111111.0)  -> "111111111111111110000"
        //   ToShortest(100000000000000000000.0)  -> "100000000000000000000"
        //   ToShortest(1111111111111111111111.0) -> "1.1111111111111111e+21"
        //
        // When converting to precision mode the converter may add
        // max_leading_padding_zeroes before returning the number in exponential
        // format.
        // Example with max_leading_padding_zeroes_in_precision_mode = 6.
        //   ToPrecision(0.0000012345, 2) -> "0.0000012"
        //   ToPrecision(0.00000012345, 2) -> "1.2e-7"
        // Similarily the converter may add up to
        // max_trailing_padding_zeroes_in_precision_mode in precision mode to avoid
        // returning an exponential representation. A zero added by the
        // EMIT_TRAILING_ZERO_AFTER_POINT flag is counted for this limit.
        // Examples for max_trailing_padding_zeroes_in_precision_mode = 1:
        //   ToPrecision(230.0, 2) -> "230"
        //   ToPrecision(230.0, 2) -> "230."  with EMIT_TRAILING_DECIMAL_POINT.
        //   ToPrecision(230.0, 2) -> "2.3e2" with EMIT_TRAILING_ZERO_AFTER_POINT.
        DoubleToStringConverter(int flags,
                                const char* infinity_symbol,
                                const char* nan_symbol,
                                char exponent_character,
                                int decimal_in_shortest_low,
                                int decimal_in_shortest_high,
                                int max_leading_padding_zeroes_in_precision_mode,
                                int max_trailing_padding_zeroes_in_precision_mode)
        : flags_(flags),
        infinity_symbol_(infinity_symbol),
        nan_symbol_(nan_symbol),
        exponent_character_(exponent_character),
        decimal_in_shortest_low_(decimal_in_shortest_low),
        decimal_in_shortest_high_(decimal_in_shortest_high),
        max_leading_padding_zeroes_in_precision_mode_(
                                                      max_leading_padding_zeroes_in_precision_mode),
        max_trailing_padding_zeroes_in_precision_mode_(
                                                       max_trailing_padding_zeroes_in_precision_mode) {
            // When 'trailing zero after the point' is set, then 'trailing point'
            // must be set too.
            ASSERT(((flags & EMIT_TRAILING_DECIMAL_POINT) != 0) ||
                   !((flags & EMIT_TRAILING_ZERO_AFTER_POINT) != 0));
        }

        // Returns a converter following the EcmaScript specification.
        static const DoubleToStringConverter& EcmaScriptConverter();

        // Computes the shortest string of digits that correctly represent the input
        // number. Depending on decimal_in_shortest_low and decimal_in_shortest_high
        // (see constructor) it then either returns a decimal representation, or an
        // exponential representation.
        // Example with decimal_in_shortest_low = -6,
        //              decimal_in_shortest_high = 21,
        //              EMIT_POSITIVE_EXPONENT_SIGN activated, and
        //              EMIT_TRAILING_DECIMAL_POINT deactived:
        //   ToShortest(0.000001)  -> "0.000001"
        //   ToShortest(0.0000001) -> "1e-7"
        //   ToShortest(111111111111111111111.0)  -> "111111111111111110000"
        //   ToShortest(100000000000000000000.0)  -> "100000000000000000000"
        //   ToShortest(1111111111111111111111.0) -> "1.1111111111111111e+21"
        //
        // Note: the conversion may round the output if the returned string
        // is accurate enough to uniquely identify the input-number.
        // For example the most precise representation of the double 9e59 equals
        // "899999999999999918767229449717619953810131273674690656206848", but
        // the converter will return the shorter (but still correct) "9e59".
        //
        // Returns true if the conversion succeeds. The conversion always succeeds
        // except when the input value is special and no infinity_symbol or
        // nan_symbol has been given to the constructor.
        bool ToShortest(double value, StringBuilder* result_builder) const;


        // Computes a decimal representation with a fixed number of digits after the
        // decimal point. The last emitted digit is rounded.
        //
        // Examples:
        //   ToFixed(3.12, 1) -> "3.1"
        //   ToFixed(3.1415, 3) -> "3.142"
        //   ToFixed(1234.56789, 4) -> "1234.5679"
        //   ToFixed(1.23, 5) -> "1.23000"
        //   ToFixed(0.1, 4) -> "0.1000"
        //   ToFixed(1e30, 2) -> "1000000000000000019884624838656.00"
        //   ToFixed(0.1, 30) -> "0.100000000000000005551115123126"
        //   ToFixed(0.1, 17) -> "0.10000000000000001"
        //
        // If requested_digits equals 0, then the tail of the result depends on
        // the EMIT_TRAILING_DECIMAL_POINT and EMIT_TRAILING_ZERO_AFTER_POINT.
        // Examples, for requested_digits == 0,
        //   let EMIT_TRAILING_DECIMAL_POINT and EMIT_TRAILING_ZERO_AFTER_POINT be
        //    - false and false: then 123.45 -> 123
        //                             0.678 -> 1
        //    - true and false: then 123.45 -> 123.
        //                            0.678 -> 1.
        //    - true and true: then 123.45 -> 123.0
        //                           0.678 -> 1.0
        //
        // Returns true if the conversion succeeds. The conversion always succeeds
        // except for the following cases:
        //   - the input value is special and no infinity_symbol or nan_symbol has
        //     been provided to the constructor,
        //   - 'value' > 10^kMaxFixedDigitsBeforePoint, or
        //   - 'requested_digits' > kMaxFixedDigitsAfterPoint.
        // The last two conditions imply that the result will never contain more than
        // 1 + kMaxFixedDigitsBeforePoint + 1 + kMaxFixedDigitsAfterPoint characters
        // (one additional character for the sign, and one for the decimal point).
        bool ToFixed(double value,
                     int requested_digits,
                     StringBuilder* result_builder) const;

        // Computes a representation in exponential format with requested_digits
        // after the decimal point. The last emitted digit is rounded.
        // If requested_digits equals -1, then the shortest exponential representation
        // is computed.
        //
        // Examples with EMIT_POSITIVE_EXPONENT_SIGN deactivated, and
        //               exponent_character set to 'e'.
        //   ToExponential(3.12, 1) -> "3.1e0"
        //   ToExponential(5.0, 3) -> "5.000e0"
        //   ToExponential(0.001, 2) -> "1.00e-3"
        //   ToExponential(3.1415, -1) -> "3.1415e0"
        //   ToExponential(3.1415, 4) -> "3.1415e0"
        //   ToExponential(3.1415, 3) -> "3.142e0"
        //   ToExponential(123456789000000, 3) -> "1.235e14"
        //   ToExponential(1000000000000000019884624838656.0, -1) -> "1e30"
        //   ToExponential(1000000000000000019884624838656.0, 32) ->
        //                     "1.00000000000000001988462483865600e30"
        //   ToExponential(1234, 0) -> "1e3"
        //
        // Returns true if the conversion succeeds. The conversion always succeeds
        // except for the following cases:
        //   - the input value is special and no infinity_symbol or nan_symbol has
        //     been provided to the constructor,
        //   - 'requested_digits' > kMaxExponentialDigits.
        // The last condition implies that the result will never contain more than
        // kMaxExponentialDigits + 8 characters (the sign, the digit before the
        // decimal point, the decimal point, the exponent character, the
        // exponent's sign, and at most 3 exponent digits).
        bool ToExponential(double value,
                           int requested_digits,
                           StringBuilder* result_builder) const;

        // Computes 'precision' leading digits of the given 'value' and returns them
        // either in exponential or decimal format, depending on
        // max_{leading|trailing}_padding_zeroes_in_precision_mode (given to the
        // constructor).
        // The last computed digit is rounded.
        //
        // Example with max_leading_padding_zeroes_in_precision_mode = 6.
        //   ToPrecision(0.0000012345, 2) -> "0.0000012"
        //   ToPrecision(0.00000012345, 2) -> "1.2e-7"
        // Similarily the converter may add up to
        // max_trailing_padding_zeroes_in_precision_mode in precision mode to avoid
        // returning an exponential representation. A zero added by the
        // EMIT_TRAILING_ZERO_AFTER_POINT flag is counted for this limit.
        // Examples for max_trailing_padding_zeroes_in_precision_mode = 1:
        //   ToPrecision(230.0, 2) -> "230"
        //   ToPrecision(230.0, 2) -> "230."  with EMIT_TRAILING_DECIMAL_POINT.
        //   ToPrecision(230.0, 2) -> "2.3e2" with EMIT_TRAILING_ZERO_AFTER_POINT.
        // Examples for max_trailing_padding_zeroes_in_precision_mode = 3, and no
        //    EMIT_TRAILING_ZERO_AFTER_POINT:
        //   ToPrecision(123450.0, 6) -> "123450"
        //   ToPrecision(123450.0, 5) -> "123450"
        //   ToPrecision(123450.0, 4) -> "123500"
        //   ToPrecision(123450.0, 3) -> "123000"
        //   ToPrecision(123450.0, 2) -> "1.2e5"
        //
        // Returns true if the conversion succeeds. The conversion always succeeds
        // except for the following cases:
        //   - the input value is special and no infinity_symbol or nan_symbol has
        //     been provided to the constructor,
        //   - precision < kMinPericisionDigits
        //   - precision > kMaxPrecisionDigits
        // The last condition implies that the result will never contain more than
        // kMaxPrecisionDigits + 7 characters (the sign, the decimal point, the
        // exponent character, the exponent's sign, and at most 3 exponent digits).
        bool ToPrecision(double value,
                         int precision,
                         StringBuilder* result_builder) const;

        enum DtoaMode {
            // Produce the shortest correct representation.
            // For example the output of 0.299999999999999988897 is (the less accurate
            // but correct) 0.3.
            SHORTEST,
            // Produce a fixed number of digits after the decimal point.
            // For instance fixed(0.1, 4) becomes 0.1000
            // If the input number is big, the output will be big.
            FIXED,
            // Fixed number of digits (independent of the decimal point).
            PRECISION
        };

        // The maximal number of digits that are needed to emit a double in base 10.
        // A higher precision can be achieved by using more digits, but the shortest
        // accurate representation of any double will never use more digits than
        // kBase10MaximalLength.
        // Note that DoubleToAscii null-terminates its input. So the given buffer
        // should be at least kBase10MaximalLength + 1 characters long.
        static const int kBase10MaximalLength = 17;

        // Converts the given double 'v' to ascii.
        // The result should be interpreted as buffer * 10^(point-length).
        //
        // The output depends on the given mode:
        //  - SHORTEST: produce the least amount of digits for which the internal
        //   identity requirement is still satisfied. If the digits are printed
        //   (together with the correct exponent) then reading this number will give
        //   'v' again. The buffer will choose the representation that is closest to
        //   'v'. If there are two at the same distance, than the one farther away
        //   from 0 is chosen (halfway cases - ending with 5 - are rounded up).
        //   In this mode the 'requested_digits' parameter is ignored.
        //  - FIXED: produces digits necessary to print a given number with
        //   'requested_digits' digits after the decimal point. The produced digits
        //   might be too short in which case the caller has to fill the remainder
        //   with '0's.
        //   Example: toFixed(0.001, 5) is allowed to return buffer="1", point=-2.
        //   Halfway cases are rounded towards +/-Infinity (away from 0). The call
        //   toFixed(0.15, 2) thus returns buffer="2", point=0.
        //   The returned buffer may contain digits that would be truncated from the
        //   shortest representation of the input.
        //  - PRECISION: produces 'requested_digits' where the first digit is not '0'.
        //   Even though the length of produced digits usually equals
        //   'requested_digits', the function is allowed to return fewer digits, in
        //   which case the caller has to fill the missing digits with '0's.
        //   Halfway cases are again rounded away from 0.
        // DoubleToAscii expects the given buffer to be big enough to hold all
        // digits and a terminating null-character. In SHORTEST-mode it expects a
        // buffer of at least kBase10MaximalLength + 1. In all other modes the
        // requested_digits parameter (+ 1 for the null-character) limits the size of
        // the output. The given length is only used in debug mode to ensure the
        // buffer is big enough.
        static void DoubleToAscii(double v,
                                  DtoaMode mode,
                                  int requested_digits,
                                  char* buffer,
                                  int buffer_length,
                                  bool* sign,
                                  int* length,
                                  int* point);

    private:
        // If the value is a special value (NaN or Infinity) constructs the
        // corresponding string using the configured infinity/nan-symbol.
        // If either of them is NULL or the value is not special then the
        // function returns false.
        bool HandleSpecialValues(double value, StringBuilder* result_builder) const;
        // Constructs an exponential representation (i.e. 1.234e56).
        // The given exponent assumes a decimal point after the first decimal digit.
        void CreateExponentialRepresentation(const char* decimal_digits,
                                             int length,
                                             int exponent,
                                             StringBuilder* result_builder) const;
        // Creates a decimal representation (i.e 1234.5678).
        void CreateDecimalRepresentation(const char* decimal_digits,
                                         int length,
                                         int decimal_point,
                                         int digits_after_point,
                                         StringBuilder* result_builder) const;

        const int flags_;
        const char* const infinity_symbol_;
        const char* const nan_symbol_;
        const char exponent_character_;
        const int decimal_in_shortest_low_;
        const int decimal_in_shortest_high_;
        const int max_leading_padding_zeroes_in_precision_mode_;
        const int max_trailing_padding_zeroes_in_precision_mode_;

        DISALLOW_IMPLICIT_CONSTRUCTORS(DoubleToStringConverter);
    };


    class StringToDoubleConverter {
    public:
        // Performs the conversion.
        // The output parameter 'processed_characters_count' is set to the number
        // of characters that have been processed to read the number.
        static double StringToDouble(const char* buffer, size_t length, size_t* processed_characters_count);

    private:
        DISALLOW_IMPLICIT_CONSTRUCTORS(StringToDoubleConverter);
    };

}  // namespace double_conversion

} // namespace WTF

#endif  // SKY_ENGINE_WTF_DTOA_DOUBLE_CONVERSION_H_
