blob: b0e45eea6c53f8eb04f76214dc4a11b7914d61ee [file] [log] [blame]
// Copyright 2006-2008 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.
#ifndef MINI_CHROMIUM_BASE_STRINGS_STRING_PIECE_H_
#define MINI_CHROMIUM_BASE_STRINGS_STRING_PIECE_H_
#include <algorithm>
#include <iterator>
#include <ostream>
#include <string>
#include "base/strings/string16.h"
namespace base {
template<typename StringType>
class BasicStringPiece {
public:
typedef typename StringType::traits_type traits_type;
typedef typename StringType::value_type value_type;
typedef typename StringType::size_type size_type;
typedef typename StringType::difference_type difference_type;
typedef const value_type& reference;
typedef const value_type& const_reference;
typedef const value_type* pointer;
typedef const value_type* const_pointer;
typedef const value_type* const_iterator;
typedef std::reverse_iterator<const_iterator> const_reverse_iterator;
static const size_type npos;
BasicStringPiece()
: pointer_(NULL),
length_(0) {
}
BasicStringPiece(const value_type* string)
: pointer_(string),
length_((string == NULL) ? 0 : traits_type::length(string)) {
}
BasicStringPiece(const StringType& string)
: pointer_(string.data()),
length_(string.size()) {
}
BasicStringPiece(const value_type* offset, size_type length)
: pointer_(offset),
length_(length) {
}
BasicStringPiece(const typename StringType::const_iterator& begin,
const typename StringType::const_iterator& end)
: pointer_((end > begin) ? &(*begin) : NULL),
length_((end > begin) ? static_cast<size_type>(end - begin) : 0) {
}
value_type operator[](size_type index) const { return pointer_[index]; }
const value_type* data() const { return pointer_; }
const_iterator begin() const { return pointer_; }
const_iterator end() const { return pointer_ + length_; }
const_reverse_iterator rbegin() const {
return const_reverse_iterator(pointer_ + length_);
}
const_reverse_iterator rend() const {
return const_reverse_iterator(pointer_);
}
bool empty() const { return length_ == 0; }
size_type size() const { return length_; }
size_type length() const { return length_; }
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 StringType::traits_type::compare(p, p2, N);
}
void clear() {
pointer_ = NULL;
length_ = 0;
}
int compare(const BasicStringPiece<StringType>& that) const {
int result = traits_type::compare(pointer_,
that.pointer_,
std::min(length_, that.length_));
if (result == 0) {
if (length_ < that.length_) {
result = -1;
} else if (length_ > that.length_) {
result = 1;
}
}
return result;
}
BasicStringPiece<StringType> substr(size_type position = 0,
size_type count = npos) const {
position = std::min(position, size());
count = std::min(count, size() - position);
return BasicStringPiece<StringType>(data() + position, count);
}
size_type copy(value_type* dest,
size_type count,
size_type position = 0) const {
size_type ret = std::min(size() - position, count);
traits_type::copy(dest, data() + position, ret);
return ret;
}
size_type find(const BasicStringPiece<StringType>& str, size_type pos) const {
if (pos >= size()) {
return npos;
}
const_iterator result = std::search(begin() + pos,
end(),
str.begin(),
str.end());
size_type xpos = static_cast<size_type>(result - begin());
return xpos + str.size() <= size() ? xpos : npos;
}
size_type find(value_type c, size_type pos) const {
if (pos >= size()) {
return npos;
}
const_iterator result = std::find(begin() + pos, end(), c);
return result != end() ? static_cast<size_type>(result - begin()) : npos;
}
void set(const value_type* string) {
pointer_ = string;
length_ = string ? traits_type::length(string) : 0;
}
StringType as_string() const {
return empty() ? StringType() : StringType(data(), size());
}
private:
const value_type* pointer_;
size_type length_;
};
template <typename StringType>
const typename BasicStringPiece<StringType>::size_type
BasicStringPiece<StringType>::npos = StringType::npos;
template<typename StringType>
std::ostream& operator<<(std::ostream& ostream,
const BasicStringPiece<StringType>& string_piece) {
ostream.write(string_piece.data(), string_piece.size());
return ostream;
}
typedef BasicStringPiece<std::string> StringPiece;
typedef BasicStringPiece<string16> StringPiece16;
inline 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;
}
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;
}
// This hash function is copied from base/strings/string16.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;
struct StringPieceHash {
std::size_t operator()(const StringPiece& sp) const {
HASH_STRING_PIECE(StringPiece, sp);
}
};
struct StringPiece16Hash {
std::size_t operator()(const StringPiece16& sp16) const {
HASH_STRING_PIECE(StringPiece16, sp16);
}
};
} // namespace base;
#endif // MINI_CHROMIUM_BASE_STRINGS_STRING_PIECE_H_