• 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 
43 namespace KJS {
44  extern const double NaN;
45  extern const double Inf;
46 }
47 
48 using namespace KJS;
49 
50 CString::CString(const char *c)
51 {
52  length = strlen(c);
53  data = new char[length+1];
54  memcpy(data, c, length + 1);
55 }
56 
57 CString::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 
65 CString::CString(const CString &b)
66 {
67  length = b.length;
68  data = new char[length+1];
69  memcpy(data, b.data, length + 1);
70 }
71 
72 CString::~CString()
73 {
74  delete [] data;
75 }
76 
77 CString &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 
93 CString &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 
103 CString &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 
120 bool 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 
126 UChar UChar::null((char)0);
127 UString::Rep UString::Rep::null = { 0, 0, 0, 1, 1 };
128 UString::Rep UString::Rep::empty = { 0, 0, 0, 1, 1 };
129 UString UString::null;
130 static const int normalStatBufferSize = 4096;
131 static char *statBuffer = 0;
132 static int statBufferSize = 0;
133 
134 UChar 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 
144 UChar 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 
153 UCharReference& 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 
162 UChar& 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
171 static inline UChar* allocateChars(int s)
172 {
173  // work around default UChar constructor code
174  return reinterpret_cast<UChar*>(new short[s]);
175 }
176 
177 UString::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 
188 void 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.
198 const 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
203 unsigned 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
237 unsigned 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 
269 UString::UString()
270 {
271  null.rep = &Rep::null;
272  attach(&Rep::null);
273 }
274 
275 UString::UString(char c)
276 {
277  UChar *d = allocateChars(1);
278  d[0] = c;
279  rep = Rep::create(d, 1);
280 }
281 
282 UString::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 
299 UString::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 
310 UString::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 
325 UString::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 
340 UString UString::from(int i)
341 {
342  return from((long)i);
343 }
344 
345 UString 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 
363 UString 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 
389 UString 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 
457 UString &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 
480 CString UString::cstring() const
481 {
482  return ascii();
483 }
484 
485 char *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
514 void UString::globalClear()
515 {
516  delete [] statBuffer;
517  statBuffer = 0;
518  statBufferSize = 0;
519 }
520 #endif
521 
522 UString &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 
540 UString &UString::operator=(const UString &str)
541 {
542  str.rep->ref();
543  release();
544  rep = str.rep;
545 
546  return *this;
547 }
548 
549 bool 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 
562 UChar UString::operator[](int pos) const
563 {
564  if (pos >= size())
565  return UChar::null;
566 
567  return ((UChar *)data())[pos];
568 }
569 
570 UCharReference UString::operator[](int pos)
571 {
572  /* TODO: boundary check */
573  return UCharReference(this, pos);
574 }
575 
576 static 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 
607 double 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 
675 double UString::toDouble(bool tolerateTrailingJunk) const
676 {
677  return toDouble(tolerateTrailingJunk, true);
678 }
679 
680 double UString::toDouble() const
681 {
682  return toDouble(false, true);
683 }
684 
685 unsigned 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 
701 unsigned long UString::toULong(bool *ok) const
702 {
703  return toULong(ok, true);
704 }
705 
706 UString 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 
714 UString 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 
722 unsigned 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 
738 unsigned 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.
790 unsigned UString::toArrayIndex(bool *ok) const
791 {
792  unsigned i = toStrictUInt32(ok);
793  if (i >= 0xFFFFFFFFU && ok)
794  *ok = false;
795  return i;
796 }
797 
798 int 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 
820 int 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 
832 int 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 
854 int 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 
868 UString 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 
887 void UString::attach(Rep *r)
888 {
889  rep = r;
890  rep->ref();
891 }
892 
893 void 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 
904 void UString::release()
905 {
906  rep->deref();
907 }
908 
909 bool 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 
925 bool 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 
943 bool 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 
962 int 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::UString::substr
UString substr(int pos=0, int len=-1) const
Definition: ustring.cpp:868
KJS::UCharReference::operator=
UCharReference & operator=(UChar c)
Set the referenced character to c.
Definition: ustring.cpp:153
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::from
static UString from(int i)
Constructs a string from an int.
Definition: ustring.cpp:340
KJS::UChar::unicode
unsigned short unicode() const
Definition: ustring.h:81
KJS::UString::toLower
UString toLower() const
Returns this string converted to lower case characters.
Definition: ustring.cpp:706
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::find
int find(const UString &f, int pos=0) const
Definition: ustring.cpp:798
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::CString
8 bit char based string class
Definition: ustring.h:165
KJS::UChar::null
static UChar null
A static instance of UChar(0).
Definition: ustring.h:94
KJS::UString::toDouble
double toDouble(bool tolerateTrailingJunk, bool tolerateEmptyString) const
Attempts an conversion to a number.
Definition: ustring.cpp:607
KJS::UString::UString
UString()
Constructs a null string.
Definition: ustring.cpp:269
KJS::UString
Unicode string class.
Definition: ustring.h:189
KJS::UChar
Unicode character.
Definition: ustring.h:51
KJS::UCharReference
Dynamic reference to a string character.
Definition: ustring.h:119
KJS::UString::isNull
bool isNull() const
Definition: ustring.h:343
KJS
Definition: array_instance.h:27
KJS::UString::operator=
UString & operator=(const char *c)
Assignment operator.
Definition: ustring.cpp:522
KJS::UChar::toUpper
UChar toUpper() const
Definition: ustring.cpp:144
KJS::UChar::toLower
UChar toLower() const
Definition: ustring.cpp:134
KJS::UString::rfind
int rfind(const UString &f, int pos) const
Definition: ustring.cpp:832
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::isEmpty
bool isEmpty() const
Definition: ustring.h:347
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::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::data
const UChar * data() const
Definition: ustring.h:339

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
  •     tdecore
  • tdeabc
  • tdecmshell
  • tdecore
  • tdefx
  • tdehtml
  • tdeinit
  • tdeio
  •   bookmarks
  •   httpfilter
  •   kpasswdserver
  •   kssl
  • tdeioslave
  •   http
  •   tdefile
  •   tdeio
  •   tdeioexec
  • tdemdi
  •   tdemdi
  • tdenewstuff
  • tdeparts
  • tdeprint
  • tderandr
  • tderesources
  • tdespell2
  • tdesu
  • tdeui
  • tdeunittest
  • tdeutils
  • tdewallet
Generated for kjs by doxygen 1.8.8
This website is maintained by Timothy Pearson.