VirtualBox

source: vbox/trunk/src/libs/xpcom18a4/xpcom/string/public/nsTSubstring.h@ 48392

Last change on this file since 48392 was 1, checked in by vboxsync, 55 years ago

import

  • Property svn:eol-style set to native
  • Property svn:keywords set to Author Date Id Revision
File size: 22.3 KB
Line 
1/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
2/* vim:set ts=2 sw=2 sts=2 et cindent: */
3/* ***** BEGIN LICENSE BLOCK *****
4 * Version: MPL 1.1/GPL 2.0/LGPL 2.1
5 *
6 * The contents of this file are subject to the Mozilla Public License Version
7 * 1.1 (the "License"); you may not use this file except in compliance with
8 * the License. You may obtain a copy of the License at
9 * http://www.mozilla.org/MPL/
10 *
11 * Software distributed under the License is distributed on an "AS IS" basis,
12 * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
13 * for the specific language governing rights and limitations under the
14 * License.
15 *
16 * The Original Code is Mozilla.
17 *
18 * The Initial Developer of the Original Code is IBM Corporation.
19 * Portions created by IBM Corporation are Copyright (C) 2003
20 * IBM Corporation. All Rights Reserved.
21 *
22 * Contributor(s):
23 * Darin Fisher <darin@meer.net>
24 *
25 * Alternatively, the contents of this file may be used under the terms of
26 * either the GNU General Public License Version 2 or later (the "GPL"), or
27 * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
28 * in which case the provisions of the GPL or the LGPL are applicable instead
29 * of those above. If you wish to allow use of your version of this file only
30 * under the terms of either the GPL or the LGPL, and not to allow others to
31 * use your version of this file under the terms of the MPL, indicate your
32 * decision by deleting the provisions above and replace them with the notice
33 * and other provisions required by the GPL or the LGPL. If you do not delete
34 * the provisions above, a recipient may use your version of this file under
35 * the terms of any one of the MPL, the GPL or the LGPL.
36 *
37 * ***** END LICENSE BLOCK ***** */
38
39
40 /**
41 * nsTSubstring
42 *
43 * The base string type. This type is not instantiated directly. A sub-
44 * class is instantiated instead. For example, see nsTString.
45 *
46 * This type works like nsTAString except that it does not have the ABI
47 * requirements of that interface. Like nsTAString, nsTSubstring
48 * represents a single contiguous array of characters that may or may not
49 * be null-terminated.
50 *
51 * Many of the accessors on nsTSubstring are inlined as an optimization.
52 *
53 * This class is also known as "nsASingleFragmentC?String".
54 */
55class nsTSubstring_CharT : public nsTAString_CharT
56 {
57 public:
58
59 typedef nsTSubstring_CharT self_type;
60 typedef nsTString_CharT string_type;
61
62 typedef char_type* char_iterator;
63 typedef const char_type* const_char_iterator;
64
65 public:
66
67 /**
68 * reading iterators
69 */
70
71 const_char_iterator BeginReading() const { return mData; }
72 const_char_iterator EndReading() const { return mData + mLength; }
73
74 /**
75 * deprecated reading iterators
76 */
77
78 const_iterator& BeginReading( const_iterator& iter ) const
79 {
80 iter.mStart = mData;
81 iter.mEnd = mData + mLength;
82 iter.mPosition = iter.mStart;
83 return iter;
84 }
85
86 const_iterator& EndReading( const_iterator& iter ) const
87 {
88 iter.mStart = mData;
89 iter.mEnd = mData + mLength;
90 iter.mPosition = iter.mEnd;
91 return iter;
92 }
93
94 const_char_iterator& BeginReading( const_char_iterator& iter ) const
95 {
96 return iter = mData;
97 }
98
99 const_char_iterator& EndReading( const_char_iterator& iter ) const
100 {
101 return iter = mData + mLength;
102 }
103
104
105 /**
106 * writing iterators
107 */
108
109 char_iterator BeginWriting() { EnsureMutable(); return mData; }
110 char_iterator EndWriting() { EnsureMutable(); return mData + mLength; }
111
112 /**
113 * deprecated writing iterators
114 */
115
116 iterator& BeginWriting( iterator& iter )
117 {
118 EnsureMutable();
119 iter.mStart = mData;
120 iter.mEnd = mData + mLength;
121 iter.mPosition = iter.mStart;
122 return iter;
123 }
124
125 iterator& EndWriting( iterator& iter )
126 {
127 EnsureMutable();
128 iter.mStart = mData;
129 iter.mEnd = mData + mLength;
130 iter.mPosition = iter.mEnd;
131 return iter;
132 }
133
134 char_iterator& BeginWriting( char_iterator& iter )
135 {
136 EnsureMutable();
137 return iter = mData;
138 }
139
140 char_iterator& EndWriting( char_iterator& iter )
141 {
142 EnsureMutable();
143 return iter = mData + mLength;
144 }
145
146
147 /**
148 * accessors
149 */
150
151 // returns pointer to string data (not necessarily null-terminated)
152 const char_type *Data() const
153 {
154 return mData;
155 }
156
157 size_type Length() const
158 {
159 return mLength;
160 }
161
162 PRBool IsEmpty() const
163 {
164 return mLength == 0;
165 }
166
167 PRBool IsVoid() const
168 {
169 return mFlags & F_VOIDED;
170 }
171
172 PRBool IsTerminated() const
173 {
174 return mFlags & F_TERMINATED;
175 }
176
177 char_type CharAt( index_type i ) const
178 {
179 NS_ASSERTION(i < mLength, "index exceeds allowable range");
180 return mData[i];
181 }
182
183 char_type operator[]( index_type i ) const
184 {
185 return CharAt(i);
186 }
187
188 char_type First() const
189 {
190 NS_ASSERTION(mLength > 0, "|First()| called on an empty string");
191 return mData[0];
192 }
193
194 inline
195 char_type Last() const
196 {
197 NS_ASSERTION(mLength > 0, "|Last()| called on an empty string");
198 return mData[mLength - 1];
199 }
200
201 NS_COM size_type NS_FASTCALL CountChar( char_type ) const;
202 NS_COM PRInt32 NS_FASTCALL FindChar( char_type, index_type offset = 0 ) const;
203
204
205 /**
206 * equality
207 */
208
209 NS_COM PRBool NS_FASTCALL Equals( const self_type& ) const;
210 NS_COM PRBool NS_FASTCALL Equals( const self_type&, const comparator_type& ) const;
211
212 NS_COM PRBool NS_FASTCALL Equals( const abstract_string_type& readable ) const;
213 NS_COM PRBool NS_FASTCALL Equals( const abstract_string_type& readable, const comparator_type& comp ) const;
214
215 NS_COM PRBool NS_FASTCALL Equals( const char_type* data ) const;
216 NS_COM PRBool NS_FASTCALL Equals( const char_type* data, const comparator_type& comp ) const;
217
218 /**
219 * An efficient comparison with ASCII that can be used even
220 * for wide strings. Call this version when you know the
221 * length of 'data'.
222 */
223 NS_COM PRBool NS_FASTCALL EqualsASCII( const char* data, size_type len ) const;
224 /**
225 * An efficient comparison with ASCII that can be used even
226 * for wide strings. Call this version when 'data' is
227 * null-terminated.
228 */
229 NS_COM PRBool NS_FASTCALL EqualsASCII( const char* data ) const;
230
231 // EqualsLiteral must ONLY be applied to an actual literal string.
232 // Do not attempt to use it with a regular char* pointer, or with a char
233 // array variable.
234 // The template trick to acquire the array length at compile time without
235 // using a macro is due to Corey Kosak, with much thanks.
236#ifdef NS_DISABLE_LITERAL_TEMPLATE
237 inline PRBool EqualsLiteral( const char* str ) const
238 {
239 return EqualsASCII(str);
240 }
241#else
242 template<int N>
243 inline PRBool EqualsLiteral( const char (&str)[N] ) const
244 {
245 return EqualsASCII(str, N-1);
246 }
247 template<int N>
248 inline PRBool EqualsLiteral( char (&str)[N] ) const
249 {
250 const char* s = str;
251 return EqualsASCII(s, N-1);
252 }
253#endif
254
255 // The LowerCaseEquals methods compare the lower case version of
256 // this string to some ASCII/Literal string. The ASCII string is
257 // *not* lowercased for you. If you compare to an ASCII or literal
258 // string that contains an uppercase character, it is guaranteed to
259 // return false. We will throw assertions too.
260 NS_COM PRBool NS_FASTCALL LowerCaseEqualsASCII( const char* data, size_type len ) const;
261 NS_COM PRBool NS_FASTCALL LowerCaseEqualsASCII( const char* data ) const;
262
263 // LowerCaseEqualsLiteral must ONLY be applied to an actual
264 // literal string. Do not attempt to use it with a regular char*
265 // pointer, or with a char array variable. Use
266 // LowerCaseEqualsASCII for them.
267#ifdef NS_DISABLE_LITERAL_TEMPLATE
268 inline PRBool LowerCaseEqualsLiteral( const char* str ) const
269 {
270 return LowerCaseEqualsASCII(str);
271 }
272#else
273 template<int N>
274 inline PRBool LowerCaseEqualsLiteral( const char (&str)[N] ) const
275 {
276 return LowerCaseEqualsASCII(str, N-1);
277 }
278 template<int N>
279 inline PRBool LowerCaseEqualsLiteral( char (&str)[N] ) const
280 {
281 const char* s = str;
282 return LowerCaseEqualsASCII(s, N-1);
283 }
284#endif
285
286 /**
287 * assignment
288 */
289
290 void Assign( char_type c ) { Assign(&c, 1); }
291 NS_COM void NS_FASTCALL Assign( const char_type* data, size_type length = size_type(-1) );
292 NS_COM void NS_FASTCALL Assign( const self_type& );
293 NS_COM void NS_FASTCALL Assign( const substring_tuple_type& );
294 NS_COM void NS_FASTCALL Assign( const abstract_string_type& );
295
296 NS_COM void NS_FASTCALL AssignASCII( const char* data, size_type length );
297 NS_COM void NS_FASTCALL AssignASCII( const char* data );
298
299 // AssignLiteral must ONLY be applied to an actual literal string.
300 // Do not attempt to use it with a regular char* pointer, or with a char
301 // array variable. Use AssignASCII for those.
302#ifdef NS_DISABLE_LITERAL_TEMPLATE
303 void AssignLiteral( const char* str )
304 { AssignASCII(str); }
305#else
306 template<int N>
307 void AssignLiteral( const char (&str)[N] )
308 { AssignASCII(str, N-1); }
309 template<int N>
310 void AssignLiteral( char (&str)[N] )
311 { AssignASCII(str, N-1); }
312#endif
313
314 self_type& operator=( char_type c ) { Assign(c); return *this; }
315 self_type& operator=( const char_type* data ) { Assign(data); return *this; }
316 self_type& operator=( const self_type& str ) { Assign(str); return *this; }
317 self_type& operator=( const substring_tuple_type& tuple ) { Assign(tuple); return *this; }
318 self_type& operator=( const abstract_string_type& readable ) { Assign(readable); return *this; }
319
320 NS_COM void NS_FASTCALL Adopt( char_type* data, size_type length = size_type(-1) );
321
322
323 /**
324 * buffer manipulation
325 */
326
327 void Replace( index_type cutStart, size_type cutLength, char_type c ) { Replace(cutStart, cutLength, &c, 1); }
328 NS_COM void NS_FASTCALL Replace( index_type cutStart, size_type cutLength, const char_type* data, size_type length = size_type(-1) );
329 void Replace( index_type cutStart, size_type cutLength, const self_type& str ) { Replace(cutStart, cutLength, str.Data(), str.Length()); }
330 NS_COM void NS_FASTCALL Replace( index_type cutStart, size_type cutLength, const substring_tuple_type& tuple );
331 NS_COM void NS_FASTCALL Replace( index_type cutStart, size_type cutLength, const abstract_string_type& readable );
332
333 NS_COM void NS_FASTCALL ReplaceASCII( index_type cutStart, size_type cutLength, const char* data, size_type length = size_type(-1) );
334
335 void Append( char_type c ) { Replace(mLength, 0, c); }
336 void Append( const char_type* data, size_type length = size_type(-1) ) { Replace(mLength, 0, data, length); }
337 void Append( const self_type& str ) { Replace(mLength, 0, str); }
338 void Append( const substring_tuple_type& tuple ) { Replace(mLength, 0, tuple); }
339 void Append( const abstract_string_type& readable ) { Replace(mLength, 0, readable); }
340
341 void AppendASCII( const char* data, size_type length = size_type(-1) ) { ReplaceASCII(mLength, 0, data, length); }
342
343 // AppendLiteral must ONLY be applied to an actual literal string.
344 // Do not attempt to use it with a regular char* pointer, or with a char
345 // array variable. Use AppendASCII for those.
346#ifdef NS_DISABLE_LITERAL_TEMPLATE
347 void AppendLiteral( const char* str )
348 { AppendASCII(str); }
349#else
350 template<int N>
351 void AppendLiteral( const char (&str)[N] )
352 { AppendASCII(str, N-1); }
353 template<int N>
354 void AppendLiteral( char (&str)[N] )
355 { AppendASCII(str, N-1); }
356#endif
357
358 self_type& operator+=( char_type c ) { Append(c); return *this; }
359 self_type& operator+=( const char_type* data ) { Append(data); return *this; }
360 self_type& operator+=( const self_type& str ) { Append(str); return *this; }
361 self_type& operator+=( const substring_tuple_type& tuple ) { Append(tuple); return *this; }
362 self_type& operator+=( const abstract_string_type& readable ) { Append(readable); return *this; }
363
364 void Insert( char_type c, index_type pos ) { Replace(pos, 0, c); }
365 void Insert( const char_type* data, index_type pos, size_type length = size_type(-1) ) { Replace(pos, 0, data, length); }
366 void Insert( const self_type& str, index_type pos ) { Replace(pos, 0, str); }
367 void Insert( const substring_tuple_type& tuple, index_type pos ) { Replace(pos, 0, tuple); }
368 void Insert( const abstract_string_type& readable, index_type pos ) { Replace(pos, 0, readable); }
369
370 void Cut( index_type cutStart, size_type cutLength ) { Replace(cutStart, cutLength, char_traits::sEmptyBuffer, 0); }
371
372
373 /**
374 * buffer sizing
375 */
376
377 NS_COM void NS_FASTCALL SetCapacity( size_type capacity );
378
379 NS_COM void NS_FASTCALL SetLength( size_type );
380
381 void Truncate( size_type newLength = 0 )
382 {
383 NS_ASSERTION(newLength <= mLength, "Truncate cannot make string longer");
384 SetLength(newLength);
385 }
386
387
388 /**
389 * string data is never null, but can be marked void. if true, the
390 * string will be truncated. @see nsTSubstring::IsVoid
391 */
392
393 NS_COM void NS_FASTCALL SetIsVoid( PRBool );
394
395
396 public:
397
398 /**
399 * this is public to support automatic conversion of tuple to string
400 * base type, which helps avoid converting to nsTAString.
401 */
402 nsTSubstring_CharT(const substring_tuple_type& tuple)
403 : abstract_string_type(nsnull, 0, F_NONE)
404 {
405 Assign(tuple);
406 }
407
408 protected:
409
410 friend class nsTObsoleteAStringThunk_CharT;
411 friend class nsTAString_CharT;
412 friend class nsTSubstringTuple_CharT;
413
414 // XXX GCC 3.4 needs this :-(
415 friend class nsTPromiseFlatString_CharT;
416
417 // default initialization
418 nsTSubstring_CharT()
419 : abstract_string_type(
420 NS_CONST_CAST(char_type*, char_traits::sEmptyBuffer), 0, F_TERMINATED) {}
421
422 // allow subclasses to initialize fields directly
423 nsTSubstring_CharT( char_type *data, size_type length, PRUint32 flags )
424 : abstract_string_type(data, length, flags) {}
425
426 // version of constructor that leaves mData and mLength uninitialized
427 explicit
428 nsTSubstring_CharT( PRUint32 flags )
429 : abstract_string_type(flags) {}
430
431 // copy-constructor, constructs as dependent on given object
432 // (NOTE: this is for internal use only)
433 nsTSubstring_CharT( const self_type& str )
434 : abstract_string_type(
435 str.mData, str.mLength, str.mFlags & (F_TERMINATED | F_VOIDED)) {}
436
437 /**
438 * this function releases mData and does not change the value of
439 * any of its member variables. inotherwords, this function acts
440 * like a destructor.
441 */
442 void NS_FASTCALL Finalize();
443
444 /**
445 * this function prepares mData to be mutated.
446 *
447 * @param capacity specifies the required capacity of mData
448 * @param old_data returns null or the old value of mData
449 * @param old_flags returns 0 or the old value of mFlags
450 *
451 * if mData is already mutable and of sufficient capacity, then this
452 * function will return immediately. otherwise, it will either resize
453 * mData or allocate a new shared buffer. if it needs to allocate a
454 * new buffer, then it will return the old buffer and the corresponding
455 * flags. this allows the caller to decide when to free the old data.
456 *
457 * XXX we should expose a way for subclasses to free old_data.
458 */
459 PRBool NS_FASTCALL MutatePrep( size_type capacity, char_type** old_data, PRUint32* old_flags );
460
461 /**
462 * this function prepares a section of mData to be modified. if
463 * necessary, this function will reallocate mData and possibly move
464 * existing data to open up the specified section.
465 *
466 * @param cutStart specifies the starting offset of the section
467 * @param cutLength specifies the length of the section to be replaced
468 * @param newLength specifies the length of the new section
469 *
470 * for example, suppose mData contains the string "abcdef" then
471 *
472 * ReplacePrep(2, 3, 4);
473 *
474 * would cause mData to look like "ab____f" where the characters
475 * indicated by '_' have an unspecified value and can be freely
476 * modified. this function will null-terminate mData upon return.
477 */
478 void NS_FASTCALL ReplacePrep( index_type cutStart, size_type cutLength, size_type newLength );
479
480 /**
481 * returns the number of writable storage units starting at mData.
482 * the value does not include space for the null-terminator character.
483 *
484 * NOTE: this function returns size_type(-1) if mData is immutable.
485 */
486 size_type NS_FASTCALL Capacity() const;
487
488 /**
489 * this helper function can be called prior to directly manipulating
490 * the contents of mData. see, for example, BeginWriting.
491 */
492 NS_COM void NS_FASTCALL EnsureMutable();
493
494 /**
495 * returns true if this string overlaps with the given string fragment.
496 */
497 PRBool IsDependentOn( const char_type *start, const char_type *end ) const
498 {
499 /**
500 * if it _isn't_ the case that one fragment starts after the other ends,
501 * or ends before the other starts, then, they conflict:
502 *
503 * !(f2.begin >= f1.end || f2.end <= f1.begin)
504 *
505 * Simplified, that gives us:
506 */
507 return ( start < (mData + mLength) && end > mData );
508 }
509
510 /**
511 * this helper function stores the specified dataFlags in mFlags
512 */
513 void SetDataFlags(PRUint32 dataFlags)
514 {
515 NS_ASSERTION((dataFlags & 0xFFFF0000) == 0, "bad flags");
516 mFlags = dataFlags | (mFlags & 0xFFFF0000);
517 }
518
519 public:
520
521 // mFlags is a bitwise combination of the following flags. the meaning
522 // and interpretation of these flags is an implementation detail.
523 //
524 // NOTE: these flags are declared public _only_ for convenience inside
525 // the string implementation.
526
527 enum
528 {
529 F_NONE = 0, // no flags
530
531 // data flags are in the lower 16-bits
532 F_TERMINATED = 1 << 0, // IsTerminated returns true
533 F_VOIDED = 1 << 1, // IsVoid returns true
534 F_SHARED = 1 << 2, // mData points to a heap-allocated, shared buffer
535 F_OWNED = 1 << 3, // mData points to a heap-allocated, raw buffer
536 F_FIXED = 1 << 4, // mData points to a fixed-size writable, dependent buffer
537
538 // class flags are in the upper 16-bits
539 F_CLASS_FIXED = 1 << 16 // indicates that |this| is of type nsTFixedString
540 };
541
542 //
543 // Some terminology:
544 //
545 // "dependent buffer" A dependent buffer is one that the string class
546 // does not own. The string class relies on some
547 // external code to ensure the lifetime of the
548 // dependent buffer.
549 //
550 // "shared buffer" A shared buffer is one that the string class
551 // allocates. When it allocates a shared string
552 // buffer, it allocates some additional space at
553 // the beginning of the buffer for additional
554 // fields, including a reference count and a
555 // buffer length. See nsStringHeader.
556 //
557 // "adopted buffer" An adopted buffer is a raw string buffer
558 // allocated on the heap (using nsMemory::Alloc)
559 // of which the string class subsumes ownership.
560 //
561 // Some comments about the string flags:
562 //
563 // F_SHARED, F_OWNED, and F_FIXED are all mutually exlusive. They
564 // indicate the allocation type of mData. If none of these flags
565 // are set, then the string buffer is dependent.
566 //
567 // F_SHARED, F_OWNED, or F_FIXED imply F_TERMINATED. This is because
568 // the string classes always allocate null-terminated buffers, and
569 // non-terminated substrings are always dependent.
570 //
571 // F_VOIDED implies F_TERMINATED, and moreover it implies that mData
572 // points to char_traits::sEmptyBuffer. Therefore, F_VOIDED is
573 // mutually exclusive with F_SHARED, F_OWNED, and F_FIXED.
574 //
575 };
Note: See TracBrowser for help on using the repository browser.

© 2024 Oracle Support Privacy / Do Not Sell My Info Terms of Use Trademark Policy Automated Access Etiquette