blob: 098c6efb30f2687865287ee7f571dd3532c8f52c [file] [log] [blame]
Carl Shapirod4e48fd2011-06-30 18:53:29 -07001// Copyright 2010 Google
2// Licensed under the Apache License, Version 2.0 (the "License");
3// you may not use this file except in compliance with the License.
4// You may obtain a copy of the License at
5//
6// http://www.apache.org/licenses/LICENSE-2.0
7//
8// Unless required by applicable law or agreed to in writing, software
9// distributed under the License is distributed on an "AS IS" BASIS,
10// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
11// See the License for the specific language governing permissions and
12// limitations under the License.
13
14#include <iostream>
15#include <utility>
16#include "src/stringpiece.h"
17
18using art::StringPiece;
19
20std::ostream& operator<<(std::ostream& o, const StringPiece& piece) {
21 o.write(piece.data(), piece.size());
22 return o;
23}
24
25bool operator==(const StringPiece& x, const StringPiece& y) {
26 int len = x.size();
27 if (len != y.size()) {
28 return false;
29 }
30 const char* p = x.data();
31 const char* p2 = y.data();
32 // Test last byte in case strings share large common prefix
33 if ((len > 0) && (p[len-1] != p2[len-1])) return false;
34 const char* p_limit = p + len;
35 for (; p < p_limit; p++, p2++) {
36 if (*p != *p2)
37 return false;
38 }
39 return true;
40}
41
42bool operator<(const art::StringPiece& x, const art::StringPiece& y) {
43 const int r = memcmp(x.data(), y.data(),
44 std::min(x.size(), y.size()));
45 return ((r < 0) || ((r == 0) && (x.size() < y.size())));
46}
47
48void StringPiece::CopyToString(std::string* target) const {
49 target->assign(ptr_, length_);
50}
51
52int StringPiece::copy(char* buf, size_type n, size_type pos) const {
53 int ret = std::min(length_ - pos, n);
54 memcpy(buf, ptr_ + pos, ret);
55 return ret;
56}
57
58int StringPiece::find(const StringPiece& s, size_type pos) const {
59 if (length_ < 0 || pos > static_cast<size_type>(length_))
60 return npos;
61
62 const char* result = std::search(ptr_ + pos, ptr_ + length_,
63 s.ptr_, s.ptr_ + s.length_);
64 const size_type xpos = result - ptr_;
65 return xpos + s.length_ <= static_cast<size_type>(length_) ? xpos : npos;
66}
67
68int StringPiece::compare(const StringPiece& x) const {
69 int r = memcmp(ptr_, x.ptr_, std::min(length_, x.length_));
70 if (r == 0) {
71 if (length_ < x.length_) r = -1;
72 else if (length_ > x.length_) r = +1;
73 }
74 return r;
75}
76
77int StringPiece::find(char c, size_type pos) const {
78 if (length_ <= 0 || pos >= static_cast<size_type>(length_)) {
79 return npos;
80 }
81 const char* result = std::find(ptr_ + pos, ptr_ + length_, c);
82 return result != ptr_ + length_ ? result - ptr_ : npos;
83}
84
85int StringPiece::rfind(const StringPiece& s, size_type pos) const {
86 if (length_ < s.length_) return npos;
87 const size_t ulen = length_;
88 if (s.length_ == 0) return std::min(ulen, pos);
89
90 const char* last = ptr_ + std::min(ulen - s.length_, pos) + s.length_;
91 const char* result = std::find_end(ptr_, last, s.ptr_, s.ptr_ + s.length_);
92 return result != last ? result - ptr_ : npos;
93}
94
95int StringPiece::rfind(char c, size_type pos) const {
96 if (length_ <= 0) return npos;
97 for (int i = std::min(pos, static_cast<size_type>(length_ - 1));
98 i >= 0; --i) {
99 if (ptr_[i] == c) {
100 return i;
101 }
102 }
103 return npos;
104}
105
106StringPiece StringPiece::substr(size_type pos, size_type n) const {
107 if (pos > static_cast<size_type>(length_)) pos = length_;
108 if (n > length_ - pos) n = length_ - pos;
109 return StringPiece(ptr_ + pos, n);
110}
111
112const StringPiece::size_type StringPiece::npos = size_type(-1);