00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021 #include "JString.h"
00022 #include <ctype.h>
00023 #include <stdio.h>
00024 #include <stdlib.h>
00025 #include <stdarg.h>
00026 #include <math.h>
00027
00028 #if defined(WIN32)
00029
00030
00031
00032 #endif
00033
00034 #include "Collections.h"
00035 #include "Dictionary.h"
00036 #include "DotString.h"
00037 #include "JTime.h"
00038
00039 namespace cmlabs {
00040
00041 JString::JString( const char *str )
00042 {
00043 Buffer = NULL;
00044 Length = BufferLen = 0;
00045 isCRTerminated = false;
00046 if ( str == NULL )
00047 str = "";
00048 #ifdef WIN32
00049 lpwBuffer = NULL;
00050 #endif
00051
00052 setBufferSizeInline(Length = (unsigned int)strlen(str));
00053 strcpy( Buffer, str );
00054 }
00055
00056 JString::JString(char ch)
00057 {
00058 Buffer = NULL;
00059 Length = BufferLen = 0;
00060 isCRTerminated = false;
00061 #ifdef WIN32
00062 lpwBuffer = NULL;
00063 #endif
00064
00065 setBufferSizeInline(Length = 1);
00066 Buffer[0] = ch;
00067 Buffer[1] = 0;
00068 }
00069
00070 JString::JString(void* pointer) {
00071 Buffer = NULL;
00072 Length = BufferLen = 0;
00073 isCRTerminated = false;
00074 #ifdef WIN32
00075 lpwBuffer = NULL;
00076 #endif
00077
00078 setBufferSizeInline(Length = 20);
00079 sprintf(Buffer, "%p", pointer);
00080
00081
00082
00083
00084
00085 }
00086
00087 JString::JString( const bool val )
00088 {
00089 Buffer = NULL;
00090 Length = BufferLen = 0;
00091 isCRTerminated = false;
00092 #ifdef WIN32
00093 lpwBuffer = NULL;
00094 #endif
00095
00096 setBufferSizeInline(Length = 4);
00097 if (val)
00098 strcpy( Buffer, "Yes" );
00099 else
00100 strcpy( Buffer, "No" );
00101 }
00102
00103 JString::JString( const JString &str )
00104 {
00105 Buffer = NULL;
00106 Length = BufferLen = 0;
00107 #ifdef WIN32
00108 if (str.lpwBuffer != NULL) {
00109 lpwBuffer = (WCHAR*)malloc((wcslen(str.lpwBuffer)+1)*sizeof(WCHAR));
00110 wcscpy(lpwBuffer, str.lpwBuffer);
00111 }
00112 else
00113 lpwBuffer = NULL;
00114 #endif
00115 isCRTerminated = str.isCRTerminated;
00116
00117 setBufferSizeInline(Length = str.Length);
00118 strcpy( Buffer, str.Buffer );
00119 }
00120
00121
00122 JString JString::format( char *formatstring, ... ) {
00123
00124 va_list args;
00125 va_start(args, formatstring);
00126
00127
00128
00129
00130
00131
00132
00133
00134
00135
00136
00137
00138
00139
00140
00141
00142
00143
00144 char* str;
00145 JString res;
00146
00147 #ifdef HAVE_VASPRINTF
00148 int len = vasprintf(&str, formatstring, args);
00149 if(len<0) {
00150 }
00151 else {
00152 free(res.Buffer);
00153 res.Buffer=str;
00154 res.Length=len;
00155 res.BufferLen=len;
00156 }
00157 va_end(args);
00158
00159
00160 #else //HAVE_VASPRINTF
00161
00162 int size = -1;
00163 #ifdef WIN32
00164 #ifdef WIN32_VS
00165 #ifndef WIN32_VS6
00166 size = _vscprintf(formatstring, args);
00167 #endif
00168 #endif // WIN32_VSN
00169 #else // WIN32
00170 size = vsnprintf(NULL, 0, formatstring, args);
00171
00172 va_end(args);
00173 va_start(args, formatstring);
00174 #endif // WIN32
00175
00176 int vsnprintf_result = -1;
00177 if (size >= 0) {
00178 size += 10;
00179 str = (char*)malloc(size+1);
00180 #ifdef WIN32
00181 #ifdef CYGWIN
00182 vsnprintf_result = vsnprintf(str, size, formatstring, args);
00183 #else
00184 vsnprintf_result = _vsnprintf(str, size, formatstring, args);
00185 #endif
00186 #else
00187 vsnprintf_result = vsnprintf(str, size, formatstring, args);
00188 #endif // WIN32
00189 }
00190 else {
00191 int max = 1024*1024*10;
00192 size = 1024*10;
00193
00194 int count = 0;
00195 while (size <= max) {
00196 count++;
00197 str = (char*)malloc(size);
00198 #ifdef WIN32
00199 #ifdef CYGWIN
00200 vsnprintf_result = vsnprintf(str, size, formatstring, args);
00201 #else
00202 vsnprintf_result = _vsnprintf(str, size, formatstring, args);
00203 #endif
00204 #else
00205 vsnprintf_result = vsnprintf(str, size, formatstring, args);
00206 #endif // WIN32
00207
00208
00209 if ( (vsnprintf_result >= 0) && (vsnprintf_result < size) ) {
00210 break;
00211 }
00212 else if (vsnprintf_result >= size) {
00213 va_end(args);
00214 free((char*)str);
00215 str = NULL;
00216 size = vsnprintf_result + 10;
00217 va_start(args, formatstring);
00218 }
00219 else {
00220 va_end(args);
00221 free((char*)str);
00222 str = NULL;
00223 size *= 2;
00224 va_start(args, formatstring);
00225 }
00226 }
00227 }
00228
00229 va_end(args);
00230 if ((vsnprintf_result >= 0) && (str != NULL))
00231 res = JString(str);
00232 else {
00233
00234 res = "";
00235 }
00236 free((char*)str);
00237
00238 #endif //HAVE_VASPRINTF
00239
00240 return res;
00241 }
00242
00243
00244 JString::JString( const JString &s, unsigned int width, int justification ) {
00245
00246 Buffer = NULL;
00247 Length = BufferLen = 0;
00248 isCRTerminated = s.isCRTerminated;
00249 JString str;
00250 unsigned int l = s.Length;
00251 unsigned int n = 0;
00252
00253 if (justification == 0) {
00254 if (l > width)
00255 str = s.substring(0, width);
00256 else if (l == width)
00257 str = s;
00258 else {
00259 str = s;
00260 for (n=0; n<(width - l); n++)
00261 str += " ";
00262 }
00263 }
00264 else if (justification == 1) {
00265 if (l > width)
00266 str = s.substring(l - width);
00267 else if (s.Length == width)
00268 str = s;
00269 else {
00270 str = s;
00271 for (n=0; n<(width - l); n++)
00272 str = JString(" ") + str;
00273 }
00274 }
00275 else {
00276 if (l > width)
00277 str = s.substring((int) ((l - width)/2));
00278 else if (s.Length == width)
00279 str = s;
00280 else {
00281 str = s;
00282 for (n=0; n<(int) ((width - l)/2); n++)
00283 str = JString(" ") + str + JString(" ");
00284 }
00285 while (str.Length < width)
00286 str = str + JString(" ");
00287 }
00288
00289
00290 setBufferSizeInline(Length = str.Length);
00291 strcpy( Buffer, str.Buffer );
00292
00293 #ifdef WIN32
00294 lpwBuffer = NULL;
00295 #endif
00296
00297 }
00298
00299 JString::JString( unsigned int intValue, int padding) {
00300 Buffer = NULL;
00301 Length = BufferLen = 0;
00302 isCRTerminated = false;
00303 char* str = (char*)malloc(100);
00304 sprintf(str, "%u", intValue);
00305 int len = (int)strlen(str);
00306 int n;
00307
00308 if (len >= padding) {
00309 }
00310 else {
00311 for (n=len; n>=0; n--)
00312 str[n+padding-len] = str[n];
00313 for (n=0; n<padding-len; n++)
00314 str[n] = '0';
00315 }
00316
00317
00318 setBufferSizeInline(Length = (unsigned int) strlen(str));
00319 strcpy( Buffer, str );
00320 free((char*)str);
00321
00322 #ifdef WIN32
00323 lpwBuffer = NULL;
00324 #endif
00325 }
00326
00327 JString::JString( int intValue, int padding) {
00328 Buffer = NULL;
00329 Length = BufferLen = 0;
00330 isCRTerminated = false;
00331 char* str = (char*)malloc(100);
00332 sprintf(str, "%d", intValue);
00333 int len = (int)strlen(str);
00334 int n;
00335
00336 if (len >= padding) {
00337 }
00338 else {
00339 for (n=len; n>=0; n--)
00340 str[n+padding-len] = str[n];
00341 for (n=0; n<padding-len; n++)
00342 str[n] = '0';
00343 }
00344
00345
00346 setBufferSizeInline(Length = (unsigned int) strlen(str));
00347 strcpy( Buffer, str );
00348 free((char*)str);
00349
00350 #ifdef WIN32
00351 lpwBuffer = NULL;
00352 #endif
00353 }
00354
00355 JString::JString( long longValue, int padding ) {
00356 Buffer = NULL;
00357 Length = BufferLen = 0;
00358 isCRTerminated = false;
00359 char* str = (char*)malloc(100);
00360 sprintf(str, "%ld", longValue);
00361 int len = (int)strlen(str);
00362 int n;
00363
00364 if (len >= padding) {
00365 }
00366 else {
00367 for (n=len; n>=0; n--)
00368 str[n+padding-len] = str[n];
00369 for (n=0; n<padding-len; n++)
00370 str[n] = '0';
00371 }
00372
00373
00374
00375 setBufferSizeInline(Length = (unsigned int) strlen(str));
00376 strcpy( Buffer, str );
00377 free((char*)str);
00378 #ifdef WIN32
00379 lpwBuffer = NULL;
00380 #endif
00381 }
00382
00383 JString::JString(unsigned long longValue, int padding) {
00384 Buffer = NULL;
00385 Length = BufferLen = 0;
00386 isCRTerminated = false;
00387 char* str = (char*)malloc(100);
00388 sprintf(str, "%llu", longValue);
00389 int len = (int)strlen(str);
00390 int n;
00391
00392 if (len >= padding) {
00393 }
00394 else {
00395 for (n=len; n>=0; n--)
00396 str[n+padding-len] = str[n];
00397 for (n=0; n<padding-len; n++)
00398 str[n] = '0';
00399 }
00400
00401
00402
00403 setBufferSizeInline(Length = (unsigned int) strlen(str));
00404 strcpy( Buffer, str );
00405 free((char*)str);
00406 #ifdef WIN32
00407 lpwBuffer = NULL;
00408 #endif
00409 }
00410
00411 JString::JString(long long longValue, int padding) {
00412 Buffer = NULL;
00413 Length = BufferLen = 0;
00414 isCRTerminated = false;
00415 char* str = (char*)malloc(100);
00416 sprintf(str, "%lld", longValue);
00417 int len = (int)strlen(str);
00418 int n;
00419
00420 if (len >= padding) {
00421 }
00422 else {
00423 for (n=len; n>=0; n--)
00424 str[n+padding-len] = str[n];
00425 for (n=0; n<padding-len; n++)
00426 str[n] = '0';
00427 }
00428
00429
00430
00431 setBufferSizeInline(Length = (unsigned int) strlen(str));
00432 strcpy( Buffer, str );
00433 free((char*)str);
00434 #ifdef WIN32
00435 lpwBuffer = NULL;
00436 #endif
00437 }
00438
00439 JString::JString(unsigned long long longValue, int padding) {
00440 Buffer = NULL;
00441 Length = BufferLen = 0;
00442 isCRTerminated = false;
00443 char* str = (char*)malloc(100);
00444 sprintf(str, "%llu", longValue);
00445 int len = (int)strlen(str);
00446 int n;
00447
00448 if (len >= padding) {
00449 }
00450 else {
00451 for (n=len; n>=0; n--)
00452 str[n+padding-len] = str[n];
00453 for (n=0; n<padding-len; n++)
00454 str[n] = '0';
00455 }
00456
00457
00458
00459 setBufferSizeInline(Length = (unsigned int) strlen(str));
00460 strcpy( Buffer, str );
00461 free((char*)str);
00462 #ifdef WIN32
00463 lpwBuffer = NULL;
00464 #endif
00465 }
00466
00467 JString::JString( double doubleValue, int afterdec, int beforedec) {
00468 Buffer = NULL;
00469 Length = BufferLen = 0;
00470 isCRTerminated = false;
00471 int zeros;
00472
00473
00474
00475
00476
00477 if (afterdec < 0) {
00478 afterdec = 20;
00479
00480
00481
00482
00483
00484
00485
00486
00487 }
00488
00489 char* decpoint;
00490 char* formatstr = (char*)malloc(20);
00491 char* str = (char*)malloc(afterdec + beforedec + 100);
00492
00493 if (afterdec >= 0) {
00494 sprintf(formatstr, "%%.%df", afterdec);
00495 sprintf(str, formatstr, doubleValue);
00496 }
00497 else {
00498 strcpy(str, "0");
00499 }
00500
00501 if (beforedec > 0) {
00502 decpoint = strstr(str, ".");
00503 if (decpoint == NULL) {
00504 zeros = beforedec - (int)strlen(str);
00505 }
00506 else {
00507 zeros = beforedec - (int)(decpoint - str);
00508 }
00509
00510 if (zeros > 0) {
00511 int n;
00512 char* charzero = (char*)malloc(zeros+50);
00513 for (n=0; n<zeros; n++)
00514 charzero[n] = '0';
00515 for (n=0; n < (int) strlen(str) + 1; n++)
00516 charzero[n+zeros] = str[n];
00517 strcpy(str, charzero);
00518 free((char*)charzero);
00519 }
00520 }
00521
00522 for (int n=(int)strlen(str)-1; n>0; n--) {
00523 if (str[n] == '0')
00524 str[n] = 0;
00525 else if (str[n] == '.') {
00526 str[n] = 0;
00527 break;
00528 }
00529 else
00530 break;
00531 }
00532 if (strlen(str) == 0)
00533 str[0] = '0';
00534
00535
00536 setBufferSizeInline(Length = (unsigned int) strlen(str));
00537 strcpy( Buffer, str );
00538
00539 free((char*)formatstr);
00540 free((char*)str);
00541
00542 #ifdef WIN32
00543 lpwBuffer = NULL;
00544 #endif
00545 }
00546
00547 JString::~JString() {
00548 free((char*)Buffer);
00549 #ifdef WIN32
00550 free((char*)lpwBuffer);
00551 #endif
00552 }
00553
00554
00555
00556 unsigned long JString::getPayloadSize() const {
00557 return Length;
00558 }
00559
00560 Object* JString::clone() const {
00561 JString* str = new JString(*this);
00562 return (Object*) str;
00563 }
00564
00565 JString JString::print() {
00566 return *this;
00567 }
00568
00569
00570 JString::operator char *() const {
00571 char* str = Buffer;
00572 return str;
00573 }
00574
00575 JString::operator const char *() const {
00576 const char* str = Buffer;
00577 return str;
00578 }
00579
00580 JString::operator void *() {
00581 void* str = (void*) Buffer;
00582 return str;
00583 }
00584
00585 JString::operator const void *() {
00586 const void* str = (void*) Buffer;
00587 return str;
00588 }
00589
00590 const char* JString::charpoint() const {
00591 const char* str = Buffer;
00592 return str;
00593 }
00594
00595 char* JString::getCharCopy(int &len) const {
00596 len = (int) Length;
00597 if (len <= 0) {
00598 len = 0;
00599 return NULL;
00600 }
00601
00602 char* data = new char [len+1];
00603 memcpy(data, charpoint(), len);
00604 data[len] = 0;
00605 return data;
00606 }
00607
00608 DotString JString::toDotString() const {
00609 return DotString(*this);
00610
00611
00612 }
00613
00614 JTime JString::toTime() {
00615 JTime t = JTime(*this);
00616 return t;
00617 }
00618
00619 JString JString::getFirst(int len) {
00620 if ((int)Length <= len)
00621 return *this;
00622 else
00623 return substring(0, len);
00624 }
00625
00626 JString JString::getLast(int len) {
00627 if ((int)Length <= len)
00628 return *this;
00629 else
00630 return substring(Length-len);
00631 }
00632
00633
00634 char JString::charAt( unsigned int loc ) const {
00635 return operator[]( loc );
00636 }
00637
00638 char JString::getCharAt( unsigned int loc ) const {
00639 return operator[]( loc );
00640 }
00641
00642 bool JString::setCharAt( unsigned int i, char ch ) {
00643 if ( (i >= 0) && (i < Length) ) {
00644 Buffer[i] = ch;
00645 return true;
00646 }
00647 else
00648 return false;
00649 }
00650
00651
00652 int JString::compare(const Object* o2) const {
00653 if ((o2 == NULL) || (!isSameClass(o2)))
00654 return 0;
00655 return compareTo(*(JString*) o2);
00656 }
00657
00658 int JString::compareTo( const JString &s2 ) const {
00659 return strcmp( Buffer, s2.Buffer );
00660 }
00661
00662 const JString& JString::concat( const JString &s2 ) {
00663 return (*this) += s2;
00664 }
00665
00666 const JString& JString::operator=( const JString &str ) {
00667 if ( this == &str )
00668 return *this;
00669
00670 if ( str.Length > Length ) {
00671
00672
00673 setBufferSizeInline(Length = (unsigned int) str.Length);
00674 }
00675
00676 Length = str.Length;
00677 if ( (Length > 0) && (str.Buffer != NULL) )
00678 strcpy( Buffer, str.Buffer );
00679 else
00680 strcpy(Buffer, "");
00681
00682 isCRTerminated = str.isCRTerminated;
00683
00684 return *this;
00685 }
00686
00687 const JString& JString::operator+=( const char aChar ) {
00688 setBufferSizeInline(Length+1);
00689
00690
00691
00692 Buffer[ Length++ ] = aChar;
00693 Buffer[ Length ] = '\0';
00694
00695 return *this;
00696 }
00697
00698 const JString& JString::operator+=( const unsigned char aChar ) {
00699 setBufferSizeInline(Length+1);
00700
00701
00702
00703 Buffer[ Length++ ] = aChar;
00704 Buffer[ Length ] = '\0';
00705
00706 return *this;
00707 }
00708
00709 const JString& JString::operator+=( const JString &other ) {
00710 setBufferSizeInline(Length + other.Length);
00711 memcpy(Buffer+Length, other.Buffer, other.Length);
00712 Length += other.Length;
00713 Buffer[Length] = 0;
00714 return *this;
00715 }
00716
00717 const JString& JString::operator+=(const char* str) {
00718 if (str != NULL) {
00719 int len = (int)strlen(str);
00720 setBufferSizeInline(Length + len);
00721 memcpy(Buffer+Length, str, len);
00722 Length += len;
00723 Buffer[Length] = 0;
00724 }
00725 return *this;
00726 }
00727
00728 int JString::operator ==(const char* chr) const {
00729 return strcmp( Buffer, chr ) == 0;
00730 }
00731
00732 int JString::operator !=(const char* chr) const {
00733 return strcmp( Buffer, chr ) != 0;
00734 }
00735
00736
00737 int JString::operator==( const JString &str ) const {
00738 return this->equals(str);
00739 }
00740
00741 int JString::operator!=( const JString &str ) const {
00742 return (!this->equals(str));
00743 }
00744
00745 int JString::operator<( const JString &str ) const {
00746 return strcmp( Buffer, str.Buffer ) < 0;
00747 }
00748
00749 int JString::operator>( const JString &str ) const {
00750 return strcmp( Buffer, str.Buffer ) > 0;
00751 }
00752
00753 int JString::operator<=( const JString &str ) const {
00754 return strcmp( Buffer, str.Buffer ) <= 0;
00755 }
00756
00757 int JString::operator>=( const JString & str ) const {
00758 return strcmp( Buffer, str.Buffer ) >= 0;
00759 }
00760
00761
00762 char& JString::operator[]( unsigned int i ) {
00763 if (i >= Length)
00764 return Buffer[ Length ];
00765 else
00766 return Buffer[ i ];
00767 }
00768
00769 char JString::operator[]( unsigned int i ) const {
00770 if (i >= Length)
00771 return 0;
00772 else
00773 return Buffer[ i ];
00774 }
00775
00776
00777 char& JString::operator[]( int i ) {
00778 return operator[]((unsigned) i);
00779 }
00780
00781 char JString::operator[]( int i ) const {
00782 return operator[]((unsigned) i);
00783 }
00784
00785
00786 bool JString::endsWith( const JString &s2 ) const {
00787 if ( Length < s2.Length )
00788 return 0;
00789
00790 return strcmp( &Buffer[ Length - s2.Length], s2.cstr() ) == 0;
00791 }
00792
00793 bool JString::equals(const Object* o2) const {
00794 if (o2 == NULL) return false;
00795 if (!this->isSameClass(o2)) {
00796 printf("O2[%s]: %s != %s\n", (char*) o2->getClass(), (char*) *this, (char*) (*(JString*)o2));
00797 return false;
00798 }
00799 return this->equals(*(JString*)o2);
00800 }
00801
00802
00803 bool JString::equals( const JString &s2 ) const {
00804 return ( strcmp( Buffer,s2.Buffer ) == 0 );
00805 }
00806
00807
00808 bool JString::equalsIgnoreCase( const JString &s2 ) const {
00809 if ( this == &s2 )
00810 return 1;
00811 else if ( Length != s2.Length )
00812 return 0;
00813
00814 #ifdef WIN32
00815 return stricmp(Buffer, s2.Buffer) == 0;
00816 #else // WIN32
00817 return strcasecmp(Buffer, s2.Buffer) == 0;
00818 #endif // WIN32
00819 }
00820
00821 int JString::indexOfCount(const JString& match) const {
00822 int count = 0;
00823 int loc = 0;
00824
00825 if (match.length() == 1) {
00826 char ch = match.charAt(0);
00827 while ( (loc = indexOf( ch, loc)) != -1 ) {
00828 loc += match.Length;
00829 count++;
00830 }
00831 }
00832 else {
00833 while ( (loc = indexOf( match, loc)) != -1 ) {
00834 loc += match.Length;
00835 count++;
00836 }
00837 }
00838 return count;
00839 }
00840
00841 int JString::indexOfCountIgnoreCase(const JString& match) const {
00842 JString str = this->toLowerCase();
00843 JString lmatch = match.toLowerCase();
00844 return str.indexOfCount(lmatch);
00845 }
00846
00847
00848 void JString::replace( char findChar, char replaceChar) {
00849 char* temp = strchr( Buffer, findChar );
00850 if ( temp != NULL )
00851 *temp = replaceChar;
00852 }
00853
00854 int JString::replace(const JString& match, const JString& replacement, bool all, bool recursive) {
00855 int crCount = indexOfCount(match);
00856 if (crCount == 0)
00857 return 0;
00858
00859 JString result;
00860 result.setBufferSizeInline(Length + (crCount * replacement.Length + 10));
00861 char* src = (char*) Buffer;
00862 char* dst = (char*) result;
00863
00864 unsigned int dstpos = 0;
00865 unsigned int srcpos = 0;
00866
00867 int matchLen = match.Length;
00868 int replLen = replacement.Length;
00869 int pos = 0;
00870 int len;
00871
00872 int count = 0;
00873 while ( (pos = indexOf(match, pos)) >= 0) {
00874 len = pos - srcpos;
00875 memcpy(dst+dstpos, src+srcpos, len);
00876 dstpos += len;
00877 memcpy(dst+dstpos, replacement.Buffer, replLen);
00878 dstpos += replLen;
00879 srcpos = pos + matchLen;
00880 pos = srcpos;
00881 count++;
00882 if (!all) break;
00883 }
00884 len = Length - srcpos;
00885 memcpy(dst+dstpos, src+srcpos, len);
00886 dstpos += len;
00887 dst[dstpos] = 0;
00888 result.Length = dstpos;
00889
00890 if ( recursive && (result.indexOf(match) >= 0) )
00891 result.replace(match, replacement, all, recursive);
00892 *this = result;
00893 return count;
00894 }
00895
00896 int JString::replaceIgnoreCase(const JString& match, const JString& replacement, bool all, bool recursive) {
00897
00898 int crCount = indexOfCountIgnoreCase(match);
00899 if (crCount == 0)
00900 return 0;
00901
00902 JString result;
00903 result.setBufferSizeInline(Length + (crCount * replacement.Length + 10));
00904 char* src = (char*) Buffer;
00905 char* dst = (char*) result;
00906
00907 unsigned int dstpos = 0;
00908 unsigned int srcpos = 0;
00909
00910 int matchLen = match.Length;
00911 int replLen = replacement.Length;
00912 int pos = -1;
00913 int len;
00914
00915 int count = 0;
00916 while ( (pos = indexOfIgnoreCase(match, pos+1)) >= 0) {
00917 len = pos - srcpos;
00918 memcpy(dst+dstpos, src+srcpos, len);
00919 dstpos += len;
00920 memcpy(dst+dstpos, replacement.Buffer, replLen);
00921 dstpos += replLen;
00922 srcpos = pos + matchLen;
00923 count++;
00924 if (!all) break;
00925 }
00926 len = Length - srcpos;
00927 memcpy(dst+dstpos, src+srcpos, len);
00928 dstpos += len;
00929 dst[dstpos] = 0;
00930 result.Length = dstpos;
00931
00932 if ( recursive && (result.indexOfIgnoreCase(match) >= 0) )
00933 result.replace(match, replacement, all, recursive);
00934 *this = result;
00935 return count;
00936 }
00937
00938
00939
00940 void JString::replace( int fromPos, int toPos, const JString& replacement ) {
00941
00942 int reloc = replacement.Length - (toPos - fromPos);
00943 setBufferSizeInline(Length + reloc);
00944 memmove(Buffer+toPos+reloc, Buffer+toPos, Length-toPos+1);
00945 Length += reloc;
00946 memcpy(Buffer+fromPos, replacement.charpoint(), replacement.length());
00947 }
00948
00949
00950 bool JString::contains(const JString& str) const {
00951 return (indexOf(str) >= 0);
00952 }
00953
00954 bool JString::looksLikeXML() const {
00955 JString str = this->trim();
00956 return (str.startsWith("<") && str.endsWith(">"));
00957 }
00958
00959 bool JString::isUTF() const {
00960 return (
00961 (((unsigned char)Buffer[0]) == 239) &&
00962 (((unsigned char)Buffer[1]) == 187) &&
00963 (((unsigned char)Buffer[2]) == 191)
00964 );
00965 }
00966
00967 JString JString::addUTFHeader() const {
00968 JString str = JString::format("xxx%s", (char*) *this);
00969 *((unsigned char*)(str.Buffer)) = 239;
00970 *((unsigned char*)(str.Buffer+1)) = 187;
00971 *((unsigned char*)(str.Buffer+2)) = 191;
00972 return str;
00973 }
00974
00975 bool JString::addCRLF() {
00976
00977 setBufferSizeInline(Length+2);
00978
00979
00980
00981 Buffer[ Length++ ] = (char) 13;
00982 Buffer[ Length++ ] = (char) 10;
00983 Buffer[ Length ] = '\0';
00984
00985 return true;
00986 }
00987
00988 JString JString::indentHTML(int numTabs) const {
00989 JString html = indentXML();
00990 html.replace("\t", " ");
00991 return html;
00992 }
00993
00994 JString JString::indentXML(int numTabs) const {
00995
00996 if (Length <= 0)
00997 return "";
00998
00999
01000
01001
01002 int n;
01003 int crCount = indexOfCount("\n") + indexOfCount("\r");
01004 JString result;
01005 result.setBufferSizeInline(Length + ((crCount+1) * 2 * numTabs));
01006 char* src = (char*) Buffer;
01007 char* dst = (char*) result;
01008
01009 unsigned int dstpos = 0;
01010 unsigned int srcpos = 0;
01011 for (n=0; n<numTabs;n++)
01012 dst[dstpos++] = '\t';
01013 while (srcpos < Length-1) {
01014 switch (src[srcpos]) {
01015 case '\n':
01016 dst[dstpos++] = '\n';
01017 for (n=0; n<numTabs;n++)
01018 dst[dstpos++] = '\t';
01019 if (src[srcpos+1] == '\r')
01020 srcpos++;
01021 srcpos++;
01022 break;
01023 case '\r':
01024 dst[dstpos++] = '\n';
01025 for (n=0; n<numTabs;n++)
01026 dst[dstpos++] = '\t';
01027 if (src[srcpos+1] == '\n')
01028 srcpos++;
01029 srcpos++;
01030 break;
01031 default:
01032 dst[dstpos++] = src[srcpos++];
01033 }
01034 }
01035 dst[dstpos++] = src[srcpos++];
01036 if ( (src[srcpos] != '\n') && (src[srcpos] != '\r') && (src[srcpos-1] != '\n') )
01037 dst[dstpos++] = '\n';
01038 dst[dstpos] = 0;
01039 result.Length = dstpos;
01040
01041
01042 return result;
01043
01044
01045
01046
01047
01048
01049
01050
01051
01052
01053
01054
01055
01056
01057
01058
01059
01060
01061
01062
01063
01064
01065
01066 }
01067
01068 JString JString::indent(int numSpaces) const {
01069
01070 if (Length <= 0)
01071 return "";
01072
01073 int n;
01074 int crCount = indexOfCount("\n") + indexOfCount("\r");
01075 JString result;
01076 result.setBufferSizeInline(Length + ((crCount+1) * 2 * numSpaces));
01077 char* src = (char*) Buffer;
01078 char* dst = (char*) result;
01079
01080 unsigned int dstpos = 0;
01081 unsigned int srcpos = 0;
01082 for (n=0; n<numSpaces;n++)
01083 dst[dstpos++] = ' ';
01084 while (srcpos < Length-1) {
01085 switch (src[srcpos]) {
01086 case '\n':
01087 dst[dstpos++] = '\n';
01088 for (n=0; n<numSpaces;n++)
01089 dst[dstpos++] = ' ';
01090 if (src[srcpos+1] == '\r')
01091 srcpos++;
01092 srcpos++;
01093 break;
01094 case '\r':
01095 dst[dstpos++] = '\n';
01096 for (n=0; n<numSpaces;n++)
01097 dst[dstpos++] = ' ';
01098 if (src[srcpos+1] == '\n')
01099 srcpos++;
01100 srcpos++;
01101 break;
01102 default:
01103 dst[dstpos++] = src[srcpos++];
01104 }
01105 }
01106 dst[dstpos++] = src[srcpos++];
01107 if ( (src[srcpos] != '\n') && (src[srcpos] != '\r') && (src[srcpos-1] != '\n') )
01108 dst[dstpos++] = '\n';
01109 dst[dstpos] = 0;
01110 result.Length = dstpos;
01111
01112
01113 return result;
01114 }
01115
01116 JString JString::toXML() {
01117 return JString::format("<string>%s</string>", (char*) this->xmlStringEncode());
01118 }
01119
01120 bool JString::fromXML(const JString& xml) {
01121
01122 char *first, *last;
01123
01124 first = strstr((char*)xml, "<string>");
01125 if (first != NULL) {
01126 last = strstr((char*)xml, "</string>");
01127 if (last != NULL) {
01128 int n;
01129 char* newchar = (char*)malloc(xml.Length);
01130 for (n=0; n<(last-first-8); n++)
01131 newchar[n] = first[n+8];
01132 newchar[n] = 0;
01133 *this = newchar;
01134
01135
01136 free((char*)newchar);
01137 return true;
01138 }
01139 }
01140
01141
01142
01143
01144
01145
01146
01147
01148 return false;
01149 }
01150
01151
01152
01153 int JString::indexOf(char c) const {
01154 return indexOf(c, 0);
01155 }
01156
01157 int JString::indexOf(char ch, unsigned int fromIndex) const
01158 {
01159 if ( fromIndex >= Length )
01160 return -1;
01161
01162 const char* temp = strchr( &Buffer[fromIndex], ch );
01163 if ( temp == NULL )
01164 return -1;
01165
01166 return (int)(temp - Buffer);
01167 }
01168
01169 int JString::indexOf( const JString &s2 ) const {
01170 return indexOf( s2, 0 );
01171 }
01172
01173
01174 int JString::indexOf( const JString &s2, unsigned int fromIndex ) const {
01175 if ( fromIndex > Length )
01176 return -1;
01177
01178 if (s2.Length == 0)
01179 return -1;
01180 else if (s2.Length == 1)
01181 return indexOf(s2.charAt(0), fromIndex);
01182
01183 const char *theFind = strstr( &Buffer[ fromIndex ], s2.cstr() );
01184
01185 if ( theFind == NULL )
01186 return -1;
01187
01188 return (int)(theFind - Buffer);
01189 }
01190
01191
01192
01193 int JString::lastIndexOf( char theChar ) const {
01194 return lastIndexOf( theChar, Length);
01195 }
01196
01197 int JString::lastIndexOf( char ch, unsigned int fromIndex ) const {
01198 if ( fromIndex > Length )
01199 return -1;
01200
01201 JString str = this->invertString();
01202 int pos = str.indexOf(ch, Length - fromIndex);
01203 if (pos < 0)
01204 return -1;
01205 return Length - 1 - pos;
01206 }
01207
01208 int JString::lastIndexOf( const JString &s2 ) const {
01209 return lastIndexOf( s2, Length);
01210 }
01211
01212 int JString::lastIndexOf( const JString &s2, unsigned int fromIndex ) const {
01213 if ( fromIndex > Length )
01214 return -1;
01215
01216 JString str = this->invertString();
01217 JString str2 = s2.invertString();
01218 int pos = str.indexOf(str2, Length - fromIndex);
01219 if (pos < 0)
01220 return -1;
01221 return Length - pos - s2.length();
01222 }
01223
01224 JString JString::invertString() const {
01225 char* buf = (char*)malloc(Length + 1);
01226 for (int n=0; n<(int)Length; n++) {
01227 buf[n] = Buffer[Length-n-1];
01228 }
01229 buf[Length] = 0;
01230 JString str = JString(buf);
01231 free((char*)buf);
01232 return str;
01233 }
01234
01235 bool JString::startsOrEndsWithWhiteSpace() const {
01236 return ( (Length > 0) && ( ((unsigned char)Buffer[0] < 33) || ((unsigned char)Buffer[Length-1] < 33) ) );
01237 }
01238
01239 bool JString::startsWithWhiteSpace() const {
01240 return ( (Length > 0) && ((unsigned char)Buffer[0] < 33) );
01241 }
01242
01243 bool JString::endsWithWhiteSpace() const {
01244 return ( (Length > 0) && ((unsigned char)Buffer[Length-1] < 33) );
01245 }
01246
01247
01248 bool JString::startsWith( const JString &s2 ) const {
01249 if ( Length < s2.Length )
01250 return 0;
01251 return startsWith( s2, 0 );
01252 }
01253
01254 bool JString::startsWith( const JString &s2, unsigned int offset ) const {
01255 if ( offset > Length - s2.Length )
01256 return 0;
01257 return strncmp( &Buffer[offset], s2.cstr(), s2.Length ) == 0;
01258 }
01259
01260 JString JString::substring( unsigned int left ) const {
01261 return substring( left, Length );
01262 }
01263
01264 JString JString::substring( unsigned int left, unsigned int right ) const {
01265 if ( left > right )
01266 {
01267 int temp = right;
01268 right = left;
01269 left = temp;
01270 }
01271
01272 if ( right > Length )
01273 {
01274 if (DEBUGLEVEL(KITCHENSINK)) {
01275 printf("Index Out Of Bounds Exception in JString\n");
01276 }
01277 right = Length;
01278 }
01279
01280 char temp = Buffer[ right ];
01281 Buffer[ right ] = '\0';
01282
01283 JString outPut = ( Buffer + left );
01284
01285 Buffer[ right ] = temp;
01286
01287 return outPut;
01288 }
01289
01290 JString JString::toLowerCase( ) const {
01291 JString temp = Buffer;
01292 for ( unsigned int i = 0; i < Length; i++ )
01293 temp.Buffer[ i ] = tolower( temp.Buffer[ i ] );
01294 return temp;
01295 }
01296
01297 JString JString::toUpperCase() const {
01298 JString temp = Buffer;
01299
01300 for ( unsigned int i = 0; i < Length; i++ )
01301 temp.Buffer[ i ] = toupper( temp.Buffer[ i ] );
01302
01303 return temp;
01304 }
01305
01306 JString JString::trimLines() const {
01307 Collection lines = splitIntoLines();
01308 JString str = lines.get(0).trim();
01309 for (int n=1; n<lines.getCount(); n++)
01310 str += JString::format("\n%s", (char*) lines.get(n).trim());
01311 if (lines.getCount() > 1)
01312 str += "\n";
01313 return str;
01314 }
01315
01316 JString JString::trimLinesRemoveEmpty() const {
01317 Collection lines = splitIntoLines();
01318 JString str;
01319 int first = 0;
01320 int c = 0;
01321 while ( (first < lines.getCount()) && ( (str = lines.get(first).trim()).length() == 0) )
01322 first++;
01323 first++;
01324 JString s;
01325 for (int n=first; n<lines.getCount(); n++) {
01326 if ( (s = lines.get(n).trim()).length() > 0) {
01327 str += JString::format("\n%s", (char*) s);
01328 c++;
01329 }
01330 }
01331 if (c > 0)
01332 str += "\n";
01333 return str;
01334 }
01335
01336 JString JString::concatLines() const {
01337 Collection lines = splitIntoLines();
01338 JString str = lines.getFirst().trim();
01339 JString s;
01340 for (int n=1; n<lines.getCount(); n++) {
01341 if ( (s = lines.get(n).trim()).length() > 0)
01342 str += JString::format(" %s", (char*) s);
01343 }
01344 return str;
01345 }
01346
01347 JString JString::trimLeading() const {
01348 if (Length == 0)
01349 return *this;
01350
01351 unsigned int i;
01352
01353 for ( i = 0; i < Length; i++ )
01354 {
01355 if ( (unsigned char)Buffer[i] > 32 )
01356 break;
01357 }
01358
01359 return substring( i);
01360 }
01361
01362 JString JString::trimTrailing() const {
01363 if (Length == 0)
01364 return *this;
01365
01366 unsigned int j;
01367
01368 for ( j = Length - 1; j > 0; j-- )
01369 {
01370 if ( (unsigned char)Buffer[j] > 32 )
01371 break;
01372 }
01373
01374 return substring( 0, j + 1);
01375 }
01376
01377 JString JString::trim() const {
01378 if (Length == 0)
01379 return *this;
01380
01381 unsigned int i,j;
01382
01383 for ( i = 0; i < Length; i++ )
01384 {
01385 if ( (unsigned char)Buffer[i] > 32 )
01386 break;
01387 }
01388
01389 for ( j = Length - 1; j > i; j-- )
01390 {
01391 if ( (unsigned char)Buffer[j] > 32 )
01392 break;
01393 }
01394
01395 return substring( i, j + 1);
01396 }
01397
01398 JString JString::trimCTRL() const {
01399 if (Length == 0)
01400 return *this;
01401
01402 JString result = *this;
01403 unsigned int dstPos = 0;
01404 char* dst = result.Buffer;
01405 for (unsigned int n=0; n<Length; n++) {
01406 if ((unsigned char)Buffer[n] > 31)
01407 dst[dstPos++] = Buffer[n];
01408 }
01409 dst[dstPos] = 0;
01410 result.Length = dstPos;
01411 return result;
01412 }
01413
01414
01415
01416
01417 Collection JString::split(const JString& splitstr) const {
01418 Collection oc;
01419 int n, last;
01420
01421 if (Length == 0)
01422 return oc;
01423
01424 int len = splitstr.Length;
01425 if (len == 0) {
01426 oc.add(*this);
01427 return oc;
01428 }
01429
01430 n = 0;
01431 last = 0;
01432 while ((n = this->indexOf(splitstr, last)) >= 0) {
01433 oc.add(this->substring(last, n));
01434 last = n+len;
01435 }
01436
01437 oc.add(this->substring(last));
01438
01439 return oc;
01440 }
01441
01442
01443
01444
01445 Dictionary JString::split(const JString& splitstr, const JString& equalstr) const {
01446 Dictionary dict;
01447 Collection oc;
01448 int n, last;
01449
01450 int len = splitstr.Length;
01451 if (len == 0) {
01452 oc = this->split(equalstr);
01453 if (oc.getCount() == 2) {
01454 dict.put(oc.get(0), oc.get(1));
01455 }
01456 return dict;
01457 }
01458
01459 n = 0;
01460 last = 0;
01461 while ((n = this->indexOf(splitstr, last)) >= 0) {
01462 oc = this->substring(last, n).split(equalstr);
01463 if (oc.getCount() == 2) {
01464 dict.put(oc.get(0), oc.get(1));
01465 }
01466 last = n+len;
01467 }
01468
01469 oc = this->substring(last).split(equalstr);
01470 if (oc.getCount() == 2) {
01471 dict.put(oc.get(0), oc.get(1));
01472 }
01473
01474 return dict;
01475 }
01476
01477 Collection JString::splitIntoLines() const {
01478
01479 JString str = *this;
01480 str.replace("\r", "");
01481 Collection oc = str.split("\n");
01482
01483
01484
01485 return oc;
01486 }
01487
01488
01489 Collection JString::splitLinesOnWidth(int maxWidth) const {
01490
01491 Collection rawlines = this->splitIntoLines();
01492
01493
01494 Collection lines;
01495 for (int n=0; n<rawlines.getCount(); n++) {
01496 lines.addAll(rawlines.get(n).splitSingleLineOnWidth(maxWidth));
01497 }
01498 return lines;
01499 }
01500
01501
01502 Collection JString::splitSingleLineOnWidth(int maxWidth) const {
01503
01504 int len = Length;
01505
01506 Collection lines;
01507 if (len < maxWidth) {
01508 lines.add(*this);
01509 return lines;
01510 }
01511
01512 int start = 0;
01513 int p;
01514 int width;
01515
01516 while (true) {
01517 if (len > (start+maxWidth))
01518 width = maxWidth;
01519 else
01520 width = len - start - 1;
01521 p = start + width;
01522 while ( (p > start) && (this->charAt(p) != 32) )
01523 p--;
01524 if (p <= start) {
01525
01526 lines.add(this->substring(start, start+width));
01527 start += width;
01528 }
01529 else {
01530 lines.add(this->substring(start, p).trim());
01531 start = p+1;
01532 }
01533 if (len - start < maxWidth) {
01534 lines.add(this->substring(start).trim());
01535 break;
01536 }
01537 }
01538 return lines;
01539 }
01540
01541 Collection JString::splitOnWhiteSpaces() const {
01542
01543 Collection oc;
01544 int n, last;
01545 bool insideQuotes = false;
01546 unsigned char ch = 0, lastch;
01547
01548 last = 0;
01549 JString str;
01550 for (n=0; n<(int)Length; n++) {
01551 lastch = ch;
01552 ch = this->charAt(n);
01553 if ((ch < 33) && (!insideQuotes) && (lastch != '\\')) {
01554 if (last < n)
01555 oc.add(this->substring(last, n));
01556 last = n+1;
01557 }
01558 else if (ch == '"') {
01559 insideQuotes = !insideQuotes;
01560 }
01561 }
01562
01563 if (last < n)
01564 oc.add(this->substring(last));
01565
01566 return oc;
01567 }
01568
01569 Dictionary JString::splitCommandLine() const {
01570
01571 bool insideQuotes = false;
01572 bool lastWasWhiteSpace = false;
01573 Dictionary dict = Dictionary();
01574 JString arg, val, str;
01575 unsigned char ch;
01576
01577 Collection oc;
01578
01579 for (unsigned int n=0; n<Length; n++) {
01580
01581 ch = this->charAt(n);
01582
01583 if (ch <= 32) {
01584 if (!insideQuotes) {
01585 if (!lastWasWhiteSpace) {
01586
01587 oc = str.split("=");
01588 arg = oc.get(0);
01589 val = oc.get(1);
01590 if ( ( (val.startsWith("\"")) && (val.endsWith("\"")) ) ||
01591 ( (val.startsWith("'")) && (val.endsWith("'")) ) ) {
01592 val = val.substring(1, val.Length-1);
01593 }
01594 dict.put(arg, val);
01595 str = "";
01596 }
01597 else {
01598
01599 }
01600 lastWasWhiteSpace = true;
01601 }
01602 else {
01603 str += ch;
01604 }
01605 }
01606 else if (ch == '"') {
01607 insideQuotes = !insideQuotes;
01608 str += ch;
01609 lastWasWhiteSpace = false;
01610 }
01611 else {
01612 str += ch;
01613 lastWasWhiteSpace = false;
01614 }
01615 }
01616
01617 if (str.length() > 0) {
01618 oc = str.split("=");
01619 arg = oc.get(0);
01620 val = oc.get(1);
01621 if ( ( (val.startsWith("\"")) && (val.endsWith("\"")) ) ||
01622 ( (val.startsWith("'")) && (val.endsWith("'")) ) ) {
01623 val = val.substring(1, val.Length-1);
01624 }
01625 dict.put(arg, val);
01626 str = "";
01627 }
01628
01629 return dict;
01630 }
01631
01632
01633 bool JString::centerLines(unsigned int width) {
01634 if (Length == 0) return true;
01635
01636 Collection lines = this->splitIntoLines();
01637 int count = lines.getCount();
01638 int n;
01639 JString line;
01640
01641
01642 for(n=0; n<count; n++) {
01643 line = lines.get(n);
01644 if (line.length() > width)
01645 width = line.length();
01646 }
01647
01648 JString result;
01649 JString formatstring = JString::format("%%%ds", width);
01650
01651 for(n=0; n<count; n++)
01652 result += JString(lines.get(n), width, 2) + "\n";
01653 *this = result;
01654 return true;
01655 }
01656
01657 JString JString::repeat(const JString& str, int count) {
01658 unsigned int len = str.length();
01659 unsigned int maxlen = len*count;
01660 char* newstr = new char[maxlen + 1];
01661 unsigned int pos = 0;
01662 for (pos=0; pos < maxlen; pos += len)
01663 memcpy(newstr+pos, (char*)str, len);
01664 newstr[maxlen] = 0;
01665 JString result = newstr;
01666 delete [] newstr;
01667 return result;
01668 }
01669
01670 JString JString::fill(const JString& str, int width) {
01671 unsigned int len = str.length();
01672 unsigned int count = (unsigned int)(width/len);
01673 unsigned int leftover = width - (len*count);
01674
01675 char* newstr = new char[width + 1];
01676 unsigned int pos = 0;
01677 for (unsigned int n=0; n < count; n++) {
01678 memcpy(newstr+pos, (char*)str, len);
01679 pos += len;
01680 }
01681 memcpy(newstr+pos, (char*)str, leftover);
01682 newstr[width] = 0;
01683 JString result = newstr;
01684 delete [] newstr;
01685 return result;
01686 }
01687
01688 JString JString::asciiMessage(const JString& title, const JString& content, unsigned int width, const JString& borderchar) {
01689
01690 unsigned int borderwidth = 2*borderchar.length()+2;
01691 Collection lines = content.splitIntoLines();
01692
01693 unsigned int contentwidth = 0;
01694 for(int n=0; n<lines.getCount(); n++) {
01695 contentwidth = lines.get(n).length() + borderwidth;
01696 if (contentwidth > width)
01697 width = contentwidth;
01698 }
01699 contentwidth = title.length() + borderwidth;
01700 if (contentwidth > width)
01701 width = contentwidth;
01702
01703 contentwidth = width - borderwidth + 2;
01704
01705 JString borderline = JString::fill(borderchar, width);
01706
01707 JString result = borderline + "\n";
01708 result += borderchar + JString(title, contentwidth, 2) + borderchar + "\n";
01709 result += borderline + "\n";
01710
01711 for (int n = 0; n < lines.getCount(); n++) {
01712 result += borderchar + JString(lines.get(n), contentwidth, 2) + borderchar + "\n";
01713 }
01714 result += borderline + "\n";
01715
01716 return result;
01717 }
01718
01719
01720 bool JString::insert(JString str, int pos) {
01721 if (pos < 0)
01722 replace(0, 0, str);
01723 else if (pos > (int)Length)
01724 replace(Length, Length, str);
01725 else
01726 replace(pos, pos, str);
01727 return true;
01728 }
01729
01730 bool JString::removeChars(int count, int pos) {
01731 if (count < 0)
01732 return true;
01733 if ((pos < 0) || (pos > (int)Length-1))
01734 return false;
01735 if (count > (int)Length-pos)
01736 count = Length-pos;
01737 memmove(Buffer+pos, Buffer+pos+count, Length+1-pos-count);
01738 Length -= count;
01739 return true;
01740 }
01741
01742
01743
01744
01745 bool JString::matchesWithRegExp(const JString& regExp) const {
01746 RegExpParser parser(regExp);
01747 return (parser.is_reg_exp_present((char*)*this) == 1);
01748 }
01749
01750 bool JString::matchMyRegExpWith(const JString& text) const {
01751 RegExpParser parser((char*)*this);
01752 return (parser.is_reg_exp_present(text) == 1);
01753 }
01754
01755 bool JString::matchesIgnoreCase(const JString& match) const {
01756 JString str = this->toLowerCase();
01757 JString lmatch = match.toLowerCase();
01758 return str.matches(lmatch);
01759 }
01760
01761 bool JString::matches(const JString& ds) const {
01762
01763 if ( (!this->contains("*")) && (!ds.contains("*")) ) {
01764 return this->equals(ds);
01765 }
01766
01767 int n;
01768 Collection col1 = this->split("*");
01769 Collection col2 = ds.split("*");
01770
01771 if (this->startsWith("*")) {
01772 col1.removeFirst();
01773 col1.replace(0, JString::format("*%s", (char*) col1.getFirst()));
01774 }
01775 if (ds.startsWith("*")) {
01776 col2.removeFirst();
01777 col2.replace(0, JString::format("*%s", (char*) col2.getFirst()));
01778 }
01779 if (this->endsWith("*")) {
01780 col1.removeLast();
01781
01782
01783
01784 col1.replace(col1.getCount()-1, JString::format("%s*", (char*) col1.getLast()));
01785 }
01786 if (ds.endsWith("*")) {
01787 col2.removeLast();
01788
01789
01790
01791 col2.replace(col2.getCount()-1, JString::format("%s*", (char*) col2.getLast()));
01792 }
01793
01794 for (n=0; n<col1.getCount(); n++) {
01795 if (col1.getCount() > n+1) {
01796 if (n>0)
01797 col1.replace(n, JString::format("*%s*", (char*) col1.get(n)));
01798 else
01799 col1.replace(n, JString::format("%s*", (char*) col1.get(n)));
01800 }
01801 else if (col1.getCount() > 1) {
01802 col1.replace(n, JString::format("*%s", (char*) col1.get(n)));
01803 }
01804 }
01805
01806 for (n=0; n<col2.getCount(); n++) {
01807 if (col2.getCount() > n+1) {
01808 if (n>0)
01809 col2.replace(n, JString::format("*%s*", (char*) col2.get(n)));
01810 else
01811 col2.replace(n, JString::format("%s*", (char*) col2.get(n)));
01812 }
01813 else if (col2.getCount() > 1) {
01814 col2.replace(n, JString::format("*%s", (char*) col2.get(n)));
01815 }
01816 }
01817
01818
01819
01820
01821 JString str, str2;
01822 int pos1, pos2;
01823 while ( (str = col1.getFirst()).Length > 0) {
01824 str.replace("*", "");
01825 while ( (str2 = col2.getFirst()).Length > 0) {
01826 str2.replace("*", "");
01827 pos1 = str2.indexOf(str);
01828 pos2 = str.indexOf(str2);
01829 if (str.equals(str2)) {
01830 col1.removeFirst();
01831 col2.removeFirst();
01832 break;
01833 }
01834 else if ( (col1.getFirst().startsWith("*")) && (col1.getFirst().endsWith("*")) && (col2.getCount() > 1)) {
01835 col2.removeFirst();
01836 col1.removeFirst();
01837 if ( (str = col1.getFirst()).Length == 0)
01838 return true;
01839 str.replace("*", "");
01840 break;
01841 }
01842 else if ( (col2.getFirst().startsWith("*")) && (col2.getFirst().endsWith("*")) && (col1.getCount() > 1)) {
01843 col2.removeFirst();
01844 col1.removeFirst();
01845 if ( (str = col1.getFirst()).Length == 0)
01846 return true;
01847 str.replace("*", "");
01848 break;
01849 }
01850 else if ( (col1.getFirst().endsWith("*")) && (((pos1 == 0) || ( (pos1 > 0) && (col1.getFirst().startsWith("*")) ) ))) {
01851 col1.removeFirst();
01852 if ( (str = col1.getFirst()).Length == 0)
01853 return true;
01854 str.replace("*", "");
01855 break;
01856 }
01857 else if ((pos1 >= 0) &&
01858 (!col1.getFirst().endsWith("*")) &&
01859 (((pos1 == 0) || ( (pos1 == ((int)str2.Length-(int)str.Length)) && (col1.getFirst().startsWith("*")) ) ))) {
01860 col1.removeFirst();
01861 if ( (str = col1.getFirst()).Length == 0)
01862 return true;
01863 str.replace("*", "");
01864 break;
01865 }
01866 else if ( (col2.getFirst().endsWith("*")) && (((pos2 == 0) || ( (pos2 > 0) && (col2.getFirst().startsWith("*")) ) ))) {
01867 col2.removeFirst();
01868 break;
01869 }
01870 else if ((pos2 >= 0) &&
01871 (!col2.getFirst().endsWith("*")) &&
01872 (((pos2 == 0) || ( (pos2 == ((int)str.Length-(int)str2.Length)) && (col2.getFirst().startsWith("*")) ) ))) {
01873 col2.removeFirst();
01874 break;
01875 }
01876 else if ( (col1.getFirst().startsWith("*")) && (col2.getFirst().startsWith("*")) ) {
01877 if ( (col1.getCount() == 1) && (col2.getCount() == 1) &&
01878 (col1.getFirst().endsWith("*")) && (col2.getFirst().endsWith("*")) ) {
01879 return true;
01880 }
01881 else
01882 return false;
01883 }
01884 else if (col1.getFirst().startsWith("*")) {
01885 if ((pos1 >= 0) &&
01886 ((pos1 == ((int)str2.Length-(int)str.Length)) ||
01887 ( (pos1 < ((int)str2.Length-(int)str.Length)) && (col1.getFirst().endsWith("*")) ) )) {
01888 col1.removeFirst();
01889 if ( (str = col1.getFirst()).Length == 0)
01890 return true;
01891 str.replace("*", "");
01892 break;
01893 }
01894 else if (col2.getCount() > 1) {
01895 col2.removeFirst();
01896 break;
01897 }
01898 else
01899 return false;
01900 }
01901 else if (col2.getFirst().startsWith("*")) {
01902 if ((pos2 >= 0) &&
01903 ((pos2 == ((int)str.Length-(int)str2.Length)) ||
01904 ( (pos2 < ((int)str.Length-(int)str2.Length)) && (col2.getFirst().endsWith("*")) ) )) {
01905 col2.removeFirst();
01906 break;
01907 }
01908 else if (col1.getCount() > 1) {
01909 if ( (str = col1.getFirst()).Length == 0)
01910 return true;
01911 str.replace("*", "");
01912 break;
01913 }
01914 else
01915 return false;
01916 }
01917 else {
01918 return false;
01919 }
01920 }
01921
01922
01923
01924
01925 if (col2.getCount() == 0)
01926 return true;
01927 }
01928
01929 return true;
01930 }
01931
01932
01933
01934
01935
01936
01937
01938
01939
01940
01941
01942 int JString::toInt() const {
01943 return atoi(charpoint());
01944 }
01945
01946 bool JString::toBool() const {
01947 if ((equalsIgnoreCase("true")) ||
01948 (equalsIgnoreCase("yes")) )
01949 return true;
01950 else
01951 return false;
01952 }
01953
01954 void* JString::toPointer() const {
01955 void* ptr = NULL;
01956 if (sscanf(this->charpoint(), "%p", &ptr) != 1)
01957 return NULL;
01958 return ptr;
01959 }
01960
01961 long JString::toLong() const {
01962 return atol(charpoint());
01963 }
01964
01965 double JString::toDouble() const {
01966 char *stopstring;
01967 return (strtod( charpoint(), &stopstring));
01968 }
01969
01970 long long JString::toLongLong() const {
01971 #if defined(WIN32)
01972 #if defined(CYGWIN)
01973 return atoll( charpoint() );
01974 #else
01975 return _atoi64( charpoint() );
01976 #endif
01977 #else
01978 return atoll( charpoint() );
01979 #endif
01980 }
01981
01982 unsigned int JString::toUnsignedInt() const {
01983 return (unsigned int) strtoul(charpoint(),NULL,0);
01984 }
01985
01986 unsigned long JString::toUnsignedLong() const {
01987 return strtoul(charpoint(),NULL,0);
01988 }
01989
01990 unsigned long long JString::toUnsignedLongLong() const {
01991 #if defined(WIN32)
01992 #if defined(CYGWIN)
01993 return strtoull(charpoint(),NULL,0);
01994 #else
01995 return _strtoui64(charpoint(), NULL, 0);
01996 #endif
01997 #else
01998 return strtoull(charpoint(),NULL,0);
01999 #endif
02000 }
02001
02002
02003
02004
02005
02006
02007
02008
02009
02010
02011
02012
02013
02014
02015
02016
02017
02018
02019 JString JString::operator+( char* aChar )
02020 {
02021 JString str = *this;
02022 str += aChar;
02023 return str;
02024 }
02025
02026 JString JString::operator+(const JString& other ) {
02027 JString str = *this;
02028 str += other;
02029 return str;
02030 }
02031
02032 JString JString::operator+( char* aChar ) const
02033 {
02034 JString str = *this;
02035 str += aChar;
02036 return str;
02037 }
02038
02039 JString JString::operator+(const JString& other ) const {
02040 JString str = *this;
02041 str += other;
02042 return str;
02043 }
02044
02045 JString JString::removeCRs() {
02046 JString str = *this;
02047
02048 str.replace("\n", "");
02049 str.replace("\r", "");
02050
02051 return str;
02052 }
02053
02054 JString JString::removeCRTabs() {
02055 JString str = *this;
02056
02057 str.replace("\n", "");
02058 str.replace("\r", "");
02059 str.replace("\t", "");
02060
02061 return str;
02062 }
02063
02064 JString JString::replaceCRs() {
02065 JString str = *this;
02066
02067 str.replace("\n", "*CR*");
02068 str.replace("\r", "*LF*");
02069
02070 return str;
02071 }
02072
02073 JString JString::restoreCRs() {
02074 JString str = *this;
02075
02076 str.replace("*CR*", "\n");
02077 str.replace("*LF*", "\r");
02078
02079 return str;
02080 }
02081
02082 #define CHARREPLACE(var,ch,str) case ch: strcat(var, str); break;
02083
02084 JString JString::toHTML() {
02085
02086 if (Length == 0)
02087 return "";
02088
02089 char c;
02090
02091 const char* input = this->Buffer;
02092
02093
02094 char* tmp = (char*)malloc(20);
02095 JString str;
02096 str.setBufferSizeInline(Length*2);
02097
02098 while ((c = *input++)) {
02099 if (c == '\n') {
02100 str += "<br>\n";
02101 }
02102 else if (c == '\r') {
02103 }
02104 else if (c == '\t') {
02105 str += " \n";
02106 }
02107 else if ( (c < 32) || (c > 122) ||
02108 ( (c > 90) && (c < 97) ) ||
02109 ( (c > 57) && (c < 65) ) ||
02110 ( (c > 33) && (c < 48) ) ) {
02111 sprintf(tmp, "&#x%x;", (int) c & 0xFF);
02112 str += tmp;
02113
02114 }
02115 else {
02116 str += c;
02117
02118
02119 }
02120 }
02121
02122
02123
02124 free((char*)tmp);
02125
02126 return str;
02127 }
02128
02129
02130 #define ADDCHAR(var,ch) var[strlen(var)+1] = 0; var[strlen(var)] = ch;
02131
02132 char HTML2Char(char* s) {
02133 JString str = s;
02134 if (strcmp(str, "&") == 0)
02135 return '&';
02136 else if (strcmp(str, "<") == 0)
02137 return '<';
02138 else if (strcmp(str, ">") == 0)
02139 return '>';
02140 else if (strcmp(str, """) == 0)
02141 return '"';
02142 else if (strcmp(str, "&apos") == 0)
02143 return '\'';
02144 else if (strcmp(str, "&lsquo") == 0)
02145 return '‘';
02146 else if (strcmp(str, "&rsquo") == 0)
02147 return '’';
02148 else if (strcmp(str, "&sbquo") == 0)
02149 return '‚';
02150 else if (strcmp(str, "&ldquo") == 0)
02151 return '“';
02152 else if (strcmp(str, "&rdquo") == 0)
02153 return '”';
02154 else if (strcmp(str, "&bdquo") == 0)
02155 return '„';
02156 else if (strcmp(str, "&dagger") == 0)
02157 return '†';
02158 else if (strcmp(str, "&Dagger") == 0)
02159 return '‡';
02160 else if (strcmp(str, "&permil") == 0)
02161 return '‰';
02162 else if (strcmp(str, "&lsaquo") == 0)
02163 return '‹';
02164 else if (strcmp(str, "&rsaquo") == 0)
02165 return '›';
02166 else if (strcmp(str, "&trade") == 0)
02167 return '™';
02168 else
02169 return 0;
02170 }
02171
02172 char Dec2Char(char* str) {
02173 return atoi(str);
02174 }
02175
02176 char Hex2Char(char* str) {
02177 char c1 = toupper(str[0]);
02178 char c2 = toupper(str[1]);
02179 unsigned short i1 = 0;
02180 if (c1 < 48) {
02181 return 0;
02182 }
02183 else {
02184 i1 = c1-48;
02185 if (i1 > 9)
02186 i1 = c1-55;
02187 }
02188 unsigned short i2 = 0;
02189 if (c2 < 48) {
02190 return (char)i1;
02191 }
02192 else {
02193 i2 = c2-48;
02194 if (i2 > 9)
02195 i2 = c2-55;
02196 return (char)(i1*16 + i2);
02197 }
02198 }
02199
02200 JString JString::fromHTML() {
02201
02202 if (Length == 0)
02203 return "";
02204
02205 char c, ch;
02206
02207 char* semi;
02208
02209
02210 char* input = Buffer;
02211
02212
02213 JString str;
02214 str.setBufferSizeInline(Length);
02215
02216 while ((c = *input++)) {
02217 switch (c) {
02218 case '&':
02219 semi = strchr(input, ';');
02220 if ( (semi == NULL) || (semi - input > 10) ) {
02221
02222 return *this;
02223 }
02224 semi[0] = 0;
02225 if (*input == '#') {
02226
02227 if (*(input+1) == 'x')
02228 ch = Hex2Char(input+2);
02229 else
02230 ch = Dec2Char(input+1);
02231 }
02232 else {
02233 ch = HTML2Char(input-1);
02234 }
02235
02236 str += ch;
02237 input = semi+1;
02238 semi[0] = ';';
02239 break;
02240 case '%':
02241 ch = Hex2Char(input);
02242
02243 str += ch;
02244 input+=2;
02245 break;
02246 case '+':
02247
02248 str += ' ';
02249 break;
02250 default:
02251
02252 str += c;
02253 }
02254 }
02255
02256
02257
02258
02259 str.replace("<br>", "\n");
02260
02261 return str;
02262 }
02263
02264 JString JString::xmlStringEncode() const {
02265 if (Length == 0)
02266 return "";
02267
02268
02269
02270
02271
02272
02273
02274
02275
02276
02277
02278 char c;
02279 char* input = this->Buffer;
02280 JString str;
02281 str.setBufferSizeInline(Length*2);
02282 char* tmp = NULL;
02283
02284 while ((c = *input++)) {
02285 switch(c) {
02286 case '&':
02287 str += "&";
02288 break;
02289 case '<':
02290 str += "<";
02291 break;
02292 case '>':
02293 str += ">";
02294 break;
02295 case '"':
02296 str += """;
02297 break;
02298 case '\'':
02299 str += "'";
02300 break;
02301 default:
02302 if ((c < 32) || (c > 126)) {
02303 if (tmp == NULL)
02304 tmp = (char*)malloc(20);
02305 sprintf(tmp, "&#x%x;", (int) c & 0xFF);
02306 str += tmp;
02307 }
02308 else
02309 str += c;
02310 break;
02311 }
02312 }
02313 free((char*)tmp);
02314 return str;
02315 }
02316
02317 JString JString::xmlStringDecode() const {
02318 if (Length == 0)
02319 return "";
02320 if (strchr(Buffer, '&') == NULL)
02321 return *this;
02322
02323 char c, ch;
02324 char* input = this->Buffer;
02325 char* semi;
02326 JString str;
02327 str.setBufferSizeInline(Length);
02328
02329 while ((c = *input++)) {
02330 switch (c) {
02331 case '&':
02332 semi = strchr(input, ';');
02333 if ( (semi == NULL) || (semi - input > 10) ) {
02334
02335 return *this;
02336 }
02337 semi[0] = 0;
02338 if (*input == '#') {
02339 if (*(input+1) == 'x')
02340 ch = Hex2Char(input+2);
02341 else
02342 ch = Dec2Char(input+1);
02343 }
02344 else {
02345 ch = HTML2Char(input-1);
02346 }
02347 str += ch;
02348 input = semi+1;
02349 semi[0] = ';';
02350 break;
02351
02352
02353
02354
02355
02356
02357
02358
02359 default:
02360 str += c;
02361 }
02362 }
02363 return str;
02364 }
02365
02366
02367
02368 int JString::indexOfIgnoreCase( const JString &str ) const {
02369 return indexOfIgnoreCase(str, 0);
02370 }
02371
02372 int JString::indexOfIgnoreCase( const JString &str, unsigned int fromIndex ) const {
02373 return (this->toLowerCase().indexOf(str.toLowerCase(), fromIndex));
02374 }
02375
02376 int JString::lastIndexOfIgnoreCase( const JString &str ) const {
02377 return lastIndexOfIgnoreCase(str, 0);
02378 }
02379
02380 int JString::lastIndexOfIgnoreCase( const JString &str, unsigned int fromIndex ) const {
02381 return (this->toLowerCase().lastIndexOf(str.toLowerCase(), fromIndex));
02382 }
02383
02384 bool JString::startsWithIgnoreCase( const JString &prefix ) const {
02385 return startsWithIgnoreCase(prefix.toLowerCase(), 0);
02386 }
02387
02388 bool JString::startsWithIgnoreCase( const JString &prefix, unsigned int toffset ) const {
02389 return (this->toLowerCase().startsWith(prefix.toLowerCase(), toffset));
02390 }
02391
02392 bool JString::containsIgnoreCase( const JString& str) const {
02393 return this->toLowerCase().contains(str.toLowerCase());
02394 }
02395
02396 bool JString::endsWithIgnoreCase( const JString &suffix ) const {
02397 return (this->toLowerCase().endsWith(suffix.toLowerCase()));
02398 }
02399
02400
02401
02402
02403
02404
02405
02406
02407
02408 #ifdef WIN32
02409
02410
02411
02412
02413 JString::JString(wchar_t wch) {
02414
02415 Buffer = NULL;
02416 Length = BufferLen = 0;
02417 isCRTerminated = false;
02418
02419 setBufferSizeInline(Length = 1);
02420 strcpy(Buffer, "");
02421 #ifdef WIN32
02422 lpwBuffer = NULL;
02423 #endif
02424
02425 wchar_t str[2];
02426 str[0] = wch;
02427 str[1] = 0;
02428 this->operator+=((LPWSTR)str);
02429 }
02430
02431 JString::JString(LPWSTR lstr) {
02432
02433 Buffer = NULL;
02434 Length = BufferLen = 0;
02435 char* buffer = NULL;
02436 isCRTerminated = false;
02437 int res = WideCharToMultiByte(CP_ACP, 0, lstr, -1, NULL, 0, NULL, NULL);
02438
02439 if (res > 0) {
02440 buffer = (char*)malloc(res+10);
02441 res = WideCharToMultiByte(CP_ACP, 0, lstr, -1, buffer, res+10, NULL, NULL);
02442 }
02443
02444 if ((res > 0) && (buffer != NULL)) {
02445
02446 setBufferSizeInline(Length = (unsigned int) strlen(buffer));
02447 strcpy(Buffer, buffer);
02448 }
02449 else {
02450
02451 setBufferSizeInline(Length = 1);
02452 strcpy(Buffer, "");
02453 }
02454
02455 free((char*)buffer);
02456 #ifdef WIN32
02457 lpwBuffer = NULL;
02458 #endif
02459 }
02460
02461 bool JString::toUnicode() {
02462 if (lpwBuffer != NULL)
02463 free((char*)lpwBuffer);
02464 lpwBuffer = (WCHAR*)malloc((Length+1)*sizeof(WCHAR));
02465 return (MultiByteToWideChar(CP_ACP, MB_PRECOMPOSED, Buffer, -1, lpwBuffer, Length+1) != 0);
02466 }
02467
02468 JString::operator LPWSTR() {
02469 if (lpwBuffer == NULL)
02470 toUnicode();
02471 return lpwBuffer;
02472 }
02473
02474 JString JString::operator+(LPWSTR wstr) {
02475 JString str = JString(wstr);
02476 return (*this) + str;
02477 }
02478
02479 const JString& JString::operator+=(LPWSTR wstr) {
02480 JString other = JString(wstr);
02481 setBufferSizeInline(Length + other.Length);
02482 memcpy(Buffer+Length, other.Buffer, other.Length);
02483 Length += other.Length;
02484 Buffer[Length] = 0;
02485 return *this;
02486 }
02487
02488 JString JString::operator+(wchar_t wch) {
02489 JString str = *this;
02490 str += wch;
02491 return str;
02492 }
02493
02494 const JString& JString::operator+=(wchar_t wch) {
02495 wchar_t str[2];
02496 str[0] = wch;
02497 str[1] = 0;
02498 return this->operator+=((LPWSTR)str);
02499 }
02500
02501
02502
02503
02504
02505
02506
02507
02508
02509 JString::operator const unsigned short*() {
02510 toUnicode();
02511 return (const unsigned short *) lpwBuffer;
02512 }
02513
02514
02515
02516
02517
02518
02519
02520
02521
02522 bool JString::utf2unicode() {
02523
02524
02525 if (lpwBuffer != NULL)
02526 free((char*)lpwBuffer);
02527 int len = MultiByteToWideChar(CP_UTF8, 0, Buffer, -1, NULL, 0);
02528
02529 lpwBuffer = (WCHAR*)malloc((len+1)*sizeof(WCHAR));
02530 int res = MultiByteToWideChar(CP_UTF8, 0, Buffer, -1, lpwBuffer, len+1);
02531
02532
02533
02534
02535
02536
02537
02538
02539
02540
02541
02542
02543
02544
02545
02546 return (res != 0);
02547
02548
02549
02550
02551
02552
02553
02554
02555
02556
02557
02558
02559
02560
02561
02562
02563
02564
02565
02566
02567
02568
02569
02570 }
02571
02572 bool JString::unicode2utf() {
02573 char* buffer = NULL;
02574 isCRTerminated = false;
02575 int res = WideCharToMultiByte(CP_UTF8, 0, lpwBuffer, -1, NULL, 0, NULL, NULL);
02576
02577 if (res > 0) {
02578 buffer = (char*)malloc(res+10);
02579 res = WideCharToMultiByte(CP_UTF8, 0, lpwBuffer, -1, buffer, res+10, NULL, NULL);
02580 }
02581
02582 if ((res > 0) && (buffer != NULL)) {
02583
02584 setBufferSizeInline(Length = (unsigned int) strlen(buffer));
02585 strcpy(Buffer, buffer);
02586 free((char*)buffer);
02587 }
02588 else {
02589
02590 setBufferSizeInline(Length = 1);
02591 strcpy(Buffer, "");
02592 free((char*)buffer);
02593 return false;
02594 }
02595 return true;
02596 }
02597
02598
02599
02600
02601
02602
02603
02604
02605
02606
02607
02608
02609
02610
02611
02612
02613
02614
02615
02616
02617
02618
02619
02620
02621
02622
02623
02624
02625
02626
02627 #endif // WIN32
02628
02629
02630
02631
02632
02633
02634
02635 JString JString::scriptGetSection(const JString& tagname) {
02636 JString startTag = JString::format("<!-- start:%s ", (char*) tagname.trim());
02637 JString endTag = JString::format("<!-- end:%s ", (char*) tagname.trim());
02638
02639 int startPos = indexOf(startTag);
02640 if (startPos < 0) return "";
02641 int startEndPos = indexOf("-->", startPos);
02642 if (startEndPos < 0) return "";
02643
02644 int endPos = indexOf(endTag, startEndPos);
02645 if (endPos < 0) return "";
02646 int endEndPos = indexOf("-->", endPos);
02647 if (endEndPos < 0) return "";
02648
02649 return substring(startEndPos + 3, endPos);
02650 }
02651
02652 Dictionary JString::scriptGetSectionParameters(const JString& tagname) {
02653 Dictionary ownParams;
02654 JString startTag = JString::format("<!-- start:%s ", (char*) tagname.trim());
02655 JString endTag = JString::format("<!-- end:%s ", (char*) tagname.trim());
02656
02657 int startPos = indexOf(startTag);
02658 if (startPos < 0) return ownParams;
02659 int startEndPos = indexOf("-->", startPos);
02660 if (startEndPos < 0) return ownParams;
02661
02662 int endPos = indexOf(endTag, startEndPos);
02663 if (endPos < 0) return ownParams;
02664 int endEndPos = indexOf("-->", endPos);
02665 if (endEndPos < 0) return ownParams;
02666
02667 JString paramString = substring(startPos + startTag.Length, startEndPos).trim();
02668 JString param;
02669 Collection col = paramString.splitOnWhiteSpaces();
02670 Collection pcol;
02671 for (int n=0; n<col.getCount(); n++) {
02672 param = col.get(n);
02673 if ( param.contains("=") ) {
02674 pcol = param.split("=");
02675 param = pcol.get(1).trim();
02676 param.replace("\"", "");
02677 ownParams.put(pcol.get(0).trim(), param);
02678 }
02679 }
02680 return ownParams;
02681 }
02682
02683 bool JString::scriptReplaceSection(const JString& tagname, const JString& text) {
02684 JString startTag = JString::format("<!-- start:%s ", (char*) tagname.trim());
02685 JString endTag = JString::format("<!-- end:%s ", (char*) tagname.trim());
02686
02687 int startPos = indexOf(startTag);
02688 if (startPos < 0) return false;
02689 int startEndPos = indexOf("-->", startPos);
02690 if (startEndPos < 0) return false;
02691
02692 int endPos = indexOf(endTag, startEndPos);
02693 if (endPos < 0) return false;
02694 int endEndPos = indexOf("-->", endPos);
02695 if (endEndPos < 0) return false;
02696
02697 replace(startPos, endEndPos+3, text);
02698 return true;
02699 }
02700
02701
02702 int
02703 JString::scriptReplace(const JString& tagname, ObjectCollection* replacements) {
02704
02705 int n;
02706
02707 JString startTag = JString::format("<!-- start:%s ", (char*) tagname.trim());
02708 JString endTag = JString::format("<!-- end:%s ", (char*) tagname.trim());
02709
02710 int startPos = indexOf(startTag);
02711 if (startPos < 0) return 0;
02712 int startEndPos = indexOf("-->", startPos);
02713 if (startEndPos < 0) return 0;
02714
02715 int endPos = indexOf(endTag, startEndPos);
02716 if (endPos < 0) return 0;
02717 int endEndPos = indexOf("-->", endPos);
02718 if (endEndPos < 0) return 0;
02719
02720 JString newString = "";
02721 if ( (replacements == NULL) || (replacements->getCount() == 0) ) {
02722 this->replace(startPos, endEndPos+3, newString);
02723 return 0;
02724 }
02725
02726
02727
02728 JString mainString = substring(startEndPos + 3, endPos);
02729
02730 Dictionary ownParams = Dictionary();
02731 JString paramString = substring(startPos + startTag.Length, startEndPos).trim();
02732 JString param;
02733 Collection col = paramString.splitOnWhiteSpaces();
02734 Collection pcol;
02735 for (n=0; n<col.getCount(); n++) {
02736 param = col.get(n);
02737 if ( param.contains("=") ) {
02738 pcol = param.split("=");
02739 param = pcol.get(1).trim();
02740 param.replace("\"", "");
02741 ownParams.put(pcol.get(0).trim(), param);
02742 }
02743 }
02744
02745 JString debugString = ownParams.printListLine("|");
02746
02747 int c, pos, count=0;
02748 JString mainStringCopy, replace;
02749 Collection* lines;
02750 for (n=0; n<replacements->getCount(); n++) {
02751 mainStringCopy = mainString;
02752 if ( (lines = (Collection*) replacements->get(n)) != NULL ) {
02753 for (c=99; c>0; c--) {
02754 replace = lines->get(c-1);
02755 if (replace.equalsIgnoreCase("%default")) {
02756 replace = ownParams.get(JString(c));
02757 if (replace.contains(";")) {
02758 col = replace.split(";");
02759 pos = count%(col.getCount());
02760 replace = col.get(pos);
02761 }
02762 }
02763 mainStringCopy.replace(JString::format("%%%d", c), replace);
02764 }
02765 count++;
02766 newString += mainStringCopy;
02767 }
02768 }
02769
02770 this->replace(startPos, endEndPos+3, newString);
02771 return count;
02772 }
02773
02774
02775
02776
02777 int
02778 JString::scriptReplaceDictionary(const JString& tagname, ObjectCollection* replacements) {
02779
02780 int n;
02781
02782 JString startTag = JString::format("<!-- start:%s ", (char*) tagname.trim());
02783 JString endTag = JString::format("<!-- end:%s ", (char*) tagname.trim());
02784
02785 int startPos = indexOf(startTag);
02786 if (startPos < 0) return 0;
02787 int startEndPos = indexOf("-->", startPos);
02788 if (startEndPos < 0) return 0;
02789
02790 int endPos = indexOf(endTag, startEndPos);
02791 if (endPos < 0) return 0;
02792 int endEndPos = indexOf("-->", endPos);
02793 if (endEndPos < 0) return 0;
02794
02795
02796
02797 JString mainString = substring(startEndPos + 3, endPos);
02798 JString newString = "";
02799
02800 Dictionary ownParams = Dictionary();
02801 JString paramString = substring(startPos + startTag.Length, startEndPos).trim();
02802 JString param;
02803 Collection col = paramString.splitOnWhiteSpaces();
02804 Collection pcol;
02805 for (n=0; n<col.getCount(); n++) {
02806 param = col.get(n);
02807 if ( param.contains("=") ) {
02808 pcol = param.split("=");
02809 param = pcol.get(1).trim();
02810 param.replace("\"", "");
02811 ownParams.put(pcol.get(0).trim(), param);
02812 }
02813 }
02814
02815 JString debugString = ownParams.printListLine("|");
02816
02817 int pos, count=0;
02818 JString mainStringCopy, replace;
02819 Dictionary* lines;
02820 JString key;
02821 for (n=0; n<replacements->getCount(); n++) {
02822 mainStringCopy = mainString;
02823 if ( (lines = (Dictionary*) replacements->get(n)) != NULL ) {
02824 for (key=lines->getFirstKey(); key.length() > 0; key=lines->getNextKey()) {
02825 replace = lines->get(key);
02826 if (replace.equalsIgnoreCase("%default")) {
02827 replace = ownParams.get(key);
02828 if (replace.contains(";")) {
02829 col = replace.split(";");
02830 pos = count%(col.getCount());
02831 replace = col.get(pos);
02832 }
02833 }
02834 mainStringCopy.replace(JString::format("%%%s", (char*)key), replace);
02835 }
02836 count++;
02837 newString += mainStringCopy;
02838 }
02839 }
02840
02841 this->replace(startPos, endEndPos+3, newString);
02842 return count;
02843 }
02844
02845
02846
02847
02848 JString JString::bytifySize(long val) {
02849 return bytifySize((double)val);
02850 }
02851
02852 JString JString::bytifySize(double val) {
02853
02854 double kb = 1024;
02855 double mb = kb*1024;
02856 double gb = mb*1024;
02857 double tb = gb*1024;
02858
02859 if (val < 512)
02860 return JString::format("%.2f B", val);
02861 else if (val < 512*kb) {
02862 val = val / kb;
02863 return JString::format("%.2f KB", val);
02864 }
02865 else if (val < 512*mb) {
02866 val = val / mb;
02867 return JString::format("%.2f MB", val);
02868 }
02869 else if (val < 512*gb) {
02870 val = val / gb;
02871 return JString::format("%.2f GB", val);
02872 }
02873 else {
02874 val = val / tb;
02875 return JString::format("%.2f TB", val);
02876 }
02877 }
02878
02879 JString JString::bytifySizes(long val1, long val2) {
02880 return bytifySizes((double)val1, (double) val2);
02881 }
02882
02883 JString JString::bytifySizes(double val1, double val2) {
02884
02885 double kb = 1024;
02886 double mb = kb*1024;
02887 double gb = mb*1024;
02888 double tb = gb*1024;
02889
02890 JString end;
02891 double val;
02892 double maximum = ((val1 > val2) ? val1 : val2);
02893
02894 if (maximum < 512) {
02895 val = 1;
02896 end = "B";
02897 }
02898 else if (maximum < 512*kb) {
02899 val = kb;
02900 end = "KB";
02901 }
02902 else if (maximum < 512*mb) {
02903 val = mb;
02904 end = "MB";
02905 }
02906 else if (maximum < 512*gb) {
02907 val = gb;
02908 end = "GB";
02909 }
02910 else {
02911 val = gb;
02912 end = "TB";
02913 }
02914 return JString::format("%.2f / %.2f %s", ((double)val1)/val, ((double)val2)/val, (char*) end);
02915 }
02916
02917 JString JString::bytifyRate(long val) {
02918 return bytifyRate((double)val);
02919 }
02920
02921 JString JString::bytifyRate(double val) {
02922 return JString::format("%s/sec", (char*) bytifySize(val));
02923 }
02924
02925 JString JString::bytifyRates(long val1, long val2) {
02926 return bytifyRates((double)val1, (double)val2);
02927 }
02928
02929 JString JString::bytifyRates(double val1, double val2) {
02930 return JString::format("%s/sec", (char*) bytifySizes(val1, val2));
02931 }
02932
02933
02934 JString JString::xml2html() const {
02935
02936 JString html;
02937 if (Length == 0)
02938 return html;
02939
02940 XMLParser parser;
02941 parser.parseComments = true;
02942 if (!parser.parseXML(*this))
02943 return html;
02944
02945 XMLNode* rootnode = parser.getRootNode();
02946 if (rootnode == NULL)
02947 return html;
02948
02949 html = rootnode->toHTML();
02950 return html;
02951 }
02952
02953
02954
02955 bool JString::setBufferSize(unsigned int size) {
02956 return setBufferSizeInline(size);
02957 }
02958
02959 inline bool
02960 JString::doubleBufferInline() {
02961 return setBufferSizeInline(BufferLen * 2);
02962 }
02963
02964 inline bool
02965 JString::setBufferSizeInline(unsigned int size) {
02966 if ((BufferLen >= size) && (Buffer != NULL) && (BufferLen > 0))
02967 return true;
02968
02969 char* newBuffer = (char*)realloc(Buffer, size+1);
02970 if (newBuffer == NULL)
02971 return false;
02972
02973
02974
02975
02976
02977
02978 Buffer = newBuffer;
02979 BufferLen = size;
02980
02981 return true;
02982 }
02983
02984
02985
02986
02987
02988
02989
02990
02991
02992
02993
02994
02995
02996
02997
02998
02999
03000
03001
03002
03003
03004
03005
03006
03007
03008
03009
03010
03011
03012
03013
03014
03015
03016
03017
03018
03019
03020
03021
03022
03023
03024
03025
03026
03027
03028
03029
03030
03031
03032
03033
03034
03035
03036
03037
03038
03039
03040
03041
03042
03043
03044
03045
03046
03047
03048
03049
03050
03051
03052
03053
03054 char *cGREP_errors[] = {
03055 "Invalid argument",
03056 "Insufficient expression",
03057 "Parse overload",
03058 "Mismatched () or []",
03059 "Extraneous characters",
03060 "Illegal use of * or +",
03061 "Illegal nesting",
03062 "Illegal [] range",
03063 "Illegal ?, +, or * usage",
03064 "Illegal backslashes",
03065 NULL};
03066
03067
03068
03069 RegExpParser::RegExpParser( char *exp ) {
03070 Special_chars = "^$.[()|?+*\\";
03071 an_error_has_occured = 0;
03072 strcpy( error_string, "" );
03073 if( exp == NULL ) {
03074 record_error( 0 );
03075 return;
03076 }
03077 Input_scan_pointer = exp;
03078 parentheses_count = 1;
03079 symbol_string_size = 0L;
03080 code_emit_pointer = ®_exp_shadow;
03081 char sigval = (char) SIGNATURE_VALUE;
03082 emit_next_byte(sigval);
03083 int flags;
03084 if( parse_parens( 0, &flags ) == NULL ) {
03085 record_error( 1 );
03086 return;
03087 }
03088 Input_scan_pointer = exp;
03089 parentheses_count = 1;
03090 code_emit_pointer = symbol_string;
03091 emit_next_byte(sigval);
03092 if( parse_parens( 0, &flags ) == NULL ) {
03093 record_error( 1 );
03094 return;
03095 }
03096 first_char_of_regexp = CHAR_ZERO;
03097 is_anchored = 0;
03098 required_substring = NULL;
03099 length_required_substring = 0;
03100 char *scan = symbol_string + 1;
03101 if( MAK_CHAR_2_OPCODE( get_next_pointer( scan ) ) == OP_END ) {
03102 scan = MAK_CONTROLLING_OPERAND( scan );
03103 if( MAK_CHAR_2_OPCODE( scan ) == OP_EXACT )
03104 first_char_of_regexp = *MAK_CONTROLLING_OPERAND( scan );
03105 else if( MAK_CHAR_2_OPCODE( scan ) == OP_BOL )
03106 is_anchored++;
03107 if( flags & BIT_OPENS_ON_STAR_OR_PLUS ) {
03108 char *longest = NULL;
03109 unsigned int len = 0;
03110 for( ; scan != NULL; scan = get_next_pointer( scan ) )
03111 if( MAK_CHAR_2_OPCODE( scan ) == OP_EXACT && strlen( MAK_CONTROLLING_OPERAND( scan ) ) >= len ) {
03112 longest = MAK_CONTROLLING_OPERAND( scan );
03113 len = (unsigned int)strlen( MAK_CONTROLLING_OPERAND( scan ) );
03114 }
03115 required_substring = longest;
03116 length_required_substring = len;
03117 }
03118 }
03119 }
03120
03121
03122
03123
03124 int RegExpParser::is_reg_exp_present( char *string ) {
03125 char *s;
03126 if( string == NULL ) {
03127 record_error( 0 );
03128 return( 0 );
03129 }
03130 if( MAK_AS_UNSIGNED( symbol_string ) != SIGNATURE_VALUE ) {
03131 record_error( 2 );
03132 return( 0 );
03133 }
03134 if( required_substring != NULL ) {
03135 s = string;
03136 while( ( s = strchr( s, required_substring[ 0 ] ) ) != NULL ) {
03137 if( strncmp( s, required_substring, length_required_substring ) == 0 )
03138 break;
03139 s++;
03140 }
03141 if( s == NULL )
03142 return( 0 );
03143 }
03144 beginning_of_input = string;
03145 if( is_anchored )
03146 return( evaluate_next( string ) );
03147 s = string;
03148 if( first_char_of_regexp != CHAR_ZERO )
03149 while( ( s = strchr( s, first_char_of_regexp ) ) != NULL ) {
03150 if( evaluate_next( s ) )
03151 return( 1 );
03152 s++;
03153 }
03154 else do {
03155 if( evaluate_next( s ) )
03156 return( 1 );
03157 } while( *s++ != CHAR_ZERO );
03158 return( 0 );
03159 }
03160
03161
03162 void RegExpParser::record_error( int n ) {
03163 strcpy( error_string, cGREP_errors[ n ] );
03164 ++an_error_has_occured;
03165 }
03166
03167
03168 char* RegExpParser::parse_parens( int paren, int *flagp ) {
03169 *flagp = BIT_MORE_THAN_NULL;
03170 char *ret = NULL;
03171 int parno = 0;
03172 if( paren ) {
03173 if( parentheses_count >= MAX_SUB_EXPRESSIONS ) {
03174 record_error( 3 );
03175 return( NULL );
03176 }
03177 parno = parentheses_count;
03178 parentheses_count++;
03179 ret = emit_node( OP_OPEN + parno );
03180 } else
03181 ret = NULL;
03182 int flags;
03183 char *br = one_side_of_or_operator( &flags );
03184 if( br == NULL )
03185 return( NULL );
03186 if( ret != NULL )
03187 go_to_end_of_chain( ret, br );
03188 else
03189 ret = br;
03190 if( !( flags & BIT_MORE_THAN_NULL ) )
03191 *flagp &= ~BIT_MORE_THAN_NULL;
03192 *flagp |= flags & BIT_OPENS_ON_STAR_OR_PLUS;
03193 while( *Input_scan_pointer == CHAR_OR ) {
03194 Input_scan_pointer++;
03195 br = one_side_of_or_operator( &flags );
03196 if( br == NULL )
03197 return( NULL );
03198 go_to_end_of_chain( ret, br );
03199 if( !( flags&BIT_MORE_THAN_NULL ) )
03200 *flagp &= ~BIT_MORE_THAN_NULL;
03201 *flagp |= flags & BIT_OPENS_ON_STAR_OR_PLUS;
03202 }
03203 char *ender = emit_node( ( paren ) ? OP_CLOSE + parno : OP_END );
03204 go_to_end_of_chain( ret, ender );
03205 for( br = ret; br != NULL; br = get_next_pointer( br ) )
03206 go_to_end_of_chain_on_operand( br, ender );
03207 if( paren && *Input_scan_pointer++ != CHAR_CLOSE_PAREN ) {
03208 record_error( 3 );
03209 return( NULL );
03210 } else if( !paren && *Input_scan_pointer != CHAR_ZERO ) {
03211 if( *Input_scan_pointer == CHAR_CLOSE_PAREN ) {
03212 record_error( 3 );
03213 return( NULL );
03214 } else
03215 record_error( 4 );
03216 return( NULL );
03217 }
03218 return( ret );
03219 }
03220
03221
03222 char* RegExpParser::one_side_of_or_operator( int *flagp ) {
03223 int flags = 0;
03224 char *ret = NULL;
03225 *flagp = BIT_CAN_MATCH_NOTHING;
03226 ret = emit_node( OP_BRANCH );
03227 char *chain = NULL;
03228 char *latest = NULL;
03229 while( *Input_scan_pointer != CHAR_ZERO && *Input_scan_pointer != CHAR_OR && *Input_scan_pointer != CHAR_CLOSE_PAREN ) {
03230 latest = trailing_wild( &flags );
03231 if( latest == NULL )
03232 return( NULL );
03233 *flagp |= flags & BIT_MORE_THAN_NULL;
03234 if( chain == NULL )
03235 *flagp |= flags & BIT_OPENS_ON_STAR_OR_PLUS;
03236 else
03237 go_to_end_of_chain( chain, latest );
03238 chain = latest;
03239 }
03240 if( chain == NULL )
03241 (void) emit_node( OP_NMEMPTY );
03242 return( ret );
03243 }
03244
03245
03246
03247 char* RegExpParser::trailing_wild( int *flagp ) {
03248 int flags = 0;
03249 char *ret = compress_ordinary_characters( &flags );
03250 char *next = NULL;
03251 if( ret == NULL )
03252 return( NULL );
03253 char op = *Input_scan_pointer;
03254 if( !MAK_IS_COMPOUND( op ) ) {
03255 *flagp = flags;
03256 return( ret );
03257 }
03258 if( !( flags & BIT_MORE_THAN_NULL ) && op != CHAR_QUESTION ) {
03259 record_error( 5 );
03260 return( NULL );
03261 }
03262 *flagp =( op != CHAR_PLUS ) ?( BIT_CAN_MATCH_NOTHING | BIT_OPENS_ON_STAR_OR_PLUS ) :
03263 ( BIT_CAN_MATCH_NOTHING | BIT_MORE_THAN_NULL );
03264 if( op == CHAR_STAR &&( flags & BIT_STAR_OR_PLUS_OK ) )
03265 insert_operator( OP_STAR, ret );
03266 else if( op == CHAR_STAR ) {
03267 insert_operator( OP_BRANCH, ret );
03268 go_to_end_of_chain_on_operand( ret, emit_node( OP_BACK ) );
03269 go_to_end_of_chain_on_operand( ret, ret );
03270 go_to_end_of_chain( ret, emit_node( OP_BRANCH ) );
03271 go_to_end_of_chain( ret, emit_node( OP_NMEMPTY ) );
03272 } else if( op == CHAR_PLUS &&( flags&BIT_STAR_OR_PLUS_OK ) )
03273 insert_operator( OP_PLUS, ret );
03274 else if( op == CHAR_PLUS ) {
03275 next = emit_node( OP_BRANCH );
03276 go_to_end_of_chain( ret, next );
03277 go_to_end_of_chain( emit_node( OP_BACK ), ret );
03278 go_to_end_of_chain( next, emit_node( OP_BRANCH ) );
03279 go_to_end_of_chain( ret, emit_node( OP_NMEMPTY ) );
03280 } else if( op == CHAR_QUESTION ) {
03281 insert_operator( OP_BRANCH, ret );
03282 go_to_end_of_chain( ret, emit_node( OP_BRANCH ) );
03283 next = emit_node( OP_NMEMPTY );
03284 go_to_end_of_chain( ret, next );
03285 go_to_end_of_chain_on_operand( ret, next );
03286 }
03287 Input_scan_pointer++;
03288 if( MAK_IS_COMPOUND( *Input_scan_pointer ) ) {
03289 record_error( 6 );
03290 return( NULL );
03291 }
03292 return( ret );
03293 }
03294
03295
03296 char* RegExpParser::compress_ordinary_characters( int *flagp ) {
03297 char *ret = NULL;
03298 int flags = 0;
03299 *flagp = BIT_CAN_MATCH_NOTHING;
03300 switch( *Input_scan_pointer++ ) {
03301 case CHAR_HOCH:
03302 ret = emit_node( OP_BOL );
03303 break;
03304 case CHAR_DOLLAR:
03305 ret = emit_node( OP_EOL );
03306 break;
03307 case CHAR_PERIOD:
03308 ret = emit_node( OP_ANY );
03309 *flagp |= BIT_MORE_THAN_NULL | BIT_STAR_OR_PLUS_OK;
03310 break;
03311 case CHAR_OPEN_BRACKET: {
03312 int gjv_reg_class;
03313 int classend;
03314 if( *Input_scan_pointer == CHAR_HOCH ) {
03315 ret = emit_node( OP_ANYBUT );
03316 Input_scan_pointer++;
03317 } else
03318 ret = emit_node( OP_ANYOF );
03319 if( *Input_scan_pointer == CHAR_CLOSE_BRACKET || *Input_scan_pointer == CHAR_MINUS )
03320 emit_next_byte( *Input_scan_pointer++ );
03321 while( *Input_scan_pointer != CHAR_ZERO && *Input_scan_pointer != CHAR_CLOSE_BRACKET ) {
03322 if( *Input_scan_pointer == CHAR_MINUS ) {
03323 Input_scan_pointer++;
03324 if( *Input_scan_pointer == CHAR_CLOSE_BRACKET || *Input_scan_pointer == CHAR_ZERO )
03325 emit_next_byte( CHAR_MINUS );
03326 else {
03327 gjv_reg_class = MAK_AS_UNSIGNED( Input_scan_pointer - 2 ) + 1;
03328 classend = MAK_AS_UNSIGNED( Input_scan_pointer );
03329 if( gjv_reg_class > classend + 1 ) {
03330 record_error( 7 );
03331 return( NULL );
03332 }
03333 for( ; gjv_reg_class <= classend; gjv_reg_class++ )
03334 emit_next_byte( gjv_reg_class );
03335 Input_scan_pointer++;
03336 }
03337 } else
03338 emit_next_byte( *Input_scan_pointer++ );
03339 }
03340 emit_next_byte( CHAR_ZERO );
03341 if( *Input_scan_pointer != CHAR_CLOSE_BRACKET ) {
03342 record_error( 3 );
03343 return( NULL );
03344 }
03345 Input_scan_pointer++;
03346 *flagp |= BIT_MORE_THAN_NULL | BIT_STAR_OR_PLUS_OK; }
03347 break;
03348 case CHAR_OPEN_PAREN:
03349 ret = parse_parens( 1, &flags );
03350 if( ret == NULL )
03351 return( NULL );
03352 *flagp |= flags & ( BIT_MORE_THAN_NULL | BIT_OPENS_ON_STAR_OR_PLUS );
03353 break;
03354 case CHAR_ZERO:
03355 case CHAR_OR:
03356 case CHAR_CLOSE_PAREN:
03357 record_error( 2 );
03358 return( NULL );
03359 case CHAR_QUESTION:
03360 case CHAR_PLUS:
03361 case CHAR_STAR:
03362 record_error( 8 );
03363 return( NULL );
03364 case CHAR_DOUBLE_BSLASH:
03365 if( *Input_scan_pointer == CHAR_ZERO ) {
03366 record_error( 9 );
03367 return( NULL );
03368 }
03369 ret = emit_node( OP_EXACT );
03370 emit_next_byte( *Input_scan_pointer++ );
03371 emit_next_byte( CHAR_ZERO );
03372 *flagp |= BIT_MORE_THAN_NULL | BIT_STAR_OR_PLUS_OK;
03373 break;
03374 default: {
03375 int len;
03376 char ender;
03377 Input_scan_pointer--;
03378 len = (int)strcspn( Input_scan_pointer, Special_chars );
03379 if( len <= 0 ) {
03380 record_error( 2 );
03381 return( NULL );
03382 }
03383 ender = *( Input_scan_pointer+len );
03384 if( len > 1 && MAK_IS_COMPOUND( ender ) )
03385 len--;
03386 *flagp |= BIT_MORE_THAN_NULL;
03387 if( len == 1 )
03388 *flagp |= BIT_STAR_OR_PLUS_OK;
03389 ret = emit_node( OP_EXACT );
03390 while( len > 0 ) {
03391 emit_next_byte( *Input_scan_pointer++ );
03392 len--;
03393 }
03394 emit_next_byte( CHAR_ZERO ); }
03395 break;
03396 }
03397 return( ret );
03398 }
03399
03400
03401 char* RegExpParser::emit_node( char op ) {
03402 char *ret = code_emit_pointer;
03403 if( ret == ®_exp_shadow ) {
03404 symbol_string_size += 3;
03405 return( ret );
03406 }
03407 char *ptr = ret;
03408 *ptr++ = op;
03409 *ptr++ = CHAR_ZERO;
03410 *ptr++ = CHAR_ZERO;
03411 code_emit_pointer = ptr;
03412 return( ret );
03413 }
03414
03415
03416 void RegExpParser::emit_next_byte( char b ) {
03417 if( code_emit_pointer != ®_exp_shadow )
03418 *code_emit_pointer++ = b;
03419 else
03420 symbol_string_size++;
03421 }
03422
03423
03424 void RegExpParser::insert_operator( char op, char *opnd ) {
03425 if( code_emit_pointer == ®_exp_shadow ) {
03426 symbol_string_size += 3;
03427 return;
03428 }
03429 char *src = code_emit_pointer;
03430 code_emit_pointer += 3;
03431 char *dst = code_emit_pointer;
03432 while( src > opnd )
03433 *--dst = *--src;
03434 char *place = opnd;
03435 *place++ = op;
03436 *place++ = CHAR_ZERO;
03437 *place++ = CHAR_ZERO;
03438 }
03439
03440
03441 void RegExpParser::go_to_end_of_chain( char *p, char *val ) {
03442 int offset = 0;
03443 if( p == ®_exp_shadow )
03444 return;
03445 char *scan = p;
03446 for( ;; ) {
03447 char *temp = get_next_pointer( scan );
03448 if( temp == NULL )
03449 break;
03450 scan = temp;
03451 }
03452 if( MAK_CHAR_2_OPCODE( scan ) == OP_BACK )
03453 offset = (int)(scan - val);
03454 else
03455 offset = (int)(val - scan);
03456 *( scan + 1 ) = ( offset >> 8 ) & 0xFF;
03457 *( scan + 2 ) = offset & 0xFF;
03458 }
03459
03460
03461 void RegExpParser::go_to_end_of_chain_on_operand( char *p, char *val ) {
03462 if( p == NULL || p == ®_exp_shadow || MAK_CHAR_2_OPCODE( p ) != OP_BRANCH )
03463 return;
03464 go_to_end_of_chain( MAK_CONTROLLING_OPERAND( p ), val );
03465 }
03466
03467
03468 int RegExpParser::lookup_engine( char *prog ) {
03469 char *scan = prog;
03470 char *next = NULL;
03471 while( scan != NULL ) {
03472 next = get_next_pointer( scan );
03473 switch( MAK_CHAR_2_OPCODE( scan ) ) {
03474 case OP_BOL:
03475 if( input_string_pointer != beginning_of_input )
03476 return( 0 );
03477 break;
03478 case OP_EOL:
03479 if( *input_string_pointer != CHAR_ZERO )
03480 return( 0 );
03481 break;
03482 case OP_ANY:
03483 if( *input_string_pointer == CHAR_ZERO )
03484 return( 0 );
03485 input_string_pointer++;
03486 break;
03487 case OP_EXACT: {
03488 int len;
03489 char *opnd;
03490 opnd = MAK_CONTROLLING_OPERAND( scan );
03491 if( *opnd != *input_string_pointer )
03492 return( 0 );
03493 len = (int)strlen( opnd );
03494 if( len > 1 && strncmp( opnd, input_string_pointer, len ) != 0 )
03495 return( 0 );
03496 input_string_pointer += len;}
03497 break;
03498 case OP_ANYOF:
03499 if( *input_string_pointer == CHAR_ZERO || strchr( MAK_CONTROLLING_OPERAND( scan ), *input_string_pointer ) == NULL )
03500 return( 0 );
03501 input_string_pointer++;
03502 break;
03503 case OP_ANYBUT:
03504 if( *input_string_pointer == CHAR_ZERO || strchr( MAK_CONTROLLING_OPERAND( scan ), *input_string_pointer ) != NULL )
03505 return( 0 );
03506 input_string_pointer++;
03507 break;
03508 case OP_NMEMPTY:
03509 break;
03510 case OP_BACK:
03511 break;
03512 case OP_OPEN + 1:
03513 case OP_OPEN + 2:
03514 case OP_OPEN + 3:
03515 case OP_OPEN + 4:
03516 case OP_OPEN + 5:
03517 case OP_OPEN + 6:
03518 case OP_OPEN + 7:
03519 case OP_OPEN + 8:
03520 case OP_OPEN + 9: {
03521 int no;
03522 char *save;
03523 no = MAK_CHAR_2_OPCODE( scan ) - OP_OPEN;
03524 save = input_string_pointer;
03525 if( lookup_engine( next ) ) {
03526 if( pointer_to_rembh[ no ] == NULL )
03527 pointer_to_rembh[ no ] = save;
03528 return( 1 );
03529 } else
03530 return( 0 );}
03531 break;
03532 case OP_CLOSE + 1:
03533 case OP_CLOSE + 2:
03534 case OP_CLOSE + 3:
03535 case OP_CLOSE + 4:
03536 case OP_CLOSE + 5:
03537 case OP_CLOSE + 6:
03538 case OP_CLOSE + 7:
03539 case OP_CLOSE + 8:
03540 case OP_CLOSE + 9: {
03541 int no;
03542 char *save;
03543 no = MAK_CHAR_2_OPCODE( scan ) - OP_CLOSE;
03544 save = input_string_pointer;
03545 if( lookup_engine( next ) ) {
03546 if( pointer_to_remeh[ no ] == NULL )
03547 pointer_to_remeh[ no ] = save;
03548 return( 1 );
03549 } else
03550 return( 0 ); }
03551 break;
03552 case OP_BRANCH: {
03553 char *save;
03554 if( MAK_CHAR_2_OPCODE( next ) != OP_BRANCH )
03555 next = MAK_CONTROLLING_OPERAND( scan );
03556 else {
03557 do {
03558 save = input_string_pointer;
03559 if( lookup_engine( MAK_CONTROLLING_OPERAND( scan ) ) )
03560 return( 1 );
03561 input_string_pointer = save;
03562 scan = get_next_pointer( scan );
03563 } while( scan != NULL && MAK_CHAR_2_OPCODE( scan ) == OP_BRANCH );
03564 return( 0 );
03565 }}
03566 break;
03567 case OP_STAR:
03568 case OP_PLUS: {
03569 char nextch;
03570 int no;
03571 char *save;
03572 int min;
03573 nextch = CHAR_ZERO;
03574 if( MAK_CHAR_2_OPCODE( next ) == OP_EXACT )
03575 nextch = *MAK_CONTROLLING_OPERAND( next );
03576 min = ( MAK_CHAR_2_OPCODE( scan ) == OP_STAR ) ? 0 : 1;
03577 save = input_string_pointer;
03578 no = wildcard_lookup( MAK_CONTROLLING_OPERAND( scan ) );
03579 while( no >= min ) {
03580 if( nextch == CHAR_ZERO || *input_string_pointer == nextch )
03581 if( lookup_engine( next ) )
03582 return( 1 );
03583 no--;
03584 input_string_pointer = save + no;
03585 }
03586 return( 0 );}
03587 break;
03588 case OP_END:
03589 return( 1 );
03590 default:
03591 record_error( 2 );
03592 return( 0 );
03593 }
03594 scan = next;
03595 }
03596 record_error( 2 );
03597 return( 0 );
03598 }
03599
03600
03601 int RegExpParser::wildcard_lookup( char *p ) {
03602 int count = 0;
03603 char *scan = input_string_pointer;
03604 char *opnd = MAK_CONTROLLING_OPERAND( p );
03605 switch( MAK_CHAR_2_OPCODE( p ) ) {
03606 case OP_ANY:
03607 count = (int)strlen( scan );
03608 scan += count;
03609 break;
03610 case OP_EXACT:
03611 while( *opnd == *scan ) {
03612 count++;
03613 scan++;
03614 }
03615 break;
03616 case OP_ANYOF:
03617 while( *scan != CHAR_ZERO && strchr( opnd, *scan ) != NULL ) {
03618 count++;
03619 scan++;
03620 }
03621 break;
03622 case OP_ANYBUT:
03623 while( *scan != CHAR_ZERO && strchr( opnd, *scan ) == NULL ) {
03624 count++;
03625 scan++;
03626 }
03627 break;
03628 default:
03629 record_error( 2 );
03630 count = 0;
03631 return( 0 );
03632 }
03633 input_string_pointer = scan;
03634 return( count );
03635 }
03636
03637
03638 char* RegExpParser::get_next_pointer( char *p ) {
03639 if( p == ®_exp_shadow )
03640 return( NULL );
03641 int offset = MAK_GET_NEXT( p );
03642 if( offset == 0 )
03643 return( NULL );
03644 if( MAK_CHAR_2_OPCODE( p ) == OP_BACK )
03645 return( p - offset );
03646 else
03647 return( p + offset );
03648 }
03649
03650
03651 int RegExpParser::evaluate_next( char *string ) {
03652 input_string_pointer = string;
03653 pointer_to_rembh = reg_exp_match_begins_here;
03654 pointer_to_remeh = reg_exp_match_ends_here;
03655 char **sp = reg_exp_match_begins_here;
03656 char **ep = reg_exp_match_ends_here;
03657 for( int i = MAX_SUB_EXPRESSIONS; i > 0; i-- ) {
03658 *sp++ = NULL;
03659 *ep++ = NULL;
03660 }
03661 if( lookup_engine( symbol_string + 1 ) ) {
03662 reg_exp_match_begins_here[ 0 ] = string;
03663 reg_exp_match_ends_here[ 0 ] = input_string_pointer;
03664 return( 1 );
03665 } else
03666 return( 0 );
03667 }
03668
03669 unsigned long JString::getHash() const {
03670 char* str = Buffer;
03671 unsigned long hash = 0;
03672 int c;
03673 while (c = *str++)
03674 hash = c + (hash << 6) + (hash << 16) - hash;
03675 return hash;
03676 }
03677
03678
03679
03680
03681
03682
03683
03684
03685
03686
03687
03688 bool JString::unitTest() {
03689 JString str, str2, strExp;
03690 addUnitTestLog("Starting JString UnitTest...");
03691
03692 addUnitTestLog("Starting Boolex UnitTest...");
03693 Boolex* bx = new Boolex();
03694
03695 str = "((mytext is one) and (mytext is two))";
03696 strExp = "((mytext is one) AND (mytext is two))";
03697 if (bx->setExpression(str)) {
03698 str2 = bx->print();
03699 if (!str2.equalsIgnoreCase(strExp)) {
03700 addUnitTestLog(JString::format("Boolex result failed:\n%s\n%s\n%s\n", (char*) str, (char*) str2, (char*) strExp));
03701 return false;
03702 }
03703 }
03704 else {
03705 addUnitTestLog(JString::format("Boolex parsing failed:\n%s\n", (char*) str));
03706 return false;
03707 }
03708
03709 str = "(mytext is one and mytext is two)";
03710 strExp = "((mytext is one) AND (mytext is two))";
03711 if (bx->setExpression(str)) {
03712 str2 = bx->print();
03713 if (!str2.equalsIgnoreCase(strExp)) {
03714 addUnitTestLog(JString::format("Boolex result failed:\n%s\n%s\n%s\n", (char*) str, (char*) str2, (char*) strExp));
03715 return false;
03716 }
03717 }
03718 else {
03719 addUnitTestLog(JString::format("Boolex parsing failed:\n%s\n", (char*) str));
03720 return false;
03721 }
03722
03723 str = "(mytext is one) and (mytext is two)";
03724 strExp = "((mytext is one) AND (mytext is two))";
03725 if (bx->setExpression(str)) {
03726 str2 = bx->print();
03727 if (!str2.equalsIgnoreCase(strExp)) {
03728 addUnitTestLog(JString::format("Boolex result failed:\n%s\n%s\n%s\n", (char*) str, (char*) str2, (char*) strExp));
03729 return false;
03730 }
03731 }
03732 else {
03733 addUnitTestLog(JString::format("Boolex parsing failed:\n%s\n", (char*) str));
03734 return false;
03735 }
03736
03737 str = "mytext is one and mytext is two";
03738 strExp = "((mytext is one) AND (mytext is two))";
03739 if (bx->setExpression(str)) {
03740 str2 = bx->print();
03741 if (!str2.equalsIgnoreCase(strExp)) {
03742 addUnitTestLog(JString::format("Boolex result failed:\n%s\n%s\n%s\n", (char*) str, (char*) str2, (char*) strExp));
03743 return false;
03744 }
03745 }
03746 else {
03747 addUnitTestLog(JString::format("Boolex parsing failed:\n%s\n", (char*) str));
03748 return false;
03749 }
03750
03751 str = "((mytext is one) and (mytext is two) or (mytext is three))";
03752 strExp = "((mytext is one) AND (mytext is two) OR (mytext is three))";
03753 if (bx->setExpression(str)) {
03754 str2 = bx->print();
03755 if (!str2.equalsIgnoreCase(strExp)) {
03756 addUnitTestLog(JString::format("Boolex result failed:\n%s\n%s\n%s\n", (char*) str, (char*) str2, (char*) strExp));
03757 return false;
03758 }
03759 }
03760 else {
03761 addUnitTestLog(JString::format("Boolex parsing failed:\n%s\n", (char*) str));
03762 return false;
03763 }
03764
03765 str = "((mytext is one) and (mytext is two)) or (mytext is three)";
03766 strExp = "(((mytext is one) AND (mytext is two)) OR (mytext is three))";
03767 if (bx->setExpression(str)) {
03768 str2 = bx->print();
03769 if (!str2.equalsIgnoreCase(strExp)) {
03770 addUnitTestLog(JString::format("Boolex result failed:\n%s\n%s\n%s\n", (char*) str, (char*) str2, (char*) strExp));
03771 return false;
03772 }
03773 }
03774 else {
03775 addUnitTestLog(JString::format("Boolex parsing failed:\n%s\n", (char*) str));
03776 return false;
03777 }
03778
03779 str = "(((mytext is one) and (mytext is two)) or (mytext is three))";
03780 strExp = "(((mytext is one) AND (mytext is two)) OR (mytext is three))";
03781 if (bx->setExpression(str)) {
03782 str2 = bx->print();
03783 if (!str2.equalsIgnoreCase(strExp)) {
03784 addUnitTestLog(JString::format("Boolex result failed:\n%s\n%s\n%s\n", (char*) str, (char*) str2, (char*) strExp));
03785 return false;
03786 }
03787 }
03788 else {
03789 addUnitTestLog(JString::format("Boolex parsing failed:\n%s\n", (char*) str));
03790 return false;
03791 }
03792
03793 str = "((mytext is one) and not (mytext is two))";
03794 strExp = "((mytext is one) AND NOT (mytext is two))";
03795 if (bx->setExpression(str)) {
03796 str2 = bx->print();
03797 if (!str2.equalsIgnoreCase(strExp)) {
03798 addUnitTestLog(JString::format("Boolex result failed:\n%s\n%s\n%s\n", (char*) str, (char*) str2, (char*) strExp));
03799 return false;
03800 }
03801 }
03802 else {
03803 addUnitTestLog(JString::format("Boolex parsing failed:\n%s\n", (char*) str));
03804 return false;
03805 }
03806
03807 str = "(not (mytext is one) and not (mytext is two))";
03808 strExp = "(NOT (mytext is one) AND NOT (mytext is two))";
03809 if (bx->setExpression(str)) {
03810 str2 = bx->print();
03811 if (!str2.equalsIgnoreCase(strExp)) {
03812 addUnitTestLog(JString::format("Boolex result failed:\n%s\n%s\n%s\n", (char*) str, (char*) str2, (char*) strExp));
03813 return false;
03814 }
03815 }
03816 else {
03817 addUnitTestLog(JString::format("Boolex parsing failed:\n%s\n", (char*) str));
03818 return false;
03819 }
03820
03821 str = "not ((mytext is one) and not (mytext is two))";
03822 strExp = "NOT ((mytext is one) AND NOT (mytext is two))";
03823 if (bx->setExpression(str)) {
03824 str2 = bx->print();
03825 if (!str2.equalsIgnoreCase(strExp)) {
03826 addUnitTestLog(JString::format("Boolex result failed:\n%s\n%s\n%s\n", (char*) str, (char*) str2, (char*) strExp));
03827 return false;
03828 }
03829 }
03830 else {
03831 addUnitTestLog(JString::format("Boolex parsing failed:\n%s\n", (char*) str));
03832 return false;
03833 }
03834
03835 bx->strAND = "&&";
03836 bx->strOR = "||";
03837 bx->strNOT = "!";
03838 str = "! ((mytext is one) || ! (mytext is two) && ! (mytext is two))";
03839 strExp = "! ((mytext is one) || ! (mytext is two) && ! (mytext is two))";
03840 if (bx->setExpression(str)) {
03841 str2 = bx->print();
03842 if (!str2.equalsIgnoreCase(strExp)) {
03843 addUnitTestLog(JString::format("Boolex result failed:\n%s\n%s\n%s\n", (char*) str, (char*) str2, (char*) strExp));
03844 return false;
03845 }
03846 }
03847 else {
03848 addUnitTestLog(JString::format("Boolex parsing failed:\n%s\n", (char*) str));
03849 return false;
03850 }
03851
03852 delete(bx);
03853 return true;
03854 }
03855
03856
03857
03858
03859
03860 Boolex::Boolex() {
03861 boolex = NULL;
03862 isNegated = false;
03863 operators = new Collection();
03864 boolexes = new ObjectCollection();
03865 strAND = "AND";
03866 strOR = "OR";
03867 strXOR = "XOR";
03868 strNOT = "NOT";
03869 }
03870
03871 Boolex::Boolex(const JString& str) {
03872 boolex = NULL;
03873 isNegated = false;
03874 operators = new Collection();
03875 boolexes = new ObjectCollection();
03876 strAND = "AND";
03877 strOR = "OR";
03878 strXOR = "XOR";
03879 strNOT = "NOT";
03880 if (str.looksLikeXML())
03881 Object::fromXML(str);
03882 else
03883 setExpression(str);
03884 }
03885
03886 Boolex::Boolex(XMLNode* node) {
03887 boolex = NULL;
03888 isNegated = false;
03889 operators = new Collection();
03890 boolexes = new ObjectCollection();
03891 strAND = "AND";
03892 strOR = "OR";
03893 strXOR = "XOR";
03894 strNOT = "NOT";
03895 fromXML(node);
03896 }
03897
03898 Boolex::~Boolex() {
03899 delete(boolex);
03900 boolex = NULL;
03901 delete(operators);
03902 operators = NULL;
03903 delete(boolexes);
03904 boolexes = NULL;
03905 }
03906
03907 bool Boolex::reset() {
03908 text = "";
03909 delete(boolex);
03910 boolex = NULL;
03911 isNegated = false;
03912 operators->removeAll();
03913 boolexes->removeAll();
03914 return true;
03915 }
03916
03917
03918 bool Boolex::fromXML(XMLNode* node) {
03919 if (node == NULL)
03920 return false;
03921
03922 if (!node->getTag().equalsIgnoreCase("boolex"))
03923 return false;
03924
03925 return setExpression(node->getText());
03926 }
03927
03928
03929
03930 bool Boolex::equals(const Object* o2) const {
03931 if (o2 == NULL) return false;
03932 return toText().equalsIgnoreCase(((Boolex*)o2)->toText());
03933 }
03934
03935 Object* Boolex::clone() const {
03936 Boolex* bx = new Boolex();
03937 bx->strAND = strAND;
03938 bx->strOR = strOR;
03939 bx->strXOR = strXOR;
03940 bx->strNOT = strNOT;
03941 bx->text = text;
03942 if (boolex != NULL)
03943 bx->boolex = (Boolex*) boolex->clone();
03944 if (operators->getCount() > 0) {
03945 bx->operators->addAll(operators);
03946 bx->boolexes->copyAll(boolexes);
03947 }
03948 return bx;
03949 }
03950
03951 JString Boolex::toXML() {
03952 return JString::format("<boolex>%s</boolex>", (char*) toText().xmlStringEncode());
03953 }
03954
03955 JString Boolex::print() {
03956 return toText();
03957 }
03958
03959 JString Boolex::toText() const {
03960 JString str;
03961 if (boolex != NULL) {
03962 str = boolex->print();
03963 }
03964 else if (text.length() > 0) {
03965 if (isNegated)
03966 str = JString::format("%s (%s)", (char*) strNOT, (char*) text);
03967 else
03968 str = JString::format("(%s)", (char*) text);
03969 }
03970 else
03971 return "";
03972 if (boolexes->getCount() == 0)
03973 return str;
03974
03975 JString opr;
03976 Boolex* bx;
03977 for (int n=0; n<boolexes->getCount(); n++) {
03978 if ( (bx = (Boolex*) boolexes->get(n)) != NULL) {
03979 if ( (opr = operators->get(n)).length() > 0) {
03980 str = JString::format("%s %s %s", (char*) str, (char*) opr.toUpperCase(), (char*) bx->print());
03981 }
03982 }
03983 }
03984 if (isNegated)
03985 return JString::format("%s (%s)", (char*) strNOT, (char*) str);
03986 else
03987 return JString::format("(%s)", (char*) str);
03988 }
03989
03990 bool Boolex::setExpression(const JString& str) {
03991 reset();
03992 JString fullStr = enforceParentheses(str);
03993 if (fullStr.length() == 0)
03994 return false;
03995 if ( (!fullStr.contains("(")) && (!fullStr.contains(")")) && (!containsReservedWords(str))) {
03996 text = fullStr;
03997 return true;
03998 }
03999 else
04000 return parseExpression(fullStr);
04001 }
04002
04003 bool Boolex::parseExpression(const JString& str) {
04004 return parseParentheses(str);
04005 }
04006
04007 bool Boolex::isReservedWord(const JString& word) {
04008 return ( word.equalsIgnoreCase(strAND) || word.equalsIgnoreCase(strOR)
04009 || word.equalsIgnoreCase(strXOR) || word.equalsIgnoreCase(strNOT) );
04010 }
04011
04012 bool Boolex::containsReservedWords(const JString& text) {
04013 return ( text.containsIgnoreCase(strAND) || text.containsIgnoreCase(strOR)
04014 || text.containsIgnoreCase(strXOR) || text.containsIgnoreCase(strNOT) );
04015 }
04016
04017 JString Boolex::enforceParentheses(JString str) {
04018
04019 if (!containsReservedWords(str))
04020 return str;
04021
04022 if ( str.indexOfCount("(") != str.indexOfCount(")") )
04023 return "";
04024
04025 str.replace("( ", "(");
04026 str.replace(" )", ")");
04027
04028 str.replaceIgnoreCase(JString::format("(%s", (char*) strNOT), JString::format("( %s ", (char*) strNOT));
04029
04030
04031
04032
04033 Collection words = str.splitOnWhiteSpaces();
04034 JString word;
04035 int first = -1, last = -1;
04036 for (int n=0; n<words.getCount(); n++) {
04037 word = words.get(n);
04038 if (!isReservedWord(word)) {
04039 if ( (!word.equals("(")) && (!word.equals(")"))) {
04040 if (first == -1)
04041 first = n;
04042 last = n;
04043 }
04044 }
04045 else if (first >= 0) {
04046 if ( (!words.get(first).startsWith("(")) || (!words.get(last).endsWith(")")) ) {
04047
04048
04049
04050 words.replace(first, JString::format("(%s", (char*) words.get(first)));
04051
04052
04053
04054 words.replace(last, JString::format("%s)", (char*) words.get(last)));
04055 }
04056 first = last = -1;
04057 }
04058 }
04059 if (first >= 0) {
04060 if ( (!words.get(first).startsWith("(")) || (!words.get(last).endsWith(")")) ) {
04061
04062
04063
04064 words.replace(first, JString::format("(%s", (char*) words.get(first)));
04065
04066
04067
04068 words.replace(last, JString::format("%s)", (char*) words.get(last)));
04069 }
04070 }
04071 return words.printListLine(" ");
04072 }
04073
04074 bool Boolex::parseParentheses(const JString& str) {
04075
04076 if ( str.indexOfCount("(") != str.indexOfCount(")") )
04077 return false;
04078
04079 int n, m;
04080 int pcount = 0;
04081 int len = str.length();
04082 JString lastWord, secondLastWord, opr, text;
04083 int lastSpace=0, secondLastSpace=0, thirdLastSpace=0;
04084 for (n=0; n<len; n++) {
04085 if (str[n] == ' ') {
04086 thirdLastSpace = secondLastSpace;
04087 secondLastSpace = lastSpace;
04088 lastSpace = n;
04089 }
04090 else if (str[n] == '(') {
04091
04092 pcount = 1;
04093 for (m=n+1; m<len; m++) {
04094 if (str[m] == '(')
04095 pcount++;
04096 else if (str[m] == ')') {
04097 pcount--;
04098 if (pcount == 0) {
04099
04100 text = str.substring(n+1, m).trim();
04101 Boolex* bx = new Boolex();
04102 bx->strAND = strAND;
04103 bx->strOR = strOR;
04104 bx->strXOR = strXOR;
04105 bx->strNOT = strNOT;
04106 bx->setExpression(text);
04107 if (boolex == NULL) {
04108
04109 lastWord = str.substring(secondLastSpace, lastSpace).trim();
04110
04111 if (lastWord.equalsIgnoreCase(strNOT)) {
04112 bx->isNegated = true;
04113 }
04114 boolex = bx;
04115 }
04116 else {
04117
04118 lastWord = str.substring(secondLastSpace, lastSpace).trim();
04119 secondLastWord = str.substring(thirdLastSpace, secondLastSpace).trim();
04120
04121 if (lastWord.equalsIgnoreCase(strNOT)) {
04122 bx->isNegated = true;
04123
04124 opr = secondLastWord;
04125 }
04126 else {
04127
04128 opr = lastWord;
04129 }
04130
04131 operators->add(opr);
04132 boolexes->add(bx);
04133 }
04134 n = m;
04135 break;
04136 }
04137 }
04138 }
04139 }
04140 }
04141
04142 return true;
04143 }
04144
04145
04146
04147
04148
04149
04150
04151 }