1*ccdc9c3eSSadaf Ebrahimi // Copyright 2004 The RE2 Authors. All Rights Reserved.
2*ccdc9c3eSSadaf Ebrahimi // Use of this source code is governed by a BSD-style
3*ccdc9c3eSSadaf Ebrahimi // license that can be found in the LICENSE file.
4*ccdc9c3eSSadaf Ebrahimi
5*ccdc9c3eSSadaf Ebrahimi #include "re2/stringpiece.h"
6*ccdc9c3eSSadaf Ebrahimi
7*ccdc9c3eSSadaf Ebrahimi #include <ostream>
8*ccdc9c3eSSadaf Ebrahimi
9*ccdc9c3eSSadaf Ebrahimi #include "util/util.h"
10*ccdc9c3eSSadaf Ebrahimi
11*ccdc9c3eSSadaf Ebrahimi namespace re2 {
12*ccdc9c3eSSadaf Ebrahimi
13*ccdc9c3eSSadaf Ebrahimi const StringPiece::size_type StringPiece::npos; // initialized in stringpiece.h
14*ccdc9c3eSSadaf Ebrahimi
copy(char * buf,size_type n,size_type pos) const15*ccdc9c3eSSadaf Ebrahimi StringPiece::size_type StringPiece::copy(char* buf, size_type n,
16*ccdc9c3eSSadaf Ebrahimi size_type pos) const {
17*ccdc9c3eSSadaf Ebrahimi size_type ret = std::min(size_ - pos, n);
18*ccdc9c3eSSadaf Ebrahimi memcpy(buf, data_ + pos, ret);
19*ccdc9c3eSSadaf Ebrahimi return ret;
20*ccdc9c3eSSadaf Ebrahimi }
21*ccdc9c3eSSadaf Ebrahimi
substr(size_type pos,size_type n) const22*ccdc9c3eSSadaf Ebrahimi StringPiece StringPiece::substr(size_type pos, size_type n) const {
23*ccdc9c3eSSadaf Ebrahimi if (pos > size_) pos = size_;
24*ccdc9c3eSSadaf Ebrahimi if (n > size_ - pos) n = size_ - pos;
25*ccdc9c3eSSadaf Ebrahimi return StringPiece(data_ + pos, n);
26*ccdc9c3eSSadaf Ebrahimi }
27*ccdc9c3eSSadaf Ebrahimi
find(const StringPiece & s,size_type pos) const28*ccdc9c3eSSadaf Ebrahimi StringPiece::size_type StringPiece::find(const StringPiece& s,
29*ccdc9c3eSSadaf Ebrahimi size_type pos) const {
30*ccdc9c3eSSadaf Ebrahimi if (pos > size_) return npos;
31*ccdc9c3eSSadaf Ebrahimi const_pointer result = std::search(data_ + pos, data_ + size_,
32*ccdc9c3eSSadaf Ebrahimi s.data_, s.data_ + s.size_);
33*ccdc9c3eSSadaf Ebrahimi size_type xpos = result - data_;
34*ccdc9c3eSSadaf Ebrahimi return xpos + s.size_ <= size_ ? xpos : npos;
35*ccdc9c3eSSadaf Ebrahimi }
36*ccdc9c3eSSadaf Ebrahimi
find(char c,size_type pos) const37*ccdc9c3eSSadaf Ebrahimi StringPiece::size_type StringPiece::find(char c, size_type pos) const {
38*ccdc9c3eSSadaf Ebrahimi if (size_ <= 0 || pos >= size_) return npos;
39*ccdc9c3eSSadaf Ebrahimi const_pointer result = std::find(data_ + pos, data_ + size_, c);
40*ccdc9c3eSSadaf Ebrahimi return result != data_ + size_ ? result - data_ : npos;
41*ccdc9c3eSSadaf Ebrahimi }
42*ccdc9c3eSSadaf Ebrahimi
rfind(const StringPiece & s,size_type pos) const43*ccdc9c3eSSadaf Ebrahimi StringPiece::size_type StringPiece::rfind(const StringPiece& s,
44*ccdc9c3eSSadaf Ebrahimi size_type pos) const {
45*ccdc9c3eSSadaf Ebrahimi if (size_ < s.size_) return npos;
46*ccdc9c3eSSadaf Ebrahimi if (s.size_ == 0) return std::min(size_, pos);
47*ccdc9c3eSSadaf Ebrahimi const_pointer last = data_ + std::min(size_ - s.size_, pos) + s.size_;
48*ccdc9c3eSSadaf Ebrahimi const_pointer result = std::find_end(data_, last, s.data_, s.data_ + s.size_);
49*ccdc9c3eSSadaf Ebrahimi return result != last ? result - data_ : npos;
50*ccdc9c3eSSadaf Ebrahimi }
51*ccdc9c3eSSadaf Ebrahimi
rfind(char c,size_type pos) const52*ccdc9c3eSSadaf Ebrahimi StringPiece::size_type StringPiece::rfind(char c, size_type pos) const {
53*ccdc9c3eSSadaf Ebrahimi if (size_ <= 0) return npos;
54*ccdc9c3eSSadaf Ebrahimi for (size_t i = std::min(pos + 1, size_); i != 0;) {
55*ccdc9c3eSSadaf Ebrahimi if (data_[--i] == c) return i;
56*ccdc9c3eSSadaf Ebrahimi }
57*ccdc9c3eSSadaf Ebrahimi return npos;
58*ccdc9c3eSSadaf Ebrahimi }
59*ccdc9c3eSSadaf Ebrahimi
operator <<(std::ostream & o,const StringPiece & p)60*ccdc9c3eSSadaf Ebrahimi std::ostream& operator<<(std::ostream& o, const StringPiece& p) {
61*ccdc9c3eSSadaf Ebrahimi o.write(p.data(), p.size());
62*ccdc9c3eSSadaf Ebrahimi return o;
63*ccdc9c3eSSadaf Ebrahimi }
64*ccdc9c3eSSadaf Ebrahimi
65*ccdc9c3eSSadaf Ebrahimi } // namespace re2
66