1*1b3f573fSAndroid Build Coastguard Worker // Protocol Buffers - Google's data interchange format 2*1b3f573fSAndroid Build Coastguard Worker // Copyright 2008 Google Inc. All rights reserved. 3*1b3f573fSAndroid Build Coastguard Worker // https://developers.google.com/protocol-buffers/ 4*1b3f573fSAndroid Build Coastguard Worker // 5*1b3f573fSAndroid Build Coastguard Worker // Redistribution and use in source and binary forms, with or without 6*1b3f573fSAndroid Build Coastguard Worker // modification, are permitted provided that the following conditions are 7*1b3f573fSAndroid Build Coastguard Worker // met: 8*1b3f573fSAndroid Build Coastguard Worker // 9*1b3f573fSAndroid Build Coastguard Worker // * Redistributions of source code must retain the above copyright 10*1b3f573fSAndroid Build Coastguard Worker // notice, this list of conditions and the following disclaimer. 11*1b3f573fSAndroid Build Coastguard Worker // * Redistributions in binary form must reproduce the above 12*1b3f573fSAndroid Build Coastguard Worker // copyright notice, this list of conditions and the following disclaimer 13*1b3f573fSAndroid Build Coastguard Worker // in the documentation and/or other materials provided with the 14*1b3f573fSAndroid Build Coastguard Worker // distribution. 15*1b3f573fSAndroid Build Coastguard Worker // * Neither the name of Google Inc. nor the names of its 16*1b3f573fSAndroid Build Coastguard Worker // contributors may be used to endorse or promote products derived from 17*1b3f573fSAndroid Build Coastguard Worker // this software without specific prior written permission. 18*1b3f573fSAndroid Build Coastguard Worker // 19*1b3f573fSAndroid Build Coastguard Worker // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 20*1b3f573fSAndroid Build Coastguard Worker // "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 21*1b3f573fSAndroid Build Coastguard Worker // LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 22*1b3f573fSAndroid Build Coastguard Worker // A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 23*1b3f573fSAndroid Build Coastguard Worker // OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 24*1b3f573fSAndroid Build Coastguard Worker // SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 25*1b3f573fSAndroid Build Coastguard Worker // LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 26*1b3f573fSAndroid Build Coastguard Worker // DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 27*1b3f573fSAndroid Build Coastguard Worker // THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 28*1b3f573fSAndroid Build Coastguard Worker // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 29*1b3f573fSAndroid Build Coastguard Worker // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 30*1b3f573fSAndroid Build Coastguard Worker 31*1b3f573fSAndroid Build Coastguard Worker // A StringPiece points to part or all of a string, Cord, double-quoted string 32*1b3f573fSAndroid Build Coastguard Worker // literal, or other string-like object. A StringPiece does *not* own the 33*1b3f573fSAndroid Build Coastguard Worker // string to which it points. A StringPiece is not null-terminated. 34*1b3f573fSAndroid Build Coastguard Worker // 35*1b3f573fSAndroid Build Coastguard Worker // You can use StringPiece as a function or method parameter. A StringPiece 36*1b3f573fSAndroid Build Coastguard Worker // parameter can receive a double-quoted string literal argument, a "const 37*1b3f573fSAndroid Build Coastguard Worker // char*" argument, a string argument, or a StringPiece argument with no data 38*1b3f573fSAndroid Build Coastguard Worker // copying. Systematic use of StringPiece for arguments reduces data 39*1b3f573fSAndroid Build Coastguard Worker // copies and strlen() calls. 40*1b3f573fSAndroid Build Coastguard Worker // 41*1b3f573fSAndroid Build Coastguard Worker // Prefer passing StringPieces by value: 42*1b3f573fSAndroid Build Coastguard Worker // void MyFunction(StringPiece arg); 43*1b3f573fSAndroid Build Coastguard Worker // If circumstances require, you may also pass by const reference: 44*1b3f573fSAndroid Build Coastguard Worker // void MyFunction(const StringPiece& arg); // not preferred 45*1b3f573fSAndroid Build Coastguard Worker // Both of these have the same lifetime semantics. Passing by value 46*1b3f573fSAndroid Build Coastguard Worker // generates slightly smaller code. For more discussion, see the thread 47*1b3f573fSAndroid Build Coastguard Worker // go/stringpiecebyvalue on c-users. 48*1b3f573fSAndroid Build Coastguard Worker // 49*1b3f573fSAndroid Build Coastguard Worker // StringPiece is also suitable for local variables if you know that 50*1b3f573fSAndroid Build Coastguard Worker // the lifetime of the underlying object is longer than the lifetime 51*1b3f573fSAndroid Build Coastguard Worker // of your StringPiece variable. 52*1b3f573fSAndroid Build Coastguard Worker // 53*1b3f573fSAndroid Build Coastguard Worker // Beware of binding a StringPiece to a temporary: 54*1b3f573fSAndroid Build Coastguard Worker // StringPiece sp = obj.MethodReturningString(); // BAD: lifetime problem 55*1b3f573fSAndroid Build Coastguard Worker // 56*1b3f573fSAndroid Build Coastguard Worker // This code is okay: 57*1b3f573fSAndroid Build Coastguard Worker // string str = obj.MethodReturningString(); // str owns its contents 58*1b3f573fSAndroid Build Coastguard Worker // StringPiece sp(str); // GOOD, because str outlives sp 59*1b3f573fSAndroid Build Coastguard Worker // 60*1b3f573fSAndroid Build Coastguard Worker // StringPiece is sometimes a poor choice for a return value and usually a poor 61*1b3f573fSAndroid Build Coastguard Worker // choice for a data member. If you do use a StringPiece this way, it is your 62*1b3f573fSAndroid Build Coastguard Worker // responsibility to ensure that the object pointed to by the StringPiece 63*1b3f573fSAndroid Build Coastguard Worker // outlives the StringPiece. 64*1b3f573fSAndroid Build Coastguard Worker // 65*1b3f573fSAndroid Build Coastguard Worker // A StringPiece may represent just part of a string; thus the name "Piece". 66*1b3f573fSAndroid Build Coastguard Worker // For example, when splitting a string, vector<StringPiece> is a natural data 67*1b3f573fSAndroid Build Coastguard Worker // type for the output. For another example, a Cord is a non-contiguous, 68*1b3f573fSAndroid Build Coastguard Worker // potentially very long string-like object. The Cord class has an interface 69*1b3f573fSAndroid Build Coastguard Worker // that iteratively provides StringPiece objects that point to the 70*1b3f573fSAndroid Build Coastguard Worker // successive pieces of a Cord object. 71*1b3f573fSAndroid Build Coastguard Worker // 72*1b3f573fSAndroid Build Coastguard Worker // A StringPiece is not null-terminated. If you write code that scans a 73*1b3f573fSAndroid Build Coastguard Worker // StringPiece, you must check its length before reading any characters. 74*1b3f573fSAndroid Build Coastguard Worker // Common idioms that work on null-terminated strings do not work on 75*1b3f573fSAndroid Build Coastguard Worker // StringPiece objects. 76*1b3f573fSAndroid Build Coastguard Worker // 77*1b3f573fSAndroid Build Coastguard Worker // There are several ways to create a null StringPiece: 78*1b3f573fSAndroid Build Coastguard Worker // StringPiece() 79*1b3f573fSAndroid Build Coastguard Worker // StringPiece(nullptr) 80*1b3f573fSAndroid Build Coastguard Worker // StringPiece(nullptr, 0) 81*1b3f573fSAndroid Build Coastguard Worker // For all of the above, sp.data() == nullptr, sp.length() == 0, 82*1b3f573fSAndroid Build Coastguard Worker // and sp.empty() == true. Also, if you create a StringPiece with 83*1b3f573fSAndroid Build Coastguard Worker // a non-null pointer then sp.data() != nullptr. Once created, 84*1b3f573fSAndroid Build Coastguard Worker // sp.data() will stay either nullptr or not-nullptr, except if you call 85*1b3f573fSAndroid Build Coastguard Worker // sp.clear() or sp.set(). 86*1b3f573fSAndroid Build Coastguard Worker // 87*1b3f573fSAndroid Build Coastguard Worker // Thus, you can use StringPiece(nullptr) to signal an out-of-band value 88*1b3f573fSAndroid Build Coastguard Worker // that is different from other StringPiece values. This is similar 89*1b3f573fSAndroid Build Coastguard Worker // to the way that const char* p1 = nullptr; is different from 90*1b3f573fSAndroid Build Coastguard Worker // const char* p2 = "";. 91*1b3f573fSAndroid Build Coastguard Worker // 92*1b3f573fSAndroid Build Coastguard Worker // There are many ways to create an empty StringPiece: 93*1b3f573fSAndroid Build Coastguard Worker // StringPiece() 94*1b3f573fSAndroid Build Coastguard Worker // StringPiece(nullptr) 95*1b3f573fSAndroid Build Coastguard Worker // StringPiece(nullptr, 0) 96*1b3f573fSAndroid Build Coastguard Worker // StringPiece("") 97*1b3f573fSAndroid Build Coastguard Worker // StringPiece("", 0) 98*1b3f573fSAndroid Build Coastguard Worker // StringPiece("abcdef", 0) 99*1b3f573fSAndroid Build Coastguard Worker // StringPiece("abcdef"+6, 0) 100*1b3f573fSAndroid Build Coastguard Worker // For all of the above, sp.length() will be 0 and sp.empty() will be true. 101*1b3f573fSAndroid Build Coastguard Worker // For some empty StringPiece values, sp.data() will be nullptr. 102*1b3f573fSAndroid Build Coastguard Worker // For some empty StringPiece values, sp.data() will not be nullptr. 103*1b3f573fSAndroid Build Coastguard Worker // 104*1b3f573fSAndroid Build Coastguard Worker // Be careful not to confuse: null StringPiece and empty StringPiece. 105*1b3f573fSAndroid Build Coastguard Worker // The set of empty StringPieces properly includes the set of null StringPieces. 106*1b3f573fSAndroid Build Coastguard Worker // That is, every null StringPiece is an empty StringPiece, 107*1b3f573fSAndroid Build Coastguard Worker // but some non-null StringPieces are empty Stringpieces too. 108*1b3f573fSAndroid Build Coastguard Worker // 109*1b3f573fSAndroid Build Coastguard Worker // All empty StringPiece values compare equal to each other. 110*1b3f573fSAndroid Build Coastguard Worker // Even a null StringPieces compares equal to a non-null empty StringPiece: 111*1b3f573fSAndroid Build Coastguard Worker // StringPiece() == StringPiece("", 0) 112*1b3f573fSAndroid Build Coastguard Worker // StringPiece(nullptr) == StringPiece("abc", 0) 113*1b3f573fSAndroid Build Coastguard Worker // StringPiece(nullptr, 0) == StringPiece("abcdef"+6, 0) 114*1b3f573fSAndroid Build Coastguard Worker // 115*1b3f573fSAndroid Build Coastguard Worker // Look carefully at this example: 116*1b3f573fSAndroid Build Coastguard Worker // StringPiece("") == nullptr 117*1b3f573fSAndroid Build Coastguard Worker // True or false? TRUE, because StringPiece::operator== converts 118*1b3f573fSAndroid Build Coastguard Worker // the right-hand side from nullptr to StringPiece(nullptr), 119*1b3f573fSAndroid Build Coastguard Worker // and then compares two zero-length spans of characters. 120*1b3f573fSAndroid Build Coastguard Worker // However, we are working to make this example produce a compile error. 121*1b3f573fSAndroid Build Coastguard Worker // 122*1b3f573fSAndroid Build Coastguard Worker // Suppose you want to write: 123*1b3f573fSAndroid Build Coastguard Worker // bool TestWhat?(StringPiece sp) { return sp == nullptr; } // BAD 124*1b3f573fSAndroid Build Coastguard Worker // Do not do that. Write one of these instead: 125*1b3f573fSAndroid Build Coastguard Worker // bool TestNull(StringPiece sp) { return sp.data() == nullptr; } 126*1b3f573fSAndroid Build Coastguard Worker // bool TestEmpty(StringPiece sp) { return sp.empty(); } 127*1b3f573fSAndroid Build Coastguard Worker // The intent of TestWhat? is unclear. Did you mean TestNull or TestEmpty? 128*1b3f573fSAndroid Build Coastguard Worker // Right now, TestWhat? behaves likes TestEmpty. 129*1b3f573fSAndroid Build Coastguard Worker // We are working to make TestWhat? produce a compile error. 130*1b3f573fSAndroid Build Coastguard Worker // TestNull is good to test for an out-of-band signal. 131*1b3f573fSAndroid Build Coastguard Worker // TestEmpty is good to test for an empty StringPiece. 132*1b3f573fSAndroid Build Coastguard Worker // 133*1b3f573fSAndroid Build Coastguard Worker // Caveats (again): 134*1b3f573fSAndroid Build Coastguard Worker // (1) The lifetime of the pointed-to string (or piece of a string) 135*1b3f573fSAndroid Build Coastguard Worker // must be longer than the lifetime of the StringPiece. 136*1b3f573fSAndroid Build Coastguard Worker // (2) There may or may not be a '\0' character after the end of 137*1b3f573fSAndroid Build Coastguard Worker // StringPiece data. 138*1b3f573fSAndroid Build Coastguard Worker // (3) A null StringPiece is empty. 139*1b3f573fSAndroid Build Coastguard Worker // An empty StringPiece may or may not be a null StringPiece. 140*1b3f573fSAndroid Build Coastguard Worker 141*1b3f573fSAndroid Build Coastguard Worker #ifndef GOOGLE_PROTOBUF_STUBS_STRINGPIECE_H_ 142*1b3f573fSAndroid Build Coastguard Worker #define GOOGLE_PROTOBUF_STUBS_STRINGPIECE_H_ 143*1b3f573fSAndroid Build Coastguard Worker 144*1b3f573fSAndroid Build Coastguard Worker #include <assert.h> 145*1b3f573fSAndroid Build Coastguard Worker #include <stddef.h> 146*1b3f573fSAndroid Build Coastguard Worker #include <string.h> 147*1b3f573fSAndroid Build Coastguard Worker #include <iosfwd> 148*1b3f573fSAndroid Build Coastguard Worker #include <limits> 149*1b3f573fSAndroid Build Coastguard Worker #include <string> 150*1b3f573fSAndroid Build Coastguard Worker 151*1b3f573fSAndroid Build Coastguard Worker #if defined(__cpp_lib_string_view) 152*1b3f573fSAndroid Build Coastguard Worker #include <string_view> 153*1b3f573fSAndroid Build Coastguard Worker #endif 154*1b3f573fSAndroid Build Coastguard Worker 155*1b3f573fSAndroid Build Coastguard Worker #include <google/protobuf/stubs/hash.h> 156*1b3f573fSAndroid Build Coastguard Worker 157*1b3f573fSAndroid Build Coastguard Worker #include <google/protobuf/port_def.inc> 158*1b3f573fSAndroid Build Coastguard Worker 159*1b3f573fSAndroid Build Coastguard Worker namespace google { 160*1b3f573fSAndroid Build Coastguard Worker namespace protobuf { 161*1b3f573fSAndroid Build Coastguard Worker namespace stringpiece_internal { 162*1b3f573fSAndroid Build Coastguard Worker 163*1b3f573fSAndroid Build Coastguard Worker class PROTOBUF_EXPORT StringPiece { 164*1b3f573fSAndroid Build Coastguard Worker public: 165*1b3f573fSAndroid Build Coastguard Worker using traits_type = std::char_traits<char>; 166*1b3f573fSAndroid Build Coastguard Worker using value_type = char; 167*1b3f573fSAndroid Build Coastguard Worker using pointer = char*; 168*1b3f573fSAndroid Build Coastguard Worker using const_pointer = const char*; 169*1b3f573fSAndroid Build Coastguard Worker using reference = char&; 170*1b3f573fSAndroid Build Coastguard Worker using const_reference = const char&; 171*1b3f573fSAndroid Build Coastguard Worker using const_iterator = const char*; 172*1b3f573fSAndroid Build Coastguard Worker using iterator = const_iterator; 173*1b3f573fSAndroid Build Coastguard Worker using const_reverse_iterator = std::reverse_iterator<const_iterator>; 174*1b3f573fSAndroid Build Coastguard Worker using reverse_iterator = const_reverse_iterator; 175*1b3f573fSAndroid Build Coastguard Worker using size_type = size_t; 176*1b3f573fSAndroid Build Coastguard Worker using difference_type = std::ptrdiff_t; 177*1b3f573fSAndroid Build Coastguard Worker 178*1b3f573fSAndroid Build Coastguard Worker private: 179*1b3f573fSAndroid Build Coastguard Worker const char* ptr_; 180*1b3f573fSAndroid Build Coastguard Worker size_type length_; 181*1b3f573fSAndroid Build Coastguard Worker 182*1b3f573fSAndroid Build Coastguard Worker static constexpr size_type kMaxSize = 183*1b3f573fSAndroid Build Coastguard Worker (std::numeric_limits<difference_type>::max)(); 184*1b3f573fSAndroid Build Coastguard Worker CheckSize(size_type size)185*1b3f573fSAndroid Build Coastguard Worker static size_type CheckSize(size_type size) { 186*1b3f573fSAndroid Build Coastguard Worker #if !defined(NDEBUG) || defined(_FORTIFY_SOURCE) && _FORTIFY_SOURCE > 0 187*1b3f573fSAndroid Build Coastguard Worker if (PROTOBUF_PREDICT_FALSE(size > kMaxSize)) { 188*1b3f573fSAndroid Build Coastguard Worker // Some people grep for this message in logs 189*1b3f573fSAndroid Build Coastguard Worker // so take care if you ever change it. 190*1b3f573fSAndroid Build Coastguard Worker LogFatalSizeTooBig(size, "string length exceeds max size"); 191*1b3f573fSAndroid Build Coastguard Worker } 192*1b3f573fSAndroid Build Coastguard Worker #endif 193*1b3f573fSAndroid Build Coastguard Worker return size; 194*1b3f573fSAndroid Build Coastguard Worker } 195*1b3f573fSAndroid Build Coastguard Worker 196*1b3f573fSAndroid Build Coastguard Worker // Out-of-line error path. 197*1b3f573fSAndroid Build Coastguard Worker static void LogFatalSizeTooBig(size_type size, const char* details); 198*1b3f573fSAndroid Build Coastguard Worker 199*1b3f573fSAndroid Build Coastguard Worker public: 200*1b3f573fSAndroid Build Coastguard Worker // We provide non-explicit singleton constructors so users can pass 201*1b3f573fSAndroid Build Coastguard Worker // in a "const char*" or a "string" wherever a "StringPiece" is 202*1b3f573fSAndroid Build Coastguard Worker // expected. 203*1b3f573fSAndroid Build Coastguard Worker // 204*1b3f573fSAndroid Build Coastguard Worker // Style guide exception granted: 205*1b3f573fSAndroid Build Coastguard Worker // http://goto/style-guide-exception-20978288 StringPiece()206*1b3f573fSAndroid Build Coastguard Worker StringPiece() : ptr_(nullptr), length_(0) {} 207*1b3f573fSAndroid Build Coastguard Worker StringPiece(const char * str)208*1b3f573fSAndroid Build Coastguard Worker StringPiece(const char* str) // NOLINT(runtime/explicit) 209*1b3f573fSAndroid Build Coastguard Worker : ptr_(str), length_(0) { 210*1b3f573fSAndroid Build Coastguard Worker if (str != nullptr) { 211*1b3f573fSAndroid Build Coastguard Worker length_ = CheckSize(strlen(str)); 212*1b3f573fSAndroid Build Coastguard Worker } 213*1b3f573fSAndroid Build Coastguard Worker } 214*1b3f573fSAndroid Build Coastguard Worker 215*1b3f573fSAndroid Build Coastguard Worker template <class Allocator> StringPiece(const std::basic_string<char,std::char_traits<char>,Allocator> & str)216*1b3f573fSAndroid Build Coastguard Worker StringPiece( // NOLINT(runtime/explicit) 217*1b3f573fSAndroid Build Coastguard Worker const std::basic_string<char, std::char_traits<char>, Allocator>& str) 218*1b3f573fSAndroid Build Coastguard Worker : ptr_(str.data()), length_(0) { 219*1b3f573fSAndroid Build Coastguard Worker length_ = CheckSize(str.size()); 220*1b3f573fSAndroid Build Coastguard Worker } 221*1b3f573fSAndroid Build Coastguard Worker 222*1b3f573fSAndroid Build Coastguard Worker #if defined(__cpp_lib_string_view) StringPiece(std::string_view str)223*1b3f573fSAndroid Build Coastguard Worker StringPiece( // NOLINT(runtime/explicit) 224*1b3f573fSAndroid Build Coastguard Worker std::string_view str) 225*1b3f573fSAndroid Build Coastguard Worker : ptr_(str.data()), length_(0) { 226*1b3f573fSAndroid Build Coastguard Worker length_ = CheckSize(str.size()); 227*1b3f573fSAndroid Build Coastguard Worker } 228*1b3f573fSAndroid Build Coastguard Worker #endif 229*1b3f573fSAndroid Build Coastguard Worker StringPiece(const char * offset,size_type len)230*1b3f573fSAndroid Build Coastguard Worker StringPiece(const char* offset, size_type len) 231*1b3f573fSAndroid Build Coastguard Worker : ptr_(offset), length_(CheckSize(len)) {} 232*1b3f573fSAndroid Build Coastguard Worker 233*1b3f573fSAndroid Build Coastguard Worker // data() may return a pointer to a buffer with embedded NULs, and the 234*1b3f573fSAndroid Build Coastguard Worker // returned buffer may or may not be null terminated. Therefore it is 235*1b3f573fSAndroid Build Coastguard Worker // typically a mistake to pass data() to a routine that expects a NUL 236*1b3f573fSAndroid Build Coastguard Worker // terminated string. data()237*1b3f573fSAndroid Build Coastguard Worker const_pointer data() const { return ptr_; } size()238*1b3f573fSAndroid Build Coastguard Worker size_type size() const { return length_; } length()239*1b3f573fSAndroid Build Coastguard Worker size_type length() const { return length_; } empty()240*1b3f573fSAndroid Build Coastguard Worker bool empty() const { return length_ == 0; } 241*1b3f573fSAndroid Build Coastguard Worker 242*1b3f573fSAndroid Build Coastguard Worker char operator[](size_type i) const { 243*1b3f573fSAndroid Build Coastguard Worker assert(i < length_); 244*1b3f573fSAndroid Build Coastguard Worker return ptr_[i]; 245*1b3f573fSAndroid Build Coastguard Worker } 246*1b3f573fSAndroid Build Coastguard Worker remove_prefix(size_type n)247*1b3f573fSAndroid Build Coastguard Worker void remove_prefix(size_type n) { 248*1b3f573fSAndroid Build Coastguard Worker assert(length_ >= n); 249*1b3f573fSAndroid Build Coastguard Worker ptr_ += n; 250*1b3f573fSAndroid Build Coastguard Worker length_ -= n; 251*1b3f573fSAndroid Build Coastguard Worker } 252*1b3f573fSAndroid Build Coastguard Worker remove_suffix(size_type n)253*1b3f573fSAndroid Build Coastguard Worker void remove_suffix(size_type n) { 254*1b3f573fSAndroid Build Coastguard Worker assert(length_ >= n); 255*1b3f573fSAndroid Build Coastguard Worker length_ -= n; 256*1b3f573fSAndroid Build Coastguard Worker } 257*1b3f573fSAndroid Build Coastguard Worker 258*1b3f573fSAndroid Build Coastguard Worker // returns {-1, 0, 1} compare(StringPiece x)259*1b3f573fSAndroid Build Coastguard Worker int compare(StringPiece x) const { 260*1b3f573fSAndroid Build Coastguard Worker size_type min_size = length_ < x.length_ ? length_ : x.length_; 261*1b3f573fSAndroid Build Coastguard Worker int r = memcmp(ptr_, x.ptr_, static_cast<size_t>(min_size)); 262*1b3f573fSAndroid Build Coastguard Worker if (r < 0) return -1; 263*1b3f573fSAndroid Build Coastguard Worker if (r > 0) return 1; 264*1b3f573fSAndroid Build Coastguard Worker if (length_ < x.length_) return -1; 265*1b3f573fSAndroid Build Coastguard Worker if (length_ > x.length_) return 1; 266*1b3f573fSAndroid Build Coastguard Worker return 0; 267*1b3f573fSAndroid Build Coastguard Worker } 268*1b3f573fSAndroid Build Coastguard Worker as_string()269*1b3f573fSAndroid Build Coastguard Worker std::string as_string() const { return ToString(); } 270*1b3f573fSAndroid Build Coastguard Worker // We also define ToString() here, since many other string-like 271*1b3f573fSAndroid Build Coastguard Worker // interfaces name the routine that converts to a C++ string 272*1b3f573fSAndroid Build Coastguard Worker // "ToString", and it's confusing to have the method that does that 273*1b3f573fSAndroid Build Coastguard Worker // for a StringPiece be called "as_string()". We also leave the 274*1b3f573fSAndroid Build Coastguard Worker // "as_string()" method defined here for existing code. ToString()275*1b3f573fSAndroid Build Coastguard Worker std::string ToString() const { 276*1b3f573fSAndroid Build Coastguard Worker if (ptr_ == nullptr) return ""; 277*1b3f573fSAndroid Build Coastguard Worker return std::string(data(), static_cast<size_type>(size())); 278*1b3f573fSAndroid Build Coastguard Worker } 279*1b3f573fSAndroid Build Coastguard Worker string()280*1b3f573fSAndroid Build Coastguard Worker explicit operator std::string() const { return ToString(); } 281*1b3f573fSAndroid Build Coastguard Worker 282*1b3f573fSAndroid Build Coastguard Worker void CopyToString(std::string* target) const; 283*1b3f573fSAndroid Build Coastguard Worker void AppendToString(std::string* target) const; 284*1b3f573fSAndroid Build Coastguard Worker starts_with(StringPiece x)285*1b3f573fSAndroid Build Coastguard Worker bool starts_with(StringPiece x) const { 286*1b3f573fSAndroid Build Coastguard Worker return (length_ >= x.length_) && 287*1b3f573fSAndroid Build Coastguard Worker (memcmp(ptr_, x.ptr_, static_cast<size_t>(x.length_)) == 0); 288*1b3f573fSAndroid Build Coastguard Worker } 289*1b3f573fSAndroid Build Coastguard Worker ends_with(StringPiece x)290*1b3f573fSAndroid Build Coastguard Worker bool ends_with(StringPiece x) const { 291*1b3f573fSAndroid Build Coastguard Worker return ((length_ >= x.length_) && 292*1b3f573fSAndroid Build Coastguard Worker (memcmp(ptr_ + (length_-x.length_), x.ptr_, 293*1b3f573fSAndroid Build Coastguard Worker static_cast<size_t>(x.length_)) == 0)); 294*1b3f573fSAndroid Build Coastguard Worker } 295*1b3f573fSAndroid Build Coastguard Worker 296*1b3f573fSAndroid Build Coastguard Worker // Checks whether StringPiece starts with x and if so advances the beginning 297*1b3f573fSAndroid Build Coastguard Worker // of it to past the match. It's basically a shortcut for starts_with 298*1b3f573fSAndroid Build Coastguard Worker // followed by remove_prefix. 299*1b3f573fSAndroid Build Coastguard Worker bool Consume(StringPiece x); 300*1b3f573fSAndroid Build Coastguard Worker // Like above but for the end of the string. 301*1b3f573fSAndroid Build Coastguard Worker bool ConsumeFromEnd(StringPiece x); 302*1b3f573fSAndroid Build Coastguard Worker 303*1b3f573fSAndroid Build Coastguard Worker // standard STL container boilerplate 304*1b3f573fSAndroid Build Coastguard Worker static const size_type npos; begin()305*1b3f573fSAndroid Build Coastguard Worker const_iterator begin() const { return ptr_; } end()306*1b3f573fSAndroid Build Coastguard Worker const_iterator end() const { return ptr_ + length_; } rbegin()307*1b3f573fSAndroid Build Coastguard Worker const_reverse_iterator rbegin() const { 308*1b3f573fSAndroid Build Coastguard Worker return const_reverse_iterator(ptr_ + length_); 309*1b3f573fSAndroid Build Coastguard Worker } rend()310*1b3f573fSAndroid Build Coastguard Worker const_reverse_iterator rend() const { 311*1b3f573fSAndroid Build Coastguard Worker return const_reverse_iterator(ptr_); 312*1b3f573fSAndroid Build Coastguard Worker } max_size()313*1b3f573fSAndroid Build Coastguard Worker size_type max_size() const { return length_; } capacity()314*1b3f573fSAndroid Build Coastguard Worker size_type capacity() const { return length_; } 315*1b3f573fSAndroid Build Coastguard Worker 316*1b3f573fSAndroid Build Coastguard Worker // cpplint.py emits a false positive [build/include_what_you_use] 317*1b3f573fSAndroid Build Coastguard Worker size_type copy(char* buf, size_type n, size_type pos = 0) const; // NOLINT 318*1b3f573fSAndroid Build Coastguard Worker 319*1b3f573fSAndroid Build Coastguard Worker bool contains(StringPiece s) const; 320*1b3f573fSAndroid Build Coastguard Worker 321*1b3f573fSAndroid Build Coastguard Worker size_type find(StringPiece s, size_type pos = 0) const; 322*1b3f573fSAndroid Build Coastguard Worker size_type find(char c, size_type pos = 0) const; 323*1b3f573fSAndroid Build Coastguard Worker size_type rfind(StringPiece s, size_type pos = npos) const; 324*1b3f573fSAndroid Build Coastguard Worker size_type rfind(char c, size_type pos = npos) const; 325*1b3f573fSAndroid Build Coastguard Worker 326*1b3f573fSAndroid Build Coastguard Worker size_type find_first_of(StringPiece s, size_type pos = 0) const; 327*1b3f573fSAndroid Build Coastguard Worker size_type find_first_of(char c, size_type pos = 0) const { 328*1b3f573fSAndroid Build Coastguard Worker return find(c, pos); 329*1b3f573fSAndroid Build Coastguard Worker } 330*1b3f573fSAndroid Build Coastguard Worker size_type find_first_not_of(StringPiece s, size_type pos = 0) const; 331*1b3f573fSAndroid Build Coastguard Worker size_type find_first_not_of(char c, size_type pos = 0) const; 332*1b3f573fSAndroid Build Coastguard Worker size_type find_last_of(StringPiece s, size_type pos = npos) const; 333*1b3f573fSAndroid Build Coastguard Worker size_type find_last_of(char c, size_type pos = npos) const { 334*1b3f573fSAndroid Build Coastguard Worker return rfind(c, pos); 335*1b3f573fSAndroid Build Coastguard Worker } 336*1b3f573fSAndroid Build Coastguard Worker size_type find_last_not_of(StringPiece s, size_type pos = npos) const; 337*1b3f573fSAndroid Build Coastguard Worker size_type find_last_not_of(char c, size_type pos = npos) const; 338*1b3f573fSAndroid Build Coastguard Worker 339*1b3f573fSAndroid Build Coastguard Worker StringPiece substr(size_type pos, size_type n = npos) const; 340*1b3f573fSAndroid Build Coastguard Worker }; 341*1b3f573fSAndroid Build Coastguard Worker 342*1b3f573fSAndroid Build Coastguard Worker // This large function is defined inline so that in a fairly common case where 343*1b3f573fSAndroid Build Coastguard Worker // one of the arguments is a literal, the compiler can elide a lot of the 344*1b3f573fSAndroid Build Coastguard Worker // following comparisons. 345*1b3f573fSAndroid Build Coastguard Worker inline bool operator==(StringPiece x, StringPiece y) { 346*1b3f573fSAndroid Build Coastguard Worker StringPiece::size_type len = x.size(); 347*1b3f573fSAndroid Build Coastguard Worker if (len != y.size()) { 348*1b3f573fSAndroid Build Coastguard Worker return false; 349*1b3f573fSAndroid Build Coastguard Worker } 350*1b3f573fSAndroid Build Coastguard Worker 351*1b3f573fSAndroid Build Coastguard Worker return x.data() == y.data() || len <= 0 || 352*1b3f573fSAndroid Build Coastguard Worker memcmp(x.data(), y.data(), static_cast<size_t>(len)) == 0; 353*1b3f573fSAndroid Build Coastguard Worker } 354*1b3f573fSAndroid Build Coastguard Worker 355*1b3f573fSAndroid Build Coastguard Worker inline bool operator!=(StringPiece x, StringPiece y) { 356*1b3f573fSAndroid Build Coastguard Worker return !(x == y); 357*1b3f573fSAndroid Build Coastguard Worker } 358*1b3f573fSAndroid Build Coastguard Worker 359*1b3f573fSAndroid Build Coastguard Worker inline bool operator<(StringPiece x, StringPiece y) { 360*1b3f573fSAndroid Build Coastguard Worker const StringPiece::size_type min_size = 361*1b3f573fSAndroid Build Coastguard Worker x.size() < y.size() ? x.size() : y.size(); 362*1b3f573fSAndroid Build Coastguard Worker const int r = memcmp(x.data(), y.data(), static_cast<size_t>(min_size)); 363*1b3f573fSAndroid Build Coastguard Worker return (r < 0) || (r == 0 && x.size() < y.size()); 364*1b3f573fSAndroid Build Coastguard Worker } 365*1b3f573fSAndroid Build Coastguard Worker 366*1b3f573fSAndroid Build Coastguard Worker inline bool operator>(StringPiece x, StringPiece y) { 367*1b3f573fSAndroid Build Coastguard Worker return y < x; 368*1b3f573fSAndroid Build Coastguard Worker } 369*1b3f573fSAndroid Build Coastguard Worker 370*1b3f573fSAndroid Build Coastguard Worker inline bool operator<=(StringPiece x, StringPiece y) { 371*1b3f573fSAndroid Build Coastguard Worker return !(x > y); 372*1b3f573fSAndroid Build Coastguard Worker } 373*1b3f573fSAndroid Build Coastguard Worker 374*1b3f573fSAndroid Build Coastguard Worker inline bool operator>=(StringPiece x, StringPiece y) { 375*1b3f573fSAndroid Build Coastguard Worker return !(x < y); 376*1b3f573fSAndroid Build Coastguard Worker } 377*1b3f573fSAndroid Build Coastguard Worker 378*1b3f573fSAndroid Build Coastguard Worker // allow StringPiece to be logged 379*1b3f573fSAndroid Build Coastguard Worker extern std::ostream& operator<<(std::ostream& o, StringPiece piece); 380*1b3f573fSAndroid Build Coastguard Worker 381*1b3f573fSAndroid Build Coastguard Worker } // namespace stringpiece_internal 382*1b3f573fSAndroid Build Coastguard Worker 383*1b3f573fSAndroid Build Coastguard Worker using ::google::protobuf::stringpiece_internal::StringPiece; 384*1b3f573fSAndroid Build Coastguard Worker 385*1b3f573fSAndroid Build Coastguard Worker } // namespace protobuf 386*1b3f573fSAndroid Build Coastguard Worker } // namespace google 387*1b3f573fSAndroid Build Coastguard Worker 388*1b3f573fSAndroid Build Coastguard Worker GOOGLE_PROTOBUF_HASH_NAMESPACE_DECLARATION_START 389*1b3f573fSAndroid Build Coastguard Worker template<> struct hash<StringPiece> { 390*1b3f573fSAndroid Build Coastguard Worker size_t operator()(const StringPiece& s) const { 391*1b3f573fSAndroid Build Coastguard Worker size_t result = 0; 392*1b3f573fSAndroid Build Coastguard Worker for (const char *str = s.data(), *end = str + s.size(); str < end; str++) { 393*1b3f573fSAndroid Build Coastguard Worker result = 5 * result + static_cast<size_t>(*str); 394*1b3f573fSAndroid Build Coastguard Worker } 395*1b3f573fSAndroid Build Coastguard Worker return result; 396*1b3f573fSAndroid Build Coastguard Worker } 397*1b3f573fSAndroid Build Coastguard Worker }; 398*1b3f573fSAndroid Build Coastguard Worker GOOGLE_PROTOBUF_HASH_NAMESPACE_DECLARATION_END 399*1b3f573fSAndroid Build Coastguard Worker 400*1b3f573fSAndroid Build Coastguard Worker #include <google/protobuf/port_undef.inc> 401*1b3f573fSAndroid Build Coastguard Worker 402*1b3f573fSAndroid Build Coastguard Worker #endif // STRINGS_STRINGPIECE_H_ 403