top level:
[WebKit-https.git] / WebCore / kwq / KWQString.h
1 /*
2  * Copyright (C) 2005 Apple Computer, Inc.  All rights reserved.
3  *
4  * Redistribution and use in source and binary forms, with or without
5  * modification, are permitted provided that the following conditions
6  * are met:
7  * 1. Redistributions of source code must retain the above copyright
8  *    notice, this list of conditions and the following disclaimer.
9  * 2. Redistributions in binary form must reproduce the above copyright
10  *    notice, this list of conditions and the following disclaimer in the
11  *    documentation and/or other materials provided with the distribution.
12  *
13  * THIS SOFTWARE IS PROVIDED BY APPLE COMPUTER, INC. ``AS IS'' AND ANY
14  * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
15  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
16  * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL APPLE COMPUTER, INC. OR
17  * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
18  * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
19  * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
20  * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
21  * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
22  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
23  * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 
24  */
25
26 #ifndef QSTRING_H_
27 #define QSTRING_H_
28
29 #include <unicode/uchar.h>
30 #include <CoreFoundation/CoreFoundation.h>
31 #include "misc/main_thread_malloc.h"
32 #include "KWQCString.h"
33
34 // Make htmltokenizer.cpp happy
35 #define QT_VERSION 300
36
37 class QRegExp;
38
39 #ifdef __OBJC__
40 @class NSString;
41 #else
42 class NSString;
43 #endif
44
45 class QChar {
46 public:
47
48     enum Direction {
49         DirL = 0, DirR, DirEN, DirES, DirET, DirAN, DirCS, DirB, DirS, DirWS, DirON,
50         DirLRE, DirLRO, DirAL, DirRLE, DirRLO, DirPDF, DirNSM, DirBN
51     };
52
53     static const char null = 0; // not a QChar as in Qt (can't have static constructor), but close enough to be compatible in most cases
54
55     QChar();
56     QChar(char);
57     QChar(uchar);
58     QChar(short);
59     QChar(ushort);
60     QChar(int);
61     QChar(uint);
62
63     ushort unicode() const;
64     uchar cell() const;
65     uchar row() const;
66     char latin1() const;
67     bool isNull() const;
68     bool isSpace() const;
69     bool isDigit() const;
70     bool isLetter() const;
71     bool isNumber() const;
72     bool isLetterOrNumber() const;
73     bool isPunct() const;
74     int digitValue() const;
75     QChar lower() const;
76     QChar upper() const;
77     Direction direction() const;
78
79     bool mirrored() const;
80     QChar mirroredChar() const;
81
82     operator char() const;
83
84     friend bool operator==(QChar, QChar);
85     friend bool operator==(QChar, char);
86     friend bool operator==(char, QChar);
87
88     friend bool operator!=(QChar, QChar);
89     friend bool operator!=(QChar, char);
90     friend bool operator!=(char, QChar);
91
92     friend bool operator>(QChar, QChar);
93     friend bool operator>(QChar, char);
94     friend bool operator>(char, QChar);
95
96     friend bool operator>=(QChar, QChar);
97     friend bool operator>=(QChar, char);
98     friend bool operator>=(char, QChar);
99
100     friend bool operator<(QChar, QChar);
101     friend bool operator<(QChar, char);
102     friend bool operator<(char, QChar);
103
104     friend bool operator<=(QChar, QChar);
105     friend bool operator<=(QChar, char);
106     friend bool operator<=(char, QChar);
107
108 private:
109     UniChar c;
110
111     friend class QString;
112     friend class QConstString;
113 };
114
115 inline QChar::QChar() : c(0)
116 {
117 }
118
119 inline QChar::QChar(char ch) : c((uchar) ch)
120 {
121 }
122
123 inline QChar::QChar(uchar uch) : c(uch)
124 {
125 }
126
127 inline QChar::QChar(short n) : c(n)
128 {
129 }
130
131 inline QChar::QChar(ushort n) : c(n)
132 {
133 }
134
135 inline QChar::QChar(uint n) : c(n)
136 {
137 }
138
139 inline QChar::QChar(int n) : c(n)
140 {
141 }
142
143 inline ushort QChar::unicode() const
144 {
145     return c;
146 }
147
148 inline uchar QChar::cell() const
149 {
150     return c;
151 }
152
153 inline bool QChar::isNull() const
154 {
155     return c == 0;
156 }
157
158 inline bool QChar::isSpace() const
159 {
160     // Use isspace() for basic Latin-1.
161     // This will include newlines, which aren't included in unicode DirWS.
162     return c <= 0x7F ? isspace(c) : direction() == DirWS;
163 }
164
165 inline bool QChar::isDigit() const
166 {
167     // FIXME: If fast enough, we should just call u_isdigit directly.
168     return c <= 0x7F ? isdigit(c) : u_isdigit(c);
169 }
170
171 inline bool QChar::isLetter() const
172 {
173     // FIXME: If fast enough, we should just call u_isalpha directly.
174     return c <= 0x7F ? isalpha(c) : u_isalpha(c);
175 }
176
177 inline bool QChar::isNumber() const
178 {
179     // FIXME: If fast enough, we should just call u_isdigit directly.
180     return c <= 0x7F ? isdigit(c) : u_isdigit(c);
181 }
182
183 inline bool QChar::isLetterOrNumber() const
184 {
185     // FIXME: If fast enough, we should just call u_isalnum directly.
186     return c <= 0x7F ? isalnum(c) : u_isalnum(c);
187 }
188
189 inline bool QChar::isPunct() const
190 {
191     return u_ispunct(c);
192 }
193
194 inline int QChar::digitValue() const
195 {
196     // FIXME: If fast enough, we should just call u_charDigitValue directly.
197     return c <= '9' ? c - '0' : u_charDigitValue(c);
198 }
199
200 inline QChar QChar::lower() const
201 {
202     // FIXME: If fast enough, we should just call u_tolower directly.
203     return c <= 0x7F ? tolower(c) : u_tolower(c);
204 }
205
206 inline QChar QChar::upper() const
207 {
208     // FIXME: If fast enough, we should just call u_toupper directly.
209     return c <= 0x7F ? toupper(c) : u_toupper(c);
210 }
211
212 inline QChar::Direction QChar::direction() const
213 {
214 #if BUILDING_ON_PANTHER
215     // Panther gets the direction of the hyphen wrong.
216     // It returns "ET" (European Terminator) when it should return "ES" (European Separator).
217     if (c == '-')
218         return DirES;
219 #endif
220     return static_cast<Direction>(u_charDirection(c));
221 }
222
223 inline bool QChar::mirrored() const
224 {
225     return u_isMirrored(c);
226 }
227
228 inline QChar QChar::mirroredChar() const
229 {
230     return QChar(static_cast<uint>(u_charMirror(c)));
231 }
232
233 inline uchar QChar::row() const
234 {
235     return c >> 8;
236 }
237
238 inline char QChar::latin1() const
239 {
240     return c > 0xff ? 0 : c;
241 }
242
243 inline QChar::operator char() const
244 {
245     return c > 0xff ? 0 : c;
246 }
247
248 inline bool operator==(QChar qc1, QChar qc2)
249 {
250     return qc1.c == qc2.c;
251 }
252
253 inline bool operator==(QChar qc, char ch)
254 {
255     return qc.c == (uchar) ch;
256 }
257
258 inline bool operator==(char ch, QChar qc)
259 {
260     return (uchar) ch == qc.c;
261 }
262
263 inline bool operator!=(QChar qc1, QChar qc2)
264 {
265     return qc1.c != qc2.c;
266 }
267
268 inline bool operator!=(QChar qc, char ch)
269 {
270     return qc.c != (uchar) ch;
271 }
272
273 inline bool operator!=(char ch, QChar qc)
274 {
275     return (uchar) ch != qc.c;
276 }
277
278 inline bool operator>=(QChar qc1, QChar qc2)
279 {
280     return qc1.c >= qc2.c;
281 }
282
283 inline bool operator>=(QChar qc, char ch)
284 {
285     return qc.c >= (uchar) ch;
286 }
287
288 inline bool operator>=(char ch, QChar qc)
289 {
290     return (uchar) ch >= qc.c;
291 }
292
293 inline bool operator>(QChar qc1, QChar qc2)
294 {
295     return qc1.c > qc2.c;
296 }
297
298 inline bool operator>(QChar qc, char ch)
299 {
300     return qc.c > (uchar) ch;
301 }
302
303 inline bool operator>(char ch, QChar qc)
304 {
305     return (uchar) ch > qc.c;
306 }
307
308 inline bool operator<=(QChar qc1, QChar qc2)
309 {
310     return qc1.c <= qc2.c;
311 }
312
313 inline bool operator<=(QChar qc, char ch)
314 {
315     return qc.c <= (uchar) ch;
316 }
317
318 inline bool operator<=(char ch, QChar qc)
319 {
320     return (uchar) ch <= qc.c;
321 }
322
323 inline bool operator<(QChar qc1, QChar qc2)
324 {
325     return qc1.c < qc2.c;
326 }
327
328 inline bool operator<(QChar qc, char ch)
329 {
330     return qc.c < (uchar) ch;
331 }
332
333 inline bool operator<(char ch, QChar qc)
334 {
335     return (uchar) ch < qc.c;
336 }
337
338 // Keep this struct to <= 46 bytes, that's what the system will allocate.
339 // Will be rounded up to a multiple of 4, so we're stuck at 44.
340
341 #define QS_INTERNAL_BUFFER_SIZE 20
342 #define QS_INTERNAL_BUFFER_CHARS QS_INTERNAL_BUFFER_SIZE-1
343 #define QS_INTERNAL_BUFFER_UCHARS QS_INTERNAL_BUFFER_SIZE/2
344
345 struct KWQStringData {
346     // Uses shared null data.
347     KWQStringData();
348     void initialize();
349     
350     // No copy.
351     KWQStringData(QChar *u, uint l, uint m);
352     void initialize(QChar *u, uint l, uint m);
353     
354     // Copy bytes.
355     KWQStringData(const QChar *u, uint l);
356     void initialize(const QChar *u, uint l);
357
358     // Copy bytes.
359     KWQStringData(const char *u, uint l);
360     void initialize(const char *u, uint l);
361
362     // Move from destination to source.
363     KWQStringData(KWQStringData &);
364
365     ~KWQStringData();
366
367 #ifdef QSTRING_DEBUG_ALLOCATIONS
368     void* operator new(size_t s);
369     void operator delete(void*p);
370 #else
371     MAIN_THREAD_ALLOCATED;
372 #endif
373
374     inline void ref() { refCount++; }
375     inline void deref() { if (--refCount == 0 && _isHeapAllocated) delete this; }
376         
377     char *ascii();
378     char *makeAscii();
379     void increaseAsciiSize(uint size);
380
381     QChar *unicode();
382     QChar *makeUnicode();    
383     void increaseUnicodeSize(uint size);
384     
385     bool isUnicodeInternal() const { return (char *)_unicode == _internalBuffer; }
386     bool isAsciiInternal() const { return _ascii == _internalBuffer; }
387
388     uint refCount;
389     uint _length;
390     mutable QChar *_unicode;
391     mutable char *_ascii;
392     uint _maxUnicode:30;
393     uint _isUnicodeValid:1;
394     uint _isHeapAllocated:1;    // Fragile, but the only way we can be sure the instance was created with 'new'.
395     uint _maxAscii:31;
396     uint _isAsciiValid:1;
397     
398     char _internalBuffer[QS_INTERNAL_BUFFER_SIZE]; // Pad out to a (((size + 1) & ~15) + 14) size
399
400 private:
401     KWQStringData(const KWQStringData &);
402     KWQStringData &operator=(const KWQStringData &);
403 };
404
405 #define QSTRING_NULL QString()
406
407 class QString {
408 public:
409     static const char * const null; // not a QString as in Qt (can't have static constructor), but close enough to be compatible in most cases
410
411     QString();
412     QString(QChar);
413     QString(const QByteArray &);
414     QString(const QChar *, uint);
415     QString(const char *);
416     QString(const char *, int len);
417     
418     QString(const QString &);
419     QString &operator=(const QString &);
420
421     ~QString();
422
423     static QString fromLatin1(const char *);
424     static QString fromLatin1(const char *, int len);
425     static QString fromUtf8(const char *);
426     static QString fromUtf8(const char *, int len);
427     static QString fromCFString(CFStringRef);
428     static QString fromNSString(NSString *);
429     
430     QString &operator=(char);
431     QString &operator=(QChar);
432     QString &operator=(const char *);
433     QString &operator=(const QCString &);
434
435     uint length() const;
436
437     const QChar *unicode() const;
438     const QChar *stableUnicode();
439     const char *latin1() const;
440     const char *ascii() const;
441     bool isAllASCII() const;
442     bool isAllLatin1() const;
443     bool hasFastLatin1() const;
444     void copyLatin1(char *buffer, uint position = 0, uint length = 0xffffffff) const;
445     QCString utf8() const { int length; return utf8(length); }
446     QCString utf8(int &length) const;
447     QCString local8Bit() const;
448
449     bool isNull() const;
450     bool isEmpty() const;
451
452     QChar at(uint) const;
453
454     int compare(const QString &) const;
455     int compare(const char *) const;
456
457     bool startsWith(const QString &) const;
458     bool startsWith(const char *) const;
459     bool startsWith(const char *, bool caseSensitive) const;
460
461     int find(char, int index = 0) const;
462     int find(QChar, int index = 0) const;
463     int find(const char *, int index = 0, bool cs = true) const;
464     int find(const QString &, int index = 0, bool cs = true) const;
465     int find(const QRegExp &, int index = 0) const;
466
467     int findRev(char, int index = -1) const;
468     int findRev(const QString& str, int index, bool cs = true) const;
469     int findRev(const char *, int index = -1) const;
470
471     int contains(char) const;
472     int contains(const char *, bool cs = true) const;
473     int contains(const QString &, bool cs = true) const;
474     int contains(QChar c, bool cs = true) const;
475
476     bool endsWith(const QString &) const;
477
478     // NOTE: toXXXXX integer functions only support base 10 and base 16
479     // NOTE: toShort, toUShort, toULong, and toDouble are NOT used but are kept
480     // for completeness
481     short toShort(bool *ok=NULL, int base=10) const;
482     // NOTE: ok and base NOT used for toUShort
483     ushort toUShort(bool *ok=NULL, int base=10) const;
484     int toInt(bool *ok=NULL, int base=10) const;
485     // NOTE: base NOT used for toUInt
486     uint toUInt(bool *ok=NULL, int base=10) const;
487     long toLong(bool *ok=NULL, int base=10) const;
488     ulong toULong(bool *ok=NULL, int base=10) const;
489     float toFloat(bool *ok=NULL) const;
490     double toDouble(bool *ok=NULL) const;
491
492     static QString number(int);
493     static QString number(uint);
494     static QString number(long);
495     static QString number(ulong);
496     static QString number(double);
497
498     bool findArg(int& pos, int& len) const;
499     
500     QString arg(const QString &, int width=0) const;
501     QString arg(short, int width=0) const;
502     QString arg(ushort, int width=0) const;
503     QString arg(int, int width=0) const;
504     QString arg(uint, int width=0) const;
505     QString arg(long, int width=0) const;
506     QString arg(ulong, int width=0) const;
507     QString arg(double, int width=0) const;
508
509     QString left(uint) const;
510     QString right(uint) const;
511     QString mid(uint, uint len=0xffffffff) const;
512
513     QString copy() const;
514
515     QString lower() const;
516     QString stripWhiteSpace() const;
517     QString simplifyWhiteSpace() const;
518
519     QString &setUnicode(const QChar *, uint);
520     QString &setLatin1(const char *, int len=-1);
521
522     QString &setNum(short);
523     QString &setNum(ushort);
524     QString &setNum(int);
525     QString &setNum(uint);
526     QString &setNum(long);
527     QString &setNum(ulong);
528     QString &setNum(double);
529
530     QString &sprintf(const char *, ...) __attribute__ ((format (printf, 2, 3)));
531
532     QString &append(const QString &);
533     QString &append(QChar);
534     QString &append(char);
535     QString &insert(uint, const QString &);
536     QString &insert(uint, QChar);
537     QString &insert(uint, char);
538     QString &insert(uint index, const char *insertChars, uint insertLength);
539     QString &prepend(const QString &);
540     QString &remove(uint, uint);
541     QString &replace(uint index, uint len, const QString &s);
542     QString &replace(char, const QString &);
543     QString &replace(QChar, const QString &);
544     QString &replace(const QString &, const QString &);
545     QString &replace(const QRegExp &, const QString &);
546     QString &replace(QChar, QChar);
547
548     QString &append(const QChar *, uint length);
549     QString &append(const char *, uint length);
550     QString &insert(uint position, const QChar *, uint length);
551     QString &prepend(const QChar *, uint length);
552     
553     void fill(QChar, int len=-1);
554     void truncate(uint);
555
556     void reserve(uint);
557
558     uint hash() const;
559
560     bool operator!() const;
561
562     const QChar operator[](int) const;
563
564     QString &operator+=(const QString &s) { return append(s); }
565     QString &operator+=(QChar c) { return append(c); }
566     QString &operator+=(char c) { return append(c); }
567
568     CFStringRef getCFString() const;
569     NSString *getNSString() const;
570
571     void setBufferFromCFString(CFStringRef);
572
573 private:
574     // Used by QConstString.
575     QString(KWQStringData *constData, bool /*dummy*/);
576     void detach();
577     void detachAndDiscardCharacters();
578     void detachIfInternal();
579     void detachInternal();
580     void deref();
581     QChar *forceUnicode();
582     void setLength(uint);
583
584     KWQStringData **dataHandle;
585     KWQStringData internalData;
586     
587     static KWQStringData *shared_null;
588     static KWQStringData *makeSharedNull();
589     static KWQStringData **shared_null_handle;
590     static KWQStringData **makeSharedNullHandle();
591
592     friend bool operator==(const QString &, const QString &);
593     friend bool operator==(const QString &, const char *);
594
595     friend class QConstString;
596     friend class QGDict;
597     friend struct KWQStringData;
598 };
599
600 QString operator+(const QString &, const QString &);
601 QString operator+(const QString &, const char *);
602 QString operator+(const QString &, QChar);
603 QString operator+(const QString &, char);
604 QString operator+(const char *, const QString &);
605 QString operator+(QChar, const QString &);
606 QString operator+(char, const QString &);
607
608 inline char *KWQStringData::ascii()
609 {
610     return _isAsciiValid ? _ascii : makeAscii();
611 }
612
613 inline QChar *KWQStringData::unicode()
614 {
615     return _isUnicodeValid ? _unicode : makeUnicode();
616 }
617
618 inline uint QString::length() const
619 {
620     return dataHandle[0]->_length;
621 }
622
623 inline bool QString::isEmpty() const
624 {
625     return dataHandle[0]->_length == 0;
626 }
627
628 inline const char *QString::latin1() const
629 {
630     return dataHandle[0]->ascii();
631 }
632
633 inline const QChar *QString::unicode() const
634 {
635     return dataHandle[0]->unicode();
636 }
637
638 inline CFStringRef QString::getCFString() const
639 {
640     return (CFStringRef)getNSString();
641 }
642
643 inline QString QString::fromLatin1(const char *chs)
644 {
645     return chs;
646 }
647
648 inline QString QString::fromLatin1(const char *chs, int length)
649 {
650     return QString(chs, length);
651 }
652
653 inline const char *QString::ascii() const
654 {
655     return latin1();
656 }
657
658 inline float QString::toFloat(bool *ok) const
659 {
660     return toDouble(ok);
661 }
662
663 inline bool QString::operator!() const
664 {
665     return isNull();
666 }
667
668 inline const QChar QString::operator[](int index) const
669 {
670     return at(index);
671 }
672
673 inline bool operator==(const char *chs, const QString &qs)
674 {
675     return qs == chs;
676 }
677
678 inline bool operator!=(const QString &qs1, const QString &qs2)
679 {
680     return !(qs1 == qs2);
681 }
682
683 inline bool operator!=(const QString &qs, const char *chs)
684 {
685     return !(qs == chs);
686 }
687
688 inline bool operator!=(const char *chs, const QString &qs)
689 {
690     return !(qs == chs);
691 }
692
693 inline bool operator<(const QString &qs1, const QString &qs2)
694 {
695     return qs1.compare(qs2) < 0;
696 }
697
698 inline bool operator<(const QString &qs, const char *chs)
699 {
700     return qs.compare(chs) < 0;
701 }
702
703 inline bool operator<(const char *chs, const QString &qs)
704 {
705     return qs.compare(chs) > 0;
706 }
707
708 inline bool operator<=(const QString &qs1, const QString &qs2)
709 {
710     return qs1.compare(qs2) <= 0;
711 }
712
713 inline bool operator<=(const QString &qs, const char *chs)
714 {
715     return qs.compare(chs) <= 0;
716 }
717
718 inline bool operator<=(const char *chs, const QString &qs)
719 {
720     return qs.compare(chs) >= 0;
721 }
722
723 inline bool operator>(const QString &qs1, const QString &qs2)
724 {
725     return qs1.compare(qs2) > 0;
726 }
727
728 inline bool operator>(const QString &qs, const char *chs)
729 {
730     return qs.compare(chs) > 0;
731 }
732
733 inline bool operator>(const char *chs, const QString &qs)
734 {
735     return qs.compare(chs) < 0;
736 }
737
738 inline bool operator>=(const QString &qs1, const QString &qs2)
739 {
740     return qs1.compare(qs2) >= 0;
741 }
742
743 inline bool operator>=(const QString &qs, const char *chs)
744 {
745     return qs.compare(chs) >= 0;
746 }
747
748 inline bool operator>=(const char *chs, const QString &qs)
749 {
750     return qs.compare(chs) <= 0;
751 }
752
753 class QConstString : private QString {
754 public:
755     QConstString(const QChar *, uint);
756     ~QConstString();
757     const QString &string() const { return *this; }
758 };
759
760 extern const CFDictionaryKeyCallBacks CFDictionaryQStringKeyCallBacks;
761
762 #endif