blob: ca122129815af0cda8eedf87ca3a85e5915640e0 [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
146 int find(const StringPiece& s, size_type pos = 0) const;
147 int find(char c, size_type pos = 0) const;
148 int rfind(const StringPiece& s, size_type pos = npos) const;
149 int rfind(char c, size_type pos = npos) const;
150
151 StringPiece substr(size_type pos, size_type n = npos) const;
152};
153
154} // namespace art
155
156bool operator==(const art::StringPiece& x, const art::StringPiece& y);
157
158inline bool operator!=(const art::StringPiece& x, const art::StringPiece& y) {
159 return !(x == y);
160}
161
162bool operator<(const art::StringPiece& x, const art::StringPiece& y);
163
164inline bool operator>(const art::StringPiece& x, const art::StringPiece& y) {
165 return y < x;
166}
167
168inline bool operator<=(const art::StringPiece& x, const art::StringPiece& y) {
169 return !(x > y);
170}
171
172inline bool operator>=(const art::StringPiece& x, const art::StringPiece& y) {
173 return !(x < y);
174}
175
176// allow StringPiece to be logged
177extern std::ostream& operator<<(std::ostream& o, const art::StringPiece& piece);
178
179#endif // ART_SRC_STRINGPIECE_H_