VirtualBox

source: vbox/trunk/src/libs/xpcom18a4/xpcom/string/public/nsTAString.h

Last change on this file was 104491, checked in by vboxsync, 8 months ago

libs/xpcom/string: Missing field initialization in constructor, bugref:3409

  • Property svn:eol-style set to native
  • Property svn:keywords set to Author Date Id Revision
File size: 22.8 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 * Scott Collins <[email protected]> (original author)
24 * Darin Fisher <[email protected]>
25 *
26 * Alternatively, the contents of this file may be used under the terms of
27 * either the GNU General Public License Version 2 or later (the "GPL"), or
28 * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
29 * in which case the provisions of the GPL or the LGPL are applicable instead
30 * of those above. If you wish to allow use of your version of this file only
31 * under the terms of either the GPL or the LGPL, and not to allow others to
32 * use your version of this file under the terms of the MPL, indicate your
33 * decision by deleting the provisions above and replace them with the notice
34 * and other provisions required by the GPL or the LGPL. If you do not delete
35 * the provisions above, a recipient may use your version of this file under
36 * the terms of any one of the MPL, the GPL or the LGPL.
37 *
38 * ***** END LICENSE BLOCK ***** */
39
40
41 /**
42 * The base for string comparators
43 */
44class NS_COM nsTStringComparator_CharT
45 {
46 public:
47 typedef CharT char_type;
48
49 nsTStringComparator_CharT() {}
50
51 virtual int operator()( const char_type*, const char_type*, PRUint32 length ) const = 0;
52 virtual int operator()( char_type, char_type ) const = 0;
53 };
54
55
56 /**
57 * The default string comparator (case-sensitive comparision)
58 */
59class NS_COM nsTDefaultStringComparator_CharT
60 : public nsTStringComparator_CharT
61 {
62 public:
63 typedef CharT char_type;
64
65 nsTDefaultStringComparator_CharT() {}
66
67 virtual int operator()( const char_type*, const char_type*, PRUint32 length ) const;
68 virtual int operator()( char_type, char_type ) const;
69 };
70
71
72 /**
73 * nsTAString is the most abstract class in the string hierarchy.
74 *
75 * In its original inception, nsTAString was designed to allow the data
76 * storage for a string to be separated into multiple fragments. This was
77 * intended to enable lazy string flattening or avoid string flattening
78 * altogether in some cases. This abstraction, however, meant that every
79 * single string operation (including simple operations such as IsEmpty() and
80 * BeginReading()) required virtual function calls. A virtual destructor was
81 * also required. This not only meant additional overhead for invoking
82 * string methods but also added to additional codesize at every callsite (to
83 * load the virtual function address).
84 *
85 * Today nsTAString exists mainly for backwards compatibility of the string
86 * API. It is restricted to representing a contiguous array of characters,
87 * where the character array is not necessarily null-terminated. Moreover,
88 * since nsTAString's virtual function table was frozen for Mozilla 1.0,
89 * nsTAString necessarily maintains ABI compatibility with older versions of
90 * Gecko. (nsTObsoleteAString provides that frozen ABI. See
91 * nsObsoleteAString.h for a description of how we solve the ABI
92 * compatibility requirement while eliminating virtual function calls on
93 * nsTAString.)
94 *
95 * XPIDL still generates C++ header files with references to nsTAStrings, so
96 * nsTAString will still be heavily used in real code.
97 *
98 * If the opportunity to break ABI compatibility with Mozilla 1.0 were to
99 * ever arise, our first move should be to make nsTAString equate to
100 * nsTSubstring. This may in fact be an option today for some Gecko-based
101 * products.
102 */
103class nsTAString_CharT
104 {
105 public:
106
107 typedef CharT char_type;
108 typedef nsCharTraits<char_type> char_traits;
109
110 typedef char_traits::incompatible_char_type incompatible_char_type;
111
112 typedef nsTAString_CharT self_type;
113 typedef nsTAString_CharT abstract_string_type;
114 typedef nsTObsoleteAString_CharT obsolete_string_type;
115 typedef nsTSubstring_CharT substring_type;
116 typedef nsTSubstringTuple_CharT substring_tuple_type;
117
118 typedef nsReadingIterator<char_type> const_iterator;
119 typedef nsWritingIterator<char_type> iterator;
120
121 typedef nsTStringComparator_CharT comparator_type;
122
123 typedef PRUint32 size_type;
124 typedef PRUint32 index_type;
125
126 public:
127
128 // this acts like a virtual destructor
129 NS_COM NS_FASTCALL ~nsTAString_CharT();
130
131
132 /**
133 * BeginReading/EndReading can be used to get immutable access to the
134 * string's underlying buffer. EndReading returns a pointer to the
135 * end of the string's buffer. nsReadableUtils.h provides a collection
136 * of utility functions that work with these iterators.
137 */
138
139 inline const_iterator& BeginReading( const_iterator& iter ) const
140 {
141 size_type len = GetReadableBuffer(&iter.mStart);
142 iter.mEnd = iter.mStart + len;
143 iter.mPosition = iter.mStart;
144 return iter;
145 }
146
147 inline const_iterator& EndReading( const_iterator& iter ) const
148 {
149 size_type len = GetReadableBuffer(&iter.mStart);
150 iter.mEnd = iter.mStart + len;
151 iter.mPosition = iter.mEnd;
152 return iter;
153 }
154
155
156 /**
157 * BeginWriting/EndWriting can be used to get mutable access to the
158 * string's underlying buffer. EndWriting returns a pointer to the
159 * end of the string's buffer. This iterator API cannot be used to
160 * grow a buffer. Use SetLength to resize the string's buffer.
161 */
162
163 inline iterator& BeginWriting( iterator& iter )
164 {
165 size_type len = GetWritableBuffer(&iter.mStart);
166 iter.mEnd = iter.mStart + len;
167 iter.mPosition = iter.mStart;
168 return iter;
169 }
170
171 inline iterator& EndWriting( iterator& iter )
172 {
173 size_type len = GetWritableBuffer(&iter.mStart);
174 iter.mEnd = iter.mStart + len;
175 iter.mPosition = iter.mEnd;
176 return iter;
177 }
178
179
180 /**
181 * Length checking functions. IsEmpty is a helper function to avoid
182 * writing code like: |if (str.Length() == 0)|
183 */
184
185 NS_COM size_type NS_FASTCALL Length() const;
186 PRBool IsEmpty() const { return Length() == 0; }
187
188
189 /**
190 * String equality tests. Pass a string comparator if you want to
191 * control how the strings are compared. By default, a binary
192 * "case-sensitive" comparision is performed.
193 */
194
195 NS_COM PRBool NS_FASTCALL Equals( const self_type& ) const;
196 NS_COM PRBool NS_FASTCALL Equals( const self_type&, const comparator_type& ) const;
197 NS_COM PRBool NS_FASTCALL Equals( const char_type* ) const;
198 NS_COM PRBool NS_FASTCALL Equals( const char_type*, const comparator_type& ) const;
199
200 /**
201 * An efficient comparison with ASCII that can be used even
202 * for wide strings. Call this version when you know the
203 * length of 'data'.
204 */
205 NS_COM PRBool NS_FASTCALL EqualsASCII( const char* data, size_type len ) const;
206 /**
207 * An efficient comparison with ASCII that can be used even
208 * for wide strings. Call this version when 'data' is
209 * null-terminated.
210 */
211 NS_COM PRBool NS_FASTCALL EqualsASCII( const char* data ) const;
212
213 // EqualsLiteral must ONLY be applied to an actual literal string.
214 // Do not attempt to use it with a regular char* pointer, or with a char
215 // array variable.
216 // The template trick to acquire the array length at compile time without
217 // using a macro is due to Corey Kosak, with much thanks.
218#ifdef NS_DISABLE_LITERAL_TEMPLATE
219 inline PRBool EqualsLiteral( const char* str ) const
220 {
221 return EqualsASCII(str);
222 }
223#else
224 template<int N>
225 inline PRBool EqualsLiteral( const char (&str)[N] ) const
226 {
227 return EqualsASCII(str, N-1);
228 }
229 template<int N>
230 inline PRBool EqualsLiteral( char (&str)[N] ) const
231 {
232 const char* s = str;
233 return EqualsASCII(s, N-1);
234 }
235#endif
236
237 // The LowerCaseEquals methods compare the lower case version of
238 // this string to some ASCII/Literal string. The ASCII string is
239 // *not* lowercased for you. If you compare to an ASCII or literal
240 // string that contains an uppercase character, it is guaranteed to
241 // return false. We will throw assertions too.
242 NS_COM PRBool NS_FASTCALL LowerCaseEqualsASCII( const char* data, size_type len ) const;
243 NS_COM PRBool NS_FASTCALL LowerCaseEqualsASCII( const char* data ) const;
244
245 // LowerCaseEqualsLiteral must ONLY be applied to an actual
246 // literal string. Do not attempt to use it with a regular char*
247 // pointer, or with a char array variable. Use
248 // LowerCaseEqualsASCII for them.
249#ifdef NS_DISABLE_LITERAL_TEMPLATE
250 inline PRBool LowerCaseEqualsLiteral( const char* str ) const
251 {
252 return LowerCaseEqualsASCII(str);
253 }
254#else
255 template<int N>
256 inline PRBool LowerCaseEqualsLiteral( const char (&str)[N] ) const
257 {
258 return LowerCaseEqualsASCII(str, N-1);
259 }
260 template<int N>
261 inline PRBool LowerCaseEqualsLiteral( char (&str)[N] ) const
262 {
263 const char* s = str;
264 return LowerCaseEqualsASCII(s, N-1);
265 }
266#endif
267
268 /**
269 * A string always references a non-null data pointer. In some
270 * applications (e.g., the DOM) it is necessary for a string class
271 * to have some way to distinguish an empty string from a null (or
272 * void) string. These methods enable support for the concept of
273 * a void string.
274 */
275
276 NS_COM PRBool NS_FASTCALL IsVoid() const;
277 NS_COM void NS_FASTCALL SetIsVoid( PRBool );
278
279
280 /**
281 * This method returns true if the string's underlying buffer is
282 * null-terminated. This should rarely be needed by applications.
283 * The PromiseFlatTString method should be used to ensure that a
284 * string's underlying buffer is null-terminated.
285 */
286
287 NS_COM PRBool NS_FASTCALL IsTerminated() const;
288
289
290 /**
291 * These are contant time since nsTAString uses flat storage
292 */
293 NS_COM char_type NS_FASTCALL First() const;
294 NS_COM char_type NS_FASTCALL Last() const;
295
296
297 /**
298 * Returns the number of occurances of the given character.
299 */
300 NS_COM size_type NS_FASTCALL CountChar( char_type ) const;
301
302
303 /**
304 * Locates the offset of the first occurance of the character. Pass a
305 * non-zero offset to control where the search begins.
306 */
307
308 NS_COM PRInt32 NS_FASTCALL FindChar( char_type, index_type offset = 0 ) const;
309
310
311 /**
312 * SetCapacity is not required to do anything; however, it can be used
313 * as a hint to the implementation to reduce allocations.
314 *
315 * SetCapacity(0) is a suggestion to discard all associated storage.
316 */
317 NS_COM void NS_FASTCALL SetCapacity( size_type );
318
319
320 /**
321 * XXX talk to dbaron about this comment. we do need a method that
322 * XXX allows someone to resize a string's buffer so that it can be
323 * XXX populated using writing iterators. SetLength seems to be the
324 * XXX right method for the job, and we do use it in this capacity
325 * XXX in certain places.
326 *
327 * SetLength is used in two ways:
328 * 1) to |Cut| a suffix of the string;
329 * 2) to prepare to |Append| or move characters around.
330 *
331 * External callers are not allowed to use |SetLength| in this
332 * latter capacity, and should prefer |Truncate| for the former.
333 * In other words, |SetLength| is deprecated for all use outside
334 * of the string library and the internal use may at some point
335 * be replaced as well.
336 *
337 * This distinction makes me think the two different uses should
338 * be split into two distinct functions.
339 */
340 NS_COM void NS_FASTCALL SetLength( size_type );
341
342
343 /**
344 * Can't use |Truncate| to make a string longer!
345 */
346 void Truncate( size_type aNewLength=0 )
347 {
348 NS_ASSERTION(aNewLength <= Length(), "Truncate cannot make string longer");
349 SetLength(aNewLength);
350 }
351
352
353 /**
354 * |Assign| and |operator=| make |this| equivalent to the string or
355 * buffer given as an argument. If possible, they do this by sharing
356 * a reference counted buffer (see |nsTSubstring|). If not, they copy
357 * the buffer into their own buffer.
358 */
359
360 NS_COM void NS_FASTCALL Assign( const self_type& readable );
361 NS_COM void NS_FASTCALL Assign( const substring_tuple_type& tuple );
362 NS_COM void NS_FASTCALL Assign( const char_type* data );
363 NS_COM void NS_FASTCALL Assign( const char_type* data, size_type length );
364 NS_COM void NS_FASTCALL Assign( char_type c );
365
366 NS_COM void NS_FASTCALL AssignASCII( const char* data, size_type length );
367 NS_COM void NS_FASTCALL AssignASCII( const char* data );
368
369 // AssignLiteral must ONLY be applied to an actual literal string.
370 // Do not attempt to use it with a regular char* pointer, or with a char
371 // array variable. Use AssignASCII for those.
372#ifdef NS_DISABLE_LITERAL_TEMPLATE
373 void AssignLiteral( const char* str )
374 { AssignASCII(str); }
375#else
376 template<int N>
377 void AssignLiteral( const char (&str)[N] )
378 { AssignASCII(str, N-1); }
379 template<int N>
380 void AssignLiteral( char (&str)[N] )
381 { AssignASCII(str, N-1); }
382#endif
383
384 // copy-assignment operator. I must define my own if I don't want the compiler to make me one
385 self_type& operator=( const self_type& readable ) { Assign(readable); return *this; }
386 self_type& operator=( const substring_tuple_type& tuple ) { Assign(tuple); return *this; }
387 self_type& operator=( const char_type* data ) { Assign(data); return *this; }
388 self_type& operator=( char_type c ) { Assign(c); return *this; }
389
390
391
392 /**
393 * |Append|, |operator+=| are used to add characters to the end of this string.
394 */
395
396 NS_COM void NS_FASTCALL Append( const self_type& readable );
397 NS_COM void NS_FASTCALL Append( const substring_tuple_type& tuple );
398 NS_COM void NS_FASTCALL Append( const char_type* data );
399 NS_COM void NS_FASTCALL Append( const char_type* data, size_type length );
400 NS_COM void NS_FASTCALL Append( char_type c );
401
402 NS_COM void NS_FASTCALL AppendASCII( const char* data, size_type length );
403 NS_COM void NS_FASTCALL AppendASCII( const char* data );
404
405 // AppendLiteral must ONLY be applied to an actual literal string.
406 // Do not attempt to use it with a regular char* pointer, or with a char
407 // array variable. Use AppendASCII for those.
408#ifdef NS_DISABLE_LITERAL_TEMPLATE
409 void AppendLiteral( const char* str )
410 { AppendASCII(str); }
411#else
412 template<int N>
413 void AppendLiteral( const char (&str)[N] )
414 { AppendASCII(str, N-1); }
415 template<int N>
416 void AppendLiteral( char (&str)[N] )
417 { AppendASCII(str, N-1); }
418#endif
419
420 self_type& operator+=( const self_type& readable ) { Append(readable); return *this; }
421 self_type& operator+=( const substring_tuple_type& tuple ) { Append(tuple); return *this; }
422 self_type& operator+=( const char_type* data ) { Append(data); return *this; }
423 self_type& operator+=( char_type c ) { Append(c); return *this; }
424
425
426 /**
427 * |Insert| is used to add characters into this string at a given position.
428 * NOTE: It's a shame the |pos| parameter isn't at the front of the arg list.
429 */
430
431 NS_COM void NS_FASTCALL Insert( const self_type& readable, index_type pos );
432 NS_COM void NS_FASTCALL Insert( const substring_tuple_type& tuple, index_type pos );
433 NS_COM void NS_FASTCALL Insert( const char_type* data, index_type pos );
434 NS_COM void NS_FASTCALL Insert( const char_type* data, index_type pos, size_type length );
435 NS_COM void NS_FASTCALL Insert( char_type c, index_type pos );
436
437
438 /**
439 * |Cut| is used to remove a range of characters from this string.
440 */
441
442 NS_COM void NS_FASTCALL Cut( index_type cutStart, size_type cutLength );
443
444
445 /**
446 * |Replace| is used overwrite a range of characters from this string.
447 */
448
449 NS_COM void NS_FASTCALL Replace( index_type cutStart, size_type cutLength, const self_type& readable );
450 NS_COM void NS_FASTCALL Replace( index_type cutStart, size_type cutLength, const substring_tuple_type& readable );
451
452
453 /**
454 * this is public to support automatic conversion of tuple to abstract
455 * string, which is necessary to support our API.
456 */
457 nsTAString_CharT(const substring_tuple_type& tuple)
458 : mVTable(obsolete_string_type::sCanonicalVTable)
459 , mData(nsnull)
460 , mLength(0)
461 , mFlags(0)
462 {
463 Assign(tuple);
464 }
465
466 protected:
467
468 friend class nsTSubstringTuple_CharT;
469
470 // GCC 3.2 erroneously needs these (even though they are subclasses!)
471 friend class nsTSubstring_CharT;
472 friend class nsTDependentSubstring_CharT;
473 friend class nsTPromiseFlatString_CharT;
474
475 /**
476 * the address of our virtual function table. required for backwards
477 * compatibility with Mozilla 1.0 frozen nsAC?String interface.
478 */
479 const void* mVTable;
480
481 /**
482 * these fields are "here" only when mVTable == sCanonicalVTable.
483 *
484 * they exist to support automatic construction of a nsTAString
485 * from a nsTSubstringTuple.
486 */
487 char_type* mData;
488 size_type mLength;
489 PRUint32 mFlags;
490
491 /**
492 * nsTAString must be subclassed before it can be instantiated.
493 */
494 nsTAString_CharT(char_type* data, size_type length, PRUint32 flags)
495 : mVTable(obsolete_string_type::sCanonicalVTable)
496 , mData(data)
497 , mLength(length)
498 , mFlags(flags)
499 {}
500
501 /**
502 * optional ctor for use by subclasses.
503 *
504 * NOTE: mData and mLength are intentionally left uninitialized.
505 */
506 explicit
507 nsTAString_CharT(PRUint32 flags)
508 : mVTable(obsolete_string_type::sCanonicalVTable)
509 , mData(NULL)
510 , mLength(0)
511 , mFlags(flags)
512 {}
513
514 /**
515 * get pointer to internal string buffer (may not be null terminated).
516 * return length of buffer.
517 */
518 NS_COM size_type NS_FASTCALL GetReadableBuffer( const char_type **data ) const;
519 NS_COM size_type NS_FASTCALL GetWritableBuffer( char_type **data );
520
521 /**
522 * returns true if this tuple is dependent on (i.e., overlapping with)
523 * the given char sequence.
524 */
525 PRBool NS_FASTCALL IsDependentOn(const char_type *start, const char_type *end) const;
526
527 /**
528 * we can be converted to a const nsTSubstring (dependent on this)
529 */
530 const substring_type NS_FASTCALL ToSubstring() const;
531
532 /**
533 * type cast helpers
534 */
535
536 const obsolete_string_type* AsObsoleteString() const
537 {
538 return NS_REINTERPRET_CAST(const obsolete_string_type*, this);
539 }
540
541 obsolete_string_type* AsObsoleteString()
542 {
543 return NS_REINTERPRET_CAST(obsolete_string_type*, this);
544 }
545
546 const substring_type* AsSubstring() const
547 {
548 return NS_REINTERPRET_CAST(const substring_type*, this);
549 }
550
551 substring_type* AsSubstring()
552 {
553 return NS_REINTERPRET_CAST(substring_type*, this);
554 }
555
556 private:
557
558 // GCC 2.95.3, EGCS-2.91.66, Sun Workshop/Forte, and IBM VisualAge C++
559 // require a public copy-constructor in order to support automatic
560 // construction of a nsTAString from a nsTSubstringTuple. I believe
561 // enabling the default copy-constructor is harmless, but I do not want
562 // it to be enabled by default because that might tempt people into
563 // using it (where it would be invalid).
564#if !defined(__SUNPRO_CC) && \
565 !(defined(_AIX) && defined(__IBMCPP__)) && \
566 (!defined(__GNUC__) || __GNUC__ > 2 || __GNUC_MINOR__ > 95)
567
568 // NOT TO BE IMPLEMENTED
569 nsTAString_CharT( const self_type& );
570
571#endif
572
573 // NOT TO BE IMPLEMENTED
574 void operator= ( incompatible_char_type );
575 void Assign ( incompatible_char_type );
576 void operator+= ( incompatible_char_type );
577 void Append ( incompatible_char_type );
578 void Insert ( incompatible_char_type, index_type );
579 };
580
581
582NS_COM
583int NS_FASTCALL Compare( const nsTAString_CharT& lhs, const nsTAString_CharT& rhs, const nsTStringComparator_CharT& = nsTDefaultStringComparator_CharT() );
584
585
586inline
587PRBool operator!=( const nsTAString_CharT& lhs, const nsTAString_CharT& rhs )
588 {
589 return !lhs.Equals(rhs);
590 }
591
592inline
593PRBool operator< ( const nsTAString_CharT& lhs, const nsTAString_CharT& rhs )
594 {
595 return Compare(lhs, rhs)< 0;
596 }
597
598inline
599PRBool operator<=( const nsTAString_CharT& lhs, const nsTAString_CharT& rhs )
600 {
601 return Compare(lhs, rhs)<=0;
602 }
603
604inline
605PRBool operator==( const nsTAString_CharT& lhs, const nsTAString_CharT& rhs )
606 {
607 return lhs.Equals(rhs);
608 }
609
610inline
611PRBool operator>=( const nsTAString_CharT& lhs, const nsTAString_CharT& rhs )
612 {
613 return Compare(lhs, rhs)>=0;
614 }
615
616inline
617PRBool operator> ( const nsTAString_CharT& lhs, const nsTAString_CharT& rhs )
618 {
619 return Compare(lhs, rhs)> 0;
620 }
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