security/sandbox/chromium/base/strings/string_piece.h

Wed, 31 Dec 2014 06:09:35 +0100

author
Michael Schloh von Bennewitz <michael@schloh.com>
date
Wed, 31 Dec 2014 06:09:35 +0100
changeset 0
6474c204b198
permissions
-rw-r--r--

Cloned upstream origin tor-browser at tor-browser-31.3.0esr-4.5-1-build1
revision ID fc1c9ff7c1b2defdbc039f12214767608f46423f for hacking purpose.

     1 // Copyright (c) 2012 The Chromium Authors. All rights reserved.
     2 // Use of this source code is governed by a BSD-style license that can be
     3 // found in the LICENSE file.
     4 // Copied from strings/stringpiece.h with modifications
     5 //
     6 // A string-like object that points to a sized piece of memory.
     7 //
     8 // Functions or methods may use const StringPiece& parameters to accept either
     9 // a "const char*" or a "string" value that will be implicitly converted to
    10 // a StringPiece.  The implicit conversion means that it is often appropriate
    11 // to include this .h file in other files rather than forward-declaring
    12 // StringPiece as would be appropriate for most other Google classes.
    13 //
    14 // Systematic usage of StringPiece is encouraged as it will reduce unnecessary
    15 // conversions from "const char*" to "string" and back again.
    16 //
    17 // StringPiece16 is similar to StringPiece but for base::string16 instead of
    18 // std::string. We do not define as large of a subset of the STL functions
    19 // from basic_string as in StringPiece, but this can be changed if these
    20 // functions (find, find_first_of, etc.) are found to be useful in this context.
    21 //
    23 #ifndef BASE_STRINGS_STRING_PIECE_H_
    24 #define BASE_STRINGS_STRING_PIECE_H_
    26 #include <stddef.h>
    28 #include <iosfwd>
    29 #include <string>
    31 #include "base/base_export.h"
    32 #include "base/basictypes.h"
    33 #include "base/containers/hash_tables.h"
    34 #include "base/strings/string16.h"
    36 namespace base {
    38 template <typename STRING_TYPE> class BasicStringPiece;
    39 typedef BasicStringPiece<std::string> StringPiece;
    40 typedef BasicStringPiece<string16> StringPiece16;
    42 namespace internal {
    44 // Defines the types, methods, operators, and data members common to both
    45 // StringPiece and StringPiece16. Do not refer to this class directly, but
    46 // rather to BasicStringPiece, StringPiece, or StringPiece16.
    47 template <typename STRING_TYPE> class StringPieceDetail {
    48  public:
    49   // standard STL container boilerplate
    50   typedef size_t size_type;
    51   typedef typename STRING_TYPE::value_type value_type;
    52   typedef const value_type* pointer;
    53   typedef const value_type& reference;
    54   typedef const value_type& const_reference;
    55   typedef ptrdiff_t difference_type;
    56   typedef const value_type* const_iterator;
    57   typedef std::reverse_iterator<const_iterator> const_reverse_iterator;
    59   static const size_type npos;
    61  public:
    62   // We provide non-explicit singleton constructors so users can pass
    63   // in a "const char*" or a "string" wherever a "StringPiece" is
    64   // expected (likewise for char16, string16, StringPiece16).
    65   StringPieceDetail() : ptr_(NULL), length_(0) {}
    66   StringPieceDetail(const value_type* str)
    67       : ptr_(str),
    68         length_((str == NULL) ? 0 : STRING_TYPE::traits_type::length(str)) {}
    69   StringPieceDetail(const STRING_TYPE& str)
    70       : ptr_(str.data()), length_(str.size()) {}
    71   StringPieceDetail(const value_type* offset, size_type len)
    72       : ptr_(offset), length_(len) {}
    73   StringPieceDetail(const typename STRING_TYPE::const_iterator& begin,
    74                     const typename STRING_TYPE::const_iterator& end)
    75       : ptr_((end > begin) ? &(*begin) : NULL),
    76         length_((end > begin) ? (size_type)(end - begin) : 0) {}
    78   // data() may return a pointer to a buffer with embedded NULs, and the
    79   // returned buffer may or may not be null terminated.  Therefore it is
    80   // typically a mistake to pass data() to a routine that expects a NUL
    81   // terminated string.
    82   const value_type* data() const { return ptr_; }
    83   size_type size() const { return length_; }
    84   size_type length() const { return length_; }
    85   bool empty() const { return length_ == 0; }
    87   void clear() {
    88     ptr_ = NULL;
    89     length_ = 0;
    90   }
    91   void set(const value_type* data, size_type len) {
    92     ptr_ = data;
    93     length_ = len;
    94   }
    95   void set(const value_type* str) {
    96     ptr_ = str;
    97     length_ = str ? STRING_TYPE::traits_type::length(str) : 0;
    98   }
   100   value_type operator[](size_type i) const { return ptr_[i]; }
   102   void remove_prefix(size_type n) {
   103     ptr_ += n;
   104     length_ -= n;
   105   }
   107   void remove_suffix(size_type n) {
   108     length_ -= n;
   109   }
   111   int compare(const BasicStringPiece<STRING_TYPE>& x) const {
   112     int r = wordmemcmp(
   113         ptr_, x.ptr_, (length_ < x.length_ ? length_ : x.length_));
   114     if (r == 0) {
   115       if (length_ < x.length_) r = -1;
   116       else if (length_ > x.length_) r = +1;
   117     }
   118     return r;
   119   }
   121   STRING_TYPE as_string() const {
   122     // std::string doesn't like to take a NULL pointer even with a 0 size.
   123     return empty() ? STRING_TYPE() : STRING_TYPE(data(), size());
   124   }
   126   const_iterator begin() const { return ptr_; }
   127   const_iterator end() const { return ptr_ + length_; }
   128   const_reverse_iterator rbegin() const {
   129     return const_reverse_iterator(ptr_ + length_);
   130   }
   131   const_reverse_iterator rend() const {
   132     return const_reverse_iterator(ptr_);
   133   }
   135   size_type max_size() const { return length_; }
   136   size_type capacity() const { return length_; }
   138   static int wordmemcmp(const value_type* p,
   139                         const value_type* p2,
   140                         size_type N) {
   141     return STRING_TYPE::traits_type::compare(p, p2, N);
   142   }
   144  protected:
   145   const value_type* ptr_;
   146   size_type     length_;
   147 };
   149 template <typename STRING_TYPE>
   150 const typename StringPieceDetail<STRING_TYPE>::size_type
   151 StringPieceDetail<STRING_TYPE>::npos =
   152     typename StringPieceDetail<STRING_TYPE>::size_type(-1);
   154 // MSVC doesn't like complex extern templates and DLLs.
   155 #if !defined(COMPILER_MSVC)
   156 extern template class BASE_EXPORT StringPieceDetail<std::string>;
   157 extern template class BASE_EXPORT StringPieceDetail<string16>;
   158 #endif
   160 BASE_EXPORT void CopyToString(const StringPiece& self, std::string* target);
   161 BASE_EXPORT void AppendToString(const StringPiece& self, std::string* target);
   162 BASE_EXPORT StringPieceDetail<std::string>::size_type copy(
   163     const StringPiece& self,
   164     char* buf,
   165     StringPieceDetail<std::string>::size_type n,
   166     StringPieceDetail<std::string>::size_type pos);
   167 BASE_EXPORT StringPieceDetail<std::string>::size_type find(
   168     const StringPiece& self,
   169     const StringPiece& s,
   170     StringPieceDetail<std::string>::size_type pos);
   171 BASE_EXPORT StringPieceDetail<std::string>::size_type find(
   172     const StringPiece& self,
   173     char c,
   174     StringPieceDetail<std::string>::size_type pos);
   175 BASE_EXPORT StringPieceDetail<std::string>::size_type rfind(
   176     const StringPiece& self,
   177     const StringPiece& s,
   178     StringPieceDetail<std::string>::size_type pos);
   179 BASE_EXPORT StringPieceDetail<std::string>::size_type rfind(
   180     const StringPiece& self,
   181     char c,
   182     StringPieceDetail<std::string>::size_type pos);
   183 BASE_EXPORT StringPieceDetail<std::string>::size_type find_first_of(
   184     const StringPiece& self,
   185     const StringPiece& s,
   186     StringPieceDetail<std::string>::size_type pos);
   187 BASE_EXPORT StringPieceDetail<std::string>::size_type find_first_not_of(
   188     const StringPiece& self,
   189     const StringPiece& s,
   190     StringPieceDetail<std::string>::size_type pos);
   191 BASE_EXPORT StringPieceDetail<std::string>::size_type find_first_not_of(
   192     const StringPiece& self,
   193     char c,
   194     StringPieceDetail<std::string>::size_type pos);
   195 BASE_EXPORT StringPieceDetail<std::string>::size_type find_last_of(
   196     const StringPiece& self,
   197     const StringPiece& s,
   198     StringPieceDetail<std::string>::size_type pos);
   199 BASE_EXPORT StringPieceDetail<std::string>::size_type find_last_of(
   200     const StringPiece& self,
   201     char c,
   202     StringPieceDetail<std::string>::size_type pos);
   203 BASE_EXPORT StringPieceDetail<std::string>::size_type find_last_not_of(
   204     const StringPiece& self,
   205     const StringPiece& s,
   206     StringPieceDetail<std::string>::size_type pos);
   207 BASE_EXPORT StringPieceDetail<std::string>::size_type find_last_not_of(
   208     const StringPiece& self,
   209     char c,
   210     StringPieceDetail<std::string>::size_type pos);
   211 BASE_EXPORT StringPiece substr(const StringPiece& self,
   212                                StringPieceDetail<std::string>::size_type pos,
   213                                StringPieceDetail<std::string>::size_type n);
   214 }  // namespace internal
   216 // Defines the template type that is instantiated as either StringPiece or
   217 // StringPiece16.
   218 template <typename STRING_TYPE> class BasicStringPiece :
   219     public internal::StringPieceDetail<STRING_TYPE> {
   220  public:
   221   typedef typename internal::StringPieceDetail<STRING_TYPE>::value_type
   222       value_type;
   223   typedef typename internal::StringPieceDetail<STRING_TYPE>::size_type
   224       size_type;
   226   BasicStringPiece() {}
   227   BasicStringPiece(const value_type*str)
   228       : internal::StringPieceDetail<STRING_TYPE>(str) {}
   229   BasicStringPiece(const STRING_TYPE& str)
   230       : internal::StringPieceDetail<STRING_TYPE>(str) {}
   231   BasicStringPiece(const value_type* offset, size_type len)
   232       : internal::StringPieceDetail<STRING_TYPE>(offset, len) {}
   233   BasicStringPiece(const typename STRING_TYPE::const_iterator& begin,
   234                    const typename STRING_TYPE::const_iterator& end)
   235       : internal::StringPieceDetail<STRING_TYPE>(begin, end) {}
   236 };
   238 // Specializes BasicStringPiece for std::string to add a few operations that
   239 // are not needed for string16.
   240 template <> class BasicStringPiece<std::string> :
   241     public internal::StringPieceDetail<std::string> {
   242  public:
   243   BasicStringPiece() {}
   244   BasicStringPiece(const char* str)
   245       : internal::StringPieceDetail<std::string>(str) {}
   246   BasicStringPiece(const std::string& str)
   247       : internal::StringPieceDetail<std::string>(str) {}
   248   BasicStringPiece(const char* offset, size_type len)
   249       : internal::StringPieceDetail<std::string>(offset, len) {}
   250   BasicStringPiece(const std::string::const_iterator& begin,
   251                    const std::string::const_iterator& end)
   252       : internal::StringPieceDetail<std::string>(begin, end) {}
   254   // Prevent the following overload of set() from hiding the definitions in the
   255   // base class.
   256   using internal::StringPieceDetail<std::string>::set;
   258   void set(const void* data, size_type len) {
   259     ptr_ = reinterpret_cast<const value_type*>(data);
   260     length_ = len;
   261   }
   263   void CopyToString(std::string* target) const {
   264     internal::CopyToString(*this, target);
   265   }
   267   void AppendToString(std::string* target) const {
   268     internal::AppendToString(*this, target);
   269   }
   271   // Does "this" start with "x"
   272   bool starts_with(const BasicStringPiece& x) const {
   273     return ((length_ >= x.length_) &&
   274             (wordmemcmp(ptr_, x.ptr_, x.length_) == 0));
   275   }
   277   // Does "this" end with "x"
   278   bool ends_with(const BasicStringPiece& x) const {
   279     return ((length_ >= x.length_) &&
   280             (wordmemcmp(ptr_ + (length_-x.length_), x.ptr_, x.length_) == 0));
   281   }
   283   size_type copy(char* buf, size_type n, size_type pos = 0) const {
   284     return internal::copy(*this, buf, n, pos);
   285   }
   287   size_type find(const BasicStringPiece& s, size_type pos = 0) const {
   288     return internal::find(*this, s, pos);
   289   }
   291   size_type find(char c, size_type pos = 0) const {
   292     return internal::find(*this, c, pos);
   293   }
   295   size_type rfind(const BasicStringPiece& s, size_type pos = npos) const {
   296     return internal::rfind(*this, s, pos);
   297   }
   299   size_type rfind(char c, size_type pos = npos) const {
   300     return internal::rfind(*this, c, pos);
   301   }
   303   size_type find_first_of(const BasicStringPiece& s, size_type pos = 0) const {
   304     return internal::find_first_of(*this, s, pos);
   305   }
   307   size_type find_first_of(char c, size_type pos = 0) const {
   308     return find(c, pos);
   309   }
   311   size_type find_first_not_of(const BasicStringPiece& s,
   312                               size_type pos = 0) const {
   313     return internal::find_first_not_of(*this, s, pos);
   314   }
   316   size_type find_first_not_of(char c, size_type pos = 0) const {
   317     return internal::find_first_not_of(*this, c, pos);
   318   }
   320   size_type find_last_of(const BasicStringPiece& s,
   321                          size_type pos = npos) const {
   322     return internal::find_last_of(*this, s, pos);
   323   }
   325   size_type find_last_of(char c, size_type pos = npos) const {
   326     return rfind(c, pos);
   327   }
   329   size_type find_last_not_of(const BasicStringPiece& s,
   330                              size_type pos = npos) const {
   331     return internal::find_last_not_of(*this, s, pos);
   332   }
   334   size_type find_last_not_of(char c, size_type pos = npos) const {
   335     return internal::find_last_not_of(*this, c, pos);
   336   }
   338   BasicStringPiece substr(size_type pos, size_type n = npos) const {
   339     return internal::substr(*this, pos, n);
   340   }
   341 };
   343 // MSVC doesn't like complex extern templates and DLLs.
   344 #if !defined(COMPILER_MSVC)
   345 // We can't explicitly declare the std::string instantiation here because it was
   346 // already instantiated when specialized, above. Not only is it a no-op, but
   347 // currently it also crashes Clang (see http://crbug.com/107412).
   348 extern template class BASE_EXPORT BasicStringPiece<string16>;
   349 #endif
   351 BASE_EXPORT bool operator==(const StringPiece& x, const StringPiece& y);
   353 inline bool operator!=(const StringPiece& x, const StringPiece& y) {
   354   return !(x == y);
   355 }
   357 inline bool operator<(const StringPiece& x, const StringPiece& y) {
   358   const int r = StringPiece::wordmemcmp(
   359       x.data(), y.data(), (x.size() < y.size() ? x.size() : y.size()));
   360   return ((r < 0) || ((r == 0) && (x.size() < y.size())));
   361 }
   363 inline bool operator>(const StringPiece& x, const StringPiece& y) {
   364   return y < x;
   365 }
   367 inline bool operator<=(const StringPiece& x, const StringPiece& y) {
   368   return !(x > y);
   369 }
   371 inline bool operator>=(const StringPiece& x, const StringPiece& y) {
   372   return !(x < y);
   373 }
   375 inline bool operator==(const StringPiece16& x, const StringPiece16& y) {
   376   if (x.size() != y.size())
   377     return false;
   379   return StringPiece16::wordmemcmp(x.data(), y.data(), x.size()) == 0;
   380 }
   382 inline bool operator!=(const StringPiece16& x, const StringPiece16& y) {
   383   return !(x == y);
   384 }
   386 inline bool operator<(const StringPiece16& x, const StringPiece16& y) {
   387   const int r = StringPiece16::wordmemcmp(
   388       x.data(), y.data(), (x.size() < y.size() ? x.size() : y.size()));
   389   return ((r < 0) || ((r == 0) && (x.size() < y.size())));
   390 }
   392 inline bool operator>(const StringPiece16& x, const StringPiece16& y) {
   393   return y < x;
   394 }
   396 inline bool operator<=(const StringPiece16& x, const StringPiece16& y) {
   397   return !(x > y);
   398 }
   400 inline bool operator>=(const StringPiece16& x, const StringPiece16& y) {
   401   return !(x < y);
   402 }
   404 BASE_EXPORT std::ostream& operator<<(std::ostream& o,
   405                                      const StringPiece& piece);
   407 }  // namespace base
   409 // We provide appropriate hash functions so StringPiece and StringPiece16 can
   410 // be used as keys in hash sets and maps.
   412 // This hash function is copied from base/containers/hash_tables.h. We don't
   413 // use the ones already defined for string and string16 directly because it
   414 // would require the string constructors to be called, which we don't want.
   415 #define HASH_STRING_PIECE(StringPieceType, string_piece)                \
   416   std::size_t result = 0;                                               \
   417   for (StringPieceType::const_iterator i = string_piece.begin();        \
   418        i != string_piece.end(); ++i)                                    \
   419     result = (result * 131) + *i;                                       \
   420   return result;                                                        \
   422 namespace BASE_HASH_NAMESPACE {
   423 #if defined(COMPILER_GCC)
   425 template<>
   426 struct hash<base::StringPiece> {
   427   std::size_t operator()(const base::StringPiece& sp) const {
   428     HASH_STRING_PIECE(base::StringPiece, sp);
   429   }
   430 };
   431 template<>
   432 struct hash<base::StringPiece16> {
   433   std::size_t operator()(const base::StringPiece16& sp16) const {
   434     HASH_STRING_PIECE(base::StringPiece16, sp16);
   435   }
   436 };
   438 #elif defined(COMPILER_MSVC)
   440 inline size_t hash_value(const base::StringPiece& sp) {
   441   HASH_STRING_PIECE(base::StringPiece, sp);
   442 }
   443 inline size_t hash_value(const base::StringPiece16& sp16) {
   444   HASH_STRING_PIECE(base::StringPiece16, sp16);
   445 }
   447 #endif  // COMPILER
   449 }  // namespace BASE_HASH_NAMESPACE
   451 #endif  // BASE_STRINGS_STRING_PIECE_H_

mercurial