00001 #ifndef __J2K__JString_New_CPP__
00002 #define __J2K__JString_New_CPP__
00003
00004 #include <j2k/Fred/String/String.hpp>
00005
00006
00007
00008
00009 ULONG JString::hash(const char* buf, ULONG len) {
00010 ULONG h = 129871;
00011 ULONG skip;
00012 ULONG i = len;
00013
00014 if (len<16) {
00015 for (i = len; i; --i, ++buf) {
00016 h = (h + *buf ) * 16647143;
00017 }
00018 } else {
00019 skip=len/8;
00020 for( i=0;i<len;i+=skip,buf+=skip ) {
00021 h = (h + *buf ) * 16647143;
00022 h = (h + *(buf+1) ) * 16647143;
00023
00024
00025
00026
00027
00028
00029
00030
00031
00032 }
00033 }
00034 return h;
00035 }
00036
00037 char* JString::dup() const {
00038 char *buf=new char[contents.getMagic()->len+1];
00039 memcpy(buf,contents.getMagic()->buf,contents.getMagic()->len+1);
00040 return buf;
00041 }
00042
00043 void JString::copyTo(void* dest, ULONG offset, ULONG len) const {
00044 ULONG mylen=length();
00045 if (offset<mylen) {
00046 if ( offset+len > mylen ) {
00047 throw IndexOutOfBoundsException(offset+len);
00048 }
00049 memcpy(dest,getBytes(),len);
00050 }
00051
00052
00053
00054
00055
00056
00057
00058
00059
00060
00061
00062
00063
00064 }
00065
00066 ULONG JString::subJStringByLength(void* dest, ULONG offset, ULONG len) const
00067 {
00068 ULONG mylen = length();
00069 if (offset<mylen) {
00070 if (offset+len>mylen) len=mylen-offset;
00071 memcpy(dest,getBytes(),len);
00072 return len;
00073 }
00074 return 0;
00075 }
00076
00077 JString JString::subJString( ULONG start, ULONG end) const {
00078 ImmutableJString *c=contents.getMagic();
00079 if (start>=c->len||end<=start) {
00080 return JString();
00081 }
00082 if (end>c->len) end=c->len;
00083 return JString(&(c->buf[start]),end-start);
00084 }
00085
00086 BOOL JString::startsWith(const char* s, ULONG off, ULONG len) const {
00087 ULONG mylen = length();
00088 const char *buf = getBytes();
00089 ULONG i;
00090 for( i = 0; i < len&&off < mylen; ++i ) {
00091 if ( s[i] != buf[off]) break;
00092 ++off;
00093 }
00094
00095
00096
00097
00098
00099
00100
00101
00102 return (i==len);
00103 }
00104
00105 BOOL JString::startsWith(const char s, ULONG off) const {
00106 ULONG mylen=length();
00107 const char* buf=getBytes();
00108 if (off<mylen) return buf[off]==s;
00109 return FALSE;
00110 }
00111
00112 BOOL JString::endsWith(const char* s, ULONG len) const {
00113 ULONG mylen=length();
00114 const char* buf=getBytes();
00115 ULONG i;
00116 if (mylen<len) return FALSE;
00117 ULONG off=mylen-len;
00118
00119 for (i=0;i<len&&off<mylen;++i) {
00120 if (s[i]!=buf[off]) break;
00121 off++;
00122 }
00123 return (i==len);
00124 }
00125
00126
00127
00128
00129
00130
00131
00132
00133
00134
00135
00136
00137
00138
00139 #define MODULO 16647143
00140
00141 int JString::indexOf(const char* buf, ULONG mylen, const char* s, ULONG len, ULONG off)
00142 {
00143 if (off+len>mylen)
00144 return -1;
00145
00146 ULONG match = 0;
00147 ULONG hash = 0;
00148 ULONG mask = 1;
00149 ULONG i;
00150
00151 for( i = 0; i < len; i++ ) {
00152 hash = (128*hash+s[i])%MODULO;
00153 if (i) mask=(128*mask)%MODULO;
00154 }
00155
00156 i=0;
00157 while (off<mylen) {
00158 if (i<len) {
00159 match=(128*match+buf[off])%MODULO;
00160
00161 } else {
00162 if (match==hash) {
00163
00164
00165
00166
00167
00168
00169
00170
00171
00172
00173
00174
00175
00176
00177
00178
00179
00180
00181
00182
00183
00184
00185
00186
00187
00188
00189
00190
00191
00192
00193
00194
00195
00196
00197
00198
00199
00200
00201
00202
00203
00204
00205
00206
00207
00208
00209
00210
00211
00212
00213
00214
00215
00216
00217
00218
00219
00220
00221
00222
00223
00224
00225
00226
00227
00228
00229
00230
00231
00232
00233
00234
00235
00236
00237
00238 ULONG JString::hash() const {
00239 return hash(contents.getMagic()->buf,contents.getMagic()->len);
00240 }
00241
00242 BOOL JString::Equals(const JObject &o) const {
00243 const JString* other=dynamic_cast<const JString* >(&o);
00244 if (other) {
00245 return ::operator==(*this,*other);
00246 } else {
00247 const JStringBuffer* other2=dynamic_cast<const JStringBuffer* >(&o);
00248 if (other2) return ::operator==(*this,*other2);
00249 }
00250 return FALSE;
00251 }
00252
00253 BOOL JString::lessThan(const Object &o) const {
00254 const JString* other=dynamic_cast<const JString* >(&o);
00255 if (other) {
00256 return ::operator<(*this,*other);
00257 } else {
00258 const JStringBuffer* other2=dynamic_cast<const JStringBuffer* >(&o);
00259 if (other2) return ::operator<(*this,*other2);
00260 }
00261 return FALSE;
00262 }
00263
00264 BOOL JString::lessThanEquals(const JObject &o) const {
00265 const JString* other=dynamic_cast<const JString* >(&o);
00266 if (other) {
00267 return ::operator<=(*this,*other);
00268 } else {
00269 const JStringBuffer* other2=dynamic_cast<const JStringBuffer* >(&o);
00270 if (other2) return ::operator<=(*this,*other2);
00271 }
00272 return FALSE;
00273 }
00274
00275 void JStringBuffer::setLength( ULONG newLength) {
00276 if (newLength>magic->len) {
00277 ensureCapacity(newLength-magic->len);
00278 }
00279 magic->len=newLength;
00280 if (magic->buf) magic->buf[newLength]=0;
00281 }
00282
00283 void JStringBuffer::ensureCapacity( ULONG extra) {
00284 MutableJString* mut=magic.getMagic();
00285 if (mut->len+extra>=mut->maxlen) {
00286 mut->reallocate(mut->len+extra);
00287 }
00288 }
00289
00290 char* JStringBuffer::dup() const {
00291 char* buf=new char[magic->len+1];
00292 memcpy(buf,magic->buf,magic->len+1);
00293 return buf;
00294 }
00295
00296 void JStringBuffer::copyTo(void* dest, ULONG offset, ULONG len) const {
00297 ULONG mylen=length();
00298 if (offset<mylen) {
00299 if (offset+len>mylen) {
00300 // throw IndexOutOfBoundsException(offset+len);
00301 }
00302 memcpy(dest,&getBytes()[offset],len);
00303 } else {
00304 // throw IndexOutOfBoundsException(offset);
00305 }
00306 }
00307
00308 ULONG JStringBuffer::subJStringByLength(void* dest, ULONG offset, ULONG len) const
00309 {
00310 ULONG mylen=length();
00311 if (offset<mylen) {
00312 if (offset+len>mylen)
00313 len=mylen-offset;
00314
00315 memcpy(dest,getBytes(),len);
00316 return len;
00317 }
00318 return 0;
00319 }
00320
00321 JStringBuffer JStringBuffer::subJString(ULONG start,ULONG end) const {
00322 MutableJString* c=magic.getMagic();
00323 if (start>=c->len||end<=start) {
00324 return JStringBuffer();
00325 }
00326
00327 if (end > c->len) {
00328 end = c->len;
00329 }
00330
00331 return JStringBuffer(&(c->buf[start]),end-start);
00332 }
00333
00334 BOOL JStringBuffer::startsWith(const char* s,ULONG off,ULONG len) const
00335 {
00336 ULONG mylen=length();
00337 const char* buf=getBytes();
00338 ULONG i;
00339 for (i=0;i<len&&off<mylen;++i) {
00340 if (s[i]!=buf[off]) break;
00341 ++off;
00342 }
00343 return (i==len);
00344 }
00345
00346 BOOL JStringBuffer::startsWith(const char s,ULONG off) const {
00347 ULONG mylen=length();
00348 const char* buf=getBytes();
00349 if (off<mylen)
00350 return buf[off]==s;
00351
00352 return FALSE;
00353 }
00354
00355 BOOL JStringBuffer::endsWith(const char* s,ULONG len) const {
00356 ULONG mylen=length();
00357 const char* buf=getBytes();
00358 ULONG i;
00359 if (mylen<len) return FALSE;
00360 ULONG off=mylen-len;
00361
00362 for (i=0;i<len&&off<mylen;++i) {
00363 if (s[i]!=buf[off]) break;
00364 ++off;
00365 }
00366 return (i==len);
00367 }
00368
00369 int JStringBuffer::indexOf(char c,ULONG off) const {
00370 ULONG len=length();
00371 const char* buf=getBytes();
00372 while (off<len) {
00373 if (buf[off]==c) return off;
00374 off++;
00375 }
00376 return -1;
00377 }
00378
00379 int JStringBuffer::lastIndexOf(char c,ULONG off) const {
00380 ULONG len=length();
00381 const char* buf=getBytes();
00382 if (off>=len) return -1;
00383 while (1) {
00384 if (buf[off]==c) return off;
00385 if (off) {
00386 off--;
00387 } else {
00388 break;
00389 }
00390 }
00391 return -1;
00392 }
00393
00394 char& JStringBuffer::operator[] (ULONG offset) {
00395 if (magic->buf&&offset<=magic->len) {
00396 return magic->buf[offset];
00397 } else if (offset==0) {
00398 magic=new MutableJString(16);
00399 return magic->buf[0];
00400 }
00401
00402 // throw IndexOutOfBoundsException(offset);
00403 }
00404
00405 char JStringBuffer::operator[] (ULONG offset) const {
00406 if (magic->buf&&offset<=magic->len) {
00407 return magic->buf[offset];
00408 } else if (offset==0) return 0;
00409
00410 // throw IndexOutOfBoundsException(offset);
00411 }
00412
00413 Object* JStringBuffer::Copy() const {
00414 JStringBuffer* ret=new JStringBuffer;
00415 *ret=*this;
00416 return ret;
00417 }
00418
00419 void JStringBuffer::Serialize(Serializer &out) const {
00420 out.pushBytes(*this);
00421 }
00422
00423 void JStringBuffer::Deserialize(Deserializer &in) {
00424 in.popBytes(*this);
00425 }
00426
00427 ULONG JStringBuffer::hash() const {
00428 return JString::hash(magic->buf,magic->len);
00429 }
00430
00431 JString JStringBuffer::toJString() const {
00432 return JString(*this);
00433 }
00434
00435 BOOL JStringBuffer::Equals(const Object &o) const {
00436 const JStringBuffer* other=dynamic_cast<const JStringBuffer* >(&o);
00437 if (other) {
00438 return ::operator==(*this,*other);
00439 } else {
00440 const JString* other2=dynamic_cast<const JString* >(&o);
00441 if (other2) return ::operator==(*this,*other2);
00442 }
00443 return FALSE;
00444 }
00445
00446 BOOL JStringBuffer::lessThan(const Object &o) const {
00447 const JStringBuffer* other=dynamic_cast<const JStringBuffer* >(&o);
00448 if (other) {
00449 return ::operator<(*this,*other);
00450 } else {
00451 const JString* other2=dynamic_cast<const JString* >(&o);
00452 if (other2) return ::operator<(*this,*other2);
00453 }
00454 return FALSE;
00455 }
00456
00457 BOOL JStringBuffer::lessThanEquals(const Object &o) const {
00458 const JStringBuffer* other=dynamic_cast<const JStringBuffer* >(&o);
00459 if (other) {
00460 return ::operator<=(*this,*other);
00461 } else {
00462 const JString* other2=dynamic_cast<const JString* >(&o);
00463 if (other2) return ::operator<=(*this,*other2);
00464 }
00465 return FALSE;
00466 }
00467
00468 int JStringBuffer::toInteger(ULONG off) const {
00469 if (off<=length()) {
00470 return atoi(&(magic->buf)[off]);
00471 }
00472 // throw IndexOutOfBoundsException(off);
00473 }
00474
00475 ULONG JStringBuffer::toUnsignedInteger(ULONG off) const {
00476 if (off<=length()) {
00477 return strtoul(&(magic->buf)[off],0,0);
00478 }
00479 // throw IndexOutOfBoundsException(off);
00480 }
00481
00482 double JStringBuffer::toDouble(ULONG off) const {
00483 if (off<=length()) {
00484 return atof(&(magic->buf)[off]);
00485 }
00486 // throw IndexOutOfBoundsException(off);
00487 }
00488
00489 JStringBuffer::IndexOutOfBoundsException::IndexOutOfBoundsException(int idx) {
00490 char* buf=new char[512];
00491 sprintf(buf,"JStringBuffer index %d out of bounds",idx);
00492 Exception::setMessage(buf,1);
00493 }
00494
00495 void JStringBuffer::MutableJString::reallocate(ULONG min) {
00496 if (min<len) min=len;
00497 if (min==0) {
00498 if (buf) delete [] buf;
00499 buf=new char[16];
00500 buf[0]=0;
00501 maxlen=16;
00502 len=0;
00503 return;
00504 }
00505 maxlen=(ULONG)((min+16)*1.2);
00506 //assert(maxlen>=len);
00507 char* newbuf=new char[maxlen];
00508 if (buf) {
00509 memcpy(newbuf,buf,len);
00510 delete [] buf;
00511 }
00512 newbuf[len]=0;
00513 buf=newbuf;
00514 }
00515
00516 JStringBuffer::MutableJString::MutableJString(const char* ibuf,ULONG len) : len(len), buf(0) {
00517 reallocate(len+1);
00518 memcpy(buf,ibuf,len);
00519 }
00520
00521 JStringBuffer::MutableJString::MutableJString(const MutableJString &other) : len(other.len), buf(0) {
00522 reallocate(other.len+1);
00523 memcpy(buf,other.buf,len);
00524 }
00525
00526 JStringBuffer::MutableJString::MutableJString(ULONG max) : len(0), buf(0) {
00527 reallocate(max);
00528 }
00529
00530 JStringBuffer::MutableJString::MutableJString() : len(0), maxlen(0), buf(0) {
00531 reallocate(maxlen);
00532 }
00533
00534 void JStringBuffer::MutableJString::append(const char* ap,ULONG amount) {
00535 if (ap&&amount) {
00536 if (len+amount+1>maxlen) {
00537 reallocate(len+amount+1);
00538 }
00539 memcpy(&buf[len],ap,amount);
00540 len+=amount;
00541 buf[len]=0;
00542 }
00543 }
00544 void JStringBuffer::translate(char from,char to) {
00545 MutableJString* c=magic.getMagic();
00546 char* buf=c->buf;
00547 ULONG len=c->len;
00548 while (len) {
00549 --len;
00550 if (*buf==from)* buf=to;
00551 ++buf;
00552 }
00553 }
00554
00555 void JStringBuffer::translate(const char* from,const char* to) {
00556 MutableJString* c=magic.getMagic();
00557 char* buf=c->buf;
00558 ULONG len=c->len;
00559 char* p;
00560 while (len) {
00561 --len;
00562 if ((p=strchr(from,*buf))) {
00563 *buf=to[p-from];
00564 }
00565 ++buf;
00566 }
00567 }
00568
00569 void JStringBuffer::remove(const char* from) {
00570 MutableJString* c=magic.getMagic();
00571 char* buf=c->buf;
00572 ULONG len=c->len;
00573 ULONG nlen=0;
00574 char* q;
00575 q=buf;
00576 while (len) {
00577 --len;
00578 if (!strchr(from,*buf)) {
00579 if (buf!=q)* q=*buf;
00580 ++q;
00581 ++nlen;
00582 }
00583 ++buf;
00584 }
00585 setLength(nlen);
00586 }
00587
00588 JStringBuffer& JStringBuffer::chop(const char* str) {
00589 ULONG len=length();
00590 const char* buf=getBytes();
00591 while (len) {
00592 --len;
00593 if (!strchr(str,buf[len])) {
00594 setLength(len+1);
00595 return* this;
00596 }
00597 }
00598 setLength(0);
00599 return *this;
00600 }
00601
00602 JStringBuffer& JStringBuffer::operator<< (int i) {
00603 char str[20];
00604 int len=sprintf(str,"%d",i);
00605 append(str,len);
00606 return *this;
00607 }
00608 JStringBuffer& JStringBuffer::chop(ULONG n) {
00609 ULONG len=length();
00610 if (len>n) {
00611 setLength(len-n);
00612 } else {
00613 setLength(0);
00614 }
00615 return *this;
00616 }
00617
00618 JStringBuffer& JStringBuffer::chop(char ch) {
00619 ULONG len=length();
00620 const char* buf=getBytes();
00621 while (len) {
00622 --len;
00623 if (buf[len]!=ch) {
00624 setLength(len+1);
00625 return *this;
00626 }
00627 }
00628 setLength(0);
00629 return *this;
00630 }
00631
00632 #endif