blob: f91bccc93019ea4415b41443304d7285e6620fed [file] [log] [blame]
Adam Lesinski6f6ceb72014-11-14 14:48:12 -08001/*
2 * Copyright (C) 2015 The Android Open Source Project
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 * http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 */
16
17#ifndef AAPT_STRING_PIECE_H
18#define AAPT_STRING_PIECE_H
19
20#include <ostream>
21#include <string>
22#include <utils/String8.h>
23#include <utils/Unicode.h>
24
25namespace aapt {
26
27/**
28 * Read only wrapper around basic C strings.
29 * Prevents excessive copying.
30 *
31 * WARNING: When creating from std::basic_string<>, moving the original
32 * std::basic_string<> will invalidate the data held in a BasicStringPiece<>.
33 * BasicStringPiece<> should only be used transitively.
34 */
35template <typename TChar>
36class BasicStringPiece {
37public:
38 using const_iterator = const TChar*;
Adam Lesinskica5638f2015-10-21 14:42:43 -070039 using difference_type = size_t;
Adam Lesinski6f6ceb72014-11-14 14:48:12 -080040
41 BasicStringPiece();
42 BasicStringPiece(const BasicStringPiece<TChar>& str);
43 BasicStringPiece(const std::basic_string<TChar>& str);
44 BasicStringPiece(const TChar* str);
45 BasicStringPiece(const TChar* str, size_t len);
46
47 BasicStringPiece<TChar>& operator=(const BasicStringPiece<TChar>& rhs);
48 BasicStringPiece<TChar>& assign(const TChar* str, size_t len);
49
50 BasicStringPiece<TChar> substr(size_t start, size_t len) const;
51 BasicStringPiece<TChar> substr(BasicStringPiece<TChar>::const_iterator begin,
52 BasicStringPiece<TChar>::const_iterator end) const;
53
54 const TChar* data() const;
55 size_t length() const;
56 size_t size() const;
57 bool empty() const;
58 std::basic_string<TChar> toString() const;
59
Michael Wrightfeaf99f2016-05-06 17:16:06 +010060 bool contains(const BasicStringPiece<TChar>& rhs) const;
Adam Lesinski6f6ceb72014-11-14 14:48:12 -080061 int compare(const BasicStringPiece<TChar>& rhs) const;
62 bool operator<(const BasicStringPiece<TChar>& rhs) const;
63 bool operator>(const BasicStringPiece<TChar>& rhs) const;
64 bool operator==(const BasicStringPiece<TChar>& rhs) const;
65 bool operator!=(const BasicStringPiece<TChar>& rhs) const;
66
67 const_iterator begin() const;
68 const_iterator end() const;
69
70private:
71 const TChar* mData;
72 size_t mLength;
73};
74
75using StringPiece = BasicStringPiece<char>;
76using StringPiece16 = BasicStringPiece<char16_t>;
77
78//
79// BasicStringPiece implementation.
80//
81
82template <typename TChar>
83inline BasicStringPiece<TChar>::BasicStringPiece() : mData(nullptr) , mLength(0) {
84}
85
86template <typename TChar>
87inline BasicStringPiece<TChar>::BasicStringPiece(const BasicStringPiece<TChar>& str) :
88 mData(str.mData), mLength(str.mLength) {
89}
90
91template <typename TChar>
92inline BasicStringPiece<TChar>::BasicStringPiece(const std::basic_string<TChar>& str) :
93 mData(str.data()), mLength(str.length()) {
94}
95
96template <>
97inline BasicStringPiece<char>::BasicStringPiece(const char* str) :
98 mData(str), mLength(str != nullptr ? strlen(str) : 0) {
99}
100
101template <>
102inline BasicStringPiece<char16_t>::BasicStringPiece(const char16_t* str) :
103 mData(str), mLength(str != nullptr ? strlen16(str) : 0) {
104}
105
106template <typename TChar>
107inline BasicStringPiece<TChar>::BasicStringPiece(const TChar* str, size_t len) :
108 mData(str), mLength(len) {
109}
110
111template <typename TChar>
112inline BasicStringPiece<TChar>& BasicStringPiece<TChar>::operator=(
113 const BasicStringPiece<TChar>& rhs) {
114 mData = rhs.mData;
115 mLength = rhs.mLength;
116 return *this;
117}
118
119template <typename TChar>
120inline BasicStringPiece<TChar>& BasicStringPiece<TChar>::assign(const TChar* str, size_t len) {
121 mData = str;
122 mLength = len;
123 return *this;
124}
125
126
127template <typename TChar>
128inline BasicStringPiece<TChar> BasicStringPiece<TChar>::substr(size_t start, size_t len) const {
129 if (start + len > mLength) {
130 return BasicStringPiece<TChar>();
131 }
132 return BasicStringPiece<TChar>(mData + start, len);
133}
134
135template <typename TChar>
136inline BasicStringPiece<TChar> BasicStringPiece<TChar>::substr(
137 BasicStringPiece<TChar>::const_iterator begin,
138 BasicStringPiece<TChar>::const_iterator end) const {
139 return BasicStringPiece<TChar>(begin, end - begin);
140}
141
142template <typename TChar>
143inline const TChar* BasicStringPiece<TChar>::data() const {
144 return mData;
145}
146
147template <typename TChar>
148inline size_t BasicStringPiece<TChar>::length() const {
149 return mLength;
150}
151
152template <typename TChar>
153inline size_t BasicStringPiece<TChar>::size() const {
154 return mLength;
155}
156
157template <typename TChar>
158inline bool BasicStringPiece<TChar>::empty() const {
159 return mLength == 0;
160}
161
162template <typename TChar>
163inline std::basic_string<TChar> BasicStringPiece<TChar>::toString() const {
164 return std::basic_string<TChar>(mData, mLength);
165}
166
167template <>
Michael Wrightfeaf99f2016-05-06 17:16:06 +0100168inline bool BasicStringPiece<char>::contains(const BasicStringPiece<char>& rhs) const {
169 if (!mData || !rhs.mData) {
170 return false;
171 }
172 if (rhs.mLength > mLength) {
173 return false;
174 }
175 return strstr(mData, rhs.mData) != nullptr;
176}
177
178template <>
Adam Lesinski6f6ceb72014-11-14 14:48:12 -0800179inline int BasicStringPiece<char>::compare(const BasicStringPiece<char>& rhs) const {
180 const char nullStr = '\0';
181 const char* b1 = mData != nullptr ? mData : &nullStr;
182 const char* e1 = b1 + mLength;
183 const char* b2 = rhs.mData != nullptr ? rhs.mData : &nullStr;
184 const char* e2 = b2 + rhs.mLength;
185
186 while (b1 < e1 && b2 < e2) {
187 const int d = static_cast<int>(*b1++) - static_cast<int>(*b2++);
188 if (d) {
189 return d;
190 }
191 }
192 return static_cast<int>(mLength - rhs.mLength);
193}
194
195inline ::std::ostream& operator<<(::std::ostream& out, const BasicStringPiece<char16_t>& str) {
196 android::String8 utf8(str.data(), str.size());
197 return out.write(utf8.string(), utf8.size());
198}
199
Michael Wrightfeaf99f2016-05-06 17:16:06 +0100200template <>
201inline bool BasicStringPiece<char16_t>::contains(const BasicStringPiece<char16_t>& rhs) const {
202 if (!mData || !rhs.mData) {
203 return false;
204 }
205 if (rhs.mLength > mLength) {
206 return false;
207 }
208 return strstr16(mData, rhs.mData) != nullptr;
209}
Adam Lesinski6f6ceb72014-11-14 14:48:12 -0800210
211template <>
212inline int BasicStringPiece<char16_t>::compare(const BasicStringPiece<char16_t>& rhs) const {
213 const char16_t nullStr = u'\0';
214 const char16_t* b1 = mData != nullptr ? mData : &nullStr;
215 const char16_t* b2 = rhs.mData != nullptr ? rhs.mData : &nullStr;
216 return strzcmp16(b1, mLength, b2, rhs.mLength);
217}
218
219template <typename TChar>
220inline bool BasicStringPiece<TChar>::operator<(const BasicStringPiece<TChar>& rhs) const {
221 return compare(rhs) < 0;
222}
223
224template <typename TChar>
225inline bool BasicStringPiece<TChar>::operator>(const BasicStringPiece<TChar>& rhs) const {
226 return compare(rhs) > 0;
227}
228
229template <typename TChar>
230inline bool BasicStringPiece<TChar>::operator==(const BasicStringPiece<TChar>& rhs) const {
231 return compare(rhs) == 0;
232}
233
234template <typename TChar>
235inline bool BasicStringPiece<TChar>::operator!=(const BasicStringPiece<TChar>& rhs) const {
236 return compare(rhs) != 0;
237}
238
239template <typename TChar>
240inline typename BasicStringPiece<TChar>::const_iterator BasicStringPiece<TChar>::begin() const {
241 return mData;
242}
243
244template <typename TChar>
245inline typename BasicStringPiece<TChar>::const_iterator BasicStringPiece<TChar>::end() const {
246 return mData + mLength;
247}
248
249inline ::std::ostream& operator<<(::std::ostream& out, const BasicStringPiece<char>& str) {
250 return out.write(str.data(), str.size());
251}
252
253} // namespace aapt
254
Adam Lesinski90959882015-07-06 18:09:18 -0700255inline ::std::ostream& operator<<(::std::ostream& out, const std::u16string& str) {
256 android::String8 utf8(str.data(), str.size());
257 return out.write(utf8.string(), utf8.size());
258}
259
Adam Lesinski6f6ceb72014-11-14 14:48:12 -0800260#endif // AAPT_STRING_PIECE_H