// 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 DOUBLE_CONVERSION_DOUBLE_CONVERSION_H_
#define DOUBLE_CONVERSION_DOUBLE_CONVERSION_H_

#include <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.
        WTF_EXPORT_PRIVATE 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).
        WTF_EXPORT_PRIVATE 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.
        WTF_EXPORT_PRIVATE 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  // DOUBLE_CONVERSION_DOUBLE_CONVERSION_H_
