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