diff options
Diffstat (limited to 'src/kvilib/core/KviQString.cpp')
| -rw-r--r-- | src/kvilib/core/KviQString.cpp | 1366 |
1 files changed, 1366 insertions, 0 deletions
diff --git a/src/kvilib/core/KviQString.cpp b/src/kvilib/core/KviQString.cpp new file mode 100644 index 000000000..2764b12ee --- /dev/null +++ b/src/kvilib/core/KviQString.cpp @@ -0,0 +1,1366 @@ +//============================================================================= +// +// File : KviQString.cpp +// Creation date : Mon Aug 04 2003 13:36:33 CEST by Szymon Stefanek +// +// This file is part of the KVirc irc client distribution +// Copyright (C) 2003-2010 Szymon Stefanek (pragma at kvirc dot net) +// +// This program is FREE software. You can redistribute it and/or +// modify it under the terms of the GNU General Public License +// as published by the Free Software Foundation; either version 2 +// of the License, or (at your opinion) any later version. +// +// This program 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 General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with this program. If not, write to the Free Software Foundation, +// Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. +// +//============================================================================= + +//============================================================================= +// +// Helper functions for the QString class +// +//============================================================================= + + +#include "KviQString.h" +#include "KviCString.h" +#include "KviMemory.h" +#include "KviLocale.h" + +#include <ctype.h> // for tolower() +#include <stdio.h> // for sprintf() +#include <QRegExp> + +// kvi_string.cpp +extern unsigned char iso88591_toLower_map[256]; +extern unsigned char iso88591_toUpper_map[256]; + +#define MY_MIN(a,b) (((a) < (b)) ? (a) : (b)) + +namespace KviQString +{ + // The global empty (and null) string + const QString Empty; + + static char cHexDigits[16] = { '0','1','2','3','4','5','6','7','8','9','a','b','c','d','e','f' }; + + bool equalCSN(const QString & sz1, const QString & sz2, unsigned int uLen) + { + if(uLen == 0) + { + // assume equal + return true; + } + const QChar * pC1 = sz1.unicode(); + const QChar * pC2 = sz2.unicode(); + unsigned int uLMin = MY_MIN(sz1.length(),sz2.length()); + if(uLMin < uLen) + { + return false; + } + const QChar * pC1e = pC1 + uLen; + + if(!pC1 || !pC2) + { + return (pC1 == pC2); + } + + while(pC1 < pC1e) + { + if(pC1->unicode() != pC2->unicode()) + { + return false; + } + pC1++; + pC2++; + } + return (pC1 == pC1e); + } + + bool equalCIN(const QString & sz1, const QString & sz2, unsigned int uLen) + { + if(uLen == 0) + { + // assume equal + return true; + } + const QChar * pC1 = sz1.unicode(); + const QChar * pC2 = sz2.unicode(); + unsigned int uLMin = MY_MIN(sz1.length(),sz2.length()); + if(uLMin < uLen) + { + return false; + } + const QChar * pC1e = pC1 + uLen; + + if(!pC1 || !pC2) + { + return (pC1 == pC2); + } + + while(pC1 < pC1e) + { + if(pC1->toLower().unicode() != pC2->toLower().unicode()) + { + return false; + } + pC1++; + pC2++; + } + return (pC1 == pC1e); + } + + bool equalCSN(const QString & sz1, const char * pc2, unsigned int uLen) + { + if(uLen == 0) + { + // assume equal + return true; + } + const QChar * pC1 = sz1.unicode(); + if((unsigned)sz1.length() < uLen) + { + return false; + } + const QChar * pC1e = pC1 + uLen; + + if(!pc2) + { + return !pC1; + } + if(!pC1) + { + return !pc2; + } + + while((pC1 < pC1e) && (*pc2)) + { + if(pC1->unicode() != *pc2) + { + return false; + } + pC1++; + pc2++; + } + return (pC1 == pC1e); + } + + bool equalCIN(const QString & sz1, const char * pc2, unsigned int uLen) + { + if(uLen == 0) + { + // assume equal + return true; + } + const QChar * pC1 = sz1.unicode(); + if((unsigned)sz1.length() < uLen) + { + return false; + } + const QChar * pC1e = pC1 + uLen; + + if(!pc2) + { + return !pC1; + } + if(!pC1) + { + return !(*pc2); + } + + while((pC1 < pC1e) && (*pc2)) + { + if(pC1->toLower().unicode() != tolower(*pc2)) + { + return false; + } + pC1++; + pc2++; + } + return (pC1 == pC1e); + } + + // pC2 is assumed to be null terminated, sz1 is not! + bool equalCIN(const QString & sz1, const QChar * pC2, unsigned int uLen) + { + if(uLen == 0) + { + // assume equal + return true; + } + const QChar * pC1 = sz1.unicode(); + if((unsigned)sz1.length() < uLen) + { + return false; + } + const QChar * pC1e = pC1 + uLen; + + if(!pC2) + { + return !pC1; + } + if(!pC1) + { + return !(pC2->unicode()); + } + + while((pC1 < pC1e) && (pC2->unicode())) + { + if(pC1->toLower().unicode() != pC2->toLower().unicode()) + { + return false; + } + pC1++; + pC2++; + } + return (pC1 == pC1e); + } + + QString makeSizeReadable(quint64 bytes) + { + double dSize = bytes; + if(dSize < 1024) + { + return QString(__tr2qs("%1 bytes")).arg(dSize,0,'f',0); + } + + dSize /= 1024; + if(dSize < 1024) + { + return QString(__tr2qs("%1 KiB")).arg(dSize,0,'f',3); + } + + dSize /= 1024; + if(dSize < 1024) + { + return QString(__tr2qs("%1 MiB")).arg(dSize,0,'f',3); + } + + //Pirated DVD?;) + dSize /= 1024; + if(dSize < 1024) + { + return QString(__tr2qs("%1 GiB")).arg(dSize,0,'f',3); + } + + //Uhm.. We are downloading a whole internet:))) + dSize /= 1024; + return QString(__tr2qs("%1 TiB")).arg(dSize,0,'f',3); + } + + bool equalCS(const QString & sz1, const QString & sz2) + { + if(sz1.length() != sz2.length()) + { + return false; + } + + const QChar * pC1 = sz1.unicode(); + const QChar * pC2 = sz2.unicode(); + const QChar * pC1e = pC1 + sz1.length(); + + if(!pC1 || !pC2) + { + return (pC1 == pC2); + } + + while(pC1 < pC1e) + { + if(pC1->unicode() != pC2->unicode()) + { + return false; + } + pC1++; + pC2++; + } + return (pC1 == pC1e); + } + + bool equalCI(const QString & sz1, const QString & sz2) + { + if(sz1.length() != sz2.length()) + { + return false; + } + + const QChar * pC1 = sz1.unicode(); + const QChar * pC2 = sz2.unicode(); + const QChar * pC1e = pC1 + sz1.length(); + + if(!pC1 || !pC2) + { + return (pC1 == pC2); + } + + while(pC1 < pC1e) + { + if(pC1->toLower().unicode() != pC2->toLower().unicode()) + { + return false; + } + pC1++; + pC2++; + } + return (pC1 == pC1e); + } + + // sz2 is assumed to be null terminated, sz1 is not! + bool equalCI(const QString & sz1, const QChar * pC2) + { + const QChar * pC1 = sz1.unicode(); + const QChar * pC1e = pC1 + sz1.length(); + + if(!pC1 || !pC2) + { + return (pC1 == pC2); + } + + while(pC1 < pC1e) + { + if(!pC2->unicode()) + { + // sz1 has at least another character + return false; + } + if(pC1->toLower().unicode() != pC2->toLower().unicode()) + { + return false; + } + pC1++; + pC2++; + } + return (pC1 == pC1e) && (!pC2->unicode()); + } + + bool equalCS(const QString & sz1, const char * pc2) + { + const QChar * pC1 = sz1.unicode(); + const QChar * pC1e = pC1 + sz1.length(); + + if(!pC1) + { + return !pc2; + } + + while((pC1 < pC1e) && (*pc2)) + { + if(pC1->unicode() != *pc2) + { + return false; + } + pC1++; + pc2++; + } + return ((pC1 == pC1e) && (*pc2 == '\0')); + } + + bool equalCI(const QString & sz1, const char * pc2) + { + const QChar * pC1 = sz1.unicode(); + const QChar * pC1e = pC1 + sz1.length(); + + if(!pC1) + { + return !pc2; + } + + while((pC1 < pC1e) && (*pc2)) + { + if(pC1->toLower().unicode() != tolower(*pc2)) + { + return false; + } + pC1++; + pc2++; + } + return ((pC1 == pC1e) && (*pc2 == '\0')); + } + + int cmpCS(const QString & sz1, const QString & sz2) + { + const QChar * pC1 = sz1.unicode(); + const QChar * pC2 = sz2.unicode(); + const QChar * pC1e = pC1 + sz1.length(); + const QChar * pC2e = pC2 + sz2.length(); + + if(!pC1) + { + if(!pC2) + { + return 0; + } + return -1; + } + if(!pC2) + { + return 1; + } + + + for(;;) + { + if(pC1 >= pC1e) + { + if(pC2 < pC2e) + { + return /* 0 */ - (pC2->unicode()); + } + return 0; + } + if(pC2 >= pC2e) + { + return pC1->unicode() /* - 0 */; + } + + int iDiff = pC1->unicode() - pC2->unicode(); + if(iDiff) + { + return iDiff; + } + + pC1++; + pC2++; + } + + return 0; // never here + } + + int cmpCI(const QString & sz1, const QString & sz2, bool bNonAlphaGreater) + { + const QChar * pC1 = sz1.unicode(); + const QChar * pC2 = sz2.unicode(); + const QChar * pC1e = pC1 + sz1.length(); + const QChar * pC2e = pC2 + sz2.length(); + + if(!pC1) + { + if(!pC2) + { + return 0; + } + return -1; + } + if(!pC2) + { + return 1; + } + + for(;;) + { + if(bNonAlphaGreater) + { + if(pC1->isLetterOrNumber() && !pC2->isLetterOrNumber()) + { + return -1; + } else if(!pC1->isLetterOrNumber() && pC2->isLetterOrNumber()) + { + return 1; + } + } + + if(pC1 >= pC1e) + { + if(pC2 < pC2e) + { + return /* 0 */ - (pC2->toLower().unicode()); + } + return 0; + } + + if(pC2 >= pC2e) + { + return pC1->toLower().unicode() /* - 0 */; + } + + int iDiff = pC1->toLower().unicode() - pC2->toLower().unicode(); + + if(iDiff) + { + return iDiff; + } + + pC1++; + pC2++; + } + + return 0; // never here + } + + int cmpCIN(const QString & sz1, const QString & sz2, unsigned int uLen) + { + if(uLen == 0) + { + // assume equal + return 0; + } + unsigned int u1 = MY_MIN(uLen,(unsigned)sz1.length()); + unsigned int u2 = MY_MIN(u1,(unsigned)sz2.length()); // FIXME: THIS IS NOT OK + + const QChar * pC1 = sz1.unicode(); + const QChar * pC2 = sz2.unicode(); + const QChar * pC1e = pC1 + u2; + + if(!pC1) + { + if(!pC2) + { + return 0; + } + return -1; + } + if(!pC2) + { + return 1; + } + + int iDiff = 0; + + while((pC1 < pC1e) && !(iDiff = (pC1->toLower().unicode() - pC2->toLower().unicode()))) + { + pC1++; + pC2++; + } + + return iDiff; + } + + void ensureLastCharIs(QString & szSrc, const QChar & c) + { + if(!lastCharIs(szSrc,c)) + { + szSrc.append(c); + } + } + + QString getToken(QString & szSrc, const QChar & sep) + { + int i = 0; + while(i < szSrc.length()) + { + if(szSrc[i] == sep) + { + break; + } + i++; + } + QString szRet; + if(i == szSrc.length()) + { + szRet = szSrc; + szSrc = ""; + } else { + szRet = szSrc.left(i); + while(i < szSrc.length()) + { + if(szSrc[i] != sep) + { + break; + } + i++; + } + if(i == szSrc.length()) + { + szSrc = ""; + } else { + szSrc.remove(0,i); + } + } + return szRet; + } + + void stripRightWhiteSpace(QString & szSrc) + { + int iRemove = 0; + while(iRemove < szSrc.length()) + { + if(szSrc.at(szSrc.length() - (iRemove + 1)).isSpace()) + { + iRemove++; + } else { + break; + } + } + if(iRemove > 0) + { + szSrc.remove(szSrc.length() - iRemove,iRemove); + } + } + + void stripRight(QString & szSrc, const QChar & c) + { + int iRemove = 0; + while(iRemove < szSrc.length()) + { + if(szSrc.at(szSrc.length() - (iRemove + 1)) == c) + { + iRemove++; + } else { + break; + } + } + if(iRemove > 0) + { + szSrc.remove(szSrc.length() - iRemove,iRemove); + } + } + + void stripLeft(QString & szSrc, const QChar & c) + { + int iRemove = 0; + while(iRemove < szSrc.length()) + { + if(szSrc[iRemove] == c) + { + iRemove++; + } else { + break; + } + } + if(iRemove > 0) + { + szSrc.remove(0,iRemove); + } + } + + void detach(QString & szSrc) + { + szSrc.resize(szSrc.length()); + } + + const QChar * nullTerminatedArray(const QString & szSrc) + { + //szSrc.resize(szSrc.length()); // detach! + return szSrc.constData(); + } + + void appendNumber(QString & szSrc, double dReal) + { +#ifdef COMPILE_ON_MINGW + //workaround for #801 + QString cBuffer; + cBuffer.setNum(dReal, 'f'); +#else + char cBuffer[512]; + ::sprintf(cBuffer,"%f",dReal); +#endif + szSrc.append(cBuffer); + } + + void appendNumber(QString & szSrc, int iInteger) + { + char cBuffer[64]; + ::sprintf(cBuffer,"%d",iInteger); + szSrc.append(cBuffer); + } + + void appendNumber(QString & szSrc, kvi_i64_t iInteger) + { + char cBuffer[64]; + ::sprintf(cBuffer,"%lld", (long long int)iInteger); + szSrc.append(cBuffer); + } + + void appendNumber(QString & szSrc, kvi_u64_t uInteger) + { + char cBuffer[64]; + ::sprintf(cBuffer,"%llu", (long long unsigned int)uInteger); + szSrc.append(cBuffer); + } + + void appendNumber(QString & szSrc, unsigned int uInteger) + { + char cBuffer[64]; + ::sprintf(cBuffer,"%u",uInteger); + szSrc.append(cBuffer); + } + + void vsprintf(QString & szSrc, const QString & szFmt, kvi_va_list list) + { +#define MEMINCREMENT 32 + + int iRealLen = 0; + int iAllocSize = MEMINCREMENT; + + //szSrc.resize(allocsize); + + const QChar * pFmt = nullTerminatedArray(szFmt); + if(!pFmt) + { + szSrc = QString(); + return; + } + + QChar * pBuffer = (QChar *)KviMemory::allocate(sizeof(QChar) * iAllocSize); + //QChar * p = (QChar *)s.unicode(); + + char * pcArgString; + long lArgValue; + unsigned long ulArgValue; + + //9999999999999999999999999999999\0 + char cNumberBuffer[32]; //enough ? 10 is enough for 32bit unsigned int... + char * pcNumBuf; + unsigned int iTmp; + + QChar * p = pBuffer; + +#define INCREMENT_MEM \ + { \ + iAllocSize += MEMINCREMENT; \ + pBuffer = (QChar *)KviMemory::reallocate(pBuffer,sizeof(QChar) * iAllocSize); \ + p = pBuffer + iRealLen; \ + } + +#define INCREMENT_MEM_BY(numchars) \ + { \ + iAllocSize += numchars + MEMINCREMENT; \ + pBuffer = (QChar *)KviMemory::reallocate(pBuffer,sizeof(QChar) * iAllocSize); \ + p = pBuffer + iRealLen; \ + } + + for(; pFmt->unicode() ; ++pFmt) + { + if(iRealLen == iAllocSize)INCREMENT_MEM + + //copy up to a '%' + if(pFmt->unicode() != '%') + { + *p++ = *pFmt; + iRealLen++; + continue; + } + + ++pFmt; //skip this '%' + switch(pFmt->unicode()) + { + case 's': // char * string + { + pcArgString = kvi_va_arg(list,char *); + if(!pcArgString) + { + pcArgString = (char*) "[!NULL!]"; + } + QString szStr(pcArgString); + if(szStr.isEmpty()) + { + continue; + } + int iLen = szStr.length(); + const QChar * pCh = szStr.unicode(); + if(!pCh) + { + continue; + } + if((iAllocSize - iRealLen) < iLen) + { + INCREMENT_MEM_BY(iLen) + } + while(iLen--) + { + *p++ = *pCh++; + } + iRealLen += szStr.length(); + continue; + } + case 'S': // KviCString * string + { + KviCString * szStr = kvi_va_arg(list,KviCString *); + if(!szStr) + { + continue; + } + if((iAllocSize - iRealLen) < szStr->len()) + { + INCREMENT_MEM_BY(szStr->len()) + } + pcArgString = szStr->ptr(); + while(*pcArgString) + { + *p++ = QChar(*pcArgString++); + } + iRealLen += szStr->len(); + continue; + } + case 'Q': // QString * string + { + QString * szStr = kvi_va_arg(list,QString *); + if(!szStr) + { + continue; + } + if(szStr->isEmpty()) + { + continue; + } + int iLen = szStr->length(); + const QChar * pCh = szStr->unicode(); + if(!pCh) + { + continue; + } + if((iAllocSize - iRealLen) < iLen) + { + INCREMENT_MEM_BY(iLen) + } + while(iLen--) + { + *p++ = *pCh++; + } + iRealLen += szStr->length(); + continue; + } + case 'c': //char + { + // + // I'm not sure about this... + // In the linux kernel source the + // unsigned char is extracted from an integer type. + // We assume that gcc stacks a char argument + // as sizeof(int) bytes value. + // Is this always true ? + // + *p++ = (char)kvi_va_arg(list,int); + iRealLen++; + continue; + } + case 'q': // QChar * + { + // + // I'm not sure about this... + // In the linux kernel source the + // unsigned char is extracted from an integer type. + // We assume that gcc stacks a char argument + // as sizeof(int) bytes value. + // Is this always true ? + // + *p++ = *((QChar *)kvi_va_arg(list,QChar *)); + iRealLen++; + continue; + } + case 'd': //signed integer + { + lArgValue = kvi_va_arg(list,int); + if(lArgValue < 0) + { + //negative integer + *p++ = '-'; + iRealLen++; + //need to have it positive. most negative integer exception (avoid completely senseless (non digit) responses) + lArgValue = -lArgValue; + if(lArgValue < 0) + { + //we get -0 here + lArgValue = 0; + } + } + //write the number in a temporary buffer + pcNumBuf = cNumberBuffer; + do { + iTmp = lArgValue / 10; + *pcNumBuf++ = lArgValue - (iTmp * 10) + '0'; + } while((lArgValue = iTmp)); + //copy now.... + ulArgValue = pcNumBuf - cNumberBuffer; //length of the number string + if((iAllocSize - iRealLen) < (int)ulArgValue) + { + INCREMENT_MEM_BY(ulArgValue) + } + do { + *p++ = QChar(*--pcNumBuf); + } while(pcNumBuf != cNumberBuffer); + iRealLen += ulArgValue; + continue; + } + case 'u': //unsigned integer + { + ulArgValue = kvi_va_arg(list,unsigned int); //many implementations place int here + //write the number in a temporary buffer + pcNumBuf = cNumberBuffer; + do { + iTmp = ulArgValue / 10; + *pcNumBuf++ = ulArgValue - (iTmp * 10) + '0'; + } while((ulArgValue = iTmp)); + //copy now.... + lArgValue = pcNumBuf - cNumberBuffer; //length of the number string + if((iAllocSize - iRealLen) < lArgValue) + { + INCREMENT_MEM_BY(lArgValue) + } + do { + *p++ = *--pcNumBuf; + } while(pcNumBuf != cNumberBuffer); + iRealLen += lArgValue; + continue; + } + case 'h': + case 'x': // hexadecimal unsigned integer + { + static char cHexSmallDigits[] = "0123456789abcdef"; + ulArgValue = kvi_va_arg(list,unsigned int); //many implementations place int here + //write the number in a temporary buffer + pcNumBuf = cNumberBuffer; + do { + iTmp = ulArgValue / 16; + *pcNumBuf++ = cHexSmallDigits[ulArgValue - (iTmp * 16)]; + } while((ulArgValue = iTmp)); + //copy now.... + lArgValue = pcNumBuf - cNumberBuffer; //length of the number string + if((iAllocSize - iRealLen) < lArgValue) + { + INCREMENT_MEM_BY(lArgValue) + } + do { + *p++ = *--pcNumBuf; + } while(pcNumBuf != cNumberBuffer); + iRealLen += lArgValue; + continue; + } + case 'H': + case 'X': // hexadecimal unsigned integer + { + static char cHexBigDigits[] = "0123456789ABCDEF"; + ulArgValue = kvi_va_arg(list,unsigned int); //many implementations place int here + //write the number in a temporary buffer + pcNumBuf = cNumberBuffer; + do { + iTmp = ulArgValue / 16; + *pcNumBuf++ = cHexBigDigits[ulArgValue - (iTmp * 16)]; + } while((ulArgValue = iTmp)); + //copy now.... + lArgValue = pcNumBuf - cNumberBuffer; //length of the number string + if((iAllocSize - iRealLen) < lArgValue) + { + INCREMENT_MEM_BY(lArgValue) + } + do { + *p++ = *--pcNumBuf; + } while(pcNumBuf != cNumberBuffer); + iRealLen += lArgValue; + continue; + } + default: + { + // a normal percent followed by some char + *p++ = '%'; //write it + iRealLen++; + if(pFmt->unicode()) + { + if(iRealLen == iAllocSize) + { + INCREMENT_MEM + } + *p++ = *pFmt; + iRealLen++; + } + continue; + } + } + } + + szSrc.setUnicode(pBuffer,iRealLen); + KviMemory::free(pBuffer); + //szSrc.squeeze(); + } + + QString & sprintf(QString & szSrc, const QString & szFmt, ...) + { + kvi_va_list list; + kvi_va_start_by_reference(list,szFmt); + //print...with max 256 chars + KviQString::vsprintf(szSrc,szFmt,list); + kvi_va_end(list); + return szSrc; + } + + void appendFormatted(QString & szSrc, const QString & szFmt, ...) + { + QString szTmp; + kvi_va_list list; + kvi_va_start_by_reference(list,szFmt); + //print...with max 256 chars + KviQString::vsprintf(szTmp,szFmt,list); + kvi_va_end(list); + szSrc.append(szTmp); + } + + bool matchWildExpressions(const QString & szM1, const QString & szM2) + { + // s1 + // pM1 + // mask1 : *xor + // mask2 : xorand*xor + // m2 + // s2 + + // s2 + // m2 + // | + // XorT!xor@111.111.111.11 + // + // *!*@*.net + // | + // pM1 + // s1 + // + + const QChar * pM1 = (const QChar *)szM1.constData(); + const QChar * pM2 = (const QChar *)szM2.constData(); + + if(!(pM1 && pM2 && (pM1->unicode()))) + { + return false; + } + + const QChar * pSavePos1 = 0; + const QChar * pSavePos2 = pM2; + while(pM1->unicode()) + { + //loop managed by pM1 (initially first mask) + if(pM1->unicode() == '*') + { + //Found a wildcard in pM1 + //move to the next char and save the position...this is our jolly + pSavePos1 = ++pM1; + if(!pSavePos1->unicode()) + { + //last was a wildcard, matches everything ahead... + return true; + } + //next return state for the second string + pSavePos2 = pM2 + 1; + //and return + continue; + } + if(!pM2->unicode()) + { + //pM2 finished and we had something to match here! + return false; + } + if(pM1->toLower() == pM2->toLower()) + { + //chars matched. go ahead in the two strings + pM1++; + pM2++; + if((!(pM1->unicode())) && pM2->unicode() && pSavePos1) + { + //pM1 finished, but pM2 not yet and we have a savePosition for pM1 (there was a wildcard)... + //retry matching the string following the * from the savePos2 (one char ahead last time) + //back to char after wildcard + pM1 = pSavePos1; + //back to last savePos2 + pM2 = pSavePos2; + //next savePos2 will be next char + pSavePos2++; + } + } else { + if(pM2->unicode() == '*') + { + //A wlidcard in the second string + //Invert the game : mask1 <-> mask2 + //mask2 now leads the game... + //aux + pSavePos1 = pM1; + //...swap + pM1 = pM2; + //...swap + pM2 = pSavePos1; + //sync save pos1 + pSavePos1 = pM1; + //sync save pos2 + pSavePos2 = pM2 + 1; + //...and again + continue; + } + // pM1 != pM2, pM1 != *, pM2 != * + if((pM1->unicode() == '?') || (pM2->unicode() == '?')) + { + pM1++; + pM2++; + if((!(pM1->unicode())) && pM2->unicode() && pSavePos1) + { + //pM1 finished, but pM2 not yet and we have a savePosition for pM1 (there was a wildcard)... + //retry matching the string following the * from the pSavePos2 (one char ahead last time) + //back to char after wildcard + pM1 = pSavePos1; + //back to last pSavePos2 + pM2 = pSavePos2; + //next pSavePos2 will be next char + pSavePos2++; + } + } else { + if(pSavePos1) + { + //Have a jolly man...allow not matching... + //go back to char after wildcard...need to rematch... + pM1 = pSavePos1; + //back to last pSavePos2 + pM2 = pSavePos2; + //and set next pSavePos2 + pSavePos2++; + } else { + //No previous wildcards...not matched! + return false; + } + } + } + } + //pM1 surely finished, so for the match, pM2 must be finished too + return (!(pM2->unicode())); + } + + bool matchString(const QString & szExp, const QString & szStr, bool bIsRegExp, bool bExact, bool bCs) + { +#ifdef PURPOSE_UNCLEAR + QString szWildcard; + QChar * pPtr = (QChar*)szExp.constData(); + + if(!pPtr) + return 0; + + while(pPtr->unicode()) + { + if((pPtr->unicode() == '[') || (pPtr->unicode() == ']')) + { + szWildcard.append("["); + szWildcard.append(*pPtr); + szWildcard.append("]"); + } else { + szWildcard.append(*pPtr); + } + pPtr++; + } + QRegExp re(szWildcard,bCs ? Qt::CaseSensitive : Qt::CaseInsensitive,bIsRegExp ? QRegExp::RegExp : QRegExp::Wildcard); +#else + QRegExp re(szExp,bCs ? Qt::CaseSensitive : Qt::CaseInsensitive,bIsRegExp ? QRegExp::RegExp : QRegExp::Wildcard); +#endif + if(bExact) + return re.exactMatch(szStr); + return re.indexIn(szStr) != -1; + } + + void cutFromFirst(QString & szSrc, const QChar & c, bool bIncluded) + { + int iIdx = szSrc.indexOf(c); + + if(iIdx == -1) return; + szSrc.truncate(bIncluded ? iIdx : iIdx + 1); + } + + void cutFromFirst(QString & szSrc, const QString & szFind, bool bIncluded) + { + int iIdx = szSrc.indexOf(szFind); + if(iIdx == -1) return; + szSrc.truncate(bIncluded ? iIdx : iIdx + szFind.length()); + } + + void cutFromLast(QString & szSrc, const QChar & c, bool bIncluded) + { + int iIdx = szSrc.lastIndexOf(c); + + if(iIdx == -1) return; + szSrc.truncate(bIncluded ? iIdx : iIdx + 1); + } + + void cutFromLast(QString & szSrc, const QString & szFind, bool bIncluded) + { + int iIdx = szSrc.lastIndexOf(szFind); + if(iIdx == -1) return; + szSrc.truncate(bIncluded ? iIdx : iIdx + szFind.length()); + } + + void cutToFirst(QString & szSrc, const QChar & c, bool bIncluded, bool bClearIfNotFound) + { + int iIdx = szSrc.indexOf(c); + if(iIdx == -1) + { + if(bClearIfNotFound) szSrc = ""; + return; + } + szSrc.remove(0,bIncluded ? iIdx + 1 : iIdx); + } + + void cutToFirst(QString & szSrc, const QString & szFind, bool bIncluded, bool bClearIfNotFound) + { + int iIdx = szSrc.indexOf(szFind); + if(iIdx == -1) + { + if(bClearIfNotFound) szSrc = ""; + return; + } + szSrc.remove(0,bIncluded ? iIdx + szFind.length() : iIdx); + } + + void cutToLast(QString & szSrc, const QChar & c, bool bIncluded, bool bClearIfNotFound) + { + int iIdx = szSrc.lastIndexOf(c); + if(iIdx == -1) + { + if(bClearIfNotFound) szSrc = ""; + return; + } + szSrc.remove(0,bIncluded ? iIdx + 1 : iIdx); + } + + void cutToLast(QString & szSrc, const QString & szFind, bool bIncluded, bool bClearIfNotFound) + { + int iIdx = szSrc.lastIndexOf(szFind); + if(iIdx == -1) + { + if(bClearIfNotFound) szSrc = ""; + return; + } + szSrc.remove(0,bIncluded ? iIdx + szFind.length() : iIdx); + } + + QString leftToFirst(QString & szSrc, const QChar & c, bool bIncluded, bool bReturnFullStringIfNotFound) + { + int iIdx = szSrc.indexOf(c); + if(iIdx == -1) + return bReturnFullStringIfNotFound ? szSrc : QString(); + return szSrc.left(bIncluded ? iIdx + 1 : iIdx); + } + + QString leftToFirst(QString & szSrc, const QString & szFind, bool bIncluded, bool bReturnFullStringIfNotFound) + { + int iIdx = szSrc.indexOf(szFind); + if(iIdx == -1) + return bReturnFullStringIfNotFound ? szSrc : QString(); + return szSrc.left(bIncluded ? iIdx + 1 : iIdx); + } + + QString leftToLast(QString & szSrc, const QChar & c, bool bIncluded, bool bReturnFullStringIfNotFound) + { + int iIdx = szSrc.lastIndexOf(c); + if(iIdx == -1) + return bReturnFullStringIfNotFound ? szSrc : QString(); + return szSrc.left(bIncluded ? iIdx + 1 : iIdx); + } + + QString leftToLast(QString & szSrc, const QString & szFind, bool bIncluded, bool bReturnFullStringIfNotFound) + { + int iIdx = szSrc.lastIndexOf(szFind); + if(iIdx == -1) + return bReturnFullStringIfNotFound ? szSrc : QString(); + return szSrc.left(bIncluded ? iIdx + 1 : iIdx); + } + + QString upperISO88591(const QString & szSrc) + { + const QChar * pC = nullTerminatedArray(szSrc); + if(!pC) + { + QString szRet; + return szRet; + } + QChar * pBuffer = (QChar *)KviMemory::allocate(sizeof(QChar) * szSrc.length()); + QChar * pB = pBuffer; + unsigned short usX = pC->unicode(); + while(usX) + { + if(usX < 256) + *pB = QChar((unsigned short)iso88591_toUpper_map[usX]); + else + *pB = *pC; + pC++; + pB++; + usX = pC->unicode(); + } + QString szRet(pBuffer,szSrc.length()); + KviMemory::free(pBuffer); + return szRet; + } + + QString lowerISO88591(const QString & szSrc) + { + const QChar * pC = nullTerminatedArray(szSrc); + if(!pC) + { + QString szRet; + return szRet; + } + QChar * pBuffer = (QChar *)KviMemory::allocate(sizeof(QChar) * szSrc.length()); + QChar * pB = pBuffer; + unsigned short usX = pC->unicode(); + while(usX) + { + if(usX < 256) + { + *pB = QChar((unsigned short)iso88591_toLower_map[usX]); + } else + *pB = *pC; + pC++; + pB++; + usX = pC->unicode(); + } + QString szRet(pBuffer,szSrc.length()); + KviMemory::free(pBuffer); + return szRet; + } + + void transliterate(QString & szSrc, const QString & szToFind, const QString & szReplacement) + { + int i = 0; + int il = MY_MIN(szToFind.length(),szReplacement.length()); + while(i < il) + { + int k = 0; + int kl = szSrc.length(); + while(k < kl) + { + if(szSrc[k] == szToFind[i]) + { + szSrc[k] = szReplacement[i]; + } + k++; + } + i++; + } + } + + void bufferToHex(QString & szRetBuffer, const unsigned char * pcBuffer, unsigned int uLen) + { + szRetBuffer.resize(uLen * 2); + unsigned int u = 0; + while(u < (uLen * 2)) + { + szRetBuffer[int(u)] = QChar((unsigned int)cHexDigits[(*pcBuffer) / 16] ); + u++; + szRetBuffer[int(u)] = QChar((unsigned int)cHexDigits[(*pcBuffer) % 16] ); + u++; + pcBuffer++; + } + } + + void escapeKvs(QString * szData, uint uFlags) + { + // escape any $;\% + szData->replace("\\","\\\\"); + szData->replace("\"","\\\""); + szData->replace(";","\\;"); + if(!(uFlags & PermitFunctions)) + szData->replace("$","\\$"); + if(!(uFlags & PermitVariables)) + szData->replace("%","\\%"); + if(!(uFlags & PermitMultiLine)) + { + szData->replace("\r"," "); + szData->replace("\n"," "); + } + if(uFlags & EscapeSpace) + szData->replace(" ","\\ "); + + /* + szData->replace("(","\\("); + szData->replace(")","\\)"); + szData->replace("-","\\-"); + szData->replace("+","\\+"); + */ + } +} |
