home *** CD-ROM | disk | FTP | other *** search
Wrap
/**************************************************************************************** XString (c) 1996 by Jens von Pilgrim Details: See header file History: Note: in Strip: while-loops (correct for non-short-evaluation... (first<length) *****************************************************************************************/ // #define _BUILD_DLL_ // #include "stdio.h" // only for testing... // #include "stdafx.h" //#include "XLib.h" #include "XString.h" #include <stdlib.h> #include <string.h> #include <ctype.h> /*@ XString::StrCmp(const XString &inThen) @group Comperasion @remarks Returns exactly the result from strcmp, usefull if other function needs this result. The Result is == 0: this string == inThen < 0: this string < inThen > 0: this string > inThen */ int XString::StrCmp(const XString &inThen) const { X_ASSERT(m_pszChar!=NULL); X_ASSERT( inThen.m_pszChar!=NULL); return strcmp(m_pszChar, inThen.m_pszChar); } /*@ XString::XString() @group Constructor/Destructor @remarks Constructs an empty string */ XString::XString() { m_pszChar = (char *) malloc(1); X_ASSERT(m_pszChar != NULL); m_pszChar[0] = '\0'; m_Length = 0; m_isNULL = TRUE; } /*@ XString::XString(const XString &aString) @group Constructor/Destructor @remarks Constructs a string as a copy of 'aString' */ XString::XString(const XString &aString) { X_ASSERT(&aString != NULL); X_ASSERT(&aString.m_pszChar != NULL); m_Length = aString.m_Length; m_isNULL = aString.m_isNULL; m_pszChar = (char *) malloc(m_Length+1); X_ASSERT(m_pszChar != NULL); memcpy(m_pszChar, aString.m_pszChar, m_Length+1); X_ASSERT(m_Length == strlen(m_pszChar)); } /*@ XString::XString(char *pszChar) @group Constructor/Destructor @remarks Constructs a string as a copy of pszChar, usefull as caster */ XString::XString(char *pszChar) { X_ASSERT(pszChar != NULL); m_Length = strlen(pszChar); m_pszChar = (char *) malloc(m_Length+1); X_ASSERT(m_pszChar != NULL); memcpy(m_pszChar, pszChar, m_Length+1); X_ASSERT(GetLength() == strlen(m_pszChar)); m_isNULL = FALSE; } XString::XString(const char *pszChar) { X_ASSERT(pszChar != NULL); m_Length = strlen(pszChar); m_pszChar = (char *) malloc(m_Length+1); X_ASSERT(m_pszChar != NULL); memcpy(m_pszChar, pszChar, m_Length+1); X_ASSERT(GetLength() == strlen(m_pszChar)); m_isNULL = FALSE; } XString::XString(char *pszChar, int duplicate) { if (pszChar != NULL) m_Length = strlen(pszChar); else m_Length = 0; m_pszChar = pszChar; m_isNULL = FALSE; } /*@ XString::XString(char aChar) @group Constructor/Destructor @remarks Constructs a string with first char == aChar */ XString::XString(char aChar) { m_Length = 1; m_pszChar = (char *) malloc(m_Length+1); X_ASSERT(m_pszChar != NULL); m_pszChar[0] = aChar; m_pszChar[1] = '\0'; X_ASSERT(m_Length == strlen(m_pszChar)); m_isNULL = FALSE; } /*@ XString::XString(int aNumber, int Radix) @group Constructor/Destructor @remarks Constructs a string and casts an int, usefull as caster */ XString::XString(int aNumber, int Radix) { m_pszChar = (char *) malloc(20); _itoa(aNumber, m_pszChar, Radix); m_Length = strlen(m_pszChar); ReleaseBuffer(); m_isNULL = FALSE; } /*@ XString::XString(long aNumber, int Radix) @group Constructor/Destructor @remarks Constructs a string and casts an int, usefull as caster */ XString::XString(long aNumber, int Radix) { m_pszChar = (char *) malloc(40); _ltoa(aNumber, m_pszChar, Radix); m_Length = strlen(m_pszChar); ReleaseBuffer(); FALSE; } /*@ XString::~XString() @group Constructor/Destructor @remarks (Virtual) Destructor, removes string from memory */ XString::~XString() { X_ASSERT (m_pszChar != NULL); free(m_pszChar); } /*@ XString::operator =(const XString &aString) @group Set @returns Returns copy of aString @remarks The Sourcestring aString is copied (duplicated) to this-string */ XString XString::operator =(const XString &aString) { X_ASSERT(aString.m_pszChar != NULL); X_ASSERT(aString.m_Length == strlen(aString.m_pszChar)); free(m_pszChar); m_Length = aString.m_Length; m_pszChar = (char *) malloc(m_Length+1); X_ASSERT(m_pszChar != NULL); memcpy(m_pszChar, aString.m_pszChar, m_Length+1); X_ASSERT(m_Length == strlen(m_pszChar)); m_isNULL = aString.m_isNULL; return *this; } /*@ XString::operator() (XSIZE_T inCount) @group Get @returns Returns a pointer to chars. @remarks Usefull in functions requiering char-pointer like printf (printf("Hallo %s", aString()); ). The method works like Left, so AString(5) returns the first 5 chars. */ char* XString::operator() (XSIZE_T inCount) { return Left(inCount)(0); } /*@ XString::operator() () @group Get */ /* const char *const XString::operator() () const { return m_pszChar; } */ /*@ XString::operator[] () @group Get @remarks The same as function At. The first char has index 0! @returns Returns the char at position inZeroIndex. */ char& XString::operator[](XSIZE_T inZeroIndex) const { X_ASSERT(inZeroIndex<m_Length); return m_pszChar[inZeroIndex]; } char& XString::operator[] (int inZeroIndex) const { X_ASSERT(XSIZE_T(inZeroIndex)<m_Length); return m_pszChar[inZeroIndex]; } /*@ XString::At () @group Get @remarks The same as operator []. The first char has index 0! @returns Returns the char at position inZeroIndex. */ char& XString::At(XSIZE_T inZeroIndex) const { X_ASSERT(inZeroIndex<m_Length); return m_pszChar[inZeroIndex]; } /*@ XString::operator const int() @group Caster @returns String as a constant int, sometimes a const is required. Uses standard C-function atoi */ XString::operator const int() const { X_ASSERT(m_pszChar != NULL); return atoi(m_pszChar); } /*@ XString::operator const long() @group Caster @returns String as a constant long int, sometimes a const is required. REMARS Uses standard C-function atol */ XString::operator const long() const { X_ASSERT(m_pszChar != NULL); return atol(m_pszChar); } /*@ XString::operator const double() @group Caster @returns String as a constant float (double), sometimes a const is required. REMARS Uses standard C-function atof */ XString::operator const double() const { X_ASSERT(m_pszChar != NULL); return atof(m_pszChar); } /*@ XString::operator +=(const XString &Str) @group Set @returns Returns thisString+Str REMARS Concats string with another string Str and saves the result in string. Like this: XString a,b,c; ... a=(b+=c); Result: (a==b) = TRUE */ XString XString::operator +=(const XString &Str) { m_isNULL = FALSE; X_ASSERT(Str.m_pszChar!=NULL); X_ASSERT(m_pszChar!=NULL); X_ASSERT(m_Length==strlen(m_pszChar)); char *newChar = (char *) malloc(m_Length+Str.m_Length+1); X_ASSERT(newChar != NULL); memcpy(newChar, m_pszChar, m_Length); memcpy(&newChar[m_Length], Str.m_pszChar, Str.m_Length + 1); free(m_pszChar); m_pszChar = newChar; m_Length += Str.m_Length; X_ASSERT(m_Length == strlen(m_pszChar)); return *this; } /*@ XString::operator +=(const char *Str) @group Set @remarks Adds a string */ XString XString::operator +=(const char *Str) { m_isNULL = FALSE; X_ASSERT(Str!=NULL); X_ASSERT(m_pszChar!=NULL); X_ASSERT(m_Length==strlen(m_pszChar)); XSIZE_T length = strlen(Str); char *newChar = (char *) malloc(m_Length+length+1); X_ASSERT(newChar != NULL); memcpy(newChar, m_pszChar, m_Length); memcpy(&newChar[m_Length], Str, length + 1); free(m_pszChar); m_pszChar = newChar; m_Length += length; X_ASSERT(m_Length == strlen(m_pszChar)); return *this; } /*@ XString::IsEmpty () @group Comperasion @returns TRUE, if the String is empty BOOL, else @remarks If the string is not allocated (f.e. a Stringpointer before calling new) is NOT empyt! If you call any String-Function before calling the Constructor, most functions fail and the program will exit by a failed assert! */ BOOL XString::IsEmpty() const { return GetLength()==0; } void XString::MakeEmpty() { m_pszChar = (char*) realloc(m_pszChar, 1); X_ASSERT(m_pszChar != NULL); m_pszChar[0] = '\0'; m_Length = 0; m_isNULL = FALSE; } BOOL XString::IsNULL() const { return m_isNULL; } void XString::MakeNULL() { MakeEmpty(); m_isNULL = TRUE; } /*@ XString::Mid(XSIZE_T From, XSIZE_T Count) @group Get @returns Returns substring with Count-length from position From in string. @remarks If From>GetLength(), an empty string is returned; if From+Count>GetLength(), a string with a length of (GetLength()-From) is returned. */ XString XString::Mid(XSIZE_T From, XSIZE_T Count) const { X_ASSERT(m_pszChar != NULL); X_ASSERT(m_Length == strlen(m_pszChar)); if ((Count == 0) || (From>=m_Length)) return XString(); if (From+Count>m_Length) Count=m_Length-From; X_ASSERT (Count<=m_Length); XString Res(NULL, 1); Res.m_pszChar = (char *) malloc(Count+1); X_ASSERT(Res.m_pszChar != NULL); memcpy(Res.m_pszChar, m_pszChar+From, Count); Res.m_pszChar[Count]=0; Res.m_Length = Count; X_ASSERT(Res.m_Length == strlen(Res.m_pszChar)); return Res; } /*@ XString::Left(XSIZE_T Count) @group Get @returns Returns the first Count chars as a XString from string. Thus, it's equal to Mid(0, nCount). @remarks If Count>GetLength(), a copy of the string is returned, if Count is 0, an empty string is returned. */ XString XString::Left(XSIZE_T Count) const { X_ASSERT(m_pszChar != NULL); if (Count==0) return XString(); if (Count>m_Length) Count=m_Length; XString Res(NULL, 1); Res.m_Length = Count; Res.m_pszChar = (char *) malloc(Count+1); X_ASSERT(Res.m_pszChar != NULL); memcpy(Res.m_pszChar, m_pszChar, Count); Res.m_pszChar[Count]=0; X_ASSERT(Res.m_Length == strlen(Res.m_pszChar)); return Res; } /*@ XString::Right(..) @group Get @remarks What do you think this methods is for? See Left() for details, rigth up! */ XString XString::Right(XSIZE_T Count) const { X_ASSERT(m_pszChar != NULL); if (Count==0) return XString(); if (Count>m_Length) Count=m_Length; XString Res(NULL, 1); Res.m_Length = Count; Res.m_pszChar = (char *) malloc(Count+1); X_ASSERT(Res.m_pszChar != NULL); memcpy(Res.m_pszChar, &m_pszChar[m_Length-Count], Count+1); // abschließendes 0 wird mitkopiert X_ASSERT(Res.m_Length == strlen(Res.m_pszChar)); return Res; } /*@ XString::Find() @group Enhanced @returns TRUE, if substring is in string, outPos is the (zero-indexed) position of the substring in string (the first). BOOL, if the substring was not found @remarks Because some parameters have standard values, you can call this method also with Find(pos, "..."). */ BOOL XString::Find(XSIZE_T &outPos, const XString &SubString, XSIZE_T From, XSIZE_T inTo, BOOL inInCase) const { X_ASSERT (SubString.m_pszChar != NULL); if (inTo==0) inTo = GetLength(); if (inTo>GetLength()) inTo = GetLength(); if (inTo<From) return FALSE; X_ASSERT (m_pszChar!=NULL); if (SubString.m_Length==0) return FALSE; if (SubString.m_Length>inTo-From) return FALSE; XSIZE_T StrI, SubI=0, SubLength=SubString.m_Length-1, First; if (!inInCase) { for (StrI=From; StrI<inTo-SubLength; StrI++) { if (m_pszChar[StrI]==SubString.m_pszChar[SubI]) { First = StrI; do { if (SubI == SubLength) { outPos = First; return TRUE; }; SubI++; StrI++; } while (m_pszChar[StrI]==SubString.m_pszChar[SubI]); SubI=0; StrI = First; // !!, eg */ in ***/ nicht gefunden! } } } else // Find InCase { for (StrI=From; StrI<inTo-SubLength; StrI++) { if (UpperChar(m_pszChar[StrI])==UpperChar(SubString.m_pszChar[SubI])) { First = StrI; do { if (SubI == SubLength) { outPos = First; return TRUE; }; SubI++; StrI++; } while (UpperChar(m_pszChar[StrI])==UpperChar(SubString.m_pszChar[SubI])); SubI=0; StrI = First; // !!, eg */ in ***/ nicht gefunden! } } } return FALSE; } /*@ XString::FindRev(XSIZE_T &outPos, const XString &SubString, XSIZE_T From = 0, XSIZE_T inTo = 0) @group Enhanced @returns TRUE, if substring is in string, outPos is the (zero-indexed) position of the substring in string (the first). BOOL, if the substring was not found @remarks Because some parameters have standard values, you can call this method also with Find(pos, "..."). */ BOOL XString::FindRev(XSIZE_T &outPos, const XString &SubString, XSIZE_T From, XSIZE_T inTo, BOOL inInCase) const { X_ASSERT (SubString.m_pszChar != NULL); if (inTo==0) inTo = GetLength(); if (From>inTo) return FALSE; X_ASSERT (m_pszChar!=NULL); if (SubString.m_Length==0) return FALSE; if (SubString.m_Length>inTo-From) return FALSE; XSIZE_T StrI, SubI=SubString.m_Length-1, SubLength=SubString.m_Length-1, First; if (!inInCase) { for (StrI=inTo; StrI>From+SubLength; StrI--) { if (m_pszChar[StrI]==SubString.m_pszChar[SubI]) { First = StrI; do { if (SubI == 0) { outPos = First; return TRUE; }; SubI--; StrI--; } while (m_pszChar[StrI]==SubString.m_pszChar[SubI]); SubI=SubLength; StrI = First; // !!, eg */ in ***/ nicht gefunden! } } } else // FindRev InCase { for (StrI=inTo; StrI>From+SubLength; StrI--) { if (UpperChar(m_pszChar[StrI])==UpperChar(SubString.m_pszChar[SubI])) { First = StrI; do { if (SubI == 0) { outPos = First; return TRUE; }; SubI--; StrI--; } while (UpperChar(m_pszChar[StrI])==UpperChar(SubString.m_pszChar[SubI])); SubI=SubLength; StrI = First; // !!, eg */ in ***/ nicht gefunden! } } } return FALSE; } BOOL XString::Search(const XString &SubString, XSIZE_T From, XSIZE_T inTo, BOOL inInCase) const { XSIZE_T dummy; return Find(dummy, SubString, From, inTo, inInCase); } BOOL XString::SearchRev(const XString &SubString, XSIZE_T From, XSIZE_T inTo, BOOL inInCase) const { XSIZE_T dummy; return FindRev(dummy, SubString, From, inTo, inInCase); } BOOL XString::FindWhitespace ( XSIZE_T &outPos, XSIZE_T inFrom, XSIZE_T inTo) const { if (inTo==0) inTo = GetLength(); if (inFrom>inTo) return FALSE; X_ASSERT (m_pszChar!=NULL); outPos = inFrom; while ( outPos < GetLength() ) { if ( isspace( At ( outPos ) ) ) return TRUE; outPos ++; } return FALSE; } BOOL XString::FindAlpha ( XSIZE_T &outPos, XSIZE_T inFrom, XSIZE_T inTo) const { if (inTo==0) inTo = GetLength(); if (inFrom>inTo) return FALSE; X_ASSERT (m_pszChar!=NULL); outPos = inFrom; while ( outPos < GetLength() ) { if ( isalpha( At ( outPos ) ) ) return TRUE; outPos ++; } return FALSE; } BOOL XString::FindNonAlpha ( XSIZE_T &outPos, XSIZE_T inFrom , XSIZE_T inTo) const { if (inTo==0) inTo = GetLength(); if (inFrom>inTo) return FALSE; X_ASSERT (m_pszChar!=NULL); outPos = inFrom; while ( outPos < GetLength() ) { if ( !isalpha( At ( outPos ) ) ) return TRUE; outPos ++; } return FALSE; } BOOL XString::SearchAlpha( XSIZE_T inFrom, XSIZE_T inTo ) const { if (inTo==0) inTo = GetLength(); if (inFrom>inTo) return FALSE; X_ASSERT (m_pszChar!=NULL); inFrom; while ( inFrom < GetLength() ) { if ( isalpha( At ( inFrom ) ) ) return TRUE; inFrom ++; } return FALSE; } BOOL XString::SearchNonAlpha ( XSIZE_T inFrom , XSIZE_T inTo ) const { if (inTo==0) inTo = GetLength(); if (inFrom>inTo) return FALSE; X_ASSERT (m_pszChar!=NULL); inFrom; while ( inFrom < GetLength() ) { if ( !isalpha( At ( inFrom ) ) ) return TRUE; inFrom ++; } return FALSE; } BOOL XString::SearchWhitespace ( XSIZE_T inFrom, XSIZE_T inTo) const { if (inTo==0) inTo = GetLength(); if (inFrom>inTo) return FALSE; X_ASSERT (m_pszChar!=NULL); inFrom; while ( inFrom < GetLength() ) { if ( isspace( At ( inFrom ) ) ) return TRUE; inFrom ++; } return FALSE; } /*@ XString::GetLength() @group Get @remarks Returns the length of the string! */ XSIZE_T XString::GetLength() const { return m_Length; } /*@ XString::GetBuffer(XSIZE_T Size) @group Caster @remarks This is the most dangerous function, because it allows you access to the heart of XString, the char-buffer! Don't use this function for dircet manipulations of the buffer! This function has another job to do! The job of this method is to work as a caster, when some awefull and dirty C-functions needs a char-pointer, like sprintf. Size is the size you initialize the string, take care that the size is great enough! Don't forget to call the ReleaseBuffer()-Function after GetBuffer()! ReleaseBuffer correct the length of the string. The Size is exactly the size of chars in the buffer, the byte for the zero-byte is automatically added! See the example! EXAMPLE XString a; double pi=3.14; sprintf(a.GetBuffer(100), "Pi = %2.3f", pi); a.ReleaseBuffer(); */ char* XString::GetBuffer(XSIZE_T Size) { if (Size==0) { return m_pszChar; } char *temp; temp = (char *) calloc(sizeof(char), Size+1); X_ASSERT (temp != NULL); XSIZE_T MinLength; if (Size>m_Length) MinLength = m_Length; else MinLength = Size; memcpy(temp, m_pszChar, MinLength); free(m_pszChar); m_pszChar = temp; m_Length = Size; return m_pszChar; } /*@ XString::GetBuffer(int Size=0) @remarks Sometimes an int is available for the length.. */ char* XString::GetBuffer(int Size) { X_ASSERT (Size>=0); return GetBuffer((XSIZE_T) Size); } /* int ReleaseBuffer(int Length) { if (Length<0) Length=0; return ReleaseBuffer((XSIZE_T) Length); } */ /*@ XString::ReleaseBuffer(XSIZE_T Length) @group Caster @remarks After getting the buffer with GetBuffer, and after setting the size of the string to Size, this function correct the size of the buffer, so that the size of the buffer is equal to the length of the string. Don't use any other function after GetBuffer, before not calling ReleaseBuffer!!!!!!!!!! */ int XString::ReleaseBuffer(XSIZE_T Length) { m_isNULL = FALSE; if (Length==0) Length = strlen(m_pszChar); X_ASSERT (Length<=m_Length); char *temp = (char *) malloc(Length+1); memcpy(temp, m_pszChar, Length); temp[Length] = 0; free(m_pszChar); m_pszChar = temp; m_Length = Length; X_ASSERT(m_Length == strlen(m_pszChar)); return Length; } /*@ XString::Strip(int inWhere, char inChar) @group Enhanced @returns Number of removed chars @remarks Strip removes all inChars at the beginning (inWhere=XLEFT), at the end (inWhere=XRIGHT), at both ends (inWhere=XBOTH) or removes all inChars (inWhere=XALL) from the string! If you have to remove substring, use Replace() instead! */ int XString::Strip(int inWhere, char inChar) { m_isNULL = FALSE; X_ASSERT(m_pszChar != NULL); if (m_Length == 0) return 0; XSIZE_T First=0, Last=m_Length; // Last 1index (>0)... if (inWhere != XRIGHT) // then strip left { while ((First<m_Length) && (m_pszChar[First] == inChar)) First++; if (First==m_Length) // Stripp all { free(m_pszChar); m_pszChar = (char *) malloc(1); X_ASSERT(m_pszChar != NULL); m_pszChar[0] = '\0'; m_Length = 0; X_ASSERT(m_Length == strlen(m_pszChar)); return Last; } } if (inWhere != XLEFT) // then strip right { while ((Last>0) && (m_pszChar[Last-1] == inChar)) { Last--; } if (Last==0) // Stripp all { free(m_pszChar); m_pszChar = (char *) malloc(1); X_ASSERT(m_pszChar != NULL); m_pszChar[0] = '\0'; Last = m_Length; m_Length = 0; X_ASSERT(m_Length == strlen(m_pszChar)); return Last; } } char *stripped; if (inWhere != XALL) // then build result string { if ((First==0) && (Last==m_Length)) // then nothing to do return 0; stripped = (char *) malloc(Last-First+1); X_ASSERT (stripped != NULL); memcpy(stripped, m_pszChar+First, Last-First); stripped[Last-First] = 0; free(m_pszChar); m_pszChar = stripped; XSIZE_T ret=m_Length; m_Length = Last-First; X_ASSERT(m_Length == strlen(m_pszChar)); return ret-m_Length; } // inWhere == ALL stripped = (char *) malloc(Last-First+1); X_ASSERT (stripped != NULL); XSIZE_T index=First, strindex=0; // 0-index while (index<Last) { if (m_pszChar[index] != inChar) // else ignore this char { stripped[strindex] = m_pszChar[index]; strindex++; } index++; } free(m_pszChar); XSIZE_T oldL=m_Length; m_pszChar = (char *) malloc(strindex+1); X_ASSERT (m_pszChar != NULL); memcpy(m_pszChar, stripped, strindex); m_pszChar[strindex] = 0; free(stripped); m_Length = strindex; X_ASSERT(m_Length == strlen(m_pszChar)); return oldL-m_Length; } /*@ XString::StripWhitespaces ( int inWhere = XBOTH ) @group Enhanced @returns Number of removed chars @remarks Strip whitespaces ( Space, Tab, Linefeed, Carriage return ) like function "Strip" */ int XString::StripWhitespaces ( int inWhere ) { m_isNULL = FALSE; X_ASSERT(m_pszChar != NULL); if (m_Length == 0) return 0; XSIZE_T First=0, Last=m_Length; // Last 1index (>0)... if (inWhere != XRIGHT) // then strip left { while ((First<m_Length) && (isspace(m_pszChar[First]))) First++; if (First==m_Length) // Stripp all { free(m_pszChar); m_pszChar = (char *) malloc(1); X_ASSERT(m_pszChar != NULL); m_pszChar[0] = '\0'; m_Length = 0; X_ASSERT(m_Length == strlen(m_pszChar)); return Last; } } if (inWhere != XLEFT) // then strip right { while ((Last>0) && (isspace(m_pszChar[Last-1]))) { Last--; } if (Last==0) // Stripp all { free(m_pszChar); m_pszChar = (char *) malloc(1); X_ASSERT(m_pszChar != NULL); m_pszChar[0] = '\0'; Last = m_Length; m_Length = 0; X_ASSERT(m_Length == strlen(m_pszChar)); return Last; } } char *stripped; if (inWhere != XALL) // then build result string { if ((First==0) && (Last==m_Length)) // then nothing to do return 0; stripped = (char *) malloc(Last-First+1); X_ASSERT (stripped != NULL); memcpy(stripped, m_pszChar+First, Last-First); stripped[Last-First] = 0; free(m_pszChar); m_pszChar = stripped; XSIZE_T ret=m_Length; m_Length = Last-First; X_ASSERT(m_Length == strlen(m_pszChar)); return ret-m_Length; } // inWhere == ALL stripped = (char *) malloc(Last-First+1); X_ASSERT (stripped != NULL); XSIZE_T index=First, strindex=0; // 0-index while (index<Last) { if (!isspace(m_pszChar[index])) // else ignore this char { stripped[strindex] = m_pszChar[index]; strindex++; } index++; } free(m_pszChar); XSIZE_T oldL=m_Length; m_pszChar = (char *) malloc(strindex+1); X_ASSERT (m_pszChar != NULL); memcpy(m_pszChar, stripped, strindex); m_pszChar[strindex] = 0; free(stripped); m_Length = strindex; X_ASSERT(m_Length == strlen(m_pszChar)); return oldL-m_Length; } /*@ XString::DelSubString(XString inSubString) @group Set @remarks Deletes the first place occurrence of inSubString */ int XString::DelSubString(XString inSubString) { m_isNULL = FALSE; X_ASSERT(inSubString.m_pszChar!=NULL); X_ASSERT(inSubString.m_Length>0); XSIZE_T pos; if (Find(pos, inSubString)) return DelSubString(pos, inSubString.m_Length); return X_ERR; } /*@ XString::DelSubString @group Set @remarks Deletes inCount-chars from inFrom (Zero-Index!). */ int XString::DelSubString(XSIZE_T inFrom, XSIZE_T inCount) { m_isNULL = FALSE; X_ASSERT(inFrom<m_Length); if (inCount==0) return X_ERR; if (inFrom+inCount>m_Length) inCount=m_Length-inFrom; char *temp = (char *) malloc(m_Length-inCount+1); X_ASSERT(temp!=NULL); memcpy(temp, m_pszChar, inFrom); memcpy(temp+inFrom, m_pszChar+inFrom+inCount, m_Length-(inCount+inFrom)); temp[m_Length-inCount] = '\0'; m_Length -= inCount; free(m_pszChar); m_pszChar = temp; X_ASSERT(m_Length == strlen(m_pszChar)); return X_OK; } /*@ XString::Replace(XString inSearch, XString inReplace, int inTimes, XSIZE_T inFrom, XSIZE_T inTo) @group Enhanced @returns Number of replacements @parameters inSearch is the substring to search, inReplace is the string wich replaces the searchstring, the substring is max. inTimes replaced and inFrom and inTo mark the scope. @remarks This is one of the most powerful methods of XString. It works as the Search-Replace-Function of you editor. Of course, the search- and the replace-substring must NOT have the same length! The methods is working very fast, because it first searches the substring, allocs new memory by calculing the new size, and then a new string is build. When the new string is build, there is no more search necessary (only if the replacement-string is greater then the searchstring and the length of the searchstring is smaller then the size of a XSIZE_T-type!). In this moment I'm working on another Replace-method: Replace(BadEnglish, CorrectEnglish, everywhere in this docu...) ;-) */ int XString::Replace(XString inSearch, XString inReplace, int inTimes, XSIZE_T inFrom, XSIZE_T inTo, BOOL inInCase) { m_isNULL = FALSE; XSIZE_T pos=inFrom; int count=0; char *temp; if (inTo==0) inTo=GetLength(); if (inTo<inFrom) { count = inTo; inTo = inFrom; inFrom = count; count =0; } if (inFrom>inTo) return 0; X_ASSERT(m_Length == strlen(m_pszChar)); if (inSearch.GetLength() == inReplace.GetLength()) { while (Find(pos,inSearch, pos, inTo, inInCase)) { count++; memcpy(&m_pszChar[pos], inReplace.m_pszChar, inReplace.GetLength()); if (count==inTimes) break; pos += inSearch.GetLength(); } } else if (inSearch.GetLength() > inReplace.GetLength()) { while (Find(pos,inSearch, pos, inTo, inInCase)) { count++; memcpy(&m_pszChar[pos], inReplace.m_pszChar, inReplace.GetLength()); memmove(&m_pszChar[pos+inReplace.GetLength()], &m_pszChar[pos+inSearch.GetLength()], GetLength()+1-(pos+inSearch.GetLength())); if (count==inTimes) break; pos += inReplace.GetLength(); } if (count>0) { temp = (char *) malloc(GetLength()+1-count*(inSearch.GetLength()-inReplace.GetLength())); memcpy(temp, m_pszChar,GetLength()+1-count*(inSearch.GetLength()-inReplace.GetLength())); free(m_pszChar); m_pszChar = temp; m_Length = GetLength()-count*(inSearch.GetLength()-inReplace.GetLength()); } } else // inSearch.GetLength() < inReplace.GetLength() { XSIZE_T *posptr, firstpos, lastpos; unsigned char nextNull=0, offsets=0; if (inSearch.GetLength()>=sizeof(XSIZE_T)) // ptrlist in string { while (Find(pos,inSearch, pos, inTo, inInCase)) { count++; if (count==1) firstpos = pos; else *posptr = pos; posptr = (XSIZE_T*) (&m_pszChar[pos]); if (count==inTimes) break; pos += inSearch.GetLength(); } } else { offsets = 1; while (Find(pos, inSearch, pos, inTo, inInCase)) { count++; if (count==1) firstpos=pos; if (count==inTimes) break; // 97-03-14: Fehler behoben: inTimes wurde hier ignoriert pos += inSearch.GetLength(); } } if (count>0) { XSIZE_T nextpos = 0; int i=0; lastpos = 0; pos = firstpos; temp = (char *) malloc(GetLength()+1+count*(inReplace.GetLength()-inSearch.GetLength())); while (i<count) { if (offsets) Find(nextpos, inSearch, pos+inSearch.GetLength(), inTo, inInCase); else nextpos = *( (XSIZE_T*) (m_pszChar+pos) ) ; if (i>0) { memcpy(&temp[inSearch.GetLength()+lastpos+(inReplace.GetLength()-inSearch.GetLength())*i ], &m_pszChar[lastpos+inSearch.GetLength()], pos-(lastpos+inSearch.GetLength())); // ...RRRxxxx... memcpy(&temp[inSearch.GetLength()+pos+(inReplace.GetLength()-inSearch.GetLength())*i -inSearch.GetLength()], inReplace.m_pszChar, inReplace.GetLength()+1); //...RRRxxxxRRR } else { memcpy(temp, m_pszChar, pos); memcpy(&temp[pos],inReplace.m_pszChar, inReplace.GetLength()+1); } lastpos = pos; pos = nextpos; i++; } memcpy(&temp[inSearch.GetLength()+lastpos+(inReplace.GetLength()-inSearch.GetLength())*i], /// RRRxxxxx &m_pszChar[lastpos+inSearch.GetLength()], GetLength()-(lastpos+inSearch.GetLength())+1); XSIZE_T A1, A2; A1 =inSearch.GetLength()+lastpos+(inReplace.GetLength()-inSearch.GetLength())*i+GetLength()-(lastpos+inSearch.GetLength()); A2 = GetLength()+count*(inReplace.GetLength()-inSearch.GetLength()); X_ASSERT(A1==A2); free(m_pszChar); m_pszChar = temp; m_Length = GetLength()+count*(inReplace.GetLength()-inSearch.GetLength()); } } return count; } void XString::MakeUpper() { m_isNULL = FALSE; X_ASSERT(m_pszChar != NULL); X_ASSERT(m_Length == strlen(m_pszChar)); strupr(m_pszChar); XSIZE_T pos; for (pos=0; pos<m_Length; pos++) if (m_pszChar[pos] == 'Σ') m_pszChar[pos] = '─'; for (pos=0; pos<m_Length; pos++) if (m_pszChar[pos] == '÷') m_pszChar[pos] = '╓'; for (pos=0; pos<m_Length; pos++) if (m_pszChar[pos] == 'ⁿ') m_pszChar[pos] = '▄'; Replace("▀", "SS"); } void XString::MakeLower() { m_isNULL = FALSE; X_ASSERT(m_pszChar != NULL); X_ASSERT(m_Length == strlen(m_pszChar)); strlwr(m_pszChar); XSIZE_T pos; for (pos=0; pos<m_Length; pos++) if (m_pszChar[pos] == '─') m_pszChar[pos] = 'Σ'; for (pos=0; pos<m_Length; pos++) if (m_pszChar[pos] == '╓') m_pszChar[pos] = '÷'; for (pos=0; pos<m_Length; pos++) if (m_pszChar[pos] == '▄') m_pszChar[pos] = 'ⁿ'; } const char __Xlow[ ] = "ΘΓΣαστΩδΦ∩ε∞─┼╔µ╞⌠÷≥√∙ ╓▄óúÑPâßφ≤·±"; const char __Xupp[ ] = "╔┬─└┼╟╩E╚I╬╠─┼╔╞╞╘╓╥█┘Y╓▄óúÑPâ┴═╙┌╤"; char XString::UpperChar(char inChar) { if (inChar<'a') return inChar; // Gro▀buchstaben und Steuerzeichen if (inChar>=165) return inChar; // Grafikzeichen if (inChar<='z') return inChar - 32; // a..z -> A--Z if (inChar<'ⁿ') return inChar; // {...╟ return __Xupp[inChar-'Θ']; } /***************************************************** FRIEND HELPERS: ********************************************************/ // FriendOperatoren: int operator ==(const XString &inS1, const XString &inS2) { X_ASSERT(inS1.m_pszChar!=NULL); X_ASSERT(inS2.m_pszChar!=NULL); return strcmp(inS1.m_pszChar, inS2.m_pszChar)==0; } int operator ==(const XString &inS1, const char *pszChar2) { X_ASSERT(inS1.m_pszChar!=NULL); X_ASSERT(pszChar2!=NULL); return strcmp(inS1.m_pszChar, pszChar2)==0; } int operator ==(const char *pszChar1, const XString &inS2) { X_ASSERT(pszChar1!=NULL); X_ASSERT(inS2.m_pszChar!=NULL); return strcmp(pszChar1, inS2.m_pszChar)==0; } int operator <(const XString &inS1, const XString &inS2) { X_ASSERT(inS1.m_pszChar!=NULL); X_ASSERT(inS2.m_pszChar!=NULL); return strcmp(inS1.m_pszChar, inS2.m_pszChar)<0; } int operator <(const XString &inS1,const char *pszChar2) { X_ASSERT(inS1.m_pszChar!=NULL); X_ASSERT(pszChar2!=NULL); return strcmp(inS1.m_pszChar, pszChar2)<0; } int operator <( const char *pszChar1, const XString &inS2) { X_ASSERT(pszChar1!=NULL); X_ASSERT(inS2.m_pszChar!=NULL); return strcmp(pszChar1, inS2.m_pszChar)<0; } int operator !=(const XString &inS1, const XString &inS2) { return !(inS1==inS2); } int operator !=(const XString &inS1, const char *pszChar2) { return !(inS1 == pszChar2); } int operator !=(const char *pszChar1, const XString &inS2) { return !(pszChar1 == inS2); } int operator >(const XString &inS1, const XString &inS2) { return (inS2 < inS1); } int operator >(const XString &inS1, const char *pszChar2) { return (pszChar2 < inS1); } int operator >( const char *pszChar1, const XString &inS2) { return (inS2 < pszChar1 ); } int operator <=(const XString &inS1, const XString &inS2) { return !(inS2<inS1); } int operator <=(const XString &inS1, const char *pszChar2) { return !(pszChar2 < inS1); } int operator <=(const char *pszChar1, const XString &inS2) { return !(inS2 < pszChar1); } int operator >=(const XString &inS1, const XString &inS2) { return !(inS1<inS2); } int operator >=(const XString &inS1, const char *pszChar2) { return !(inS1 < pszChar2); } int operator >=(const char *pszChar1, const XString &inS2) { return !(pszChar1 < inS2); } // Friend-Functionen: // TBO #ifndef __WATCOMC__ XString operator +(const XString Str1, const char *pszChar2) #else XString operator +(XString Str1, const char *pszChar2) #endif { X_ASSERT(Str1.m_pszChar!=NULL); X_ASSERT(pszChar2!=NULL); X_ASSERT(Str1.m_Length == strlen(Str1.m_pszChar)); XString Res; XSIZE_T C2Length=strlen(pszChar2); Res.m_Length = Str1.m_Length+C2Length; free(Res.m_pszChar); Res.m_pszChar = (char *) malloc(Res.m_Length+1); X_ASSERT(Res.m_pszChar != NULL); memcpy(Res.m_pszChar, Str1.m_pszChar, Str1.m_Length); memcpy(&Res.m_pszChar[Str1.m_Length], pszChar2, C2Length+1); X_ASSERT(Res.GetLength() == strlen(Res.m_pszChar)); return Res; } // TBO #ifndef __WATCOMC__ XString operator +(const char *pszChar1, const XString Str2) #else XString operator +(const char *pszChar1, XString Str2) #endif { X_ASSERT(Str2.m_pszChar!=NULL); X_ASSERT(pszChar1!=NULL); X_ASSERT(Str2.m_Length == strlen(Str2.m_pszChar)); XString Res; XSIZE_T C1Length = strlen(pszChar1); Res.m_Length = Str2.m_Length+C1Length; free(Res.m_pszChar); Res.m_pszChar = (char *) malloc(Res.m_Length+1); X_ASSERT(Res.m_pszChar != NULL); memcpy(Res.m_pszChar, pszChar1, C1Length); memcpy(&Res.m_pszChar[C1Length], Str2.m_pszChar, Str2.m_Length+1); X_ASSERT(Res.m_Length == strlen(Res.m_pszChar)); return Res; } // TBO #ifndef __WATCOMC__ XString operator +(const XString& Str1, const XString& Str2) #else XString operator +(XString& Str1, XString& Str2) #endif { X_ASSERT(Str2.m_pszChar!=NULL); X_ASSERT(Str1.m_pszChar!=NULL); X_ASSERT(Str1.m_Length == strlen(Str1.m_pszChar)); X_ASSERT(Str2.m_Length == strlen(Str2.m_pszChar)); XString Res; Res.m_Length = Str2.m_Length+Str1.m_Length; free(Res.m_pszChar); Res.m_pszChar = (char *) malloc(Res.m_Length+1); X_ASSERT(Res.m_pszChar != NULL); memcpy(Res.m_pszChar, Str1.m_pszChar, Str1.m_Length); memcpy(&Res.m_pszChar[Str1.m_Length], Str2.m_pszChar, Str2.m_Length+1); X_ASSERT(Res.GetLength() == strlen(Res.m_pszChar)); return Res; } /* Vereinfachung: x==y und x<y definiert, ansonsten: x!=y : !(x==y) x>y : y<x x<=y : !(y<x) x>=< : !(x<y) */ ///////////////////////////////////////////////// // streams: ostream& operator<<(ostream& outStream, const XString& outString) { return outStream << outString.m_pszChar; } istream& operator>>(istream& inStream, XString& inString) { char buf[100]; char c; while (inStream.get(c) && (c!= '\n')) { inString += c; inStream.get (buf, 100, '\n'); inString += buf; } return inStream; }