1*635a8641SAndroid Build Coastguard Worker // Copyright (c) 2012 The Chromium Authors. All rights reserved. 2*635a8641SAndroid Build Coastguard Worker // Use of this source code is governed by a BSD-style license that can be 3*635a8641SAndroid Build Coastguard Worker // found in the LICENSE file. 4*635a8641SAndroid Build Coastguard Worker // Copied from strings/stringpiece.h with modifications 5*635a8641SAndroid Build Coastguard Worker // 6*635a8641SAndroid Build Coastguard Worker // A string-like object that points to a sized piece of memory. 7*635a8641SAndroid Build Coastguard Worker // 8*635a8641SAndroid Build Coastguard Worker // You can use StringPiece as a function or method parameter. A StringPiece 9*635a8641SAndroid Build Coastguard Worker // parameter can receive a double-quoted string literal argument, a "const 10*635a8641SAndroid Build Coastguard Worker // char*" argument, a string argument, or a StringPiece argument with no data 11*635a8641SAndroid Build Coastguard Worker // copying. Systematic use of StringPiece for arguments reduces data 12*635a8641SAndroid Build Coastguard Worker // copies and strlen() calls. 13*635a8641SAndroid Build Coastguard Worker // 14*635a8641SAndroid Build Coastguard Worker // Prefer passing StringPieces by value: 15*635a8641SAndroid Build Coastguard Worker // void MyFunction(StringPiece arg); 16*635a8641SAndroid Build Coastguard Worker // If circumstances require, you may also pass by const reference: 17*635a8641SAndroid Build Coastguard Worker // void MyFunction(const StringPiece& arg); // not preferred 18*635a8641SAndroid Build Coastguard Worker // Both of these have the same lifetime semantics. Passing by value 19*635a8641SAndroid Build Coastguard Worker // generates slightly smaller code. For more discussion, Googlers can see 20*635a8641SAndroid Build Coastguard Worker // the thread go/stringpiecebyvalue on c-users. 21*635a8641SAndroid Build Coastguard Worker 22*635a8641SAndroid Build Coastguard Worker #ifndef BASE_STRINGS_STRING_PIECE_H_ 23*635a8641SAndroid Build Coastguard Worker #define BASE_STRINGS_STRING_PIECE_H_ 24*635a8641SAndroid Build Coastguard Worker 25*635a8641SAndroid Build Coastguard Worker #include <stddef.h> 26*635a8641SAndroid Build Coastguard Worker 27*635a8641SAndroid Build Coastguard Worker #include <iosfwd> 28*635a8641SAndroid Build Coastguard Worker #include <string> 29*635a8641SAndroid Build Coastguard Worker 30*635a8641SAndroid Build Coastguard Worker #include "base/base_export.h" 31*635a8641SAndroid Build Coastguard Worker #include "base/logging.h" 32*635a8641SAndroid Build Coastguard Worker #include "base/strings/char_traits.h" 33*635a8641SAndroid Build Coastguard Worker #include "base/strings/string16.h" 34*635a8641SAndroid Build Coastguard Worker #include "base/strings/string_piece_forward.h" 35*635a8641SAndroid Build Coastguard Worker 36*635a8641SAndroid Build Coastguard Worker namespace base { 37*635a8641SAndroid Build Coastguard Worker 38*635a8641SAndroid Build Coastguard Worker // internal -------------------------------------------------------------------- 39*635a8641SAndroid Build Coastguard Worker 40*635a8641SAndroid Build Coastguard Worker // Many of the StringPiece functions use different implementations for the 41*635a8641SAndroid Build Coastguard Worker // 8-bit and 16-bit versions, and we don't want lots of template expansions in 42*635a8641SAndroid Build Coastguard Worker // this (very common) header that will slow down compilation. 43*635a8641SAndroid Build Coastguard Worker // 44*635a8641SAndroid Build Coastguard Worker // So here we define overloaded functions called by the StringPiece template. 45*635a8641SAndroid Build Coastguard Worker // For those that share an implementation, the two versions will expand to a 46*635a8641SAndroid Build Coastguard Worker // template internal to the .cc file. 47*635a8641SAndroid Build Coastguard Worker namespace internal { 48*635a8641SAndroid Build Coastguard Worker 49*635a8641SAndroid Build Coastguard Worker BASE_EXPORT void CopyToString(const StringPiece& self, std::string* target); 50*635a8641SAndroid Build Coastguard Worker BASE_EXPORT void CopyToString(const StringPiece16& self, string16* target); 51*635a8641SAndroid Build Coastguard Worker 52*635a8641SAndroid Build Coastguard Worker BASE_EXPORT void AppendToString(const StringPiece& self, std::string* target); 53*635a8641SAndroid Build Coastguard Worker BASE_EXPORT void AppendToString(const StringPiece16& self, string16* target); 54*635a8641SAndroid Build Coastguard Worker 55*635a8641SAndroid Build Coastguard Worker BASE_EXPORT size_t copy(const StringPiece& self, 56*635a8641SAndroid Build Coastguard Worker char* buf, 57*635a8641SAndroid Build Coastguard Worker size_t n, 58*635a8641SAndroid Build Coastguard Worker size_t pos); 59*635a8641SAndroid Build Coastguard Worker BASE_EXPORT size_t copy(const StringPiece16& self, 60*635a8641SAndroid Build Coastguard Worker char16* buf, 61*635a8641SAndroid Build Coastguard Worker size_t n, 62*635a8641SAndroid Build Coastguard Worker size_t pos); 63*635a8641SAndroid Build Coastguard Worker 64*635a8641SAndroid Build Coastguard Worker BASE_EXPORT size_t find(const StringPiece& self, 65*635a8641SAndroid Build Coastguard Worker const StringPiece& s, 66*635a8641SAndroid Build Coastguard Worker size_t pos); 67*635a8641SAndroid Build Coastguard Worker BASE_EXPORT size_t find(const StringPiece16& self, 68*635a8641SAndroid Build Coastguard Worker const StringPiece16& s, 69*635a8641SAndroid Build Coastguard Worker size_t pos); 70*635a8641SAndroid Build Coastguard Worker BASE_EXPORT size_t find(const StringPiece& self, 71*635a8641SAndroid Build Coastguard Worker char c, 72*635a8641SAndroid Build Coastguard Worker size_t pos); 73*635a8641SAndroid Build Coastguard Worker BASE_EXPORT size_t find(const StringPiece16& self, 74*635a8641SAndroid Build Coastguard Worker char16 c, 75*635a8641SAndroid Build Coastguard Worker size_t pos); 76*635a8641SAndroid Build Coastguard Worker 77*635a8641SAndroid Build Coastguard Worker BASE_EXPORT size_t rfind(const StringPiece& self, 78*635a8641SAndroid Build Coastguard Worker const StringPiece& s, 79*635a8641SAndroid Build Coastguard Worker size_t pos); 80*635a8641SAndroid Build Coastguard Worker BASE_EXPORT size_t rfind(const StringPiece16& self, 81*635a8641SAndroid Build Coastguard Worker const StringPiece16& s, 82*635a8641SAndroid Build Coastguard Worker size_t pos); 83*635a8641SAndroid Build Coastguard Worker BASE_EXPORT size_t rfind(const StringPiece& self, 84*635a8641SAndroid Build Coastguard Worker char c, 85*635a8641SAndroid Build Coastguard Worker size_t pos); 86*635a8641SAndroid Build Coastguard Worker BASE_EXPORT size_t rfind(const StringPiece16& self, 87*635a8641SAndroid Build Coastguard Worker char16 c, 88*635a8641SAndroid Build Coastguard Worker size_t pos); 89*635a8641SAndroid Build Coastguard Worker 90*635a8641SAndroid Build Coastguard Worker BASE_EXPORT size_t find_first_of(const StringPiece& self, 91*635a8641SAndroid Build Coastguard Worker const StringPiece& s, 92*635a8641SAndroid Build Coastguard Worker size_t pos); 93*635a8641SAndroid Build Coastguard Worker BASE_EXPORT size_t find_first_of(const StringPiece16& self, 94*635a8641SAndroid Build Coastguard Worker const StringPiece16& s, 95*635a8641SAndroid Build Coastguard Worker size_t pos); 96*635a8641SAndroid Build Coastguard Worker 97*635a8641SAndroid Build Coastguard Worker BASE_EXPORT size_t find_first_not_of(const StringPiece& self, 98*635a8641SAndroid Build Coastguard Worker const StringPiece& s, 99*635a8641SAndroid Build Coastguard Worker size_t pos); 100*635a8641SAndroid Build Coastguard Worker BASE_EXPORT size_t find_first_not_of(const StringPiece16& self, 101*635a8641SAndroid Build Coastguard Worker const StringPiece16& s, 102*635a8641SAndroid Build Coastguard Worker size_t pos); 103*635a8641SAndroid Build Coastguard Worker BASE_EXPORT size_t find_first_not_of(const StringPiece& self, 104*635a8641SAndroid Build Coastguard Worker char c, 105*635a8641SAndroid Build Coastguard Worker size_t pos); 106*635a8641SAndroid Build Coastguard Worker BASE_EXPORT size_t find_first_not_of(const StringPiece16& self, 107*635a8641SAndroid Build Coastguard Worker char16 c, 108*635a8641SAndroid Build Coastguard Worker size_t pos); 109*635a8641SAndroid Build Coastguard Worker 110*635a8641SAndroid Build Coastguard Worker BASE_EXPORT size_t find_last_of(const StringPiece& self, 111*635a8641SAndroid Build Coastguard Worker const StringPiece& s, 112*635a8641SAndroid Build Coastguard Worker size_t pos); 113*635a8641SAndroid Build Coastguard Worker BASE_EXPORT size_t find_last_of(const StringPiece16& self, 114*635a8641SAndroid Build Coastguard Worker const StringPiece16& s, 115*635a8641SAndroid Build Coastguard Worker size_t pos); 116*635a8641SAndroid Build Coastguard Worker BASE_EXPORT size_t find_last_of(const StringPiece& self, 117*635a8641SAndroid Build Coastguard Worker char c, 118*635a8641SAndroid Build Coastguard Worker size_t pos); 119*635a8641SAndroid Build Coastguard Worker BASE_EXPORT size_t find_last_of(const StringPiece16& self, 120*635a8641SAndroid Build Coastguard Worker char16 c, 121*635a8641SAndroid Build Coastguard Worker size_t pos); 122*635a8641SAndroid Build Coastguard Worker 123*635a8641SAndroid Build Coastguard Worker BASE_EXPORT size_t find_last_not_of(const StringPiece& self, 124*635a8641SAndroid Build Coastguard Worker const StringPiece& s, 125*635a8641SAndroid Build Coastguard Worker size_t pos); 126*635a8641SAndroid Build Coastguard Worker BASE_EXPORT size_t find_last_not_of(const StringPiece16& self, 127*635a8641SAndroid Build Coastguard Worker const StringPiece16& s, 128*635a8641SAndroid Build Coastguard Worker size_t pos); 129*635a8641SAndroid Build Coastguard Worker BASE_EXPORT size_t find_last_not_of(const StringPiece16& self, 130*635a8641SAndroid Build Coastguard Worker char16 c, 131*635a8641SAndroid Build Coastguard Worker size_t pos); 132*635a8641SAndroid Build Coastguard Worker BASE_EXPORT size_t find_last_not_of(const StringPiece& self, 133*635a8641SAndroid Build Coastguard Worker char c, 134*635a8641SAndroid Build Coastguard Worker size_t pos); 135*635a8641SAndroid Build Coastguard Worker 136*635a8641SAndroid Build Coastguard Worker BASE_EXPORT StringPiece substr(const StringPiece& self, 137*635a8641SAndroid Build Coastguard Worker size_t pos, 138*635a8641SAndroid Build Coastguard Worker size_t n); 139*635a8641SAndroid Build Coastguard Worker BASE_EXPORT StringPiece16 substr(const StringPiece16& self, 140*635a8641SAndroid Build Coastguard Worker size_t pos, 141*635a8641SAndroid Build Coastguard Worker size_t n); 142*635a8641SAndroid Build Coastguard Worker 143*635a8641SAndroid Build Coastguard Worker #if DCHECK_IS_ON() 144*635a8641SAndroid Build Coastguard Worker // Asserts that begin <= end to catch some errors with iterator usage. 145*635a8641SAndroid Build Coastguard Worker BASE_EXPORT void AssertIteratorsInOrder(std::string::const_iterator begin, 146*635a8641SAndroid Build Coastguard Worker std::string::const_iterator end); 147*635a8641SAndroid Build Coastguard Worker BASE_EXPORT void AssertIteratorsInOrder(string16::const_iterator begin, 148*635a8641SAndroid Build Coastguard Worker string16::const_iterator end); 149*635a8641SAndroid Build Coastguard Worker #endif 150*635a8641SAndroid Build Coastguard Worker 151*635a8641SAndroid Build Coastguard Worker } // namespace internal 152*635a8641SAndroid Build Coastguard Worker 153*635a8641SAndroid Build Coastguard Worker // BasicStringPiece ------------------------------------------------------------ 154*635a8641SAndroid Build Coastguard Worker 155*635a8641SAndroid Build Coastguard Worker // Defines the types, methods, operators, and data members common to both 156*635a8641SAndroid Build Coastguard Worker // StringPiece and StringPiece16. Do not refer to this class directly, but 157*635a8641SAndroid Build Coastguard Worker // rather to BasicStringPiece, StringPiece, or StringPiece16. 158*635a8641SAndroid Build Coastguard Worker // 159*635a8641SAndroid Build Coastguard Worker // This is templatized by string class type rather than character type, so 160*635a8641SAndroid Build Coastguard Worker // BasicStringPiece<std::string> or BasicStringPiece<base::string16>. 161*635a8641SAndroid Build Coastguard Worker template <typename STRING_TYPE> class BasicStringPiece { 162*635a8641SAndroid Build Coastguard Worker public: 163*635a8641SAndroid Build Coastguard Worker // Standard STL container boilerplate. 164*635a8641SAndroid Build Coastguard Worker typedef size_t size_type; 165*635a8641SAndroid Build Coastguard Worker typedef typename STRING_TYPE::value_type value_type; 166*635a8641SAndroid Build Coastguard Worker typedef const value_type* pointer; 167*635a8641SAndroid Build Coastguard Worker typedef const value_type& reference; 168*635a8641SAndroid Build Coastguard Worker typedef const value_type& const_reference; 169*635a8641SAndroid Build Coastguard Worker typedef ptrdiff_t difference_type; 170*635a8641SAndroid Build Coastguard Worker typedef const value_type* const_iterator; 171*635a8641SAndroid Build Coastguard Worker typedef std::reverse_iterator<const_iterator> const_reverse_iterator; 172*635a8641SAndroid Build Coastguard Worker 173*635a8641SAndroid Build Coastguard Worker static const size_type npos; 174*635a8641SAndroid Build Coastguard Worker 175*635a8641SAndroid Build Coastguard Worker public: 176*635a8641SAndroid Build Coastguard Worker // We provide non-explicit singleton constructors so users can pass 177*635a8641SAndroid Build Coastguard Worker // in a "const char*" or a "string" wherever a "StringPiece" is 178*635a8641SAndroid Build Coastguard Worker // expected (likewise for char16, string16, StringPiece16). BasicStringPiece()179*635a8641SAndroid Build Coastguard Worker constexpr BasicStringPiece() : ptr_(NULL), length_(0) {} 180*635a8641SAndroid Build Coastguard Worker // TODO(dcheng): Construction from nullptr is not allowed for 181*635a8641SAndroid Build Coastguard Worker // std::basic_string_view, so remove the special handling for it. 182*635a8641SAndroid Build Coastguard Worker // Note: This doesn't just use STRING_TYPE::traits_type::length(), since that 183*635a8641SAndroid Build Coastguard Worker // isn't constexpr until C++17. BasicStringPiece(const value_type * str)184*635a8641SAndroid Build Coastguard Worker constexpr BasicStringPiece(const value_type* str) 185*635a8641SAndroid Build Coastguard Worker : ptr_(str), length_(!str ? 0 : CharTraits<value_type>::length(str)) {} BasicStringPiece(const STRING_TYPE & str)186*635a8641SAndroid Build Coastguard Worker BasicStringPiece(const STRING_TYPE& str) 187*635a8641SAndroid Build Coastguard Worker : ptr_(str.data()), length_(str.size()) {} BasicStringPiece(const value_type * offset,size_type len)188*635a8641SAndroid Build Coastguard Worker constexpr BasicStringPiece(const value_type* offset, size_type len) 189*635a8641SAndroid Build Coastguard Worker : ptr_(offset), length_(len) {} BasicStringPiece(const typename STRING_TYPE::const_iterator & begin,const typename STRING_TYPE::const_iterator & end)190*635a8641SAndroid Build Coastguard Worker BasicStringPiece(const typename STRING_TYPE::const_iterator& begin, 191*635a8641SAndroid Build Coastguard Worker const typename STRING_TYPE::const_iterator& end) { 192*635a8641SAndroid Build Coastguard Worker #if DCHECK_IS_ON() 193*635a8641SAndroid Build Coastguard Worker // This assertion is done out-of-line to avoid bringing in logging.h and 194*635a8641SAndroid Build Coastguard Worker // instantiating logging macros for every instantiation. 195*635a8641SAndroid Build Coastguard Worker internal::AssertIteratorsInOrder(begin, end); 196*635a8641SAndroid Build Coastguard Worker #endif 197*635a8641SAndroid Build Coastguard Worker length_ = static_cast<size_t>(std::distance(begin, end)); 198*635a8641SAndroid Build Coastguard Worker 199*635a8641SAndroid Build Coastguard Worker // The length test before assignment is to avoid dereferencing an iterator 200*635a8641SAndroid Build Coastguard Worker // that may point to the end() of a string. 201*635a8641SAndroid Build Coastguard Worker ptr_ = length_ > 0 ? &*begin : nullptr; 202*635a8641SAndroid Build Coastguard Worker } 203*635a8641SAndroid Build Coastguard Worker 204*635a8641SAndroid Build Coastguard Worker // data() may return a pointer to a buffer with embedded NULs, and the 205*635a8641SAndroid Build Coastguard Worker // returned buffer may or may not be null terminated. Therefore it is 206*635a8641SAndroid Build Coastguard Worker // typically a mistake to pass data() to a routine that expects a NUL 207*635a8641SAndroid Build Coastguard Worker // terminated string. data()208*635a8641SAndroid Build Coastguard Worker constexpr const value_type* data() const { return ptr_; } size()209*635a8641SAndroid Build Coastguard Worker constexpr size_type size() const { return length_; } length()210*635a8641SAndroid Build Coastguard Worker constexpr size_type length() const { return length_; } empty()211*635a8641SAndroid Build Coastguard Worker bool empty() const { return length_ == 0; } 212*635a8641SAndroid Build Coastguard Worker clear()213*635a8641SAndroid Build Coastguard Worker void clear() { 214*635a8641SAndroid Build Coastguard Worker ptr_ = NULL; 215*635a8641SAndroid Build Coastguard Worker length_ = 0; 216*635a8641SAndroid Build Coastguard Worker } set(const value_type * data,size_type len)217*635a8641SAndroid Build Coastguard Worker void set(const value_type* data, size_type len) { 218*635a8641SAndroid Build Coastguard Worker ptr_ = data; 219*635a8641SAndroid Build Coastguard Worker length_ = len; 220*635a8641SAndroid Build Coastguard Worker } set(const value_type * str)221*635a8641SAndroid Build Coastguard Worker void set(const value_type* str) { 222*635a8641SAndroid Build Coastguard Worker ptr_ = str; 223*635a8641SAndroid Build Coastguard Worker length_ = str ? STRING_TYPE::traits_type::length(str) : 0; 224*635a8641SAndroid Build Coastguard Worker } 225*635a8641SAndroid Build Coastguard Worker 226*635a8641SAndroid Build Coastguard Worker constexpr value_type operator[](size_type i) const { 227*635a8641SAndroid Build Coastguard Worker CHECK(i < length_); 228*635a8641SAndroid Build Coastguard Worker return ptr_[i]; 229*635a8641SAndroid Build Coastguard Worker } 230*635a8641SAndroid Build Coastguard Worker front()231*635a8641SAndroid Build Coastguard Worker value_type front() const { 232*635a8641SAndroid Build Coastguard Worker CHECK_NE(0UL, length_); 233*635a8641SAndroid Build Coastguard Worker return ptr_[0]; 234*635a8641SAndroid Build Coastguard Worker } 235*635a8641SAndroid Build Coastguard Worker back()236*635a8641SAndroid Build Coastguard Worker value_type back() const { 237*635a8641SAndroid Build Coastguard Worker CHECK_NE(0UL, length_); 238*635a8641SAndroid Build Coastguard Worker return ptr_[length_ - 1]; 239*635a8641SAndroid Build Coastguard Worker } 240*635a8641SAndroid Build Coastguard Worker remove_prefix(size_type n)241*635a8641SAndroid Build Coastguard Worker constexpr void remove_prefix(size_type n) { 242*635a8641SAndroid Build Coastguard Worker CHECK(n <= length_); 243*635a8641SAndroid Build Coastguard Worker ptr_ += n; 244*635a8641SAndroid Build Coastguard Worker length_ -= n; 245*635a8641SAndroid Build Coastguard Worker } 246*635a8641SAndroid Build Coastguard Worker remove_suffix(size_type n)247*635a8641SAndroid Build Coastguard Worker constexpr void remove_suffix(size_type n) { 248*635a8641SAndroid Build Coastguard Worker CHECK(n <= length_); 249*635a8641SAndroid Build Coastguard Worker length_ -= n; 250*635a8641SAndroid Build Coastguard Worker } 251*635a8641SAndroid Build Coastguard Worker compare(BasicStringPiece x)252*635a8641SAndroid Build Coastguard Worker constexpr int compare(BasicStringPiece x) const noexcept { 253*635a8641SAndroid Build Coastguard Worker int r = CharTraits<value_type>::compare( 254*635a8641SAndroid Build Coastguard Worker ptr_, x.ptr_, (length_ < x.length_ ? length_ : x.length_)); 255*635a8641SAndroid Build Coastguard Worker if (r == 0) { 256*635a8641SAndroid Build Coastguard Worker if (length_ < x.length_) r = -1; 257*635a8641SAndroid Build Coastguard Worker else if (length_ > x.length_) r = +1; 258*635a8641SAndroid Build Coastguard Worker } 259*635a8641SAndroid Build Coastguard Worker return r; 260*635a8641SAndroid Build Coastguard Worker } 261*635a8641SAndroid Build Coastguard Worker 262*635a8641SAndroid Build Coastguard Worker // This is the style of conversion preferred by std::string_view in C++17. STRING_TYPE()263*635a8641SAndroid Build Coastguard Worker explicit operator STRING_TYPE() const { return as_string(); } 264*635a8641SAndroid Build Coastguard Worker as_string()265*635a8641SAndroid Build Coastguard Worker STRING_TYPE as_string() const { 266*635a8641SAndroid Build Coastguard Worker // std::string doesn't like to take a NULL pointer even with a 0 size. 267*635a8641SAndroid Build Coastguard Worker return empty() ? STRING_TYPE() : STRING_TYPE(data(), size()); 268*635a8641SAndroid Build Coastguard Worker } 269*635a8641SAndroid Build Coastguard Worker begin()270*635a8641SAndroid Build Coastguard Worker const_iterator begin() const { return ptr_; } end()271*635a8641SAndroid Build Coastguard Worker const_iterator end() const { return ptr_ + length_; } rbegin()272*635a8641SAndroid Build Coastguard Worker const_reverse_iterator rbegin() const { 273*635a8641SAndroid Build Coastguard Worker return const_reverse_iterator(ptr_ + length_); 274*635a8641SAndroid Build Coastguard Worker } rend()275*635a8641SAndroid Build Coastguard Worker const_reverse_iterator rend() const { 276*635a8641SAndroid Build Coastguard Worker return const_reverse_iterator(ptr_); 277*635a8641SAndroid Build Coastguard Worker } 278*635a8641SAndroid Build Coastguard Worker max_size()279*635a8641SAndroid Build Coastguard Worker size_type max_size() const { return length_; } capacity()280*635a8641SAndroid Build Coastguard Worker size_type capacity() const { return length_; } 281*635a8641SAndroid Build Coastguard Worker 282*635a8641SAndroid Build Coastguard Worker // Sets the value of the given string target type to be the current string. 283*635a8641SAndroid Build Coastguard Worker // This saves a temporary over doing |a = b.as_string()| CopyToString(STRING_TYPE * target)284*635a8641SAndroid Build Coastguard Worker void CopyToString(STRING_TYPE* target) const { 285*635a8641SAndroid Build Coastguard Worker internal::CopyToString(*this, target); 286*635a8641SAndroid Build Coastguard Worker } 287*635a8641SAndroid Build Coastguard Worker AppendToString(STRING_TYPE * target)288*635a8641SAndroid Build Coastguard Worker void AppendToString(STRING_TYPE* target) const { 289*635a8641SAndroid Build Coastguard Worker internal::AppendToString(*this, target); 290*635a8641SAndroid Build Coastguard Worker } 291*635a8641SAndroid Build Coastguard Worker 292*635a8641SAndroid Build Coastguard Worker size_type copy(value_type* buf, size_type n, size_type pos = 0) const { 293*635a8641SAndroid Build Coastguard Worker return internal::copy(*this, buf, n, pos); 294*635a8641SAndroid Build Coastguard Worker } 295*635a8641SAndroid Build Coastguard Worker 296*635a8641SAndroid Build Coastguard Worker // Does "this" start with "x" starts_with(BasicStringPiece x)297*635a8641SAndroid Build Coastguard Worker constexpr bool starts_with(BasicStringPiece x) const noexcept { 298*635a8641SAndroid Build Coastguard Worker return ( 299*635a8641SAndroid Build Coastguard Worker (this->length_ >= x.length_) && 300*635a8641SAndroid Build Coastguard Worker (CharTraits<value_type>::compare(this->ptr_, x.ptr_, x.length_) == 0)); 301*635a8641SAndroid Build Coastguard Worker } 302*635a8641SAndroid Build Coastguard Worker 303*635a8641SAndroid Build Coastguard Worker // Does "this" end with "x" ends_with(BasicStringPiece x)304*635a8641SAndroid Build Coastguard Worker constexpr bool ends_with(BasicStringPiece x) const noexcept { 305*635a8641SAndroid Build Coastguard Worker return ((this->length_ >= x.length_) && 306*635a8641SAndroid Build Coastguard Worker (CharTraits<value_type>::compare( 307*635a8641SAndroid Build Coastguard Worker this->ptr_ + (this->length_ - x.length_), x.ptr_, x.length_) == 308*635a8641SAndroid Build Coastguard Worker 0)); 309*635a8641SAndroid Build Coastguard Worker } 310*635a8641SAndroid Build Coastguard Worker 311*635a8641SAndroid Build Coastguard Worker // find: Search for a character or substring at a given offset. 312*635a8641SAndroid Build Coastguard Worker size_type find(const BasicStringPiece<STRING_TYPE>& s, 313*635a8641SAndroid Build Coastguard Worker size_type pos = 0) const { 314*635a8641SAndroid Build Coastguard Worker return internal::find(*this, s, pos); 315*635a8641SAndroid Build Coastguard Worker } 316*635a8641SAndroid Build Coastguard Worker size_type find(value_type c, size_type pos = 0) const { 317*635a8641SAndroid Build Coastguard Worker return internal::find(*this, c, pos); 318*635a8641SAndroid Build Coastguard Worker } 319*635a8641SAndroid Build Coastguard Worker 320*635a8641SAndroid Build Coastguard Worker // rfind: Reverse find. 321*635a8641SAndroid Build Coastguard Worker size_type rfind(const BasicStringPiece& s, 322*635a8641SAndroid Build Coastguard Worker size_type pos = BasicStringPiece::npos) const { 323*635a8641SAndroid Build Coastguard Worker return internal::rfind(*this, s, pos); 324*635a8641SAndroid Build Coastguard Worker } 325*635a8641SAndroid Build Coastguard Worker size_type rfind(value_type c, size_type pos = BasicStringPiece::npos) const { 326*635a8641SAndroid Build Coastguard Worker return internal::rfind(*this, c, pos); 327*635a8641SAndroid Build Coastguard Worker } 328*635a8641SAndroid Build Coastguard Worker 329*635a8641SAndroid Build Coastguard Worker // find_first_of: Find the first occurence of one of a set of characters. 330*635a8641SAndroid Build Coastguard Worker size_type find_first_of(const BasicStringPiece& s, 331*635a8641SAndroid Build Coastguard Worker size_type pos = 0) const { 332*635a8641SAndroid Build Coastguard Worker return internal::find_first_of(*this, s, pos); 333*635a8641SAndroid Build Coastguard Worker } 334*635a8641SAndroid Build Coastguard Worker size_type find_first_of(value_type c, size_type pos = 0) const { 335*635a8641SAndroid Build Coastguard Worker return find(c, pos); 336*635a8641SAndroid Build Coastguard Worker } 337*635a8641SAndroid Build Coastguard Worker 338*635a8641SAndroid Build Coastguard Worker // find_first_not_of: Find the first occurence not of a set of characters. 339*635a8641SAndroid Build Coastguard Worker size_type find_first_not_of(const BasicStringPiece& s, 340*635a8641SAndroid Build Coastguard Worker size_type pos = 0) const { 341*635a8641SAndroid Build Coastguard Worker return internal::find_first_not_of(*this, s, pos); 342*635a8641SAndroid Build Coastguard Worker } 343*635a8641SAndroid Build Coastguard Worker size_type find_first_not_of(value_type c, size_type pos = 0) const { 344*635a8641SAndroid Build Coastguard Worker return internal::find_first_not_of(*this, c, pos); 345*635a8641SAndroid Build Coastguard Worker } 346*635a8641SAndroid Build Coastguard Worker 347*635a8641SAndroid Build Coastguard Worker // find_last_of: Find the last occurence of one of a set of characters. 348*635a8641SAndroid Build Coastguard Worker size_type find_last_of(const BasicStringPiece& s, 349*635a8641SAndroid Build Coastguard Worker size_type pos = BasicStringPiece::npos) const { 350*635a8641SAndroid Build Coastguard Worker return internal::find_last_of(*this, s, pos); 351*635a8641SAndroid Build Coastguard Worker } 352*635a8641SAndroid Build Coastguard Worker size_type find_last_of(value_type c, 353*635a8641SAndroid Build Coastguard Worker size_type pos = BasicStringPiece::npos) const { 354*635a8641SAndroid Build Coastguard Worker return rfind(c, pos); 355*635a8641SAndroid Build Coastguard Worker } 356*635a8641SAndroid Build Coastguard Worker 357*635a8641SAndroid Build Coastguard Worker // find_last_not_of: Find the last occurence not of a set of characters. 358*635a8641SAndroid Build Coastguard Worker size_type find_last_not_of(const BasicStringPiece& s, 359*635a8641SAndroid Build Coastguard Worker size_type pos = BasicStringPiece::npos) const { 360*635a8641SAndroid Build Coastguard Worker return internal::find_last_not_of(*this, s, pos); 361*635a8641SAndroid Build Coastguard Worker } 362*635a8641SAndroid Build Coastguard Worker size_type find_last_not_of(value_type c, 363*635a8641SAndroid Build Coastguard Worker size_type pos = BasicStringPiece::npos) const { 364*635a8641SAndroid Build Coastguard Worker return internal::find_last_not_of(*this, c, pos); 365*635a8641SAndroid Build Coastguard Worker } 366*635a8641SAndroid Build Coastguard Worker 367*635a8641SAndroid Build Coastguard Worker // substr. 368*635a8641SAndroid Build Coastguard Worker BasicStringPiece substr(size_type pos, 369*635a8641SAndroid Build Coastguard Worker size_type n = BasicStringPiece::npos) const { 370*635a8641SAndroid Build Coastguard Worker return internal::substr(*this, pos, n); 371*635a8641SAndroid Build Coastguard Worker } 372*635a8641SAndroid Build Coastguard Worker 373*635a8641SAndroid Build Coastguard Worker protected: 374*635a8641SAndroid Build Coastguard Worker const value_type* ptr_; 375*635a8641SAndroid Build Coastguard Worker size_type length_; 376*635a8641SAndroid Build Coastguard Worker }; 377*635a8641SAndroid Build Coastguard Worker 378*635a8641SAndroid Build Coastguard Worker template <typename STRING_TYPE> 379*635a8641SAndroid Build Coastguard Worker const typename BasicStringPiece<STRING_TYPE>::size_type 380*635a8641SAndroid Build Coastguard Worker BasicStringPiece<STRING_TYPE>::npos = 381*635a8641SAndroid Build Coastguard Worker typename BasicStringPiece<STRING_TYPE>::size_type(-1); 382*635a8641SAndroid Build Coastguard Worker 383*635a8641SAndroid Build Coastguard Worker // MSVC doesn't like complex extern templates and DLLs. 384*635a8641SAndroid Build Coastguard Worker #if !defined(COMPILER_MSVC) 385*635a8641SAndroid Build Coastguard Worker extern template class BASE_EXPORT BasicStringPiece<std::string>; 386*635a8641SAndroid Build Coastguard Worker extern template class BASE_EXPORT BasicStringPiece<string16>; 387*635a8641SAndroid Build Coastguard Worker #endif 388*635a8641SAndroid Build Coastguard Worker 389*635a8641SAndroid Build Coastguard Worker // StingPiece operators -------------------------------------------------------- 390*635a8641SAndroid Build Coastguard Worker 391*635a8641SAndroid Build Coastguard Worker BASE_EXPORT bool operator==(const StringPiece& x, const StringPiece& y); 392*635a8641SAndroid Build Coastguard Worker 393*635a8641SAndroid Build Coastguard Worker inline bool operator!=(const StringPiece& x, const StringPiece& y) { 394*635a8641SAndroid Build Coastguard Worker return !(x == y); 395*635a8641SAndroid Build Coastguard Worker } 396*635a8641SAndroid Build Coastguard Worker 397*635a8641SAndroid Build Coastguard Worker inline bool operator<(const StringPiece& x, const StringPiece& y) { 398*635a8641SAndroid Build Coastguard Worker const int r = CharTraits<StringPiece::value_type>::compare( 399*635a8641SAndroid Build Coastguard Worker x.data(), y.data(), (x.size() < y.size() ? x.size() : y.size())); 400*635a8641SAndroid Build Coastguard Worker return ((r < 0) || ((r == 0) && (x.size() < y.size()))); 401*635a8641SAndroid Build Coastguard Worker } 402*635a8641SAndroid Build Coastguard Worker 403*635a8641SAndroid Build Coastguard Worker inline bool operator>(const StringPiece& x, const StringPiece& y) { 404*635a8641SAndroid Build Coastguard Worker return y < x; 405*635a8641SAndroid Build Coastguard Worker } 406*635a8641SAndroid Build Coastguard Worker 407*635a8641SAndroid Build Coastguard Worker inline bool operator<=(const StringPiece& x, const StringPiece& y) { 408*635a8641SAndroid Build Coastguard Worker return !(x > y); 409*635a8641SAndroid Build Coastguard Worker } 410*635a8641SAndroid Build Coastguard Worker 411*635a8641SAndroid Build Coastguard Worker inline bool operator>=(const StringPiece& x, const StringPiece& y) { 412*635a8641SAndroid Build Coastguard Worker return !(x < y); 413*635a8641SAndroid Build Coastguard Worker } 414*635a8641SAndroid Build Coastguard Worker 415*635a8641SAndroid Build Coastguard Worker // StringPiece16 operators ----------------------------------------------------- 416*635a8641SAndroid Build Coastguard Worker 417*635a8641SAndroid Build Coastguard Worker inline bool operator==(const StringPiece16& x, const StringPiece16& y) { 418*635a8641SAndroid Build Coastguard Worker if (x.size() != y.size()) 419*635a8641SAndroid Build Coastguard Worker return false; 420*635a8641SAndroid Build Coastguard Worker 421*635a8641SAndroid Build Coastguard Worker return CharTraits<StringPiece16::value_type>::compare(x.data(), y.data(), 422*635a8641SAndroid Build Coastguard Worker x.size()) == 0; 423*635a8641SAndroid Build Coastguard Worker } 424*635a8641SAndroid Build Coastguard Worker 425*635a8641SAndroid Build Coastguard Worker inline bool operator!=(const StringPiece16& x, const StringPiece16& y) { 426*635a8641SAndroid Build Coastguard Worker return !(x == y); 427*635a8641SAndroid Build Coastguard Worker } 428*635a8641SAndroid Build Coastguard Worker 429*635a8641SAndroid Build Coastguard Worker inline bool operator<(const StringPiece16& x, const StringPiece16& y) { 430*635a8641SAndroid Build Coastguard Worker const int r = CharTraits<StringPiece16::value_type>::compare( 431*635a8641SAndroid Build Coastguard Worker x.data(), y.data(), (x.size() < y.size() ? x.size() : y.size())); 432*635a8641SAndroid Build Coastguard Worker return ((r < 0) || ((r == 0) && (x.size() < y.size()))); 433*635a8641SAndroid Build Coastguard Worker } 434*635a8641SAndroid Build Coastguard Worker 435*635a8641SAndroid Build Coastguard Worker inline bool operator>(const StringPiece16& x, const StringPiece16& y) { 436*635a8641SAndroid Build Coastguard Worker return y < x; 437*635a8641SAndroid Build Coastguard Worker } 438*635a8641SAndroid Build Coastguard Worker 439*635a8641SAndroid Build Coastguard Worker inline bool operator<=(const StringPiece16& x, const StringPiece16& y) { 440*635a8641SAndroid Build Coastguard Worker return !(x > y); 441*635a8641SAndroid Build Coastguard Worker } 442*635a8641SAndroid Build Coastguard Worker 443*635a8641SAndroid Build Coastguard Worker inline bool operator>=(const StringPiece16& x, const StringPiece16& y) { 444*635a8641SAndroid Build Coastguard Worker return !(x < y); 445*635a8641SAndroid Build Coastguard Worker } 446*635a8641SAndroid Build Coastguard Worker 447*635a8641SAndroid Build Coastguard Worker BASE_EXPORT std::ostream& operator<<(std::ostream& o, 448*635a8641SAndroid Build Coastguard Worker const StringPiece& piece); 449*635a8641SAndroid Build Coastguard Worker 450*635a8641SAndroid Build Coastguard Worker // Hashing --------------------------------------------------------------------- 451*635a8641SAndroid Build Coastguard Worker 452*635a8641SAndroid Build Coastguard Worker // We provide appropriate hash functions so StringPiece and StringPiece16 can 453*635a8641SAndroid Build Coastguard Worker // be used as keys in hash sets and maps. 454*635a8641SAndroid Build Coastguard Worker 455*635a8641SAndroid Build Coastguard Worker // This hash function is copied from base/strings/string16.h. We don't use the 456*635a8641SAndroid Build Coastguard Worker // ones already defined for string and string16 directly because it would 457*635a8641SAndroid Build Coastguard Worker // require the string constructors to be called, which we don't want. 458*635a8641SAndroid Build Coastguard Worker #define HASH_STRING_PIECE(StringPieceType, string_piece) \ 459*635a8641SAndroid Build Coastguard Worker std::size_t result = 0; \ 460*635a8641SAndroid Build Coastguard Worker for (StringPieceType::const_iterator i = string_piece.begin(); \ 461*635a8641SAndroid Build Coastguard Worker i != string_piece.end(); ++i) \ 462*635a8641SAndroid Build Coastguard Worker result = (result * 131) + *i; \ 463*635a8641SAndroid Build Coastguard Worker return result; 464*635a8641SAndroid Build Coastguard Worker 465*635a8641SAndroid Build Coastguard Worker struct StringPieceHash { operatorStringPieceHash466*635a8641SAndroid Build Coastguard Worker std::size_t operator()(const StringPiece& sp) const { 467*635a8641SAndroid Build Coastguard Worker HASH_STRING_PIECE(StringPiece, sp); 468*635a8641SAndroid Build Coastguard Worker } 469*635a8641SAndroid Build Coastguard Worker }; 470*635a8641SAndroid Build Coastguard Worker struct StringPiece16Hash { operatorStringPiece16Hash471*635a8641SAndroid Build Coastguard Worker std::size_t operator()(const StringPiece16& sp16) const { 472*635a8641SAndroid Build Coastguard Worker HASH_STRING_PIECE(StringPiece16, sp16); 473*635a8641SAndroid Build Coastguard Worker } 474*635a8641SAndroid Build Coastguard Worker }; 475*635a8641SAndroid Build Coastguard Worker struct WStringPieceHash { operatorWStringPieceHash476*635a8641SAndroid Build Coastguard Worker std::size_t operator()(const WStringPiece& wsp) const { 477*635a8641SAndroid Build Coastguard Worker HASH_STRING_PIECE(WStringPiece, wsp); 478*635a8641SAndroid Build Coastguard Worker } 479*635a8641SAndroid Build Coastguard Worker }; 480*635a8641SAndroid Build Coastguard Worker 481*635a8641SAndroid Build Coastguard Worker } // namespace base 482*635a8641SAndroid Build Coastguard Worker 483*635a8641SAndroid Build Coastguard Worker #endif // BASE_STRINGS_STRING_PIECE_H_ 484