1.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 1.2 +++ b/security/sandbox/chromium/base/strings/string_piece.cc Wed Dec 31 06:09:35 2014 +0100 1.3 @@ -0,0 +1,255 @@ 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.cc with modifications 1.8 + 1.9 +#include "base/strings/string_piece.h" 1.10 + 1.11 +#include <algorithm> 1.12 +#include <ostream> 1.13 + 1.14 +namespace base { 1.15 + 1.16 +// MSVC doesn't like complex extern templates and DLLs. 1.17 +#if !defined(COMPILER_MSVC) 1.18 +namespace internal { 1.19 +template class StringPieceDetail<std::string>; 1.20 +template class StringPieceDetail<string16>; 1.21 +} // namespace internal 1.22 + 1.23 +template class BasicStringPiece<string16>; 1.24 +#endif 1.25 + 1.26 +bool operator==(const StringPiece& x, const StringPiece& y) { 1.27 + if (x.size() != y.size()) 1.28 + return false; 1.29 + 1.30 + return StringPiece::wordmemcmp(x.data(), y.data(), x.size()) == 0; 1.31 +} 1.32 + 1.33 +std::ostream& operator<<(std::ostream& o, const StringPiece& piece) { 1.34 + o.write(piece.data(), static_cast<std::streamsize>(piece.size())); 1.35 + return o; 1.36 +} 1.37 + 1.38 +namespace internal { 1.39 +void CopyToString(const StringPiece& self, std::string* target) { 1.40 + target->assign(!self.empty() ? self.data() : "", self.size()); 1.41 +} 1.42 + 1.43 +void AppendToString(const StringPiece& self, std::string* target) { 1.44 + if (!self.empty()) 1.45 + target->append(self.data(), self.size()); 1.46 +} 1.47 + 1.48 +StringPiece::size_type copy(const StringPiece& self, 1.49 + char* buf, 1.50 + StringPiece::size_type n, 1.51 + StringPiece::size_type pos) { 1.52 + StringPiece::size_type ret = std::min(self.size() - pos, n); 1.53 + memcpy(buf, self.data() + pos, ret); 1.54 + return ret; 1.55 +} 1.56 + 1.57 +StringPiece::size_type find(const StringPiece& self, 1.58 + const StringPiece& s, 1.59 + StringPiece::size_type pos) { 1.60 + if (pos > self.size()) 1.61 + return StringPiece::npos; 1.62 + 1.63 + StringPiece::const_iterator result = 1.64 + std::search(self.begin() + pos, self.end(), s.begin(), s.end()); 1.65 + const StringPiece::size_type xpos = 1.66 + static_cast<size_t>(result - self.begin()); 1.67 + return xpos + s.size() <= self.size() ? xpos : StringPiece::npos; 1.68 +} 1.69 + 1.70 +StringPiece::size_type find(const StringPiece& self, 1.71 + char c, 1.72 + StringPiece::size_type pos) { 1.73 + if (pos >= self.size()) 1.74 + return StringPiece::npos; 1.75 + 1.76 + StringPiece::const_iterator result = 1.77 + std::find(self.begin() + pos, self.end(), c); 1.78 + return result != self.end() ? 1.79 + static_cast<size_t>(result - self.begin()) : StringPiece::npos; 1.80 +} 1.81 + 1.82 +StringPiece::size_type rfind(const StringPiece& self, 1.83 + const StringPiece& s, 1.84 + StringPiece::size_type pos) { 1.85 + if (self.size() < s.size()) 1.86 + return StringPiece::npos; 1.87 + 1.88 + if (s.empty()) 1.89 + return std::min(self.size(), pos); 1.90 + 1.91 + StringPiece::const_iterator last = 1.92 + self.begin() + std::min(self.size() - s.size(), pos) + s.size(); 1.93 + StringPiece::const_iterator result = 1.94 + std::find_end(self.begin(), last, s.begin(), s.end()); 1.95 + return result != last ? 1.96 + static_cast<size_t>(result - self.begin()) : StringPiece::npos; 1.97 +} 1.98 + 1.99 +StringPiece::size_type rfind(const StringPiece& self, 1.100 + char c, 1.101 + StringPiece::size_type pos) { 1.102 + if (self.size() == 0) 1.103 + return StringPiece::npos; 1.104 + 1.105 + for (StringPiece::size_type i = std::min(pos, self.size() - 1); ; --i) { 1.106 + if (self.data()[i] == c) 1.107 + return i; 1.108 + if (i == 0) 1.109 + break; 1.110 + } 1.111 + return StringPiece::npos; 1.112 +} 1.113 + 1.114 +// For each character in characters_wanted, sets the index corresponding 1.115 +// to the ASCII code of that character to 1 in table. This is used by 1.116 +// the find_.*_of methods below to tell whether or not a character is in 1.117 +// the lookup table in constant time. 1.118 +// The argument `table' must be an array that is large enough to hold all 1.119 +// the possible values of an unsigned char. Thus it should be be declared 1.120 +// as follows: 1.121 +// bool table[UCHAR_MAX + 1] 1.122 +static inline void BuildLookupTable(const StringPiece& characters_wanted, 1.123 + bool* table) { 1.124 + const StringPiece::size_type length = characters_wanted.length(); 1.125 + const char* const data = characters_wanted.data(); 1.126 + for (StringPiece::size_type i = 0; i < length; ++i) { 1.127 + table[static_cast<unsigned char>(data[i])] = true; 1.128 + } 1.129 +} 1.130 + 1.131 +StringPiece::size_type find_first_of(const StringPiece& self, 1.132 + const StringPiece& s, 1.133 + StringPiece::size_type pos) { 1.134 + if (self.size() == 0 || s.size() == 0) 1.135 + return StringPiece::npos; 1.136 + 1.137 + // Avoid the cost of BuildLookupTable() for a single-character search. 1.138 + if (s.size() == 1) 1.139 + return find(self, s.data()[0], pos); 1.140 + 1.141 + bool lookup[UCHAR_MAX + 1] = { false }; 1.142 + BuildLookupTable(s, lookup); 1.143 + for (StringPiece::size_type i = pos; i < self.size(); ++i) { 1.144 + if (lookup[static_cast<unsigned char>(self.data()[i])]) { 1.145 + return i; 1.146 + } 1.147 + } 1.148 + return StringPiece::npos; 1.149 +} 1.150 + 1.151 +StringPiece::size_type find_first_not_of(const StringPiece& self, 1.152 + const StringPiece& s, 1.153 + StringPiece::size_type pos) { 1.154 + if (self.size() == 0) 1.155 + return StringPiece::npos; 1.156 + 1.157 + if (s.size() == 0) 1.158 + return 0; 1.159 + 1.160 + // Avoid the cost of BuildLookupTable() for a single-character search. 1.161 + if (s.size() == 1) 1.162 + return find_first_not_of(self, s.data()[0], pos); 1.163 + 1.164 + bool lookup[UCHAR_MAX + 1] = { false }; 1.165 + BuildLookupTable(s, lookup); 1.166 + for (StringPiece::size_type i = pos; i < self.size(); ++i) { 1.167 + if (!lookup[static_cast<unsigned char>(self.data()[i])]) { 1.168 + return i; 1.169 + } 1.170 + } 1.171 + return StringPiece::npos; 1.172 +} 1.173 + 1.174 +StringPiece::size_type find_first_not_of(const StringPiece& self, 1.175 + char c, 1.176 + StringPiece::size_type pos) { 1.177 + if (self.size() == 0) 1.178 + return StringPiece::npos; 1.179 + 1.180 + for (; pos < self.size(); ++pos) { 1.181 + if (self.data()[pos] != c) { 1.182 + return pos; 1.183 + } 1.184 + } 1.185 + return StringPiece::npos; 1.186 +} 1.187 + 1.188 +StringPiece::size_type find_last_of(const StringPiece& self, 1.189 + const StringPiece& s, 1.190 + StringPiece::size_type pos) { 1.191 + if (self.size() == 0 || s.size() == 0) 1.192 + return StringPiece::npos; 1.193 + 1.194 + // Avoid the cost of BuildLookupTable() for a single-character search. 1.195 + if (s.size() == 1) 1.196 + return rfind(self, s.data()[0], pos); 1.197 + 1.198 + bool lookup[UCHAR_MAX + 1] = { false }; 1.199 + BuildLookupTable(s, lookup); 1.200 + for (StringPiece::size_type i = std::min(pos, self.size() - 1); ; --i) { 1.201 + if (lookup[static_cast<unsigned char>(self.data()[i])]) 1.202 + return i; 1.203 + if (i == 0) 1.204 + break; 1.205 + } 1.206 + return StringPiece::npos; 1.207 +} 1.208 + 1.209 +StringPiece::size_type find_last_not_of(const StringPiece& self, 1.210 + const StringPiece& s, 1.211 + StringPiece::size_type pos) { 1.212 + if (self.size() == 0) 1.213 + return StringPiece::npos; 1.214 + 1.215 + StringPiece::size_type i = std::min(pos, self.size() - 1); 1.216 + if (s.size() == 0) 1.217 + return i; 1.218 + 1.219 + // Avoid the cost of BuildLookupTable() for a single-character search. 1.220 + if (s.size() == 1) 1.221 + return find_last_not_of(self, s.data()[0], pos); 1.222 + 1.223 + bool lookup[UCHAR_MAX + 1] = { false }; 1.224 + BuildLookupTable(s, lookup); 1.225 + for (; ; --i) { 1.226 + if (!lookup[static_cast<unsigned char>(self.data()[i])]) 1.227 + return i; 1.228 + if (i == 0) 1.229 + break; 1.230 + } 1.231 + return StringPiece::npos; 1.232 +} 1.233 + 1.234 +StringPiece::size_type find_last_not_of(const StringPiece& self, 1.235 + char c, 1.236 + StringPiece::size_type pos) { 1.237 + if (self.size() == 0) 1.238 + return StringPiece::npos; 1.239 + 1.240 + for (StringPiece::size_type i = std::min(pos, self.size() - 1); ; --i) { 1.241 + if (self.data()[i] != c) 1.242 + return i; 1.243 + if (i == 0) 1.244 + break; 1.245 + } 1.246 + return StringPiece::npos; 1.247 +} 1.248 + 1.249 +StringPiece substr(const StringPiece& self, 1.250 + StringPiece::size_type pos, 1.251 + StringPiece::size_type n) { 1.252 + if (pos > self.size()) pos = self.size(); 1.253 + if (n > self.size() - pos) n = self.size() - pos; 1.254 + return StringPiece(self.data() + pos, n); 1.255 +} 1.256 + 1.257 +} // namespace internal 1.258 +} // namespace base