OLD | NEW |
| (Empty) |
1 // Copyright 2001-2010 The RE2 Authors. All Rights Reserved. | |
2 // Use of this source code is governed by a BSD-style | |
3 // license that can be found in the LICENSE file. | |
4 | |
5 // A string-like object that points to a sized piece of memory. | |
6 // | |
7 // Functions or methods may use const StringPiece& parameters to accept either | |
8 // a "const char*" or a "string" value that will be implicitly converted to | |
9 // a StringPiece. The implicit conversion means that it is often appropriate | |
10 // to include this .h file in other files rather than forward-declaring | |
11 // StringPiece as would be appropriate for most other Google classes. | |
12 // | |
13 // Systematic usage of StringPiece is encouraged as it will reduce unnecessary | |
14 // conversions from "const char*" to "string" and back again. | |
15 // | |
16 // | |
17 // Arghh! I wish C++ literals were "string". | |
18 | |
19 #ifndef STRINGS_STRINGPIECE_H__ | |
20 #define STRINGS_STRINGPIECE_H__ | |
21 | |
22 #include <string.h> | |
23 #include <algorithm> | |
24 #include <cstddef> | |
25 #include <iosfwd> | |
26 #include <string> | |
27 | |
28 namespace re2 { | |
29 | |
30 class StringPiece { | |
31 private: | |
32 const char* ptr_; | |
33 int 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 StringPiece(const char* str) | |
41 : ptr_(str), length_((str == NULL) ? 0 : static_cast<int>(strlen(str))) { } | |
42 StringPiece(const std::string& str) | |
43 : ptr_(str.data()), length_(static_cast<int>(str.size())) { } | |
44 StringPiece(const char* offset, int len) : ptr_(offset), length_(len) { } | |
45 | |
46 // data() may return a pointer to a buffer with embedded NULs, and the | |
47 // returned buffer may or may not be null terminated. Therefore it is | |
48 // typically a mistake to pass data() to a routine that expects a NUL | |
49 // terminated string. | |
50 const char* data() const { return ptr_; } | |
51 int size() const { return length_; } | |
52 int length() const { return length_; } | |
53 bool empty() const { return length_ == 0; } | |
54 | |
55 void clear() { ptr_ = NULL; length_ = 0; } | |
56 void set(const char* data, int len) { ptr_ = data; length_ = len; } | |
57 void set(const char* str) { | |
58 ptr_ = str; | |
59 if (str != NULL) | |
60 length_ = static_cast<int>(strlen(str)); | |
61 else | |
62 length_ = 0; | |
63 } | |
64 void set(const void* data, int len) { | |
65 ptr_ = reinterpret_cast<const char*>(data); | |
66 length_ = len; | |
67 } | |
68 | |
69 char operator[](int i) const { return ptr_[i]; } | |
70 | |
71 void remove_prefix(int n) { | |
72 ptr_ += n; | |
73 length_ -= n; | |
74 } | |
75 | |
76 void remove_suffix(int n) { | |
77 length_ -= n; | |
78 } | |
79 | |
80 int compare(const StringPiece& x) const { | |
81 int r = memcmp(ptr_, x.ptr_, std::min(length_, x.length_)); | |
82 if (r == 0) { | |
83 if (length_ < x.length_) r = -1; | |
84 else if (length_ > x.length_) r = +1; | |
85 } | |
86 return r; | |
87 } | |
88 | |
89 std::string as_string() const { | |
90 return std::string(data(), size()); | |
91 } | |
92 // We also define ToString() here, since many other string-like | |
93 // interfaces name the routine that converts to a C++ string | |
94 // "ToString", and it's confusing to have the method that does that | |
95 // for a StringPiece be called "as_string()". We also leave the | |
96 // "as_string()" method defined here for existing code. | |
97 std::string ToString() const { | |
98 return std::string(data(), size()); | |
99 } | |
100 | |
101 void CopyToString(std::string* target) const; | |
102 void AppendToString(std::string* target) const; | |
103 | |
104 // Does "this" start with "x" | |
105 bool starts_with(const StringPiece& x) const { | |
106 return ((length_ >= x.length_) && | |
107 (memcmp(ptr_, x.ptr_, x.length_) == 0)); | |
108 } | |
109 | |
110 // Does "this" end with "x" | |
111 bool ends_with(const StringPiece& x) const { | |
112 return ((length_ >= x.length_) && | |
113 (memcmp(ptr_ + (length_-x.length_), x.ptr_, x.length_) == 0)); | |
114 } | |
115 | |
116 // standard STL container boilerplate | |
117 typedef char value_type; | |
118 typedef const char* pointer; | |
119 typedef const char& reference; | |
120 typedef const char& const_reference; | |
121 typedef size_t size_type; | |
122 typedef ptrdiff_t difference_type; | |
123 static const size_type npos; | |
124 typedef const char* const_iterator; | |
125 typedef const char* iterator; | |
126 typedef std::reverse_iterator<const_iterator> const_reverse_iterator; | |
127 typedef std::reverse_iterator<iterator> reverse_iterator; | |
128 iterator begin() const { return ptr_; } | |
129 iterator end() const { return ptr_ + length_; } | |
130 const_reverse_iterator rbegin() const { | |
131 return const_reverse_iterator(ptr_ + length_); | |
132 } | |
133 const_reverse_iterator rend() const { | |
134 return const_reverse_iterator(ptr_); | |
135 } | |
136 // STLS says return size_type, but Google says return int | |
137 int max_size() const { return length_; } | |
138 int capacity() const { return length_; } | |
139 | |
140 size_type copy(char* buf, size_type n, size_type pos = 0) const; | |
141 | |
142 bool contains(StringPiece s) const; | |
143 | |
144 size_type find(const StringPiece& s, size_type pos = 0) const; | |
145 size_type find(char c, size_type pos = 0) const; | |
146 size_type rfind(const StringPiece& s, size_type pos = npos) const; | |
147 size_type rfind(char c, size_type pos = npos) const; | |
148 | |
149 StringPiece substr(size_type pos, size_type n = npos) const; | |
150 | |
151 static bool _equal(const StringPiece&, const StringPiece&); | |
152 }; | |
153 | |
154 inline bool operator==(const StringPiece& x, const StringPiece& y) { | |
155 return StringPiece::_equal(x, y); | |
156 } | |
157 | |
158 inline bool operator!=(const StringPiece& x, const StringPiece& y) { | |
159 return !(x == y); | |
160 } | |
161 | |
162 inline bool operator<(const StringPiece& x, const StringPiece& y) { | |
163 const int r = memcmp(x.data(), y.data(), | |
164 std::min(x.size(), y.size())); | |
165 return ((r < 0) || ((r == 0) && (x.size() < y.size()))); | |
166 } | |
167 | |
168 inline bool operator>(const StringPiece& x, const StringPiece& y) { | |
169 return y < x; | |
170 } | |
171 | |
172 inline bool operator<=(const StringPiece& x, const StringPiece& y) { | |
173 return !(x > y); | |
174 } | |
175 | |
176 inline bool operator>=(const StringPiece& x, const StringPiece& y) { | |
177 return !(x < y); | |
178 } | |
179 | |
180 } // namespace re2 | |
181 | |
182 // allow StringPiece to be logged | |
183 extern std::ostream& operator<<(std::ostream& o, const re2::StringPiece& piece); | |
184 | |
185 #endif // STRINGS_STRINGPIECE_H__ | |
OLD | NEW |