Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(215)

Side by Side Diff: base/string_piece.cc

Issue 8659047: De-duplicate common code from StringPiece, StringPiece16, and their tests. (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: Fix two bugs introduced during refactoring. Created 9 years ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
« no previous file with comments | « base/string_piece.h ('k') | base/string_piece_unittest.cc » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 // Copyright (c) 2011 The Chromium Authors. All rights reserved. 1 // Copyright (c) 2011 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 <algorithm> 6 #include <algorithm>
7 #include <ostream> 7 #include <ostream>
8 8
9 #include "base/string_piece.h" 9 #include "base/string_piece.h"
10 10
11 namespace base { 11 namespace base {
12 12
13 typedef StringPiece::size_type size_type; 13 // MSVC doesn't like complex extern templates and DLLs.
14 #if !defined(COMPILER_MSVC)
15 namespace internal {
16 template class StringPieceDetail<std::string>;
17 template class StringPieceDetail<string16>;
18 } // namespace internal
19
20 template class BasicStringPiece<string16>;
21 #endif
14 22
15 bool operator==(const StringPiece& x, const StringPiece& y) { 23 bool operator==(const StringPiece& x, const StringPiece& y) {
16 if (x.size() != y.size()) 24 if (x.size() != y.size())
17 return false; 25 return false;
18 26
19 return StringPiece::wordmemcmp(x.data(), y.data(), x.size()) == 0; 27 return StringPiece::wordmemcmp(x.data(), y.data(), x.size()) == 0;
20 } 28 }
21 29
22 void StringPiece::CopyToString(std::string* target) const { 30 namespace internal {
23 target->assign(!empty() ? data() : "", size()); 31 void CopyToString(const StringPiece& self, std::string* target) {
32 target->assign(!self.empty() ? self.data() : "", self.size());
24 } 33 }
25 34
26 void StringPiece::AppendToString(std::string* target) const { 35 void AppendToString(const StringPiece& self, std::string* target) {
27 if (!empty()) 36 if (!self.empty())
28 target->append(data(), size()); 37 target->append(self.data(), self.size());
29 } 38 }
30 39
31 size_type StringPiece::copy(char* buf, size_type n, size_type pos) const { 40 StringPiece::size_type copy(const StringPiece& self,
32 size_type ret = std::min(length_ - pos, n); 41 char* buf,
33 memcpy(buf, ptr_ + pos, ret); 42 StringPiece::size_type n,
43 StringPiece::size_type pos) {
44 StringPiece::size_type ret = std::min(self.size() - pos, n);
45 memcpy(buf, self.data() + pos, ret);
34 return ret; 46 return ret;
35 } 47 }
36 48
37 size_type StringPiece::find(const StringPiece& s, size_type pos) const { 49 StringPiece::size_type find(const StringPiece& self,
38 if (pos > length_) 50 const StringPiece& s,
39 return npos; 51 StringPiece::size_type pos) {
52 if (pos > self.size())
53 return StringPiece::npos;
40 54
41 const char* result = std::search(ptr_ + pos, ptr_ + length_, 55 StringPiece::const_iterator result =
42 s.ptr_, s.ptr_ + s.length_); 56 std::search(self.begin() + pos, self.end(), s.begin(), s.end());
43 const size_type xpos = result - ptr_; 57 const StringPiece::size_type xpos =
44 return xpos + s.length_ <= length_ ? xpos : npos; 58 static_cast<size_t>(result - self.begin());
59 return xpos + s.size() <= self.size() ? xpos : StringPiece::npos;
45 } 60 }
46 61
47 size_type StringPiece::find(char c, size_type pos) const { 62 StringPiece::size_type find(const StringPiece& self,
48 if (pos >= length_) 63 char c,
49 return npos; 64 StringPiece::size_type pos) {
65 if (pos >= self.size())
66 return StringPiece::npos;
50 67
51 const char* result = std::find(ptr_ + pos, ptr_ + length_, c); 68 StringPiece::const_iterator result =
52 return result != ptr_ + length_ ? static_cast<size_t>(result - ptr_) : npos; 69 std::find(self.begin() + pos, self.end(), c);
70 return result != self.end() ?
71 static_cast<size_t>(result - self.begin()) : StringPiece::npos;
53 } 72 }
54 73
55 size_type StringPiece::rfind(const StringPiece& s, size_type pos) const { 74 StringPiece::size_type rfind(const StringPiece& self,
56 if (length_ < s.length_) 75 const StringPiece& s,
57 return npos; 76 StringPiece::size_type pos) {
77 if (self.size() < s.size())
78 return StringPiece::npos;
58 79
59 if (s.empty()) 80 if (s.empty())
60 return std::min(length_, pos); 81 return std::min(self.size(), pos);
61 82
62 const char* last = ptr_ + std::min(length_ - s.length_, pos) + s.length_; 83 StringPiece::const_iterator last =
63 const char* result = std::find_end(ptr_, last, s.ptr_, s.ptr_ + s.length_); 84 self.begin() + std::min(self.size() - s.size(), pos) + s.size();
64 return result != last ? static_cast<size_t>(result - ptr_) : npos; 85 StringPiece::const_iterator result =
86 std::find_end(self.begin(), last, s.begin(), s.end());
87 return result != last ?
88 static_cast<size_t>(result - self.begin()) : StringPiece::npos;
65 } 89 }
66 90
67 size_type StringPiece::rfind(char c, size_type pos) const { 91 StringPiece::size_type rfind(const StringPiece& self,
68 if (length_ == 0) 92 char c,
69 return npos; 93 StringPiece::size_type pos) {
94 if (self.size() == 0)
95 return StringPiece::npos;
70 96
71 for (size_type i = std::min(pos, length_ - 1); ; --i) { 97 for (StringPiece::size_type i = std::min(pos, self.size() - 1); ; --i) {
72 if (ptr_[i] == c) 98 if (self.data()[i] == c)
73 return i; 99 return i;
74 if (i == 0) 100 if (i == 0)
75 break; 101 break;
76 } 102 }
77 return npos; 103 return StringPiece::npos;
78 } 104 }
79 105
80 // For each character in characters_wanted, sets the index corresponding 106 // For each character in characters_wanted, sets the index corresponding
81 // to the ASCII code of that character to 1 in table. This is used by 107 // to the ASCII code of that character to 1 in table. This is used by
82 // the find_.*_of methods below to tell whether or not a character is in 108 // the find_.*_of methods below to tell whether or not a character is in
83 // the lookup table in constant time. 109 // the lookup table in constant time.
84 // The argument `table' must be an array that is large enough to hold all 110 // The argument `table' must be an array that is large enough to hold all
85 // the possible values of an unsigned char. Thus it should be be declared 111 // the possible values of an unsigned char. Thus it should be be declared
86 // as follows: 112 // as follows:
87 // bool table[UCHAR_MAX + 1] 113 // bool table[UCHAR_MAX + 1]
88 static inline void BuildLookupTable(const StringPiece& characters_wanted, 114 static inline void BuildLookupTable(const StringPiece& characters_wanted,
89 bool* table) { 115 bool* table) {
90 const size_type length = characters_wanted.length(); 116 const StringPiece::size_type length = characters_wanted.length();
91 const char* const data = characters_wanted.data(); 117 const char* const data = characters_wanted.data();
92 for (size_type i = 0; i < length; ++i) { 118 for (StringPiece::size_type i = 0; i < length; ++i) {
93 table[static_cast<unsigned char>(data[i])] = true; 119 table[static_cast<unsigned char>(data[i])] = true;
94 } 120 }
95 } 121 }
96 122
97 size_type StringPiece::find_first_of(const StringPiece& s, 123 StringPiece::size_type find_first_of(const StringPiece& self,
98 size_type pos) const { 124 const StringPiece& s,
99 if (length_ == 0 || s.length_ == 0) 125 StringPiece::size_type pos) {
100 return npos; 126 if (self.size() == 0 || s.size() == 0)
127 return StringPiece::npos;
101 128
102 // Avoid the cost of BuildLookupTable() for a single-character search. 129 // Avoid the cost of BuildLookupTable() for a single-character search.
103 if (s.length_ == 1) 130 if (s.size() == 1)
104 return find_first_of(s.ptr_[0], pos); 131 return find(self, s.data()[0], pos);
105 132
106 bool lookup[UCHAR_MAX + 1] = { false }; 133 bool lookup[UCHAR_MAX + 1] = { false };
107 BuildLookupTable(s, lookup); 134 BuildLookupTable(s, lookup);
108 for (size_type i = pos; i < length_; ++i) { 135 for (StringPiece::size_type i = pos; i < self.size(); ++i) {
109 if (lookup[static_cast<unsigned char>(ptr_[i])]) { 136 if (lookup[static_cast<unsigned char>(self.data()[i])]) {
110 return i; 137 return i;
111 } 138 }
112 } 139 }
113 return npos; 140 return StringPiece::npos;
114 } 141 }
115 142
116 size_type StringPiece::find_first_not_of(const StringPiece& s, 143 StringPiece::size_type find_first_not_of(const StringPiece& self,
117 size_type pos) const { 144 const StringPiece& s,
118 if (length_ == 0) 145 StringPiece::size_type pos) {
119 return npos; 146 if (self.size() == 0)
147 return StringPiece::npos;
120 148
121 if (s.length_ == 0) 149 if (s.size() == 0)
122 return 0; 150 return 0;
123 151
124 // Avoid the cost of BuildLookupTable() for a single-character search. 152 // Avoid the cost of BuildLookupTable() for a single-character search.
125 if (s.length_ == 1) 153 if (s.size() == 1)
126 return find_first_not_of(s.ptr_[0], pos); 154 return find_first_not_of(self, s.data()[0], pos);
127 155
128 bool lookup[UCHAR_MAX + 1] = { false }; 156 bool lookup[UCHAR_MAX + 1] = { false };
129 BuildLookupTable(s, lookup); 157 BuildLookupTable(s, lookup);
130 for (size_type i = pos; i < length_; ++i) { 158 for (StringPiece::size_type i = pos; i < self.size(); ++i) {
131 if (!lookup[static_cast<unsigned char>(ptr_[i])]) { 159 if (!lookup[static_cast<unsigned char>(self.data()[i])]) {
132 return i; 160 return i;
133 } 161 }
134 } 162 }
135 return npos; 163 return StringPiece::npos;
136 } 164 }
137 165
138 size_type StringPiece::find_first_not_of(char c, size_type pos) const { 166 StringPiece::size_type find_first_not_of(const StringPiece& self,
139 if (length_ == 0) 167 char c,
140 return npos; 168 StringPiece::size_type pos) {
169 if (self.size() == 0)
170 return StringPiece::npos;
141 171
142 for (; pos < length_; ++pos) { 172 for (; pos < self.size(); ++pos) {
143 if (ptr_[pos] != c) { 173 if (self.data()[pos] != c) {
144 return pos; 174 return pos;
145 } 175 }
146 } 176 }
147 return npos; 177 return StringPiece::npos;
148 } 178 }
149 179
150 size_type StringPiece::find_last_of(const StringPiece& s, size_type pos) const { 180 StringPiece::size_type find_last_of(const StringPiece& self,
151 if (length_ == 0 || s.length_ == 0) 181 const StringPiece& s,
152 return npos; 182 StringPiece::size_type pos) {
183 if (self.size() == 0 || s.size() == 0)
184 return StringPiece::npos;
153 185
154 // Avoid the cost of BuildLookupTable() for a single-character search. 186 // Avoid the cost of BuildLookupTable() for a single-character search.
155 if (s.length_ == 1) 187 if (s.size() == 1)
156 return find_last_of(s.ptr_[0], pos); 188 return rfind(self, s.data()[0], pos);
157 189
158 bool lookup[UCHAR_MAX + 1] = { false }; 190 bool lookup[UCHAR_MAX + 1] = { false };
159 BuildLookupTable(s, lookup); 191 BuildLookupTable(s, lookup);
160 for (size_type i = std::min(pos, length_ - 1); ; --i) { 192 for (StringPiece::size_type i = std::min(pos, self.size() - 1); ; --i) {
161 if (lookup[static_cast<unsigned char>(ptr_[i])]) 193 if (lookup[static_cast<unsigned char>(self.data()[i])])
162 return i; 194 return i;
163 if (i == 0) 195 if (i == 0)
164 break; 196 break;
165 } 197 }
166 return npos; 198 return StringPiece::npos;
167 } 199 }
168 200
169 size_type StringPiece::find_last_not_of(const StringPiece& s, 201 StringPiece::size_type find_last_not_of(const StringPiece& self,
170 size_type pos) const { 202 const StringPiece& s,
171 if (length_ == 0) 203 StringPiece::size_type pos) {
172 return npos; 204 if (self.size() == 0)
205 return StringPiece::npos;
173 206
174 size_type i = std::min(pos, length_ - 1); 207 StringPiece::size_type i = std::min(pos, self.size() - 1);
175 if (s.length_ == 0) 208 if (s.size() == 0)
176 return i; 209 return i;
177 210
178 // Avoid the cost of BuildLookupTable() for a single-character search. 211 // Avoid the cost of BuildLookupTable() for a single-character search.
179 if (s.length_ == 1) 212 if (s.size() == 1)
180 return find_last_not_of(s.ptr_[0], pos); 213 return find_last_not_of(self, s.data()[0], pos);
181 214
182 bool lookup[UCHAR_MAX + 1] = { false }; 215 bool lookup[UCHAR_MAX + 1] = { false };
183 BuildLookupTable(s, lookup); 216 BuildLookupTable(s, lookup);
184 for (; ; --i) { 217 for (; ; --i) {
185 if (!lookup[static_cast<unsigned char>(ptr_[i])]) 218 if (!lookup[static_cast<unsigned char>(self.data()[i])])
186 return i; 219 return i;
187 if (i == 0) 220 if (i == 0)
188 break; 221 break;
189 } 222 }
190 return npos; 223 return StringPiece::npos;
191 } 224 }
192 225
193 size_type StringPiece::find_last_not_of(char c, size_type pos) const { 226 StringPiece::size_type find_last_not_of(const StringPiece& self,
194 if (length_ == 0) 227 char c,
195 return npos; 228 StringPiece::size_type pos) {
229 if (self.size() == 0)
230 return StringPiece::npos;
196 231
197 for (size_type i = std::min(pos, length_ - 1); ; --i) { 232 for (StringPiece::size_type i = std::min(pos, self.size() - 1); ; --i) {
198 if (ptr_[i] != c) 233 if (self.data()[i] != c)
199 return i; 234 return i;
200 if (i == 0) 235 if (i == 0)
201 break; 236 break;
202 } 237 }
203 return npos; 238 return StringPiece::npos;
204 } 239 }
205 240
206 StringPiece StringPiece::substr(size_type pos, size_type n) const { 241 StringPiece substr(const StringPiece& self,
207 if (pos > length_) pos = length_; 242 StringPiece::size_type pos,
208 if (n > length_ - pos) n = length_ - pos; 243 StringPiece::size_type n) {
209 return StringPiece(ptr_ + pos, n); 244 if (pos > self.size()) pos = self.size();
245 if (n > self.size() - pos) n = self.size() - pos;
246 return StringPiece(self.data() + pos, n);
210 } 247 }
211 248
212 const StringPiece::size_type StringPiece::npos = size_type(-1); 249 } // namespace internal
213
214 } // namespace base 250 } // namespace base
OLDNEW
« no previous file with comments | « base/string_piece.h ('k') | base/string_piece_unittest.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698