1.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 1.2 +++ b/security/sandbox/chromium/base/strings/string_piece.h Wed Dec 31 06:09:35 2014 +0100 1.3 @@ -0,0 +1,451 @@ 1.4 +// Copyright (c) 2012 The Chromium Authors. All rights reserved. 1.5 +// Use of this source code is governed by a BSD-style license that can be 1.6 +// found in the LICENSE file. 1.7 +// Copied from strings/stringpiece.h with modifications 1.8 +// 1.9 +// A string-like object that points to a sized piece of memory. 1.10 +// 1.11 +// Functions or methods may use const StringPiece& parameters to accept either 1.12 +// a "const char*" or a "string" value that will be implicitly converted to 1.13 +// a StringPiece. The implicit conversion means that it is often appropriate 1.14 +// to include this .h file in other files rather than forward-declaring 1.15 +// StringPiece as would be appropriate for most other Google classes. 1.16 +// 1.17 +// Systematic usage of StringPiece is encouraged as it will reduce unnecessary 1.18 +// conversions from "const char*" to "string" and back again. 1.19 +// 1.20 +// StringPiece16 is similar to StringPiece but for base::string16 instead of 1.21 +// std::string. We do not define as large of a subset of the STL functions 1.22 +// from basic_string as in StringPiece, but this can be changed if these 1.23 +// functions (find, find_first_of, etc.) are found to be useful in this context. 1.24 +// 1.25 + 1.26 +#ifndef BASE_STRINGS_STRING_PIECE_H_ 1.27 +#define BASE_STRINGS_STRING_PIECE_H_ 1.28 + 1.29 +#include <stddef.h> 1.30 + 1.31 +#include <iosfwd> 1.32 +#include <string> 1.33 + 1.34 +#include "base/base_export.h" 1.35 +#include "base/basictypes.h" 1.36 +#include "base/containers/hash_tables.h" 1.37 +#include "base/strings/string16.h" 1.38 + 1.39 +namespace base { 1.40 + 1.41 +template <typename STRING_TYPE> class BasicStringPiece; 1.42 +typedef BasicStringPiece<std::string> StringPiece; 1.43 +typedef BasicStringPiece<string16> StringPiece16; 1.44 + 1.45 +namespace internal { 1.46 + 1.47 +// Defines the types, methods, operators, and data members common to both 1.48 +// StringPiece and StringPiece16. Do not refer to this class directly, but 1.49 +// rather to BasicStringPiece, StringPiece, or StringPiece16. 1.50 +template <typename STRING_TYPE> class StringPieceDetail { 1.51 + public: 1.52 + // standard STL container boilerplate 1.53 + typedef size_t size_type; 1.54 + typedef typename STRING_TYPE::value_type value_type; 1.55 + typedef const value_type* pointer; 1.56 + typedef const value_type& reference; 1.57 + typedef const value_type& const_reference; 1.58 + typedef ptrdiff_t difference_type; 1.59 + typedef const value_type* const_iterator; 1.60 + typedef std::reverse_iterator<const_iterator> const_reverse_iterator; 1.61 + 1.62 + static const size_type npos; 1.63 + 1.64 + public: 1.65 + // We provide non-explicit singleton constructors so users can pass 1.66 + // in a "const char*" or a "string" wherever a "StringPiece" is 1.67 + // expected (likewise for char16, string16, StringPiece16). 1.68 + StringPieceDetail() : ptr_(NULL), length_(0) {} 1.69 + StringPieceDetail(const value_type* str) 1.70 + : ptr_(str), 1.71 + length_((str == NULL) ? 0 : STRING_TYPE::traits_type::length(str)) {} 1.72 + StringPieceDetail(const STRING_TYPE& str) 1.73 + : ptr_(str.data()), length_(str.size()) {} 1.74 + StringPieceDetail(const value_type* offset, size_type len) 1.75 + : ptr_(offset), length_(len) {} 1.76 + StringPieceDetail(const typename STRING_TYPE::const_iterator& begin, 1.77 + const typename STRING_TYPE::const_iterator& end) 1.78 + : ptr_((end > begin) ? &(*begin) : NULL), 1.79 + length_((end > begin) ? (size_type)(end - begin) : 0) {} 1.80 + 1.81 + // data() may return a pointer to a buffer with embedded NULs, and the 1.82 + // returned buffer may or may not be null terminated. Therefore it is 1.83 + // typically a mistake to pass data() to a routine that expects a NUL 1.84 + // terminated string. 1.85 + const value_type* data() const { return ptr_; } 1.86 + size_type size() const { return length_; } 1.87 + size_type length() const { return length_; } 1.88 + bool empty() const { return length_ == 0; } 1.89 + 1.90 + void clear() { 1.91 + ptr_ = NULL; 1.92 + length_ = 0; 1.93 + } 1.94 + void set(const value_type* data, size_type len) { 1.95 + ptr_ = data; 1.96 + length_ = len; 1.97 + } 1.98 + void set(const value_type* str) { 1.99 + ptr_ = str; 1.100 + length_ = str ? STRING_TYPE::traits_type::length(str) : 0; 1.101 + } 1.102 + 1.103 + value_type operator[](size_type i) const { return ptr_[i]; } 1.104 + 1.105 + void remove_prefix(size_type n) { 1.106 + ptr_ += n; 1.107 + length_ -= n; 1.108 + } 1.109 + 1.110 + void remove_suffix(size_type n) { 1.111 + length_ -= n; 1.112 + } 1.113 + 1.114 + int compare(const BasicStringPiece<STRING_TYPE>& x) const { 1.115 + int r = wordmemcmp( 1.116 + ptr_, x.ptr_, (length_ < x.length_ ? length_ : x.length_)); 1.117 + if (r == 0) { 1.118 + if (length_ < x.length_) r = -1; 1.119 + else if (length_ > x.length_) r = +1; 1.120 + } 1.121 + return r; 1.122 + } 1.123 + 1.124 + STRING_TYPE as_string() const { 1.125 + // std::string doesn't like to take a NULL pointer even with a 0 size. 1.126 + return empty() ? STRING_TYPE() : STRING_TYPE(data(), size()); 1.127 + } 1.128 + 1.129 + const_iterator begin() const { return ptr_; } 1.130 + const_iterator end() const { return ptr_ + length_; } 1.131 + const_reverse_iterator rbegin() const { 1.132 + return const_reverse_iterator(ptr_ + length_); 1.133 + } 1.134 + const_reverse_iterator rend() const { 1.135 + return const_reverse_iterator(ptr_); 1.136 + } 1.137 + 1.138 + size_type max_size() const { return length_; } 1.139 + size_type capacity() const { return length_; } 1.140 + 1.141 + static int wordmemcmp(const value_type* p, 1.142 + const value_type* p2, 1.143 + size_type N) { 1.144 + return STRING_TYPE::traits_type::compare(p, p2, N); 1.145 + } 1.146 + 1.147 + protected: 1.148 + const value_type* ptr_; 1.149 + size_type length_; 1.150 +}; 1.151 + 1.152 +template <typename STRING_TYPE> 1.153 +const typename StringPieceDetail<STRING_TYPE>::size_type 1.154 +StringPieceDetail<STRING_TYPE>::npos = 1.155 + typename StringPieceDetail<STRING_TYPE>::size_type(-1); 1.156 + 1.157 +// MSVC doesn't like complex extern templates and DLLs. 1.158 +#if !defined(COMPILER_MSVC) 1.159 +extern template class BASE_EXPORT StringPieceDetail<std::string>; 1.160 +extern template class BASE_EXPORT StringPieceDetail<string16>; 1.161 +#endif 1.162 + 1.163 +BASE_EXPORT void CopyToString(const StringPiece& self, std::string* target); 1.164 +BASE_EXPORT void AppendToString(const StringPiece& self, std::string* target); 1.165 +BASE_EXPORT StringPieceDetail<std::string>::size_type copy( 1.166 + const StringPiece& self, 1.167 + char* buf, 1.168 + StringPieceDetail<std::string>::size_type n, 1.169 + StringPieceDetail<std::string>::size_type pos); 1.170 +BASE_EXPORT StringPieceDetail<std::string>::size_type find( 1.171 + const StringPiece& self, 1.172 + const StringPiece& s, 1.173 + StringPieceDetail<std::string>::size_type pos); 1.174 +BASE_EXPORT StringPieceDetail<std::string>::size_type find( 1.175 + const StringPiece& self, 1.176 + char c, 1.177 + StringPieceDetail<std::string>::size_type pos); 1.178 +BASE_EXPORT StringPieceDetail<std::string>::size_type rfind( 1.179 + const StringPiece& self, 1.180 + const StringPiece& s, 1.181 + StringPieceDetail<std::string>::size_type pos); 1.182 +BASE_EXPORT StringPieceDetail<std::string>::size_type rfind( 1.183 + const StringPiece& self, 1.184 + char c, 1.185 + StringPieceDetail<std::string>::size_type pos); 1.186 +BASE_EXPORT StringPieceDetail<std::string>::size_type find_first_of( 1.187 + const StringPiece& self, 1.188 + const StringPiece& s, 1.189 + StringPieceDetail<std::string>::size_type pos); 1.190 +BASE_EXPORT StringPieceDetail<std::string>::size_type find_first_not_of( 1.191 + const StringPiece& self, 1.192 + const StringPiece& s, 1.193 + StringPieceDetail<std::string>::size_type pos); 1.194 +BASE_EXPORT StringPieceDetail<std::string>::size_type find_first_not_of( 1.195 + const StringPiece& self, 1.196 + char c, 1.197 + StringPieceDetail<std::string>::size_type pos); 1.198 +BASE_EXPORT StringPieceDetail<std::string>::size_type find_last_of( 1.199 + const StringPiece& self, 1.200 + const StringPiece& s, 1.201 + StringPieceDetail<std::string>::size_type pos); 1.202 +BASE_EXPORT StringPieceDetail<std::string>::size_type find_last_of( 1.203 + const StringPiece& self, 1.204 + char c, 1.205 + StringPieceDetail<std::string>::size_type pos); 1.206 +BASE_EXPORT StringPieceDetail<std::string>::size_type find_last_not_of( 1.207 + const StringPiece& self, 1.208 + const StringPiece& s, 1.209 + StringPieceDetail<std::string>::size_type pos); 1.210 +BASE_EXPORT StringPieceDetail<std::string>::size_type find_last_not_of( 1.211 + const StringPiece& self, 1.212 + char c, 1.213 + StringPieceDetail<std::string>::size_type pos); 1.214 +BASE_EXPORT StringPiece substr(const StringPiece& self, 1.215 + StringPieceDetail<std::string>::size_type pos, 1.216 + StringPieceDetail<std::string>::size_type n); 1.217 +} // namespace internal 1.218 + 1.219 +// Defines the template type that is instantiated as either StringPiece or 1.220 +// StringPiece16. 1.221 +template <typename STRING_TYPE> class BasicStringPiece : 1.222 + public internal::StringPieceDetail<STRING_TYPE> { 1.223 + public: 1.224 + typedef typename internal::StringPieceDetail<STRING_TYPE>::value_type 1.225 + value_type; 1.226 + typedef typename internal::StringPieceDetail<STRING_TYPE>::size_type 1.227 + size_type; 1.228 + 1.229 + BasicStringPiece() {} 1.230 + BasicStringPiece(const value_type*str) 1.231 + : internal::StringPieceDetail<STRING_TYPE>(str) {} 1.232 + BasicStringPiece(const STRING_TYPE& str) 1.233 + : internal::StringPieceDetail<STRING_TYPE>(str) {} 1.234 + BasicStringPiece(const value_type* offset, size_type len) 1.235 + : internal::StringPieceDetail<STRING_TYPE>(offset, len) {} 1.236 + BasicStringPiece(const typename STRING_TYPE::const_iterator& begin, 1.237 + const typename STRING_TYPE::const_iterator& end) 1.238 + : internal::StringPieceDetail<STRING_TYPE>(begin, end) {} 1.239 +}; 1.240 + 1.241 +// Specializes BasicStringPiece for std::string to add a few operations that 1.242 +// are not needed for string16. 1.243 +template <> class BasicStringPiece<std::string> : 1.244 + public internal::StringPieceDetail<std::string> { 1.245 + public: 1.246 + BasicStringPiece() {} 1.247 + BasicStringPiece(const char* str) 1.248 + : internal::StringPieceDetail<std::string>(str) {} 1.249 + BasicStringPiece(const std::string& str) 1.250 + : internal::StringPieceDetail<std::string>(str) {} 1.251 + BasicStringPiece(const char* offset, size_type len) 1.252 + : internal::StringPieceDetail<std::string>(offset, len) {} 1.253 + BasicStringPiece(const std::string::const_iterator& begin, 1.254 + const std::string::const_iterator& end) 1.255 + : internal::StringPieceDetail<std::string>(begin, end) {} 1.256 + 1.257 + // Prevent the following overload of set() from hiding the definitions in the 1.258 + // base class. 1.259 + using internal::StringPieceDetail<std::string>::set; 1.260 + 1.261 + void set(const void* data, size_type len) { 1.262 + ptr_ = reinterpret_cast<const value_type*>(data); 1.263 + length_ = len; 1.264 + } 1.265 + 1.266 + void CopyToString(std::string* target) const { 1.267 + internal::CopyToString(*this, target); 1.268 + } 1.269 + 1.270 + void AppendToString(std::string* target) const { 1.271 + internal::AppendToString(*this, target); 1.272 + } 1.273 + 1.274 + // Does "this" start with "x" 1.275 + bool starts_with(const BasicStringPiece& x) const { 1.276 + return ((length_ >= x.length_) && 1.277 + (wordmemcmp(ptr_, x.ptr_, x.length_) == 0)); 1.278 + } 1.279 + 1.280 + // Does "this" end with "x" 1.281 + bool ends_with(const BasicStringPiece& x) const { 1.282 + return ((length_ >= x.length_) && 1.283 + (wordmemcmp(ptr_ + (length_-x.length_), x.ptr_, x.length_) == 0)); 1.284 + } 1.285 + 1.286 + size_type copy(char* buf, size_type n, size_type pos = 0) const { 1.287 + return internal::copy(*this, buf, n, pos); 1.288 + } 1.289 + 1.290 + size_type find(const BasicStringPiece& s, size_type pos = 0) const { 1.291 + return internal::find(*this, s, pos); 1.292 + } 1.293 + 1.294 + size_type find(char c, size_type pos = 0) const { 1.295 + return internal::find(*this, c, pos); 1.296 + } 1.297 + 1.298 + size_type rfind(const BasicStringPiece& s, size_type pos = npos) const { 1.299 + return internal::rfind(*this, s, pos); 1.300 + } 1.301 + 1.302 + size_type rfind(char c, size_type pos = npos) const { 1.303 + return internal::rfind(*this, c, pos); 1.304 + } 1.305 + 1.306 + size_type find_first_of(const BasicStringPiece& s, size_type pos = 0) const { 1.307 + return internal::find_first_of(*this, s, pos); 1.308 + } 1.309 + 1.310 + size_type find_first_of(char c, size_type pos = 0) const { 1.311 + return find(c, pos); 1.312 + } 1.313 + 1.314 + size_type find_first_not_of(const BasicStringPiece& s, 1.315 + size_type pos = 0) const { 1.316 + return internal::find_first_not_of(*this, s, pos); 1.317 + } 1.318 + 1.319 + size_type find_first_not_of(char c, size_type pos = 0) const { 1.320 + return internal::find_first_not_of(*this, c, pos); 1.321 + } 1.322 + 1.323 + size_type find_last_of(const BasicStringPiece& s, 1.324 + size_type pos = npos) const { 1.325 + return internal::find_last_of(*this, s, pos); 1.326 + } 1.327 + 1.328 + size_type find_last_of(char c, size_type pos = npos) const { 1.329 + return rfind(c, pos); 1.330 + } 1.331 + 1.332 + size_type find_last_not_of(const BasicStringPiece& s, 1.333 + size_type pos = npos) const { 1.334 + return internal::find_last_not_of(*this, s, pos); 1.335 + } 1.336 + 1.337 + size_type find_last_not_of(char c, size_type pos = npos) const { 1.338 + return internal::find_last_not_of(*this, c, pos); 1.339 + } 1.340 + 1.341 + BasicStringPiece substr(size_type pos, size_type n = npos) const { 1.342 + return internal::substr(*this, pos, n); 1.343 + } 1.344 +}; 1.345 + 1.346 +// MSVC doesn't like complex extern templates and DLLs. 1.347 +#if !defined(COMPILER_MSVC) 1.348 +// We can't explicitly declare the std::string instantiation here because it was 1.349 +// already instantiated when specialized, above. Not only is it a no-op, but 1.350 +// currently it also crashes Clang (see http://crbug.com/107412). 1.351 +extern template class BASE_EXPORT BasicStringPiece<string16>; 1.352 +#endif 1.353 + 1.354 +BASE_EXPORT bool operator==(const StringPiece& x, const StringPiece& y); 1.355 + 1.356 +inline bool operator!=(const StringPiece& x, const StringPiece& y) { 1.357 + return !(x == y); 1.358 +} 1.359 + 1.360 +inline bool operator<(const StringPiece& x, const StringPiece& y) { 1.361 + const int r = StringPiece::wordmemcmp( 1.362 + x.data(), y.data(), (x.size() < y.size() ? x.size() : y.size())); 1.363 + return ((r < 0) || ((r == 0) && (x.size() < y.size()))); 1.364 +} 1.365 + 1.366 +inline bool operator>(const StringPiece& x, const StringPiece& y) { 1.367 + return y < x; 1.368 +} 1.369 + 1.370 +inline bool operator<=(const StringPiece& x, const StringPiece& y) { 1.371 + return !(x > y); 1.372 +} 1.373 + 1.374 +inline bool operator>=(const StringPiece& x, const StringPiece& y) { 1.375 + return !(x < y); 1.376 +} 1.377 + 1.378 +inline bool operator==(const StringPiece16& x, const StringPiece16& y) { 1.379 + if (x.size() != y.size()) 1.380 + return false; 1.381 + 1.382 + return StringPiece16::wordmemcmp(x.data(), y.data(), x.size()) == 0; 1.383 +} 1.384 + 1.385 +inline bool operator!=(const StringPiece16& x, const StringPiece16& y) { 1.386 + return !(x == y); 1.387 +} 1.388 + 1.389 +inline bool operator<(const StringPiece16& x, const StringPiece16& y) { 1.390 + const int r = StringPiece16::wordmemcmp( 1.391 + x.data(), y.data(), (x.size() < y.size() ? x.size() : y.size())); 1.392 + return ((r < 0) || ((r == 0) && (x.size() < y.size()))); 1.393 +} 1.394 + 1.395 +inline bool operator>(const StringPiece16& x, const StringPiece16& y) { 1.396 + return y < x; 1.397 +} 1.398 + 1.399 +inline bool operator<=(const StringPiece16& x, const StringPiece16& y) { 1.400 + return !(x > y); 1.401 +} 1.402 + 1.403 +inline bool operator>=(const StringPiece16& x, const StringPiece16& y) { 1.404 + return !(x < y); 1.405 +} 1.406 + 1.407 +BASE_EXPORT std::ostream& operator<<(std::ostream& o, 1.408 + const StringPiece& piece); 1.409 + 1.410 +} // namespace base 1.411 + 1.412 +// We provide appropriate hash functions so StringPiece and StringPiece16 can 1.413 +// be used as keys in hash sets and maps. 1.414 + 1.415 +// This hash function is copied from base/containers/hash_tables.h. We don't 1.416 +// use the ones already defined for string and string16 directly because it 1.417 +// would require the string constructors to be called, which we don't want. 1.418 +#define HASH_STRING_PIECE(StringPieceType, string_piece) \ 1.419 + std::size_t result = 0; \ 1.420 + for (StringPieceType::const_iterator i = string_piece.begin(); \ 1.421 + i != string_piece.end(); ++i) \ 1.422 + result = (result * 131) + *i; \ 1.423 + return result; \ 1.424 + 1.425 +namespace BASE_HASH_NAMESPACE { 1.426 +#if defined(COMPILER_GCC) 1.427 + 1.428 +template<> 1.429 +struct hash<base::StringPiece> { 1.430 + std::size_t operator()(const base::StringPiece& sp) const { 1.431 + HASH_STRING_PIECE(base::StringPiece, sp); 1.432 + } 1.433 +}; 1.434 +template<> 1.435 +struct hash<base::StringPiece16> { 1.436 + std::size_t operator()(const base::StringPiece16& sp16) const { 1.437 + HASH_STRING_PIECE(base::StringPiece16, sp16); 1.438 + } 1.439 +}; 1.440 + 1.441 +#elif defined(COMPILER_MSVC) 1.442 + 1.443 +inline size_t hash_value(const base::StringPiece& sp) { 1.444 + HASH_STRING_PIECE(base::StringPiece, sp); 1.445 +} 1.446 +inline size_t hash_value(const base::StringPiece16& sp16) { 1.447 + HASH_STRING_PIECE(base::StringPiece16, sp16); 1.448 +} 1.449 + 1.450 +#endif // COMPILER 1.451 + 1.452 +} // namespace BASE_HASH_NAMESPACE 1.453 + 1.454 +#endif // BASE_STRINGS_STRING_PIECE_H_