• Skip to content
  • Skip to link menu
Trinity API Reference
  • Trinity API Reference
  • kjs
 

kjs

  • kjs
ustring.cpp
1/*
2 * This file is part of the KDE libraries
3 * Copyright (C) 1999-2000 Harri Porten (porten@kde.org)
4 * Copyright (C) 2003 Apple Computer, Inc.
5 *
6 * This library is free software; you can redistribute it and/or
7 * modify it under the terms of the GNU Library General Public
8 * License as published by the Free Software Foundation; either
9 * version 2 of the License, or (at your option) any later version.
10 *
11 * This library is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14 * Library General Public License for more details.
15 *
16 * You should have received a copy of the GNU Library General Public License
17 * along with this library; see the file COPYING.LIB. If not, write to
18 * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
19 * Boston, MA 02110-1301, USA.
20 *
21 */
22
23#ifdef HAVE_CONFIG_H
24#include <config.h>
25#endif
26
27#include <stdlib.h>
28#include <stdio.h>
29#include <ctype.h>
30#ifdef HAVE_STRING_H
31#include <string.h>
32#endif
33#ifdef HAVE_STRINGS_H
34#include <strings.h>
35#endif
36
37#include "ustring.h"
38#include "operations.h"
39#include "identifier.h"
40#include <math.h>
41#include "dtoa.h"
42
43namespace KJS {
44 extern const double NaN;
45 extern const double Inf;
46}
47
48using namespace KJS;
49
50CString::CString(const char *c)
51{
52 length = strlen(c);
53 data = new char[length+1];
54 memcpy(data, c, length + 1);
55}
56
57CString::CString(const char *c, int len)
58{
59 length = len;
60 data = new char[len+1];
61 memcpy(data, c, len);
62 data[len] = 0;
63}
64
65CString::CString(const CString &b)
66{
67 length = b.length;
68 data = new char[length+1];
69 memcpy(data, b.data, length + 1);
70}
71
72CString::~CString()
73{
74 delete [] data;
75}
76
77CString &CString::append(const CString &t)
78{
79 char *n = new char[length + t.length + 1];
80 if (length)
81 memcpy(n, data, length);
82 if (t.length)
83 memcpy(n+length, t.data, t.length);
84 length += t.length;
85 n[length] = 0;
86
87 delete [] data;
88 data = n;
89
90 return *this;
91}
92
93CString &CString::operator=(const char *c)
94{
95 delete [] data;
96 length = strlen(c);
97 data = new char[length+1];
98 memcpy(data, c, length + 1);
99
100 return *this;
101}
102
103CString &CString::operator=(const CString &str)
104{
105 if (this == &str)
106 return *this;
107
108 delete [] data;
109 length = str.length;
110 if (str.data) {
111 data = new char[length + 1];
112 memcpy(data, str.data, length + 1);
113 }
114 else
115 data = 0;
116
117 return *this;
118}
119
120bool KJS::operator==(const KJS::CString& c1, const KJS::CString& c2)
121{
122 int len = c1.size();
123 return len == c2.size() && (len == 0 || memcmp(c1.c_str(), c2.c_str(), len) == 0);
124}
125
126UChar UChar::null((char)0);
127UString::Rep UString::Rep::null = { 0, 0, 0, 1, 1 };
128UString::Rep UString::Rep::empty = { 0, 0, 0, 1, 1 };
129UString UString::null;
130static const int normalStatBufferSize = 4096;
131static char *statBuffer = 0;
132static int statBufferSize = 0;
133
134UChar UChar::toLower() const
135{
136 // ### properly support unicode tolower
137 if (uc >= 256)
138 return *this;
139
140 // tolower is locale-dependent, don't use it.
141 return static_cast<unsigned char>( ( ( uc >= 'A' ) && ( uc <= 'Z' ) ) ? ( (int)uc + 'a' - 'A' ) : uc );
142}
143
144UChar UChar::toUpper() const
145{
146 if (uc >= 256)
147 return *this;
148
149 // toupper is locale-dependent, don't use it.
150 return static_cast<unsigned char>( ( ( uc >= 'a' ) && ( uc <= 'z' ) ) ? ( (int)uc + 'A' - 'a' ) : uc );
151}
152
153UCharReference& UCharReference::operator=(UChar c)
154{
155 str->detach();
156 if (offset < str->rep->len)
157 *(str->rep->dat + offset) = c;
158 /* TODO: lengthen string ? */
159 return *this;
160}
161
162UChar& UCharReference::ref() const
163{
164 if (offset < str->rep->len)
165 return *(str->rep->dat + offset);
166 else
167 return UChar::null;
168}
169
170// return an uninitialized UChar array of size s
171static inline UChar* allocateChars(int s)
172{
173 // work around default UChar constructor code
174 return reinterpret_cast<UChar*>(new short[s]);
175}
176
177UString::Rep *UString::Rep::create(UChar *d, int l)
178{
179 Rep *r = new Rep;
180 r->dat = d;
181 r->len = l;
182 r->capacity = l;
183 r->rc = 1;
184 r->_hash = 0;
185 return r;
186}
187
188void UString::Rep::destroy()
189{
190 if (capacity == capacityForIdentifier)
191 Identifier::remove(this);
192 delete [] dat;
193 delete this;
194}
195
196// Golden ratio - arbitrary start value to avoid mapping all 0's to all 0's
197// or anything like that.
198const unsigned PHI = 0x9e3779b9U;
199
200// This hash algorithm comes from:
201// http://burtleburtle.net/bob/hash/hashfaq.html
202// http://burtleburtle.net/bob/hash/doobs.html
203unsigned UString::Rep::computeHash(const UChar *s, int length)
204{
205 int prefixLength = length < 8 ? length : 8;
206 int suffixPosition = length < 16 ? 8 : length - 8;
207
208 unsigned h = PHI;
209 h += length;
210 h += (h << 10);
211 h ^= (h << 6);
212
213 for (int i = 0; i < prefixLength; i++) {
214 h += s[i].uc;
215 h += (h << 10);
216 h ^= (h << 6);
217 }
218 for (int i = suffixPosition; i < length; i++){
219 h += s[i].uc;
220 h += (h << 10);
221 h ^= (h << 6);
222 }
223
224 h += (h << 3);
225 h ^= (h >> 11);
226 h += (h << 15);
227
228 if (h == 0)
229 h = 0x80000000;
230
231 return h;
232}
233
234// This hash algorithm comes from:
235// http://burtleburtle.net/bob/hash/hashfaq.html
236// http://burtleburtle.net/bob/hash/doobs.html
237unsigned UString::Rep::computeHash(const char *s)
238{
239 int length = strlen(s);
240 int prefixLength = length < 8 ? length : 8;
241 int suffixPosition = length < 16 ? 8 : length - 8;
242
243 unsigned h = PHI;
244 h += length;
245 h += (h << 10);
246 h ^= (h << 6);
247
248 for (int i = 0; i < prefixLength; i++) {
249 h += (unsigned char)s[i];
250 h += (h << 10);
251 h ^= (h << 6);
252 }
253 for (int i = suffixPosition; i < length; i++) {
254 h += (unsigned char)s[i];
255 h += (h << 10);
256 h ^= (h << 6);
257 }
258
259 h += (h << 3);
260 h ^= (h >> 11);
261 h += (h << 15);
262
263 if (h == 0)
264 h = 0x80000000;
265
266 return h;
267}
268
269UString::UString()
270{
271 null.rep = &Rep::null;
272 attach(&Rep::null);
273}
274
275UString::UString(char c)
276{
277 UChar *d = allocateChars(1);
278 d[0] = c;
279 rep = Rep::create(d, 1);
280}
281
282UString::UString(const char *c)
283{
284 if (!c) {
285 attach(&Rep::null);
286 return;
287 }
288 int length = strlen(c);
289 if (length == 0) {
290 attach(&Rep::empty);
291 return;
292 }
293 UChar *d = new UChar[length];
294 for (int i = 0; i < length; i++)
295 d[i].uc = (unsigned char)c[i];
296 rep = Rep::create(d, length);
297}
298
299UString::UString(const UChar *c, int length)
300{
301 if (length == 0) {
302 attach(&Rep::empty);
303 return;
304 }
305 UChar *d = allocateChars(length);
306 memcpy(d, c, length * sizeof(UChar));
307 rep = Rep::create(d, length);
308}
309
310UString::UString(UChar *c, int length, bool copy)
311{
312 if (length == 0) {
313 attach(&Rep::empty);
314 return;
315 }
316 UChar *d;
317 if (copy) {
318 d = allocateChars(length);
319 memcpy(d, c, length * sizeof(UChar));
320 } else
321 d = c;
322 rep = Rep::create(d, length);
323}
324
325UString::UString(const UString &a, const UString &b)
326{
327 int aSize = a.size();
328 int bSize = b.size();
329 int length = aSize + bSize;
330 if (length == 0) {
331 attach(&Rep::empty);
332 return;
333 }
334 UChar *d = allocateChars(length);
335 memcpy(d, a.data(), aSize * sizeof(UChar));
336 memcpy(d + aSize, b.data(), bSize * sizeof(UChar));
337 rep = Rep::create(d, length);
338}
339
340UString UString::from(int i)
341{
342 return from((long)i);
343}
344
345UString UString::from(unsigned int u)
346{
347 UChar buf[20];
348 UChar *end = buf + 20;
349 UChar *p = end;
350
351 if (u == 0) {
352 *--p = '0';
353 } else {
354 while (u) {
355 *--p = (unsigned short)((u % 10) + '0');
356 u /= 10;
357 }
358 }
359
360 return UString(p, end - p);
361}
362
363UString UString::from(long l)
364{
365 UChar buf[20];
366 UChar *end = buf + 20;
367 UChar *p = end;
368
369 if (l == 0) {
370 *--p = '0';
371 } else {
372 bool negative = false;
373 if (l < 0) {
374 negative = true;
375 l = -l;
376 }
377 while (l) {
378 *--p = (unsigned short)((l % 10) + '0');
379 l /= 10;
380 }
381 if (negative) {
382 *--p = '-';
383 }
384 }
385
386 return UString(p, end - p);
387}
388
389UString UString::from(double d)
390{
391 char buf[80];
392 int decimalPoint;
393 int sign;
394
395 char *result = kjs_dtoa(d, 0, 0, &decimalPoint, &sign, NULL);
396 int length = strlen(result);
397
398 int i = 0;
399 if (sign) {
400 buf[i++] = '-';
401 }
402
403 if (decimalPoint <= 0 && decimalPoint > -6) {
404 buf[i++] = '0';
405 buf[i++] = '.';
406 for (int j = decimalPoint; j < 0; j++) {
407 buf[i++] = '0';
408 }
409 strcpy(buf + i, result);
410 } else if (decimalPoint <= 21 && decimalPoint > 0) {
411 if (length <= decimalPoint) {
412 strcpy(buf + i, result);
413 i += length;
414 for (int j = 0; j < decimalPoint - length; j++) {
415 buf[i++] = '0';
416 }
417 buf[i] = '\0';
418 } else {
419 strncpy(buf + i, result, decimalPoint);
420 i += decimalPoint;
421 buf[i++] = '.';
422 strcpy(buf + i, result + decimalPoint);
423 }
424 } else if (result[0] < '0' || result[0] > '9') {
425 strcpy(buf + i, result);
426 } else {
427 buf[i++] = result[0];
428 if (length > 1) {
429 buf[i++] = '.';
430 strcpy(buf + i, result + 1);
431 i += length - 1;
432 }
433
434 buf[i++] = 'e';
435 buf[i++] = (decimalPoint >= 0) ? '+' : '-';
436 // decimalPoint can't be more than 3 digits decimal given the
437 // nature of float representation
438 int exponential = decimalPoint - 1;
439 if (exponential < 0) {
440 exponential = exponential * -1;
441 }
442 if (exponential >= 100) {
443 buf[i++] = '0' + exponential / 100;
444 }
445 if (exponential >= 10) {
446 buf[i++] = '0' + (exponential % 100) / 10;
447 }
448 buf[i++] = '0' + exponential % 10;
449 buf[i++] = '\0';
450 }
451
452 kjs_freedtoa(result);
453
454 return UString(buf);
455}
456
457UString &UString::append(const UString &t)
458{
459 int l = size();
460 int tLen = t.size();
461 int newLen = l + tLen;
462 if (rep->rc == 1 && newLen <= rep->capacity) {
463 memcpy(rep->dat+l, t.data(), tLen * sizeof(UChar));
464 rep->len = newLen;
465 rep->_hash = 0;
466 return *this;
467 }
468
469 int newCapacity = (newLen * 3 + 1) / 2;
470 UChar *n = allocateChars(newCapacity);
471 memcpy(n, data(), l * sizeof(UChar));
472 memcpy(n+l, t.data(), tLen * sizeof(UChar));
473 release();
474 rep = Rep::create(n, newLen);
475 rep->capacity = newCapacity;
476
477 return *this;
478}
479
480CString UString::cstring() const
481{
482 return ascii();
483}
484
485char *UString::ascii() const
486{
487 // Never make the buffer smaller than normalStatBufferSize.
488 // Thus we almost never need to reallocate.
489 int length = size();
490 int neededSize = length + 1;
491 if (neededSize < normalStatBufferSize) {
492 neededSize = normalStatBufferSize;
493 }
494 if (neededSize != statBufferSize) {
495 delete [] statBuffer;
496 statBuffer = new char [neededSize];
497 statBufferSize = neededSize;
498 }
499
500 const UChar *p = data();
501 char *q = statBuffer;
502 const UChar *limit = p + length;
503 while (p != limit) {
504 *q = p->uc;
505 ++p;
506 ++q;
507 }
508 *q = '\0';
509
510 return statBuffer;
511}
512
513#ifdef KJS_DEBUG_MEM
514void UString::globalClear()
515{
516 delete [] statBuffer;
517 statBuffer = 0;
518 statBufferSize = 0;
519}
520#endif
521
522UString &UString::operator=(const char *c)
523{
524 int l = c ? strlen(c) : 0;
525 UChar *d;
526 if (rep->rc == 1 && l <= rep->capacity) {
527 d = rep->dat;
528 rep->_hash = 0;
529 } else {
530 release();
531 d = allocateChars(l);
532 rep = Rep::create(d, l);
533 }
534 for (int i = 0; i < l; i++)
535 d[i].uc = (unsigned char)c[i];
536
537 return *this;
538}
539
540UString &UString::operator=(const UString &str)
541{
542 str.rep->ref();
543 release();
544 rep = str.rep;
545
546 return *this;
547}
548
549bool UString::is8Bit() const
550{
551 const UChar *u = data();
552 const UChar *limit = u + size();
553 while (u < limit) {
554 if (u->uc > 0xFF)
555 return false;
556 ++u;
557 }
558
559 return true;
560}
561
562UChar UString::operator[](int pos) const
563{
564 if (pos >= size())
565 return UChar::null;
566
567 return ((UChar *)data())[pos];
568}
569
570UCharReference UString::operator[](int pos)
571{
572 /* TODO: boundary check */
573 return UCharReference(this, pos);
574}
575
576static int skipInfString(const char *start)
577{
578 const char *c = start;
579 if (*c == '+' || *c == '-')
580 c++;
581 if (!strncmp(c,"Infinity",8))
582 return c+8-start;
583
584 while (*c >= '0' && *c <= '9')
585 c++;
586 const char * const at_dot = c;
587 if (*c == '.')
588 c++;
589 while (*c >= '0' && *c <= '9')
590 c++;
591
592 // don't accept a single dot as a number
593 if (c - at_dot == 1 && *at_dot == '.')
594 return at_dot-start;
595
596 if (*c != 'e')
597 return c-start;
598
599 c++;
600 if (*c == '+' || *c == '-')
601 c++;
602 while (*c >= '0' && *c <= '9')
603 c++;
604 return c-start;
605}
606
607double UString::toDouble(bool tolerateTrailingJunk, bool tolerateEmptyString) const
608{
609 double d;
610 double sign = 1;
611
612 // FIXME: If tolerateTrailingJunk is true, then we want to tolerate non-8-bit junk
613 // after the number, so is8Bit is too strict a check.
614 if (!is8Bit())
615 return NaN;
616
617 const char *c = ascii();
618
619 // skip leading white space
620 while (isspace(*c))
621 c++;
622
623 // empty string ?
624 if (*c == '\0')
625 return tolerateEmptyString ? 0.0 : NaN;
626
627 if (*c == '-') {
628 sign = -1;
629 c++;
630 }
631 else if (*c == '+') {
632 sign = 1;
633 c++;
634 }
635
636 // hex number ?
637 if (*c == '0' && (*(c+1) == 'x' || *(c+1) == 'X')) {
638 c++;
639 d = 0.0;
640 while (*(++c)) {
641 if (*c >= '0' && *c <= '9')
642 d = d * 16.0 + *c - '0';
643 else if ((*c >= 'A' && *c <= 'F') || (*c >= 'a' && *c <= 'f'))
644 d = d * 16.0 + (*c & 0xdf) - 'A' + 10.0;
645 else
646 break;
647 }
648 } else {
649 // regular number ?
650 char *end;
651 d = kjs_strtod(c, &end);
652 if ((d != 0.0 || end != c) && d != HUGE_VAL && d != -HUGE_VAL) {
653 c = end;
654 } else {
655 // infinity ?
656
657 int count = skipInfString(c);
658 if (count == 0)
659 return NaN;
660 d = Inf;
661 c += count;
662 }
663 }
664
665 // allow trailing white space
666 while (isspace(*c))
667 c++;
668 // don't allow anything after - unless tolerant=true
669 if (!tolerateTrailingJunk && *c != '\0')
670 return NaN;
671
672 return d*sign;
673}
674
675double UString::toDouble(bool tolerateTrailingJunk) const
676{
677 return toDouble(tolerateTrailingJunk, true);
678}
679
680double UString::toDouble() const
681{
682 return toDouble(false, true);
683}
684
685unsigned long UString::toULong(bool *ok, bool tolerateEmptyString) const
686{
687 double d = toDouble(false, tolerateEmptyString);
688 bool b = true;
689
690 if (isNaN(d) || d != static_cast<unsigned long>(d)) {
691 b = false;
692 d = 0;
693 }
694
695 if (ok)
696 *ok = b;
697
698 return static_cast<unsigned long>(d);
699}
700
701unsigned long UString::toULong(bool *ok) const
702{
703 return toULong(ok, true);
704}
705
706UString UString::toLower() const
707{
708 UString u = *this;
709 for (int i = 0; i < size(); i++)
710 u[i] = u[i].toLower();
711 return u;
712}
713
714UString UString::toUpper() const
715{
716 UString u = *this;
717 for (int i = 0; i < size(); i++)
718 u[i] = u[i].toUpper();
719 return u;
720}
721
722unsigned int UString::toUInt32(bool *ok) const
723{
724 double d = toDouble();
725 bool b = true;
726
727 if (isNaN(d) || d != static_cast<unsigned>(d)) {
728 b = false;
729 d = 0;
730 }
731
732 if (ok)
733 *ok = b;
734
735 return static_cast<unsigned>(d);
736}
737
738unsigned int UString::toStrictUInt32(bool *ok) const
739{
740 if (ok)
741 *ok = false;
742
743 // Empty string is not OK.
744 int len = rep->len;
745 if (len == 0)
746 return 0;
747 const UChar *p = rep->dat;
748 unsigned short c = p->unicode();
749
750 // If the first digit is 0, only 0 itself is OK.
751 if (c == '0') {
752 if (len == 1 && ok)
753 *ok = true;
754 return 0;
755 }
756
757 // Convert to UInt32, checking for overflow.
758 unsigned int i = 0;
759 while (1) {
760 // Process character, turning it into a digit.
761 if (c < '0' || c > '9')
762 return 0;
763 const unsigned d = c - '0';
764
765 // Multiply by 10, checking for overflow out of 32 bits.
766 if (i > 0xFFFFFFFFU / 10)
767 return 0;
768 i *= 10;
769
770 // Add in the digit, checking for overflow out of 32 bits.
771 const unsigned max = 0xFFFFFFFFU - d;
772 if (i > max)
773 return 0;
774 i += d;
775
776 // Handle end of string.
777 if (--len == 0) {
778 if (ok)
779 *ok = true;
780 return i;
781 }
782
783 // Get next character.
784 c = (++p)->unicode();
785 }
786}
787
788// Rule from ECMA 15.2 about what an array index is.
789// Must exactly match string form of an unsigned integer, and be less than 2^32 - 1.
790unsigned UString::toArrayIndex(bool *ok) const
791{
792 unsigned i = toStrictUInt32(ok);
793 if (i >= 0xFFFFFFFFU && ok)
794 *ok = false;
795 return i;
796}
797
798int UString::find(const UString &f, int pos) const
799{
800 int sz = size();
801 int fsz = f.size();
802 if (sz < fsz)
803 return -1;
804 if (pos < 0)
805 pos = 0;
806 if (fsz == 0)
807 return pos;
808 const UChar *end = data() + sz - fsz;
809 long fsizeminusone = (fsz - 1) * sizeof(UChar);
810 const UChar *fdata = f.data();
811 unsigned short fchar = fdata->uc;
812 ++fdata;
813 for (const UChar *c = data() + pos; c <= end; c++)
814 if (c->uc == fchar && !memcmp(c + 1, fdata, fsizeminusone))
815 return (c-data());
816
817 return -1;
818}
819
820int UString::find(UChar ch, int pos) const
821{
822 if (pos < 0)
823 pos = 0;
824 const UChar *end = data() + size();
825 for (const UChar *c = data() + pos; c < end; c++)
826 if (*c == ch)
827 return (c-data());
828
829 return -1;
830}
831
832int UString::rfind(const UString &f, int pos) const
833{
834 int sz = size();
835 int fsz = f.size();
836 if (sz < fsz)
837 return -1;
838 if (pos < 0)
839 pos = 0;
840 if (pos > sz - fsz)
841 pos = sz - fsz;
842 if (fsz == 0)
843 return pos;
844 long fsizeminusone = (fsz - 1) * sizeof(UChar);
845 const UChar *fdata = f.data();
846 for (const UChar *c = data() + pos; c >= data(); c--) {
847 if (*c == *fdata && !memcmp(c + 1, fdata + 1, fsizeminusone))
848 return (c-data());
849 }
850
851 return -1;
852}
853
854int UString::rfind(UChar ch, int pos) const
855{
856 if (isEmpty())
857 return -1;
858 if (pos + 1 >= size())
859 pos = size() - 1;
860 for (const UChar *c = data() + pos; c >= data(); c--) {
861 if (*c == ch)
862 return (c-data());
863 }
864
865 return -1;
866}
867
868UString UString::substr(int pos, int len) const
869{
870 if (pos < 0)
871 pos = 0;
872 else if (pos >= (int) size())
873 pos = size();
874 if (len < 0)
875 len = size();
876 if (pos + len >= (int) size())
877 len = size() - pos;
878
879 UChar *tmp = allocateChars(len);
880 memcpy(tmp, data()+pos, len * sizeof(UChar));
881 UString result(tmp, len);
882 delete [] tmp;
883
884 return result;
885}
886
887void UString::attach(Rep *r)
888{
889 rep = r;
890 rep->ref();
891}
892
893void UString::detach()
894{
895 if (rep->rc > 1) {
896 int l = size();
897 UChar *n = allocateChars(l);
898 memcpy(n, data(), l * sizeof(UChar));
899 release();
900 rep = Rep::create(n, l);
901 }
902}
903
904void UString::release()
905{
906 rep->deref();
907}
908
909bool KJS::operator==(const UString& s1, const UString& s2)
910{
911 if (s1.rep->len != s2.rep->len)
912 return false;
913
914#ifndef NDEBUG
915 if ((s1.isNull() && s2.isEmpty() && !s2.isNull()) ||
916 (s2.isNull() && s1.isEmpty() && !s1.isNull()))
917 fprintf(stderr,
918 "KJS warning: comparison between empty and null string\n");
919#endif
920
921 return (memcmp(s1.rep->dat, s2.rep->dat,
922 s1.rep->len * sizeof(UChar)) == 0);
923}
924
925bool KJS::operator==(const UString& s1, const char *s2)
926{
927 if (s2 == 0) {
928 return s1.isEmpty();
929 }
930
931 const UChar *u = s1.data();
932 const UChar *uend = u + s1.size();
933 while (u != uend && *s2) {
934 if (u->uc != (unsigned char)*s2)
935 return false;
936 s2++;
937 u++;
938 }
939
940 return u == uend && *s2 == 0;
941}
942
943bool KJS::operator<(const UString& s1, const UString& s2)
944{
945 const int l1 = s1.size();
946 const int l2 = s2.size();
947 const int lmin = l1 < l2 ? l1 : l2;
948 const UChar *c1 = s1.data();
949 const UChar *c2 = s2.data();
950 int l = 0;
951 while (l < lmin && *c1 == *c2) {
952 c1++;
953 c2++;
954 l++;
955 }
956 if (l < lmin)
957 return (c1->uc < c2->uc);
958
959 return (l1 < l2);
960}
961
962int KJS::compare(const UString& s1, const UString& s2)
963{
964 const int l1 = s1.size();
965 const int l2 = s2.size();
966 const int lmin = l1 < l2 ? l1 : l2;
967 const UChar *c1 = s1.data();
968 const UChar *c2 = s2.data();
969 int l = 0;
970 while (l < lmin && *c1 == *c2) {
971 c1++;
972 c2++;
973 l++;
974 }
975 if (l < lmin)
976 return (c1->uc > c2->uc) ? 1 : -1;
977
978 if (l1 == l2) {
979 return 0;
980 }
981 return (l1 < l2) ? 1 : -1;
982}
KJS::CString
8 bit char based string class
Definition: ustring.h:165
KJS::UCharReference
Dynamic reference to a string character.
Definition: ustring.h:119
KJS::UCharReference::operator=
UCharReference & operator=(UChar c)
Set the referenced character to c.
Definition: ustring.cpp:153
KJS::UString
Unicode string class.
Definition: ustring.h:189
KJS::UString::toULong
unsigned long toULong(bool *ok, bool tolerateEmptyString) const
Attempts an conversion to an unsigned long integer.
Definition: ustring.cpp:685
KJS::UString::toArrayIndex
unsigned toArrayIndex(bool *ok=0) const
Attempts an conversion to an array index.
Definition: ustring.cpp:790
KJS::UString::is8Bit
bool is8Bit() const
Use this if you want to make sure that this string is a plain ASCII string.
Definition: ustring.cpp:549
KJS::UString::toLower
UString toLower() const
Returns this string converted to lower case characters.
Definition: ustring.cpp:706
KJS::UString::toDouble
double toDouble(bool tolerateTrailingJunk, bool tolerateEmptyString) const
Attempts an conversion to a number.
Definition: ustring.cpp:607
KJS::UString::find
int find(const UString &f, int pos=0) const
Definition: ustring.cpp:798
KJS::UString::isEmpty
bool isEmpty() const
Definition: ustring.h:347
KJS::UString::rfind
int rfind(const UString &f, int pos) const
Definition: ustring.cpp:832
KJS::UString::UString
UString()
Constructs a null string.
Definition: ustring.cpp:269
KJS::UString::operator=
UString & operator=(const char *c)
Assignment operator.
Definition: ustring.cpp:522
KJS::UString::ascii
char * ascii() const
Convert the Unicode string to plain ASCII chars chopping of any higher bytes.
Definition: ustring.cpp:485
KJS::UString::isNull
bool isNull() const
Definition: ustring.h:343
KJS::UString::size
int size() const
Definition: ustring.h:359
KJS::UString::null
static UString null
Static instance of a null string.
Definition: ustring.h:428
KJS::UString::substr
UString substr(int pos=0, int len=-1) const
Definition: ustring.cpp:868
KJS::UString::cstring
CString cstring() const
Definition: ustring.cpp:480
KJS::UString::toUpper
UString toUpper() const
Returns this string converted to upper case characters.
Definition: ustring.cpp:714
KJS::UString::data
const UChar * data() const
Definition: ustring.h:339
KJS::UString::operator[]
UChar operator[](int pos) const
Const character at specified position.
Definition: ustring.cpp:562
KJS::UString::append
UString & append(const UString &)
Append another string.
Definition: ustring.cpp:457
KJS::UString::from
static UString from(int i)
Constructs a string from an int.
Definition: ustring.cpp:340
KJS::UChar
Unicode character.
Definition: ustring.h:51
KJS::UChar::null
static UChar null
A static instance of UChar(0).
Definition: ustring.h:94
KJS::UChar::toLower
UChar toLower() const
Definition: ustring.cpp:134
KJS::UChar::toUpper
UChar toUpper() const
Definition: ustring.cpp:144
KJS::UChar::unicode
unsigned short unicode() const
Definition: ustring.h:81

kjs

Skip menu "kjs"
  • Main Page
  • Class Hierarchy
  • Alphabetical List
  • Class List
  • File List
  • Class Members
  • Related Pages

kjs

Skip menu "kjs"
  • arts
  • dcop
  • dnssd
  • interfaces
  •   kspeech
  •     interface
  •     library
  •   tdetexteditor
  • kate
  • kded
  • kdoctools
  • kimgio
  • kjs
  • libtdemid
  • libtdescreensaver
  • tdeabc
  • tdecmshell
  • tdecore
  • tdefx
  • tdehtml
  • tdeinit
  • tdeio
  •   bookmarks
  •   httpfilter
  •   kpasswdserver
  •   kssl
  •   tdefile
  •   tdeio
  •   tdeioexec
  • tdeioslave
  •   http
  • tdemdi
  •   tdemdi
  • tdenewstuff
  • tdeparts
  • tdeprint
  • tderandr
  • tderesources
  • tdespell2
  • tdesu
  • tdeui
  • tdeunittest
  • tdeutils
  • tdewallet
Generated for kjs by doxygen 1.9.4
This website is maintained by Timothy Pearson.