12ee91b4af4353b9e6a9d591c32fedfc58fd4ef35Ian Hodson// Copyright 2004 The RE2 Authors. All Rights Reserved. 22ee91b4af4353b9e6a9d591c32fedfc58fd4ef35Ian Hodson// Use of this source code is governed by a BSD-style 32ee91b4af4353b9e6a9d591c32fedfc58fd4ef35Ian Hodson// license that can be found in the LICENSE file. 42ee91b4af4353b9e6a9d591c32fedfc58fd4ef35Ian Hodson 52ee91b4af4353b9e6a9d591c32fedfc58fd4ef35Ian Hodson#include "re2/stringpiece.h" 62ee91b4af4353b9e6a9d591c32fedfc58fd4ef35Ian Hodson#include "util/util.h" 72ee91b4af4353b9e6a9d591c32fedfc58fd4ef35Ian Hodson 82ee91b4af4353b9e6a9d591c32fedfc58fd4ef35Ian Hodsonusing re2::StringPiece; 92ee91b4af4353b9e6a9d591c32fedfc58fd4ef35Ian Hodson 102ee91b4af4353b9e6a9d591c32fedfc58fd4ef35Ian Hodsonstd::ostream& operator<<(std::ostream& o, const StringPiece& piece) { 112ee91b4af4353b9e6a9d591c32fedfc58fd4ef35Ian Hodson o.write(piece.data(), piece.size()); 122ee91b4af4353b9e6a9d591c32fedfc58fd4ef35Ian Hodson return o; 132ee91b4af4353b9e6a9d591c32fedfc58fd4ef35Ian Hodson} 142ee91b4af4353b9e6a9d591c32fedfc58fd4ef35Ian Hodson 152ee91b4af4353b9e6a9d591c32fedfc58fd4ef35Ian Hodsonbool StringPiece::_equal(const StringPiece& x, const StringPiece& y) { 162ee91b4af4353b9e6a9d591c32fedfc58fd4ef35Ian Hodson int len = x.size(); 172ee91b4af4353b9e6a9d591c32fedfc58fd4ef35Ian Hodson if (len != y.size()) { 182ee91b4af4353b9e6a9d591c32fedfc58fd4ef35Ian Hodson return false; 192ee91b4af4353b9e6a9d591c32fedfc58fd4ef35Ian Hodson } 202ee91b4af4353b9e6a9d591c32fedfc58fd4ef35Ian Hodson const char* p = x.data(); 212ee91b4af4353b9e6a9d591c32fedfc58fd4ef35Ian Hodson const char* p2 = y.data(); 222ee91b4af4353b9e6a9d591c32fedfc58fd4ef35Ian Hodson // Test last byte in case strings share large common prefix 232ee91b4af4353b9e6a9d591c32fedfc58fd4ef35Ian Hodson if ((len > 0) && (p[len-1] != p2[len-1])) return false; 242ee91b4af4353b9e6a9d591c32fedfc58fd4ef35Ian Hodson const char* p_limit = p + len; 252ee91b4af4353b9e6a9d591c32fedfc58fd4ef35Ian Hodson for (; p < p_limit; p++, p2++) { 262ee91b4af4353b9e6a9d591c32fedfc58fd4ef35Ian Hodson if (*p != *p2) 272ee91b4af4353b9e6a9d591c32fedfc58fd4ef35Ian Hodson return false; 282ee91b4af4353b9e6a9d591c32fedfc58fd4ef35Ian Hodson } 292ee91b4af4353b9e6a9d591c32fedfc58fd4ef35Ian Hodson return true; 302ee91b4af4353b9e6a9d591c32fedfc58fd4ef35Ian Hodson} 312ee91b4af4353b9e6a9d591c32fedfc58fd4ef35Ian Hodson 322ee91b4af4353b9e6a9d591c32fedfc58fd4ef35Ian Hodsonvoid StringPiece::CopyToString(string* target) const { 332ee91b4af4353b9e6a9d591c32fedfc58fd4ef35Ian Hodson target->assign(ptr_, length_); 342ee91b4af4353b9e6a9d591c32fedfc58fd4ef35Ian Hodson} 352ee91b4af4353b9e6a9d591c32fedfc58fd4ef35Ian Hodson 362ee91b4af4353b9e6a9d591c32fedfc58fd4ef35Ian Hodsonint StringPiece::copy(char* buf, size_type n, size_type pos) const { 372ee91b4af4353b9e6a9d591c32fedfc58fd4ef35Ian Hodson int ret = min(length_ - pos, n); 382ee91b4af4353b9e6a9d591c32fedfc58fd4ef35Ian Hodson memcpy(buf, ptr_ + pos, ret); 392ee91b4af4353b9e6a9d591c32fedfc58fd4ef35Ian Hodson return ret; 402ee91b4af4353b9e6a9d591c32fedfc58fd4ef35Ian Hodson} 412ee91b4af4353b9e6a9d591c32fedfc58fd4ef35Ian Hodson 422ee91b4af4353b9e6a9d591c32fedfc58fd4ef35Ian Hodsonint StringPiece::find(const StringPiece& s, size_type pos) const { 432ee91b4af4353b9e6a9d591c32fedfc58fd4ef35Ian Hodson if (length_ < 0 || pos > static_cast<size_type>(length_)) 442ee91b4af4353b9e6a9d591c32fedfc58fd4ef35Ian Hodson return npos; 452ee91b4af4353b9e6a9d591c32fedfc58fd4ef35Ian Hodson 462ee91b4af4353b9e6a9d591c32fedfc58fd4ef35Ian Hodson const char* result = std::search(ptr_ + pos, ptr_ + length_, 472ee91b4af4353b9e6a9d591c32fedfc58fd4ef35Ian Hodson s.ptr_, s.ptr_ + s.length_); 482ee91b4af4353b9e6a9d591c32fedfc58fd4ef35Ian Hodson const size_type xpos = result - ptr_; 492ee91b4af4353b9e6a9d591c32fedfc58fd4ef35Ian Hodson return xpos + s.length_ <= length_ ? xpos : npos; 502ee91b4af4353b9e6a9d591c32fedfc58fd4ef35Ian Hodson} 512ee91b4af4353b9e6a9d591c32fedfc58fd4ef35Ian Hodson 522ee91b4af4353b9e6a9d591c32fedfc58fd4ef35Ian Hodsonint StringPiece::find(char c, size_type pos) const { 532ee91b4af4353b9e6a9d591c32fedfc58fd4ef35Ian Hodson if (length_ <= 0 || pos >= static_cast<size_type>(length_)) { 542ee91b4af4353b9e6a9d591c32fedfc58fd4ef35Ian Hodson return npos; 552ee91b4af4353b9e6a9d591c32fedfc58fd4ef35Ian Hodson } 562ee91b4af4353b9e6a9d591c32fedfc58fd4ef35Ian Hodson const char* result = std::find(ptr_ + pos, ptr_ + length_, c); 572ee91b4af4353b9e6a9d591c32fedfc58fd4ef35Ian Hodson return result != ptr_ + length_ ? result - ptr_ : npos; 582ee91b4af4353b9e6a9d591c32fedfc58fd4ef35Ian Hodson} 592ee91b4af4353b9e6a9d591c32fedfc58fd4ef35Ian Hodson 602ee91b4af4353b9e6a9d591c32fedfc58fd4ef35Ian Hodsonint StringPiece::rfind(const StringPiece& s, size_type pos) const { 612ee91b4af4353b9e6a9d591c32fedfc58fd4ef35Ian Hodson if (length_ < s.length_) return npos; 622ee91b4af4353b9e6a9d591c32fedfc58fd4ef35Ian Hodson const size_t ulen = length_; 632ee91b4af4353b9e6a9d591c32fedfc58fd4ef35Ian Hodson if (s.length_ == 0) return min(ulen, pos); 642ee91b4af4353b9e6a9d591c32fedfc58fd4ef35Ian Hodson 652ee91b4af4353b9e6a9d591c32fedfc58fd4ef35Ian Hodson const char* last = ptr_ + min(ulen - s.length_, pos) + s.length_; 662ee91b4af4353b9e6a9d591c32fedfc58fd4ef35Ian Hodson const char* result = std::find_end(ptr_, last, s.ptr_, s.ptr_ + s.length_); 672ee91b4af4353b9e6a9d591c32fedfc58fd4ef35Ian Hodson return result != last ? result - ptr_ : npos; 682ee91b4af4353b9e6a9d591c32fedfc58fd4ef35Ian Hodson} 692ee91b4af4353b9e6a9d591c32fedfc58fd4ef35Ian Hodson 702ee91b4af4353b9e6a9d591c32fedfc58fd4ef35Ian Hodsonint StringPiece::rfind(char c, size_type pos) const { 712ee91b4af4353b9e6a9d591c32fedfc58fd4ef35Ian Hodson if (length_ <= 0) return npos; 722ee91b4af4353b9e6a9d591c32fedfc58fd4ef35Ian Hodson for (int i = min(pos, static_cast<size_type>(length_ - 1)); 732ee91b4af4353b9e6a9d591c32fedfc58fd4ef35Ian Hodson i >= 0; --i) { 742ee91b4af4353b9e6a9d591c32fedfc58fd4ef35Ian Hodson if (ptr_[i] == c) { 752ee91b4af4353b9e6a9d591c32fedfc58fd4ef35Ian Hodson return i; 762ee91b4af4353b9e6a9d591c32fedfc58fd4ef35Ian Hodson } 772ee91b4af4353b9e6a9d591c32fedfc58fd4ef35Ian Hodson } 782ee91b4af4353b9e6a9d591c32fedfc58fd4ef35Ian Hodson return npos; 792ee91b4af4353b9e6a9d591c32fedfc58fd4ef35Ian Hodson} 802ee91b4af4353b9e6a9d591c32fedfc58fd4ef35Ian Hodson 812ee91b4af4353b9e6a9d591c32fedfc58fd4ef35Ian HodsonStringPiece StringPiece::substr(size_type pos, size_type n) const { 822ee91b4af4353b9e6a9d591c32fedfc58fd4ef35Ian Hodson if (pos > length_) pos = length_; 832ee91b4af4353b9e6a9d591c32fedfc58fd4ef35Ian Hodson if (n > length_ - pos) n = length_ - pos; 842ee91b4af4353b9e6a9d591c32fedfc58fd4ef35Ian Hodson return StringPiece(ptr_ + pos, n); 852ee91b4af4353b9e6a9d591c32fedfc58fd4ef35Ian Hodson} 862ee91b4af4353b9e6a9d591c32fedfc58fd4ef35Ian Hodson 872ee91b4af4353b9e6a9d591c32fedfc58fd4ef35Ian Hodsonconst StringPiece::size_type StringPiece::npos = size_type(-1); 88