// SPDX-License-Identifier: Apache-2.0
// Copyright Apache Software Foundation 2019
/** @file

    Class for handling "views" of a buffer. Views presume the memory for the
    buffer is managed elsewhere and allow efficient access to segments of the
    buffer without copies. Views are read only as the view doesn't own the
    memory. Along with generic buffer methods are specialized methods to support
    better string parsing, particularly token based parsing.
*/

#include "swoc/TextView.h"
#include <cctype>
#include <sstream>

int
memcmp(std::string_view const &lhs, std::string_view const &rhs)
{
  int zret = 0;
  size_t n = rhs.size();

  // Seems a bit ugly but size comparisons must be done anyway to get the memcmp args.
  if (lhs.size() < rhs.size()) {
    zret = 1;
    n    = lhs.size();
  } else if (lhs.size() > rhs.size()) {
    zret = -1;
  } else if (lhs.data() == rhs.data()) { // same memory, obviously equal.
    return 0;
  }

  int r = ::memcmp(lhs.data(), rhs.data(), n);
  return r ? r : zret;
}

int
strcasecmp(const std::string_view &lhs, const std::string_view &rhs)
{
  int zret = 0;
  size_t n = rhs.size();

  // Seems a bit ugly but size comparisons must be done anyway to get the @c strncasecmp args.
  if (lhs.size() < rhs.size()) {
    zret = 1;
    n    = lhs.size();
  } else if (lhs.size() > rhs.size()) {
    zret = -1;
  } else if (lhs.data() == rhs.data()) { // the same memory, obviously equal.
    return 0;
  }

  int r = ::strncasecmp(lhs.data(), rhs.data(), n);

  return r ? r : zret;
}

namespace swoc { inline namespace SWOC_VERSION_NS {

/// @cond INTERNAL_DETAIL
const int8_t svtoi_convert[256] = {
    /* [can't do this nicely because clang format won't allow exdented comments]
     0   1   2   3   4   5   6   7   8   9   A   B   C   D   E   F
    */
    -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, // 00
    -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, // 10
    -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, // 20
    0, 1, 2, 3, 4, 5, 6, 7, 8, 9, -1, -1, -1, -1, -1, -1, // 30
    -1, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, // 40
    25, 26, 27, 28, 20, 30, 31, 32, 33, 34, 35, -1, -1, -1, -1, -1, // 50
    -1, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, // 60
    25, 26, 27, 28, 20, 30, 31, 32, 33, 34, 35, -1, -1, -1, -1, -1, // 70
    -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, // 80
    -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, // 90
    -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, // A0
    -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, // B0
    -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, // C0
    -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, // D0
    -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, // E0
    -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, // F0
};
/// @endcond

intmax_t
svtoi(TextView src, TextView *out, int base) {
  intmax_t zret = 0;

  if (src.ltrim_if(&isspace) && src) {
    TextView parsed;
    const char *start = src.data();
    bool neg = false;
    if ('-' == *src) {
      ++src;
      neg = true;
    } else if ('+' == *src) {
      ++src;
    }
    zret = intmax_t(svtou(src, &parsed, base));
    if (!parsed.empty()) {
      if (out) {
        out->assign(start, parsed.data_end());
      }
      if (neg) {
        zret = -zret;
      }
    }
  }
  return zret;
}

uintmax_t
svtou(TextView src, TextView *out, int base) {
  uintmax_t zret = 0;

  if (out) {
    out->clear();
  }
  if (!(0 <= base && base <= 36)) {
    return 0;
  }
  if (src.ltrim_if(&isspace).size()) {
    auto origin = src.data();
    int8_t v;
    // If base is 0, it wasn't specified - check for standard base prefixes
    if (0 == base) {
      base = 10;
      if ('0' == *src) {
        ++src;
        base = 8;
        if (src && ('x' == *src || 'X' == *src)) {
          ++src;
          base = 16;
        }
      }
    }

    // For performance in common cases, use the templated conversion.
    switch (base) {
      case 8:zret = svto_radix<8>(src);
        break;
      case 10:zret = svto_radix<10>(src);
        break;
      case 16:zret = svto_radix<16>(src);
        break;
      default:
        while (src.size() && (0 <= (v = svtoi_convert[static_cast<unsigned char>(*src)])) &&
               v < base) {
          auto n = zret * base + v;
          if (n < zret) {
            zret = std::numeric_limits<uintmax_t>::max();
            break; // overflow, stop parsing.
          }
          zret = n;
          ++src;
        }
        break;
    }

    if (out) {
      out->assign(origin, src.data());
    }
  }
  return zret;
}

// Do the template instantiations.
template std::ostream& TextView::stream_write(std::ostream&, const TextView&) const;

}} // namespace swoc

namespace std
{
ostream &
operator<<(ostream &os, const swoc::TextView &b)
{
  if (os.good()) {
    b.stream_write<ostream>(os, b);
    os.width(0);
  }
  return os;
}
} // namespace std
