/*
 * Copyright 2017 Google Inc.
 *
 * Use of this source code is governed by a BSD-style license that can be
 * found in the LICENSE file.
 */

#include "SkFloatToDecimal.h"

#include <cfloat>
#include <climits>
#include <cmath>

#include "SkTypes.h"

// returns `value * pow(base, e)`, assuming `e` is positive.
static double pow_by_squaring(double value, double base, int e) {
    // https://en.wikipedia.org/wiki/Exponentiation_by_squaring
    SkASSERT(e > 0);
    while (true) {
        if (e & 1) {
            value *= base;
        }
        e >>= 1;
        if (0 == e) {
            return value;
        }
        base *= base;
    }
}

// Return pow(10.0, e), optimized for common cases.
static double pow10(int e) {
    switch (e) {
        case 0:  return 1.0;  // common cases
        case 1:  return 10.0;
        case 2:  return 100.0;
        case 3:  return 1e+03;
        case 4:  return 1e+04;
        case 5:  return 1e+05;
        case 6:  return 1e+06;
        case 7:  return 1e+07;
        case 8:  return 1e+08;
        case 9:  return 1e+09;
        case 10: return 1e+10;
        case 11: return 1e+11;
        case 12: return 1e+12;
        case 13: return 1e+13;
        case 14: return 1e+14;
        case 15: return 1e+15;
        default:
            if (e > 15) {
                return pow_by_squaring(1e+15, 10.0, e - 15);
            } else {
                SkASSERT(e < 0);
                return pow_by_squaring(1.0, 0.1, -e);
            }
    }
}

/** Write a string into result, includeing a terminating '\0' (for
    unit testing).  Return strlen(result) (for SkWStream::write) The
    resulting string will be in the form /[-]?([0-9]*.)?[0-9]+/ and
    sscanf(result, "%f", &x) will return the original value iff the
    value is finite. This function accepts all possible input values.

    Motivation: "PDF does not support [numbers] in exponential format
    (such as 6.02e23)."  Otherwise, this function would rely on a
    sprintf-type function from the standard library. */
unsigned SkFloatToDecimal(float value, char result[kMaximumSkFloatToDecimalLength]) {
    /* The longest result is -FLT_MIN.
       We serialize it as "-.0000000000000000000000000000000000000117549435"
       which has 48 characters plus a terminating '\0'. */

    static_assert(kMaximumSkFloatToDecimalLength == 49, "");
    // 3 = '-', '.', and '\0' characters.
    // 9 = number of significant digits
    // abs(FLT_MIN_10_EXP) = number of zeros in FLT_MIN
    static_assert(kMaximumSkFloatToDecimalLength == 3 + 9 - FLT_MIN_10_EXP, "");

    /* section C.1 of the PDF1.4 spec (http://goo.gl/0SCswJ) says that
       most PDF rasterizers will use fixed-point scalars that lack the
       dynamic range of floats.  Even if this is the case, I want to
       serialize these (uncommon) very small and very large scalar
       values with enough precision to allow a floating-point
       rasterizer to read them in with perfect accuracy.
       Experimentally, rasterizers such as pdfium do seem to benefit
       from this.  Rasterizers that rely on fixed-point scalars should
       gracefully ignore these values that they can not parse. */
    char* output = &result[0];
    const char* const end = &result[kMaximumSkFloatToDecimalLength - 1];
    // subtract one to leave space for '\0'.

    /* This function is written to accept any possible input value,
       including non-finite values such as INF and NAN.  In that case,
       we ignore value-correctness and and output a syntacticly-valid
       number. */
    if (value == INFINITY) {
        value = FLT_MAX;  // nearest finite float.
    }
    if (value == -INFINITY) {
        value = -FLT_MAX;  // nearest finite float.
    }
    if (!std::isfinite(value) || value == 0.0f) {
        // NAN is unsupported in PDF.  Always output a valid number.
        // Also catch zero here, as a special case.
        *output++ = '0';
        *output = '\0';
        return static_cast<unsigned>(output - result);
    }
    if (value < 0.0) {
        *output++ = '-';
        value = -value;
    }
    SkASSERT(value >= 0.0f);

    int binaryExponent;
    (void)std::frexp(value, &binaryExponent);
    static const double kLog2 = 0.3010299956639812;  // log10(2.0);
    int decimalExponent = static_cast<int>(std::floor(kLog2 * binaryExponent));
    int decimalShift = decimalExponent - 8;
    double power = pow10(-decimalShift);
    SkASSERT(value * power <= (double)INT_MAX);
    int d = static_cast<int>(value * power + 0.5);
    // SkASSERT(value == (float)(d * pow(10.0, decimalShift)));
    SkASSERT(d <= 999999999);
    if (d > 167772159) {  // floor(pow(10,1+log10(1<<24)))
       // need one fewer decimal digits for 24-bit precision.
       decimalShift = decimalExponent - 7;
       // SkASSERT(power * 0.1 = pow10(-decimalShift));
       // recalculate to get rounding right.
       d = static_cast<int>(value * (power * 0.1) + 0.5);
       SkASSERT(d <= 99999999);
    }
    while (d % 10 == 0) {
        d /= 10;
        ++decimalShift;
    }
    SkASSERT(d > 0);
    // SkASSERT(value == (float)(d * pow(10.0, decimalShift)));
    unsigned char buffer[9]; // decimal value buffer.
    int bufferIndex = 0;
    do {
        buffer[bufferIndex++] = d % 10;
        d /= 10;
    } while (d != 0);
    SkASSERT(bufferIndex <= (int)sizeof(buffer) && bufferIndex > 0);
    if (decimalShift >= 0) {
        do {
            --bufferIndex;
            *output++ = '0' + buffer[bufferIndex];
        } while (bufferIndex);
        for (int i = 0; i < decimalShift; ++i) {
            *output++ = '0';
        }
    } else {
        int placesBeforeDecimal = bufferIndex + decimalShift;
        if (placesBeforeDecimal > 0) {
            while (placesBeforeDecimal-- > 0) {
                --bufferIndex;
                *output++ = '0' + buffer[bufferIndex];
            }
            *output++ = '.';
        } else {
            *output++ = '.';
            int placesAfterDecimal = -placesBeforeDecimal;
            while (placesAfterDecimal-- > 0) {
                *output++ = '0';
            }
        }
        while (bufferIndex > 0) {
            --bufferIndex;
            *output++ = '0' + buffer[bufferIndex];
            if (output == end) {
                break;  // denormalized: don't need extra precision.
                // Note: denormalized numbers will not have the same number of
                // significantDigits, but do not need them to round-trip.
            }
        }
    }
    SkASSERT(output <= end);
    *output = '\0';
    return static_cast<unsigned>(output - result);
}
