1b0575e93e4c39dec69365b850088a1eb7f82c5b3Tamas Berghammer// Protocol Buffers - Google's data interchange format 2b0575e93e4c39dec69365b850088a1eb7f82c5b3Tamas Berghammer// Copyright 2008 Google Inc. All rights reserved. 3b0575e93e4c39dec69365b850088a1eb7f82c5b3Tamas Berghammer// https://developers.google.com/protocol-buffers/ 4b0575e93e4c39dec69365b850088a1eb7f82c5b3Tamas Berghammer// 5b0575e93e4c39dec69365b850088a1eb7f82c5b3Tamas Berghammer// Redistribution and use in source and binary forms, with or without 6b0575e93e4c39dec69365b850088a1eb7f82c5b3Tamas Berghammer// modification, are permitted provided that the following conditions are 7b0575e93e4c39dec69365b850088a1eb7f82c5b3Tamas Berghammer// met: 8b0575e93e4c39dec69365b850088a1eb7f82c5b3Tamas Berghammer// 9b0575e93e4c39dec69365b850088a1eb7f82c5b3Tamas Berghammer// * Redistributions of source code must retain the above copyright 10b0575e93e4c39dec69365b850088a1eb7f82c5b3Tamas Berghammer// notice, this list of conditions and the following disclaimer. 11b0575e93e4c39dec69365b850088a1eb7f82c5b3Tamas Berghammer// * Redistributions in binary form must reproduce the above 12b0575e93e4c39dec69365b850088a1eb7f82c5b3Tamas Berghammer// copyright notice, this list of conditions and the following disclaimer 13b0575e93e4c39dec69365b850088a1eb7f82c5b3Tamas Berghammer// in the documentation and/or other materials provided with the 14b0575e93e4c39dec69365b850088a1eb7f82c5b3Tamas Berghammer// distribution. 15b0575e93e4c39dec69365b850088a1eb7f82c5b3Tamas Berghammer// * Neither the name of Google Inc. nor the names of its 16b0575e93e4c39dec69365b850088a1eb7f82c5b3Tamas Berghammer// contributors may be used to endorse or promote products derived from 17b0575e93e4c39dec69365b850088a1eb7f82c5b3Tamas Berghammer// this software without specific prior written permission. 18b0575e93e4c39dec69365b850088a1eb7f82c5b3Tamas Berghammer// 19b0575e93e4c39dec69365b850088a1eb7f82c5b3Tamas Berghammer// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 20b0575e93e4c39dec69365b850088a1eb7f82c5b3Tamas Berghammer// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 21b0575e93e4c39dec69365b850088a1eb7f82c5b3Tamas Berghammer// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 22b0575e93e4c39dec69365b850088a1eb7f82c5b3Tamas Berghammer// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 23b0575e93e4c39dec69365b850088a1eb7f82c5b3Tamas Berghammer// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 24b0575e93e4c39dec69365b850088a1eb7f82c5b3Tamas Berghammer// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 25b0575e93e4c39dec69365b850088a1eb7f82c5b3Tamas Berghammer// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 26b0575e93e4c39dec69365b850088a1eb7f82c5b3Tamas Berghammer// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 27b0575e93e4c39dec69365b850088a1eb7f82c5b3Tamas Berghammer// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 28b0575e93e4c39dec69365b850088a1eb7f82c5b3Tamas Berghammer// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 29b0575e93e4c39dec69365b850088a1eb7f82c5b3Tamas Berghammer// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 30b0575e93e4c39dec69365b850088a1eb7f82c5b3Tamas Berghammer#include <google/protobuf/stubs/stringpiece.h> 31b0575e93e4c39dec69365b850088a1eb7f82c5b3Tamas Berghammer 32b0575e93e4c39dec69365b850088a1eb7f82c5b3Tamas Berghammer#include <string.h> 33b0575e93e4c39dec69365b850088a1eb7f82c5b3Tamas Berghammer#include <algorithm> 34b0575e93e4c39dec69365b850088a1eb7f82c5b3Tamas Berghammer#include <climits> 35b0575e93e4c39dec69365b850088a1eb7f82c5b3Tamas Berghammer#include <string> 36b0575e93e4c39dec69365b850088a1eb7f82c5b3Tamas Berghammer#include <ostream> 37b0575e93e4c39dec69365b850088a1eb7f82c5b3Tamas Berghammer 38b0575e93e4c39dec69365b850088a1eb7f82c5b3Tamas Berghammernamespace google { 39b0575e93e4c39dec69365b850088a1eb7f82c5b3Tamas Berghammernamespace protobuf { 40b0575e93e4c39dec69365b850088a1eb7f82c5b3Tamas Berghammerstd::ostream& operator<<(std::ostream& o, StringPiece piece) { 41b0575e93e4c39dec69365b850088a1eb7f82c5b3Tamas Berghammer o.write(piece.data(), piece.size()); 42b0575e93e4c39dec69365b850088a1eb7f82c5b3Tamas Berghammer return o; 43b0575e93e4c39dec69365b850088a1eb7f82c5b3Tamas Berghammer} 44b0575e93e4c39dec69365b850088a1eb7f82c5b3Tamas Berghammer 45b0575e93e4c39dec69365b850088a1eb7f82c5b3Tamas Berghammer// Out-of-line error path. 46b0575e93e4c39dec69365b850088a1eb7f82c5b3Tamas Berghammervoid StringPiece::LogFatalSizeTooBig(size_t size, const char* details) { 47b0575e93e4c39dec69365b850088a1eb7f82c5b3Tamas Berghammer GOOGLE_LOG(FATAL) << "size too big: " << size << " details: " << details; 48b0575e93e4c39dec69365b850088a1eb7f82c5b3Tamas Berghammer} 49b0575e93e4c39dec69365b850088a1eb7f82c5b3Tamas Berghammer 50b0575e93e4c39dec69365b850088a1eb7f82c5b3Tamas BerghammerStringPiece::StringPiece(StringPiece x, stringpiece_ssize_type pos) 51b0575e93e4c39dec69365b850088a1eb7f82c5b3Tamas Berghammer : ptr_(x.ptr_ + pos), length_(x.length_ - pos) { 52b0575e93e4c39dec69365b850088a1eb7f82c5b3Tamas Berghammer GOOGLE_DCHECK_LE(0, pos); 53b0575e93e4c39dec69365b850088a1eb7f82c5b3Tamas Berghammer GOOGLE_DCHECK_LE(pos, x.length_); 54b0575e93e4c39dec69365b850088a1eb7f82c5b3Tamas Berghammer} 55b0575e93e4c39dec69365b850088a1eb7f82c5b3Tamas Berghammer 56b0575e93e4c39dec69365b850088a1eb7f82c5b3Tamas BerghammerStringPiece::StringPiece(StringPiece x, 57b0575e93e4c39dec69365b850088a1eb7f82c5b3Tamas Berghammer stringpiece_ssize_type pos, 58b0575e93e4c39dec69365b850088a1eb7f82c5b3Tamas Berghammer stringpiece_ssize_type len) 59b0575e93e4c39dec69365b850088a1eb7f82c5b3Tamas Berghammer : ptr_(x.ptr_ + pos), length_(std::min(len, x.length_ - pos)) { 60b0575e93e4c39dec69365b850088a1eb7f82c5b3Tamas Berghammer GOOGLE_DCHECK_LE(0, pos); 61b0575e93e4c39dec69365b850088a1eb7f82c5b3Tamas Berghammer GOOGLE_DCHECK_LE(pos, x.length_); 62b0575e93e4c39dec69365b850088a1eb7f82c5b3Tamas Berghammer GOOGLE_DCHECK_GE(len, 0); 63b0575e93e4c39dec69365b850088a1eb7f82c5b3Tamas Berghammer} 64b0575e93e4c39dec69365b850088a1eb7f82c5b3Tamas Berghammer 65b0575e93e4c39dec69365b850088a1eb7f82c5b3Tamas Berghammervoid StringPiece::CopyToString(string* target) const { 66b0575e93e4c39dec69365b850088a1eb7f82c5b3Tamas Berghammer target->assign(ptr_, length_); 67b0575e93e4c39dec69365b850088a1eb7f82c5b3Tamas Berghammer} 68b0575e93e4c39dec69365b850088a1eb7f82c5b3Tamas Berghammer 69b0575e93e4c39dec69365b850088a1eb7f82c5b3Tamas Berghammervoid StringPiece::AppendToString(string* target) const { 70b0575e93e4c39dec69365b850088a1eb7f82c5b3Tamas Berghammer target->append(ptr_, length_); 71b0575e93e4c39dec69365b850088a1eb7f82c5b3Tamas Berghammer} 72b0575e93e4c39dec69365b850088a1eb7f82c5b3Tamas Berghammer 73b0575e93e4c39dec69365b850088a1eb7f82c5b3Tamas Berghammerbool StringPiece::Consume(StringPiece x) { 74b0575e93e4c39dec69365b850088a1eb7f82c5b3Tamas Berghammer if (starts_with(x)) { 75b0575e93e4c39dec69365b850088a1eb7f82c5b3Tamas Berghammer ptr_ += x.length_; 76b0575e93e4c39dec69365b850088a1eb7f82c5b3Tamas Berghammer length_ -= x.length_; 77b0575e93e4c39dec69365b850088a1eb7f82c5b3Tamas Berghammer return true; 78b0575e93e4c39dec69365b850088a1eb7f82c5b3Tamas Berghammer } 79b0575e93e4c39dec69365b850088a1eb7f82c5b3Tamas Berghammer return false; 80b0575e93e4c39dec69365b850088a1eb7f82c5b3Tamas Berghammer} 81b0575e93e4c39dec69365b850088a1eb7f82c5b3Tamas Berghammer 82b0575e93e4c39dec69365b850088a1eb7f82c5b3Tamas Berghammerbool StringPiece::ConsumeFromEnd(StringPiece x) { 83b0575e93e4c39dec69365b850088a1eb7f82c5b3Tamas Berghammer if (ends_with(x)) { 84b0575e93e4c39dec69365b850088a1eb7f82c5b3Tamas Berghammer length_ -= x.length_; 85b0575e93e4c39dec69365b850088a1eb7f82c5b3Tamas Berghammer return true; 86b0575e93e4c39dec69365b850088a1eb7f82c5b3Tamas Berghammer } 87b0575e93e4c39dec69365b850088a1eb7f82c5b3Tamas Berghammer return false; 88b0575e93e4c39dec69365b850088a1eb7f82c5b3Tamas Berghammer} 89b0575e93e4c39dec69365b850088a1eb7f82c5b3Tamas Berghammer 90b0575e93e4c39dec69365b850088a1eb7f82c5b3Tamas Berghammerstringpiece_ssize_type StringPiece::copy(char* buf, 91b0575e93e4c39dec69365b850088a1eb7f82c5b3Tamas Berghammer size_type n, 92b0575e93e4c39dec69365b850088a1eb7f82c5b3Tamas Berghammer size_type pos) const { 93b0575e93e4c39dec69365b850088a1eb7f82c5b3Tamas Berghammer stringpiece_ssize_type ret = std::min(length_ - pos, n); 94b0575e93e4c39dec69365b850088a1eb7f82c5b3Tamas Berghammer memcpy(buf, ptr_ + pos, ret); 95b0575e93e4c39dec69365b850088a1eb7f82c5b3Tamas Berghammer return ret; 96b0575e93e4c39dec69365b850088a1eb7f82c5b3Tamas Berghammer} 97b0575e93e4c39dec69365b850088a1eb7f82c5b3Tamas Berghammer 98b0575e93e4c39dec69365b850088a1eb7f82c5b3Tamas Berghammerbool StringPiece::contains(StringPiece s) const { 99b0575e93e4c39dec69365b850088a1eb7f82c5b3Tamas Berghammer return find(s, 0) != npos; 100b0575e93e4c39dec69365b850088a1eb7f82c5b3Tamas Berghammer} 101b0575e93e4c39dec69365b850088a1eb7f82c5b3Tamas Berghammer 102b0575e93e4c39dec69365b850088a1eb7f82c5b3Tamas Berghammerstringpiece_ssize_type StringPiece::find(StringPiece s, size_type pos) const { 103b0575e93e4c39dec69365b850088a1eb7f82c5b3Tamas Berghammer if (length_ <= 0 || pos > static_cast<size_type>(length_)) { 104b0575e93e4c39dec69365b850088a1eb7f82c5b3Tamas Berghammer if (length_ == 0 && pos == 0 && s.length_ == 0) return 0; 105b0575e93e4c39dec69365b850088a1eb7f82c5b3Tamas Berghammer return npos; 106b0575e93e4c39dec69365b850088a1eb7f82c5b3Tamas Berghammer } 107b0575e93e4c39dec69365b850088a1eb7f82c5b3Tamas Berghammer const char *result = std::search(ptr_ + pos, ptr_ + length_, 108b0575e93e4c39dec69365b850088a1eb7f82c5b3Tamas Berghammer s.ptr_, s.ptr_ + s.length_); 109b0575e93e4c39dec69365b850088a1eb7f82c5b3Tamas Berghammer return result == ptr_ + length_ ? npos : result - ptr_; 110b0575e93e4c39dec69365b850088a1eb7f82c5b3Tamas Berghammer} 111b0575e93e4c39dec69365b850088a1eb7f82c5b3Tamas Berghammer 112b0575e93e4c39dec69365b850088a1eb7f82c5b3Tamas Berghammerstringpiece_ssize_type StringPiece::find(char c, size_type pos) const { 113b0575e93e4c39dec69365b850088a1eb7f82c5b3Tamas Berghammer if (length_ <= 0 || pos >= static_cast<size_type>(length_)) { 114b0575e93e4c39dec69365b850088a1eb7f82c5b3Tamas Berghammer return npos; 115b0575e93e4c39dec69365b850088a1eb7f82c5b3Tamas Berghammer } 116b0575e93e4c39dec69365b850088a1eb7f82c5b3Tamas Berghammer const char* result = static_cast<const char*>( 117b0575e93e4c39dec69365b850088a1eb7f82c5b3Tamas Berghammer memchr(ptr_ + pos, c, length_ - pos)); 118b0575e93e4c39dec69365b850088a1eb7f82c5b3Tamas Berghammer return result != NULL ? result - ptr_ : npos; 119b0575e93e4c39dec69365b850088a1eb7f82c5b3Tamas Berghammer} 120b0575e93e4c39dec69365b850088a1eb7f82c5b3Tamas Berghammer 121b0575e93e4c39dec69365b850088a1eb7f82c5b3Tamas Berghammerstringpiece_ssize_type StringPiece::rfind(StringPiece s, size_type pos) const { 122b0575e93e4c39dec69365b850088a1eb7f82c5b3Tamas Berghammer if (length_ < s.length_) return npos; 123b0575e93e4c39dec69365b850088a1eb7f82c5b3Tamas Berghammer const size_t ulen = length_; 124b0575e93e4c39dec69365b850088a1eb7f82c5b3Tamas Berghammer if (s.length_ == 0) return std::min(ulen, pos); 125b0575e93e4c39dec69365b850088a1eb7f82c5b3Tamas Berghammer 126b0575e93e4c39dec69365b850088a1eb7f82c5b3Tamas Berghammer const char* last = ptr_ + std::min(ulen - s.length_, pos) + s.length_; 127b0575e93e4c39dec69365b850088a1eb7f82c5b3Tamas Berghammer const char* result = std::find_end(ptr_, last, s.ptr_, s.ptr_ + s.length_); 128b0575e93e4c39dec69365b850088a1eb7f82c5b3Tamas Berghammer return result != last ? result - ptr_ : npos; 129b0575e93e4c39dec69365b850088a1eb7f82c5b3Tamas Berghammer} 130b0575e93e4c39dec69365b850088a1eb7f82c5b3Tamas Berghammer 131b0575e93e4c39dec69365b850088a1eb7f82c5b3Tamas Berghammer// Search range is [0..pos] inclusive. If pos == npos, search everything. 132b0575e93e4c39dec69365b850088a1eb7f82c5b3Tamas Berghammerstringpiece_ssize_type StringPiece::rfind(char c, size_type pos) const { 133b0575e93e4c39dec69365b850088a1eb7f82c5b3Tamas Berghammer // Note: memrchr() is not available on Windows. 134b0575e93e4c39dec69365b850088a1eb7f82c5b3Tamas Berghammer if (length_ <= 0) return npos; 135b0575e93e4c39dec69365b850088a1eb7f82c5b3Tamas Berghammer for (stringpiece_ssize_type i = 136b0575e93e4c39dec69365b850088a1eb7f82c5b3Tamas Berghammer std::min(pos, static_cast<size_type>(length_ - 1)); 137b0575e93e4c39dec69365b850088a1eb7f82c5b3Tamas Berghammer i >= 0; --i) { 138b0575e93e4c39dec69365b850088a1eb7f82c5b3Tamas Berghammer if (ptr_[i] == c) { 139b0575e93e4c39dec69365b850088a1eb7f82c5b3Tamas Berghammer return i; 140b0575e93e4c39dec69365b850088a1eb7f82c5b3Tamas Berghammer } 141b0575e93e4c39dec69365b850088a1eb7f82c5b3Tamas Berghammer } 142b0575e93e4c39dec69365b850088a1eb7f82c5b3Tamas Berghammer return npos; 143b0575e93e4c39dec69365b850088a1eb7f82c5b3Tamas Berghammer} 144b0575e93e4c39dec69365b850088a1eb7f82c5b3Tamas Berghammer 145b0575e93e4c39dec69365b850088a1eb7f82c5b3Tamas Berghammer// For each character in characters_wanted, sets the index corresponding 146b0575e93e4c39dec69365b850088a1eb7f82c5b3Tamas Berghammer// to the ASCII code of that character to 1 in table. This is used by 147b0575e93e4c39dec69365b850088a1eb7f82c5b3Tamas Berghammer// the find_.*_of methods below to tell whether or not a character is in 148b0575e93e4c39dec69365b850088a1eb7f82c5b3Tamas Berghammer// the lookup table in constant time. 149b0575e93e4c39dec69365b850088a1eb7f82c5b3Tamas Berghammer// The argument `table' must be an array that is large enough to hold all 150b0575e93e4c39dec69365b850088a1eb7f82c5b3Tamas Berghammer// the possible values of an unsigned char. Thus it should be be declared 151b0575e93e4c39dec69365b850088a1eb7f82c5b3Tamas Berghammer// as follows: 152b0575e93e4c39dec69365b850088a1eb7f82c5b3Tamas Berghammer// bool table[UCHAR_MAX + 1] 153b0575e93e4c39dec69365b850088a1eb7f82c5b3Tamas Berghammerstatic inline void BuildLookupTable(StringPiece characters_wanted, 154b0575e93e4c39dec69365b850088a1eb7f82c5b3Tamas Berghammer bool* table) { 155b0575e93e4c39dec69365b850088a1eb7f82c5b3Tamas Berghammer const stringpiece_ssize_type length = characters_wanted.length(); 156b0575e93e4c39dec69365b850088a1eb7f82c5b3Tamas Berghammer const char* const data = characters_wanted.data(); 157b0575e93e4c39dec69365b850088a1eb7f82c5b3Tamas Berghammer for (stringpiece_ssize_type i = 0; i < length; ++i) { 158b0575e93e4c39dec69365b850088a1eb7f82c5b3Tamas Berghammer table[static_cast<unsigned char>(data[i])] = true; 159b0575e93e4c39dec69365b850088a1eb7f82c5b3Tamas Berghammer } 160b0575e93e4c39dec69365b850088a1eb7f82c5b3Tamas Berghammer} 161b0575e93e4c39dec69365b850088a1eb7f82c5b3Tamas Berghammer 162b0575e93e4c39dec69365b850088a1eb7f82c5b3Tamas Berghammerstringpiece_ssize_type StringPiece::find_first_of(StringPiece s, 163b0575e93e4c39dec69365b850088a1eb7f82c5b3Tamas Berghammer size_type pos) const { 164b0575e93e4c39dec69365b850088a1eb7f82c5b3Tamas Berghammer if (length_ <= 0 || s.length_ <= 0) { 165b0575e93e4c39dec69365b850088a1eb7f82c5b3Tamas Berghammer return npos; 166b0575e93e4c39dec69365b850088a1eb7f82c5b3Tamas Berghammer } 167b0575e93e4c39dec69365b850088a1eb7f82c5b3Tamas Berghammer // Avoid the cost of BuildLookupTable() for a single-character search. 168b0575e93e4c39dec69365b850088a1eb7f82c5b3Tamas Berghammer if (s.length_ == 1) return find_first_of(s.ptr_[0], pos); 169b0575e93e4c39dec69365b850088a1eb7f82c5b3Tamas Berghammer 170b0575e93e4c39dec69365b850088a1eb7f82c5b3Tamas Berghammer bool lookup[UCHAR_MAX + 1] = { false }; 171b0575e93e4c39dec69365b850088a1eb7f82c5b3Tamas Berghammer BuildLookupTable(s, lookup); 172b0575e93e4c39dec69365b850088a1eb7f82c5b3Tamas Berghammer for (stringpiece_ssize_type i = pos; i < length_; ++i) { 173b0575e93e4c39dec69365b850088a1eb7f82c5b3Tamas Berghammer if (lookup[static_cast<unsigned char>(ptr_[i])]) { 174b0575e93e4c39dec69365b850088a1eb7f82c5b3Tamas Berghammer return i; 175b0575e93e4c39dec69365b850088a1eb7f82c5b3Tamas Berghammer } 176b0575e93e4c39dec69365b850088a1eb7f82c5b3Tamas Berghammer } 177b0575e93e4c39dec69365b850088a1eb7f82c5b3Tamas Berghammer return npos; 178b0575e93e4c39dec69365b850088a1eb7f82c5b3Tamas Berghammer} 179b0575e93e4c39dec69365b850088a1eb7f82c5b3Tamas Berghammer 180b0575e93e4c39dec69365b850088a1eb7f82c5b3Tamas Berghammerstringpiece_ssize_type StringPiece::find_first_not_of(StringPiece s, 181b0575e93e4c39dec69365b850088a1eb7f82c5b3Tamas Berghammer size_type pos) const { 182b0575e93e4c39dec69365b850088a1eb7f82c5b3Tamas Berghammer if (length_ <= 0) return npos; 183b0575e93e4c39dec69365b850088a1eb7f82c5b3Tamas Berghammer if (s.length_ <= 0) return 0; 184b0575e93e4c39dec69365b850088a1eb7f82c5b3Tamas Berghammer // Avoid the cost of BuildLookupTable() for a single-character search. 185b0575e93e4c39dec69365b850088a1eb7f82c5b3Tamas Berghammer if (s.length_ == 1) return find_first_not_of(s.ptr_[0], pos); 186b0575e93e4c39dec69365b850088a1eb7f82c5b3Tamas Berghammer 187b0575e93e4c39dec69365b850088a1eb7f82c5b3Tamas Berghammer bool lookup[UCHAR_MAX + 1] = { false }; 188b0575e93e4c39dec69365b850088a1eb7f82c5b3Tamas Berghammer BuildLookupTable(s, lookup); 189b0575e93e4c39dec69365b850088a1eb7f82c5b3Tamas Berghammer for (stringpiece_ssize_type i = pos; i < length_; ++i) { 190b0575e93e4c39dec69365b850088a1eb7f82c5b3Tamas Berghammer if (!lookup[static_cast<unsigned char>(ptr_[i])]) { 191b0575e93e4c39dec69365b850088a1eb7f82c5b3Tamas Berghammer return i; 192b0575e93e4c39dec69365b850088a1eb7f82c5b3Tamas Berghammer } 193b0575e93e4c39dec69365b850088a1eb7f82c5b3Tamas Berghammer } 194b0575e93e4c39dec69365b850088a1eb7f82c5b3Tamas Berghammer return npos; 195b0575e93e4c39dec69365b850088a1eb7f82c5b3Tamas Berghammer} 196b0575e93e4c39dec69365b850088a1eb7f82c5b3Tamas Berghammer 197b0575e93e4c39dec69365b850088a1eb7f82c5b3Tamas Berghammerstringpiece_ssize_type StringPiece::find_first_not_of(char c, 198b0575e93e4c39dec69365b850088a1eb7f82c5b3Tamas Berghammer size_type pos) const { 199b0575e93e4c39dec69365b850088a1eb7f82c5b3Tamas Berghammer if (length_ <= 0) return npos; 200b0575e93e4c39dec69365b850088a1eb7f82c5b3Tamas Berghammer 201b0575e93e4c39dec69365b850088a1eb7f82c5b3Tamas Berghammer for (; pos < static_cast<size_type>(length_); ++pos) { 202b0575e93e4c39dec69365b850088a1eb7f82c5b3Tamas Berghammer if (ptr_[pos] != c) { 203b0575e93e4c39dec69365b850088a1eb7f82c5b3Tamas Berghammer return pos; 204b0575e93e4c39dec69365b850088a1eb7f82c5b3Tamas Berghammer } 205b0575e93e4c39dec69365b850088a1eb7f82c5b3Tamas Berghammer } 206b0575e93e4c39dec69365b850088a1eb7f82c5b3Tamas Berghammer return npos; 207b0575e93e4c39dec69365b850088a1eb7f82c5b3Tamas Berghammer} 208b0575e93e4c39dec69365b850088a1eb7f82c5b3Tamas Berghammer 209b0575e93e4c39dec69365b850088a1eb7f82c5b3Tamas Berghammerstringpiece_ssize_type StringPiece::find_last_of(StringPiece s, 210b0575e93e4c39dec69365b850088a1eb7f82c5b3Tamas Berghammer size_type pos) const { 211b0575e93e4c39dec69365b850088a1eb7f82c5b3Tamas Berghammer if (length_ <= 0 || s.length_ <= 0) return npos; 212b0575e93e4c39dec69365b850088a1eb7f82c5b3Tamas Berghammer // Avoid the cost of BuildLookupTable() for a single-character search. 213b0575e93e4c39dec69365b850088a1eb7f82c5b3Tamas Berghammer if (s.length_ == 1) return find_last_of(s.ptr_[0], pos); 214b0575e93e4c39dec69365b850088a1eb7f82c5b3Tamas Berghammer 215b0575e93e4c39dec69365b850088a1eb7f82c5b3Tamas Berghammer bool lookup[UCHAR_MAX + 1] = { false }; 216b0575e93e4c39dec69365b850088a1eb7f82c5b3Tamas Berghammer BuildLookupTable(s, lookup); 217b0575e93e4c39dec69365b850088a1eb7f82c5b3Tamas Berghammer for (stringpiece_ssize_type i = 218b0575e93e4c39dec69365b850088a1eb7f82c5b3Tamas Berghammer std::min(pos, static_cast<size_type>(length_ - 1)); i >= 0; --i) { 219b0575e93e4c39dec69365b850088a1eb7f82c5b3Tamas Berghammer if (lookup[static_cast<unsigned char>(ptr_[i])]) { 220b0575e93e4c39dec69365b850088a1eb7f82c5b3Tamas Berghammer return i; 221b0575e93e4c39dec69365b850088a1eb7f82c5b3Tamas Berghammer } 222b0575e93e4c39dec69365b850088a1eb7f82c5b3Tamas Berghammer } 223b0575e93e4c39dec69365b850088a1eb7f82c5b3Tamas Berghammer return npos; 224b0575e93e4c39dec69365b850088a1eb7f82c5b3Tamas Berghammer} 225b0575e93e4c39dec69365b850088a1eb7f82c5b3Tamas Berghammer 226b0575e93e4c39dec69365b850088a1eb7f82c5b3Tamas Berghammerstringpiece_ssize_type StringPiece::find_last_not_of(StringPiece s, 227b0575e93e4c39dec69365b850088a1eb7f82c5b3Tamas Berghammer size_type pos) const { 228b0575e93e4c39dec69365b850088a1eb7f82c5b3Tamas Berghammer if (length_ <= 0) return npos; 229b0575e93e4c39dec69365b850088a1eb7f82c5b3Tamas Berghammer 230b0575e93e4c39dec69365b850088a1eb7f82c5b3Tamas Berghammer stringpiece_ssize_type i = std::min(pos, static_cast<size_type>(length_ - 1)); 231b0575e93e4c39dec69365b850088a1eb7f82c5b3Tamas Berghammer if (s.length_ <= 0) return i; 232b0575e93e4c39dec69365b850088a1eb7f82c5b3Tamas Berghammer 233b0575e93e4c39dec69365b850088a1eb7f82c5b3Tamas Berghammer // Avoid the cost of BuildLookupTable() for a single-character search. 234b0575e93e4c39dec69365b850088a1eb7f82c5b3Tamas Berghammer if (s.length_ == 1) return find_last_not_of(s.ptr_[0], pos); 235b0575e93e4c39dec69365b850088a1eb7f82c5b3Tamas Berghammer 236b0575e93e4c39dec69365b850088a1eb7f82c5b3Tamas Berghammer bool lookup[UCHAR_MAX + 1] = { false }; 237b0575e93e4c39dec69365b850088a1eb7f82c5b3Tamas Berghammer BuildLookupTable(s, lookup); 238b0575e93e4c39dec69365b850088a1eb7f82c5b3Tamas Berghammer for (; i >= 0; --i) { 239b0575e93e4c39dec69365b850088a1eb7f82c5b3Tamas Berghammer if (!lookup[static_cast<unsigned char>(ptr_[i])]) { 240b0575e93e4c39dec69365b850088a1eb7f82c5b3Tamas Berghammer return i; 241b0575e93e4c39dec69365b850088a1eb7f82c5b3Tamas Berghammer } 242b0575e93e4c39dec69365b850088a1eb7f82c5b3Tamas Berghammer } 243b0575e93e4c39dec69365b850088a1eb7f82c5b3Tamas Berghammer return npos; 244b0575e93e4c39dec69365b850088a1eb7f82c5b3Tamas Berghammer} 245b0575e93e4c39dec69365b850088a1eb7f82c5b3Tamas Berghammer 246b0575e93e4c39dec69365b850088a1eb7f82c5b3Tamas Berghammerstringpiece_ssize_type StringPiece::find_last_not_of(char c, 247b0575e93e4c39dec69365b850088a1eb7f82c5b3Tamas Berghammer size_type pos) const { 248b0575e93e4c39dec69365b850088a1eb7f82c5b3Tamas Berghammer if (length_ <= 0) return npos; 249b0575e93e4c39dec69365b850088a1eb7f82c5b3Tamas Berghammer 250b0575e93e4c39dec69365b850088a1eb7f82c5b3Tamas Berghammer for (stringpiece_ssize_type i = 251b0575e93e4c39dec69365b850088a1eb7f82c5b3Tamas Berghammer std::min(pos, static_cast<size_type>(length_ - 1)); i >= 0; --i) { 252b0575e93e4c39dec69365b850088a1eb7f82c5b3Tamas Berghammer if (ptr_[i] != c) { 253b0575e93e4c39dec69365b850088a1eb7f82c5b3Tamas Berghammer return i; 254b0575e93e4c39dec69365b850088a1eb7f82c5b3Tamas Berghammer } 255b0575e93e4c39dec69365b850088a1eb7f82c5b3Tamas Berghammer } 256b0575e93e4c39dec69365b850088a1eb7f82c5b3Tamas Berghammer return npos; 257b0575e93e4c39dec69365b850088a1eb7f82c5b3Tamas Berghammer} 258b0575e93e4c39dec69365b850088a1eb7f82c5b3Tamas Berghammer 259b0575e93e4c39dec69365b850088a1eb7f82c5b3Tamas BerghammerStringPiece StringPiece::substr(size_type pos, size_type n) const { 260b0575e93e4c39dec69365b850088a1eb7f82c5b3Tamas Berghammer if (pos > length_) pos = length_; 261b0575e93e4c39dec69365b850088a1eb7f82c5b3Tamas Berghammer if (n > length_ - pos) n = length_ - pos; 262b0575e93e4c39dec69365b850088a1eb7f82c5b3Tamas Berghammer return StringPiece(ptr_ + pos, n); 263b0575e93e4c39dec69365b850088a1eb7f82c5b3Tamas Berghammer} 264b0575e93e4c39dec69365b850088a1eb7f82c5b3Tamas Berghammer 265b0575e93e4c39dec69365b850088a1eb7f82c5b3Tamas Berghammerconst StringPiece::size_type StringPiece::npos = size_type(-1); 266b0575e93e4c39dec69365b850088a1eb7f82c5b3Tamas Berghammer 267b0575e93e4c39dec69365b850088a1eb7f82c5b3Tamas Berghammer} // namespace protobuf 268b0575e93e4c39dec69365b850088a1eb7f82c5b3Tamas Berghammer} // namespace google 269