/*
 *  Licensed to the Apache Software Foundation (ASF) under one or more
 *  contributor license agreements.  See the NOTICE file distributed with
 *  this work for additional information regarding copyright ownership.
 *  The ASF licenses this file to You under the Apache License, Version 2.0
 *  (the "License"); you may not use this file except in compliance with
 *  the License.  You may obtain a copy of the License at
 *
 *     http://www.apache.org/licenses/LICENSE-2.0
 *
 *  Unless required by applicable law or agreed to in writing, software
 *  distributed under the License is distributed on an "AS IS" BASIS,
 *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 *  See the License for the specific language governing permissions and
 *  limitations under the License.
 */

#include <stdlib.h>
#include <string.h>
#include <math.h>
#include "JNIHelp.h"
#include "commonDblParce.h"
#include "cbigint.h"

#if defined(LINUX) || defined(FREEBSD) || defined(ZOS)
#define USE_LL
#endif

#define LOW_I32_FROM_VAR(u64)     LOW_I32_FROM_LONG64(u64)
#ifdef HY_LITTLE_ENDIAN
#define LOW_I32_FROM_PTR(ptr64) (*(I_32 *) (ptr64))
#else
#define LOW_I32_FROM_PTR(ptr64) (*(((I_32 *) (ptr64)) + 1))
#endif
#define HIGH_I32_FROM_VAR(u64)    HIGH_I32_FROM_LONG64(u64)
#define HIGH_I32_FROM_PTR(u64ptr) HIGH_I32_FROM_LONG64_PTR(u64ptr)

#define MAX_ACCURACY_WIDTH 8

#define DEFAULT_WIDTH MAX_ACCURACY_WIDTH

JNIEXPORT jfloat JNICALL
Java_org_apache_harmony_luni_util_FloatingPointParser_parseFltImpl (JNIEnv* env,
                                                        jclass clazz,
                                                        jstring s, jint e);
JNIEXPORT jdouble JNICALL
Java_org_apache_harmony_luni_util_FloatingPointParser_parseDblImpl (JNIEnv* env,
                                                        jclass clazz,
                                                        jstring s, jint e);

jfloat createFloat1 (JNIEnv* env, U_64 * f, IDATA length, jint e);
jfloat floatAlgorithm (JNIEnv* env, U_64 * f, IDATA length, jint e,
                       jfloat z);
jfloat createFloat (JNIEnv* env, const char *s, jint e);

static const U_32 tens[] = {
  0x3f800000,
  0x41200000,
  0x42c80000,
  0x447a0000,
  0x461c4000,
  0x47c35000,
  0x49742400,
  0x4b189680,
  0x4cbebc20,
  0x4e6e6b28,
  0x501502f9                    /* 10 ^ 10 in float */
};

#define tenToTheE(e) (*((jfloat *) (tens + (e))))
#define LOG5_OF_TWO_TO_THE_N 11

#define sizeOfTenToTheE(e) (((e) / 19) + 1)

#define INFINITE_INTBITS (0x7F800000)
#define MINIMUM_INTBITS (1)

#define MANTISSA_MASK (0x007FFFFF)
#define EXPONENT_MASK (0x7F800000)
#define NORMAL_MASK   (0x00800000)
#define FLOAT_TO_INTBITS(flt) (*((U_32 *)(&flt)))

/* Keep a count of the number of times we decrement and increment to
 * approximate the double, and attempt to detect the case where we
 * could potentially toggle back and forth between decrementing and
 * incrementing. It is possible for us to be stuck in the loop when
 * incrementing by one or decrementing by one may exceed or stay below
 * the value that we are looking for. In this case, just break out of
 * the loop if we toggle between incrementing and decrementing for more
 * than twice.
 */
#define INCREMENT_FLOAT(_x, _decCount, _incCount) \
    { \
        ++FLOAT_TO_INTBITS(_x); \
        _incCount++; \
        if( (_incCount > 2) && (_decCount > 2) ) { \
            if( _decCount > _incCount ) { \
                FLOAT_TO_INTBITS(_x) += _decCount - _incCount; \
            } else if( _incCount > _decCount ) { \
                FLOAT_TO_INTBITS(_x) -= _incCount - _decCount; \
            } \
            break; \
        } \
    }
#define DECREMENT_FLOAT(_x, _decCount, _incCount) \
    { \
        --FLOAT_TO_INTBITS(_x); \
        _decCount++; \
        if( (_incCount > 2) && (_decCount > 2) ) { \
            if( _decCount > _incCount ) { \
                FLOAT_TO_INTBITS(_x) += _decCount - _incCount; \
            } else if( _incCount > _decCount ) { \
                FLOAT_TO_INTBITS(_x) -= _incCount - _decCount; \
            } \
            break; \
        } \
    }
#define ERROR_OCCURED(x) (HIGH_I32_FROM_VAR(x) < 0)

#define allocateU64(x, n) if (!((x) = (U_64*) malloc((n) * sizeof(U_64)))) goto OutOfMemory;
#define release(r) if ((r)) free((r));

jfloat
createFloat (JNIEnv* env, const char *s, jint e)
{
  /* assumes s is a null terminated string with at least one
   * character in it */
  U_64 def[DEFAULT_WIDTH];
  U_64 defBackup[DEFAULT_WIDTH];
  U_64 *f, *fNoOverflow, *g, *tempBackup;
  U_32 overflow;
  jfloat result;
  IDATA index = 1;
  int unprocessedDigits = 0;

  f = def;
  fNoOverflow = defBackup;
  *f = 0;
  tempBackup = g = 0;
  do
    {
      if (*s >= '0' && *s <= '9')
        {
          /* Make a back up of f before appending, so that we can
           * back out of it if there is no more room, i.e. index >
           * MAX_ACCURACY_WIDTH.
           */
          memcpy (fNoOverflow, f, sizeof (U_64) * index);
          overflow =
            simpleAppendDecimalDigitHighPrecision (f, index, *s - '0');
          if (overflow)
            {

              f[index++] = overflow;
              /* There is an overflow, but there is no more room
               * to store the result. We really only need the top 52
               * bits anyway, so we must back out of the overflow,
               * and ignore the rest of the string.
               */
              if (index >= MAX_ACCURACY_WIDTH)
                {
                  index--;
                  memcpy (f, fNoOverflow, sizeof (U_64) * index);
                  break;
                }
              if (tempBackup)
                {
                  fNoOverflow = tempBackup;
                }
            }
        }
      else
        index = -1;
    }
  while (index > 0 && *(++s) != '\0');

  /* We've broken out of the parse loop either because we've reached
   * the end of the string or we've overflowed the maximum accuracy
   * limit of a double. If we still have unprocessed digits in the
   * given string, then there are three possible results:
   *   1. (unprocessed digits + e) == 0, in which case we simply
   *      convert the existing bits that are already parsed
   *   2. (unprocessed digits + e) < 0, in which case we simply
   *      convert the existing bits that are already parsed along
   *      with the given e
   *   3. (unprocessed digits + e) > 0 indicates that the value is
   *      simply too big to be stored as a double, so return Infinity
   */
  if ((unprocessedDigits = strlen (s)) > 0)
    {
      e += unprocessedDigits;
      if (index > -1)
        {
          if (e <= 0)
            {
              result = createFloat1 (env, f, index, e);
            }
          else
            {
              FLOAT_TO_INTBITS (result) = INFINITE_INTBITS;
            }
        }
      else
        {
          result = *(jfloat *) & index;
        }
    }
  else
    {
      if (index > -1)
        {
          result = createFloat1 (env, f, index, e);
        }
      else
        {
        result = *(jfloat *) & index;
        }
    }

  return result;

}

jfloat
createFloat1 (JNIEnv* env, U_64 * f, IDATA length, jint e)
{
  IDATA numBits;
  jdouble dresult;
  jfloat result;

  numBits = highestSetBitHighPrecision (f, length) + 1;
  if (numBits < 25 && e >= 0 && e < LOG5_OF_TWO_TO_THE_N)
    {
      return ((jfloat) LOW_I32_FROM_PTR (f)) * tenToTheE (e);
    }
  else if (numBits < 25 && e < 0 && (-e) < LOG5_OF_TWO_TO_THE_N)
    {
      return ((jfloat) LOW_I32_FROM_PTR (f)) / tenToTheE (-e);
    }
  else if (e >= 0 && e < 39)
    {
      result = (jfloat) (toDoubleHighPrecision (f, length) * pow (10.0, (double) e));
    }
  else if (e >= 39)
    {
      /* Convert the partial result to make sure that the
       * non-exponential part is not zero. This check fixes the case
       * where the user enters 0.0e309! */
      result = (jfloat) toDoubleHighPrecision (f, length);

      if (result == 0.0)

        FLOAT_TO_INTBITS (result) = MINIMUM_INTBITS;
      else
        FLOAT_TO_INTBITS (result) = INFINITE_INTBITS;
    }
  else if (e > -309)
    {
      int dexp;
      U_32 fmant, fovfl;
      U_64 dmant;
      dresult = toDoubleHighPrecision (f, length) / pow (10.0, (double) -e);
      if (IS_DENORMAL_DBL (dresult))
        {
          FLOAT_TO_INTBITS (result) = 0;
          return result;
        }
      dexp = doubleExponent (dresult) + 51;
      dmant = doubleMantissa (dresult);
      /* Is it too small to be represented by a single-precision
       * float? */
      if (dexp <= -155)
        {
          FLOAT_TO_INTBITS (result) = 0;
          return result;
        }
      /* Is it a denormalized single-precision float? */
      if ((dexp <= -127) && (dexp > -155))
        {
          /* Only interested in 24 msb bits of the 53-bit double mantissa */
          fmant = (U_32) (dmant >> 29);
          fovfl = ((U_32) (dmant & 0x1FFFFFFF)) << 3;
          while ((dexp < -127) && ((fmant | fovfl) != 0))
            {
              if ((fmant & 1) != 0)
                {
                  fovfl |= 0x80000000;
                }
              fovfl >>= 1;
              fmant >>= 1;
              dexp++;
            }
          if ((fovfl & 0x80000000) != 0)
            {
              if ((fovfl & 0x7FFFFFFC) != 0)
                {
                  fmant++;
                }
              else if ((fmant & 1) != 0)
                {
                  fmant++;
                }
            }
          else if ((fovfl & 0x40000000) != 0)
            {
              if ((fovfl & 0x3FFFFFFC) != 0)
                {
                  fmant++;
                }
            }
          FLOAT_TO_INTBITS (result) = fmant;
        }
      else
        {
          result = (jfloat) dresult;
        }
    }

  /* Don't go straight to zero as the fact that x*0 = 0 independent
   * of x might cause the algorithm to produce an incorrect result.
   * Instead try the min  value first and let it fall to zero if need
   * be.
   */
  if (e <= -309 || FLOAT_TO_INTBITS (result) == 0)
    FLOAT_TO_INTBITS (result) = MINIMUM_INTBITS;

  return floatAlgorithm (env, f, length, e, (jfloat) result);
}

#if defined(WIN32)
/* disable global optimizations on the microsoft compiler for the
 * floatAlgorithm function otherwise it won't properly compile */
#pragma optimize("g",off)
#endif

/* The algorithm for the function floatAlgorithm() below can be found
 * in:
 *
 *      "How to Read Floating-Point Numbers Accurately", William D.
 *      Clinger, Proceedings of the ACM SIGPLAN '90 Conference on
 *      Programming Language Design and Implementation, June 20-22,
 *      1990, pp. 92-101.
 *
 * There is a possibility that the function will end up in an endless
 * loop if the given approximating floating-point number (a very small
 * floating-point whose value is very close to zero) straddles between
 * two approximating integer values. We modified the algorithm slightly
 * to detect the case where it oscillates back and forth between
 * incrementing and decrementing the floating-point approximation. It
 * is currently set such that if the oscillation occurs more than twice
 * then return the original approximation.
 */
jfloat
floatAlgorithm (JNIEnv* env __attribute__ ((unused)), U_64 * f, IDATA length, jint e, jfloat z)
{
  U_64 m;
  IDATA k, comparison, comparison2;
  U_64 *x, *y, *D, *D2;
  IDATA xLength, yLength, DLength, D2Length;
  IDATA decApproxCount, incApproxCount;

  x = y = D = D2 = 0;
  xLength = yLength = DLength = D2Length = 0;
  decApproxCount = incApproxCount = 0;

  do
    {
      m = floatMantissa (z);
      k = floatExponent (z);

      if (x && x != f)
          free(x);

      release (y);
      release (D);
      release (D2);

      if (e >= 0 && k >= 0)
        {
          xLength = sizeOfTenToTheE (e) + length;
          allocateU64 (x, xLength);
          memset (x + length, 0, sizeof (U_64) * (xLength - length));
          memcpy (x, f, sizeof (U_64) * length);
          timesTenToTheEHighPrecision (x, xLength, e);

          yLength = (k >> 6) + 2;
          allocateU64 (y, yLength);
          memset (y + 1, 0, sizeof (U_64) * (yLength - 1));
          *y = m;
          simpleShiftLeftHighPrecision (y, yLength, k);
        }
      else if (e >= 0)
        {
          xLength = sizeOfTenToTheE (e) + length + ((-k) >> 6) + 1;
          allocateU64 (x, xLength);
          memset (x + length, 0, sizeof (U_64) * (xLength - length));
          memcpy (x, f, sizeof (U_64) * length);
          timesTenToTheEHighPrecision (x, xLength, e);
          simpleShiftLeftHighPrecision (x, xLength, -k);

          yLength = 1;
          allocateU64 (y, 1);
          *y = m;
        }
      else if (k >= 0)
        {
          xLength = length;
          x = f;

          yLength = sizeOfTenToTheE (-e) + 2 + (k >> 6);
          allocateU64 (y, yLength);
          memset (y + 1, 0, sizeof (U_64) * (yLength - 1));
          *y = m;
          timesTenToTheEHighPrecision (y, yLength, -e);
          simpleShiftLeftHighPrecision (y, yLength, k);
        }
      else
        {
          xLength = length + ((-k) >> 6) + 1;
          allocateU64 (x, xLength);
          memset (x + length, 0, sizeof (U_64) * (xLength - length));
          memcpy (x, f, sizeof (U_64) * length);
          simpleShiftLeftHighPrecision (x, xLength, -k);

          yLength = sizeOfTenToTheE (-e) + 1;
          allocateU64 (y, yLength);
          memset (y + 1, 0, sizeof (U_64) * (yLength - 1));
          *y = m;
          timesTenToTheEHighPrecision (y, yLength, -e);
        }

      comparison = compareHighPrecision (x, xLength, y, yLength);
      if (comparison > 0)
        {                       /* x > y */
          DLength = xLength;
          allocateU64 (D, DLength);
          memcpy (D, x, DLength * sizeof (U_64));
          subtractHighPrecision (D, DLength, y, yLength);
        }
      else if (comparison)
        {                       /* y > x */
          DLength = yLength;
          allocateU64 (D, DLength);
          memcpy (D, y, DLength * sizeof (U_64));
          subtractHighPrecision (D, DLength, x, xLength);
        }
      else
        {                       /* y == x */
          DLength = 1;
          allocateU64 (D, 1);
          *D = 0;
        }

      D2Length = DLength + 1;
      allocateU64 (D2, D2Length);
      m <<= 1;
      multiplyHighPrecision (D, DLength, &m, 1, D2, D2Length);
      m >>= 1;

      comparison2 = compareHighPrecision (D2, D2Length, y, yLength);
      if (comparison2 < 0)
        {
          if (comparison < 0 && m == NORMAL_MASK)
            {
              simpleShiftLeftHighPrecision (D2, D2Length, 1);
              if (compareHighPrecision (D2, D2Length, y, yLength) > 0)
                {
                  DECREMENT_FLOAT (z, decApproxCount, incApproxCount);
                }
              else
                {
                  break;
                }
            }
          else
            {
              break;
            }
        }
      else if (comparison2 == 0)
        {
          if ((m & 1) == 0)
            {
              if (comparison < 0 && m == NORMAL_MASK)
                {
                  DECREMENT_FLOAT (z, decApproxCount, incApproxCount);
                }
              else
                {
                  break;
                }
            }
          else if (comparison < 0)
            {
              DECREMENT_FLOAT (z, decApproxCount, incApproxCount);
              break;
            }
          else
            {
              INCREMENT_FLOAT (z, decApproxCount, incApproxCount);
              break;
            }
        }
      else if (comparison < 0)
        {
          DECREMENT_FLOAT (z, decApproxCount, incApproxCount);
        }
      else
        {
          if (FLOAT_TO_INTBITS (z) == EXPONENT_MASK)
            break;
          INCREMENT_FLOAT (z, decApproxCount, incApproxCount);
        }
    }
  while (1);

  if (x && x != f)
      free(x);
  release (y);
  release (D);
  release (D2);
  return z;

OutOfMemory:
  if (x && x != f)
      free(x);
  release (y);
  release (D);
  release (D2);

  FLOAT_TO_INTBITS (z) = -2;

  return z;
}

#if defined(WIN32)
#pragma optimize("",on)         /*restore optimizations */
#endif

JNIEXPORT jfloat JNICALL
Java_org_apache_harmony_luni_util_FloatingPointParser_parseFltImpl (JNIEnv* env,
                                                        jclass clazz __attribute__ ((unused)),
                                                        jstring s, jint e)
{
  jfloat flt;
  const char *str = (*env)->GetStringUTFChars (env, s, 0);
  flt = createFloat (env, str, e);
  (*env)->ReleaseStringUTFChars (env, s, str);

  if (((I_32) FLOAT_TO_INTBITS (flt)) >= 0)
    {
      return flt;
    }
  else if (((I_32) FLOAT_TO_INTBITS (flt)) == (I_32) - 1)
    {                           /* NumberFormatException */
      jniThrowException(env, "java/lang/NumberFormatException", "");
    }
  else
    {                           /* OutOfMemoryError */
      jniThrowException(env, "java/lang/OutOfMemoryError", "");
    }

  return 0.0;
}

JNIEXPORT jdouble JNICALL
Java_org_apache_harmony_luni_util_FloatingPointParser_parseDblImpl (JNIEnv* env,
                                                        jclass clazz __attribute__ ((unused)),
                                                        jstring s, jint e)
{
  jdouble dbl;
  const char *str = (*env)->GetStringUTFChars (env, s, 0);
  dbl = createDouble (env, str, e);
  (*env)->ReleaseStringUTFChars (env, s, str);

  if (!ERROR_OCCURED (dbl))
    {
      return dbl;
    }
  else if (LOW_I32_FROM_VAR (dbl) == (I_32) - 1)
    {                           /* NumberFormatException */
      jniThrowException(env, "java/lang/NumberFormatException", "");
    }
  else
    {                           /* OutOfMemoryError */
      jniThrowException(env, "java/lang/OutOfMemoryError", "");
    }

  return 0.0;
}

static JNINativeMethod gMethods[] = {
    { "parseFltImpl", "(Ljava/lang/String;I)F",
        Java_org_apache_harmony_luni_util_FloatingPointParser_parseFltImpl },
    { "parseDblImpl", "(Ljava/lang/String;I)D",
        Java_org_apache_harmony_luni_util_FloatingPointParser_parseDblImpl },
};
int register_org_apache_harmony_luni_util_fltparse(JNIEnv *env) {
    return jniRegisterNativeMethods(env, "org/apache/harmony/luni/util/FloatingPointParser",
                gMethods, NELEM(gMethods));
}
