Main Page   Packages   Namespace List   Class Hierarchy   Alphabetical List   Compound List   File List   Compound Members   File Members   Search  

C:/temp/src/j2k/Fred/String/StrNew.cpp

Go to the documentation of this file.
00001 #ifndef __J2K__JString_New_CPP__
00002 #define __J2K__JString_New_CPP__
00003 
00004 #include <j2k/Fred/String/String.hpp>
00005 
00006 // New features from Odin Plus Plus 0.2 library
00007 // LGPL licensed too.
00008 
00009 ULONG JString::hash(const char* buf, ULONG len) {
00010   ULONG h = 129871;  // "randomly" chosen
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 /** ANDREA ***************************************************
00024 
00025   This code may access buf[len], in other words the (len+1)-th
00026   byte. I hope this is understood by callers. To see why
00027   consider a string of lenght 17.
00028 
00029   It's not my code... =)
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   //else throw IndexOutOfBoundsException(offset);
00052 
00053 /** ANDREA ***************************************************
00054 
00055   Seeing a throw I may suspect that your library should be
00056   used in an environment that supports exceptions.
00057   Unfortunately most of your code is really really far from
00058   being exception safe.
00059 
00060   It's not my code... =)
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 /** ANDREA ***************************************************
00095 
00096   This is a good idea. Removing all spaces can make your
00097   code running faster...  (joke ;) )
00098 
00099   Why not using strncmp() ?
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 /* NOTE: this originally used memmem(),
00127  * which is apparently broken under Linux...
00128  */
00129 
00130 /** ANDREA ***************************************************
00131 
00132 Really hard to believe but I'll check. What gcc and libraries
00133 version ?
00134 
00135   It's not my code... =)
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         /* possible match on previous length characters* /
00164         if (memcmp(&buf[off-len],s,len)==0) {
00165           return off-len;
00166         }
00167       }
00168 
00169       match = (match+128*MODULO-mask*buf[off-len])%MODULO;
00170       match = (match*128+buf[off])%MODULO;
00171     }
00172 
00173   ++off;
00174   ++i;
00175   }
00176   return -1;
00177 }
00178 
00179 int JString::lastIndexOf(char c, ULONG off) const {
00180   ULONG len = length();
00181   const char* buf = getBytes();
00182 
00183   if (off>=len)
00184     return -1;
00185 
00186   while (1) {
00187     if (buf[off]==c)
00188       return off;
00189    
00190     if (off) {
00191       off--;
00192     } else {
00193       break;
00194     }
00195   }
00196   return -1;
00197 }
00198 
00199 int JString::toInteger( ULONG off) const {
00200   if (off<=length()) {
00201     return atoi(&(contents.getMagic()->buf)[off]);
00202   }
00203   // throw IndexOutOfBoundsException(off);
00204 }
00205 
00206 ULONG JString::toUnsignedInteger(ULONG off) const {
00207   if (off<=length()) {
00208     return strtoul(&(contents.getMagic()->buf)[off],0,0);
00209   }
00210   // throw IndexOutOfBoundsException(off);
00211 }
00212 
00213 double JString::toDouble(ULONG off) const {
00214   if (off<=length()) {
00215     return atof(&(contents.getMagic()->buf)[off]);
00216   }
00217  // throw IndexOutOfBoundsException(off);
00218 }
00219 
00220 char JString::operator[] (ULONG offset) const {
00221   if (offset<=length()) {
00222     return contents.getMagic()->buf[offset];
00223   }
00224   // throw IndexOutOfBoundsException(offset);
00225 }
00226 
00227 JObject* JString::Copy() const {
00228   return new JString(*this);
00229 }
00230 
00231 /** ANDREA ***************************************************
00232 
00233   Hey... this is a different thing.
00234   Gosh... my reading stops here.
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

Generated on Sun Oct 14 18:46:32 2001 for Standard J2K Library by doxygen1.2.11.1 written by Dimitri van Heesch, © 1997-2001