// Copyright 2014 The Crashpad Authors
//
// Licensed 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 "util/stdlib/string_number_conversion.h"

#include <errno.h>
#include <inttypes.h>
#include <stdlib.h>
#include <string.h>

#include <limits>

#include "base/strings/string_util.h"

namespace {

template <typename TIntType, typename TLongType>
struct StringToIntegerTraits {
  using IntType = TIntType;
  using LongType = TLongType;
  static void TypeCheck() {
    static_assert(std::numeric_limits<TIntType>::is_integer &&
                      std::numeric_limits<TLongType>::is_integer,
                  "IntType and LongType must be integer");
    static_assert(std::numeric_limits<TIntType>::is_signed ==
                      std::numeric_limits<TLongType>::is_signed,
                  "IntType and LongType signedness must agree");
    static_assert(std::numeric_limits<TIntType>::min() >=
                          std::numeric_limits<TLongType>::min() &&
                      std::numeric_limits<TIntType>::min() <
                          std::numeric_limits<TLongType>::max(),
                  "IntType min must be in LongType range");
    static_assert(std::numeric_limits<TIntType>::max() >
                          std::numeric_limits<TLongType>::min() &&
                      std::numeric_limits<TIntType>::max() <=
                          std::numeric_limits<TLongType>::max(),
                  "IntType max must be in LongType range");
  }
};

template <typename TIntType, typename TLongType>
struct StringToSignedIntegerTraits
    : public StringToIntegerTraits<TIntType, TLongType> {
  static void TypeCheck() {
    static_assert(std::numeric_limits<TIntType>::is_signed,
                  "StringToSignedTraits IntType must be signed");
    return super::TypeCheck();
  }
  static bool IsNegativeOverflow(TLongType value) {
    return value < std::numeric_limits<TIntType>::min();
  }

 private:
  using super = StringToIntegerTraits<TIntType, TLongType>;
};

template <typename TIntType, typename TLongType>
struct StringToUnsignedIntegerTraits
    : public StringToIntegerTraits<TIntType, TLongType> {
  static void TypeCheck() {
    static_assert(!std::numeric_limits<TIntType>::is_signed,
                  "StringToUnsignedTraits IntType must be unsigned");
    return super::TypeCheck();
  }
  static bool IsNegativeOverflow(TLongType value) { return false; }

 private:
  using super = StringToIntegerTraits<TIntType, TLongType>;
};

struct StringToIntTraits : public StringToSignedIntegerTraits<int, long> {
  static LongType Convert(const char* str, char** end, int base) {
    return strtol(str, end, base);
  }
};

struct StringToUnsignedIntTraits
    : public StringToUnsignedIntegerTraits<unsigned int, unsigned long> {
  static LongType Convert(const char* str, char** end, int base) {
    if (str[0] == '-') {
      *end = const_cast<char*>(str);
      return 0;
    }
    return strtoul(str, end, base);
  }
};

struct StringToLongTraits
    : public StringToSignedIntegerTraits<long, long long> {
  static LongType Convert(const char* str, char** end, int base) {
    return strtoll(str, end, base);
  }
};

struct StringToUnsignedLongTraits
    : public StringToUnsignedIntegerTraits<unsigned long, unsigned long long> {
  static LongType Convert(const char* str, char** end, int base) {
    if (str[0] == '-') {
      *end = const_cast<char*>(str);
      return 0;
    }
    return strtoull(str, end, base);
  }
};

struct StringToLongLongTraits
    : public StringToSignedIntegerTraits<long long, long long> {
  static LongType Convert(const char* str, char** end, int base) {
    return strtoll(str, end, base);
  }
};

struct StringToUnsignedLongLongTraits
    : public StringToUnsignedIntegerTraits<unsigned long long,
                                           unsigned long long> {
  static LongType Convert(const char* str, char** end, int base) {
    if (str[0] == '-') {
      *end = const_cast<char*>(str);
      return 0;
    }
    return strtoull(str, end, base);
  }
};

template <typename Traits>
bool StringToIntegerInternal(const std::string& string,
                             typename Traits::IntType* number) {
  using IntType = typename Traits::IntType;
  using LongType = typename Traits::LongType;

  Traits::TypeCheck();

  if (string.empty() || base::IsAsciiWhitespace(string[0])) {
    return false;
  }

  errno = 0;
  char* end;
  LongType result = Traits::Convert(string.data(), &end, 0);
  if (Traits::IsNegativeOverflow(result) ||
      result > std::numeric_limits<IntType>::max() ||
      errno == ERANGE ||
      end != string.data() + string.length()) {
    return false;
  }
  *number = static_cast<IntType>(result);
  return true;
}

}  // namespace

namespace crashpad {

bool StringToNumber(const std::string& string, int* number) {
  return StringToIntegerInternal<StringToIntTraits>(string, number);
}

bool StringToNumber(const std::string& string, unsigned int* number) {
  return StringToIntegerInternal<StringToUnsignedIntTraits>(string, number);
}

bool StringToNumber(const std::string& string, long* number) {
  return StringToIntegerInternal<StringToLongTraits>(string, number);
}

bool StringToNumber(const std::string& string, unsigned long* number) {
  return StringToIntegerInternal<StringToUnsignedLongTraits>(string, number);
}

bool StringToNumber(const std::string& string, long long* number) {
  return StringToIntegerInternal<StringToLongLongTraits>(string, number);
}

bool StringToNumber(const std::string& string, unsigned long long* number) {
  return StringToIntegerInternal<StringToUnsignedLongLongTraits>(string,
                                                                 number);
}

}  // namespace crashpad
