/fox-1.6.37/src/FXString.cpp
C++ | 3078 lines | 2335 code | 472 blank | 271 comment | 393 complexity | 8983686a81d7949ae1ebff6b223a4c2d MD5 | raw file
Possible License(s): GPL-2.0, BSD-3-Clause, LGPL-2.0, MPL-2.0-no-copyleft-exception, BSD-2-Clause, LGPL-2.1, LGPL-3.0
Large files files are truncated, but you can click here to view the full file
- /********************************************************************************
- * *
- * S t r i n g O b j e c t *
- * *
- *********************************************************************************
- * Copyright (C) 1997,2006 by Jeroen van der Zijp. All Rights Reserved. *
- *********************************************************************************
- * This library is free software; you can redistribute it and/or *
- * modify it under the terms of the GNU Lesser General Public *
- * License as published by the Free Software Foundation; either *
- * version 2.1 of the License, or (at your option) any later version. *
- * *
- * This library is distributed in the hope that it will be useful, *
- * but WITHOUT ANY WARRANTY; without even the implied warranty of *
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU *
- * Lesser General Public License for more details. *
- * *
- * You should have received a copy of the GNU Lesser General Public *
- * License along with this library; if not, write to the Free Software *
- * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA. *
- *********************************************************************************
- * $Id: FXString.cpp,v 1.218.2.1 2006/08/15 05:03:16 fox Exp $ *
- ********************************************************************************/
- #include "xincs.h"
- #include "fxver.h"
- #include "fxdefs.h"
- #include "fxascii.h"
- #include "fxunicode.h"
- #include "FXHash.h"
- #include "FXStream.h"
- #include "FXString.h"
- /*
- Notes:
- - The special pointer-value null represents an empty "" string.
- - Strings are never NULL:- this speeds things up a lot as there is no
- need to check for NULL strings anymore.
- - In the new representation, '\0' is allowed as a character everywhere; but there
- is always an (uncounted) '\0' at the end.
- - The length preceeds the text in the buffer.
- */
- // The string buffer is always rounded to a multiple of ROUNDVAL
- // which must be 2^n. Thus, small size changes will not result in any
- // actual resizing of the buffer except when ROUNDVAL is exceeded.
- #define ROUNDVAL 16
- // Round up to nearest ROUNDVAL
- #define ROUNDUP(n) (((n)+ROUNDVAL-1)&-ROUNDVAL)
- // This will come in handy
- #define EMPTY ((FXchar*)&emptystring[1])
- using namespace FX;
- /*******************************************************************************/
- namespace FX {
- // For conversion from UTF16 to UTF32
- const FXint SURROGATE_OFFSET=0x10000-(0xD800<<10)-0xDC00;
- // For conversion of UTF32 to UTF16
- const FXint LEAD_OFFSET=0xD800-(0x10000>>10);
- // Empty string
- static const FXint emptystring[2]={0,0};
- // Special NULL string
- const FXchar FXString::null[4]={0,0,0,0};
- // Numbers for hexadecimal
- const FXchar FXString::hex[17]={'0','1','2','3','4','5','6','7','8','9','a','b','c','d','e','f',0};
- const FXchar FXString::HEX[17]={'0','1','2','3','4','5','6','7','8','9','A','B','C','D','E','F',0};
- // Length of a utf8 character representation
- const signed char FXString::utfBytes[256]={
- 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,
- 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,
- 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,
- 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,
- 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,
- 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,
- 2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,
- 3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,4,4,4,4,4,4,4,4,5,5,5,5,6,6,1,1
- };
- /*******************************************************************************/
- // Length of wide character string
- static inline FXint strlen(const FXchar *src){
- return ::strlen(src);
- }
- // Length of wide character string
- static inline FXint strlen(const FXwchar *src){
- register FXint i=0;
- while(src[i]) i++;
- return i;
- }
- // Length of narrow character string
- static inline FXint strlen(const FXnchar *src){
- register FXint i=0;
- while(src[i]) i++;
- return i;
- }
- /*******************************************************************************/
- // Return wide character from utf8 string at ptr
- FXwchar wc(const FXchar *ptr){
- register FXwchar w=(FXuchar)ptr[0];
- if(0xC0<=w){ w=(w<<6)^(FXuchar)ptr[1]^0x3080;
- if(0x800<=w){ w=(w<<6)^(FXuchar)ptr[2]^0x20080;
- if(0x10000<=w){ w=(w<<6)^(FXuchar)ptr[3]^0x400080;
- if(0x200000<=w){ w=(w<<6)^(FXuchar)ptr[4]^0x8000080;
- if(0x4000000<=w){ w=(w<<6)^(FXuchar)ptr[5]^0x80; }}}}}
- return w;
- }
- // Return wide character from utf16 string at ptr
- FXwchar wc(const FXnchar *ptr){
- register FXwchar w=ptr[0];
- if(0xD800<=w && w<0xDC00){ w=(w<<10)+ptr[1]+SURROGATE_OFFSET; }
- return w;
- }
- // Return number of FXchar's of wide character at ptr
- FXint wclen(const FXchar *ptr){
- return FXString::utfBytes[(FXuchar)ptr[0]];
- }
- // Return number of FXnchar's of narrow character at ptr
- FXint wclen(const FXnchar *ptr){
- return (0xD800<=ptr[0] && ptr[0]<0xDC00) ? 2 : 1;
- }
- // Return start of utf8 character containing position
- FXint wcvalidate(const FXchar* string,FXint pos){
- return (pos<=0 || FXISUTF(string[pos]) || --pos<=0 || FXISUTF(string[pos]) || --pos<=0 || FXISUTF(string[pos]) || --pos<=0 || FXISUTF(string[pos]) || --pos<=0 || FXISUTF(string[pos]) || --pos), pos;
- }
- // Return start of utf16 character containing position
- FXint wcvalidate(const FXnchar *string,FXint pos){
- return (pos<=0 || !(0xDC00<=string[pos] && string[pos]<=0xDFFF) || --pos), pos;
- }
- // Advance to next utf8 character start
- FXint wcinc(const FXchar* string,FXint pos){
- return (string[pos++]==0 || FXISUTF(string[pos]) || string[pos++]==0 || FXISUTF(string[pos]) || string[pos++]==0 || FXISUTF(string[pos]) || string[pos++]==0 || FXISUTF(string[pos]) || string[pos++]==0 || FXISUTF(string[pos]) || ++pos), pos;
- }
- // Advance to next utf16 character start
- FXint wcinc(const FXnchar *string,FXint pos){
- return ((0xDC00<=string[++pos] && string[pos]<=0xDFFF) || ++pos),pos;
- }
- // Retreat to previous utf8 character start
- FXint wcdec(const FXchar* string,FXint pos){
- return (--pos<=0 || FXISUTF(string[pos]) || --pos<=0 || FXISUTF(string[pos]) || --pos<=0 || FXISUTF(string[pos]) || --pos<=0 || FXISUTF(string[pos]) || --pos<=0 || FXISUTF(string[pos]) || --pos), pos;
- }
- // Retreat to previous utf16 character start
- FXint wcdec(const FXnchar *string,FXint pos){
- return (--pos<=0 || !(0xDC00<=string[pos] && string[pos]<=0xDFFF) || --pos), pos;
- }
- // Return true if valid utf8 character sequence
- bool isutfvalid(const FXchar* str){
- if((FXuchar)str[0]<0x80) return true;
- if((FXuchar)str[0]<0xC0) return false;
- if((FXuchar)str[1]<0x80) return false;
- if((FXuchar)str[1]>0xBF) return false;
- if((FXuchar)str[0]<0xE0) return true;
- if((FXuchar)str[2]<0x80) return false;
- if((FXuchar)str[2]>0xBF) return false;
- if((FXuchar)str[0]<0xF0) return true;
- if((FXuchar)str[3]<0x80) return false;
- if((FXuchar)str[3]>0xBF) return false;
- if((FXuchar)str[0]<0xF8) return true;
- if((FXuchar)str[4]<0x80) return false;
- if((FXuchar)str[4]>0xBF) return false;
- if((FXuchar)str[0]<0xFC) return true;
- if((FXuchar)str[5]<0x80) return false;
- if((FXuchar)str[5]>0xBF) return false;
- return true;
- }
- // Length of utf8 representation of wide characters string str of length n
- FXint utfslen(const FXwchar *str,FXint n){
- register FXint len=0;
- register FXint p=0;
- register FXwchar w;
- while(p<n){
- w=str[p++];
- len++;
- if(0x80<=w){ len++;
- if(0x800<=w){ len++;
- if(0x10000<=w){ len++;
- if(0x200000<=w){ len++;
- if(0x4000000<=w){ len++; }}}}}
- }
- return len;
- }
- // Length of utf8 representation of wide character string str
- FXint utfslen(const FXwchar *str){
- return utfslen(str,strlen(str));
- }
- // Length of utf8 representation of narrow characters string str of length n
- // Test for surrogates is deferred till code possibly exceeds 0xD800
- FXint utfslen(const FXnchar *str,FXint n){
- register FXint len=0;
- register FXint p=0;
- register FXwchar w;
- while(p<n){
- w=str[p++];
- len++;
- if(0x80<=w){ len++;
- if(0x800<=w){ len++; if(0xD800<=w && w<0xDC00 && p<n){ w=(w<<10)+str[p++]+SURROGATE_OFFSET; }
- if(0x10000<=w){ len++;
- if(0x200000<=w){ len++;
- if(0x4000000<=w){ len++; }}}}}
- }
- return len;
- }
- // Length of utf8 representation of narrow characters string str
- FXint utfslen(const FXnchar *str){
- return utfslen(str,strlen(str));
- }
- // Length of wide character representation of utf8 string str of length n
- FXint wcslen(const FXchar *str,FXint n){
- register FXint len=0;
- register FXint p=0;
- while(p<n){
- p+=FXString::utfBytes[(FXuchar)str[p]];
- len++;
- }
- return len;
- }
- // Length of wide character representation of utf8 string str
- FXint wcslen(const FXchar *str){
- return wcslen(str,strlen(str));
- }
- // Length of narrow character representation of utf8 string str of length n
- // Assume surrogates are needed if utf8 code is more than 16 bits
- FXint ncslen(const FXchar *str,FXint n){
- register FXint len=0;
- register FXint p=0;
- register FXwchar c;
- while(p<n){
- c=(FXuchar)str[p++];
- if(0xC0<=c){ p++;
- if(0xE0<=c){ p++;
- if(0xF0<=c){ p++;
- if(0xF8<=c){ p++;
- if(0xFC<=c){ p++; }} len++; }}}
- len++;
- }
- return len;
- }
- // Length of narrow character representation of utf8 string str
- FXint ncslen(const FXchar *str){
- return ncslen(str,strlen(str));
- }
- /*******************************************************************************/
- // Copy utf8 string of length n to wide character string dst
- FXint utf2wcs(FXwchar *dst,const FXchar *src,FXint n){
- register FXint len=0;
- register FXint p=0;
- register FXwchar w;
- while(p<n){
- w=(FXuchar)src[p++];
- if(0xC0<=w){ w=(w<<6)^(FXuchar)src[p++]^0x3080;
- if(0x800<=w){ w=(w<<6)^(FXuchar)src[p++]^0x20080;
- if(0x10000<=w){ w=(w<<6)^(FXuchar)src[p++]^0x400080;
- if(0x200000<=w){ w=(w<<6)^(FXuchar)src[p++]^0x8000080;
- if(0x4000000<=w){ w=(w<<6)^(FXuchar)src[p++]^0x80; }}}}}
- dst[len++]=w;
- }
- return len;
- }
- // Copy utf8 string to wide character string dst
- FXint utf2wcs(FXwchar *dst,const FXchar *src){
- return utf2wcs(dst,src,strlen(src)+1);
- }
- // Copy utf8 string of length n to narrow character string dst
- // Assume surrogates are needed if utf8 code is more than 16 bits
- FXint utf2ncs(FXnchar *dst,const FXchar *src,FXint n){
- register FXint len=0;
- register FXint p=0;
- register FXwchar w;
- while(p<n){
- w=(FXuchar)src[p++];
- if(0xC0<=w){ w=(w<<6)^(FXuchar)src[p++]^0x3080;
- if(0x800<=w){ w=(w<<6)^(FXuchar)src[p++]^0x20080;
- if(0x10000<=w){ w=(w<<6)^(FXuchar)src[p++]^0x400080;
- if(0x200000<=w){ w=(w<<6)^(FXuchar)src[p++]^0x8000080;
- if(0x4000000<=w){ w=(w<<6)^(FXuchar)src[p++]^0x80; }} dst[len++]=(w>>10)+LEAD_OFFSET; w=(w&0x3FF)+0xDC00; }}}
- dst[len++]=w;
- }
- return len;
- }
- // Copy utf8 string to narrow character string dst
- FXint utf2ncs(FXnchar *dst,const FXchar *src){
- return utf2ncs(dst,src,strlen(src)+1);
- }
- /*******************************************************************************/
- // Copy wide character substring of length n to dst
- FXint wc2utfs(FXchar* dst,const FXwchar *src,FXint n){
- register FXint len=0;
- register FXint p=0;
- register FXwchar w;
- while(p<n){
- w=src[p++];
- if(w<0x80){
- dst[len++]=w;
- continue;
- }
- if(w<0x800){
- dst[len++]=(w>>6)|0xC0;
- dst[len++]=(w&0x3F)|0x80;
- continue;
- }
- if(w<0x10000){
- dst[len++]=(w>>12)|0xE0;
- dst[len++]=((w>>6)&0x3F)|0x80;
- dst[len++]=(w&0x3F)|0x80;
- continue;
- }
- if(w<0x200000){
- dst[len++]=(w>>18)|0xF0;
- dst[len++]=((w>>12)&0x3F)|0x80;
- dst[len++]=((w>>6)&0x3F)|0x80;
- dst[len++]=(w&0x3F)|0x80;
- continue;
- }
- if(w<0x4000000){
- dst[len++]=(w>>24)|0xF8;
- dst[len++]=((w>>18)&0x3F)|0x80;
- dst[len++]=((w>>12)&0x3F)|0x80;
- dst[len++]=((w>>6)&0x3F)|0x80;
- dst[len++]=(w&0x3F)|0x80;
- continue;
- }
- dst[len++]=(w>>30)|0xFC;
- dst[len++]=((w>>24)&0X3F)|0x80;
- dst[len++]=((w>>18)&0X3F)|0x80;
- dst[len++]=((w>>12)&0X3F)|0x80;
- dst[len++]=((w>>6)&0X3F)|0x80;
- dst[len++]=(w&0X3F)|0x80;
- }
- return len;
- }
- // Copy wide character string to dst
- FXint wc2utfs(FXchar* dst,const FXwchar *src){
- return wc2utfs(dst,src,strlen(src)+1);
- }
- // Copy narrow character substring of length n to dst
- // Test for surrogates is deferred till code possibly exceeds 0xD800
- FXint nc2utfs(FXchar* dst,const FXnchar *src,FXint n){
- register FXint len=0;
- register FXint p=0;
- register FXwchar w;
- while(p<n){
- w=src[p++];
- if(w<0x80){
- dst[len++]=w;
- continue;
- }
- if(w<0x800){
- dst[len++]=(w>>6)|0xC0;
- dst[len++]=(w&0x3F)|0x80;
- continue;
- }
- if(0xD800<=w && w<0xDC00 && p<n){ w=(w<<10)+src[p++]+SURROGATE_OFFSET; }
- if(w<0x10000){
- dst[len++]=(w>>12)|0xE0;
- dst[len++]=((w>>6)&0x3F)|0x80;
- dst[len++]=(w&0x3F)|0x80;
- continue;
- }
- if(w<0x200000){
- dst[len++]=(w>>18)|0xF0;
- dst[len++]=((w>>12)&0x3F)|0x80;
- dst[len++]=((w>>6)&0x3F)|0x80;
- dst[len++]=(w&0x3F)|0x80;
- continue;
- }
- if(w<0x4000000){
- dst[len++]=(w>>24)|0xF8;
- dst[len++]=((w>>18)&0x3F)|0x80;
- dst[len++]=((w>>12)&0x3F)|0x80;
- dst[len++]=((w>>6)&0x3F)|0x80;
- dst[len++]=(w&0x3F)|0x80;
- continue;
- }
- dst[len++]=(w>>30)|0xFC;
- dst[len++]=((w>>24)&0X3F)|0x80;
- dst[len++]=((w>>18)&0X3F)|0x80;
- dst[len++]=((w>>12)&0X3F)|0x80;
- dst[len++]=((w>>6)&0X3F)|0x80;
- dst[len++]=(w&0X3F)|0x80;
- }
- return len;
- }
- // Copy narrow character string to dst
- FXint nc2utfs(FXchar* dst,const FXnchar *src){
- return nc2utfs(dst,src,strlen(src)+1);
- }
- /*******************************************************************************/
- // Change the length of the string to len
- void FXString::length(FXint len){
- if(*(((FXint*)str)-1)!=len){
- if(0<len){
- if(str==EMPTY)
- str=sizeof(FXint)+(FXchar*)malloc(ROUNDUP(1+len)+sizeof(FXint));
- else
- str=sizeof(FXint)+(FXchar*)realloc(str-sizeof(FXint),ROUNDUP(1+len)+sizeof(FXint));
- str[len]=0;
- *(((FXint*)str)-1)=len;
- }
- else if(str!=EMPTY){
- free(str-sizeof(FXint));
- str=EMPTY;
- }
- }
- }
- // Return start of utf8 character containing position
- FXint FXString::validate(FXint p) const { return wcvalidate(str,p); }
- // Advance to next utf8 character start
- FXint FXString::inc(FXint p) const { return wcinc(str,p); }
- // Retreat to previous utf8 character start
- FXint FXString::dec(FXint p) const { return wcdec(str,p); }
- // Return wide character starting at offset i
- FXwchar FXString::wc(FXint i) const {
- register FXwchar w=(FXuchar)str[i];
- if(0xC0<=w){ w=(w<<6)^(FXuchar)str[i+1]^0x3080;
- if(0x800<=w){ w=(w<<6)^(FXuchar)str[i+2]^0x20080;
- if(0x10000<=w){ w=(w<<6)^(FXuchar)str[i+3]^0x400080;
- if(0x200000<=w){ w=(w<<6)^(FXuchar)str[i+4]^0x8000080;
- if(0x4000000<=w){ w=(w<<6)^(FXuchar)str[i+5]^0x80; }}}}}
- return w;
- }
- // Count number of utf8 characters in subrange
- FXint FXString::count(FXint pos,FXint len) const {
- register FXint cnt=0;
- while(pos<len){
- pos+=utfBytes[(FXuchar)str[pos]];
- cnt++;
- }
- return cnt;
- }
- // Count number of utf8 characters
- FXint FXString::count() const {
- return count(0,length());
- }
- // Return index of utf8 character at byte offset
- FXint FXString::index(FXint offs) const {
- register FXint len=length();
- register FXint i=0;
- register FXint p=0;
- while(p<offs && p<len){
- p+=utfBytes[(FXuchar)str[p]];
- i++;
- }
- return i;
- }
- // Return byte offset of utf8 character at index
- FXint FXString::offset(FXint indx) const {
- register FXint len=length();
- register FXint i=0;
- register FXint p=0;
- while(i<indx && p<len){
- p+=utfBytes[(FXuchar)str[p]];
- i++;
- }
- return p;
- }
- // Simple construct
- FXString::FXString():str(EMPTY){
- }
- // Copy construct
- FXString::FXString(const FXString& s):str(EMPTY){
- register FXint n=s.length();
- if(0<n){
- length(n);
- memcpy(str,s.str,n);
- }
- }
- // Construct and init
- FXString::FXString(const FXchar* s):str(EMPTY){
- if(s && s[0]){
- register FXint n=strlen(s);
- length(n);
- memcpy(str,s,n);
- }
- }
- // Construct and init
- FXString::FXString(const FXwchar* s):str(EMPTY){
- if(s && s[0]){
- register FXint n=utfslen(s);
- length(n);
- wc2utfs(str,s);
- }
- }
- // Construct and init
- FXString::FXString(const FXnchar* s):str(EMPTY){
- if(s && s[0]){
- register FXint n=utfslen(s);
- length(n);
- nc2utfs(str,s);
- }
- }
- // Construct and init with substring
- FXString::FXString(const FXchar* s,FXint n):str(EMPTY){
- if(s && 0<n){
- length(n);
- memcpy(str,s,n);
- }
- }
- // Construct and init with wide character substring
- FXString::FXString(const FXwchar* s,FXint m):str(EMPTY){
- if(s && 0<m){
- register FXint n=utfslen(s,m);
- length(n);
- wc2utfs(str,s,m);
- }
- }
- // Construct and init with narrow character substring
- FXString::FXString(const FXnchar* s,FXint m):str(EMPTY){
- if(s && 0<m){
- register FXint n=utfslen(s,m);
- length(n);
- nc2utfs(str,s,m);
- }
- }
- // Construct and fill with constant
- FXString::FXString(FXchar c,FXint n):str(EMPTY){
- if(0<n){
- length(n);
- memset(str,c,n);
- }
- }
- // Return partition of string separated by delimiter delim
- FXString FXString::section(FXchar delim,FXint start,FXint num) const {
- register FXint len=length(),s,e;
- s=0;
- if(0<start){
- while(s<len){
- ++s;
- if(str[s-1]==delim && --start==0) break;
- }
- }
- e=s;
- if(0<num){
- while(e<len){
- if(str[e]==delim && --num==0) break;
- ++e;
- }
- }
- return FXString(str+s,e-s);
- }
- // Return partition of string separated by delimiters in delim
- FXString FXString::section(const FXchar* delim,FXint n,FXint start,FXint num) const {
- register FXint len=length(),s,e,i;
- register FXchar c;
- s=0;
- if(0<start){
- while(s<len){
- c=str[s++];
- i=n;
- while(--i>=0){
- if(delim[i]==c){
- if(--start==0) goto a;
- break;
- }
- }
- }
- }
- a:e=s;
- if(0<num){
- while(e<len){
- c=str[e];
- i=n;
- while(--i>=0){
- if(delim[i]==c){
- if(--num==0) goto b;
- break;
- }
- }
- ++e;
- }
- }
- b:return FXString(str+s,e-s);
- }
- // Return partition of string separated by delimiters in delim
- FXString FXString::section(const FXchar* delim,FXint start,FXint num) const {
- return section(delim,strlen(delim),start,num);
- }
- // Return partition of string separated by delimiters in delim
- FXString FXString::section(const FXString& delim,FXint start,FXint num) const {
- return section(delim.text(),delim.length(),start,num);
- }
- // Adopt string s, leaving s empty
- FXString& FXString::adopt(FXString& s){
- if(this!=&s){
- if(str!=EMPTY){ free(str-sizeof(FXint)); }
- str=s.str;
- s.str=EMPTY;
- }
- return *this;
- }
- // Assign input character to this string
- FXString& FXString::assign(FXchar c){
- length(1);
- str[0]=c;
- return *this;
- }
- // Assign input n characters c to this string
- FXString& FXString::assign(FXchar c,FXint n){
- length(n);
- memset(str,c,n);
- return *this;
- }
- // Assign first n characters of input string to this string
- FXString& FXString::assign(const FXchar* s,FXint n){
- if(s && 0<n){
- length(n);
- memmove(str,s,n);
- }
- else{
- length(0);
- }
- return *this;
- }
- // Assign first n characters of wide character string s to this string
- FXString& FXString::assign(const FXwchar* s,FXint m){
- if(s && 0<m){
- register FXint n=utfslen(s,m);
- length(n);
- wc2utfs(str,s,m);
- }
- else{
- length(0);
- }
- return *this;
- }
- // Assign first n characters of narrow character string s to this string
- FXString& FXString::assign(const FXnchar* s,FXint m){
- if(s && 0<m){
- register FXint n=utfslen(s,m);
- length(n);
- nc2utfs(str,s,m);
- }
- else{
- length(0);
- }
- return *this;
- }
- // Assign input string to this string
- FXString& FXString::assign(const FXchar* s){
- if(s && s[0]){
- register FXint n=strlen(s);
- length(n);
- memmove(str,s,n);
- }
- else{
- length(0);
- }
- return *this;
- }
- // Assign wide character string s to this string
- FXString& FXString::assign(const FXwchar* s){
- if(s && s[0]){
- register FXint n=utfslen(s);
- length(n);
- wc2utfs(str,s);
- }
- else{
- length(0);
- }
- return *this;
- }
- // Assign narrow character string s to this string
- FXString& FXString::assign(const FXnchar* s){
- if(s && s[0]){
- register FXint n=utfslen(s);
- length(n);
- nc2utfs(str,s);
- }
- else{
- length(0);
- }
- return *this;
- }
- // Assign input string to this string
- FXString& FXString::assign(const FXString& s){
- if(str!=s.str) assign(s.str,s.length());
- return *this;
- }
- // Assign a string
- FXString& FXString::operator=(const FXchar* s){
- return assign(s);
- }
- // Assign a wide character string to this
- FXString& FXString::operator=(const FXwchar* s){
- return assign(s);
- }
- // Assign a narrow character string to this
- FXString& FXString::operator=(const FXnchar* s){
- return assign(s);
- }
- // Assignment
- FXString& FXString::operator=(const FXString& s){
- if(str!=s.str) assign(s.str,s.length());
- return *this;
- }
- // Insert character at position
- FXString& FXString::insert(FXint pos,FXchar c){
- register FXint len=length();
- length(len+1);
- if(pos<=0){
- memmove(str+1,str,len);
- str[0]=c;
- }
- else if(pos>=len){
- str[len]=c;
- }
- else{
- memmove(str+pos+1,str+pos,len-pos);
- str[pos]=c;
- }
- return *this;
- }
- // Insert n characters c at specified position
- FXString& FXString::insert(FXint pos,FXchar c,FXint n){
- if(0<n){
- register FXint len=length();
- length(len+n);
- if(pos<=0){
- memmove(str+n,str,len);
- memset(str,c,n);
- }
- else if(pos>=len){
- memset(str+len,c,n);
- }
- else{
- memmove(str+pos+n,str+pos,len-pos);
- memset(str+pos,c,n);
- }
- }
- return *this;
- }
- // Insert string at position
- FXString& FXString::insert(FXint pos,const FXchar* s,FXint n){
- if(s && 0<n){
- register FXint len=length();
- length(len+n);
- if(pos<=0){
- memmove(str+n,str,len);
- memcpy(str,s,n);
- }
- else if(pos>=len){
- memcpy(str+len,s,n);
- }
- else{
- memmove(str+pos+n,str+pos,len-pos);
- memcpy(str+pos,s,n);
- }
- }
- return *this;
- }
- // Insert wide character string at position
- FXString& FXString::insert(FXint pos,const FXwchar* s,FXint m){
- if(s && 0<m){
- register FXint len=length();
- register FXint n=utfslen(s,m);
- length(len+n);
- if(pos<=0){
- memmove(str+n,str,len);
- wc2utfs(str,s,m);
- }
- else if(pos>=len){
- wc2utfs(str+len,s,m);
- }
- else{
- memmove(str+pos+n,str+pos,len-pos);
- wc2utfs(str+pos,s,m);
- }
- }
- return *this;
- }
- // Insert narrow character string at position
- FXString& FXString::insert(FXint pos,const FXnchar* s,FXint m){
- if(s && 0<m){
- register FXint len=length();
- register FXint n=utfslen(s,m);
- length(len+n);
- if(pos<=0){
- memmove(str+n,str,len);
- nc2utfs(str,s,m);
- }
- else if(pos>=len){
- nc2utfs(str+len,s,m);
- }
- else{
- memmove(str+pos+n,str+pos,len-pos);
- nc2utfs(str+pos,s,m);
- }
- }
- return *this;
- }
- // Insert string at position
- FXString& FXString::insert(FXint pos,const FXchar* s){
- if(s && s[0]){
- register FXint len=length();
- register FXint n=strlen(s);
- length(len+n);
- if(pos<=0){
- memmove(str+n,str,len);
- memcpy(str,s,n);
- }
- else if(pos>=len){
- memcpy(str+len,s,n);
- }
- else{
- memmove(str+pos+n,str+pos,len-pos);
- memcpy(str+pos,s,n);
- }
- }
- return *this;
- }
- // Insert wide character string at position
- FXString& FXString::insert(FXint pos,const FXwchar* s){
- if(s && s[0]){
- register FXint len=length();
- register FXint n=utfslen(s);
- length(len+n);
- if(pos<=0){
- memmove(str+n,str,len);
- wc2utfs(str,s);
- }
- else if(pos>=len){
- wc2utfs(str+len,s);
- }
- else{
- memmove(str+pos+n,str+pos,len-pos);
- wc2utfs(str+pos,s);
- }
- }
- return *this;
- }
- // Insert narrow character string at position
- FXString& FXString::insert(FXint pos,const FXnchar* s){
- if(s && s[0]){
- register FXint len=length();
- register FXint n=utfslen(s);
- length(len+n);
- if(pos<=0){
- memmove(str+n,str,len);
- nc2utfs(str,s);
- }
- else if(pos>=len){
- nc2utfs(str+len,s);
- }
- else{
- memmove(str+pos+n,str+pos,len-pos);
- nc2utfs(str+pos,s);
- }
- }
- return *this;
- }
- // Insert string at position
- FXString& FXString::insert(FXint pos,const FXString& s){
- return insert(pos,s.str,s.length());
- }
- // Append character c to this string
- FXString& FXString::append(FXchar c){
- register FXint len=length();
- length(len+1);
- str[len]=c;
- return *this;
- }
- // Append n characters c to this string
- FXString& FXString::append(FXchar c,FXint n){
- if(0<n){
- register FXint len=length();
- length(len+n);
- memset(str+len,c,n);
- }
- return *this;
- }
- // Append string to this string
- FXString& FXString::append(const FXchar* s,FXint n){
- if(s && 0<n){
- register FXint len=length();
- length(len+n);
- memcpy(str+len,s,n);
- }
- return *this;
- }
- // Append string to this string
- FXString& FXString::append(const FXwchar* s,FXint m){
- if(s && 0<m){
- register FXint len=length();
- register FXint n=utfslen(s,m);
- length(len+n);
- wc2utfs(str+len,s,m);
- }
- return *this;
- }
- // Append string to this string
- FXString& FXString::append(const FXnchar* s,FXint m){
- if(s && 0<m){
- register FXint len=length();
- register FXint n=utfslen(s,m);
- length(len+n);
- nc2utfs(str+len,s,m);
- }
- return *this;
- }
- // Append string to this string
- FXString& FXString::append(const FXchar* s){
- if(s && s[0]){
- register FXint len=length();
- register FXint n=strlen(s);
- length(len+n);
- memcpy(str+len,s,n);
- }
- return *this;
- }
- // Append string to this string
- FXString& FXString::append(const FXwchar* s){
- if(s && s[0]){
- register FXint len=length();
- register FXint n=utfslen(s);
- length(len+n);
- wc2utfs(str+len,s);
- }
- return *this;
- }
- // Append string to this string
- FXString& FXString::append(const FXnchar* s){
- if(s && s[0]){
- register FXint len=length();
- register FXint n=utfslen(s);
- length(len+n);
- nc2utfs(str+len,s);
- }
- return *this;
- }
- // Append string to this string
- FXString& FXString::append(const FXString& s){
- return append(s.str,s.length());
- }
- // Append character
- FXString& FXString::operator+=(FXchar c){
- return append(c);
- }
- // Append string
- FXString& FXString::operator+=(const FXchar* s){
- return append(s);
- }
- // Append string
- FXString& FXString::operator+=(const FXwchar* s){
- return append(s);
- }
- // Append string
- FXString& FXString::operator+=(const FXnchar* s){
- return append(s);
- }
- // Append FXString
- FXString& FXString::operator+=(const FXString& s){
- return append(s);
- }
- // Prepend character
- FXString& FXString::prepend(FXchar c){
- register FXint len=length();
- length(len+1);
- memmove(str+1,str,len);
- str[0]=c;
- return *this;
- }
- // Prepend string with n characters c
- FXString& FXString::prepend(FXchar c,FXint n){
- if(0<n){
- register FXint len=length();
- length(len+n);
- memmove(str+n,str,len);
- memset(str,c,n);
- }
- return *this;
- }
- // Prepend string
- FXString& FXString::prepend(const FXchar* s,FXint n){
- if(s && 0<n){
- register FXint len=length();
- length(len+n);
- memmove(str+n,str,len);
- memcpy(str,s,n);
- }
- return *this;
- }
- // Prepend wide character string
- FXString& FXString::prepend(const FXwchar* s,FXint m){
- if(s && 0<m){
- register FXint len=length();
- register FXint n=utfslen(s,m);
- length(len+n);
- memmove(str+n,str,len);
- wc2utfs(str,s,m);
- }
- return *this;
- }
- // Prepend narrow character string
- FXString& FXString::prepend(const FXnchar* s,FXint m){
- if(s && 0<m){
- register FXint len=length();
- register FXint n=utfslen(s,m);
- length(len+n);
- memmove(str+n,str,len);
- nc2utfs(str,s,m);
- }
- return *this;
- }
- // Prepend string
- FXString& FXString::prepend(const FXchar* s){
- if(s && s[0]){
- register FXint len=length();
- register FXint n=strlen(s);
- length(len+n);
- memmove(str+n,str,len);
- memcpy(str,s,n);
- }
- return *this;
- }
- // Prepend wide character string
- FXString& FXString::prepend(const FXwchar* s){
- if(s && s[0]){
- register FXint len=length();
- register FXint n=utfslen(s);
- length(len+n);
- memmove(str+n,str,len);
- wc2utfs(str,s);
- }
- return *this;
- }
- // Prepend narrow character string
- FXString& FXString::prepend(const FXnchar* s){
- if(s && s[0]){
- register FXint len=length();
- register FXint n=utfslen(s);
- length(len+n);
- memmove(str+n,str,len);
- nc2utfs(str,s);
- }
- return *this;
- }
- // Prepend string
- FXString& FXString::prepend(const FXString& s){
- return prepend(s.str,s.length());
- }
- // Replace character in string
- FXString& FXString::replace(FXint pos,FXchar c){
- register FXint len=length();
- if(pos<0){
- length(len+1);
- memmove(str+1,str,len);
- str[0]=c;
- }
- else if(pos>=len){
- length(len+1);
- str[len]=c;
- }
- else{
- str[pos]=c;
- }
- return *this;
- }
- // Replace the m characters at pos with n characters c
- FXString& FXString::replace(FXint pos,FXint m,FXchar c,FXint n){
- register FXint len=length();
- if(pos<0){
- m+=pos;
- if(m<0) m=0;
- pos=0;
- }
- if(pos+m>len){
- if(pos>len) pos=len;
- m=len-pos;
- }
- if(m<n){
- length(len+n-m);
- memmove(str+pos+n,str+pos+m,len-pos-m);
- }
- else if(m>n){
- memmove(str+pos+n,str+pos+m,len-pos-m);
- length(len+n-m);
- }
- memset(str+pos,c,n);
- return *this;
- }
- // Replace part of string
- FXString& FXString::replace(FXint pos,FXint m,const FXchar* s,FXint n){
- register FXint len=length();
- if(pos<0){
- m+=pos;
- if(m<0) m=0;
- pos=0;
- }
- if(pos+m>len){
- if(pos>len) pos=len;
- m=len-pos;
- }
- if(m<n){
- length(len+n-m);
- memmove(str+pos+n,str+pos+m,len-pos-m);
- }
- else if(m>n){
- memmove(str+pos+n,str+pos+m,len-pos-m);
- length(len+n-m);
- }
- memcpy(str+pos,s,n);
- return *this;
- }
- // Replace part of wide character string
- FXString& FXString::replace(FXint pos,FXint m,const FXwchar* s,FXint n){
- register FXint w=utfslen(s,n);
- register FXint len=length();
- if(pos<0){
- m+=pos;
- if(m<0) m=0;
- pos=0;
- }
- if(pos+m>len){
- if(pos>len) pos=len;
- m=len-pos;
- }
- if(m<w){
- length(len+w-m);
- memmove(str+pos+w,str+pos+m,len-pos-m);
- }
- else if(m>w){
- memmove(str+pos+w,str+pos+m,len-pos-m);
- length(len+w-m);
- }
- wc2utfs(str+pos,s,n);
- return *this;
- }
- // Replace part of narrow character string
- FXString& FXString::replace(FXint pos,FXint m,const FXnchar* s,FXint n){
- register FXint w=utfslen(s,n);
- register FXint len=length();
- if(pos<0){
- m+=pos;
- if(m<0) m=0;
- pos=0;
- }
- if(pos+m>len){
- if(pos>len) pos=len;
- m=len-pos;
- }
- if(m<w){
- length(len+w-m);
- memmove(str+pos+w,str+pos+m,len-pos-m);
- }
- else if(m>w){
- memmove(str+pos+w,str+pos+m,len-pos-m);
- length(len+w-m);
- }
- nc2utfs(str+pos,s,n);
- return *this;
- }
- // Replace part of string
- FXString& FXString::replace(FXint pos,FXint m,const FXchar* s){
- return replace(pos,m,s,strlen(s));
- }
- // Replace part of string
- FXString& FXString::replace(FXint pos,FXint m,const FXwchar* s){
- return replace(pos,m,s,strlen(s));
- }
- // Replace part of string
- FXString& FXString::replace(FXint pos,FXint m,const FXnchar* s){
- return replace(pos,m,s,strlen(s));
- }
- // Replace part of string
- FXString& FXString::replace(FXint pos,FXint m,const FXString& s){
- return replace(pos,m,s.str,s.length());
- }
- // Move range of m characters from src position to dst position
- FXString& FXString::move(FXint dst,FXint src,FXint n){
- register FXint len=length();
- if(0<n && 0<=src && src+n<=len){
- if(dst<0){ // Move below begin
- if(dst<-n) dst=-n;
- length(len-dst);
- memmove(str-dst,str,len);
- memmove(str,str-dst+src,n);
- }
- else if(dst+n>len){ // Move beyond end
- if(dst>len) dst=len;
- length(dst+n);
- memmove(str+dst,str+src,n);
- }
- else{
- memmove(str+dst,str+src,n); // Move inside
- }
- }
- return *this;
- }
- // Remove one character
- FXString& FXString::erase(FXint pos){
- register FXint len=length();
- if(0<=pos && pos<len){
- memmove(str+pos,str+pos+1,len-pos-1);
- length(len-1);
- }
- return *this;
- }
- // Remove section from buffer
- FXString& FXString::erase(FXint pos,FXint n){
- if(0<n){
- register FXint len=length();
- if(pos<len && pos+n>0){
- if(pos<0){n+=pos;pos=0;}
- if(pos+n>len){n=len-pos;}
- memmove(str+pos,str+pos+n,len-pos-n);
- length(len-n);
- }
- }
- return *this;
- }
- // Return number of occurrences of ch in string
- FXint FXString::contains(FXchar ch) const {
- register FXint len=length();
- register FXint c=ch;
- register FXint m=0;
- register FXint i=0;
- while(i<len){
- if(str[i]==c){
- m++;
- }
- i++;
- }
- return m;
- }
- // Return number of occurrences of string sub in string
- FXint FXString::contains(const FXchar* sub,FXint n) const {
- register FXint len=length()-n;
- register FXint m=0;
- register FXint i=0;
- while(i<=len){
- if(compare(str+i,sub,n)==0){
- m++;
- }
- i++;
- }
- return m;
- }
- // Return number of occurrences of string sub in string
- FXint FXString::contains(const FXchar* sub) const {
- return contains(sub,strlen(sub));
- }
- // Return number of occurrences of string sub in string
- FXint FXString::contains(const FXString& sub) const {
- return contains(sub.text(),sub.length());
- }
- // Concatenate two FXStrings
- FXString operator+(const FXString& s1,const FXString& s2){
- FXString result(s1);
- return result.append(s2);
- }
- // Concatenate FXString and string
- FXString operator+(const FXString& s1,const FXchar* s2){
- FXString result(s1);
- return result.append(s2);
- }
- // Concatenate FXString and wide character string
- FXString operator+(const FXString& s1,const FXwchar* s2){
- FXString result(s1);
- return result.append(s2);
- }
- // Concatenate FXString and narrow character string
- FXString operator+(const FXString& s1,const FXnchar* s2){
- FXString result(s1);
- return result.append(s2);
- }
- // Concatenate string and FXString
- FXString operator+(const FXchar* s1,const FXString& s2){
- FXString result(s1);
- return result.append(s2);
- }
- // Concatenate wide character string and FXString
- FXString operator+(const FXwchar* s1,const FXString& s2){
- FXString result(s1);
- return result.append(s2);
- }
- // Concatenate narrow character string and FXString
- FXString operator+(const FXnchar* s1,const FXString& s2){
- FXString result(s1);
- return result.append(s2);
- }
- // Concatenate FXString and character
- FXString operator+(const FXString& s,FXchar c){
- FXString result(s);
- return result.append(c);
- }
- // Concatenate character and FXString
- FXString operator+(FXchar c,const FXString& s){
- FXString result(&c,1);
- return result.append(s);
- }
- // Substitute one character by another
- FXString& FXString::substitute(FXchar org,FXchar sub,bool all){
- register FXint len=length();
- register FXint c=org;
- register FXint s=sub;
- register FXint i=0;
- while(i<len){
- if(str[i]==c){
- str[i]=s;
- if(!all) break;
- }
- i++;
- }
- return *this;
- }
- // Substitute one string by another
- FXString& FXString::substitute(const FXchar* org,FXint olen,const FXchar* rep,FXint rlen,bool all){
- if(0<olen){
- register FXint pos=0;
- while(pos<=length()-olen){
- if(compare(str+pos,org,olen)==0){
- replace(pos,olen,rep,rlen);
- if(!all) break;
- pos+=rlen;
- continue;
- }
- pos++;
- }
- }
- return *this;
- }
- // Substitute one string by another
- FXString& FXString::substitute(const FXchar* org,const FXchar* rep,bool all){
- return substitute(org,strlen(org),rep,strlen(rep),all);
- }
- // Substitute one string by another
- FXString& FXString::substitute(const FXString& org,const FXString& rep,bool all){
- return substitute(org.text(),org.length(),rep.text(),rep.length(),all);
- }
- // Simplify whitespace in string
- FXString& FXString::simplify(){
- if(str!=EMPTY){
- register FXint s=0;
- register FXint d=0;
- register FXint e=length();
- while(s<e && Ascii::isSpace(str[s])) s++;
- while(1){
- while(s<e && !Ascii::isSpace(str[s])) str[d++]=str[s++];
- while(s<e && Ascii::isSpace(str[s])) s++;
- if(s>=e) break;
- str[d++]=' ';
- }
- length(d);
- }
- return *this;
- }
- // Remove leading and trailing whitespace
- FXString& FXString::trim(){
- if(str!=EMPTY){
- register FXint s=0;
- register FXint e=length();
- while(0<e && Ascii::isSpace(str[e-1])) e--;
- while(s<e && Ascii::isSpace(str[s])) s++;
- memmove(str,&str[s],e-s);
- length(e-s);
- }
- return *this;
- }
- // Remove leading whitespace
- FXString& FXString::trimBegin(){
- if(str!=EMPTY){
- register FXint s=0;
- register FXint e=length();
- while(s<e && Ascii::isSpace(str[s])) s++;
- memmove(str,str+s,e-s);
- length(e-s);
- }
- return *this;
- }
- // Remove trailing whitespace
- FXString& FXString::trimEnd(){
- if(str!=EMPTY){
- register FXint e=length();
- while(0<e && Ascii::isSpace(str[e-1])) e--;
- length(e);
- }
- return *this;
- }
- // Truncate string
- FXString& FXString::trunc(FXint pos){
- register FXint len=length();
- if(pos>len) pos=len;
- length(pos);
- return *this;
- }
- // Clean string
- FXString& FXString::clear(){
- length(0);
- return *this;
- }
- // Get leftmost part
- FXString FXString::left(FXint n) const {
- if(0<n){
- register FXint len=length();
- if(n>len) n=len;
- return FXString(str,n);
- }
- return FXString::null;
- }
- // Get rightmost part
- FXString FXString::right(FXint n) const {
- if(0<n){
- register FXint len=length();
- if(n>len) n=len;
- return FXString(str+len-n,n);
- }
- return FXString::null;
- }
- // Get some part in the middle
- FXString FXString::mid(FXint pos,FXint n) const {
- if(0<n){
- register FXint len=length();
- if(pos<len && pos+n>0){
- if(pos<0){n+=pos;pos=0;}
- if(pos+n>len){n=len-pos;}
- return FXString(str+pos,n);
- }
- }
- return FXString::null;
- }
- // Return all characters before the nth occurrence of ch, searching forward
- FXString FXString::before(FXchar c,FXint n) const {
- register FXint len=length();
- register FXint p=0;
- if(0<n){
- while(p<len){
- if(str[p]==c && --n==0) break;
- p++;
- }
- }
- return FXString(str,p);
- }
- // Return all characters before the nth occurrence of ch, searching backward
- FXString FXString::rbefore(FXchar c,FXint n) const {
- register FXint p=length();
- if(0<n){
- while(0<p){
- p--;
- if(str[p]==c && --n==0) break;
- }
- }
- return FXString(str,p);
- }
- // Return all characters after the nth occurrence of ch, searching forward
- FXString FXString::after(FXchar c,FXint n) const {
- register FXint len=length();
- register FXint p=0;
- if(0<n){
- while(p<len){
- p++;
- if(str[p-1]==c && --n==0) break;
- }
- }
- return FXString(str+p,len-p);
- }
- // Return all characters after the nth occurrence of ch, searching backward
- FXString FXString::rafter(FXchar c,FXint n) const {
- register FXint len=length();
- register FXint p=len;
- if(0<n){
- while(0<p){
- if(str[p-1]==c && --n==0) break;
- p--;
- }
- }
- return FXString(str+p,len-p);
- }
- // Convert to lower case
- FXString& FXString::lower(){
- FXString string;
- for(FXint p=0; p<length(); p=inc(p)){
- FXwchar w=Unicode::toLower(wc(p));
- string.append(&w,1);
- }
- adopt(string);
- return *this;
- }
- // Convert to upper case
- FXString& FXString::upper(){
- FXString string;
- for(FXint p=0; p<length(); p=inc(p)){
- FXwchar w=Unicode::toUpper(wc(p));
- string.append(&w,1);
- }
- adopt(string);
- return *this;
- }
- // Compare strings
- FXint compare(const FXchar* s1,const FXchar* s2){
- register const FXuchar *p1=(const FXuchar *)s1;
- register const FXuchar *p2=(const FXuchar *)s2;
- register FXint c1,c2;
- do{
- c1=*p1++;
- c2=*p2++;
- }
- while(c1 && (c1==c2));
- return c1-c2;
- }
- FXint compare(const FXchar* s1,const FXString& s2){
- return compare(s1,s2.str);
- }
- FXint compare(const FXString& s1,const FXchar* s2){
- return compare(s1.str,s2);
- }
- FXint compare(const FXString& s1,const FXString& s2){
- return compare(s1.str,s2.str);
- }
- // Compare strings up to n
- FXint compare(const FXchar* s1,const FXchar* s2,FXint n){
- register const FXuchar *p1=(const FXuchar *)s1;
- register const FXuchar *p2=(const FXuchar *)s2;
- register FXint c1,c2;
- if(0<n){
- do{
- c1=*p1++;
- c2=*p2++;
- }
- while(--n && c1 && (c1==c2));
- return c1-c2;
- }
- return 0;
- }
- FXint compare(const FXchar* s1,const FXString& s2,FXint n){
- return compare(s1,s2.str,n);
- }
- FXint compare(const FXString& s1,const FXchar* s2,FXint n){
- return compare(s1.str,s2,n);
- }
- FXint compare(const FXString& s1,const FXString& s2,FXint n){
- return compare(s1.str,s2.str,n);
- }
- // Compare utf-8 strings case insensitive
- // At each iteration through the loop, the following is true:
- // o Both characters are ascii. In this case, fold using Ascii
- // and compare.
- // o One of the two is ascii. This means the other is > 0x80
- // so fold using Ascii [leaving upper 128 codes invariant], and
- // compare; they will be unequal so we'll fall out of the loop.
- // o Both characters are wide. This is the complex case, and
- // here we have to obtain the wide character, convert to lower
- // case using the Unicode, and compare. Skip to the start of
- // the next character by consulting character-width table.
- FXint comparecase(const FXchar* s1,const FXchar* s2){
- register FXint c1,c2;
- do{
- if((*s1 & 0x80) && (*s2 & 0x80)){
- c1=Unicode::toLower(wc(s1)); s1+=wclen(s1);
- c2=Unicode::toLower(wc(s2)); s2+=wclen(s2);
- }
- else{
- c1=Ascii::toLower(*s1); s1+=1;
- c2=Ascii::toLower(*s2); s2+=1;
- }
- }
- while(c1 && (c1==c2));
- return c1-c2;
- }
- // Compare strings case insensitive up to n
- FXint comparecase(const FXchar* s1,const FXchar* s2,FXint n){
- register FXint c1,c2;
- if(0<n){
- do{
- if((*s1 & 0x80) && (*s2 & 0x80)){
- c1=Unicode::toLower(wc(s1)); s1+=wclen(s1);
- c2=Unicode::toLower(wc(s2)); s2+=wclen(s2);
- }
- else{
- c1=Ascii::toLower(*s1); s1+=1;
- c2=Ascii::toLower(*s2); s2+=1;
- }
- }
- while(--n && c1 && (c1==c2));
- return c1-c2;
- }
- return 0;
- }
- #if 0
- // Compare strings case insensitive
- FXint comparecase(const FXchar* s1,const FXchar* s2){
- register const FXuchar *p1=(const FXuchar *)s1;
- register const FXuchar *p2=(const FXuchar *)s2;
- register FXint c1,c2;
- do{
- c1=Ascii::toLower(*p1++);
- c2=Ascii::toLower(*p2++);
- }
- while(c1 && (c1==c2));
- return c1-c2;
- }
- #endif
- FXint comparecase(const FXchar* s1,const FXString& s2){
- return comparecase(s1,s2.str);
- }
- FXint comparecase(const FXString& s1,const FXchar* s2){
- return comparecase(s1.str,s2);
- }
- FXint comparecase(const FXString& s1,const FXString& s2){
- return comparecase(s1.str,s2.str);
- }
- #if 0
- // Compare strings case insensitive up to n
- FXint comparecase(const FXchar* s1,const FXchar* s2,FXint n){
- register const FXuchar *p1=(const FXuchar *)s1;
- register const FXuchar *p2=(const FXuchar *)s2;
- register FXint c1,c2;
- if(0<n){
- do{
- c1=Ascii::toLower(*p1++);
- c2=Ascii::toLower(*p2++);
- }
- while(--n && c1 && (c1==c2));
- return c1-c2;
- }
- return 0;
- }
- #endif
- FXint comparecase(const FXchar* s1,const FXString& s2,FXint n){
- return comparecase(s1,s2.str,n);
- }
- FXint comparecase(const FXString& s1,const FXchar* s2,FXint n){
- return comparecase(s1.str,s2,n);
- }
- FXint comparecase(const FXString& s1,const FXString& s2,FXint n){
- return comparecase(s1.str,s2.str,n);
- }
- // Comparison operators
- bool operator==(const FXString& s1,const FXString& s2){
- return compare(s1.str,s2.str)==0;
- }
- bool operator==(const FXString& s1,const FXchar* s2){
- return compare(s1.str,s2)==0;
- }
- bool operator==(const FXchar* s1,const FXString& s2){
- return compare(s1,s2.str)==0;
- }
- bool operator!=(const FXString& s1,const FXString& s2){
- return compare(s1.str,s2.str)!=0;
- }
- bool operator!=(const FXString& s1,const FXchar* s2){
- return compare(s1.str,s2)!=0;
- }
- bool operator!=(const FXchar* s1,const FXString& s2){
- return compare(s1,s2.str)!=0;
- }
- bool operator<(const FXString& s1,const FXString& s2){
- return compare(s1.str,s2.str)<0;
- }
- bool operator<(const FXString& s1,const FXchar* s2){
- return compare(s1.str,s2)<0;
- }
- bool operator<(const FXchar* s1,const FXString& s2){
- return compare(s1,s2.str)<0;
- }
- bool operator<=(const FXString& s1,const FXString& s2){
- return compare(s1.str,s2.str)<=0;
- }
- bool operator<=(const FXString& s1,const FXchar* s2){
- return compare(s1.str,s2)<=0;
- }
- bool operator<=(const FXchar* s1,const FXString& s2){
- return compare(s1,s2.str)<=0;
- }
- bool operator>(const FXString& s1,const FXString& s2){
- return compare(s1.str,s2.str)>0;
- }
- bool operator>(const FXString& s1,const FXchar* s2){
- return compare(s1.str,s2)>0;
- }
- bool operator>(const FXchar* s1,const FXString& s2){
- return compare(s1,s2.str)>0;
- }
- bool operator>=(const FXString& s1,const FXString& s2){
- return compare(s1.str,s2.str)>=0;
- }
- bool operator>=(const FXString& s1,const FXchar* s2){
- return compare(s1.str,s2)>=0;
- }
- bool operator>=(const FXchar* s1,const FXString& s2){
- return compare(s1,s2.str)>=0;
- }
- // Find n-th occurrence of character, searching forward; return position or -1
- FXint FXString::find(FXchar c,FXint pos,FXint n) const {
- register FXint len=length();
- register FXint p=pos;
- register FXint cc=c;
- if(p<0) p=0;
- if(n<=0) return p;
- while(p<len){
- if(str[p]==cc){ if(--n==0) return p; }
- ++p;
- }
- return -1;
- }
- // Find n-th occurrence of character, searching backward; return position or -1
- FXint FXString::rfind(FXchar c,FXint pos,FXint n) const {
- register FXint len=length();
- register FXint p=pos;
- register FXint cc=c;
- if(p>=len) p=len-1;
- if(n<=0) return p;
- while(0<=p){
- if(str[p]==cc){ if(--n==0) return p; }
- --p;
- }
- return -1;
- }
- // Find a character, searching forward; return position or -1
- FXint FXString::find(FXchar c,FXint pos) const {
- register FXint len=length();
- register FXint p=pos;
- register FXint cc=c;
- if(p<0) p=0;
- while(p<len){ if(str[p]==cc){ return p; } ++p; }
- return -1;
- }
- // Find a character, searching backward; return position or -1
- FXint FXString::rfind(FXchar c,FXint pos) const {
- register FXint len=length();
- register FXint p=pos;
- register FXint cc=c;
- if(p>=len) p=len-1;
- while(0<=p){ if(str[p]==cc){ return p; } --p; }
- return -1;
- }
- // Find a substring of length n, searching forward; return position or -1
- FXint FXString::find(const FXchar* substr,FXint n,FXint pos) const {
- register FXint len=length();
- if(0<=pos && 0<n && n<=len){
- register FXint c=substr[0];
- len=len-n+1;
- while(pos<len){
- if(str[pos]==c){
- if(!compare(str+pos,substr,n)){
- return pos;
- }
- }
- pos++;
- }
- }
- return -1;
- }
- // Find a substring, searching forward; return position or -1
- FXint FXString::find(const FXchar* substr,FXint pos) const {
- return find(substr,strlen(substr),pos);
- }
- // Find a substring, searching forward; return position or -1
- FXint FXString::find(const FXString& substr,FXint pos) const {
- return find(substr.text(),substr.length(),pos);
- }
- // Find a substring of length n, searching backward; return position or -1
- FXint FXString::rfind(const FXchar* substr,FXint n,FXint pos) const {
- register FXint len=length();
- if(0<=pos && 0<n && n<=len){
- register FXint c=substr[0];
- len-=n;
- if(pos>len) pos=len;
- while(0<=pos){
- if(str[pos]==c){
- if(!compare(str+pos,substr,n)){
- return pos;
- }
- }
- pos--;
- }
- }
- return -1;
- }
- // Find a substring, searching backward; return position or -1
- FXint FXString::rfind(const FXchar* substr,FXint pos) const {
- return rfind(substr,strlen(substr),pos);
- }
- // Find a substring, searching backward; return position or -1
- FXint FXString::rfind(const FXString& substr,FXint pos) const {
- return rfind(substr.text(),substr.length(),pos);
- }
- // Find first character in the set of size n, starting from pos; return position or -1
- FXint FXString::find_first_of(const FXchar* set,FXint n,FXint pos) const {
- register FXint len=length();
- register FXint p=pos;
- if(p<0) p=0;
- while(p<len){
- register FXint c=str[p];
- register FXint i=n;
- while(--i>=0){ if(set[i]==c) return p; }
- p++;
- }
- return -1;
- }
- // Find first character in the set, starting from pos; return positiā¦
Large files files are truncated, but you can click here to view the full file