blob: 1338ed97ccbd745bfa2dc9e8838b070f77619084 [file] [log] [blame]
Carl Shapirod4e48fd2011-06-30 18:53:29 -07001// Copyright 2010 Google
2// Licensed under the Apache License, Version 2.0 (the "License");
3// you may not use this file except in compliance with the License.
4// You may obtain a copy of the License at
5//
6// http://www.apache.org/licenses/LICENSE-2.0
7//
8// Unless required by applicable law or agreed to in writing, software
9// distributed under the License is distributed on an "AS IS" BASIS,
10// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
11// See the License for the specific language governing permissions and
12// limitations under the License.
13
14// A string-like object that points to a sized piece of memory.
15//
16// Functions or methods may use const StringPiece& parameters to accept either
17// a "const char*" or a "string" value that will be implicitly converted to
18// a StringPiece. The implicit conversion means that it is often appropriate
19// to include this .h file in other files rather than forward-declaring
20// StringPiece as would be appropriate for most other Google classes.
21//
22// Systematic usage of StringPiece is encouraged as it will reduce unnecessary
23// conversions from "const char*" to "string" and back again.
24
25#ifndef ART_SRC_STRINGPIECE_H_
26#define ART_SRC_STRINGPIECE_H_
27
28#include <string.h>
29#include <algorithm>
30#include <iosfwd>
31#include <string>
32
33namespace art {
34
35class StringPiece {
36 private:
37 const char* ptr_;
38 int length_;
39
40 public:
41 // We provide non-explicit singleton constructors so users can pass
42 // in a "const char*" or a "string" wherever a "StringPiece" is
43 // expected.
44 StringPiece() : ptr_(NULL), length_(0) { }
45 StringPiece(const char* str) // NOLINT
46 : ptr_(str), length_((str == NULL) ? 0 : static_cast<int>(strlen(str))) { }
47 StringPiece(const std::string& str) // NOLINT
48 : ptr_(str.data()), length_(static_cast<int>(str.size())) { }
49 StringPiece(const char* offset, int len) : ptr_(offset), length_(len) { }
50
51 // data() may return a pointer to a buffer with embedded NULs, and the
52 // returned buffer may or may not be null terminated. Therefore it is
53 // typically a mistake to pass data() to a routine that expects a NUL
54 // terminated string.
55 const char* data() const { return ptr_; }
56 int size() const { return length_; }
57 int length() const { return length_; }
58 bool empty() const { return length_ == 0; }
59
60 void clear() {
61 ptr_ = NULL;
62 length_ = 0;
63 }
64 void set(const char* data, int len) {
65 ptr_ = data;
66 length_ = len;
67 }
68 void set(const char* str) {
69 ptr_ = str;
70 if (str != NULL)
71 length_ = static_cast<int>(strlen(str));
72 else
73 length_ = 0;
74 }
75 void set(const void* data, int len) {
76 ptr_ = reinterpret_cast<const char*>(data);
77 length_ = len;
78 }
79
80 char operator[](int i) const { return ptr_[i]; }
81
82 void remove_prefix(int n) {
83 ptr_ += n;
84 length_ -= n;
85 }
86
87 void remove_suffix(int n) {
88 length_ -= n;
89 }
90
91 int compare(const StringPiece& x) const;
92
93 std::string as_string() const {
94 return std::string(data(), size());
95 }
96 // We also define ToString() here, since many other string-like
97 // interfaces name the routine that converts to a C++ string
98 // "ToString", and it's confusing to have the method that does that
99 // for a StringPiece be called "as_string()". We also leave the
100 // "as_string()" method defined here for existing code.
101 std::string ToString() const {
102 return std::string(data(), size());
103 }
104
105 void CopyToString(std::string* target) const;
106 void AppendToString(std::string* target) const;
107
108 // Does "this" start with "x"
109 bool starts_with(const StringPiece& x) const {
110 return ((length_ >= x.length_) &&
111 (memcmp(ptr_, x.ptr_, x.length_) == 0));
112 }
113
114 // Does "this" end with "x"
115 bool ends_with(const StringPiece& x) const {
116 return ((length_ >= x.length_) &&
117 (memcmp(ptr_ + (length_-x.length_), x.ptr_, x.length_) == 0));
118 }
119
120 // standard STL container boilerplate
121 typedef char value_type;
122 typedef const char* pointer;
123 typedef const char& reference;
124 typedef const char& const_reference;
125 typedef size_t size_type;
126 typedef ptrdiff_t difference_type;
127 static const size_type npos;
128 typedef const char* const_iterator;
129 typedef const char* iterator;
130 typedef std::reverse_iterator<const_iterator> const_reverse_iterator;
131 typedef std::reverse_iterator<iterator> reverse_iterator;
132 iterator begin() const { return ptr_; }
133 iterator end() const { return ptr_ + length_; }
134 const_reverse_iterator rbegin() const {
135 return const_reverse_iterator(ptr_ + length_);
136 }
137 const_reverse_iterator rend() const {
138 return const_reverse_iterator(ptr_);
139 }
140 // STLS says return size_type, but Google says return int
141 int max_size() const { return length_; }
142 int capacity() const { return length_; }
143
144 int copy(char* buf, size_type n, size_type pos = 0) const;
145
Brian Carlstrom6cc18452011-07-18 15:10:33 -0700146 size_type find(const StringPiece& s, size_type pos = 0) const;
147 size_type find(char c, size_type pos = 0) const;
148 size_type rfind(const StringPiece& s, size_type pos = npos) const;
149 size_type rfind(char c, size_type pos = npos) const;
Carl Shapirod4e48fd2011-06-30 18:53:29 -0700150
151 StringPiece substr(size_type pos, size_type n = npos) const;
152};
153
Carl Shapiro0e5d75d2011-07-06 18:28:37 -0700154// This large function is defined inline so that in a fairly common case where
155// one of the arguments is a literal, the compiler can elide a lot of the
156// following comparisons.
157inline bool operator==(const art::StringPiece& x, const art::StringPiece& y) {
158 int len = x.size();
159 if (len != y.size()) {
160 return false;
161 }
Carl Shapirod4e48fd2011-06-30 18:53:29 -0700162
Carl Shapiro0e5d75d2011-07-06 18:28:37 -0700163 const char* p1 = x.data();
164 const char* p2 = y.data();
165 if (p1 == p2) {
166 return true;
167 }
168 if (len <= 0) {
169 return true;
170 }
171
172 // Test last byte in case strings share large common prefix
173 if (p1[len-1] != p2[len-1]) return false;
174 if (len == 1) return true;
175
176 // At this point we can, but don't have to, ignore the last byte. We use
177 // this observation to fold the odd-length case into the even-length case.
178 len &= ~1;
179
180 return memcmp(p1, p2, len) == 0;
181}
Carl Shapirod4e48fd2011-06-30 18:53:29 -0700182
183inline bool operator!=(const art::StringPiece& x, const art::StringPiece& y) {
184 return !(x == y);
185}
186
187bool operator<(const art::StringPiece& x, const art::StringPiece& y);
188
189inline bool operator>(const art::StringPiece& x, const art::StringPiece& y) {
190 return y < x;
191}
192
193inline bool operator<=(const art::StringPiece& x, const art::StringPiece& y) {
194 return !(x > y);
195}
196
197inline bool operator>=(const art::StringPiece& x, const art::StringPiece& y) {
198 return !(x < y);
199}
200
Carl Shapirod4e48fd2011-06-30 18:53:29 -0700201extern std::ostream& operator<<(std::ostream& o, const art::StringPiece& piece);
202
Brian Carlstroma663ea52011-08-19 23:33:41 -0700203// BEGIN android-added
204struct StringPieceHash {
205 size_t operator()(const art::StringPiece& string_piece) const {
206 size_t string_size = string_piece.size();
207 const char* string_data = string_piece.data();
208 // this is the java.lang.String hashcode for convenience, not interoperability
209 size_t hash = 0;
210 while (string_size--) {
211 hash = hash * 31 + *string_data++;
212 }
213 return hash;
214 }
215};
216// END android-added
217
Elliott Hughes1f359b02011-07-17 14:27:17 -0700218} // namespace art
219
Carl Shapirod4e48fd2011-06-30 18:53:29 -0700220#endif // ART_SRC_STRINGPIECE_H_