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

kjs

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

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
  •     interface
  •     library
  •   kspeech
  •   ktexteditor
  • kabc
  • kate
  • kcmshell
  • kdecore
  • kded
  • kdefx
  • kdeprint
  • kdesu
  • kdeui
  • kdoctools
  • khtml
  • kimgio
  • kinit
  • kio
  •   bookmarks
  •   httpfilter
  •   kfile
  •   kio
  •   kioexec
  •   kpasswdserver
  •   kssl
  • kioslave
  •   http
  • kjs
  • kmdi
  •   kmdi
  • knewstuff
  • kparts
  • krandr
  • kresources
  • kspell2
  • kunittest
  • kutils
  • kwallet
  • libkmid
  • libkscreensaver
Generated for kjs by doxygen 1.9.1
This website is maintained by Timothy Pearson.
KDE® and the K Desktop Environment® logo are registered trademarks of KDE e.V. |