Line data Source code
1 : /*
2 : * Copyright (C) 2005 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 ANDROID_STRING8_H
18 : #define ANDROID_STRING8_H
19 :
20 : #include <utils/Errors.h>
21 : #include <utils/SharedBuffer.h>
22 : #include <utils/Unicode.h>
23 : #include <utils/TypeHelpers.h>
24 :
25 : #include <string.h> // for strcmp
26 : #include <stdarg.h>
27 :
28 : // ---------------------------------------------------------------------------
29 :
30 : #ifdef _MSC_VER
31 : #define __attribute__(X)
32 : #endif
33 :
34 : namespace stagefright {
35 :
36 : class String16;
37 : class TextOutput;
38 :
39 : //! This is a string holding UTF-8 characters. Does not allow the value more
40 : // than 0x10FFFF, which is not valid unicode codepoint.
41 : class String8
42 : {
43 : public:
44 : /* use String8(StaticLinkage) if you're statically linking against
45 : * libutils and declaring an empty static String8, e.g.:
46 : *
47 : * static String8 sAStaticEmptyString(String8::kEmptyString);
48 : * static String8 sAnotherStaticEmptyString(sAStaticEmptyString);
49 : */
50 : enum StaticLinkage { kEmptyString };
51 :
52 : String8();
53 : explicit String8(StaticLinkage);
54 : String8(const String8& o);
55 : explicit String8(const char* o);
56 : explicit String8(const char* o, size_t numChars);
57 :
58 : explicit String8(const String16& o);
59 : explicit String8(const char16_t* o);
60 : explicit String8(const char16_t* o, size_t numChars);
61 : explicit String8(const char32_t* o);
62 : explicit String8(const char32_t* o, size_t numChars);
63 : ~String8();
64 :
65 : static inline const String8 empty();
66 :
67 : static String8 format(const char* fmt, ...)
68 : #ifdef __MINGW32__
69 : __attribute__((format (__MINGW_PRINTF_FORMAT, 1, 2)));
70 : #else
71 : __attribute__((format (printf, 1, 2)));
72 : #endif
73 : static String8 formatV(const char* fmt, va_list args);
74 :
75 : inline const char* string() const;
76 : inline size_t size() const;
77 : inline size_t length() const;
78 : inline size_t bytes() const;
79 : inline bool isEmpty() const;
80 :
81 : inline const SharedBuffer* sharedBuffer() const;
82 :
83 : void clear();
84 :
85 : void setTo(const String8& other);
86 : status_t setTo(const char* other);
87 : status_t setTo(const char* other, size_t numChars);
88 : status_t setTo(const char16_t* other, size_t numChars);
89 : status_t setTo(const char32_t* other,
90 : size_t length);
91 :
92 : status_t append(const String8& other);
93 : status_t append(const char* other);
94 : status_t append(const char* other, size_t numChars);
95 :
96 : status_t appendFormat(const char* fmt, ...)
97 : __attribute__((format (printf, 2, 3)));
98 : status_t appendFormatV(const char* fmt, va_list args);
99 :
100 : // Note that this function takes O(N) time to calculate the value.
101 : // No cache value is stored.
102 : size_t getUtf32Length() const;
103 : int32_t getUtf32At(size_t index,
104 : size_t *next_index) const;
105 : void getUtf32(char32_t* dst) const;
106 :
107 : inline String8& operator=(const String8& other);
108 : inline String8& operator=(const char* other);
109 :
110 : inline String8& operator+=(const String8& other);
111 : inline String8 operator+(const String8& other) const;
112 :
113 : inline String8& operator+=(const char* other);
114 : inline String8 operator+(const char* other) const;
115 :
116 : inline int compare(const String8& other) const;
117 :
118 : inline bool operator<(const String8& other) const;
119 : inline bool operator<=(const String8& other) const;
120 : inline bool operator==(const String8& other) const;
121 : inline bool operator!=(const String8& other) const;
122 : inline bool operator>=(const String8& other) const;
123 : inline bool operator>(const String8& other) const;
124 :
125 : inline bool operator<(const char* other) const;
126 : inline bool operator<=(const char* other) const;
127 : inline bool operator==(const char* other) const;
128 : inline bool operator!=(const char* other) const;
129 : inline bool operator>=(const char* other) const;
130 : inline bool operator>(const char* other) const;
131 :
132 : inline operator const char*() const;
133 :
134 : char* lockBuffer(size_t size);
135 : void unlockBuffer();
136 : status_t unlockBuffer(size_t size);
137 :
138 : // return the index of the first byte of other in this at or after
139 : // start, or -1 if not found
140 : ssize_t find(const char* other, size_t start = 0) const;
141 :
142 : void toLower();
143 : void toLower(size_t start, size_t numChars);
144 : void toUpper();
145 : void toUpper(size_t start, size_t numChars);
146 :
147 : /*
148 : * These methods operate on the string as if it were a path name.
149 : */
150 :
151 : /*
152 : * Set the filename field to a specific value.
153 : *
154 : * Normalizes the filename, removing a trailing '/' if present.
155 : */
156 : void setPathName(const char* name);
157 : void setPathName(const char* name, size_t numChars);
158 :
159 : /*
160 : * Get just the filename component.
161 : *
162 : * "/tmp/foo/bar.c" --> "bar.c"
163 : */
164 : String8 getPathLeaf(void) const;
165 :
166 : /*
167 : * Remove the last (file name) component, leaving just the directory
168 : * name.
169 : *
170 : * "/tmp/foo/bar.c" --> "/tmp/foo"
171 : * "/tmp" --> "" // ????? shouldn't this be "/" ???? XXX
172 : * "bar.c" --> ""
173 : */
174 : String8 getPathDir(void) const;
175 :
176 : /*
177 : * Retrieve the front (root dir) component. Optionally also return the
178 : * remaining components.
179 : *
180 : * "/tmp/foo/bar.c" --> "tmp" (remain = "foo/bar.c")
181 : * "/tmp" --> "tmp" (remain = "")
182 : * "bar.c" --> "bar.c" (remain = "")
183 : */
184 : String8 walkPath(String8* outRemains = NULL) const;
185 :
186 : /*
187 : * Return the filename extension. This is the last '.' and any number
188 : * of characters that follow it. The '.' is included in case we
189 : * decide to expand our definition of what constitutes an extension.
190 : *
191 : * "/tmp/foo/bar.c" --> ".c"
192 : * "/tmp" --> ""
193 : * "/tmp/foo.bar/baz" --> ""
194 : * "foo.jpeg" --> ".jpeg"
195 : * "foo." --> ""
196 : */
197 : String8 getPathExtension(void) const;
198 :
199 : /*
200 : * Return the path without the extension. Rules for what constitutes
201 : * an extension are described in the comment for getPathExtension().
202 : *
203 : * "/tmp/foo/bar.c" --> "/tmp/foo/bar"
204 : */
205 : String8 getBasePath(void) const;
206 :
207 : /*
208 : * Add a component to the pathname. We guarantee that there is
209 : * exactly one path separator between the old path and the new.
210 : * If there is no existing name, we just copy the new name in.
211 : *
212 : * If leaf is a fully qualified path (i.e. starts with '/', it
213 : * replaces whatever was there before.
214 : */
215 : String8& appendPath(const char* leaf);
216 : String8& appendPath(const String8& leaf) { return appendPath(leaf.string()); }
217 :
218 : /*
219 : * Like appendPath(), but does not affect this string. Returns a new one instead.
220 : */
221 : String8 appendPathCopy(const char* leaf) const
222 : { String8 p(*this); p.appendPath(leaf); return p; }
223 : String8 appendPathCopy(const String8& leaf) const { return appendPathCopy(leaf.string()); }
224 :
225 : /*
226 : * Converts all separators in this string to /, the default path separator.
227 : *
228 : * If the default OS separator is backslash, this converts all
229 : * backslashes to slashes, in-place. Otherwise it does nothing.
230 : * Returns self.
231 : */
232 : String8& convertToResPath();
233 :
234 : private:
235 : status_t real_append(const char* other, size_t numChars);
236 : char* find_extension(void) const;
237 :
238 : const char* mString;
239 : };
240 :
241 : // String8 can be trivially moved using memcpy() because moving does not
242 : // require any change to the underlying SharedBuffer contents or reference count.
243 : ANDROID_TRIVIAL_MOVE_TRAIT(String8)
244 :
245 : // ---------------------------------------------------------------------------
246 : // No user servicable parts below.
247 :
248 : inline int compare_type(const String8& lhs, const String8& rhs)
249 : {
250 : return lhs.compare(rhs);
251 : }
252 :
253 : inline int strictly_order_type(const String8& lhs, const String8& rhs)
254 : {
255 : return compare_type(lhs, rhs) < 0;
256 : }
257 :
258 : inline const String8 String8::empty() {
259 : return String8();
260 : }
261 :
262 0 : inline const char* String8::string() const
263 : {
264 0 : return mString;
265 : }
266 :
267 0 : inline size_t String8::length() const
268 : {
269 0 : return SharedBuffer::sizeFromData(mString)-1;
270 : }
271 :
272 0 : inline size_t String8::size() const
273 : {
274 0 : return length();
275 : }
276 :
277 : inline bool String8::isEmpty() const
278 : {
279 : return length() == 0;
280 : }
281 :
282 0 : inline size_t String8::bytes() const
283 : {
284 0 : return SharedBuffer::sizeFromData(mString)-1;
285 : }
286 :
287 : inline const SharedBuffer* String8::sharedBuffer() const
288 : {
289 : return SharedBuffer::bufferFromData(mString);
290 : }
291 :
292 0 : inline String8& String8::operator=(const String8& other)
293 : {
294 0 : setTo(other);
295 0 : return *this;
296 : }
297 :
298 : inline String8& String8::operator=(const char* other)
299 : {
300 : setTo(other);
301 : return *this;
302 : }
303 :
304 : inline String8& String8::operator+=(const String8& other)
305 : {
306 : append(other);
307 : return *this;
308 : }
309 :
310 : inline String8 String8::operator+(const String8& other) const
311 : {
312 : String8 tmp(*this);
313 : tmp += other;
314 : return tmp;
315 : }
316 :
317 : inline String8& String8::operator+=(const char* other)
318 : {
319 : append(other);
320 : return *this;
321 : }
322 :
323 : inline String8 String8::operator+(const char* other) const
324 : {
325 : String8 tmp(*this);
326 : tmp += other;
327 : return tmp;
328 : }
329 :
330 : inline int String8::compare(const String8& other) const
331 : {
332 : return strcmp(mString, other.mString);
333 : }
334 :
335 : inline bool String8::operator<(const String8& other) const
336 : {
337 : return strcmp(mString, other.mString) < 0;
338 : }
339 :
340 : inline bool String8::operator<=(const String8& other) const
341 : {
342 : return strcmp(mString, other.mString) <= 0;
343 : }
344 :
345 : inline bool String8::operator==(const String8& other) const
346 : {
347 : return strcmp(mString, other.mString) == 0;
348 : }
349 :
350 : inline bool String8::operator!=(const String8& other) const
351 : {
352 : return strcmp(mString, other.mString) != 0;
353 : }
354 :
355 : inline bool String8::operator>=(const String8& other) const
356 : {
357 : return strcmp(mString, other.mString) >= 0;
358 : }
359 :
360 : inline bool String8::operator>(const String8& other) const
361 : {
362 : return strcmp(mString, other.mString) > 0;
363 : }
364 :
365 : inline bool String8::operator<(const char* other) const
366 : {
367 : return strcmp(mString, other) < 0;
368 : }
369 :
370 : inline bool String8::operator<=(const char* other) const
371 : {
372 : return strcmp(mString, other) <= 0;
373 : }
374 :
375 0 : inline bool String8::operator==(const char* other) const
376 : {
377 0 : return strcmp(mString, other) == 0;
378 : }
379 :
380 : inline bool String8::operator!=(const char* other) const
381 : {
382 : return strcmp(mString, other) != 0;
383 : }
384 :
385 : inline bool String8::operator>=(const char* other) const
386 : {
387 : return strcmp(mString, other) >= 0;
388 : }
389 :
390 : inline bool String8::operator>(const char* other) const
391 : {
392 : return strcmp(mString, other) > 0;
393 : }
394 :
395 0 : inline String8::operator const char*() const
396 : {
397 0 : return mString;
398 : }
399 :
400 : } // namespace stagefright
401 :
402 : #ifdef _MSC_VER
403 : #undef __attribute__
404 : #endif
405 :
406 : // ---------------------------------------------------------------------------
407 :
408 : #endif // ANDROID_STRING8_H
|