// 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"
#include "base/strings/utf_string_conversions.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

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

std::ostream& operator<<(std::ostream& o, const StringPiece16& piece) {
  return o << UTF16ToUTF8(piece);
}

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) {
  // Use the faster std::find() if searching for a single character.
  StringPiece16::const_iterator found =
      s.size() == 1 ? std::find(self.begin() + pos, self.end(), s[0])
                    : 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 (auto c : s) {
      if (self[self_i] == c) {
        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 (auto c : s) {
      if (self.data()[self_i] == c)
        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 (auto c : s) {
      if (self.data()[self_i] == c) {
        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
