// 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 #include #include #include #include "base/strings/string16.h" namespace base { template 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_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(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& 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 substr(size_type position = 0, size_type count = npos) const { position = std::min(position, size()); count = std::min(count, size() - position); return BasicStringPiece(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& 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(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(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 const typename BasicStringPiece::size_type BasicStringPiece::npos = StringType::npos; template std::ostream& operator<<(std::ostream& ostream, const BasicStringPiece& string_piece) { ostream.write(string_piece.data(), string_piece.size()); return ostream; } typedef BasicStringPiece StringPiece; typedef BasicStringPiece StringPiece16; typedef BasicStringPiece 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_