00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
#ifdef HAVE_CONFIG_H
00025
#include <config.h>
00026
#endif
00027
00028
#include <stdlib.h>
00029
#include <stdio.h>
00030
#include <ctype.h>
00031
#ifdef HAVE_STRING_H
00032
#include <string.h>
00033
#endif
00034
#ifdef HAVE_STRINGS_H
00035
#include <strings.h>
00036
#endif
00037
00038
#include "ustring.h"
00039
#include "operations.h"
00040
#include "identifier.h"
00041
#include <math.h>
00042
#include "dtoa.h"
00043
00044
namespace KJS {
00045
extern const double NaN;
00046
extern const double Inf;
00047 }
00048
00049
using namespace KJS;
00050
00051 CString::CString(
const char *c)
00052 {
00053 length = strlen(c);
00054 data =
new char[length+1];
00055 memcpy(data, c, length + 1);
00056 }
00057
00058 CString::CString(
const char *c,
int len)
00059 {
00060 length = len;
00061 data =
new char[len+1];
00062 memcpy(data, c, len);
00063 data[len] = 0;
00064 }
00065
00066 CString::CString(
const CString &b)
00067 {
00068 length = b.
length;
00069 data =
new char[length+1];
00070 memcpy(data, b.
data, length + 1);
00071 }
00072
00073 CString::~CString()
00074 {
00075
delete [] data;
00076 }
00077
00078
CString &CString::append(
const CString &t)
00079 {
00080
char *n =
new char[length + t.
length + 1];
00081
if (length)
00082 memcpy(n, data, length);
00083
if (t.
length)
00084 memcpy(n+length, t.
data, t.
length);
00085 length += t.
length;
00086 n[length] = 0;
00087
00088
delete [] data;
00089 data = n;
00090
00091
return *
this;
00092 }
00093
00094
CString &CString::operator=(
const char *c)
00095 {
00096
delete [] data;
00097 length = strlen(c);
00098 data =
new char[length+1];
00099 memcpy(data, c, length + 1);
00100
00101
return *
this;
00102 }
00103
00104
CString &CString::operator=(
const CString &str)
00105 {
00106
if (
this == &str)
00107
return *
this;
00108
00109
delete [] data;
00110 length = str.
length;
00111 data =
new char[length + 1];
00112 memcpy(data, str.
data, length + 1);
00113
00114
return *
this;
00115 }
00116
00117
bool KJS::operator==(
const KJS::CString& c1,
const KJS::CString& c2)
00118 {
00119
int len = c1.
size();
00120
return len == c2.
size() && (len == 0 || memcmp(c1.
c_str(), c2.
c_str(), len) == 0);
00121 }
00122
00123
UChar UChar::null((
char)0);
00124 UString::Rep UString::Rep::null = { 0, 0, 0, 1, 1 };
00125 UString::Rep UString::Rep::empty = { 0, 0, 0, 1, 1 };
00126 UString UString::null;
00127
static const int normalStatBufferSize = 4096;
00128
static char *statBuffer = 0;
00129
static int statBufferSize = 0;
00130
00131 UChar UChar::toLower()
const
00132
{
00133
00134
if (uc >= 256 || islower(uc))
00135
return *
this;
00136
00137
return (
unsigned char)tolower(uc);
00138 }
00139
00140 UChar UChar::toUpper()
const
00141
{
00142
if (uc >= 256 || isupper(uc))
00143
return *
this;
00144
00145
return (
unsigned char)toupper(uc);
00146 }
00147
00148 UCharReference&
UCharReference::operator=(
UChar c)
00149 {
00150 str->
detach();
00151
if (offset < str->
rep->len)
00152 *(str->
rep->dat + offset) = c;
00153
00154
return *
this;
00155 }
00156
00157
UChar& UCharReference::ref()
const
00158
{
00159
if (offset < str->
rep->len)
00160
return *(str->
rep->dat + offset);
00161
else
00162
return UChar::null;
00163 }
00164
00165
00166
static inline UChar* allocateChars(
int s)
00167 {
00168
00169
return reinterpret_cast<UChar*>(
new short[s]);
00170 }
00171
00172 UString::Rep *UString::Rep::create(
UChar *d,
int l)
00173 {
00174 Rep *r =
new Rep;
00175 r->dat = d;
00176 r->len = l;
00177 r->capacity = l;
00178 r->rc = 1;
00179 r->_hash = 0;
00180
return r;
00181 }
00182
00183
void UString::Rep::destroy()
00184 {
00185
if (capacity == capacityForIdentifier)
00186 Identifier::remove(
this);
00187
delete [] dat;
00188
delete this;
00189 }
00190
00191
00192
00193
const unsigned PHI = 0x9e3779b9U;
00194
00195
00196
00197
00198
unsigned UString::Rep::computeHash(
const UChar *s,
int length)
00199 {
00200
int prefixLength = length < 8 ? length : 8;
00201
int suffixPosition = length < 16 ? 8 : length - 8;
00202
00203
unsigned h = PHI;
00204 h += length;
00205 h += (h << 10);
00206 h ^= (h << 6);
00207
00208
for (
int i = 0; i < prefixLength; i++) {
00209 h += s[i].
uc;
00210 h += (h << 10);
00211 h ^= (h << 6);
00212 }
00213
for (
int i = suffixPosition; i < length; i++){
00214 h += s[i].
uc;
00215 h += (h << 10);
00216 h ^= (h << 6);
00217 }
00218
00219 h += (h << 3);
00220 h ^= (h >> 11);
00221 h += (h << 15);
00222
00223
if (h == 0)
00224 h = 0x80000000;
00225
00226
return h;
00227 }
00228
00229
00230
00231
00232
unsigned UString::Rep::computeHash(
const char *s)
00233 {
00234
int length = strlen(s);
00235
int prefixLength = length < 8 ? length : 8;
00236
int suffixPosition = length < 16 ? 8 : length - 8;
00237
00238
unsigned h = PHI;
00239 h += length;
00240 h += (h << 10);
00241 h ^= (h << 6);
00242
00243
for (
int i = 0; i < prefixLength; i++) {
00244 h += (
unsigned char)s[i];
00245 h += (h << 10);
00246 h ^= (h << 6);
00247 }
00248
for (
int i = suffixPosition; i < length; i++) {
00249 h += (
unsigned char)s[i];
00250 h += (h << 10);
00251 h ^= (h << 6);
00252 }
00253
00254 h += (h << 3);
00255 h ^= (h >> 11);
00256 h += (h << 15);
00257
00258
if (h == 0)
00259 h = 0x80000000;
00260
00261
return h;
00262 }
00263
00264 UString::UString()
00265 {
00266
null.
rep = &Rep::null;
00267 attach(&Rep::null);
00268 }
00269
00270 UString::UString(
char c)
00271 {
00272
UChar *d = allocateChars(1);
00273 d[0] = c;
00274 rep = Rep::create(d, 1);
00275 }
00276
00277 UString::UString(
const char *c)
00278 {
00279
if (!c) {
00280 attach(&Rep::null);
00281
return;
00282 }
00283
int length = strlen(c);
00284
if (length == 0) {
00285 attach(&Rep::empty);
00286
return;
00287 }
00288
UChar *d =
new UChar[length];
00289
for (
int i = 0; i < length; i++)
00290 d[i].
uc = c[i];
00291 rep = Rep::create(d, length);
00292 }
00293
00294 UString::UString(
const UChar *c,
int length)
00295 {
00296
if (length == 0) {
00297 attach(&Rep::empty);
00298
return;
00299 }
00300
UChar *d = allocateChars(length);
00301 memcpy(d, c, length *
sizeof(
UChar));
00302 rep = Rep::create(d, length);
00303 }
00304
00305 UString::UString(
UChar *c,
int length,
bool copy)
00306 {
00307
if (length == 0) {
00308 attach(&Rep::empty);
00309
return;
00310 }
00311
UChar *d;
00312
if (copy) {
00313 d = allocateChars(length);
00314 memcpy(d, c, length *
sizeof(
UChar));
00315 }
else
00316 d = c;
00317 rep = Rep::create(d, length);
00318 }
00319
00320 UString::UString(
const UString &a,
const UString &b)
00321 {
00322
int aSize = a.
size();
00323
int bSize = b.
size();
00324
int length = aSize + bSize;
00325
if (length == 0) {
00326 attach(&Rep::empty);
00327
return;
00328 }
00329
UChar *d = allocateChars(length);
00330 memcpy(d, a.
data(), aSize *
sizeof(
UChar));
00331 memcpy(d + aSize, b.
data(), bSize *
sizeof(
UChar));
00332 rep = Rep::create(d, length);
00333 }
00334
00335 UString UString::from(
int i)
00336 {
00337
return from((
long)i);
00338 }
00339
00340 UString UString::from(
unsigned int u)
00341 {
00342
UChar buf[20];
00343
UChar *end = buf + 20;
00344
UChar *p = end;
00345
00346
if (u == 0) {
00347 *--p =
'0';
00348 }
else {
00349
while (u) {
00350 *--p = (
unsigned short)((u % 10) +
'0');
00351 u /= 10;
00352 }
00353 }
00354
00355
return UString(p, end - p);
00356 }
00357
00358 UString UString::from(
long l)
00359 {
00360
UChar buf[20];
00361
UChar *end = buf + 20;
00362
UChar *p = end;
00363
00364
if (l == 0) {
00365 *--p =
'0';
00366 }
else {
00367
bool negative =
false;
00368
if (l < 0) {
00369 negative =
true;
00370 l = -l;
00371 }
00372
while (l) {
00373 *--p = (
unsigned short)((l % 10) +
'0');
00374 l /= 10;
00375 }
00376
if (negative) {
00377 *--p =
'-';
00378 }
00379 }
00380
00381
return UString(p, end - p);
00382 }
00383
00384 UString UString::from(
double d)
00385 {
00386
char buf[80];
00387
int decimalPoint;
00388
int sign;
00389
00390
char *result = kjs_dtoa(d, 0, 0, &decimalPoint, &sign, NULL);
00391
int length = strlen(result);
00392
00393
int i = 0;
00394
if (sign) {
00395 buf[i++] =
'-';
00396 }
00397
00398
if (decimalPoint <= 0 && decimalPoint > -6) {
00399 buf[i++] =
'0';
00400 buf[i++] =
'.';
00401
for (
int j = decimalPoint; j < 0; j++) {
00402 buf[i++] =
'0';
00403 }
00404 strcpy(buf + i, result);
00405 }
else if (decimalPoint <= 21 && decimalPoint > 0) {
00406
if (length <= decimalPoint) {
00407 strcpy(buf + i, result);
00408 i += length;
00409
for (
int j = 0; j < decimalPoint - length; j++) {
00410 buf[i++] =
'0';
00411 }
00412 buf[i] =
'\0';
00413 }
else {
00414 strncpy(buf + i, result, decimalPoint);
00415 i += decimalPoint;
00416 buf[i++] =
'.';
00417 strcpy(buf + i, result + decimalPoint);
00418 }
00419 }
else if (result[0] <
'0' || result[0] >
'9') {
00420 strcpy(buf + i, result);
00421 }
else {
00422 buf[i++] = result[0];
00423
if (length > 1) {
00424 buf[i++] =
'.';
00425 strcpy(buf + i, result + 1);
00426 i += length - 1;
00427 }
00428
00429 buf[i++] =
'e';
00430 buf[i++] = (decimalPoint >= 0) ?
'+' :
'-';
00431
00432
00433
int exponential = decimalPoint - 1;
00434
if (exponential < 0) {
00435 exponential = exponential * -1;
00436 }
00437
if (exponential >= 100) {
00438 buf[i++] =
'0' + exponential / 100;
00439 }
00440
if (exponential >= 10) {
00441 buf[i++] =
'0' + (exponential % 100) / 10;
00442 }
00443 buf[i++] =
'0' + exponential % 10;
00444 buf[i++] =
'\0';
00445 }
00446
00447 kjs_freedtoa(result);
00448
00449
return UString(buf);
00450 }
00451
00452 UString &
UString::append(
const UString &t)
00453 {
00454
int l =
size();
00455
int tLen = t.
size();
00456
int newLen = l + tLen;
00457
if (rep->rc == 1 && newLen <= rep->capacity) {
00458 memcpy(rep->dat+l, t.
data(), tLen *
sizeof(
UChar));
00459 rep->len = newLen;
00460 rep->_hash = 0;
00461
return *
this;
00462 }
00463
00464
int newCapacity = (newLen * 3 + 1) / 2;
00465
UChar *n = allocateChars(newCapacity);
00466 memcpy(n,
data(), l *
sizeof(
UChar));
00467 memcpy(n+l, t.
data(), tLen *
sizeof(UChar));
00468 release();
00469 rep = Rep::create(n, newLen);
00470 rep->capacity = newCapacity;
00471
00472
return *
this;
00473 }
00474
00475 CString UString::cstring()
const
00476
{
00477
return ascii();
00478 }
00479
00480 char *
UString::ascii()
const
00481
{
00482
00483
00484
int length =
size();
00485
int neededSize = length + 1;
00486
if (neededSize < normalStatBufferSize) {
00487 neededSize = normalStatBufferSize;
00488 }
00489
if (neededSize != statBufferSize) {
00490
delete [] statBuffer;
00491 statBuffer =
new char [neededSize];
00492 statBufferSize = neededSize;
00493 }
00494
00495
const UChar *p =
data();
00496
char *q = statBuffer;
00497
const UChar *limit = p + length;
00498
while (p != limit) {
00499 *q = p->
uc;
00500 ++p;
00501 ++q;
00502 }
00503 *q =
'\0';
00504
00505
return statBuffer;
00506 }
00507
00508
#ifdef KJS_DEBUG_MEM
00509
void UString::globalClear()
00510 {
00511
delete [] statBuffer;
00512 statBuffer = 0;
00513 statBufferSize = 0;
00514 }
00515
#endif
00516
00517 UString &
UString::operator=(
const char *c)
00518 {
00519
int l = c ? strlen(c) : 0;
00520
UChar *d;
00521
if (rep->rc == 1 && l <= rep->capacity) {
00522 d = rep->dat;
00523 rep->_hash = 0;
00524 }
else {
00525 release();
00526 d = allocateChars(l);
00527 rep = Rep::create(d, l);
00528 }
00529
for (
int i = 0; i < l; i++)
00530 d[i].
uc = c[i];
00531
00532
return *
this;
00533 }
00534
00535
UString &
UString::operator=(
const UString &str)
00536 {
00537 str.
rep->ref();
00538 release();
00539 rep = str.
rep;
00540
00541
return *
this;
00542 }
00543
00544 bool UString::is8Bit()
const
00545
{
00546
const UChar *u =
data();
00547
const UChar *limit = u +
size();
00548
while (u < limit) {
00549
if (u->
uc > 0xFF)
00550
return false;
00551 ++u;
00552 }
00553
00554
return true;
00555 }
00556
00557 UChar UString::operator[](
int pos)
const
00558
{
00559
if (pos >=
size())
00560
return UChar::null;
00561
00562
return ((
UChar *)
data())[pos];
00563 }
00564
00565 UCharReference UString::operator[](
int pos)
00566 {
00567
00568
return UCharReference(
this, pos);
00569 }
00570
00571
static int skipInfString(
const char *start)
00572 {
00573
const char *c = start;
00574
if (*c ==
'+' || *c ==
'-')
00575 c++;
00576
if (!strncmp(c,
"Infinity",8))
00577
return c+8-start;
00578
00579
while (*c >=
'0' && *c <=
'9')
00580 c++;
00581
if (*c ==
'.')
00582 c++;
00583
while (*c >=
'0' && *c <=
'9')
00584 c++;
00585
00586
if (*c !=
'e')
00587
return c-start;
00588
00589 c++;
00590
if (*c ==
'+' || *c ==
'-')
00591 c++;
00592
while (*c >=
'0' && *c <=
'9')
00593 c++;
00594
return c-start;
00595 }
00596
00597 double UString::toDouble(
bool tolerateTrailingJunk,
bool tolerateEmptyString)
const
00598
{
00599
double d;
00600
double sign = 1;
00601
00602
00603
00604
if (!
is8Bit())
00605
return NaN;
00606
00607
const char *c =
ascii();
00608
00609
00610
while (isspace(*c))
00611 c++;
00612
00613
00614
if (*c ==
'\0')
00615
return tolerateEmptyString ? 0.0 : NaN;
00616
00617
if (*c ==
'-') {
00618 sign = -1;
00619 c++;
00620 }
00621
else if (*c ==
'+') {
00622 sign = 1;
00623 c++;
00624 }
00625
00626
00627
if (*c ==
'0' && (*(c+1) ==
'x' || *(c+1) ==
'X')) {
00628 c++;
00629 d = 0.0;
00630
while (*(++c)) {
00631
if (*c >=
'0' && *c <=
'9')
00632 d = d * 16.0 + *c -
'0';
00633
else if ((*c >=
'A' && *c <= 'F') || (*c >=
'a' && *c <=
'f'))
00634 d = d * 16.0 + (*c & 0xdf) -
'A' + 10.0;
00635
else
00636
break;
00637 }
00638 }
else {
00639
00640
char *end;
00641 d = kjs_strtod(c, &end);
00642
if ((d != 0.0 || end != c) && d != HUGE_VAL && d != -HUGE_VAL) {
00643 c = end;
00644 }
else {
00645
00646
00647
int count = skipInfString(c);
00648
if (count == 0)
00649
return NaN;
00650 d = Inf;
00651 c += count;
00652 }
00653 }
00654
00655
00656
while (isspace(*c))
00657 c++;
00658
00659
if (!tolerateTrailingJunk && *c !=
'\0')
00660
return NaN;
00661
00662
return d*sign;
00663 }
00664
00665
double UString::toDouble(
bool tolerateTrailingJunk)
const
00666
{
00667
return toDouble(tolerateTrailingJunk,
true);
00668 }
00669
00670
double UString::toDouble()
const
00671
{
00672
return toDouble(
false,
true);
00673 }
00674
00675 unsigned long UString::toULong(
bool *ok,
bool tolerateEmptyString)
const
00676
{
00677
double d =
toDouble(
false, tolerateEmptyString);
00678
bool b =
true;
00679
00680
if (isNaN(d) || d != static_cast<unsigned long>(d)) {
00681 b =
false;
00682 d = 0;
00683 }
00684
00685
if (ok)
00686 *ok = b;
00687
00688
return static_cast<unsigned long>(d);
00689 }
00690
00691
unsigned long UString::toULong(
bool *ok)
const
00692
{
00693
return toULong(ok,
true);
00694 }
00695
00696 UString UString::toLower()
const
00697
{
00698
UString u = *
this;
00699
for (
int i = 0; i <
size(); i++)
00700 u[i] = u[i].
toLower();
00701
return u;
00702 }
00703
00704 UString UString::toUpper()
const
00705
{
00706
UString u = *
this;
00707
for (
int i = 0; i <
size(); i++)
00708 u[i] = u[i].
toUpper();
00709
return u;
00710 }
00711
00712
unsigned int UString::toUInt32(
bool *ok)
const
00713
{
00714
double d =
toDouble();
00715
bool b =
true;
00716
00717
if (isNaN(d) || d != static_cast<unsigned>(d)) {
00718 b =
false;
00719 d = 0;
00720 }
00721
00722
if (ok)
00723 *ok = b;
00724
00725
return static_cast<unsigned>(d);
00726 }
00727
00728
unsigned int UString::toStrictUInt32(
bool *ok)
const
00729
{
00730
if (ok)
00731 *ok =
false;
00732
00733
00734
int len = rep->len;
00735
if (len == 0)
00736
return 0;
00737
const UChar *p = rep->dat;
00738
unsigned short c = p->
unicode();
00739
00740
00741
if (c ==
'0') {
00742
if (len == 1 && ok)
00743 *ok =
true;
00744
return 0;
00745 }
00746
00747
00748
unsigned int i = 0;
00749
while (1) {
00750
00751
if (c < '0' || c >
'9')
00752
return 0;
00753
const unsigned d = c -
'0';
00754
00755
00756
if (i > 0xFFFFFFFFU / 10)
00757
return 0;
00758 i *= 10;
00759
00760
00761
const unsigned max = 0xFFFFFFFFU - d;
00762
if (i > max)
00763
return 0;
00764 i += d;
00765
00766
00767
if (--len == 0) {
00768
if (ok)
00769 *ok =
true;
00770
return i;
00771 }
00772
00773
00774 c = (++p)->unicode();
00775 }
00776 }
00777
00778
00779
00780 unsigned UString::toArrayIndex(
bool *ok)
const
00781
{
00782
unsigned i = toStrictUInt32(ok);
00783
if (i >= 0xFFFFFFFFU && ok)
00784 *ok =
false;
00785
return i;
00786 }
00787
00788 int UString::find(
const UString &f,
int pos)
const
00789
{
00790
int sz =
size();
00791
int fsz = f.
size();
00792
if (sz < fsz)
00793
return -1;
00794
if (pos < 0)
00795 pos = 0;
00796
if (fsz == 0)
00797
return pos;
00798
const UChar *end =
data() + sz - fsz;
00799
long fsizeminusone = (fsz - 1) *
sizeof(
UChar);
00800
const UChar *fdata = f.
data();
00801
for (
const UChar *c =
data() + pos; c <= end; c++)
00802
if (*c == *fdata && !memcmp(c + 1, fdata + 1, fsizeminusone))
00803
return (c-
data());
00804
00805
return -1;
00806 }
00807
00808
int UString::find(
UChar ch,
int pos)
const
00809
{
00810
if (pos < 0)
00811 pos = 0;
00812
const UChar *end =
data() +
size();
00813
for (
const UChar *c =
data() + pos; c < end; c++)
00814
if (*c == ch)
00815
return (c-
data());
00816
00817
return -1;
00818 }
00819
00820 int UString::rfind(
const UString &f,
int pos)
const
00821
{
00822
int sz =
size();
00823
int fsz = f.
size();
00824
if (sz < fsz)
00825
return -1;
00826
if (pos < 0)
00827 pos = 0;
00828
if (pos > sz - fsz)
00829 pos = sz - fsz;
00830
if (fsz == 0)
00831
return pos;
00832
long fsizeminusone = (fsz - 1) *
sizeof(
UChar);
00833
const UChar *fdata = f.
data();
00834
for (
const UChar *c =
data() + pos; c >=
data(); c--) {
00835
if (*c == *fdata && !memcmp(c + 1, fdata + 1, fsizeminusone))
00836
return (c-
data());
00837 }
00838
00839
return -1;
00840 }
00841
00842
int UString::rfind(
UChar ch,
int pos)
const
00843
{
00844
if (
isEmpty())
00845
return -1;
00846
if (pos + 1 >=
size())
00847 pos =
size() - 1;
00848
for (
const UChar *c =
data() + pos; c >=
data(); c--) {
00849
if (*c == ch)
00850
return (c-
data());
00851 }
00852
00853
return -1;
00854 }
00855
00856 UString UString::substr(
int pos,
int len)
const
00857
{
00858
if (pos < 0)
00859 pos = 0;
00860
else if (pos >= (
int)
size())
00861 pos =
size();
00862
if (len < 0)
00863 len =
size();
00864
if (pos + len >= (
int)
size())
00865 len =
size() - pos;
00866
00867
UChar *tmp = allocateChars(len);
00868 memcpy(tmp,
data()+pos, len *
sizeof(
UChar));
00869
UString result(tmp, len);
00870
delete [] tmp;
00871
00872
return result;
00873 }
00874
00875
void UString::attach(Rep *r)
00876 {
00877 rep = r;
00878 rep->ref();
00879 }
00880
00881
void UString::detach()
00882 {
00883
if (rep->rc > 1) {
00884
int l =
size();
00885
UChar *n = allocateChars(l);
00886 memcpy(n,
data(), l *
sizeof(
UChar));
00887 release();
00888 rep = Rep::create(n, l);
00889 }
00890 }
00891
00892
void UString::release()
00893 {
00894 rep->deref();
00895 }
00896
00897
bool KJS::operator==(
const UString& s1,
const UString& s2)
00898 {
00899
if (s1.
rep->len != s2.
rep->len)
00900
return false;
00901
00902
return (memcmp(s1.
rep->dat, s2.
rep->dat,
00903 s1.
rep->len *
sizeof(
UChar)) == 0);
00904 }
00905
00906
bool KJS::operator==(
const UString& s1,
const char *s2)
00907 {
00908
if (s2 == 0) {
00909
return s1.
isEmpty();
00910 }
00911
00912
const UChar *u = s1.
data();
00913
const UChar *uend = u + s1.
size();
00914
while (u != uend && *s2) {
00915
if (u->
uc != (
unsigned char)*s2)
00916
return false;
00917 s2++;
00918 u++;
00919 }
00920
00921
return u == uend && *s2 == 0;
00922 }
00923
00924
bool KJS::operator<(
const UString& s1,
const UString& s2)
00925 {
00926
const int l1 = s1.
size();
00927
const int l2 = s2.
size();
00928
const int lmin = l1 < l2 ? l1 : l2;
00929
const UChar *c1 = s1.
data();
00930
const UChar *c2 = s2.
data();
00931
int l = 0;
00932
while (l < lmin && *c1 == *c2) {
00933 c1++;
00934 c2++;
00935 l++;
00936 }
00937
if (l < lmin)
00938
return (c1->uc < c2->
uc);
00939
00940
return (l1 < l2);
00941 }
00942
00943
int KJS::compare(
const UString& s1,
const UString& s2)
00944 {
00945
const int l1 = s1.
size();
00946
const int l2 = s2.
size();
00947
const int lmin = l1 < l2 ? l1 : l2;
00948
const UChar *c1 = s1.
data();
00949
const UChar *c2 = s2.
data();
00950
int l = 0;
00951
while (l < lmin && *c1 == *c2) {
00952 c1++;
00953 c2++;
00954 l++;
00955 }
00956
if (l < lmin)
00957
return (c1->uc > c2->
uc) ? 1 : -1;
00958
00959
if (l1 == l2) {
00960
return 0;
00961 }
00962
return (l1 < l2) ? 1 : -1;
00963 }