blob: 31deb452b53c4a8750803de883935b63fa898023 [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
60 int compare(const BasicStringPiece<TChar>& rhs) const;
61 bool operator<(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
66 const_iterator begin() const;
67 const_iterator end() const;
68
69private:
70 const TChar* mData;
71 size_t mLength;
72};
73
74using StringPiece = BasicStringPiece<char>;
75using StringPiece16 = BasicStringPiece<char16_t>;
76
77//
78// BasicStringPiece implementation.
79//
80
81template <typename TChar>
82inline BasicStringPiece<TChar>::BasicStringPiece() : mData(nullptr) , mLength(0) {
83}
84
85template <typename TChar>
86inline BasicStringPiece<TChar>::BasicStringPiece(const BasicStringPiece<TChar>& str) :
87 mData(str.mData), mLength(str.mLength) {
88}
89
90template <typename TChar>
91inline BasicStringPiece<TChar>::BasicStringPiece(const std::basic_string<TChar>& str) :
92 mData(str.data()), mLength(str.length()) {
93}
94
95template <>
96inline BasicStringPiece<char>::BasicStringPiece(const char* str) :
97 mData(str), mLength(str != nullptr ? strlen(str) : 0) {
98}
99
100template <>
101inline BasicStringPiece<char16_t>::BasicStringPiece(const char16_t* str) :
102 mData(str), mLength(str != nullptr ? strlen16(str) : 0) {
103}
104
105template <typename TChar>
106inline BasicStringPiece<TChar>::BasicStringPiece(const TChar* str, size_t len) :
107 mData(str), mLength(len) {
108}
109
110template <typename TChar>
111inline BasicStringPiece<TChar>& BasicStringPiece<TChar>::operator=(
112 const BasicStringPiece<TChar>& rhs) {
113 mData = rhs.mData;
114 mLength = rhs.mLength;
115 return *this;
116}
117
118template <typename TChar>
119inline BasicStringPiece<TChar>& BasicStringPiece<TChar>::assign(const TChar* str, size_t len) {
120 mData = str;
121 mLength = len;
122 return *this;
123}
124
125
126template <typename TChar>
127inline BasicStringPiece<TChar> BasicStringPiece<TChar>::substr(size_t start, size_t len) const {
128 if (start + len > mLength) {
129 return BasicStringPiece<TChar>();
130 }
131 return BasicStringPiece<TChar>(mData + start, len);
132}
133
134template <typename TChar>
135inline BasicStringPiece<TChar> BasicStringPiece<TChar>::substr(
136 BasicStringPiece<TChar>::const_iterator begin,
137 BasicStringPiece<TChar>::const_iterator end) const {
138 return BasicStringPiece<TChar>(begin, end - begin);
139}
140
141template <typename TChar>
142inline const TChar* BasicStringPiece<TChar>::data() const {
143 return mData;
144}
145
146template <typename TChar>
147inline size_t BasicStringPiece<TChar>::length() const {
148 return mLength;
149}
150
151template <typename TChar>
152inline size_t BasicStringPiece<TChar>::size() const {
153 return mLength;
154}
155
156template <typename TChar>
157inline bool BasicStringPiece<TChar>::empty() const {
158 return mLength == 0;
159}
160
161template <typename TChar>
162inline std::basic_string<TChar> BasicStringPiece<TChar>::toString() const {
163 return std::basic_string<TChar>(mData, mLength);
164}
165
166template <>
167inline int BasicStringPiece<char>::compare(const BasicStringPiece<char>& rhs) const {
168 const char nullStr = '\0';
169 const char* b1 = mData != nullptr ? mData : &nullStr;
170 const char* e1 = b1 + mLength;
171 const char* b2 = rhs.mData != nullptr ? rhs.mData : &nullStr;
172 const char* e2 = b2 + rhs.mLength;
173
174 while (b1 < e1 && b2 < e2) {
175 const int d = static_cast<int>(*b1++) - static_cast<int>(*b2++);
176 if (d) {
177 return d;
178 }
179 }
180 return static_cast<int>(mLength - rhs.mLength);
181}
182
183inline ::std::ostream& operator<<(::std::ostream& out, const BasicStringPiece<char16_t>& str) {
184 android::String8 utf8(str.data(), str.size());
185 return out.write(utf8.string(), utf8.size());
186}
187
188
189template <>
190inline int BasicStringPiece<char16_t>::compare(const BasicStringPiece<char16_t>& rhs) const {
191 const char16_t nullStr = u'\0';
192 const char16_t* b1 = mData != nullptr ? mData : &nullStr;
193 const char16_t* b2 = rhs.mData != nullptr ? rhs.mData : &nullStr;
194 return strzcmp16(b1, mLength, b2, rhs.mLength);
195}
196
197template <typename TChar>
198inline bool BasicStringPiece<TChar>::operator<(const BasicStringPiece<TChar>& rhs) const {
199 return compare(rhs) < 0;
200}
201
202template <typename TChar>
203inline bool BasicStringPiece<TChar>::operator>(const BasicStringPiece<TChar>& rhs) const {
204 return compare(rhs) > 0;
205}
206
207template <typename TChar>
208inline bool BasicStringPiece<TChar>::operator==(const BasicStringPiece<TChar>& rhs) const {
209 return compare(rhs) == 0;
210}
211
212template <typename TChar>
213inline bool BasicStringPiece<TChar>::operator!=(const BasicStringPiece<TChar>& rhs) const {
214 return compare(rhs) != 0;
215}
216
217template <typename TChar>
218inline typename BasicStringPiece<TChar>::const_iterator BasicStringPiece<TChar>::begin() const {
219 return mData;
220}
221
222template <typename TChar>
223inline typename BasicStringPiece<TChar>::const_iterator BasicStringPiece<TChar>::end() const {
224 return mData + mLength;
225}
226
227inline ::std::ostream& operator<<(::std::ostream& out, const BasicStringPiece<char>& str) {
228 return out.write(str.data(), str.size());
229}
230
231} // namespace aapt
232
Adam Lesinski90959882015-07-06 18:09:18 -0700233inline ::std::ostream& operator<<(::std::ostream& out, const std::u16string& str) {
234 android::String8 utf8(str.data(), str.size());
235 return out.write(utf8.string(), utf8.size());
236}
237
Adam Lesinski6f6ceb72014-11-14 14:48:12 -0800238#endif // AAPT_STRING_PIECE_H