| OLD | NEW | 
|    1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. |    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 |    2 // Use of this source code is governed by a BSD-style license that can be | 
|    3 // found in the LICENSE file. |    3 // found in the LICENSE file. | 
|    4 // Copied from strings/stringpiece.cc with modifications |    4 // Copied from strings/stringpiece.cc with modifications | 
|    5  |    5  | 
|    6 #include "base/strings/string_piece.h" |    6 #include "base/strings/string_piece.h" | 
|    7  |    7  | 
|    8 #include <algorithm> |    8 #include <algorithm> | 
|    9 #include <ostream> |    9 #include <ostream> | 
|   10  |   10  | 
|   11 namespace base { |   11 namespace base { | 
 |   12 namespace { | 
 |   13  | 
 |   14 // For each character in characters_wanted, sets the index corresponding | 
 |   15 // to the ASCII code of that character to 1 in table.  This is used by | 
 |   16 // the find_.*_of methods below to tell whether or not a character is in | 
 |   17 // the lookup table in constant time. | 
 |   18 // The argument `table' must be an array that is large enough to hold all | 
 |   19 // the possible values of an unsigned char.  Thus it should be be declared | 
 |   20 // as follows: | 
 |   21 //   bool table[UCHAR_MAX + 1] | 
 |   22 inline void BuildLookupTable(const StringPiece& characters_wanted, | 
 |   23                              bool* table) { | 
 |   24   const size_t length = characters_wanted.length(); | 
 |   25   const char* const data = characters_wanted.data(); | 
 |   26   for (size_t i = 0; i < length; ++i) { | 
 |   27     table[static_cast<unsigned char>(data[i])] = true; | 
 |   28   } | 
 |   29 } | 
 |   30  | 
 |   31 }  // namespace | 
|   12  |   32  | 
|   13 // MSVC doesn't like complex extern templates and DLLs. |   33 // MSVC doesn't like complex extern templates and DLLs. | 
|   14 #if !defined(COMPILER_MSVC) |   34 #if !defined(COMPILER_MSVC) | 
|   15 namespace internal { |   35 template class BasicStringPiece<std::string>; | 
|   16 template class StringPieceDetail<std::string>; |  | 
|   17 template class StringPieceDetail<string16>; |  | 
|   18 }  // namespace internal |  | 
|   19  |  | 
|   20 template class BasicStringPiece<string16>; |   36 template class BasicStringPiece<string16>; | 
|   21 #endif |   37 #endif | 
|   22  |   38  | 
|   23 bool operator==(const StringPiece& x, const StringPiece& y) { |   39 bool operator==(const StringPiece& x, const StringPiece& y) { | 
|   24   if (x.size() != y.size()) |   40   if (x.size() != y.size()) | 
|   25     return false; |   41     return false; | 
|   26  |   42  | 
|   27   return StringPiece::wordmemcmp(x.data(), y.data(), x.size()) == 0; |   43   return StringPiece::wordmemcmp(x.data(), y.data(), x.size()) == 0; | 
|   28 } |   44 } | 
|   29  |   45  | 
|   30 std::ostream& operator<<(std::ostream& o, const StringPiece& piece) { |   46 std::ostream& operator<<(std::ostream& o, const StringPiece& piece) { | 
|   31   o.write(piece.data(), static_cast<std::streamsize>(piece.size())); |   47   o.write(piece.data(), static_cast<std::streamsize>(piece.size())); | 
|   32   return o; |   48   return o; | 
|   33 } |   49 } | 
|   34  |   50  | 
|   35 namespace internal { |   51 namespace internal { | 
|   36 void CopyToString(const StringPiece& self, std::string* target) { |   52  | 
|   37   target->assign(!self.empty() ? self.data() : "", self.size()); |   53 template<typename STR> | 
 |   54 void CopyToStringT(const BasicStringPiece<STR>& self, STR* target) { | 
 |   55   if (self.empty()) | 
 |   56     target->clear(); | 
 |   57   else | 
 |   58     target->assign(self.data(), self.size()); | 
|   38 } |   59 } | 
|   39  |   60  | 
|   40 void AppendToString(const StringPiece& self, std::string* target) { |   61 void CopyToString(const StringPiece& self, std::string* target) { | 
 |   62   CopyToStringT(self, target); | 
 |   63 } | 
 |   64  | 
 |   65 void CopyToString(const StringPiece16& self, string16* target) { | 
 |   66   CopyToStringT(self, target); | 
 |   67 } | 
 |   68  | 
 |   69 template<typename STR> | 
 |   70 void AppendToStringT(const BasicStringPiece<STR>& self, STR* target) { | 
|   41   if (!self.empty()) |   71   if (!self.empty()) | 
|   42     target->append(self.data(), self.size()); |   72     target->append(self.data(), self.size()); | 
|   43 } |   73 } | 
|   44  |   74  | 
|   45 StringPiece::size_type copy(const StringPiece& self, |   75 void AppendToString(const StringPiece& self, std::string* target) { | 
|   46                             char* buf, |   76   AppendToStringT(self, target); | 
|   47                             StringPiece::size_type n, |   77 } | 
|   48                             StringPiece::size_type pos) { |   78  | 
|   49   StringPiece::size_type ret = std::min(self.size() - pos, n); |   79 void AppendToString(const StringPiece16& self, string16* target) { | 
|   50   memcpy(buf, self.data() + pos, ret); |   80   AppendToStringT(self, target); | 
 |   81 } | 
 |   82  | 
 |   83 template<typename STR> | 
 |   84 size_t copyT(const BasicStringPiece<STR>& self, | 
 |   85              typename STR::value_type* buf, | 
 |   86              size_t n, | 
 |   87              size_t pos) { | 
 |   88   size_t ret = std::min(self.size() - pos, n); | 
 |   89   memcpy(buf, self.data() + pos, ret * sizeof(typename STR::value_type)); | 
|   51   return ret; |   90   return ret; | 
|   52 } |   91 } | 
|   53  |   92  | 
|   54 StringPiece::size_type find(const StringPiece& self, |   93 size_t copy(const StringPiece& self, char* buf, size_t n, size_t pos) { | 
|   55                             const StringPiece& s, |   94   return copyT(self, buf, n, pos); | 
|   56                             StringPiece::size_type pos) { |  | 
|   57   if (pos > self.size()) |  | 
|   58     return StringPiece::npos; |  | 
|   59  |  | 
|   60   StringPiece::const_iterator result = |  | 
|   61       std::search(self.begin() + pos, self.end(), s.begin(), s.end()); |  | 
|   62   const StringPiece::size_type xpos = |  | 
|   63     static_cast<size_t>(result - self.begin()); |  | 
|   64   return xpos + s.size() <= self.size() ? xpos : StringPiece::npos; |  | 
|   65 } |   95 } | 
|   66  |   96  | 
|   67 StringPiece::size_type find(const StringPiece& self, |   97 size_t copy(const StringPiece16& self, char16* buf, size_t n, size_t pos) { | 
|   68                             char c, |   98   return copyT(self, buf, n, pos); | 
|   69                             StringPiece::size_type pos) { |   99 } | 
 |  100  | 
 |  101 template<typename STR> | 
 |  102 size_t findT(const BasicStringPiece<STR>& self, | 
 |  103              const BasicStringPiece<STR>& s, | 
 |  104              size_t pos) { | 
 |  105   if (pos > self.size()) | 
 |  106     return BasicStringPiece<STR>::npos; | 
 |  107  | 
 |  108   typename BasicStringPiece<STR>::const_iterator result = | 
 |  109       std::search(self.begin() + pos, self.end(), s.begin(), s.end()); | 
 |  110   const size_t xpos = | 
 |  111     static_cast<size_t>(result - self.begin()); | 
 |  112   return xpos + s.size() <= self.size() ? xpos : BasicStringPiece<STR>::npos; | 
 |  113 } | 
 |  114  | 
 |  115 size_t find(const StringPiece& self, const StringPiece& s, size_t pos) { | 
 |  116   return findT(self, s, pos); | 
 |  117 } | 
 |  118  | 
 |  119 size_t find(const StringPiece16& self, const StringPiece16& s, size_t pos) { | 
 |  120   return findT(self, s, pos); | 
 |  121 } | 
 |  122  | 
 |  123 template<typename STR> | 
 |  124 size_t findT(const BasicStringPiece<STR>& self, | 
 |  125              typename STR::value_type c, | 
 |  126              size_t pos) { | 
|   70   if (pos >= self.size()) |  127   if (pos >= self.size()) | 
|   71     return StringPiece::npos; |  128     return BasicStringPiece<STR>::npos; | 
|   72  |  129  | 
|   73   StringPiece::const_iterator result = |  130   typename BasicStringPiece<STR>::const_iterator result = | 
|   74       std::find(self.begin() + pos, self.end(), c); |  131       std::find(self.begin() + pos, self.end(), c); | 
|   75   return result != self.end() ? |  132   return result != self.end() ? | 
|   76       static_cast<size_t>(result - self.begin()) : StringPiece::npos; |  133       static_cast<size_t>(result - self.begin()) : BasicStringPiece<STR>::npos; | 
|   77 } |  134 } | 
|   78  |  135  | 
|   79 StringPiece::size_type rfind(const StringPiece& self, |  136 size_t find(const StringPiece& self, char c, size_t pos) { | 
|   80                              const StringPiece& s, |  137   return findT(self, c, pos); | 
|   81                              StringPiece::size_type pos) { |  138 } | 
 |  139  | 
 |  140 size_t find(const StringPiece16& self, char16 c, size_t pos) { | 
 |  141   return findT(self, c, pos); | 
 |  142 } | 
 |  143  | 
 |  144 template<typename STR> | 
 |  145 size_t rfindT(const BasicStringPiece<STR>& self, | 
 |  146               const BasicStringPiece<STR>& s, | 
 |  147               size_t pos) { | 
|   82   if (self.size() < s.size()) |  148   if (self.size() < s.size()) | 
|   83     return StringPiece::npos; |  149     return BasicStringPiece<STR>::npos; | 
|   84  |  150  | 
|   85   if (s.empty()) |  151   if (s.empty()) | 
|   86     return std::min(self.size(), pos); |  152     return std::min(self.size(), pos); | 
|   87  |  153  | 
|   88   StringPiece::const_iterator last = |  154   typename BasicStringPiece<STR>::const_iterator last = | 
|   89       self.begin() + std::min(self.size() - s.size(), pos) + s.size(); |  155       self.begin() + std::min(self.size() - s.size(), pos) + s.size(); | 
|   90   StringPiece::const_iterator result = |  156   typename BasicStringPiece<STR>::const_iterator result = | 
|   91       std::find_end(self.begin(), last, s.begin(), s.end()); |  157       std::find_end(self.begin(), last, s.begin(), s.end()); | 
|   92   return result != last ? |  158   return result != last ? | 
|   93       static_cast<size_t>(result - self.begin()) : StringPiece::npos; |  159       static_cast<size_t>(result - self.begin()) : BasicStringPiece<STR>::npos; | 
|   94 } |  160 } | 
|   95  |  161  | 
|   96 StringPiece::size_type rfind(const StringPiece& self, |  162 size_t rfind(const StringPiece& self, const StringPiece& s, size_t pos) { | 
|   97                              char c, |  163   return rfindT(self, s, pos); | 
|   98                              StringPiece::size_type pos) { |  164 } | 
 |  165  | 
 |  166 size_t rfind(const StringPiece16& self, const StringPiece16& s, size_t pos) { | 
 |  167   return rfindT(self, s, pos); | 
 |  168 } | 
 |  169  | 
 |  170 template<typename STR> | 
 |  171 size_t rfindT(const BasicStringPiece<STR>& self, | 
 |  172               typename STR::value_type c, | 
 |  173               size_t pos) { | 
|   99   if (self.size() == 0) |  174   if (self.size() == 0) | 
|  100     return StringPiece::npos; |  175     return BasicStringPiece<STR>::npos; | 
|  101  |  176  | 
|  102   for (StringPiece::size_type i = std::min(pos, self.size() - 1); ; --i) { |  177   for (size_t i = std::min(pos, self.size() - 1); ; | 
 |  178        --i) { | 
|  103     if (self.data()[i] == c) |  179     if (self.data()[i] == c) | 
|  104       return i; |  180       return i; | 
|  105     if (i == 0) |  181     if (i == 0) | 
|  106       break; |  182       break; | 
|  107   } |  183   } | 
|  108   return StringPiece::npos; |  184   return BasicStringPiece<STR>::npos; | 
|  109 } |  185 } | 
|  110  |  186  | 
|  111 // For each character in characters_wanted, sets the index corresponding |  187 size_t rfind(const StringPiece& self, char c, size_t pos) { | 
|  112 // to the ASCII code of that character to 1 in table.  This is used by |  188   return rfindT(self, c, pos); | 
|  113 // the find_.*_of methods below to tell whether or not a character is in |  | 
|  114 // the lookup table in constant time. |  | 
|  115 // The argument `table' must be an array that is large enough to hold all |  | 
|  116 // the possible values of an unsigned char.  Thus it should be be declared |  | 
|  117 // as follows: |  | 
|  118 //   bool table[UCHAR_MAX + 1] |  | 
|  119 static inline void BuildLookupTable(const StringPiece& characters_wanted, |  | 
|  120                                     bool* table) { |  | 
|  121   const StringPiece::size_type length = characters_wanted.length(); |  | 
|  122   const char* const data = characters_wanted.data(); |  | 
|  123   for (StringPiece::size_type i = 0; i < length; ++i) { |  | 
|  124     table[static_cast<unsigned char>(data[i])] = true; |  | 
|  125   } |  | 
|  126 } |  189 } | 
|  127  |  190  | 
|  128 StringPiece::size_type find_first_of(const StringPiece& self, |  191 size_t rfind(const StringPiece16& self, char16 c, size_t pos) { | 
|  129                                      const StringPiece& s, |  192   return rfindT(self, c, pos); | 
|  130                                      StringPiece::size_type pos) { |  193 } | 
 |  194  | 
 |  195 // 8-bit version using lookup table. | 
 |  196 size_t find_first_of(const StringPiece& self, | 
 |  197                      const StringPiece& s, | 
 |  198                      size_t pos) { | 
|  131   if (self.size() == 0 || s.size() == 0) |  199   if (self.size() == 0 || s.size() == 0) | 
|  132     return StringPiece::npos; |  200     return StringPiece::npos; | 
|  133  |  201  | 
|  134   // Avoid the cost of BuildLookupTable() for a single-character search. |  202   // Avoid the cost of BuildLookupTable() for a single-character search. | 
|  135   if (s.size() == 1) |  203   if (s.size() == 1) | 
|  136     return find(self, s.data()[0], pos); |  204     return find(self, s.data()[0], pos); | 
|  137  |  205  | 
|  138   bool lookup[UCHAR_MAX + 1] = { false }; |  206   bool lookup[UCHAR_MAX + 1] = { false }; | 
|  139   BuildLookupTable(s, lookup); |  207   BuildLookupTable(s, lookup); | 
|  140   for (StringPiece::size_type i = pos; i < self.size(); ++i) { |  208   for (size_t i = pos; i < self.size(); ++i) { | 
|  141     if (lookup[static_cast<unsigned char>(self.data()[i])]) { |  209     if (lookup[static_cast<unsigned char>(self.data()[i])]) { | 
|  142       return i; |  210       return i; | 
|  143     } |  211     } | 
|  144   } |  212   } | 
|  145   return StringPiece::npos; |  213   return StringPiece::npos; | 
|  146 } |  214 } | 
|  147  |  215  | 
|  148 StringPiece::size_type find_first_not_of(const StringPiece& self, |  216 // 16-bit brute force version. | 
|  149                                          const StringPiece& s, |  217 size_t find_first_of(const StringPiece16& self, | 
|  150                                          StringPiece::size_type pos) { |  218                      const StringPiece16& s, | 
 |  219                      size_t pos) { | 
 |  220   StringPiece16::const_iterator found = | 
 |  221       std::find_first_of(self.begin() + pos, self.end(), s.begin(), s.end()); | 
 |  222   if (found == self.end()) | 
 |  223     return StringPiece16::npos; | 
 |  224   return found - self.begin(); | 
 |  225 } | 
 |  226  | 
 |  227 // 8-bit version using lookup table. | 
 |  228 size_t find_first_not_of(const StringPiece& self, | 
 |  229                          const StringPiece& s, | 
 |  230                          size_t pos) { | 
|  151   if (self.size() == 0) |  231   if (self.size() == 0) | 
|  152     return StringPiece::npos; |  232     return StringPiece::npos; | 
|  153  |  233  | 
|  154   if (s.size() == 0) |  234   if (s.size() == 0) | 
|  155     return 0; |  235     return 0; | 
|  156  |  236  | 
|  157   // Avoid the cost of BuildLookupTable() for a single-character search. |  237   // Avoid the cost of BuildLookupTable() for a single-character search. | 
|  158   if (s.size() == 1) |  238   if (s.size() == 1) | 
|  159     return find_first_not_of(self, s.data()[0], pos); |  239     return find_first_not_of(self, s.data()[0], pos); | 
|  160  |  240  | 
|  161   bool lookup[UCHAR_MAX + 1] = { false }; |  241   bool lookup[UCHAR_MAX + 1] = { false }; | 
|  162   BuildLookupTable(s, lookup); |  242   BuildLookupTable(s, lookup); | 
|  163   for (StringPiece::size_type i = pos; i < self.size(); ++i) { |  243   for (size_t i = pos; i < self.size(); ++i) { | 
|  164     if (!lookup[static_cast<unsigned char>(self.data()[i])]) { |  244     if (!lookup[static_cast<unsigned char>(self.data()[i])]) { | 
|  165       return i; |  245       return i; | 
|  166     } |  246     } | 
|  167   } |  247   } | 
|  168   return StringPiece::npos; |  248   return StringPiece::npos; | 
|  169 } |  249 } | 
|  170  |  250  | 
|  171 StringPiece::size_type find_first_not_of(const StringPiece& self, |  251 // 16-bit brute-force version. | 
|  172                                          char c, |  252 BASE_EXPORT size_t find_first_not_of(const StringPiece16& self, | 
|  173                                          StringPiece::size_type pos) { |  253                                      const StringPiece16& s, | 
 |  254                                      size_t pos) { | 
|  174   if (self.size() == 0) |  255   if (self.size() == 0) | 
|  175     return StringPiece::npos; |  256     return StringPiece16::npos; | 
 |  257  | 
 |  258   for (size_t self_i = pos; self_i < self.size(); ++self_i) { | 
 |  259     bool found = false; | 
 |  260     for (size_t s_i = 0; s_i < s.size(); ++s_i) { | 
 |  261       if (self[self_i] == s[s_i]) { | 
 |  262         found = true; | 
 |  263         break; | 
 |  264       } | 
 |  265     } | 
 |  266     if (!found) | 
 |  267       return self_i; | 
 |  268   } | 
 |  269   return StringPiece16::npos; | 
 |  270 } | 
 |  271  | 
 |  272 template<typename STR> | 
 |  273 size_t find_first_not_ofT(const BasicStringPiece<STR>& self, | 
 |  274                           typename STR::value_type c, | 
 |  275                           size_t pos) { | 
 |  276   if (self.size() == 0) | 
 |  277     return BasicStringPiece<STR>::npos; | 
|  176  |  278  | 
|  177   for (; pos < self.size(); ++pos) { |  279   for (; pos < self.size(); ++pos) { | 
|  178     if (self.data()[pos] != c) { |  280     if (self.data()[pos] != c) { | 
|  179       return pos; |  281       return pos; | 
|  180     } |  282     } | 
|  181   } |  283   } | 
|  182   return StringPiece::npos; |  284   return BasicStringPiece<STR>::npos; | 
|  183 } |  285 } | 
|  184  |  286  | 
|  185 StringPiece::size_type find_last_of(const StringPiece& self, |  287 size_t find_first_not_of(const StringPiece& self, | 
|  186                                     const StringPiece& s, |  288                          char c, | 
|  187                                     StringPiece::size_type pos) { |  289                          size_t pos) { | 
 |  290   return find_first_not_ofT(self, c, pos); | 
 |  291 } | 
 |  292  | 
 |  293 size_t find_first_not_of(const StringPiece16& self, | 
 |  294                          char16 c, | 
 |  295                          size_t pos) { | 
 |  296   return find_first_not_ofT(self, c, pos); | 
 |  297 } | 
 |  298  | 
 |  299 // 8-bit version using lookup table. | 
 |  300 size_t find_last_of(const StringPiece& self, const StringPiece& s, size_t pos) { | 
|  188   if (self.size() == 0 || s.size() == 0) |  301   if (self.size() == 0 || s.size() == 0) | 
|  189     return StringPiece::npos; |  302     return StringPiece::npos; | 
|  190  |  303  | 
|  191   // Avoid the cost of BuildLookupTable() for a single-character search. |  304   // Avoid the cost of BuildLookupTable() for a single-character search. | 
|  192   if (s.size() == 1) |  305   if (s.size() == 1) | 
|  193     return rfind(self, s.data()[0], pos); |  306     return rfind(self, s.data()[0], pos); | 
|  194  |  307  | 
|  195   bool lookup[UCHAR_MAX + 1] = { false }; |  308   bool lookup[UCHAR_MAX + 1] = { false }; | 
|  196   BuildLookupTable(s, lookup); |  309   BuildLookupTable(s, lookup); | 
|  197   for (StringPiece::size_type i = std::min(pos, self.size() - 1); ; --i) { |  310   for (size_t i = std::min(pos, self.size() - 1); ; --i) { | 
|  198     if (lookup[static_cast<unsigned char>(self.data()[i])]) |  311     if (lookup[static_cast<unsigned char>(self.data()[i])]) | 
|  199       return i; |  312       return i; | 
|  200     if (i == 0) |  313     if (i == 0) | 
|  201       break; |  314       break; | 
|  202   } |  315   } | 
|  203   return StringPiece::npos; |  316   return StringPiece::npos; | 
|  204 } |  317 } | 
|  205  |  318  | 
|  206 StringPiece::size_type find_last_not_of(const StringPiece& self, |  319 // 16-bit brute-force version. | 
|  207                                         const StringPiece& s, |  320 size_t find_last_of(const StringPiece16& self, | 
|  208                                         StringPiece::size_type pos) { |  321                     const StringPiece16& s, | 
 |  322                     size_t pos) { | 
 |  323   if (self.size() == 0) | 
 |  324     return StringPiece16::npos; | 
 |  325  | 
 |  326   for (size_t self_i = std::min(pos, self.size() - 1); ; | 
 |  327        --self_i) { | 
 |  328     for (size_t s_i = 0; s_i < s.size(); s_i++) { | 
 |  329       if (self.data()[self_i] == s[s_i]) | 
 |  330         return self_i; | 
 |  331     } | 
 |  332     if (self_i == 0) | 
 |  333       break; | 
 |  334   } | 
 |  335   return StringPiece16::npos; | 
 |  336 } | 
 |  337  | 
 |  338 // 8-bit version using lookup table. | 
 |  339 size_t find_last_not_of(const StringPiece& self, | 
 |  340                         const StringPiece& s, | 
 |  341                         size_t pos) { | 
|  209   if (self.size() == 0) |  342   if (self.size() == 0) | 
|  210     return StringPiece::npos; |  343     return StringPiece::npos; | 
|  211  |  344  | 
|  212   StringPiece::size_type i = std::min(pos, self.size() - 1); |  345   size_t i = std::min(pos, self.size() - 1); | 
|  213   if (s.size() == 0) |  346   if (s.size() == 0) | 
|  214     return i; |  347     return i; | 
|  215  |  348  | 
|  216   // Avoid the cost of BuildLookupTable() for a single-character search. |  349   // Avoid the cost of BuildLookupTable() for a single-character search. | 
|  217   if (s.size() == 1) |  350   if (s.size() == 1) | 
|  218     return find_last_not_of(self, s.data()[0], pos); |  351     return find_last_not_of(self, s.data()[0], pos); | 
|  219  |  352  | 
|  220   bool lookup[UCHAR_MAX + 1] = { false }; |  353   bool lookup[UCHAR_MAX + 1] = { false }; | 
|  221   BuildLookupTable(s, lookup); |  354   BuildLookupTable(s, lookup); | 
|  222   for (; ; --i) { |  355   for (; ; --i) { | 
|  223     if (!lookup[static_cast<unsigned char>(self.data()[i])]) |  356     if (!lookup[static_cast<unsigned char>(self.data()[i])]) | 
|  224       return i; |  357       return i; | 
|  225     if (i == 0) |  358     if (i == 0) | 
|  226       break; |  359       break; | 
|  227   } |  360   } | 
|  228   return StringPiece::npos; |  361   return StringPiece::npos; | 
|  229 } |  362 } | 
|  230  |  363  | 
|  231 StringPiece::size_type find_last_not_of(const StringPiece& self, |  364 // 16-bit brute-force version. | 
|  232                                         char c, |  365 size_t find_last_not_of(const StringPiece16& self, | 
|  233                                         StringPiece::size_type pos) { |  366                         const StringPiece16& s, | 
 |  367                         size_t pos) { | 
|  234   if (self.size() == 0) |  368   if (self.size() == 0) | 
|  235     return StringPiece::npos; |  369     return StringPiece::npos; | 
|  236  |  370  | 
|  237   for (StringPiece::size_type i = std::min(pos, self.size() - 1); ; --i) { |  371   for (size_t self_i = std::min(pos, self.size() - 1); ; --self_i) { | 
 |  372     bool found = false; | 
 |  373     for (size_t s_i = 0; s_i < s.size(); s_i++) { | 
 |  374       if (self.data()[self_i] == s[s_i]) { | 
 |  375         found = true; | 
 |  376         break; | 
 |  377       } | 
 |  378     } | 
 |  379     if (!found) | 
 |  380       return self_i; | 
 |  381     if (self_i == 0) | 
 |  382       break; | 
 |  383   } | 
 |  384   return StringPiece16::npos; | 
 |  385 } | 
 |  386  | 
 |  387 template<typename STR> | 
 |  388 size_t find_last_not_ofT(const BasicStringPiece<STR>& self, | 
 |  389                          typename STR::value_type c, | 
 |  390                          size_t pos) { | 
 |  391   if (self.size() == 0) | 
 |  392     return BasicStringPiece<STR>::npos; | 
 |  393  | 
 |  394   for (size_t i = std::min(pos, self.size() - 1); ; --i) { | 
|  238     if (self.data()[i] != c) |  395     if (self.data()[i] != c) | 
|  239       return i; |  396       return i; | 
|  240     if (i == 0) |  397     if (i == 0) | 
|  241       break; |  398       break; | 
|  242   } |  399   } | 
|  243   return StringPiece::npos; |  400   return BasicStringPiece<STR>::npos; | 
 |  401 } | 
 |  402  | 
 |  403 size_t find_last_not_of(const StringPiece& self, | 
 |  404                         char c, | 
 |  405                         size_t pos) { | 
 |  406   return find_last_not_ofT(self, c, pos); | 
 |  407 } | 
 |  408  | 
 |  409 size_t find_last_not_of(const StringPiece16& self, | 
 |  410                         char16 c, | 
 |  411                         size_t pos) { | 
 |  412   return find_last_not_ofT(self, c, pos); | 
 |  413 } | 
 |  414  | 
 |  415 template<typename STR> | 
 |  416 BasicStringPiece<STR> substrT(const BasicStringPiece<STR>& self, | 
 |  417                               size_t pos, | 
 |  418                               size_t n) { | 
 |  419   if (pos > self.size()) pos = self.size(); | 
 |  420   if (n > self.size() - pos) n = self.size() - pos; | 
 |  421   return BasicStringPiece<STR>(self.data() + pos, n); | 
|  244 } |  422 } | 
|  245  |  423  | 
|  246 StringPiece substr(const StringPiece& self, |  424 StringPiece substr(const StringPiece& self, | 
|  247                    StringPiece::size_type pos, |  425                    size_t pos, | 
|  248                    StringPiece::size_type n) { |  426                    size_t n) { | 
|  249   if (pos > self.size()) pos = self.size(); |  427   return substrT(self, pos, n); | 
|  250   if (n > self.size() - pos) n = self.size() - pos; |  428 } | 
|  251   return StringPiece(self.data() + pos, n); |  429  | 
 |  430 StringPiece16 substr(const StringPiece16& self, | 
 |  431                      size_t pos, | 
 |  432                      size_t n) { | 
 |  433   return substrT(self, pos, n); | 
|  252 } |  434 } | 
|  253  |  435  | 
|  254 }  // namespace internal |  436 }  // namespace internal | 
|  255 }  // namespace base |  437 }  // namespace base | 
| OLD | NEW |