home *** CD-ROM | disk | FTP | other *** search
- /* -------------------------------------------------------------------- */
- /* String++ Version 3.00 04/10/93 */
- /* */
- /* Enhanced string class for Turbo C++/Borland C++. */
- /* Copyright 1991-1993 by Carl W. Moreland */
- /* */
- /* str.cpp */
- /* -------------------------------------------------------------------- */
-
- #include <ctype.h>
- #include <stdio.h>
- #include <stdlib.h>
-
- #ifdef BCCL
- #include "strng.h"
- #else
- #include "str.h"
- #endif
-
- const String STR_NULL = "";
- const String& Str = STR_NULL;
- const String& StrNull = STR_NULL;
-
- unsigned String::strMinLength = 16;
- unsigned String::strIncLength = 8;
- String* String::findIn = 0;
- String& String::findStr = (String&)StrNull;
- unsigned String::findPos = 0;
- String String::fpFormat("%0.4f");
-
- /* ----- Constructors/Destructors ------------------------------------- */
-
- String::String()
- {
- strPtr = 0;
- strLen = 0;
- bufferLen = 0;
- }
-
- String::String(const char c, const unsigned n)
- {
- strPtr = 0;
- strLen = 0;
- bufferLen = 0;
- SetStr(c, n);
- }
-
- String::String(const char* p)
- {
- strPtr = 0;
- strLen = 0;
- bufferLen = 0;
- SetStr(p);
- }
-
- String::String(const char* p, const unsigned pos, const unsigned len)
- {
- strPtr = 0;
- strLen = 0;
- bufferLen = 0;
- SetStr(p, pos, len);
- }
-
- String::String(const String& s)
- {
- strPtr = 0;
- strLen = 0;
- bufferLen = 0;
- SetStr(s);
- }
-
- String::String(const String& s, const unsigned pos, const unsigned len)
- {
- strPtr = 0;
- strLen = 0;
- bufferLen = 0;
- SetStr(s, pos, len);
- }
-
- String::String(const int n)
- {
- strPtr = 0;
- strLen = 0;
- bufferLen = 0;
- ltos((long)n);
- }
-
- String::String(const long n)
- {
- strPtr = 0;
- strLen = 0;
- bufferLen = 0;
- ltos(n);
- }
-
- String::String(const float n, const char* format)
- {
- strPtr = 0;
- strLen = 0;
- bufferLen = 0;
- dtos((double)n, format);
- }
-
- String::String(const double n, const char* format)
- {
- strPtr = 0;
- strLen = 0;
- bufferLen = 0;
- dtos(n, format);
- }
-
- String::~String(void)
- {
- if(strPtr)
- delete strPtr;
- }
-
- /* ----- SetStr/AddStr ------------------------------------------------ */
-
- void String::SetStr(const char c, const unsigned n)
- {
- int i;
- strLen = n;
-
- if(bufferLen > strLen) // if the buffer is large enough...
- {
- for(i=0; i<strLen; i++)
- strPtr[i] = c; // copy n chars
- }
- else // else create a new buffer
- {
- if(strPtr)
- delete strPtr;
-
- strPtr = new char[GetSize(strLen)]; // allocate the memory
-
- for(i=0; i<strLen; i++)
- strPtr[i] = c; // copy n chars
- }
- strPtr[strLen] = 0; // add NULL termination
- }
-
- void String::SetStr(const char* p)
- {
- strLen = strlen(p);
-
- if(bufferLen > strLen) // if the buffer is large enough...
- memcpy(strPtr, p, strLen); // copy the String
- else // else create a new buffer
- {
- char* tmp = new char[GetSize(strLen)];
- memcpy(tmp, p, strLen); // copy the String
-
- if(strPtr)
- delete strPtr;
- strPtr = tmp; // now make strPtr = tmp
- }
- strPtr[strLen] = 0; // add NULL termination
- }
-
- void String::SetStr(const char* p, const unsigned pos, const unsigned len)
- {
- int p_len = strlen(p);
-
- if(pos > p_len) // error check the start pos
- return;
-
- strLen = p_len - pos;
- if(len < strLen) // error check the copy length
- strLen = len;
-
- if(bufferLen > strLen) // if the buffer is large enough...
- memcpy(strPtr, p+pos, strLen); // copy the substring
- else // else create a new buffer
- {
- char* tmp = new char[GetSize(strLen)];
- memcpy(tmp, p+pos, strLen); // copy the substring
-
- if(strPtr)
- delete strPtr;
- strPtr = tmp; // now make strPtr = tmp
- }
- strPtr[strLen] = 0; // add NULL termination
- }
-
- void String::SetStr(const String& s)
- {
- strLen = s.strLen;
-
- if(bufferLen > strLen) // if the buffer is large enough...
- memcpy(strPtr, s.strPtr, strLen); // copy the String
- else // else create a new buffer
- {
- char* tmp = new char[GetSize(strLen)];
- memcpy(tmp, s.strPtr, strLen); // copy the String
-
- if(strPtr)
- delete strPtr;
- strPtr = tmp; // now make strPtr = tmp
- }
- strPtr[strLen] = 0; // add NULL termination
- }
-
- void String::SetStr(const String& s, const unsigned pos, const unsigned len)
- {
- if(pos > s.strLen) // error check the start pos
- return;
-
- strLen = s.strLen - pos;
- if(len < strLen) // error check the copy length
- strLen = len;
-
- if(bufferLen > strLen) // if the buffer is large enough...
- memcpy(strPtr, s.strPtr+pos, strLen); // copy the substring
- else // else create a new buffer
- {
- char* tmp = new char[GetSize(len)]; // allocate new memory
- memcpy(tmp, s.strPtr+pos, len); // copy the subString
-
- if(strPtr)
- delete strPtr;
- strPtr = tmp; // now make strPtr = tmp
- }
- strPtr[strLen] = 0; // add NULL termination
- }
-
- void String::AddStr(const char c)
- {
- strLen += 1;
-
- if(bufferLen > strLen) // if the buffer is large enough...
- strPtr[strLen-1] = c; // append character c
- else // else create a new buffer
- {
- char* tmp = new char[GetSize(strLen)];
- memcpy(tmp, strPtr, strLen-1); // copy the original String
- tmp[strLen-1] = c; // append character c
-
- if(strPtr)
- delete strPtr;
- strPtr = tmp; // now make strPtr = tmp
- }
- strPtr[strLen] = 0; // add NULL termination
- }
-
- void String::AddStr(const char* p)
- {
- unsigned s_len = strlen(p);
-
- if(bufferLen > strLen+s_len) // if the buffer is large enough...
- memcpy(strPtr+strLen, p, s_len); // append String p
- else // else create a new buffer
- {
- char* tmp = new char[GetSize(strLen+s_len)];
- memcpy(tmp, strPtr, strLen); // copy the original String
- memcpy(tmp+strLen, p, s_len); // append String p
-
- if(strPtr)
- delete strPtr;
- strPtr = tmp; // now make strPtr = tmp
- }
- strLen += s_len;
- strPtr[strLen] = 0; // add NULL termination
- }
-
- void String::AddStr(const String& s)
- {
- if(bufferLen > strLen + s.strLen) // if the buffer is large enough...
- memcpy(strPtr+strLen, s.strPtr, s.strLen); // append String s
- else // else create a new buffer
- {
- char* tmp = new char[GetSize(strLen+s.strLen)];
- memcpy(tmp, strPtr, strLen); // copy the original String
- memcpy(tmp+strLen, s.strPtr, s.strLen); // append String s
-
- if(strPtr)
- delete strPtr;
- strPtr = tmp; // now make strPtr = tmp
- }
- strLen += s.strLen;
- strPtr[strLen] = 0; // add NULL termination
- }
-
- void String::ltos(const long n)
- {
- char num[15];
- ltoa(n, num, 10);
-
- SetStr(num);
- }
-
- void String::dtos(const double n, const char* format)
- {
- char num[40];
-
- if(format[0] != 0 && fpFormat != format)
- fpFormat = format;
-
- sprintf(num, fpFormat, n);
-
- SetStr(num);
- }
-
- unsigned String::GetSize(unsigned n)
- {
- bufferLen = strMinLength; // start with strMinLength
-
- if(n > bufferLen)
- {
- while(n > bufferLen)
- bufferLen += strIncLength; // incrementally add strIncLength
- }
- bufferLen++; // add one for NULL termination
-
- return bufferLen;
- }
-
- unsigned String::SetSize(unsigned len)
- {
- if(len < strLen)
- return 0;
-
- bufferLen = len + 1;
- char *tmp = new char[bufferLen];
-
- memcpy(tmp, strPtr, strLen); // copy the original String
- tmp[strLen] = 0; // add NULL termination
-
- if(strPtr) // now make strPtr = tmp
- delete strPtr;
- strPtr = tmp;
-
- return bufferLen-1;
- }
-
- void String::Minimize(void)
- {
- if(strLen < bufferLen-1)
- SetSize(strLen);
- }
-
- void String::SetFloatFormat(const char* format) const
- {
- if(format[0] != 0)
- fpFormat = format;
- }
-
- /* -------------------------------------------------------------------- */
-
- String& String::Right(unsigned len)
- {
- SetStr(strPtr, strLen-len, len);
- return *this;
- }
-
- String& String::Left(unsigned len)
- {
- SetStr(strPtr, 0, len);
- return *this;
- }
-
- String& String::Mid(unsigned pos, unsigned len)
- {
- SetStr(strPtr, pos, len);
- return *this;
- }
-
- String& String::Justify(char type, unsigned len, char mode)
- {
- if(mode&TRIM)
- Trim(); // delete outter whitespace
-
- if(strLen >= len && !(mode&CLIP)) // check for out-of-bounds
- return *this;
-
- if(strLen > len && (mode&CLIP)) // check for clipping
- {
- if(type == LEFT)
- Left(len);
- else if(type == CENTER)
- Mid((strLen-len)/2, len);
- else if(type == RIGHT)
- Right(len);
-
- return *this; // return clipped String
- }
-
- if(type == LEFT)
- *this = *this + String(' ', len-strLen);
- else if(type == CENTER)
- *this = String(' ', (len-strLen)/2) + *this +
- String(' ', len - (len+strLen)/2);
- else if(type == RIGHT)
- *this = String(' ', len-strLen) + *this;
-
- strLen = strlen(strPtr);
- return *this; // return normal String
- }
-
- String& String::toUpper(void)
- {
- for(int i=0; i<strlen(strPtr); i++)
- strPtr[i] = ::toupper(strPtr[i]);
- return *this;
- }
-
- String& String::toLower(void)
- {
- for(int i=0; i<strlen(strPtr); i++)
- strPtr[i] = ::tolower(strPtr[i]);
- return *this;
- }
-
- int& String::Value(int& n) const
- {
- n = atoi(strPtr);
- return n;
- }
-
- long& String::Value(long& n) const
- {
- n = atol(strPtr);
- return n;
- }
-
- float& String::Value(float& n) const
- {
- n = (float)atof(strPtr);
- return n;
- }
-
- double& String::Value(double& n) const
- {
- n = atof(strPtr);
- return n;
- }
-
- String& String::Insert(unsigned pos, const String& s)
- {
- if(pos > strLen)
- return *this;
-
- if(bufferLen > strLen + s.strLen)
- {
- memmove(strPtr+pos+s.strLen, strPtr+pos, strLen-pos);
- memcpy(strPtr+pos, s.strPtr, s.strLen);
- }
- else
- {
- GetSize(strLen + s.strLen);
- char* tmp = new char[bufferLen];
-
- memcpy(tmp, strPtr, pos);
- memcpy(tmp+pos, s.strPtr, s.strLen);
- memcpy(tmp+pos+s.strLen, strPtr+pos, strLen-pos);
-
- delete strPtr;
- strPtr = tmp;
- }
- strLen += s.strLen;
- strPtr[strLen] = 0;
-
- return *this;
- }
-
- String& String::Delete(unsigned pos, unsigned len)
- {
- if(pos >= strLen)
- return *this;
- if(len > strLen - pos)
- len = strLen - pos;
- if(len == 0)
- len = strLen - pos;
-
- strLen -= len;
- memmove(strPtr+pos, strPtr+pos+len, strLen-pos);
- strPtr[strLen] = 0;
-
- return *this;
- }
-
- String& String::Replace(unsigned pos, unsigned len, const String& to)
- {
- Delete(pos, len);
- Insert(pos, to);
-
- return *this;
- }
-
- char* String::Copy(char*& p) const
- {
- p = new char[strLen + 1];
- memcpy(p, strPtr, strLen);
-
- return p;
- }
-
- String& String::Trim(int mode, char c)
- {
- int begin = 0;
- int end = strLen-1;
-
- if(c == WHITESPACE) // if we're deleting whitespaces...
- {
- if(mode == LEFT || mode == CENTER) // delete leading whitespace
- {
- while(isspace(strPtr[begin]) && begin <= end)
- begin++;
- }
-
- if(mode == RIGHT || mode == CENTER) // delete trailing whitespace
- {
- while(isspace(strPtr[end]) && end >= begin)
- end--;
- }
- }
- else // else a character was specified
- {
- if(mode == LEFT || mode == CENTER) // delete leading characters
- {
- while(strPtr[begin] == c && begin <= end)
- begin++;
- }
-
- if(mode == RIGHT || mode == CENTER) // delete trailing characters
- {
- while(strPtr[end] == c && end >= begin)
- end--;
- }
- }
-
- SetStr(strPtr, begin, end-begin+1);
- return *this;
- }
-
- /* ----- Find methods ------------------------------------------------- */
-
- int String::FindFirst(const String& s) const
- {
- char* tmp;
-
- if((tmp = strstr(strPtr, s.strPtr)) != NULL)
- {
- findIn = (String*)this;
- findStr = s;
- findPos = (int)(tmp-strPtr);
- }
- else
- {
- findStr = 0;
- findPos = -1;
- }
-
- return findPos;
- }
-
- int String::FindNext(void) const
- {
- char* tmp;
-
- if(findIn != this) // wrong string
- return -1;
-
- if((tmp = strstr(strPtr+findPos+1, findStr.strPtr)) != NULL)
- findPos += (int)(tmp-(strPtr+findPos));
- else
- {
- findStr = 0;
- findPos = -1;
- }
-
- return findPos;
- }
-
- int String::FindPrev(void) const
- {
- if(findIn != this) // wrong string
- return -1;
-
- for(int i = findPos-findStr.strLen; i >= 0; i--)
- {
- if(memcmp(strPtr+i, findStr.strPtr, findStr.strLen) == 0)
- {
- findPos = i;
- return findPos;
- }
- }
- findPos = -1;
- return findPos;
- }
-
- int String::FindLast(const String& s) const
- {
- for(int i = strLen-s.strLen; i > 0; i--)
- {
- if(memcmp(strPtr+i, s.strPtr, s.strLen) == 0)
- {
- findIn = (String*)this;
- findStr = s;
- findPos = i;
- return findPos;
- }
- }
- findIn = 0;
- findPos = -1;
- return findPos;
- }
-
- /* ----- Operators ---------------------------------------------------- */
-
- String String::operator()(unsigned pos, unsigned len) const
- {
- String tmp(strPtr, pos, len);
- return tmp;
- }
-
- String& String::operator=(const char c)
- {
- SetStr(c);
- return *this;
- }
-
- String& String::operator=(const char* p)
- {
- SetStr(p);
- return *this;
- }
-
- String& String::operator=(const String& s)
- {
- SetStr(s);
- return *this;
- }
-
- String& String::operator=(const long n)
- {
- ltos(n);
- return *this;
- }
-
- String& String::operator=(const double n)
- {
- dtos(n, "");
- return *this;
- }
-
- String& String::operator+=(const char c)
- {
- AddStr(c);
- return *this;
- }
-
- String& String::operator+=(const char* p)
- {
- AddStr(p);
- return *this;
- }
-
- String& String::operator+=(const String& s)
- {
- AddStr(s);
- return *this;
- }
-
- String operator+(const String& s, const char* p)
- {
- String tmp(s);
- tmp.AddStr(p);
- return tmp;
- }
-
- String operator+(const char* p, const String& s)
- {
- String tmp(p);
- tmp.AddStr(s);
- return tmp;
- }
-
- String operator+(const String& s1, const String& s2)
- {
- String tmp(s1);
- tmp.AddStr(s2);
- return tmp;
- }
-
- String operator*(const String& s1, const unsigned n)
- {
- String tmp(s1);
-
- for(int i=1; i<n; i++)
- tmp += s1;
- return tmp;
- }
-
- String operator*(const unsigned n, const String& s1)
- {
- String tmp(s1);
-
- for(int i=1; i<n; i++)
- tmp += s1;
- return tmp;
- }
-
- String& String::operator*=(const unsigned n)
- {
- unsigned nlen = n*strLen;
-
- if(bufferLen > nlen)
- {
- for(int i=0; i<n; i++)
- memcpy(strPtr+i*strLen, strPtr, strLen);
- strPtr[nlen] = 0;
- }
- else
- {
- char *tmp = new char[nlen + 1];
-
- for(int i=0; i<n; i++)
- memcpy(tmp+i*strLen, strPtr, strLen);
- tmp[nlen] = 0;
-
- SetStr(tmp);
- }
- return *this;
- }
-
- char& String::operator[](const unsigned n) const
- {
- if(n > strLen)
- return *(strPtr + strLen);
- return *(strPtr + n);
- }
-
- String& String::operator<<(const char c)
- {
- AddStr(c);
- return *this;
- }
-
- String& String::operator<<(const char* p)
- {
- AddStr(p);
- return *this;
- }
-
- String& String::operator<<(const String& s)
- {
- AddStr(s);
- return *this;
- }
-
- String& String::operator<<(const long n)
- {
- char num[15];
- ltoa(n, num, 10);
- AddStr(num);
-
- return *this;
- };
-
- String& String::operator<<(const double n)
- {
- String tmp(n);
- AddStr(tmp);
- return *this;
- };
-
- /* -------------------------------------------------------------------- */
- /* AWK-style functions */
- /* -------------------------------------------------------------------- */
-
- int index(const String& s, const String& t)
- {
- int pos;
- char *tmp;
-
- if((tmp = strstr(s, t)) != NULL)
- pos = (int)(tmp-(const)s());
- else
- pos = -1;
-
- return pos;
- }
-
- String substr(const String& s, unsigned pos, unsigned len)
- {
- String tmp(s, pos, len);
- return tmp;
- }
-
- int split(const String& s, String*& array, const String& fs)
- {
- int i=0, j=1, start=0;
- String *tmp;
-
- while(i < s.Len()) // find the number of substrings
- {
- if(memcmp(s(i), fs(), fs.Len()) == 0)
- j++;
- i++;
- }
- tmp = new String[j]; // allocate the array of strings
- i = 0;
- j = 0;
-
- while(i < s.Len()) // fill in the array
- {
- if(memcmp(s(i), fs(), fs.Len()) == 0)
- {
- tmp[j++] = mid(s, start, i-start);
- i += fs.Len();
- start = i;
- }
- else
- i++;
- }
- tmp[j++] = mid(s, start, i-start);
-
- array = tmp;
- return j;
- }
-
- int gsub(const String& from, const String& to, String& s, unsigned count)
- {
- int i=0, j=0;
-
- while(i <= s.Len() - from.Len())
- {
- if(memcmp(s(i), from(), from.Len()) == 0)
- {
- s = left(s, i) + to + right(s, s.Len()-i-from.Len());
- i += to.Len();
- if(++j == count)
- break;
- }
- else
- i++;
- }
- return j;
- }
-
- /* -------------------------------------------------------------------- */
- /* C-style functions */
- /* -------------------------------------------------------------------- */
-
- String toupper(const String& s)
- {
- String tmp(s);
- tmp.toUpper();
- return tmp;
- }
-
- String tolower(const String& s)
- {
- String tmp(s);
- tmp.toLower();
- return tmp;
- }
-
- String left(const String& s, unsigned len)
- {
- String tmp(s, 0, len);
- return tmp;
- }
-
- String right(const String& s, unsigned len)
- {
- String tmp(s, s.Len()-len, len);
- return tmp;
- }
-
- String mid(const String& s, unsigned pos, unsigned len)
- {
- String tmp(s, pos, len);
- return tmp;
- }
-
- String justify(const String& s, char type, unsigned len, char mode)
- {
- String tmp(s);
- tmp.Justify(type, len, mode);
- return tmp;
- }
-
- String trim(const String& s, int mode)
- {
- String tmp(s);
- tmp.Trim(mode);
- return tmp;
- }
-
- /* ----- Stream I/O --------------------------------------------------- */
-
- ostream& operator<<(ostream& strm, const String& s)
- {
- return strm << s();
- }
-
- istream& operator>>(istream& strm, String& s)
- {
- char p[256];
-
- strm >> p;
- s = p;
-
- return strm;
- }
-