home *** CD-ROM | disk | FTP | other *** search
/ OS/2 Shareware BBS: 10 Tools / 10-Tools.zip / CTECHAPP.ZIP / STRINGS.ZIP / STR.CPP next >
C/C++ Source or Header  |  1990-03-25  |  8KB  |  440 lines

  1. //  Module:     Str  (Dynamic Strings)
  2. //  Version:    3.10
  3. //
  4. //  Language:   C++ 2.0
  5. //  Environ:    Any
  6. //
  7. //  Purpose:    Provides a general dynamic string class.
  8. //
  9. //  Written by: Scott Robert Ladd
  10.  
  11. #include "Str.hpp"
  12.  
  13. extern "C"
  14.     {
  15.     #include "string.h"
  16.     #include "stdio.h"
  17.     #include "stdlib.h"
  18.     #include "ctype.h"
  19.     #include "limits.h"
  20.     }
  21.  
  22. // prototype for default error handler
  23. static void DefaultHandler(StrError err);
  24.  
  25. // class-global constant intialization
  26. unsigned int String::AllocIncr = 8;
  27. void (*(String::ErrorHandler))(StrError) = DefaultHandler;
  28.  
  29. // default exception handler
  30. static void DefaultHandler(StrError err)
  31.     {
  32.     printf("\aERROR in String object: ");
  33.  
  34.     switch (err)
  35.         {
  36.         case SE_ALLOC :
  37.             printf("memory allocation failure");
  38.             break;
  39.         case SE_TOO_LONG :
  40.             printf("exceeded %d character limit",UINT_MAX);
  41.         }
  42.  
  43.     printf("\n");
  44.  
  45.     exit(1);
  46.     }
  47.  
  48. // private function to shrink the size of an allocated string
  49. void String::Shrink()
  50.     {
  51.     char * temp;
  52.  
  53.     if ((Siz - Len) > AllocIncr)
  54.         {
  55.         Siz  = ((Len + AllocIncr) / AllocIncr) * AllocIncr;
  56.  
  57.         temp = new char [Siz];
  58.  
  59.         if (temp != NULL)
  60.             {
  61.             strcpy(temp,Txt);
  62.             delete Txt;
  63.             Txt  = temp;
  64.             }
  65.         else
  66.             ErrorHandler(SE_ALLOC);
  67.         }
  68.     }
  69.  
  70. // constructor
  71. String::String()
  72.     {
  73.     Len = 0;
  74.     Siz = AllocIncr;
  75.  
  76.     Txt = new char[Siz];
  77.  
  78.     if (Txt == NULL)
  79.         ErrorHandler(SE_ALLOC);
  80.  
  81.     Txt[0] = '\x00';
  82.     }
  83.  
  84. String::String(const String & str)
  85.     {
  86.     Len = str.Len;
  87.     Siz = str.Siz;
  88.  
  89.     Txt = new char[Siz];
  90.  
  91.     if (Txt == NULL)
  92.         ErrorHandler(SE_ALLOC);
  93.  
  94.     strcpy(Txt,str.Txt);
  95.     }
  96.  
  97. String::String(const char * cstr)
  98.     {
  99.     if ((cstr == NULL) || (cstr[0] == '\x00'))
  100.         {
  101.         Len = 0;
  102.         Siz = AllocIncr;
  103.         }
  104.     else
  105.         {
  106.         Len = strlen(cstr);
  107.         Siz = ((Len + AllocIncr) / AllocIncr) * AllocIncr;
  108.         }
  109.  
  110.     Txt = new char [Siz];
  111.  
  112.     if (Txt == NULL)
  113.         ErrorHandler(SE_ALLOC);
  114.  
  115.     if (Len > 0)
  116.         strcpy(Txt,cstr);
  117.     else
  118.         Txt[0] = '\x00';
  119.     }
  120.  
  121. String::String(char fillCh, unsigned int count)
  122.     {
  123.     Siz = ((count + AllocIncr) / AllocIncr) * AllocIncr;
  124.     Len = Siz;
  125.  
  126.     Txt = new char[Siz];
  127.  
  128.     if (Txt == NULL)
  129.         ErrorHandler(SE_ALLOC);
  130.  
  131.     memset(Txt,fillCh,count);
  132.  
  133.     Txt[count] = '\x00';
  134.     }
  135.  
  136. // destructor
  137. String::~String()
  138.     {
  139.     delete Txt;
  140.     }
  141.  
  142. // Assign an exception handler
  143. void String::SetErrorHandler(void (* userHandler)(StrError))
  144.     {
  145.     ErrorHandler = userHandler;
  146.     }
  147.  
  148. // create a c-string from String method
  149. String::operator const char * ()
  150.     {
  151.     return Txt;
  152.     }
  153.  
  154. // assignment method
  155. void String::operator = (const String & str)
  156.     {
  157.     Len = str.Len;
  158.     Siz = str.Siz;
  159.  
  160.     delete Txt;
  161.  
  162.     Txt = new char[Siz];
  163.  
  164.     if (Txt == NULL)
  165.         ErrorHandler(SE_ALLOC);
  166.  
  167.     strcpy(Txt,str.Txt);
  168.     }
  169.  
  170. // concatenation methods
  171. String operator + (const String & str1, const String & str2)
  172.     {
  173.     unsigned long totalLen;
  174.     unsigned int newLen, newSiz;
  175.     String tempStr;
  176.     char * temp;
  177.  
  178.     totalLen = str1.Len + str2.Len;
  179.  
  180.     if (totalLen > UINT_MAX)
  181.         String::ErrorHandler(SE_TOO_LONG);
  182.  
  183.     newLen  = (unsigned int)totalLen;
  184.  
  185.     newSiz  = str1.Siz + str2.Siz;
  186.  
  187.     temp = new char[newSiz];
  188.  
  189.     if (temp == NULL)
  190.         String::ErrorHandler(SE_ALLOC);
  191.  
  192.     strcpy(temp,str1.Txt);
  193.  
  194.     strcpy(&temp[str1.Len],str2.Txt);
  195.  
  196.     tempStr = temp;
  197.  
  198.     return tempStr;
  199.     }
  200.  
  201. void String::operator += (const String & str)
  202.     {
  203.     unsigned long totalLen;
  204.     unsigned int newLen, newSiz;
  205.     char * temp;
  206.  
  207.     totalLen = str.Len + Len;
  208.  
  209.     if (totalLen > UINT_MAX)
  210.         ErrorHandler(SE_TOO_LONG);
  211.  
  212.     newLen  = (unsigned int)totalLen;
  213.     newSiz  = Siz + str.Siz;
  214.  
  215.     temp = new char[newSiz];
  216.  
  217.     if (temp == NULL)
  218.         ErrorHandler(SE_ALLOC);
  219.  
  220.     strcpy(temp,Txt);
  221.  
  222.     delete Txt;
  223.  
  224.     Txt = temp;
  225.  
  226.     strcpy(&Txt[Len],str.Txt);
  227.  
  228.     Len = newLen;
  229.     Siz = newSiz;
  230.  
  231.     Shrink();
  232.     }
  233.  
  234. StrCompVal String::Compare(const String & str, StrCompMode caseChk)
  235.     {
  236.     char * tempStr1, * tempStr2;
  237.     StrCompVal compVal;
  238.  
  239.     tempStr1 = strdup(Txt);
  240.  
  241.     if (tempStr1 == NULL)
  242.         ErrorHandler(SE_ALLOC);
  243.  
  244.     tempStr2 = strdup(str.Txt);
  245.  
  246.     if (tempStr2 == NULL)
  247.         ErrorHandler(SE_ALLOC);
  248.  
  249.     if (caseChk == SM_IGNORE)
  250.         {
  251.         strupr(tempStr1);
  252.         strupr(tempStr2);
  253.         }
  254.  
  255.     switch (strcmp(tempStr1,tempStr2))
  256.         {
  257.         case -1:
  258.             compVal = SC_LESS;
  259.             break;
  260.         case 0:
  261.             compVal = SC_EQUAL;
  262.             break;
  263.         case 1:
  264.             compVal = SC_GREATER;
  265.             break;
  266.         default:
  267.             compVal = SC_ERROR;
  268.         }
  269.  
  270.     delete tempStr1;
  271.     delete tempStr2;
  272.  
  273.     return compVal;
  274.     }
  275.  
  276. // substring search methods
  277. int String::Find(const String & str, unsigned int & pos, StrCompMode caseChk)
  278.     {
  279.     char * tempStr1, * tempStr2;
  280.     unsigned int lastPos, searchLen, tempPos;
  281.     int found;
  282.  
  283.     tempStr1 = strdup(Txt);
  284.  
  285.     if (tempStr1 == NULL)
  286.         ErrorHandler(SE_ALLOC);
  287.  
  288.     tempStr2 = strdup(str.Txt);
  289.  
  290.     if (tempStr2 == NULL)
  291.         ErrorHandler(SE_ALLOC);
  292.  
  293.     if (caseChk == SM_IGNORE)
  294.         {
  295.         strupr(tempStr1);
  296.         strupr(tempStr2);
  297.         }
  298.  
  299.     pos     = 0;
  300.     tempPos = 0;
  301.     found   = 0;
  302.  
  303.     searchLen = str.Len;
  304.     lastPos   = Len - searchLen;
  305.  
  306.     while ((tempPos <= lastPos) && !found)
  307.         {
  308.         if (0 == strncmp(&tempStr1[tempPos],tempStr2,searchLen))
  309.             {
  310.             pos   = tempPos;
  311.             found = 1;
  312.             }
  313.         else
  314.             ++tempPos;
  315.         }
  316.  
  317.     delete tempStr1;
  318.     delete tempStr2;
  319.  
  320.     return found;
  321.     }
  322.  
  323. // substring deletion method
  324. void String::Delete(unsigned int pos, unsigned int count)
  325.     {
  326.     unsigned int copyPos;
  327.  
  328.     if (pos > Len)
  329.         return;
  330.  
  331.     copyPos = pos + count;
  332.  
  333.     if (copyPos >= Len)
  334.         Txt[pos] = 0;
  335.     else
  336.         while (copyPos <= Len + 1)
  337.             {
  338.             Txt[pos] = Txt[copyPos];
  339.             ++pos;
  340.             ++copyPos;
  341.             }
  342.  
  343.     Len -= count;
  344.  
  345.     Shrink();
  346.     }
  347.  
  348. // substring insertion methods
  349. void String::Insert(unsigned int pos, char ch)
  350.     {
  351.     char * temp;
  352.  
  353.     if (pos > Len)
  354.         return;
  355.  
  356.     if (Len + 1 == Siz)
  357.         {
  358.         Siz  += AllocIncr;
  359.         temp  = new char[Siz];
  360.  
  361.         if (temp == NULL)
  362.             ErrorHandler(SE_ALLOC);
  363.  
  364.         strcpy(temp,Txt);
  365.  
  366.         delete Txt;
  367.  
  368.         Txt = temp;
  369.         }
  370.  
  371.     for (unsigned int col = Len + 1; col > pos; --col)
  372.         Txt[col] = Txt[col-1];
  373.  
  374.     Txt[pos] = ch;
  375.  
  376.     ++Len;
  377.  
  378.     Txt[Len + 1] = '\x00';
  379.     }
  380.  
  381. void String::Insert(unsigned int pos, const String & str)
  382.     {
  383.     unsigned long totalLen = str.Len + Len;
  384.  
  385.     if (totalLen > UINT_MAX)
  386.         ErrorHandler(SE_TOO_LONG);
  387.  
  388.     unsigned int SLen = str.Len;
  389.  
  390.     if (SLen > 0)
  391.         for (unsigned int i = 0; i < SLen; ++i)
  392.             {
  393.             Insert(pos,str.Txt[i]);
  394.             ++pos;
  395.             }
  396.     }
  397.  
  398. // substring retrieval method
  399. String String::SubStr(unsigned int start, unsigned int count)
  400.     {
  401.     String tempStr;
  402.     char * temp;
  403.  
  404.     if ((start < Len) && (count > 0))
  405.         {
  406.         temp = new char [count + 1];
  407.  
  408.         memcpy(temp,&Txt[start],count);
  409.  
  410.         temp[count] = '\x00';
  411.         }
  412.     else
  413.         temp = "";
  414.  
  415.     tempStr = temp;
  416.  
  417.     delete temp;
  418.  
  419.     return tempStr;
  420.     }
  421.  
  422. // case-modification methods
  423. String String::ToUpper()
  424.     {
  425.     String tempStr = *this;
  426.  
  427.     strupr(tempStr.Txt);
  428.  
  429.     return tempStr;
  430.     }
  431.  
  432. String String::ToLower()
  433.     {
  434.     String tempStr = *this;
  435.  
  436.     strlwr(tempStr.Txt);
  437.  
  438.     return tempStr;
  439.     }
  440.