1 : // Copyright (c) 2006-2008 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 :
18 : #ifndef BASE_STRING_PIECE_H_
19 : #define BASE_STRING_PIECE_H_
20 :
21 : #include <algorithm>
22 : #include <iosfwd>
23 : #include <string>
24 :
25 : #include "base/basictypes.h"
26 :
27 : class StringPiece {
28 : public:
29 : typedef size_t size_type;
30 :
31 : private:
32 : const char* ptr_;
33 : size_type length_;
34 :
35 : public:
36 : // We provide non-explicit singleton constructors so users can pass
37 : // in a "const char*" or a "string" wherever a "StringPiece" is
38 : // expected.
39 : StringPiece() : ptr_(NULL), length_(0) { }
40 0 : StringPiece(const char* str)
41 0 : : ptr_(str), length_((str == NULL) ? 0 : strlen(str)) { }
42 0 : StringPiece(const std::string& str)
43 0 : : ptr_(str.data()), length_(str.size()) { }
44 0 : StringPiece(const char* offset, size_type len)
45 0 : : ptr_(offset), length_(len) { }
46 :
47 : // data() may return a pointer to a buffer with embedded NULs, and the
48 : // returned buffer may or may not be null terminated. Therefore it is
49 : // typically a mistake to pass data() to a routine that expects a NUL
50 : // terminated string.
51 0 : const char* data() const { return ptr_; }
52 0 : size_type size() const { return length_; }
53 0 : size_type length() const { return length_; }
54 0 : bool empty() const { return length_ == 0; }
55 :
56 : void clear() { ptr_ = NULL; length_ = 0; }
57 : void set(const char* data, size_type len) { ptr_ = data; length_ = len; }
58 : void set(const char* str) {
59 : ptr_ = str;
60 : length_ = str ? strlen(str) : 0;
61 : }
62 : void set(const void* data, size_type len) {
63 : ptr_ = reinterpret_cast<const char*>(data);
64 : length_ = len;
65 : }
66 :
67 0 : char operator[](size_type i) const { return ptr_[i]; }
68 :
69 : void remove_prefix(size_type n) {
70 : ptr_ += n;
71 : length_ -= n;
72 : }
73 :
74 : void remove_suffix(size_type n) {
75 : length_ -= n;
76 : }
77 :
78 : int compare(const StringPiece& x) const {
79 : int r = wordmemcmp(ptr_, x.ptr_, std::min(length_, x.length_));
80 : if (r == 0) {
81 : if (length_ < x.length_) r = -1;
82 : else if (length_ > x.length_) r = +1;
83 : }
84 : return r;
85 : }
86 :
87 : std::string as_string() const {
88 : // std::string doesn't like to take a NULL pointer even with a 0 size.
89 : return std::string(!empty() ? data() : "", size());
90 : }
91 :
92 : void CopyToString(std::string* target) const;
93 : void AppendToString(std::string* target) const;
94 :
95 : // Does "this" start with "x"
96 : bool starts_with(const StringPiece& x) const {
97 : return ((length_ >= x.length_) &&
98 : (wordmemcmp(ptr_, x.ptr_, x.length_) == 0));
99 : }
100 :
101 : // Does "this" end with "x"
102 : bool ends_with(const StringPiece& x) const {
103 : return ((length_ >= x.length_) &&
104 : (wordmemcmp(ptr_ + (length_-x.length_), x.ptr_, x.length_) == 0));
105 : }
106 :
107 : // standard STL container boilerplate
108 : typedef char value_type;
109 : typedef const char* pointer;
110 : typedef const char& reference;
111 : typedef const char& const_reference;
112 : typedef ptrdiff_t difference_type;
113 : static const size_type npos;
114 : typedef const char* const_iterator;
115 : typedef const char* iterator;
116 : typedef std::reverse_iterator<const_iterator> const_reverse_iterator;
117 : typedef std::reverse_iterator<iterator> reverse_iterator;
118 : iterator begin() const { return ptr_; }
119 : iterator end() const { return ptr_ + length_; }
120 : const_reverse_iterator rbegin() const {
121 : return const_reverse_iterator(ptr_ + length_);
122 : }
123 : const_reverse_iterator rend() const {
124 : return const_reverse_iterator(ptr_);
125 : }
126 :
127 : size_type max_size() const { return length_; }
128 : size_type capacity() const { return length_; }
129 :
130 : size_type copy(char* buf, size_type n, size_type pos = 0) const;
131 :
132 : size_type find(const StringPiece& s, size_type pos = 0) const;
133 : size_type find(char c, size_type pos = 0) const;
134 : size_type rfind(const StringPiece& s, size_type pos = npos) const;
135 : size_type rfind(char c, size_type pos = npos) const;
136 :
137 : size_type find_first_of(const StringPiece& s, size_type pos = 0) const;
138 0 : size_type find_first_of(char c, size_type pos = 0) const {
139 0 : return find(c, pos);
140 : }
141 : size_type find_first_not_of(const StringPiece& s, size_type pos = 0) const;
142 : size_type find_first_not_of(char c, size_type pos = 0) const;
143 : size_type find_last_of(const StringPiece& s, size_type pos = npos) const;
144 0 : size_type find_last_of(char c, size_type pos = npos) const {
145 0 : return rfind(c, pos);
146 : }
147 : size_type find_last_not_of(const StringPiece& s, size_type pos = npos) const;
148 : size_type find_last_not_of(char c, size_type pos = npos) const;
149 :
150 : StringPiece substr(size_type pos, size_type n = npos) const;
151 :
152 0 : static int wordmemcmp(const char* p, const char* p2, size_type N) {
153 0 : return memcmp(p, p2, N);
154 : }
155 : };
156 :
157 : bool operator==(const StringPiece& x, const StringPiece& y);
158 :
159 : inline bool operator!=(const StringPiece& x, const StringPiece& y) {
160 : return !(x == y);
161 : }
162 :
163 : inline bool operator<(const StringPiece& x, const StringPiece& y) {
164 : const int r = StringPiece::wordmemcmp(x.data(), y.data(),
165 : std::min(x.size(), y.size()));
166 : return ((r < 0) || ((r == 0) && (x.size() < y.size())));
167 : }
168 :
169 : inline bool operator>(const StringPiece& x, const StringPiece& y) {
170 : return y < x;
171 : }
172 :
173 : inline bool operator<=(const StringPiece& x, const StringPiece& y) {
174 : return !(x > y);
175 : }
176 :
177 : inline bool operator>=(const StringPiece& x, const StringPiece& y) {
178 : return !(x < y);
179 : }
180 :
181 : // allow StringPiece to be logged (needed for unit testing).
182 : extern std::ostream& operator<<(std::ostream& o, const StringPiece& piece);
183 :
184 : #endif // BASE_STRING_PIECE_H_
|