Files
CPP/common/string.cpp
2025-08-10 11:35:20 -04:00

706 lines
17 KiB
C++
Executable File

#include <stdio.h>
#include <ctype.h>
#include <common/string.hpp>
#include <common/block.hpp>
#include <common/array.hpp>
String::String(const char *npStr)
: mnpStr(0), mLengthBytes(0)
{
DWORD stringLength;
if(!npStr)return;
try{stringLength=::strlen(npStr);}
catch(...){{stringLength=0;}}
if(!stringLength)return;
stringLength++;
reserve(stringLength,FALSE);
::strcpy(mnpStr,npStr);
}
String::String(const wchar_t* npWideString, int length)
: mnpStr(0), mLengthBytes(0)
{
if (!npWideString || 0 == length)return;
reserve(length);
for (wchar_t index = 0;index < length;index++)
{
char character = (char)((npWideString[index]<<8)>>8);
operator[](index) = character;
}
}
String::String(const String &newString)
: mnpStr(0), mLengthBytes(0)
{
DWORD stringLength;
if(!newString.mnpStr)return;
if(!(stringLength=newString.length()))return;
stringLength++;
reserve(stringLength,FALSE);
::strcpy(mnpStr,newString.mnpStr);
}
String &String::operator=(const String &someString)
{
int stringLength;
if(this==&someString)return *this;
if(someString.isNull()){removeData();return *this;}
if(!(stringLength=::strlen(someString.mnpStr)))return *this;
stringLength++;
if(lengthBytes()>=stringLength)::strcpy(mnpStr,someString.mnpStr);
else {reserve(stringLength,FALSE);::strcpy(mnpStr,someString.mnpStr);}
return *this;
}
int String::operator=(const char *someCharStar)
{
int stringLength;
if(!someCharStar)return 0;
if(!(stringLength=::strlen(someCharStar)))return 0;
stringLength++;
if(lengthBytes()>=stringLength)::strcpy(mnpStr,someCharStar);
else {reserve(stringLength,FALSE);::strcpy(mnpStr,someCharStar);}
return 1;
}
void String::operator+=(char someChar)
{
DWORD strLength(length());
if(strLength+2>mLengthBytes)
{
String tmpString(someChar);
*this+=tmpString;
return;
}
*(mnpStr+strLength)=someChar;
*(mnpStr+strLength+1)=0;
}
int String::operator+=(const String &someString)
{
char *lpString;
DWORD currLength;
DWORD stringLength;
if(!someString.mnpStr)return 0;
stringLength=someString.length();
stringLength++;
if(!mnpStr)
{
reserve(stringLength,FALSE);
::strcpy(mnpStr,someString.mnpStr);
return 1;
}
currLength=::strlen(mnpStr);
if(lengthBytes()-currLength>=stringLength)
{
::strcat(mnpStr,someString.mnpStr);
return 1;
}
lpString=mnpStr;
mnpStr=::new char[currLength+stringLength+MaxString];
mLengthBytes=currLength+stringLength+MaxString;
::strcpy(mnpStr,lpString);
::strcpy(mnpStr+currLength,someString.mnpStr);
::delete[] lpString;
return 1;
}
int String::operator+=(const char *someStr)
{
char *lpString;
DWORD currLength;
DWORD stringLength;
if(!someStr)return 0;
stringLength=::strlen(someStr);
stringLength++;
if(!mnpStr)
{
reserve(stringLength,FALSE);
::strcpy(mnpStr,someStr);
return 1;
}
currLength=::strlen(mnpStr);
if(lengthBytes()-currLength>=stringLength)
{
::strcat(mnpStr,someStr);
return 1;
}
lpString=mnpStr;
mnpStr=::new char[currLength+stringLength+MaxString];
mLengthBytes=currLength+stringLength+MaxString;
::strcpy(mnpStr,lpString);
::strcpy(mnpStr+currLength,someStr);
::delete[] lpString;
return 1;
}
String String::operator+(const String &someString)const
{
String tmpString(*this);
tmpString+=someString;
return tmpString;
}
int String::token(const char *tokenString)
{
if(!tokenString||!mnpStr)return 0;
if(::strtok(mnpStr,tokenString))return 1;
return 0;
}
long String::strchr(char someChar)const
{
long pos;
if(!mnpStr)return -1;
pos=(long)::strchr(mnpStr,someChar);
if(!pos)return -1;
return pos-(long)mnpStr;
}
long String::strpos(const char *string)const
{
long stringPosition;
if(!mnpStr)return -1;
stringPosition=(long)::strstr(mnpStr,string);
if(!stringPosition)return -1;
return stringPosition-(long)mnpStr;
}
int String::strncmp(const char *string)const
{
int srcLength;
int dstLength;
if(!mnpStr)return -1;
srcLength=::strlen(string);
dstLength=::strlen(mnpStr);
return ::strncmp(mnpStr,string,srcLength<dstLength?srcLength:dstLength);
}
void String::upper(void)
{
char *string=mnpStr;
if(!mnpStr)return;
while(*string)
{
*string=::toupper(*string);
string++;
}
}
void String::lower(void)
{
char *string=mnpStr;
if(!mnpStr)return;
while(*string)
{
*string=::tolower(*string);
string++;
}
}
String String::betweenString(char beginToken,char endToken)const
{
char nullString[MaxString]={0};
short stringLength;
char *lpBegin;
char *lpEnd;
if(!mnpStr)return String(nullString);
stringLength=length();
if(1>=stringLength)return String(nullString);
if(beginToken)
{
if(0==(lpBegin=::strchr(mnpStr,beginToken)))return String(nullString);
if(++lpBegin-mnpStr>=stringLength)return String(nullString);
}
else lpBegin=mnpStr;
if(0==(lpEnd=::strchr(lpBegin,endToken)))return *this;
if(lpBegin==lpEnd)return String(nullString);
if(sizeof(nullString)<=(lpEnd-lpBegin)+1)
{
String nullString;
nullString.reserve((lpEnd-lpBegin)+1,FALSE);
::memcpy(nullString,lpBegin,lpEnd-lpBegin);
*((char*)nullString+(lpEnd-lpBegin))=0;
return nullString;
}
::memcpy(nullString,lpBegin,lpEnd-lpBegin);
*(nullString+(lpEnd-lpBegin))=0;
return String(nullString);
}
Block<String> String::split(char delimeter)const
{
Block<String> stringList = Block<String>();
String strDelimeter = String(delimeter);
String runningString = String(*this);
int position = runningString.strpos(strDelimeter);
while (-1 != position)
{
stringList.insert(new String(runningString.substr(0, position - 1)));
runningString = runningString.substr(position + 1);
position = runningString.strpos(strDelimeter);
}
if (runningString.length())stringList.insert(new String(runningString));
return stringList;
}
WORD String::makeBlock(Block<String> &receiveStrings,const String &tokenString)const
{
String stringData(*this);
String workString;
LONG stringPos;
LONG lengthToken;
receiveStrings.remove();
if(!(lengthToken=tokenString.length()))return FALSE;
if(stringData.isNull())return FALSE;
while(TRUE)
{
if(-1==(stringPos=stringData.strpos(tokenString)))
{
if(!stringData.isNull())receiveStrings.insert(&stringData);
return receiveStrings.size();
}
else if(stringData.length()!=stringPos+lengthToken)
{
if(stringPos)
{
workString=stringData.substr(0,stringPos-lengthToken);
receiveStrings.insert(&workString);
}
stringData=stringData.substr(stringPos+lengthToken,stringData.length());
}
else stringData.removeTokens(tokenString);
}
}
String String::extractDigits(void)const
{
String tempString;
String nullString;
char *lpClampOne;
char *lpClampTwo;
if(!mnpStr)return nullString;
tempString=mnpStr;
lpClampOne=(char*)tempString;
while(*lpClampOne&&!isdigit(*lpClampOne))lpClampOne++;
if(!*lpClampOne)return nullString;
lpClampTwo=lpClampOne;
while(*lpClampTwo&&isdigit(*lpClampTwo))lpClampTwo++;
*lpClampTwo=0;
return lpClampOne;
}
String String::extractAlpha(void)const
{
String tempString;
String nullString;
char *lpClampOne;
char *lpClampTwo;
if(!mnpStr)return nullString;
tempString=mnpStr;
lpClampOne=(char*)tempString;
while(*lpClampOne&&!isalpha(*lpClampOne))lpClampOne++;
if(!*lpClampOne)return nullString;
lpClampTwo=lpClampOne;
while(*lpClampTwo&&isalpha(*lpClampTwo))lpClampTwo++;
*lpClampTwo=0;
return lpClampOne;
}
int String::hex(void)const
{
String workString(*this);
DWORD stringLength;
DWORD multiplier(0x01);
DWORD value(0L);
char *ptrString;
if(workString.isNull())return FALSE;
if(workString.strstr(" "))workString.removeTokens(" ");
if(!(stringLength=workString.length()))return FALSE;
workString.upper();
if(0!=(ptrString=(char*)workString.strstr("0X")))
{
ptrString+=2;
stringLength=::strlen(ptrString);
ptrString+=(stringLength-1);
}
else if('H'==*((char*)workString+(stringLength-1)))
{
stringLength--;
ptrString=(char*)workString+(stringLength-1);
}
else ptrString=(char*)workString+(stringLength-1);
for(LONG stringIndex=stringLength-1;stringIndex>=0;stringIndex--)
{
switch(*(ptrString--))
{
case '0' : break;
case '1' : {value+=multiplier;break;}
case '2' : {value+=multiplier*2;break;}
case '3' : {value+=multiplier*3;break;}
case '4' : {value+=multiplier*4;break;}
case '5' : {value+=multiplier*5;break;}
case '6' : {value+=multiplier*6;break;}
case '7' : {value+=multiplier*7;break;}
case '8' : {value+=multiplier*8;break;}
case '9' : {value+=multiplier*9;break;}
case 'A' : {value+=multiplier*10;break;}
case 'B' : {value+=multiplier*11;break;}
case 'C' : {value+=multiplier*12;break;}
case 'D' : {value+=multiplier*13;break;}
case 'E' : {value+=multiplier*14;break;}
case 'F' : {value+=multiplier*15;break;}
case '-' : {value*=-1;break;}
default : return value;
}
multiplier*=16;
}
return value;
}
void String::spaceTerm(void)
{
size_t strLen;
if(isNull()||(0==(strLen=length())))return;
for(short index=0;index<strLen;index++)if(Blank==*(mnpStr+index)){*(mnpStr+index)=0;return;}
}
BOOL String::endsWidth(char ch)const
{
int strLength = length();
if(isNull()||strLength)return FALSE;
return ch == charAt(strLength-1);
}
String& String::trim(void)
{
String str = trimRight();
str=trimLeft();
*this = str;
return *this;
}
String &String::trimRight(void)
{
size_t strLen;
if(isNull()||(0==(strLen=length())))return *this;
for(short index=strLen-1;index>=0;index--)
{
char ch = mnpStr[index];
if (Blank == ch || CarriageReturn==ch || LineFeed==ch)mnpStr[index] = 0;
else break;
}
return *this;
}
String &String::trimLeft(void)
{
size_t strLen;
if(isNull()||(0==(strLen=length())))return *this;
short index=0;
for (index = 0;index < strLen;index++)
{
char ch = mnpStr[index];
if (Blank != ch && CarriageReturn != ch && LineFeed != ch)break;
}
if(!index)return *this;
*this=substr(index);
return *this;
}
void String::removeTokens(String someTokens)
{
int length(this->length());
int tokens(someTokens.length());
String tempString;
if(!length||!tokens)return;
for(int token=0;token<tokens;token++)
for (int pos = 0;pos < length;pos++)
{
if (*(mnpStr + pos) == *(someTokens.mnpStr + token))*(mnpStr + pos) = 0;
}
for(int pos=0;pos<length;pos++)
if((mnpStr+pos))tempString+=*(mnpStr+pos);
*this=tempString;
}
void String::replaceToken(BYTE tokenFind,BYTE tokenReplace)
{
int length(this->length());
String tempString;
if(!length)return;
int pos=0;
for(pos=0;pos<length;pos++)if(*(mnpStr+pos)==tokenFind)*(mnpStr+pos)=tokenReplace;
for(pos=0;pos<length;pos++){if((mnpStr+pos))tempString+=*(mnpStr+pos);}
*this=tempString;
}
void String::length(short newLength)
{
short currLength(length());
if(currLength==newLength)return;
if(currLength>newLength)
{
String tempString;
tempString.reserve(newLength+1);
::memcpy(tempString,*this,newLength);
*this=tempString;
}
else while(length()<newLength)*this+=" ";
}
void String::convert(double doubleValue,const char *formatString)
{
if(!formatString)return;
reserve(MaxString);
::sprintf(mnpStr,formatString,doubleValue);
return;
}
void String::convert(int integerValue,const char *formatString)
{
if(!formatString)return;
reserve(MaxString);
::sprintf(mnpStr,formatString,integerValue);
return;
}
void String::convert(long longValue,const char *formatString)
{
if(!formatString)return;
reserve(MaxString);
::sprintf(mnpStr,formatString,longValue);
return;
}
WORD String::remove(WORD removePosition)
{
WORD stringLength(length());
String tempString;
if(!mnpStr)return FALSE;
if(stringLength<=removePosition)return FALSE;
if(!removePosition&&1==stringLength){*(mnpStr)='\0';return TRUE;}
if(!removePosition){*this=(mnpStr+1);return TRUE;}
*(mnpStr+removePosition)=0;
tempString=mnpStr;
tempString+=String((mnpStr+removePosition+1));
*this=tempString;
return TRUE;
}
String String::substr(WORD startPosition,WORD endPosition)const
{
WORD stringLength(length());
String resultString;
if(!stringLength)return resultString;
if(startPosition>endPosition)return resultString;
if(endPosition>stringLength)endPosition=stringLength;
resultString.reserve(endPosition-startPosition+2);
::memcpy(resultString,mnpStr+startPosition,(endPosition-startPosition)+1);
return resultString;
}
WORD String::insert(const String &insertString,WORD insertPosition)
{
WORD insertLength(insertString.length());
if(!insertLength)return FALSE;
if(!mnpStr)
{
reserve(insertLength+insertPosition+1);
::memset(mnpStr,Blank,insertLength+insertPosition);
::memcpy(mnpStr+insertPosition,insertString,insertLength);
}
else
{
WORD currentLength(length());
String tempString;
if(insertLength+insertPosition>currentLength)
{
tempString.reserve(insertLength+insertPosition+currentLength+1);
::memset(tempString,Blank,insertLength+insertPosition+currentLength);
}
else
{
tempString.reserve(currentLength+insertLength+1);
::memset(tempString,Blank,currentLength+insertLength);
}
::memcpy(tempString,mnpStr,currentLength);
if(!(insertPosition>currentLength))shiftRight(tempString,insertPosition,currentLength+insertLength-1,insertLength,currentLength);
::memcpy(((char*)tempString)+insertPosition,insertString,insertLength);
*this=tempString;
}
return TRUE;
}
WORD String::insert(char *lpInsertString,WORD insertPosition)
{
WORD insertLength;
if(!lpInsertString||!(insertLength=::strlen(lpInsertString)))return FALSE;
if(!mnpStr)
{
reserve(insertLength+insertPosition+1);
::memset(mnpStr,Blank,insertLength+insertPosition);
::memcpy(mnpStr+insertPosition,lpInsertString,insertLength);
}
else
{
WORD currentLength(length());
String tempString;
if(insertLength+insertPosition>currentLength)
{
tempString.reserve(insertLength+insertPosition+currentLength+1);
::memset(tempString,Blank,insertLength+insertPosition+currentLength);
}
else
{
tempString.reserve(currentLength+insertLength+1);
::memset(tempString,Blank,currentLength+insertLength);
}
::memcpy(tempString,mnpStr,currentLength);
if(!(insertPosition>currentLength))shiftRight(tempString,insertPosition,currentLength+insertLength-1,insertLength,currentLength);
::memcpy(((char*)tempString)+insertPosition,lpInsertString,insertLength);
*this=tempString;
}
return TRUE;
}
void String::shiftRight(String &shiftString,WORD startPos,WORD endPos,WORD insertLength,WORD originalLength)
{
WORD shiftLength(originalLength-startPos);
for(WORD shiftIndex=0;shiftIndex<shiftLength;shiftIndex++,endPos--)
*((char*)shiftString+endPos)=*((char*)shiftString+endPos-insertLength);
}
int String::toInt(void)const
{
if(isNull())return 0;
return ::atoi(str());
}
short String::toShort(void)const
{
if(isNull())return 0;
return short(::atoi(str()));
}
unsigned short String::toUShort(void)const
{
if (isNull())return 0;
return (unsigned short)(::atoi(str()));
}
float String::toFloat(void)const
{
if(isNull())return 0.00;
return ::atof(str());
}
double String::toDouble(void)const
{
if(isNull())return 0.00;
return ::atof(str());
}
long String::toLong(void)const
{
if(isNull())return 0;
return ::atol(str());
}
unsigned long String::toULong(void)const
{
if(isNull())return 0;
return (unsigned long)::atol(str());
}
String &String::fromInt(int value)
{
reserve(MaxString);
::sprintf(mnpStr,"%d",value);
return *this;
}
String &String::fromShort(short value)
{
reserve(MaxString);
::sprintf(mnpStr,"%d",value);
return *this;
}
String &String::fromUShort(unsigned short value)
{
reserve(MaxString);
::sprintf(mnpStr,"%d",value);
return *this;
}
String &String::fromFloat(float value)
{
reserve(MaxString);
::sprintf(mnpStr,"%9.2lf",value);
return *this;
}
String &String::fromDouble(double value)
{
reserve(MaxString);
::sprintf(mnpStr,"%9.2lf",value);
return *this;
}
String &String::fromLong(long value)
{
reserve(MaxString);
::sprintf(mnpStr,"%ld",value);
return *this;
}
String &String::fromULong(unsigned long value)
{
reserve(MaxString);
::sprintf(mnpStr,"%lu",value);
return *this;
}
String &String::fromBool(bool boolValue)
{
*this=boolValue?"T":"F";
return *this;
}
// non-member
String operator+(const char *str,const String &string)
{
return String(str)+string;
}