JavaScriptCore:
[WebKit-https.git] / WebCore / platform / DeprecatedString.h
1 /*
2  * Copyright (C) 2005, 2006 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 DeprecatedString_h
27 #define DeprecatedString_h
28
29 #include "DeprecatedCString.h"
30
31 #include <wtf/unicode/Unicode.h>
32
33 #include <ctype.h>
34
35 /* On ARM some versions of GCC don't pack structures by default so sizeof(DeprecatedChar)
36    will end up being != 2 which causes crashes since the code depends on that. */
37 #if COMPILER(GCC) && PLATFORM(ARM)
38 #define PACK_STRUCT __attribute__((packed))
39 #else
40 #define PACK_STRUCT
41 #endif
42
43 #if PLATFORM(CF)
44 typedef const struct __CFString * CFStringRef;
45 #endif
46
47 #if PLATFORM(MAC)
48 #ifdef __OBJC__
49 @class NSString;
50 #else
51 class NSString;
52 #endif
53 #endif
54
55 #if PLATFORM(QT)
56 class QString;
57 #endif
58
59 namespace KJS {
60     class Identifier;
61     class UString;
62 }
63
64 namespace WebCore {
65
66 class RegularExpression;
67
68 class DeprecatedChar {
69 public:
70     DeprecatedChar();
71     DeprecatedChar(char);
72     DeprecatedChar(unsigned char);
73     DeprecatedChar(short);
74     DeprecatedChar(unsigned short);
75     DeprecatedChar(int);
76     DeprecatedChar(unsigned);
77
78     unsigned short unicode() const;
79     char latin1() const;
80     bool isSpace() const;
81     DeprecatedChar lower() const;
82     DeprecatedChar upper() const;
83
84 private:
85     unsigned short c;
86 } PACK_STRUCT;
87
88 inline DeprecatedChar::DeprecatedChar() : c(0)
89 {
90 }
91
92 inline DeprecatedChar::DeprecatedChar(char ch) : c((unsigned char) ch)
93 {
94 }
95
96 inline DeprecatedChar::DeprecatedChar(unsigned char uch) : c(uch)
97 {
98 }
99
100 inline DeprecatedChar::DeprecatedChar(short n) : c(n)
101 {
102 }
103
104 inline DeprecatedChar::DeprecatedChar(unsigned short n) : c(n)
105 {
106 }
107
108 inline DeprecatedChar::DeprecatedChar(unsigned n) : c(n)
109 {
110 }
111
112 inline DeprecatedChar::DeprecatedChar(int n) : c(n)
113 {
114 }
115
116 inline unsigned short DeprecatedChar::unicode() const
117 {
118     return c;
119 }
120
121 inline bool DeprecatedChar::isSpace() const
122 {
123 #if USE(ICU_UNICODE)
124     // Use isspace() for basic Latin-1.
125     // This will include newlines, which aren't included in unicode DirWS.
126     return c <= 0x7F ? isspace(c) : (u_charDirection(c) == U_WHITE_SPACE_NEUTRAL);
127 #elif USE(QT4_UNICODE)
128     return QChar(c).isSpace();
129 #endif
130 }
131
132 inline DeprecatedChar DeprecatedChar::lower() const
133 {
134 #if USE(ICU_UNICODE)
135     // FIXME: If fast enough, we should just call u_tolower directly.
136     return c <= 0x7F ? tolower(c) : u_tolower(c);
137 #elif USE(QT4_UNICODE)
138     return QChar(c).toLower().unicode();
139 #endif
140 }
141
142 inline DeprecatedChar DeprecatedChar::upper() const
143 {
144 #if USE(ICU_UNICODE)
145     // FIXME: If fast enough, we should just call u_toupper directly.
146     return c <= 0x7F ? toupper(c) : u_toupper(c);
147 #elif USE(QT4_UNICODE)
148     return QChar(c).toUpper().unicode();
149 #endif
150 }
151
152 inline char DeprecatedChar::latin1() const
153 {
154     return c > 0xff ? 0 : c;
155 }
156
157 inline bool operator==(DeprecatedChar qc1, DeprecatedChar qc2)
158 {
159     return qc1.unicode() == qc2.unicode();
160 }
161
162 inline bool operator==(DeprecatedChar qc, char ch)
163 {
164     return qc.unicode() == (unsigned char) ch;
165 }
166
167 inline bool operator==(char ch, DeprecatedChar qc)
168 {
169     return (unsigned char) ch == qc.unicode();
170 }
171
172 inline bool operator!=(DeprecatedChar qc1, DeprecatedChar qc2)
173 {
174     return qc1.unicode() != qc2.unicode();
175 }
176
177 inline bool operator!=(DeprecatedChar qc, char ch)
178 {
179     return qc.unicode() != (unsigned char) ch;
180 }
181
182 inline bool operator!=(char ch, DeprecatedChar qc)
183 {
184     return (unsigned char) ch != qc.unicode();
185 }
186
187 // Keep this struct to <= 46 bytes, that's what the system will allocate.
188 // Will be rounded up to a multiple of 4, so we're stuck at 44.
189
190 #define WEBCORE_DS_INTERNAL_BUFFER_SIZE 20
191 #define WEBCORE_DS_INTERNAL_BUFFER_CHARS WEBCORE_DS_INTERNAL_BUFFER_SIZE-1
192 #define WEBCORE_DS_INTERNAL_BUFFER_UCHARS WEBCORE_DS_INTERNAL_BUFFER_SIZE/2
193
194 struct DeprecatedStringData  
195 {
196     // Uses shared null data.
197     DeprecatedStringData();
198     void initialize();
199     
200     // No copy.
201     DeprecatedStringData(DeprecatedChar *u, unsigned l, unsigned m);
202     void initialize(DeprecatedChar *u, unsigned l, unsigned m);
203     
204     // Copy bytes.
205     DeprecatedStringData(const DeprecatedChar *u, unsigned l);
206     void initialize(const DeprecatedChar *u, unsigned l);
207
208     // Copy bytes.
209     DeprecatedStringData(const char *u, unsigned l);
210     void initialize(const char *u, unsigned l);
211
212     // Move from destination to source.
213     DeprecatedStringData(DeprecatedStringData &);
214
215     ~DeprecatedStringData();
216
217 #ifdef WEBCORE_DS_DEBUG_ALLOCATIONS
218     void* operator new(size_t s);
219     void operator delete(void*p);
220 #endif
221
222     inline void ref() { refCount++; }
223     inline void deref() { if (--refCount == 0 && _isHeapAllocated) delete this; }
224         
225     char *ascii();
226     char *makeAscii();
227     void increaseAsciiSize(unsigned size);
228
229     DeprecatedChar *unicode();
230     DeprecatedChar *makeUnicode();    
231     void increaseUnicodeSize(unsigned size);
232     
233     bool isUnicodeInternal() const { return (char *)_unicode == _internalBuffer; }
234     bool isAsciiInternal() const { return _ascii == _internalBuffer; }
235
236     unsigned refCount;
237     unsigned _length;
238     mutable DeprecatedChar *_unicode;
239     mutable char *_ascii;
240
241     unsigned _maxUnicode : 30;
242     bool _isUnicodeValid : 1;
243     bool _isHeapAllocated : 1; // Fragile, but the only way we can be sure the instance was created with 'new'.
244     unsigned _maxAscii : 31;
245     bool _isAsciiValid : 1;
246
247     // _internalBuffer must be at the end - otherwise it breaks on archs that
248     // don't pack structs on byte boundary, like some versions of gcc on ARM
249     char _internalBuffer[WEBCORE_DS_INTERNAL_BUFFER_SIZE]; // Pad out to a (((size + 1) & ~15) + 14) size
250     
251 private:
252     DeprecatedStringData(const DeprecatedStringData &);
253     DeprecatedStringData &operator=(const DeprecatedStringData &);
254 };
255
256 class DeprecatedString;
257
258 bool operator==(const DeprecatedString&, const DeprecatedString&);
259 bool operator==(const DeprecatedString&, const char*);
260
261 class DeprecatedString {
262 public:
263     static const char * const null;
264
265     DeprecatedString();
266     DeprecatedString(DeprecatedChar);
267     DeprecatedString(const DeprecatedChar *, unsigned);
268     DeprecatedString(const char *);
269     DeprecatedString(const char *, int len);
270     DeprecatedString(const KJS::Identifier&);
271     DeprecatedString(const KJS::UString&);
272     
273     DeprecatedString(const DeprecatedString &);
274     DeprecatedString &operator=(const DeprecatedString &);
275
276     ~DeprecatedString();
277
278     operator KJS::Identifier() const;
279     operator KJS::UString() const;
280
281 #if PLATFORM(QT)
282     DeprecatedString(const QString&);
283     operator QString() const;
284 #endif
285
286     static DeprecatedString fromLatin1(const char *);
287     static DeprecatedString fromLatin1(const char *, int len);
288     static DeprecatedString fromUtf8(const char *);
289     static DeprecatedString fromUtf8(const char *, int len);
290 #if PLATFORM(CF)
291     static DeprecatedString fromCFString(CFStringRef);
292 #endif
293 #if PLATFORM(MAC)
294     static DeprecatedString fromNSString(NSString*);
295 #endif
296 #if PLATFORM(SYMBIAN)
297     static DeprecatedString fromDes(const TDesC&);
298     static DeprecatedString fromDes(const TDesC8&);
299 #endif
300     DeprecatedString &operator=(char);
301     DeprecatedString &operator=(DeprecatedChar);
302     DeprecatedString &operator=(const char *);
303     DeprecatedString &operator=(const DeprecatedCString &);
304
305     unsigned length() const;
306
307     const DeprecatedChar *unicode() const;
308     const DeprecatedChar *stableUnicode();
309     const char *latin1() const;
310     const char *ascii() const;
311     bool isAllASCII() const;
312     bool isAllLatin1() const;
313     bool hasFastLatin1() const;
314     void copyLatin1(char *buffer, unsigned position = 0, unsigned length = 0xffffffff) const;
315     DeprecatedCString utf8() const { int length; return utf8(length); }
316     DeprecatedCString utf8(int &length) const;
317
318     bool isNull() const;
319     bool isEmpty() const;
320
321     DeprecatedChar at(unsigned) const;
322
323     int compare(const DeprecatedString &) const;
324     int compare(const char *) const;
325
326     bool startsWith(const DeprecatedString &) const;
327     bool startsWith(const char *) const;
328     bool startsWith(const char *, bool caseSensitive) const;
329
330     int find(char, int index = 0) const;
331     int find(DeprecatedChar, int index = 0) const;
332     int find(const char *, int index = 0, bool cs = true) const;
333     int find(const DeprecatedString &, int index = 0, bool cs = true) const;
334     int find(const RegularExpression &, int index = 0) const;
335
336     int findRev(char, int index = -1) const;
337     int findRev(const DeprecatedString& str, int index, bool cs = true) const;
338     int findRev(const char *, int index = -1) const;
339
340     int contains(char) const;
341     int contains(const char *, bool cs = true) const;
342     int contains(const DeprecatedString &, bool cs = true) const;
343     int contains(DeprecatedChar c, bool cs = true) const;
344
345     bool endsWith(const DeprecatedString &) const;
346
347     short toShort(bool *ok = 0, int base = 10) const;
348     unsigned short toUShort(bool *ok = 0, int base = 10) const;
349     int toInt(bool *ok = 0, int base = 10) const;
350     unsigned toUInt(bool *ok = 0, int base = 10) const;
351     double toDouble(bool *ok = 0) const;
352
353     static DeprecatedString number(int);
354     static DeprecatedString number(unsigned);
355     static DeprecatedString number(long);
356     static DeprecatedString number(unsigned long);
357     static DeprecatedString number(double);
358
359     DeprecatedString left(unsigned) const;
360     DeprecatedString right(unsigned) const;
361     DeprecatedString mid(unsigned, unsigned len=0xffffffff) const;
362
363     DeprecatedString copy() const;
364
365     DeprecatedString lower() const;
366     DeprecatedString stripWhiteSpace() const;
367     DeprecatedString simplifyWhiteSpace() const;
368
369     DeprecatedString &setUnicode(const DeprecatedChar *, unsigned);
370     DeprecatedString &setLatin1(const char *, int len=-1);
371
372     DeprecatedString &setNum(short);
373     DeprecatedString &setNum(unsigned short);
374     DeprecatedString &setNum(int);
375     DeprecatedString &setNum(unsigned);
376     DeprecatedString &setNum(long);
377     DeprecatedString &setNum(unsigned long);
378     DeprecatedString &setNum(double);
379
380     DeprecatedString& format(const char *, ...) 
381 #if __GNUC__
382     __attribute__ ((format (printf, 2, 3)))
383 #endif
384     ;
385
386     DeprecatedString &append(const DeprecatedString &);
387     DeprecatedString &append(DeprecatedChar);
388     DeprecatedString &append(char);
389     DeprecatedString &insert(unsigned, const DeprecatedString &);
390     DeprecatedString &insert(unsigned, DeprecatedChar);
391     DeprecatedString &insert(unsigned, char);
392     DeprecatedString &insert(unsigned index, const char *insertChars, unsigned insertLength);
393     DeprecatedString &prepend(const DeprecatedString &);
394     DeprecatedString &remove(unsigned, unsigned);
395     DeprecatedString &remove(const DeprecatedChar &c) { return replace(DeprecatedString(c), ""); }
396     DeprecatedString &remove(const DeprecatedString &s) { return replace(s, ""); }
397     DeprecatedString &replace(unsigned index, unsigned len, const DeprecatedString &s);
398     DeprecatedString &replace(char, const DeprecatedString &);
399     DeprecatedString &replace(DeprecatedChar, const DeprecatedString &);
400     DeprecatedString &replace(const DeprecatedString &, const DeprecatedString &);
401     DeprecatedString &replace(const RegularExpression &, const DeprecatedString &);
402     DeprecatedString &replace(DeprecatedChar, DeprecatedChar);
403
404     DeprecatedString &append(const DeprecatedChar *, unsigned length);
405     DeprecatedString &append(const char *, unsigned length);
406     DeprecatedString &insert(unsigned position, const DeprecatedChar *, unsigned length);
407     DeprecatedString &prepend(const DeprecatedChar *, unsigned length);
408     
409     void fill(DeprecatedChar, int len=-1);
410     void truncate(unsigned);
411
412     void reserve(unsigned);
413
414     bool operator!() const;
415
416     const DeprecatedChar operator[](int) const;
417
418     DeprecatedString &operator+=(const DeprecatedString &s) { return append(s); }
419     DeprecatedString &operator+=(DeprecatedChar c) { return append(c); }
420     DeprecatedString &operator+=(char c) { return append(c); }
421
422 #if PLATFORM(CF)
423     CFStringRef getCFString() const;
424     void setBufferFromCFString(CFStringRef);
425 #endif
426     
427 #if PLATFORM(MAC)
428     NSString *getNSString() const;
429
430 #ifdef __OBJC__
431     operator NSString*() const { return getNSString(); }
432 #endif
433
434 #endif
435
436 #if PLATFORM(SYMBIAN)
437     TPtrC des() const;
438     TPtrC8 des8() const;
439     void setBufferFromDes(const TDesC&);
440     void setBufferFromDes(const TDesC8&);
441 #endif
442
443 private:
444     // Used by DeprecatedConstString.
445     DeprecatedString(DeprecatedStringData *constData, bool /*dummy*/);
446     void detach();
447     void detachAndDiscardCharacters();
448     void detachIfInternal();
449     void detachInternal();
450     void deref();
451     DeprecatedChar *forceUnicode();
452     void setLength(unsigned);
453
454     DeprecatedStringData **dataHandle;
455     DeprecatedStringData internalData;
456     
457     static DeprecatedStringData *shared_null;
458     static DeprecatedStringData *makeSharedNull();
459     static DeprecatedStringData **shared_null_handle;
460     static DeprecatedStringData **makeSharedNullHandle();
461
462     friend bool operator==(const DeprecatedString &, const DeprecatedString &);
463     friend bool operator==(const DeprecatedString &, const char *);
464
465     friend class DeprecatedConstString;
466     friend class QGDict;
467     friend struct DeprecatedStringData;
468 };
469
470 DeprecatedString operator+(const DeprecatedString &, const DeprecatedString &);
471 DeprecatedString operator+(const DeprecatedString &, const char *);
472 DeprecatedString operator+(const DeprecatedString &, DeprecatedChar);
473 DeprecatedString operator+(const DeprecatedString &, char);
474 DeprecatedString operator+(const char *, const DeprecatedString &);
475 DeprecatedString operator+(DeprecatedChar, const DeprecatedString &);
476 DeprecatedString operator+(char, const DeprecatedString &);
477
478 inline char *DeprecatedStringData::ascii()
479 {
480     return _isAsciiValid ? _ascii : makeAscii();
481 }
482
483 inline DeprecatedChar *DeprecatedStringData::unicode()
484 {
485     return _isUnicodeValid ? _unicode : makeUnicode();
486 }
487
488 inline unsigned DeprecatedString::length() const
489 {
490     return dataHandle[0]->_length;
491 }
492
493 inline bool DeprecatedString::isEmpty() const
494 {
495     return dataHandle[0]->_length == 0;
496 }
497
498 inline const char *DeprecatedString::latin1() const
499 {
500     return dataHandle[0]->ascii();
501 }
502
503 inline const DeprecatedChar *DeprecatedString::unicode() const
504 {
505     return dataHandle[0]->unicode();
506 }
507
508 #if PLATFORM(MAC)
509 #if PLATFORM(CF)
510 inline CFStringRef DeprecatedString::getCFString() const
511 {
512     return (CFStringRef)getNSString();
513 }
514 #endif
515 #endif
516
517 inline DeprecatedString DeprecatedString::fromLatin1(const char *chs)
518 {
519     return chs;
520 }
521
522 inline DeprecatedString DeprecatedString::fromLatin1(const char *chs, int length)
523 {
524     return DeprecatedString(chs, length);
525 }
526
527 inline const char *DeprecatedString::ascii() const
528 {
529     return latin1();
530 }
531
532 inline bool DeprecatedString::operator!() const
533 {
534     return isNull();
535 }
536
537 inline const DeprecatedChar DeprecatedString::operator[](int index) const
538 {
539     return at(index);
540 }
541
542 inline bool operator==(const char *chs, const DeprecatedString &qs)
543 {
544     return qs == chs;
545 }
546
547 inline bool operator!=(const DeprecatedString &qs1, const DeprecatedString &qs2)
548 {
549     return !(qs1 == qs2);
550 }
551
552 inline bool operator!=(const DeprecatedString &qs, const char *chs)
553 {
554     return !(qs == chs);
555 }
556
557 inline bool operator!=(const char *chs, const DeprecatedString &qs)
558 {
559     return !(qs == chs);
560 }
561
562 inline bool operator<(const DeprecatedString &qs1, const DeprecatedString &qs2)
563 {
564     return qs1.compare(qs2) < 0;
565 }
566
567 inline bool operator<(const DeprecatedString &qs, const char *chs)
568 {
569     return qs.compare(chs) < 0;
570 }
571
572 inline bool operator<(const char *chs, const DeprecatedString &qs)
573 {
574     return qs.compare(chs) > 0;
575 }
576
577 inline bool operator<=(const DeprecatedString &qs1, const DeprecatedString &qs2)
578 {
579     return qs1.compare(qs2) <= 0;
580 }
581
582 inline bool operator<=(const DeprecatedString &qs, const char *chs)
583 {
584     return qs.compare(chs) <= 0;
585 }
586
587 inline bool operator<=(const char *chs, const DeprecatedString &qs)
588 {
589     return qs.compare(chs) >= 0;
590 }
591
592 inline bool operator>(const DeprecatedString &qs1, const DeprecatedString &qs2)
593 {
594     return qs1.compare(qs2) > 0;
595 }
596
597 inline bool operator>(const DeprecatedString &qs, const char *chs)
598 {
599     return qs.compare(chs) > 0;
600 }
601
602 inline bool operator>(const char *chs, const DeprecatedString &qs)
603 {
604     return qs.compare(chs) < 0;
605 }
606
607 inline bool operator>=(const DeprecatedString &qs1, const DeprecatedString &qs2)
608 {
609     return qs1.compare(qs2) >= 0;
610 }
611
612 inline bool operator>=(const DeprecatedString &qs, const char *chs)
613 {
614     return qs.compare(chs) >= 0;
615 }
616
617 inline bool operator>=(const char *chs, const DeprecatedString &qs)
618 {
619     return qs.compare(chs) <= 0;
620 }
621
622 class DeprecatedConstString : private DeprecatedString {
623 public:
624     DeprecatedConstString(const DeprecatedChar *, unsigned);
625     ~DeprecatedConstString();
626     const DeprecatedString &string() const { return *this; }
627 };
628
629 }
630
631 #endif