1 // Copyright 2015 Google Inc. All rights reserved 2 // 3 // Licensed under the Apache License, Version 2.0 (the "License"); 4 // you may not use this file except in compliance with the License. 5 // You may obtain a copy of the License at 6 // 7 // http://www.apache.org/licenses/LICENSE-2.0 8 // 9 // Unless required by applicable law or agreed to in writing, software 10 // distributed under the License is distributed on an "AS IS" BASIS, 11 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 // See the License for the specific language governing permissions and 13 // limitations under the License. 14 15 // Copyright (c) 2011 The Chromium Authors. All rights reserved. 16 // Use of this source code is governed by a BSD-style license that can be 17 // found in the LICENSE file. 18 // Copied from strings/stringpiece.h with modifications 19 // 20 // A string-like object that points to a sized piece of memory. 21 // 22 // Functions or methods may use const StringPiece& parameters to accept either 23 // a "const char*" or a "string" value that will be implicitly converted to 24 // a StringPiece. The implicit conversion means that it is often appropriate 25 // to include this .h file in other files rather than forward-declaring 26 // StringPiece as would be appropriate for most other Google classes. 27 // 28 // Systematic usage of StringPiece is encouraged as it will reduce unnecessary 29 // conversions from "const char*" to "string" and back again. 30 // 31 32 #ifndef BASE_STRING_PIECE_H_ 33 #define BASE_STRING_PIECE_H_ 34 #pragma once 35 36 #include <stddef.h> 37 #include <string.h> 38 39 #include <string> 40 41 //#include "base/base_api.h" 42 //#include "base/basictypes.h" 43 44 class StringPiece { 45 public: 46 // standard STL container boilerplate 47 typedef size_t size_type; 48 typedef char value_type; 49 typedef const char* pointer; 50 typedef const char& reference; 51 typedef const char& const_reference; 52 typedef ptrdiff_t difference_type; 53 typedef const char* const_iterator; 54 typedef const char* iterator; 55 typedef std::reverse_iterator<const_iterator> const_reverse_iterator; 56 typedef std::reverse_iterator<iterator> reverse_iterator; 57 58 static const size_type npos; 59 60 public: 61 // We provide non-explicit singleton constructors so users can pass 62 // in a "const char*" or a "string" wherever a "StringPiece" is 63 // expected. StringPiece()64 StringPiece() : ptr_(NULL), length_(0) {} StringPiece(const char * str)65 StringPiece(const char* str) 66 : ptr_(str), length_((str == NULL) ? 0 : strlen(str)) {} StringPiece(const std::string & str)67 StringPiece(const std::string& str) : ptr_(str.data()), length_(str.size()) {} StringPiece(const std::string && str)68 StringPiece(const std::string&& str) 69 : ptr_(str.data()), length_(str.size()) {} StringPiece(const char * offset,size_type len)70 StringPiece(const char* offset, size_type len) : ptr_(offset), length_(len) {} 71 72 // data() may return a pointer to a buffer with embedded NULs, and the 73 // returned buffer may or may not be null terminated. Therefore it is 74 // typically a mistake to pass data() to a routine that expects a NUL 75 // terminated string. data()76 const char* data() const { return ptr_; } size()77 size_type size() const { return length_; } length()78 size_type length() const { return length_; } empty()79 bool empty() const { return length_ == 0; } 80 clear()81 void clear() { 82 ptr_ = NULL; 83 length_ = 0; 84 } set(const char * data,size_type len)85 void set(const char* data, size_type len) { 86 ptr_ = data; 87 length_ = len; 88 } set(const char * str)89 void set(const char* str) { 90 ptr_ = str; 91 length_ = str ? strlen(str) : 0; 92 } set(const void * data,size_type len)93 void set(const void* data, size_type len) { 94 ptr_ = reinterpret_cast<const char*>(data); 95 length_ = len; 96 } 97 98 char operator[](size_type i) const { return ptr_[i]; } 99 remove_prefix(size_type n)100 void remove_prefix(size_type n) { 101 ptr_ += n; 102 length_ -= n; 103 } 104 remove_suffix(size_type n)105 void remove_suffix(size_type n) { length_ -= n; } 106 compare(const StringPiece & x)107 int compare(const StringPiece& x) const { 108 int r = 109 wordmemcmp(ptr_, x.ptr_, (length_ < x.length_ ? length_ : x.length_)); 110 if (r == 0) { 111 if (length_ < x.length_) 112 r = -1; 113 else if (length_ > x.length_) 114 r = +1; 115 } 116 return r; 117 } 118 as_string()119 std::string as_string() const { 120 // std::string doesn't like to take a NULL pointer even with a 0 size. 121 return std::string(!empty() ? data() : "", size()); 122 } 123 124 void CopyToString(std::string* target) const; 125 void AppendToString(std::string* target) const; 126 127 // Does "this" start with "x" starts_with(const StringPiece & x)128 bool starts_with(const StringPiece& x) const { 129 return ((length_ >= x.length_) && 130 (wordmemcmp(ptr_, x.ptr_, x.length_) == 0)); 131 } 132 133 // Does "this" end with "x" ends_with(const StringPiece & x)134 bool ends_with(const StringPiece& x) const { 135 return ((length_ >= x.length_) && 136 (wordmemcmp(ptr_ + (length_ - x.length_), x.ptr_, x.length_) == 0)); 137 } 138 begin()139 iterator begin() const { return ptr_; } end()140 iterator end() const { return ptr_ + length_; } rbegin()141 const_reverse_iterator rbegin() const { 142 return const_reverse_iterator(ptr_ + length_); 143 } rend()144 const_reverse_iterator rend() const { return const_reverse_iterator(ptr_); } 145 max_size()146 size_type max_size() const { return length_; } capacity()147 size_type capacity() const { return length_; } 148 149 size_type copy(char* buf, size_type n, size_type pos = 0) const; 150 151 size_type find(const StringPiece& s, size_type pos = 0) const; 152 size_type find(char c, size_type pos = 0) const; 153 size_type rfind(const StringPiece& s, size_type pos = npos) const; 154 size_type rfind(char c, size_type pos = npos) const; 155 156 size_type find_first_of(const StringPiece& s, size_type pos = 0) const; 157 size_type find_first_of(char c, size_type pos = 0) const { 158 return find(c, pos); 159 } 160 size_type find_first_not_of(const StringPiece& s, size_type pos = 0) const; 161 size_type find_first_not_of(char c, size_type pos = 0) const; 162 size_type find_last_of(const StringPiece& s, size_type pos = npos) const; 163 size_type find_last_of(char c, size_type pos = npos) const { 164 return rfind(c, pos); 165 } 166 size_type find_last_not_of(const StringPiece& s, size_type pos = npos) const; 167 size_type find_last_not_of(char c, size_type pos = npos) const; 168 169 StringPiece substr(size_type pos, size_type n = npos) const; 170 wordmemcmp(const char * p,const char * p2,size_type N)171 static int wordmemcmp(const char* p, const char* p2, size_type N) { 172 return memcmp(p, p2, N); 173 } 174 175 // kati specific functions will follow. 176 get(size_type i)177 char get(size_type i) const { return i < length_ ? ptr_[i] : 0; } 178 179 private: 180 const char* ptr_; 181 size_type length_; 182 }; 183 184 bool operator==(const StringPiece& x, const StringPiece& y); 185 186 inline bool operator!=(const StringPiece& x, const StringPiece& y) { 187 return !(x == y); 188 } 189 190 inline bool operator<(const StringPiece& x, const StringPiece& y) { 191 const int r = StringPiece::wordmemcmp( 192 x.data(), y.data(), (x.size() < y.size() ? x.size() : y.size())); 193 return ((r < 0) || ((r == 0) && (x.size() < y.size()))); 194 } 195 196 inline bool operator>(const StringPiece& x, const StringPiece& y) { 197 return y < x; 198 } 199 200 inline bool operator<=(const StringPiece& x, const StringPiece& y) { 201 return !(x > y); 202 } 203 204 inline bool operator>=(const StringPiece& x, const StringPiece& y) { 205 return !(x < y); 206 } 207 208 namespace std { 209 template <> 210 struct hash<StringPiece> { 211 size_t operator()(const StringPiece& s) const { 212 size_t result = 0; 213 for (char c : s) { 214 result = (result * 131) + c; 215 } 216 return result; 217 } 218 }; 219 220 } // namespace std 221 222 #define SPF(s) static_cast<int>((s).size()), (s).data() 223 224 #endif // BASE_STRING_PIECE_H_ 225