// 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;
|
typedef BasicStringPiece<std::wstring> WStringPiece;
|
|
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_
|