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

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: Comment on assymetry. 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 // 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
22
13 typedef StringPiece::size_type size_type; 23 typedef StringPiece::size_type size_type;
14 24
15 bool operator==(const StringPiece& x, const StringPiece& y) { 25 bool operator==(const StringPiece& x, const StringPiece& y) {
16 if (x.size() != y.size()) 26 if (x.size() != y.size())
17 return false; 27 return false;
18 28
19 return StringPiece::wordmemcmp(x.data(), y.data(), x.size()) == 0; 29 return StringPiece::wordmemcmp(x.data(), y.data(), x.size()) == 0;
20 } 30 }
21 31
22 void StringPiece::CopyToString(std::string* target) const { 32 void BasicStringPiece<std::string>::CopyToString(std::string* target) const {
23 target->assign(!empty() ? data() : "", size()); 33 target->assign(!empty() ? data() : "", size());
24 } 34 }
25 35
26 void StringPiece::AppendToString(std::string* target) const { 36 void BasicStringPiece<std::string>::AppendToString(std::string* target) const {
27 if (!empty()) 37 if (!empty())
28 target->append(data(), size()); 38 target->append(data(), size());
29 } 39 }
30 40
31 size_type StringPiece::copy(char* buf, size_type n, size_type pos) const { 41 size_type BasicStringPiece<std::string>::copy(char* buf,
42 size_type n,
43 size_type pos) const {
32 size_type ret = std::min(length_ - pos, n); 44 size_type ret = std::min(length_ - pos, n);
33 memcpy(buf, ptr_ + pos, ret); 45 memcpy(buf, ptr_ + 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 size_type BasicStringPiece<std::string>::find(const BasicStringPiece& s,
50 size_type pos) const {
38 if (pos > length_) 51 if (pos > length_)
39 return npos; 52 return npos;
40 53
41 const char* result = std::search(ptr_ + pos, ptr_ + length_, 54 const char* result = std::search(ptr_ + pos, ptr_ + length_,
42 s.ptr_, s.ptr_ + s.length_); 55 s.ptr_, s.ptr_ + s.length_);
43 const size_type xpos = result - ptr_; 56 const size_type xpos = result - ptr_;
44 return xpos + s.length_ <= length_ ? xpos : npos; 57 return xpos + s.length_ <= length_ ? xpos : npos;
45 } 58 }
46 59
47 size_type StringPiece::find(char c, size_type pos) const { 60 size_type BasicStringPiece<std::string>::find(char c, size_type pos) const {
48 if (pos >= length_) 61 if (pos >= length_)
49 return npos; 62 return npos;
50 63
51 const char* result = std::find(ptr_ + pos, ptr_ + length_, c); 64 const char* result = std::find(ptr_ + pos, ptr_ + length_, c);
52 return result != ptr_ + length_ ? static_cast<size_t>(result - ptr_) : npos; 65 return result != ptr_ + length_ ? static_cast<size_t>(result - ptr_) : npos;
53 } 66 }
54 67
55 size_type StringPiece::rfind(const StringPiece& s, size_type pos) const { 68 size_type BasicStringPiece<std::string>::rfind(const BasicStringPiece& s,
69 size_type pos) const {
56 if (length_ < s.length_) 70 if (length_ < s.length_)
57 return npos; 71 return npos;
58 72
59 if (s.empty()) 73 if (s.empty())
60 return std::min(length_, pos); 74 return std::min(length_, pos);
61 75
62 const char* last = ptr_ + std::min(length_ - s.length_, pos) + s.length_; 76 const char* last = ptr_ + std::min(length_ - s.length_, pos) + s.length_;
63 const char* result = std::find_end(ptr_, last, s.ptr_, s.ptr_ + s.length_); 77 const char* result = std::find_end(ptr_, last, s.ptr_, s.ptr_ + s.length_);
64 return result != last ? static_cast<size_t>(result - ptr_) : npos; 78 return result != last ? static_cast<size_t>(result - ptr_) : npos;
65 } 79 }
66 80
67 size_type StringPiece::rfind(char c, size_type pos) const { 81 size_type BasicStringPiece<std::string>::rfind(char c, size_type pos) const {
68 if (length_ == 0) 82 if (length_ == 0)
69 return npos; 83 return npos;
70 84
71 for (size_type i = std::min(pos, length_ - 1); ; --i) { 85 for (size_type i = std::min(pos, length_ - 1); ; --i) {
72 if (ptr_[i] == c) 86 if (ptr_[i] == c)
73 return i; 87 return i;
74 if (i == 0) 88 if (i == 0)
75 break; 89 break;
76 } 90 }
77 return npos; 91 return npos;
78 } 92 }
79 93
80 // For each character in characters_wanted, sets the index corresponding 94 // 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 95 // 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 96 // the find_.*_of methods below to tell whether or not a character is in
83 // the lookup table in constant time. 97 // the lookup table in constant time.
84 // The argument `table' must be an array that is large enough to hold all 98 // 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 99 // the possible values of an unsigned char. Thus it should be be declared
86 // as follows: 100 // as follows:
87 // bool table[UCHAR_MAX + 1] 101 // bool table[UCHAR_MAX + 1]
88 static inline void BuildLookupTable(const StringPiece& characters_wanted, 102 static inline void BuildLookupTable(const StringPiece& characters_wanted,
89 bool* table) { 103 bool* table) {
90 const size_type length = characters_wanted.length(); 104 const size_type length = characters_wanted.length();
91 const char* const data = characters_wanted.data(); 105 const char* const data = characters_wanted.data();
92 for (size_type i = 0; i < length; ++i) { 106 for (size_type i = 0; i < length; ++i) {
93 table[static_cast<unsigned char>(data[i])] = true; 107 table[static_cast<unsigned char>(data[i])] = true;
94 } 108 }
95 } 109 }
96 110
97 size_type StringPiece::find_first_of(const StringPiece& s, 111 size_type BasicStringPiece<std::string>::find_first_of(
98 size_type pos) const { 112 const BasicStringPiece& s, size_type pos) const {
99 if (length_ == 0 || s.length_ == 0) 113 if (length_ == 0 || s.length_ == 0)
100 return npos; 114 return npos;
101 115
102 // Avoid the cost of BuildLookupTable() for a single-character search. 116 // Avoid the cost of BuildLookupTable() for a single-character search.
103 if (s.length_ == 1) 117 if (s.length_ == 1)
104 return find_first_of(s.ptr_[0], pos); 118 return find_first_of(s.ptr_[0], pos);
105 119
106 bool lookup[UCHAR_MAX + 1] = { false }; 120 bool lookup[UCHAR_MAX + 1] = { false };
107 BuildLookupTable(s, lookup); 121 BuildLookupTable(s, lookup);
108 for (size_type i = pos; i < length_; ++i) { 122 for (size_type i = pos; i < length_; ++i) {
109 if (lookup[static_cast<unsigned char>(ptr_[i])]) { 123 if (lookup[static_cast<unsigned char>(ptr_[i])]) {
110 return i; 124 return i;
111 } 125 }
112 } 126 }
113 return npos; 127 return npos;
114 } 128 }
115 129
116 size_type StringPiece::find_first_not_of(const StringPiece& s, 130 size_type BasicStringPiece<std::string>::find_first_not_of(
117 size_type pos) const { 131 const BasicStringPiece& s, size_type pos) const {
118 if (length_ == 0) 132 if (length_ == 0)
119 return npos; 133 return npos;
120 134
121 if (s.length_ == 0) 135 if (s.length_ == 0)
122 return 0; 136 return 0;
123 137
124 // Avoid the cost of BuildLookupTable() for a single-character search. 138 // Avoid the cost of BuildLookupTable() for a single-character search.
125 if (s.length_ == 1) 139 if (s.length_ == 1)
126 return find_first_not_of(s.ptr_[0], pos); 140 return find_first_not_of(s.ptr_[0], pos);
127 141
128 bool lookup[UCHAR_MAX + 1] = { false }; 142 bool lookup[UCHAR_MAX + 1] = { false };
129 BuildLookupTable(s, lookup); 143 BuildLookupTable(s, lookup);
130 for (size_type i = pos; i < length_; ++i) { 144 for (size_type i = pos; i < length_; ++i) {
131 if (!lookup[static_cast<unsigned char>(ptr_[i])]) { 145 if (!lookup[static_cast<unsigned char>(ptr_[i])]) {
132 return i; 146 return i;
133 } 147 }
134 } 148 }
135 return npos; 149 return npos;
136 } 150 }
137 151
138 size_type StringPiece::find_first_not_of(char c, size_type pos) const { 152 size_type BasicStringPiece<std::string>::find_first_not_of(
153 char c, size_type pos) const {
139 if (length_ == 0) 154 if (length_ == 0)
140 return npos; 155 return npos;
141 156
142 for (; pos < length_; ++pos) { 157 for (; pos < length_; ++pos) {
143 if (ptr_[pos] != c) { 158 if (ptr_[pos] != c) {
144 return pos; 159 return pos;
145 } 160 }
146 } 161 }
147 return npos; 162 return npos;
148 } 163 }
149 164
150 size_type StringPiece::find_last_of(const StringPiece& s, size_type pos) const { 165 size_type BasicStringPiece<std::string>::find_last_of(const StringPiece& s,
166 size_type pos) const {
151 if (length_ == 0 || s.length_ == 0) 167 if (length_ == 0 || s.length_ == 0)
152 return npos; 168 return npos;
153 169
154 // Avoid the cost of BuildLookupTable() for a single-character search. 170 // Avoid the cost of BuildLookupTable() for a single-character search.
155 if (s.length_ == 1) 171 if (s.length_ == 1)
156 return find_last_of(s.ptr_[0], pos); 172 return find_last_of(s.ptr_[0], pos);
157 173
158 bool lookup[UCHAR_MAX + 1] = { false }; 174 bool lookup[UCHAR_MAX + 1] = { false };
159 BuildLookupTable(s, lookup); 175 BuildLookupTable(s, lookup);
160 for (size_type i = std::min(pos, length_ - 1); ; --i) { 176 for (size_type i = std::min(pos, length_ - 1); ; --i) {
161 if (lookup[static_cast<unsigned char>(ptr_[i])]) 177 if (lookup[static_cast<unsigned char>(ptr_[i])])
162 return i; 178 return i;
163 if (i == 0) 179 if (i == 0)
164 break; 180 break;
165 } 181 }
166 return npos; 182 return npos;
167 } 183 }
168 184
169 size_type StringPiece::find_last_not_of(const StringPiece& s, 185 size_type BasicStringPiece<std::string>::find_last_not_of(
170 size_type pos) const { 186 const BasicStringPiece& s, size_type pos) const {
171 if (length_ == 0) 187 if (length_ == 0)
172 return npos; 188 return npos;
173 189
174 size_type i = std::min(pos, length_ - 1); 190 size_type i = std::min(pos, length_ - 1);
175 if (s.length_ == 0) 191 if (s.length_ == 0)
176 return i; 192 return i;
177 193
178 // Avoid the cost of BuildLookupTable() for a single-character search. 194 // Avoid the cost of BuildLookupTable() for a single-character search.
179 if (s.length_ == 1) 195 if (s.length_ == 1)
180 return find_last_not_of(s.ptr_[0], pos); 196 return find_last_not_of(s.ptr_[0], pos);
181 197
182 bool lookup[UCHAR_MAX + 1] = { false }; 198 bool lookup[UCHAR_MAX + 1] = { false };
183 BuildLookupTable(s, lookup); 199 BuildLookupTable(s, lookup);
184 for (; ; --i) { 200 for (; ; --i) {
185 if (!lookup[static_cast<unsigned char>(ptr_[i])]) 201 if (!lookup[static_cast<unsigned char>(ptr_[i])])
186 return i; 202 return i;
187 if (i == 0) 203 if (i == 0)
188 break; 204 break;
189 } 205 }
190 return npos; 206 return npos;
191 } 207 }
192 208
193 size_type StringPiece::find_last_not_of(char c, size_type pos) const { 209 size_type BasicStringPiece<std::string>::find_last_not_of(char c,
210 size_type pos) const {
194 if (length_ == 0) 211 if (length_ == 0)
195 return npos; 212 return npos;
196 213
197 for (size_type i = std::min(pos, length_ - 1); ; --i) { 214 for (size_type i = std::min(pos, length_ - 1); ; --i) {
198 if (ptr_[i] != c) 215 if (ptr_[i] != c)
199 return i; 216 return i;
200 if (i == 0) 217 if (i == 0)
201 break; 218 break;
202 } 219 }
203 return npos; 220 return npos;
204 } 221 }
205 222
206 StringPiece StringPiece::substr(size_type pos, size_type n) const { 223 BasicStringPiece<std::string> BasicStringPiece<std::string>::substr(
224 size_type pos, size_type n) const {
207 if (pos > length_) pos = length_; 225 if (pos > length_) pos = length_;
208 if (n > length_ - pos) n = length_ - pos; 226 if (n > length_ - pos) n = length_ - pos;
209 return StringPiece(ptr_ + pos, n); 227 return StringPiece(ptr_ + pos, n);
210 } 228 }
211 229
212 const StringPiece::size_type StringPiece::npos = size_type(-1);
213
214 } // namespace base 230 } // 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