// 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>


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
