// Copyright 2014 The Crashpad Authors. All rights reserved.
//
// 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 <ctype.h>
#include <errno.h>
#include <inttypes.h>
#include <stdlib.h>
#include <string.h>

#include <limits>

#include "base/logging.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() || isspace(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
