// Copyright 2017 PDFium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

// Original code copyright 2014 Foxit Software Inc. http://www.foxitsoftware.com

#include <limits>
#include <vector>

#include "core/fxcrt/fx_extension.h"
#include "core/fxcrt/fx_string.h"

namespace {

class CFX_UTF8Encoder {
 public:
  CFX_UTF8Encoder() {}
  ~CFX_UTF8Encoder() {}

  void Input(wchar_t unicodeAsWchar) {
    uint32_t unicode = static_cast<uint32_t>(unicodeAsWchar);
    if (unicode < 0x80) {
      m_Buffer.push_back(unicode);
    } else {
      if (unicode >= 0x80000000)
        return;

      int nbytes = 0;
      if (unicode < 0x800)
        nbytes = 2;
      else if (unicode < 0x10000)
        nbytes = 3;
      else if (unicode < 0x200000)
        nbytes = 4;
      else if (unicode < 0x4000000)
        nbytes = 5;
      else
        nbytes = 6;

      static uint8_t prefix[] = {0xc0, 0xe0, 0xf0, 0xf8, 0xfc};
      int order = 1 << ((nbytes - 1) * 6);
      int code = unicodeAsWchar;
      m_Buffer.push_back(prefix[nbytes - 2] | (code / order));
      for (int i = 0; i < nbytes - 1; i++) {
        code = code % order;
        order >>= 6;
        m_Buffer.push_back(0x80 | (code / order));
      }
    }
  }

  // The data returned by GetResult() is invalidated when this is modified by
  // appending any data.
  CFX_ByteStringC GetResult() const {
    return CFX_ByteStringC(m_Buffer.data(), m_Buffer.size());
  }

 private:
  std::vector<uint8_t> m_Buffer;
};

}  // namespace

CFX_ByteString FX_UTF8Encode(const CFX_WideStringC& wsStr) {
  FX_STRSIZE len = wsStr.GetLength();
  const wchar_t* pStr = wsStr.unterminated_c_str();
  CFX_UTF8Encoder encoder;
  while (len-- > 0)
    encoder.Input(*pStr++);

  return CFX_ByteString(encoder.GetResult());
}

namespace {

const float fraction_scales[] = {0.1f,          0.01f,         0.001f,
                                 0.0001f,       0.00001f,      0.000001f,
                                 0.0000001f,    0.00000001f,   0.000000001f,
                                 0.0000000001f, 0.00000000001f};

float FractionalScale(size_t scale_factor, int value) {
  return fraction_scales[scale_factor] * value;
}

}  // namespace

bool FX_atonum(const CFX_ByteStringC& strc, void* pData) {
  if (strc.Contains('.')) {
    float* pFloat = static_cast<float*>(pData);
    *pFloat = FX_atof(strc);
    return false;
  }

  // Note, numbers in PDF are typically of the form 123, -123, etc. But,
  // for things like the Permissions on the encryption hash the number is
  // actually an unsigned value. We use a uint32_t so we can deal with the
  // unsigned and then check for overflow if the user actually signed the value.
  // The Permissions flag is listed in Table 3.20 PDF 1.7 spec.
  pdfium::base::CheckedNumeric<uint32_t> integer = 0;
  bool bNegative = false;
  bool bSigned = false;
  FX_STRSIZE cc = 0;
  if (strc[0] == '+') {
    cc++;
    bSigned = true;
  } else if (strc[0] == '-') {
    bNegative = true;
    bSigned = true;
    cc++;
  }

  while (cc < strc.GetLength() && std::isdigit(strc[cc])) {
    integer = integer * 10 + FXSYS_DecimalCharToInt(strc.CharAt(cc));
    if (!integer.IsValid())
      break;
    cc++;
  }

  // We have a sign, and the value was greater then a regular integer
  // we've overflowed, reset to the default value.
  if (bSigned) {
    if (bNegative) {
      if (integer.ValueOrDefault(0) >
          static_cast<uint32_t>(std::numeric_limits<int>::max()) + 1) {
        integer = 0;
      }
    } else if (integer.ValueOrDefault(0) >
               static_cast<uint32_t>(std::numeric_limits<int>::max())) {
      integer = 0;
    }
  }

  // Switch back to the int space so we can flip to a negative if we need.
  uint32_t uValue = integer.ValueOrDefault(0);
  int32_t value = static_cast<int>(uValue);
  if (bNegative)
    value = -value;

  int* pInt = static_cast<int*>(pData);
  *pInt = value;
  return true;
}

float FX_atof(const CFX_ByteStringC& strc) {
  if (strc.IsEmpty())
    return 0.0;

  int cc = 0;
  bool bNegative = false;
  int len = strc.GetLength();
  if (strc[0] == '+') {
    cc++;
  } else if (strc[0] == '-') {
    bNegative = true;
    cc++;
  }
  while (cc < len) {
    if (strc[cc] != '+' && strc[cc] != '-')
      break;
    cc++;
  }
  float value = 0;
  while (cc < len) {
    if (strc[cc] == '.')
      break;
    value = value * 10 + FXSYS_DecimalCharToInt(strc.CharAt(cc));
    cc++;
  }
  int scale = 0;
  if (cc < len && strc[cc] == '.') {
    cc++;
    while (cc < len) {
      value += FractionalScale(scale, FXSYS_DecimalCharToInt(strc.CharAt(cc)));
      scale++;
      if (scale == FX_ArraySize(fraction_scales))
        break;
      cc++;
    }
  }
  return bNegative ? -value : value;
}

float FX_atof(const CFX_WideStringC& wsStr) {
  return FX_atof(FX_UTF8Encode(wsStr).c_str());
}

FX_STRSIZE FX_ftoa(float d, char* buf) {
  buf[0] = '0';
  buf[1] = '\0';
  if (d == 0.0f) {
    return 1;
  }
  bool bNegative = false;
  if (d < 0) {
    bNegative = true;
    d = -d;
  }
  int scale = 1;
  int scaled = FXSYS_round(d);
  while (scaled < 100000) {
    if (scale == 1000000) {
      break;
    }
    scale *= 10;
    scaled = FXSYS_round(d * scale);
  }
  if (scaled == 0) {
    return 1;
  }
  char buf2[32];
  FX_STRSIZE buf_size = 0;
  if (bNegative) {
    buf[buf_size++] = '-';
  }
  int i = scaled / scale;
  FXSYS_itoa(i, buf2, 10);
  FX_STRSIZE len = FXSYS_strlen(buf2);
  memcpy(buf + buf_size, buf2, len);
  buf_size += len;
  int fraction = scaled % scale;
  if (fraction == 0) {
    return buf_size;
  }
  buf[buf_size++] = '.';
  scale /= 10;
  while (fraction) {
    buf[buf_size++] = '0' + fraction / scale;
    fraction %= scale;
    scale /= 10;
  }
  return buf_size;
}
