home *** CD-ROM | disk | FTP | other *** search
/ Monster Media 1994 #1 / monster.zip / monster / PROG_C / SNIP9404.ZIP / STR.CPP < prev    next >
C/C++ Source or Header  |  1994-04-03  |  6KB  |  304 lines

  1. //
  2. // Implements simple string class 'str'
  3. //
  4.  
  5. # include "str.h"
  6. # include <string.h>
  7. # include <memory.h>
  8. # if defined( _MSC_VER )
  9. # pragma warning(disable:4505)
  10. # endif
  11.  
  12. # define STDLEN 32
  13.  
  14. extern "C" void * malloc (unsigned sz);
  15. extern "C" void free (void * ptr);
  16.  
  17. # if defined( PLACEMENT_NEW_BUG )
  18.  
  19. inline void *
  20. operator new (unsigned sz, short allocsz)
  21. {
  22.     return malloc (sz + allocsz);
  23. }
  24.  
  25. # else
  26.  
  27. void *
  28. refstr::operator new (unsigned sz, short allocsz)
  29. {
  30.     return malloc (sz + allocsz);
  31. }
  32.  
  33. # endif
  34.  
  35. void
  36. str::_strinit (char const * s, short len, short siz)
  37. {
  38.     if (len < 0)
  39.         len = (short) ((s) ? strlen (s) : 0);
  40.     if (siz < 0)
  41.         siz = STDLEN;
  42.     if (siz < len + 1)
  43.         siz = short(len + 1);
  44.     strdata = new(siz) refstr(len, siz);
  45.     if (s && len)
  46.         memcpy (c_ptr(), s, len);
  47. }
  48.  
  49.         // Called whenever string is to be modified or grown
  50. int
  51. str::_chksize (short sz)
  52. {
  53.     refstr * old = 0;
  54.     if (strdata->_refs > 1) // Need to dup memory
  55.         --strdata->_refs;   // Dec existing string reference
  56.     else if (sz >= size())
  57.         old = strdata;
  58.     else
  59.         return 0;
  60.     _strinit (c_ptr(), length(), sz);
  61.     delete old;
  62.     return 1;
  63. }
  64.  
  65. str &
  66. str::operator= (str const & s)
  67. {
  68.     if (&s != this)
  69.     {
  70.         if (!--strdata->_refs)
  71.             delete strdata;
  72.         strdata = s.strdata;
  73.         ++strdata->_refs;
  74.     }
  75.     return *this;
  76. }
  77.  
  78. str &
  79. str::operator= (char const * s)
  80. {
  81.     if (s != c_ptr())
  82.     {
  83.         short len = (short) strlen (s);
  84.         _chksize (len);
  85.         memcpy (c_ptr(), s, len + 1);
  86.         strdata->_length = len;
  87.     }
  88.     return *this;
  89. }
  90.  
  91. str &
  92. str::operator= (char c)
  93. {
  94.     _chksize (1);
  95.     *c_ptr() = c;
  96.     strdata->_length = 1;
  97.     return *this;
  98. }
  99.  
  100. short
  101. str::insert (short pos, char const * s, short len)
  102. {
  103.     if (len < 0)
  104.         len = (short) strlen (s);
  105.     if (len)
  106.     {
  107.         short leng = strdata->_length;
  108.         if (pos < 0 || pos > leng)
  109.             pos = leng;
  110.         _chksize (short(leng + len));
  111.         char * buf = c_ptr();
  112.         if (pos < leng)
  113.             memmove (buf + pos + len, buf + pos, leng - pos);
  114.         memcpy (buf + pos, s, len);
  115.         strdata->_length += len;
  116.     }
  117.     return length();
  118. }
  119.  
  120. short
  121. str::remove (short pos, short len)
  122. {
  123.     if (pos >= 0 && pos < length())
  124.     {
  125.         short leng = strdata->_length;
  126.         if (len < 0 || (pos + len) > leng)
  127.             len = short(leng - pos);
  128.         if (len)
  129.         {
  130.             _chksize (0);
  131.             char * buf = c_ptr();
  132.             memcpy (buf + pos, buf + pos + len, leng - (pos + len));
  133.             strdata->_length -= len;
  134.         }
  135.     }
  136.     return length();
  137. }
  138.  
  139. short
  140. str::replace (short pos, char const * s, short clen, short len)
  141. {
  142.     if (pos >= 0)
  143.     {
  144.         short leng = strdata->_length;
  145.         if (clen < 0 || (pos + clen) > leng)
  146.             clen = short(leng - pos);
  147.         if (len < 0)
  148.             len = (short) strlen (s);
  149.         if (pos > leng)
  150.             pos = leng;
  151.         _chksize (short(leng - clen + len));
  152.         char * buf = c_ptr();
  153.         if (clen != len && clen)
  154.             memmove (buf + pos + len, buf + pos + clen,
  155.                      leng - (pos + clen - len));
  156.         if (len)
  157.             memcpy (buf + pos, s, len);
  158.         strdata->_length += short(len - clen);
  159.     }
  160.     return length();
  161. }
  162.  
  163.  
  164. str &
  165. str::left (short len, char padch)
  166. {
  167.     if (len < 0)
  168.         return right (short(-len), padch);
  169.     short leng = strdata->_length;
  170.     if (len != leng)
  171.     {
  172.         _chksize (len);
  173.         if (len > leng)
  174.             memset (strdata->ptr() + leng, padch, leng - len);
  175.         strdata->_length = len;
  176.     }
  177.     return *this;
  178. }
  179.  
  180. str &
  181. str::right (short len, char padch)
  182. {
  183.     if (len < 0)
  184.         return left(-1, padch);
  185.     short leng = strdata->_length;
  186.     if (len != leng)
  187.     {
  188.         _chksize (len);
  189.         if (len > leng)
  190.         {
  191.             char * buf = strdata->ptr();
  192.             memmove (buf + len - leng, buf, leng);
  193.             memset (buf, padch, len - leng);
  194.         }
  195.         strdata->_length = len;
  196.     }
  197.     return *this;
  198. }
  199.  
  200. str &
  201. str::mid (short pos, short len, char padch)
  202. {
  203.     if (pos <= 0)
  204.         return left(len, padch);
  205.     short leng = strdata->_length;
  206.     if (pos > leng)
  207.         pos = leng;
  208.     if (leng < len)         // Are we padding?
  209.     {
  210.         _chksize (len);
  211.         char * buf = strdata->ptr();
  212.         short nlen = short((len - (leng - pos)) / 2);
  213.         if (nlen > 0)
  214.         {
  215.             memmove (buf, buf + pos, leng - pos);
  216.             memset (buf + leng - pos, padch, nlen);
  217.             strdata->_length -= short(pos - nlen);
  218.         }
  219.     }
  220.     return right (len, padch);
  221. }
  222.  
  223.  
  224. int
  225. str::_concat (char const * s, short len)
  226. {
  227.     if (len < 0)
  228.         len = (short) strlen (s);
  229.     if (len)
  230.     {
  231.         _chksize (short(len + length()));
  232.         memcpy (c_ptr() + length(), s, len);
  233.         strdata->_length += len;
  234.     }
  235.     return length();
  236. }
  237.  
  238. short
  239. str::removech (char const * clist)
  240. {
  241.     short result = 0;
  242.     if (*clist)
  243.     {
  244.         char * buf, * sub;
  245.         buf = sub = strdata->ptr();
  246.         short nlen = strdata->_length;
  247.         for (short i = 0; i < nlen; ++i)
  248.         {
  249.             if (strchr (clist, *buf) == 0)
  250.             {
  251.                 if (result)
  252.                     *sub = *buf;
  253.                 ++sub;
  254.             }
  255.             else
  256.             {
  257.                 if (!result)
  258.                     _chksize (0);
  259.                 ++result;
  260.             }
  261.             ++buf;
  262.         }
  263.         strdata->_length = short(nlen - result);
  264.     }
  265.     return result;
  266. }
  267.  
  268. short
  269. str::countch (char const * clist)
  270. {
  271.     short result = 0;
  272.     if (*clist)
  273.     {
  274.         char * buf = strdata->ptr();
  275.         short nlen = strdata->_length;
  276.         for (short i = 0; i < nlen; ++i, ++buf)
  277.             if (strchr (clist, *buf) != 0)
  278.                 ++result;
  279.     }
  280.     return result;
  281. }
  282.  
  283.  
  284. str
  285. left (str const & s, short len, char padch)
  286. {
  287.     str n(s);
  288.     return n.left(len, padch);
  289. }
  290.  
  291. str
  292. right (str const & s, short len, char padch)
  293. {
  294.     str n(s);
  295.     return n.right(len, padch);
  296. }
  297.  
  298. str
  299. mid (str const & s, short pos, short len, char padch)
  300. {
  301.     str n(s);
  302.     return n.mid(pos, len, padch);
  303. }
  304.