// 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.h with modifications
//
// A string-like object that points to a sized piece of memory.
//
// Functions or methods may use const StringPiece& parameters to accept either
// a "const char*" or a "string" value that will be implicitly converted to
// a StringPiece.  The implicit conversion means that it is often appropriate
// to include this .h file in other files rather than forward-declaring
// StringPiece as would be appropriate for most other Google classes.
//
// Systematic usage of StringPiece is encouraged as it will reduce unnecessary
// conversions from "const char*" to "string" and back again.
//
// StringPiece16 is similar to StringPiece but for base::string16 instead of
// std::string. We do not define as large of a subset of the STL functions
// from basic_string as in StringPiece, but this can be changed if these
// functions (find, find_first_of, etc.) are found to be useful in this context.
//

#ifndef BASE_STRINGS_STRING_PIECE_H_
#define BASE_STRINGS_STRING_PIECE_H_

#include <stddef.h>

#include <iosfwd>
#include <string>

#include "base/base_export.h"
#include "base/basictypes.h"
#include "base/containers/hash_tables.h"
#include "base/strings/string16.h"

namespace base {

template <typename STRING_TYPE> class BasicStringPiece;
typedef BasicStringPiece<std::string> StringPiece;
typedef BasicStringPiece<string16> StringPiece16;

namespace internal {

// Defines the types, methods, operators, and data members common to both
// StringPiece and StringPiece16. Do not refer to this class directly, but
// rather to BasicStringPiece, StringPiece, or StringPiece16.
template <typename STRING_TYPE> class StringPieceDetail {
 public:
  // standard STL container boilerplate
  typedef size_t size_type;
  typedef typename STRING_TYPE::value_type value_type;
  typedef const value_type* pointer;
  typedef const value_type& reference;
  typedef const value_type& const_reference;
  typedef ptrdiff_t difference_type;
  typedef const value_type* const_iterator;
  typedef std::reverse_iterator<const_iterator> const_reverse_iterator;

  static const size_type npos;

 public:
  // We provide non-explicit singleton constructors so users can pass
  // in a "const char*" or a "string" wherever a "StringPiece" is
  // expected (likewise for char16, string16, StringPiece16).
  StringPieceDetail() : ptr_(NULL), length_(0) {}
  StringPieceDetail(const value_type* str)
      : ptr_(str),
        length_((str == NULL) ? 0 : STRING_TYPE::traits_type::length(str)) {}
  StringPieceDetail(const STRING_TYPE& str)
      : ptr_(str.data()), length_(str.size()) {}
  StringPieceDetail(const value_type* offset, size_type len)
      : ptr_(offset), length_(len) {}
  StringPieceDetail(const typename STRING_TYPE::const_iterator& begin,
                    const typename STRING_TYPE::const_iterator& end)
      : ptr_((end > begin) ? &(*begin) : NULL),
        length_((end > begin) ? (size_type)(end - begin) : 0) {}

  // data() may return a pointer to a buffer with embedded NULs, and the
  // returned buffer may or may not be null terminated.  Therefore it is
  // typically a mistake to pass data() to a routine that expects a NUL
  // terminated string.
  const value_type* data() const { return ptr_; }
  size_type size() const { return length_; }
  size_type length() const { return length_; }
  bool empty() const { return length_ == 0; }

  void clear() {
    ptr_ = NULL;
    length_ = 0;
  }
  void set(const value_type* data, size_type len) {
    ptr_ = data;
    length_ = len;
  }
  void set(const value_type* str) {
    ptr_ = str;
    length_ = str ? STRING_TYPE::traits_type::length(str) : 0;
  }

  value_type operator[](size_type i) const { return ptr_[i]; }

  void remove_prefix(size_type n) {
    ptr_ += n;
    length_ -= n;
  }

  void remove_suffix(size_type n) {
    length_ -= n;
  }

  int compare(const BasicStringPiece<STRING_TYPE>& x) const {
    int r = wordmemcmp(
        ptr_, x.ptr_, (length_ < x.length_ ? length_ : x.length_));
    if (r == 0) {
      if (length_ < x.length_) r = -1;
      else if (length_ > x.length_) r = +1;
    }
    return r;
  }

  STRING_TYPE as_string() const {
    // std::string doesn't like to take a NULL pointer even with a 0 size.
    return empty() ? STRING_TYPE() : STRING_TYPE(data(), size());
  }

  const_iterator begin() const { return ptr_; }
  const_iterator end() const { return ptr_ + length_; }
  const_reverse_iterator rbegin() const {
    return const_reverse_iterator(ptr_ + length_);
  }
  const_reverse_iterator rend() const {
    return const_reverse_iterator(ptr_);
  }

  size_type max_size() const { return length_; }
  size_type capacity() const { return length_; }

  static int wordmemcmp(const value_type* p,
                        const value_type* p2,
                        size_type N) {
    return STRING_TYPE::traits_type::compare(p, p2, N);
  }

 protected:
  const value_type* ptr_;
  size_type     length_;
};

template <typename STRING_TYPE>
const typename StringPieceDetail<STRING_TYPE>::size_type
StringPieceDetail<STRING_TYPE>::npos =
    typename StringPieceDetail<STRING_TYPE>::size_type(-1);

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

BASE_EXPORT void CopyToString(const StringPiece& self, std::string* target);
BASE_EXPORT void AppendToString(const StringPiece& self, std::string* target);
BASE_EXPORT StringPieceDetail<std::string>::size_type copy(
    const StringPiece& self,
    char* buf,
    StringPieceDetail<std::string>::size_type n,
    StringPieceDetail<std::string>::size_type pos);
BASE_EXPORT StringPieceDetail<std::string>::size_type find(
    const StringPiece& self,
    const StringPiece& s,
    StringPieceDetail<std::string>::size_type pos);
BASE_EXPORT StringPieceDetail<std::string>::size_type find(
    const StringPiece& self,
    char c,
    StringPieceDetail<std::string>::size_type pos);
BASE_EXPORT StringPieceDetail<std::string>::size_type rfind(
    const StringPiece& self,
    const StringPiece& s,
    StringPieceDetail<std::string>::size_type pos);
BASE_EXPORT StringPieceDetail<std::string>::size_type rfind(
    const StringPiece& self,
    char c,
    StringPieceDetail<std::string>::size_type pos);
BASE_EXPORT StringPieceDetail<std::string>::size_type find_first_of(
    const StringPiece& self,
    const StringPiece& s,
    StringPieceDetail<std::string>::size_type pos);
BASE_EXPORT StringPieceDetail<std::string>::size_type find_first_not_of(
    const StringPiece& self,
    const StringPiece& s,
    StringPieceDetail<std::string>::size_type pos);
BASE_EXPORT StringPieceDetail<std::string>::size_type find_first_not_of(
    const StringPiece& self,
    char c,
    StringPieceDetail<std::string>::size_type pos);
BASE_EXPORT StringPieceDetail<std::string>::size_type find_last_of(
    const StringPiece& self,
    const StringPiece& s,
    StringPieceDetail<std::string>::size_type pos);
BASE_EXPORT StringPieceDetail<std::string>::size_type find_last_of(
    const StringPiece& self,
    char c,
    StringPieceDetail<std::string>::size_type pos);
BASE_EXPORT StringPieceDetail<std::string>::size_type find_last_not_of(
    const StringPiece& self,
    const StringPiece& s,
    StringPieceDetail<std::string>::size_type pos);
BASE_EXPORT StringPieceDetail<std::string>::size_type find_last_not_of(
    const StringPiece& self,
    char c,
    StringPieceDetail<std::string>::size_type pos);
BASE_EXPORT StringPiece substr(const StringPiece& self,
                               StringPieceDetail<std::string>::size_type pos,
                               StringPieceDetail<std::string>::size_type n);
}  // namespace internal

// Defines the template type that is instantiated as either StringPiece or
// StringPiece16.
template <typename STRING_TYPE> class BasicStringPiece :
    public internal::StringPieceDetail<STRING_TYPE> {
 public:
  typedef typename internal::StringPieceDetail<STRING_TYPE>::value_type
      value_type;
  typedef typename internal::StringPieceDetail<STRING_TYPE>::size_type
      size_type;

  BasicStringPiece() {}
  BasicStringPiece(const value_type*str)
      : internal::StringPieceDetail<STRING_TYPE>(str) {}
  BasicStringPiece(const STRING_TYPE& str)
      : internal::StringPieceDetail<STRING_TYPE>(str) {}
  BasicStringPiece(const value_type* offset, size_type len)
      : internal::StringPieceDetail<STRING_TYPE>(offset, len) {}
  BasicStringPiece(const typename STRING_TYPE::const_iterator& begin,
                   const typename STRING_TYPE::const_iterator& end)
      : internal::StringPieceDetail<STRING_TYPE>(begin, end) {}
};

// Specializes BasicStringPiece for std::string to add a few operations that
// are not needed for string16.
template <> class BasicStringPiece<std::string> :
    public internal::StringPieceDetail<std::string> {
 public:
  BasicStringPiece() {}
  BasicStringPiece(const char* str)
      : internal::StringPieceDetail<std::string>(str) {}
  BasicStringPiece(const std::string& str)
      : internal::StringPieceDetail<std::string>(str) {}
  BasicStringPiece(const char* offset, size_type len)
      : internal::StringPieceDetail<std::string>(offset, len) {}
  BasicStringPiece(const std::string::const_iterator& begin,
                   const std::string::const_iterator& end)
      : internal::StringPieceDetail<std::string>(begin, end) {}

  // Prevent the following overload of set() from hiding the definitions in the
  // base class.
  using internal::StringPieceDetail<std::string>::set;

  void set(const void* data, size_type len) {
    ptr_ = reinterpret_cast<const value_type*>(data);
    length_ = len;
  }

  void CopyToString(std::string* target) const {
    internal::CopyToString(*this, target);
  }

  void AppendToString(std::string* target) const {
    internal::AppendToString(*this, target);
  }

  // Does "this" start with "x"
  bool starts_with(const BasicStringPiece& x) const {
    return ((length_ >= x.length_) &&
            (wordmemcmp(ptr_, x.ptr_, x.length_) == 0));
  }

  // Does "this" end with "x"
  bool ends_with(const BasicStringPiece& x) const {
    return ((length_ >= x.length_) &&
            (wordmemcmp(ptr_ + (length_-x.length_), x.ptr_, x.length_) == 0));
  }

  size_type copy(char* buf, size_type n, size_type pos = 0) const {
    return internal::copy(*this, buf, n, pos);
  }

  size_type find(const BasicStringPiece& s, size_type pos = 0) const {
    return internal::find(*this, s, pos);
  }

  size_type find(char c, size_type pos = 0) const {
    return internal::find(*this, c, pos);
  }

  size_type rfind(const BasicStringPiece& s, size_type pos = npos) const {
    return internal::rfind(*this, s, pos);
  }

  size_type rfind(char c, size_type pos = npos) const {
    return internal::rfind(*this, c, pos);
  }

  size_type find_first_of(const BasicStringPiece& s, size_type pos = 0) const {
    return internal::find_first_of(*this, s, pos);
  }

  size_type find_first_of(char c, size_type pos = 0) const {
    return find(c, pos);
  }

  size_type find_first_not_of(const BasicStringPiece& s,
                              size_type pos = 0) const {
    return internal::find_first_not_of(*this, s, pos);
  }

  size_type find_first_not_of(char c, size_type pos = 0) const {
    return internal::find_first_not_of(*this, c, pos);
  }

  size_type find_last_of(const BasicStringPiece& s,
                         size_type pos = npos) const {
    return internal::find_last_of(*this, s, pos);
  }

  size_type find_last_of(char c, size_type pos = npos) const {
    return rfind(c, pos);
  }

  size_type find_last_not_of(const BasicStringPiece& s,
                             size_type pos = npos) const {
    return internal::find_last_not_of(*this, s, pos);
  }

  size_type find_last_not_of(char c, size_type pos = npos) const {
    return internal::find_last_not_of(*this, c, pos);
  }

  BasicStringPiece substr(size_type pos, size_type n = npos) const {
    return internal::substr(*this, pos, n);
  }
};

// MSVC doesn't like complex extern templates and DLLs.
#if !defined(COMPILER_MSVC)
// We can't explicitly declare the std::string instantiation here because it was
// already instantiated when specialized, above. Not only is it a no-op, but
// currently it also crashes Clang (see http://crbug.com/107412).
extern template class BASE_EXPORT BasicStringPiece<string16>;
#endif

BASE_EXPORT bool operator==(const StringPiece& x, const StringPiece& y);

inline bool operator!=(const StringPiece& x, const StringPiece& y) {
  return !(x == y);
}

inline bool operator<(const StringPiece& x, const StringPiece& y) {
  const int r = StringPiece::wordmemcmp(
      x.data(), y.data(), (x.size() < y.size() ? x.size() : y.size()));
  return ((r < 0) || ((r == 0) && (x.size() < y.size())));
}

inline bool operator>(const StringPiece& x, const StringPiece& y) {
  return y < x;
}

inline bool operator<=(const StringPiece& x, const StringPiece& y) {
  return !(x > y);
}

inline bool operator>=(const StringPiece& x, const StringPiece& y) {
  return !(x < y);
}

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

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

inline bool operator!=(const StringPiece16& x, const StringPiece16& y) {
  return !(x == y);
}

inline bool operator<(const StringPiece16& x, const StringPiece16& y) {
  const int r = StringPiece16::wordmemcmp(
      x.data(), y.data(), (x.size() < y.size() ? x.size() : y.size()));
  return ((r < 0) || ((r == 0) && (x.size() < y.size())));
}

inline bool operator>(const StringPiece16& x, const StringPiece16& y) {
  return y < x;
}

inline bool operator<=(const StringPiece16& x, const StringPiece16& y) {
  return !(x > y);
}

inline bool operator>=(const StringPiece16& x, const StringPiece16& y) {
  return !(x < y);
}

BASE_EXPORT std::ostream& operator<<(std::ostream& o,
                                     const StringPiece& piece);

}  // namespace base

// We provide appropriate hash functions so StringPiece and StringPiece16 can
// be used as keys in hash sets and maps.

// This hash function is copied from base/containers/hash_tables.h. We don't
// use the ones already defined for string and string16 directly because it
// would require the string constructors to be called, which we don't want.
#define HASH_STRING_PIECE(StringPieceType, string_piece)                \
  std::size_t result = 0;                                               \
  for (StringPieceType::const_iterator i = string_piece.begin();        \
       i != string_piece.end(); ++i)                                    \
    result = (result * 131) + *i;                                       \
  return result;                                                        \

namespace BASE_HASH_NAMESPACE {
#if defined(COMPILER_GCC)

template<>
struct hash<base::StringPiece> {
  std::size_t operator()(const base::StringPiece& sp) const {
    HASH_STRING_PIECE(base::StringPiece, sp);
  }
};
template<>
struct hash<base::StringPiece16> {
  std::size_t operator()(const base::StringPiece16& sp16) const {
    HASH_STRING_PIECE(base::StringPiece16, sp16);
  }
};

#elif defined(COMPILER_MSVC)

inline size_t hash_value(const base::StringPiece& sp) {
  HASH_STRING_PIECE(base::StringPiece, sp);
}
inline size_t hash_value(const base::StringPiece16& sp16) {
  HASH_STRING_PIECE(base::StringPiece16, sp16);
}

#endif  // COMPILER

}  // namespace BASE_HASH_NAMESPACE

#endif  // BASE_STRINGS_STRING_PIECE_H_
