1 /* secqstring.cpp - Secure version of TQString.
2 * Copyright (C) 1992-2002 Trolltech AS. All rights reserved.
3 * Copyright (C) 2003 g10 Code GmbH
4 *
5 * The license of the original qstring.cpp file from which this file
6 * is derived can be found below. Modified by Marcus Brinkmann
7 * <marcus@g10code.de>. All modifications are licensed as follows, so
8 * that the intersection of the two licenses is then the GNU General
9 * Public License version 2.
10 *
11 * This program is free software; you can redistribute it and/or
12 * modify it under the terms of the GNU General Public License as
13 * published by the Free Software Foundation; either version 2 of the
14 * License, or (at your option) any later version.
15 *
16 * This program is distributed in the hope that it will be useful, but
17 * WITHOUT ANY WARRANTY; without even the implied warranty of
18 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
19 * General Public License for more details.
20 *
21 * You should have received a copy of the GNU General Public License
22 * along with this program; if not, see <https://www.gnu.org/licenses/>.
23 * SPDX-License-Identifier: GPL-2.0
24 */
25
26 /****************************************************************************
27 ** $Id$
28 **
29 ** Implementation of the SecTQString class and related Unicode functions
30 **
31 ** Created : 920722
32 **
33 ** Copyright (C) 1992-2002 Trolltech AS. All rights reserved.
34 **
35 ** This file is part of the tools module of the TQt GUI Toolkit.
36 **
37 ** This file may be distributed under the terms of the Q Public License
38 ** as defined by Trolltech AS of Norway and appearing in the file
39 ** LICENSE.TQPL included in the packaging of this file.
40 **
41 ** This file may be distributed and/or modified under the terms of the
42 ** GNU General Public License version 2 as published by the Free Software
43 ** Foundation and appearing in the file LICENSE.GPL included in the
44 ** packaging of this file.
45 **
46 ** Licensees holding valid TQt Enterprise Edition or TQt Professional Edition
47 ** licenses may use this file in accordance with the TQt Commercial License
48 ** Agreement provided with the Software.
49 **
50 ** This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE
51 ** WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
52 **
53 ** See http://www.trolltech.com/pricing.html or email sales@trolltech.com for
54 ** information about TQt Commercial License Agreements.
55 ** See http://www.trolltech.com/qpl/ for TQPL licensing information.
56 ** See http://www.trolltech.com/gpl/ for GPL licensing information.
57 **
58 ** Contact info@trolltech.com if any conditions of this licensing are
59 ** not clear to you.
60 **
61 **********************************************************************/
62
63 // Don't define it while compiling this module, or USERS of TQt will
64 // not be able to link.
65
66 #include "secqstring.h"
67
computeNewMax(uint len)68 static uint computeNewMax( uint len )
69 {
70 uint newMax = 4;
71 while ( newMax < len )
72 newMax *= 2;
73 // try to save some memory
74 if ( newMax >= 1024 * 1024 && len <= newMax - (newMax >> 2) )
75 newMax -= newMax >> 2;
76 return newMax;
77 }
78
79 // These macros are used for efficient allocation of TQChar strings.
80 // IMPORTANT! If you change these, make sure you also change the
81 // "delete unicode" statement in ~SecTQStringData() in SecTQString.h correspondingly!
82
83 #define QT_ALLOC_SECTQCHAR_VEC(N) (TQChar*) ::secmem_malloc (sizeof(TQChar) * (N))
84 #define QT_DELETE_SECTQCHAR_VEC(P) ::secmem_free (P)
85
86
87 /*****************************************************************************
88 SecTQString member functions
89 *****************************************************************************/
90
91 /*!
92 \class SecTQString SecTQString.h
93 \reentrant
94
95 \brief The SecTQString class provides an abstraction of Unicode text
96 and the classic C '\0'-terminated char array.
97
98 \ingroup tools
99 \ingroup shared
100 \ingroup text
101 \mainclass
102
103 SecTQString uses \link shclass.html implicit sharing\endlink, which
104 makes it very efficient and easy to use.
105
106 In all of the SecTQString methods that take \c {const char *}
107 parameters, the \c {const char *} is interpreted as a classic
108 C-style '\0'-terminated ASCII string. It is legal for the \c
109 {const char *} parameter to be 0. If the \c {const char *} is not
110 '\0'-terminated, the results are undefined. Functions that copy
111 classic C strings into a SecTQString will not copy the terminating
112 '\0' character. The TQChar array of the SecTQString (as returned by
113 unicode()) is generally not terminated by a '\0'. If you need to
114 pass a SecTQString to a function that requires a C '\0'-terminated
115 string use latin1().
116
117 \keyword SecTQString::null
118 A SecTQString that has not been assigned to anything is \e null, i.e.
119 both the length and data pointer is 0. A SecTQString that references
120 the empty string ("", a single '\0' char) is \e empty. Both null
121 and empty SecTQStrings are legal parameters to the methods. Assigning
122 \c{(const char *) 0} to SecTQString gives a null SecTQString. For
123 convenience, \c SecTQString::null is a null SecTQString. When sorting,
124 empty strings come first, followed by non-empty strings, followed
125 by null strings. We recommend using \c{if ( !str.isNull() )} to
126 check for a non-null string rather than \c{if ( !str )}; see \l
127 operator!() for an explanation.
128
129 Note that if you find that you are mixing usage of \l TQCString,
130 SecTQString, and \l TQByteArray, this causes lots of unnecessary
131 copying and might indicate that the true nature of the data you
132 are dealing with is uncertain. If the data is '\0'-terminated 8-bit
133 data, use \l TQCString; if it is unterminated (i.e. contains '\0's)
134 8-bit data, use \l TQByteArray; if it is text, use SecTQString.
135
136 Lists of strings are handled by the SecTQStringList class. You can
137 split a string into a list of strings using SecTQStringList::split(),
138 and join a list of strings into a single string with an optional
139 separator using SecTQStringList::join(). You can obtain a list of
140 strings from a string list that contain a particular substring or
141 that match a particular \link ntqregexp.html regex\endlink using
142 SecTQStringList::grep().
143
144 <b>Note for C programmers</b>
145
146 Due to C++'s type system and the fact that SecTQString is implicitly
147 shared, SecTQStrings may be treated like ints or other simple base
148 types. For example:
149
150 \code
151 SecTQString boolToString( bool b )
152 {
153 SecTQString result;
154 if ( b )
155 result = "True";
156 else
157 result = "False";
158 return result;
159 }
160 \endcode
161
162 The variable, result, is an auto variable allocated on the stack.
163 When return is called, because we're returning by value, The copy
164 constructor is called and a copy of the string is returned. (No
165 actual copying takes place thanks to the implicit sharing, see
166 below.)
167
168 Throughout TQt's source code you will encounter SecTQString usages like
169 this:
170 \code
171 SecTQString func( const SecTQString& input )
172 {
173 SecTQString output = input;
174 // process output
175 return output;
176 }
177 \endcode
178
179 The 'copying' of input to output is almost as fast as copying a
180 pointer because behind the scenes copying is achieved by
181 incrementing a reference count. SecTQString (like all TQt's implicitly
182 shared classes) operates on a copy-on-write basis, only copying if
183 an instance is actually changed.
184
185 If you wish to create a deep copy of a SecTQString without losing any
186 Unicode information then you should use TQDeepCopy.
187
188 \sa TQChar TQCString TQByteArray SecTQConstString
189 */
190
191 Q_EXPORT SecTQStringData *SecTQString::shared_null = 0;
192 QT_STATIC_CONST_IMPL SecTQString SecTQString::null;
193 QT_STATIC_CONST_IMPL TQChar TQChar::null;
194 QT_STATIC_CONST_IMPL TQChar TQChar::replacement((ushort)0xfffd);
195 QT_STATIC_CONST_IMPL TQChar TQChar::byteOrderMark((ushort)0xfeff);
196 QT_STATIC_CONST_IMPL TQChar TQChar::byteOrderSwapped((ushort)0xfffe);
197 QT_STATIC_CONST_IMPL TQChar TQChar::nbsp((ushort)0x00a0);
198
makeSharedNull()199 SecTQStringData* SecTQString::makeSharedNull()
200 {
201 SecTQString::shared_null = new SecTQStringData;
202 #if defined( Q_OS_MAC )
203 SecTQString *that = const_cast<SecTQString *>(&SecTQString::null);
204 that->d = SecTQString::shared_null;
205 #endif
206 return SecTQString::shared_null;
207 }
208
209 /*!
210 \fn SecTQString::SecTQString()
211
212 Constructs a null string, i.e. both the length and data pointer
213 are 0.
214
215 \sa isNull()
216 */
217
218 /*!
219 Constructs a string of length one, containing the character \a ch.
220 */
SecTQString(TQChar ch)221 SecTQString::SecTQString( TQChar ch )
222 {
223 d = new SecTQStringData( QT_ALLOC_SECTQCHAR_VEC( 1 ), 1, 1 );
224 d->unicode[0] = ch;
225 }
226
227 /*!
228 Constructs an implicitly shared copy of \a s. This is very fast
229 since it only involves incrementing a reference count.
230 */
SecTQString(const SecTQString & s)231 SecTQString::SecTQString( const SecTQString &s ) :
232 d(s.d)
233 {
234 d->ref();
235 }
236
237
SecTQString(int size,bool)238 SecTQString::SecTQString( int size, bool /*dummy*/ )
239 {
240 if ( size ) {
241 int l = size;
242 TQChar* uc = QT_ALLOC_SECTQCHAR_VEC( l );
243 d = new SecTQStringData( uc, 0, l );
244 } else {
245 d = shared_null ? shared_null : (shared_null=new SecTQStringData);
246 d->ref();
247 }
248 }
249
250
251 /* Deep copy of STR. */
SecTQString(const TQString & str)252 SecTQString::SecTQString( const TQString &str )
253 {
254 const TQChar *unicode = str.unicode ();
255 uint length = str.length ();
256
257 if ( !unicode && !length ) {
258 d = shared_null ? shared_null : makeSharedNull();
259 d->ref();
260 } else {
261 TQChar* uc = QT_ALLOC_SECTQCHAR_VEC( length );
262 if ( unicode )
263 memcpy(uc, unicode, length*sizeof(TQChar));
264 d = new SecTQStringData(uc,unicode ? length : 0,length);
265 }
266 }
267
268
269 /*!
270 Constructs a string that is a deep copy of the first \a length
271 characters in the TQChar array.
272
273 If \a unicode and \a length are 0, then a null string is created.
274
275 If only \a unicode is 0, the string is empty but has \a length
276 characters of space preallocated: SecTQString expands automatically
277 anyway, but this may speed up some cases a little. We recommend
278 using the plain constructor and setLength() for this purpose since
279 it will result in more readable code.
280
281 \sa isNull() setLength()
282 */
283
SecTQString(const TQChar * unicode,uint length)284 SecTQString::SecTQString( const TQChar* unicode, uint length )
285 {
286 if ( !unicode && !length ) {
287 d = shared_null ? shared_null : makeSharedNull();
288 d->ref();
289 } else {
290 TQChar* uc = QT_ALLOC_SECTQCHAR_VEC( length );
291 if ( unicode )
292 memcpy(uc, unicode, length*sizeof(TQChar));
293 d = new SecTQStringData(uc,unicode ? length : 0,length);
294 }
295 }
296
297 /*!
298 \fn SecTQString::~SecTQString()
299
300 Destroys the string and frees the string's data if this is the
301 last reference to the string.
302 */
303
304
305 /*!
306 Deallocates any space reserved solely by this SecTQString.
307
308 If the string does not share its data with another SecTQString
309 instance, nothing happens; otherwise the function creates a new,
310 unique copy of this string. This function is called whenever the
311 string is modified.
312 */
313
real_detach()314 void SecTQString::real_detach()
315 {
316 setLength( length() );
317 }
318
deref()319 void SecTQString::deref()
320 {
321 if ( d && d->deref() ) {
322 if ( d != shared_null )
323 delete d;
324 d = 0;
325 }
326 }
327
deleteSelf()328 void SecTQStringData::deleteSelf()
329 {
330 delete this;
331 }
332
333 /*!
334 \fn SecTQString& SecTQString::operator=( TQChar c )
335
336 Sets the string to contain just the single character \a c.
337 */
338
339
340 /*!
341 \overload
342
343 Assigns a shallow copy of \a s to this string and returns a
344 reference to this string. This is very fast because the string
345 isn't actually copied.
346 */
operator =(const SecTQString & s)347 SecTQString &SecTQString::operator=( const SecTQString &s )
348 {
349 s.d->ref();
350 deref();
351 d = s.d;
352 return *this;
353 }
354
355
356 /*!
357 \fn bool SecTQString::isNull() const
358
359 Returns TRUE if the string is null; otherwise returns FALSE. A
360 null string is always empty.
361
362 \code
363 SecTQString a; // a.unicode() == 0, a.length() == 0
364 a.isNull(); // TRUE, because a.unicode() == 0
365 a.isEmpty(); // TRUE, because a.length() == 0
366 \endcode
367
368 \sa isEmpty(), length()
369 */
370
371 /*!
372 \fn bool SecTQString::isEmpty() const
373
374 Returns TRUE if the string is empty, i.e. if length() == 0;
375 otherwise returns FALSE. Null strings are also empty.
376
377 \code
378 SecTQString a( "" );
379 a.isEmpty(); // TRUE
380 a.isNull(); // FALSE
381
382 SecTQString b;
383 b.isEmpty(); // TRUE
384 b.isNull(); // TRUE
385 \endcode
386
387 \sa isNull(), length()
388 */
389
390 /*!
391 \fn uint SecTQString::length() const
392
393 Returns the length of the string.
394
395 Null strings and empty strings have zero length.
396
397 \sa isNull(), isEmpty()
398 */
399
400 /*!
401 If \a newLen is less than the length of the string, then the
402 string is truncated at position \a newLen. Otherwise nothing
403 happens.
404
405 \code
406 SecTQString s = "truncate me";
407 s.truncate( 5 ); // s == "trunc"
408 \endcode
409
410 \sa setLength()
411 */
412
truncate(uint newLen)413 void SecTQString::truncate( uint newLen )
414 {
415 if ( newLen < d->len )
416 setLength( newLen );
417 }
418
419 /*!
420 Ensures that at least \a newLen characters are allocated to the
421 string, and sets the length of the string to \a newLen. Any new
422 space allocated contains arbitrary data.
423
424 \sa reserve(), truncate()
425 */
setLength(uint newLen)426 void SecTQString::setLength( uint newLen )
427 {
428 if ( d->count != 1 || newLen > d->maxl ||
429 ( newLen * 4 < d->maxl && d->maxl > 4 ) ) {
430 // detach, grow or shrink
431 uint newMax = computeNewMax( newLen );
432 TQChar* nd = QT_ALLOC_SECTQCHAR_VEC( newMax );
433 if ( nd ) {
434 uint len = TQMIN( d->len, newLen );
435 memcpy( nd, d->unicode, sizeof(TQChar) * len );
436 deref();
437 d = new SecTQStringData( nd, newLen, newMax );
438 }
439 } else {
440 d->len = newLen;
441 }
442 }
443
444
445 /*!
446 \internal
447
448 Like setLength, but doesn't shrink the allocated memory.
449 */
grow(uint newLen)450 void SecTQString::grow( uint newLen )
451 {
452 if ( d->count != 1 || newLen > d->maxl ) {
453 setLength( newLen );
454 } else {
455 d->len = newLen;
456 }
457 }
458
459
460 /*!
461 Returns a substring that contains the \a len leftmost characters
462 of the string.
463
464 The whole string is returned if \a len exceeds the length of the
465 string.
466
467 \code
468 SecTQString s = "Pineapple";
469 SecTQString t = s.left( 4 ); // t == "Pine"
470 \endcode
471
472 \sa right(), mid(), isEmpty()
473 */
474
left(uint len) const475 SecTQString SecTQString::left( uint len ) const
476 {
477 if ( isEmpty() ) {
478 return SecTQString();
479 } else if ( len == 0 ) { // ## just for 1.x compat:
480 return SecTQString ("");
481 } else if ( len >= length() ) {
482 return *this;
483 } else {
484 SecTQString s( len, TRUE );
485 memcpy( s.d->unicode, d->unicode, len * sizeof(TQChar) );
486 s.d->len = len;
487 return s;
488 }
489 }
490
491 /*!
492 Returns a string that contains the \a len rightmost characters of
493 the string.
494
495 If \a len is greater than the length of the string then the whole
496 string is returned.
497
498 \code
499 SecTQString string( "Pineapple" );
500 SecTQString t = string.right( 5 ); // t == "apple"
501 \endcode
502
503 \sa left(), mid(), isEmpty()
504 */
505
right(uint len) const506 SecTQString SecTQString::right( uint len ) const
507 {
508 if ( isEmpty() ) {
509 return SecTQString();
510 } else if ( len == 0 ) { // ## just for 1.x compat:
511 return SecTQString ("");
512 } else {
513 uint l = length();
514 if ( len >= l )
515 return *this;
516 SecTQString s( len, TRUE );
517 memcpy( s.d->unicode, d->unicode+(l-len), len*sizeof(TQChar) );
518 s.d->len = len;
519 return s;
520 }
521 }
522
523 /*!
524 Returns a string that contains the \a len characters of this
525 string, starting at position \a index.
526
527 Returns a null string if the string is empty or \a index is out of
528 range. Returns the whole string from \a index if \a index + \a len
529 exceeds the length of the string.
530
531 \code
532 SecTQString s( "Five pineapples" );
533 SecTQString t = s.mid( 5, 4 ); // t == "pine"
534 \endcode
535
536 \sa left(), right()
537 */
538
mid(uint index,uint len) const539 SecTQString SecTQString::mid( uint index, uint len ) const
540 {
541 uint slen = length();
542 if ( isEmpty() || index >= slen ) {
543 return SecTQString();
544 } else if ( len == 0 ) { // ## just for 1.x compat:
545 return SecTQString ("");
546 } else {
547 if ( len > slen-index )
548 len = slen - index;
549 if ( index == 0 && len == slen )
550 return *this;
551 register const TQChar *p = unicode()+index;
552 SecTQString s( len, TRUE );
553 memcpy( s.d->unicode, p, len * sizeof(TQChar) );
554 s.d->len = len;
555 return s;
556 }
557 }
558
559 /*!
560 Inserts \a s into the string at position \a index.
561
562 If \a index is beyond the end of the string, the string is
563 extended with spaces to length \a index and \a s is then appended
564 and returns a reference to the string.
565
566 \code
567 SecTQString string( "I like fish" );
568 str = string.insert( 2, "don't " );
569 // str == "I don't like fish"
570 \endcode
571
572 \sa remove(), replace()
573 */
574
insert(uint index,const SecTQString & s)575 SecTQString &SecTQString::insert( uint index, const SecTQString &s )
576 {
577 // the sub function takes care of &s == this case.
578 return insert( index, s.unicode(), s.length() );
579 }
580
581 /*!
582 \overload
583
584 Inserts the first \a len characters in \a s into the string at
585 position \a index and returns a reference to the string.
586 */
587
insert(uint index,const TQChar * s,uint len)588 SecTQString &SecTQString::insert( uint index, const TQChar* s, uint len )
589 {
590 if ( len == 0 )
591 return *this;
592 uint olen = length();
593 int nlen = olen + len;
594
595 if ( s >= d->unicode && (uint)(s - d->unicode) < d->maxl ) {
596 // Part of me - take a copy.
597 TQChar *tmp = QT_ALLOC_SECTQCHAR_VEC( len );
598 memcpy(tmp,s,len*sizeof(TQChar));
599 insert(index,tmp,len);
600 QT_DELETE_SECTQCHAR_VEC( tmp );
601 return *this;
602 }
603
604 if ( index >= olen ) { // insert after end of string
605 grow( len + index );
606 int n = index - olen;
607 TQChar* uc = d->unicode+olen;
608 while (n--)
609 *uc++ = ' ';
610 memcpy( d->unicode+index, s, sizeof(TQChar)*len );
611 } else { // normal insert
612 grow( nlen );
613 memmove( d->unicode + index + len, unicode() + index,
614 sizeof(TQChar) * (olen - index) );
615 memcpy( d->unicode + index, s, sizeof(TQChar) * len );
616 }
617 return *this;
618 }
619
620 /*!
621 Removes \a len characters from the string starting at position \a
622 index, and returns a reference to the string.
623
624 If \a index is beyond the length of the string, nothing happens.
625 If \a index is within the string, but \a index + \a len is beyond
626 the end of the string, the string is truncated at position \a
627 index.
628
629 \code
630 SecTQString string( "Montreal" );
631 string.remove( 1, 4 ); // string == "Meal"
632 \endcode
633
634 \sa insert(), replace()
635 */
636
remove(uint index,uint len)637 SecTQString &SecTQString::remove( uint index, uint len )
638 {
639 uint olen = length();
640 if ( index >= olen ) {
641 // range problems
642 } else if ( index + len >= olen ) { // index ok
643 setLength( index );
644 } else if ( len != 0 ) {
645 real_detach();
646 memmove( d->unicode+index, d->unicode+index+len,
647 sizeof(TQChar)*(olen-index-len) );
648 setLength( olen-len );
649 }
650 return *this;
651 }
652
653
654 /*!
655 \overload
656
657 Replaces \a len characters with \a slen characters of TQChar data
658 from \a s, starting at position \a index, and returns a reference
659 to the string.
660
661 \sa insert(), remove()
662 */
663
replace(uint index,uint len,const TQChar * s,uint slen)664 SecTQString &SecTQString::replace( uint index, uint len, const TQChar* s, uint slen )
665 {
666 real_detach();
667 if ( len == slen && index + len <= length() ) {
668 // Optimized common case: replace without size change
669 memcpy( d->unicode+index, s, len * sizeof(TQChar) );
670 } else if ( s >= d->unicode && (uint)(s - d->unicode) < d->maxl ) {
671 // Part of me - take a copy.
672 TQChar *tmp = QT_ALLOC_SECTQCHAR_VEC( slen );
673 memcpy( tmp, s, slen * sizeof(TQChar) );
674 replace( index, len, tmp, slen );
675 QT_DELETE_SECTQCHAR_VEC( tmp );
676 } else {
677 remove( index, len );
678 insert( index, s, slen );
679 }
680 return *this;
681 }
682
683
684 /*!
685 Replaces \a len characters from the string with \a s, starting at
686 position \a index, and returns a reference to the string.
687
688 If \a index is beyond the length of the string, nothing is deleted
689 and \a s is appended at the end of the string. If \a index is
690 valid, but \a index + \a len is beyond the end of the string,
691 the string is truncated at position \a index, then \a s is
692 appended at the end.
693
694 \code
695 TQString string( "Say yes!" );
696 string = string.replace( 4, 3, "NO" );
697 // string == "Say NO!"
698 \endcode
699
700 \sa insert(), remove()
701 */
702
replace(uint index,uint len,const SecTQString & s)703 SecTQString &SecTQString::replace( uint index, uint len, const SecTQString &s )
704 {
705 return replace( index, len, s.unicode(), s.length() );
706 }
707
708
709 /*!
710 Appends \a str to the string and returns a reference to the string.
711 */
operator +=(const SecTQString & str)712 SecTQString& SecTQString::operator+=( const SecTQString &str )
713 {
714 uint len1 = length();
715 uint len2 = str.length();
716 if ( len2 ) {
717 if ( isEmpty() ) {
718 operator=( str );
719 } else {
720 grow( len1+len2 );
721 memcpy( d->unicode+len1, str.unicode(), sizeof(TQChar)*len2 );
722 }
723 } else if ( isNull() && !str.isNull() ) { // ## just for 1.x compat:
724 *this = SecTQString ("");
725 }
726 return *this;
727 }
728
729
730 /*!
731 Returns the string encoded in UTF-8 format.
732
733 See TQTextCodec for more diverse coding/decoding of Unicode strings.
734
735 \sa fromUtf8(), ascii(), latin1(), local8Bit()
736 */
utf8() const737 uchar *SecTQString::utf8() const
738 {
739 int l = length();
740 int rlen = l*3+1;
741 uchar* rstr = (uchar*) ::secmem_malloc (rlen);
742 uchar* cursor = rstr;
743 const TQChar *ch = d->unicode;
744 for (int i=0; i < l; i++) {
745 uint u = ch->unicode();
746 if ( u < 0x80 ) {
747 *cursor++ = (uchar)u;
748 } else {
749 if ( u < 0x0800 ) {
750 *cursor++ = 0xc0 | ((uchar) (u >> 6));
751 } else {
752 if (u >= 0xd800 && u < 0xdc00 && i < l-1) {
753 unsigned short low = ch[1].unicode();
754 if (low >= 0xdc00 && low < 0xe000) {
755 ++ch;
756 ++i;
757 u = (u - 0xd800)*0x400 + (low - 0xdc00) + 0x10000;
758 }
759 }
760 if (u > 0xffff) {
761 // if people are working in utf8, but strings are encoded in eg. latin1, the resulting
762 // name might be invalid utf8. This and the corresponding code in fromUtf8 takes care
763 // we can handle this without loosing information. This can happen with latin filenames
764 // and a utf8 locale under Unix.
765 if (u > 0x10fe00 && u < 0x10ff00) {
766 *cursor++ = (u - 0x10fe00);
767 ++ch;
768 continue;
769 } else {
770 *cursor++ = 0xf0 | ((uchar) (u >> 18));
771 *cursor++ = 0x80 | ( ((uchar) (u >> 12)) & 0x3f);
772 }
773 } else {
774 *cursor++ = 0xe0 | ((uchar) (u >> 12));
775 }
776 *cursor++ = 0x80 | ( ((uchar) (u >> 6)) & 0x3f);
777 }
778 *cursor++ = 0x80 | ((uchar) (u&0x3f));
779 }
780 ++ch;
781 }
782 /* FIXME: secmem_realloc doesn't release extra memory. */
783 *cursor = '\0';
784 return rstr;
785 }
786
787
788 /*!
789 \fn TQChar SecTQString::at( uint ) const
790
791 Returns the character at index \a i, or 0 if \a i is beyond the
792 length of the string.
793
794 \code
795 const SecTQString string( "abcdefgh" );
796 TQChar ch = string.at( 4 );
797 // ch == 'e'
798 \endcode
799
800 If the SecTQString is not const (i.e. const SecTQString) or const& (i.e.
801 const SecTQString &), then the non-const overload of at() will be used
802 instead.
803 */
804
805 /*!
806 \fn TQChar SecTQString::constref(uint i) const
807
808 Returns the TQChar at index \a i by value.
809
810 Equivalent to at(\a i).
811
812 \sa ref()
813 */
814
815 /*!
816 \fn TQChar& SecTQString::ref(uint i)
817
818 Returns the TQChar at index \a i by reference, expanding the string
819 with TQChar::null if necessary. The resulting reference can be
820 assigned to, or otherwise used immediately, but becomes invalid
821 once furher modifications are made to the string.
822
823 \code
824 SecTQString string("ABCDEF");
825 TQChar ch = string.ref( 3 ); // ch == 'D'
826 \endcode
827
828 \sa constref()
829 */
830
831 /*!
832 \fn TQChar SecTQString::operator[]( int ) const
833
834 Returns the character at index \a i, or TQChar::null if \a i is
835 beyond the length of the string.
836
837 If the SecTQString is not const (i.e., const SecTQString) or const\&
838 (i.e., const SecTQString\&), then the non-const overload of operator[]
839 will be used instead.
840 */
841
842 /*!
843 \fn TQCharRef SecTQString::operator[]( int )
844
845 \overload
846
847 The function returns a reference to the character at index \a i.
848 The resulting reference can then be assigned to, or used
849 immediately, but it will become invalid once further modifications
850 are made to the original string.
851
852 If \a i is beyond the length of the string then the string is
853 expanded with TQChar::nulls, so that the TQCharRef references a
854 valid (null) character in the string.
855
856 The TQCharRef internal class can be used much like a constant
857 TQChar, but if you assign to it, you change the original string
858 (which will detach itself because of SecTQString's copy-on-write
859 semantics). You will get compilation errors if you try to use the
860 result as anything but a TQChar.
861 */
862
863 /*!
864 \fn TQCharRef SecTQString::at( uint i )
865
866 \overload
867
868 The function returns a reference to the character at index \a i.
869 The resulting reference can then be assigned to, or used
870 immediately, but it will become invalid once further modifications
871 are made to the original string.
872
873 If \a i is beyond the length of the string then the string is
874 expanded with TQChar::null.
875 */
876
877 /*
878 Internal chunk of code to handle the
879 uncommon cases of at() above.
880 */
subat(uint i)881 void SecTQString::subat( uint i )
882 {
883 uint olen = d->len;
884 if ( i >= olen ) {
885 setLength( i+1 ); // i is index; i+1 is needed length
886 for ( uint j=olen; j<=i; j++ )
887 d->unicode[j] = TQChar::null;
888 } else {
889 // Just be sure to detach
890 real_detach();
891 }
892 }
893
894
895 /*! \internal
896 */
isRightToLeft() const897 bool SecTQString::isRightToLeft() const
898 {
899 int len = length();
900 TQChar *p = d->unicode;
901 while ( len-- ) {
902 switch( (*p).direction () )
903 {
904 case TQChar::DirL:
905 case TQChar::DirLRO:
906 case TQChar::DirLRE:
907 return FALSE;
908 case TQChar::DirR:
909 case TQChar::DirAL:
910 case TQChar::DirRLO:
911 case TQChar::DirRLE:
912 return TRUE;
913 default:
914 break;
915 }
916 ++p;
917 }
918 return FALSE;
919 }
920
921
922 /*!
923 \fn const SecTQString operator+( const SecTQString &s1, const SecTQString &s2 )
924
925 \relates SecTQString
926
927 Returns a string which is the result of concatenating the string
928 \a s1 and the string \a s2.
929
930 Equivalent to \a {s1}.append(\a s2).
931 */
932
933
934 /*! \fn void SecTQString::detach()
935 If the string does not share its data with another SecTQString instance,
936 nothing happens; otherwise the function creates a new, unique copy of
937 this string. This function is called whenever the string is modified. The
938 implicit sharing mechanism is implemented this way.
939 */
940