// Copyright (c) 2012 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
// Copied from strings/stringpiece.cc with modifications

#include "base/strings/string_piece.h"

#include <limits.h>

#include <algorithm>
#include <ostream>

#include "base/logging.h"

namespace base {
namespace {

// For each character in characters_wanted, sets the index corresponding
// to the ASCII code of that character to 1 in table.  This is used by
// the find_.*_of methods below to tell whether or not a character is in
// the lookup table in constant time.
// The argument `table' must be an array that is large enough to hold all
// the possible values of an unsigned char.  Thus it should be be declared
// as follows:
//   bool table[UCHAR_MAX + 1]
inline void BuildLookupTable(const StringPiece& characters_wanted,
                             bool* table) {
  const size_t length = characters_wanted.length();
  const char* const data = characters_wanted.data();
  for (size_t i = 0; i < length; ++i) {
    table[static_cast<unsigned char>(data[i])] = true;
  }
}

}  // namespace

// MSVC doesn't like complex extern templates and DLLs.
#if !defined(COMPILER_MSVC)
template class BasicStringPiece<std::string>;
template class BasicStringPiece<string16>;
#endif

bool operator==(const StringPiece& x, const StringPiece& y) {
  if (x.size() != y.size())
    return false;

  return StringPiece::wordmemcmp(x.data(), y.data(), x.size()) == 0;
}

std::ostream& operator<<(std::ostream& o, const StringPiece& piece) {
  o.write(piece.data(), static_cast<std::streamsize>(piece.size()));
  return o;
}

namespace internal {

template<typename STR>
void CopyToStringT(const BasicStringPiece<STR>& self, STR* target) {
  if (self.empty())
    target->clear();
  else
    target->assign(self.data(), self.size());
}

void CopyToString(const StringPiece& self, std::string* target) {
  CopyToStringT(self, target);
}

void CopyToString(const StringPiece16& self, string16* target) {
  CopyToStringT(self, target);
}

template<typename STR>
void AppendToStringT(const BasicStringPiece<STR>& self, STR* target) {
  if (!self.empty())
    target->append(self.data(), self.size());
}

void AppendToString(const StringPiece& self, std::string* target) {
  AppendToStringT(self, target);
}

void AppendToString(const StringPiece16& self, string16* target) {
  AppendToStringT(self, target);
}

template<typename STR>
size_t copyT(const BasicStringPiece<STR>& self,
             typename STR::value_type* buf,
             size_t n,
             size_t pos) {
  size_t ret = std::min(self.size() - pos, n);
  memcpy(buf, self.data() + pos, ret * sizeof(typename STR::value_type));
  return ret;
}

size_t copy(const StringPiece& self, char* buf, size_t n, size_t pos) {
  return copyT(self, buf, n, pos);
}

size_t copy(const StringPiece16& self, char16* buf, size_t n, size_t pos) {
  return copyT(self, buf, n, pos);
}

template<typename STR>
size_t findT(const BasicStringPiece<STR>& self,
             const BasicStringPiece<STR>& s,
             size_t pos) {
  if (pos > self.size())
    return BasicStringPiece<STR>::npos;

  typename BasicStringPiece<STR>::const_iterator result =
      std::search(self.begin() + pos, self.end(), s.begin(), s.end());
  const size_t xpos =
    static_cast<size_t>(result - self.begin());
  return xpos + s.size() <= self.size() ? xpos : BasicStringPiece<STR>::npos;
}

size_t find(const StringPiece& self, const StringPiece& s, size_t pos) {
  return findT(self, s, pos);
}

size_t find(const StringPiece16& self, const StringPiece16& s, size_t pos) {
  return findT(self, s, pos);
}

template<typename STR>
size_t findT(const BasicStringPiece<STR>& self,
             typename STR::value_type c,
             size_t pos) {
  if (pos >= self.size())
    return BasicStringPiece<STR>::npos;

  typename BasicStringPiece<STR>::const_iterator result =
      std::find(self.begin() + pos, self.end(), c);
  return result != self.end() ?
      static_cast<size_t>(result - self.begin()) : BasicStringPiece<STR>::npos;
}

size_t find(const StringPiece& self, char c, size_t pos) {
  return findT(self, c, pos);
}

size_t find(const StringPiece16& self, char16 c, size_t pos) {
  return findT(self, c, pos);
}

template<typename STR>
size_t rfindT(const BasicStringPiece<STR>& self,
              const BasicStringPiece<STR>& s,
              size_t pos) {
  if (self.size() < s.size())
    return BasicStringPiece<STR>::npos;

  if (s.empty())
    return std::min(self.size(), pos);

  typename BasicStringPiece<STR>::const_iterator last =
      self.begin() + std::min(self.size() - s.size(), pos) + s.size();
  typename BasicStringPiece<STR>::const_iterator result =
      std::find_end(self.begin(), last, s.begin(), s.end());
  return result != last ?
      static_cast<size_t>(result - self.begin()) : BasicStringPiece<STR>::npos;
}

size_t rfind(const StringPiece& self, const StringPiece& s, size_t pos) {
  return rfindT(self, s, pos);
}

size_t rfind(const StringPiece16& self, const StringPiece16& s, size_t pos) {
  return rfindT(self, s, pos);
}

template<typename STR>
size_t rfindT(const BasicStringPiece<STR>& self,
              typename STR::value_type c,
              size_t pos) {
  if (self.size() == 0)
    return BasicStringPiece<STR>::npos;

  for (size_t i = std::min(pos, self.size() - 1); ;
       --i) {
    if (self.data()[i] == c)
      return i;
    if (i == 0)
      break;
  }
  return BasicStringPiece<STR>::npos;
}

size_t rfind(const StringPiece& self, char c, size_t pos) {
  return rfindT(self, c, pos);
}

size_t rfind(const StringPiece16& self, char16 c, size_t pos) {
  return rfindT(self, c, pos);
}

// 8-bit version using lookup table.
size_t find_first_of(const StringPiece& self,
                     const StringPiece& s,
                     size_t pos) {
  if (self.size() == 0 || s.size() == 0)
    return StringPiece::npos;

  // Avoid the cost of BuildLookupTable() for a single-character search.
  if (s.size() == 1)
    return find(self, s.data()[0], pos);

  bool lookup[UCHAR_MAX + 1] = { false };
  BuildLookupTable(s, lookup);
  for (size_t i = pos; i < self.size(); ++i) {
    if (lookup[static_cast<unsigned char>(self.data()[i])]) {
      return i;
    }
  }
  return StringPiece::npos;
}

// 16-bit brute force version.
size_t find_first_of(const StringPiece16& self,
                     const StringPiece16& s,
                     size_t pos) {
  StringPiece16::const_iterator found =
      std::find_first_of(self.begin() + pos, self.end(), s.begin(), s.end());
  if (found == self.end())
    return StringPiece16::npos;
  return found - self.begin();
}

// 8-bit version using lookup table.
size_t find_first_not_of(const StringPiece& self,
                         const StringPiece& s,
                         size_t pos) {
  if (self.size() == 0)
    return StringPiece::npos;

  if (s.size() == 0)
    return 0;

  // Avoid the cost of BuildLookupTable() for a single-character search.
  if (s.size() == 1)
    return find_first_not_of(self, s.data()[0], pos);

  bool lookup[UCHAR_MAX + 1] = { false };
  BuildLookupTable(s, lookup);
  for (size_t i = pos; i < self.size(); ++i) {
    if (!lookup[static_cast<unsigned char>(self.data()[i])]) {
      return i;
    }
  }
  return StringPiece::npos;
}

// 16-bit brute-force version.
BASE_EXPORT size_t find_first_not_of(const StringPiece16& self,
                                     const StringPiece16& s,
                                     size_t pos) {
  if (self.size() == 0)
    return StringPiece16::npos;

  for (size_t self_i = pos; self_i < self.size(); ++self_i) {
    bool found = false;
    for (size_t s_i = 0; s_i < s.size(); ++s_i) {
      if (self[self_i] == s[s_i]) {
        found = true;
        break;
      }
    }
    if (!found)
      return self_i;
  }
  return StringPiece16::npos;
}

template<typename STR>
size_t find_first_not_ofT(const BasicStringPiece<STR>& self,
                          typename STR::value_type c,
                          size_t pos) {
  if (self.size() == 0)
    return BasicStringPiece<STR>::npos;

  for (; pos < self.size(); ++pos) {
    if (self.data()[pos] != c) {
      return pos;
    }
  }
  return BasicStringPiece<STR>::npos;
}

size_t find_first_not_of(const StringPiece& self,
                         char c,
                         size_t pos) {
  return find_first_not_ofT(self, c, pos);
}

size_t find_first_not_of(const StringPiece16& self,
                         char16 c,
                         size_t pos) {
  return find_first_not_ofT(self, c, pos);
}

// 8-bit version using lookup table.
size_t find_last_of(const StringPiece& self, const StringPiece& s, size_t pos) {
  if (self.size() == 0 || s.size() == 0)
    return StringPiece::npos;

  // Avoid the cost of BuildLookupTable() for a single-character search.
  if (s.size() == 1)
    return rfind(self, s.data()[0], pos);

  bool lookup[UCHAR_MAX + 1] = { false };
  BuildLookupTable(s, lookup);
  for (size_t i = std::min(pos, self.size() - 1); ; --i) {
    if (lookup[static_cast<unsigned char>(self.data()[i])])
      return i;
    if (i == 0)
      break;
  }
  return StringPiece::npos;
}

// 16-bit brute-force version.
size_t find_last_of(const StringPiece16& self,
                    const StringPiece16& s,
                    size_t pos) {
  if (self.size() == 0)
    return StringPiece16::npos;

  for (size_t self_i = std::min(pos, self.size() - 1); ;
       --self_i) {
    for (size_t s_i = 0; s_i < s.size(); s_i++) {
      if (self.data()[self_i] == s[s_i])
        return self_i;
    }
    if (self_i == 0)
      break;
  }
  return StringPiece16::npos;
}

// 8-bit version using lookup table.
size_t find_last_not_of(const StringPiece& self,
                        const StringPiece& s,
                        size_t pos) {
  if (self.size() == 0)
    return StringPiece::npos;

  size_t i = std::min(pos, self.size() - 1);
  if (s.size() == 0)
    return i;

  // Avoid the cost of BuildLookupTable() for a single-character search.
  if (s.size() == 1)
    return find_last_not_of(self, s.data()[0], pos);

  bool lookup[UCHAR_MAX + 1] = { false };
  BuildLookupTable(s, lookup);
  for (; ; --i) {
    if (!lookup[static_cast<unsigned char>(self.data()[i])])
      return i;
    if (i == 0)
      break;
  }
  return StringPiece::npos;
}

// 16-bit brute-force version.
size_t find_last_not_of(const StringPiece16& self,
                        const StringPiece16& s,
                        size_t pos) {
  if (self.size() == 0)
    return StringPiece::npos;

  for (size_t self_i = std::min(pos, self.size() - 1); ; --self_i) {
    bool found = false;
    for (size_t s_i = 0; s_i < s.size(); s_i++) {
      if (self.data()[self_i] == s[s_i]) {
        found = true;
        break;
      }
    }
    if (!found)
      return self_i;
    if (self_i == 0)
      break;
  }
  return StringPiece16::npos;
}

template<typename STR>
size_t find_last_not_ofT(const BasicStringPiece<STR>& self,
                         typename STR::value_type c,
                         size_t pos) {
  if (self.size() == 0)
    return BasicStringPiece<STR>::npos;

  for (size_t i = std::min(pos, self.size() - 1); ; --i) {
    if (self.data()[i] != c)
      return i;
    if (i == 0)
      break;
  }
  return BasicStringPiece<STR>::npos;
}

size_t find_last_not_of(const StringPiece& self,
                        char c,
                        size_t pos) {
  return find_last_not_ofT(self, c, pos);
}

size_t find_last_not_of(const StringPiece16& self,
                        char16 c,
                        size_t pos) {
  return find_last_not_ofT(self, c, pos);
}

template<typename STR>
BasicStringPiece<STR> substrT(const BasicStringPiece<STR>& self,
                              size_t pos,
                              size_t n) {
  if (pos > self.size()) pos = self.size();
  if (n > self.size() - pos) n = self.size() - pos;
  return BasicStringPiece<STR>(self.data() + pos, n);
}

StringPiece substr(const StringPiece& self,
                   size_t pos,
                   size_t n) {
  return substrT(self, pos, n);
}

StringPiece16 substr(const StringPiece16& self,
                     size_t pos,
                     size_t n) {
  return substrT(self, pos, n);
}

#if DCHECK_IS_ON()
void AssertIteratorsInOrder(std::string::const_iterator begin,
                            std::string::const_iterator end) {
  DCHECK(begin <= end) << "StringPiece iterators swapped or invalid.";
}
void AssertIteratorsInOrder(string16::const_iterator begin,
                            string16::const_iterator end) {
  DCHECK(begin <= end) << "StringPiece iterators swapped or invalid.";
}
#endif

}  // namespace internal
}  // namespace base
