Initialize Tizen 2.3
[external/chromium.git] / base / string_piece.h
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
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 //
22
23 #ifndef BASE_STRING_PIECE_H_
24 #define BASE_STRING_PIECE_H_
25 #pragma once
26
27 #include <string>
28
29 #include "base/base_export.h"
30 #include "base/basictypes.h"
31 #include "base/hash_tables.h"
32 #include "base/string16.h"
33
34 namespace base {
35
36 class BASE_EXPORT StringPiece {
37  public:
38   // standard STL container boilerplate
39   typedef size_t size_type;
40   typedef char value_type;
41   typedef const char* pointer;
42   typedef const char& reference;
43   typedef const char& const_reference;
44   typedef ptrdiff_t difference_type;
45   typedef const char* const_iterator;
46   typedef const char* iterator;
47   typedef std::reverse_iterator<const_iterator> const_reverse_iterator;
48   typedef std::reverse_iterator<iterator> reverse_iterator;
49
50   static const size_type npos;
51
52  public:
53   // We provide non-explicit singleton constructors so users can pass
54   // in a "const char*" or a "string" wherever a "StringPiece" is
55   // expected.
56   StringPiece() : ptr_(NULL), length_(0) { }
57   StringPiece(const char* str)
58     : ptr_(str), length_((str == NULL) ? 0 : strlen(str)) { }
59   StringPiece(const std::string& str)
60     : ptr_(str.data()), length_(str.size()) { }
61   StringPiece(const char* offset, size_type len)
62     : ptr_(offset), length_(len) { }
63
64   // data() may return a pointer to a buffer with embedded NULs, and the
65   // returned buffer may or may not be null terminated.  Therefore it is
66   // typically a mistake to pass data() to a routine that expects a NUL
67   // terminated string.
68   const char* data() const { return ptr_; }
69   size_type size() const { return length_; }
70   size_type length() const { return length_; }
71   bool empty() const { return length_ == 0; }
72
73   void clear() {
74     ptr_ = NULL;
75     length_ = 0;
76   }
77   void set(const char* data, size_type len) {
78     ptr_ = data;
79     length_ = len;
80   }
81   void set(const char* str) {
82     ptr_ = str;
83     length_ = str ? strlen(str) : 0;
84   }
85   void set(const void* data, size_type len) {
86     ptr_ = reinterpret_cast<const char*>(data);
87     length_ = len;
88   }
89
90   char operator[](size_type i) const { return ptr_[i]; }
91
92   void remove_prefix(size_type n) {
93     ptr_ += n;
94     length_ -= n;
95   }
96
97   void remove_suffix(size_type n) {
98     length_ -= n;
99   }
100
101   int compare(const StringPiece& x) const {
102     int r = wordmemcmp(
103         ptr_, x.ptr_, (length_ < x.length_ ? length_ : x.length_));
104     if (r == 0) {
105       if (length_ < x.length_) r = -1;
106       else if (length_ > x.length_) r = +1;
107     }
108     return r;
109   }
110
111   std::string as_string() const {
112     // std::string doesn't like to take a NULL pointer even with a 0 size.
113     return std::string(!empty() ? data() : "", size());
114   }
115
116   void CopyToString(std::string* target) const;
117   void AppendToString(std::string* target) const;
118
119   // Does "this" start with "x"
120   bool starts_with(const StringPiece& x) const {
121     return ((length_ >= x.length_) &&
122             (wordmemcmp(ptr_, x.ptr_, x.length_) == 0));
123   }
124
125   // Does "this" end with "x"
126   bool ends_with(const StringPiece& x) const {
127     return ((length_ >= x.length_) &&
128             (wordmemcmp(ptr_ + (length_-x.length_), x.ptr_, x.length_) == 0));
129   }
130
131   iterator begin() const { return ptr_; }
132   iterator end() const { return ptr_ + length_; }
133   const_reverse_iterator rbegin() const {
134     return const_reverse_iterator(ptr_ + length_);
135   }
136   const_reverse_iterator rend() const {
137     return const_reverse_iterator(ptr_);
138   }
139
140   size_type max_size() const { return length_; }
141   size_type capacity() const { return length_; }
142
143   size_type copy(char* buf, size_type n, size_type pos = 0) const;
144
145   size_type find(const StringPiece& s, size_type pos = 0) const;
146   size_type find(char c, size_type pos = 0) const;
147   size_type rfind(const StringPiece& s, size_type pos = npos) const;
148   size_type rfind(char c, size_type pos = npos) const;
149
150   size_type find_first_of(const StringPiece& s, size_type pos = 0) const;
151   size_type find_first_of(char c, size_type pos = 0) const {
152     return find(c, pos);
153   }
154   size_type find_first_not_of(const StringPiece& s, size_type pos = 0) const;
155   size_type find_first_not_of(char c, size_type pos = 0) const;
156   size_type find_last_of(const StringPiece& s, size_type pos = npos) const;
157   size_type find_last_of(char c, size_type pos = npos) const {
158     return rfind(c, pos);
159   }
160   size_type find_last_not_of(const StringPiece& s, size_type pos = npos) const;
161   size_type find_last_not_of(char c, size_type pos = npos) const;
162
163   StringPiece substr(size_type pos, size_type n = npos) const;
164
165   static int wordmemcmp(const char* p, const char* p2, size_type N) {
166     return memcmp(p, p2, N);
167   }
168
169  private:
170   const char*   ptr_;
171   size_type     length_;
172 };
173
174 class BASE_EXPORT StringPiece16 {
175  public:
176   // standard STL container boilerplate
177   typedef size_t size_type;
178   typedef char16 value_type;
179   typedef const char16* pointer;
180   typedef const char16& reference;
181   typedef const char16& const_reference;
182   typedef ptrdiff_t difference_type;
183   typedef const char16* const_iterator;
184   typedef const char16* iterator;
185   typedef std::reverse_iterator<const_iterator> const_reverse_iterator;
186   typedef std::reverse_iterator<iterator> reverse_iterator;
187
188  public:
189   // We provide non-explicit singleton constructors so users can pass
190   // in a "const char16*" or a "string16" wherever a "StringPiece16" is
191   // expected.
192   StringPiece16() : ptr_(NULL), length_(0) { }
193   StringPiece16(const char16* str)
194       : ptr_(str),
195         length_((str == NULL) ? 0 : string16::traits_type::length(str)) { }
196   StringPiece16(const string16& str)
197       : ptr_(str.data()), length_(str.size()) { }
198   StringPiece16(const char16* offset, size_type len)
199       : ptr_(offset), length_(len) { }
200
201   // data() may return a pointer to a buffer with embedded NULs, and the
202   // returned buffer may or may not be null terminated.  Therefore it is
203   // typically a mistake to pass data() to a routine that expects a NUL
204   // terminated string.
205   const char16* data() const { return ptr_; }
206   size_type size() const { return length_; }
207   size_type length() const { return length_; }
208   bool empty() const { return length_ == 0; }
209
210   void clear() {
211     ptr_ = NULL;
212     length_ = 0;
213   }
214   void set(const char16* data, size_type len) {
215     ptr_ = data;
216     length_ = len;
217   }
218   void set(const char16* str) {
219     ptr_ = str;
220     length_ = str ? string16::traits_type::length(str) : 0;
221   }
222
223   char16 operator[](size_type i) const { return ptr_[i]; }
224
225   string16 as_string16() const {
226     // StringPiece claims that this is bad when data() is NULL, but unittesting
227     // seems to say otherwise.
228     return string16(data(), size());
229   }
230
231   iterator begin() const { return ptr_; }
232   iterator end() const { return ptr_ + length_; }
233   const_reverse_iterator rbegin() const {
234     return const_reverse_iterator(ptr_ + length_);
235   }
236   const_reverse_iterator rend() const {
237     return const_reverse_iterator(ptr_);
238   }
239
240   size_type max_size() const { return length_; }
241   size_type capacity() const { return length_; }
242
243   static int wordmemcmp(const char16* p, const char16* p2, size_type N) {
244     return string16::traits_type::compare(p, p2, N);
245   }
246
247  private:
248   const char16*   ptr_;
249   size_type       length_;
250 };
251
252 BASE_EXPORT bool operator==(const StringPiece& x, const StringPiece& y);
253
254 inline bool operator!=(const StringPiece& x, const StringPiece& y) {
255   return !(x == y);
256 }
257
258 inline bool operator<(const StringPiece& x, const StringPiece& y) {
259   const int r = StringPiece::wordmemcmp(
260       x.data(), y.data(), (x.size() < y.size() ? x.size() : y.size()));
261   return ((r < 0) || ((r == 0) && (x.size() < y.size())));
262 }
263
264 inline bool operator>(const StringPiece& x, const StringPiece& y) {
265   return y < x;
266 }
267
268 inline bool operator<=(const StringPiece& x, const StringPiece& y) {
269   return !(x > y);
270 }
271
272 inline bool operator>=(const StringPiece& x, const StringPiece& y) {
273   return !(x < y);
274 }
275
276 inline bool operator==(const StringPiece16& x, const StringPiece16& y) {
277   if (x.size() != y.size())
278     return false;
279
280   return StringPiece16::wordmemcmp(x.data(), y.data(), x.size()) == 0;
281 }
282
283 inline bool operator!=(const StringPiece16& x, const StringPiece16& y) {
284   return !(x == y);
285 }
286
287 inline bool operator<(const StringPiece16& x, const StringPiece16& y) {
288   const int r = StringPiece16::wordmemcmp(
289       x.data(), y.data(), (x.size() < y.size() ? x.size() : y.size()));
290   return ((r < 0) || ((r == 0) && (x.size() < y.size())));
291 }
292
293 inline bool operator>(const StringPiece16& x, const StringPiece16& y) {
294   return y < x;
295 }
296
297 inline bool operator<=(const StringPiece16& x, const StringPiece16& y) {
298   return !(x > y);
299 }
300
301 inline bool operator>=(const StringPiece16& x, const StringPiece16& y) {
302   return !(x < y);
303 }
304
305 }  // namespace base
306
307 // We provide appropriate hash functions so StringPiece and StringPiece16 can
308 // be used as keys in hash sets and maps.
309
310 // This hash function is copied from base/hash_tables.h. We don't use the
311 // ones already defined for string and string16 directly because it would
312 // require the string constructors to be called, which we don't want.
313 #define HASH_STRING_PIECE(StringPieceType, string_piece)                \
314   std::size_t result = 0;                                               \
315   for (StringPieceType::const_iterator i = string_piece.begin();        \
316        i != string_piece.end(); ++i)                                    \
317     result = (result * 131) + *i;                                       \
318   return result;                                                        \
319
320 namespace BASE_HASH_NAMESPACE {
321 #if defined(COMPILER_GCC)
322
323 template<>
324 struct hash<base::StringPiece> {
325   std::size_t operator()(const base::StringPiece& sp) const {
326     HASH_STRING_PIECE(base::StringPiece, sp);
327   }
328 };
329 template<>
330 struct hash<base::StringPiece16> {
331   std::size_t operator()(const base::StringPiece16& sp16) const {
332     HASH_STRING_PIECE(base::StringPiece16, sp16);
333   }
334 };
335
336 #elif defined(COMPILER_MSVC)
337
338 inline size_t hash_value(const base::StringPiece& sp) {
339   HASH_STRING_PIECE(base::StringPiece, sp);
340 }
341 inline size_t hash_value(const base::StringPiece16& sp16) {
342   HASH_STRING_PIECE(base::StringPiece16, sp16);
343 }
344
345 #endif  // COMPILER
346
347 }  // namespace BASE_HASH_NAMESPACE
348
349 #endif  // BASE_STRING_PIECE_H_