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