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