summaryrefslogtreecommitdiff
path: root/reference/C/CONTRIB/SNIP/str.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'reference/C/CONTRIB/SNIP/str.cpp')
-rwxr-xr-xreference/C/CONTRIB/SNIP/str.cpp303
1 files changed, 303 insertions, 0 deletions
diff --git a/reference/C/CONTRIB/SNIP/str.cpp b/reference/C/CONTRIB/SNIP/str.cpp
new file mode 100755
index 0000000..df4f118
--- /dev/null
+++ b/reference/C/CONTRIB/SNIP/str.cpp
@@ -0,0 +1,303 @@
+//
+// Implements simple string class 'str'
+//
+
+# include "str.h"
+# include <string.h>
+# include <memory.h>
+# if defined( _MSC_VER )
+# pragma warning(disable:4505)
+# endif
+
+# define STDLEN 32
+
+extern "C" void * malloc (unsigned sz);
+extern "C" void free (void * ptr);
+
+# if defined( PLACEMENT_NEW_BUG )
+
+inline void *
+operator new (unsigned sz, short allocsz)
+{
+ return malloc (sz + allocsz);
+}
+
+# else
+
+void *
+refstr::operator new (unsigned sz, short allocsz)
+{
+ return malloc (sz + allocsz);
+}
+
+# endif
+
+void
+str::_strinit (char const * s, short len, short siz)
+{
+ if (len < 0)
+ len = (short) ((s) ? strlen (s) : 0);
+ if (siz < 0)
+ siz = STDLEN;
+ if (siz < len + 1)
+ siz = short(len + 1);
+ strdata = new(siz) refstr(len, siz);
+ if (s && len)
+ memcpy (c_ptr(), s, len);
+}
+
+ // Called whenever string is to be modified or grown
+int
+str::_chksize (short sz)
+{
+ refstr * old = 0;
+ if (strdata->_refs > 1) // Need to dup memory
+ --strdata->_refs; // Dec existing string reference
+ else if (sz >= size())
+ old = strdata;
+ else
+ return 0;
+ _strinit (c_ptr(), length(), sz);
+ delete old;
+ return 1;
+}
+
+str &
+str::operator= (str const & s)
+{
+ if (&s != this)
+ {
+ if (!--strdata->_refs)
+ delete strdata;
+ strdata = s.strdata;
+ ++strdata->_refs;
+ }
+ return *this;
+}
+
+str &
+str::operator= (char const * s)
+{
+ if (s != c_ptr())
+ {
+ short len = (short) strlen (s);
+ _chksize (len);
+ memcpy (c_ptr(), s, len + 1);
+ strdata->_length = len;
+ }
+ return *this;
+}
+
+str &
+str::operator= (char c)
+{
+ _chksize (1);
+ *c_ptr() = c;
+ strdata->_length = 1;
+ return *this;
+}
+
+short
+str::insert (short pos, char const * s, short len)
+{
+ if (len < 0)
+ len = (short) strlen (s);
+ if (len)
+ {
+ short leng = strdata->_length;
+ if (pos < 0 || pos > leng)
+ pos = leng;
+ _chksize (short(leng + len));
+ char * buf = c_ptr();
+ if (pos < leng)
+ memmove (buf + pos + len, buf + pos, leng - pos);
+ memcpy (buf + pos, s, len);
+ strdata->_length += len;
+ }
+ return length();
+}
+
+short
+str::remove (short pos, short len)
+{
+ if (pos >= 0 && pos < length())
+ {
+ short leng = strdata->_length;
+ if (len < 0 || (pos + len) > leng)
+ len = short(leng - pos);
+ if (len)
+ {
+ _chksize (0);
+ char * buf = c_ptr();
+ memcpy (buf + pos, buf + pos + len, leng - (pos + len));
+ strdata->_length -= len;
+ }
+ }
+ return length();
+}
+
+short
+str::replace (short pos, char const * s, short clen, short len)
+{
+ if (pos >= 0)
+ {
+ short leng = strdata->_length;
+ if (clen < 0 || (pos + clen) > leng)
+ clen = short(leng - pos);
+ if (len < 0)
+ len = (short) strlen (s);
+ if (pos > leng)
+ pos = leng;
+ _chksize (short(leng - clen + len));
+ char * buf = c_ptr();
+ if (clen != len && clen)
+ memmove (buf + pos + len, buf + pos + clen,
+ leng - (pos + clen - len));
+ if (len)
+ memcpy (buf + pos, s, len);
+ strdata->_length += short(len - clen);
+ }
+ return length();
+}
+
+
+str &
+str::left (short len, char padch)
+{
+ if (len < 0)
+ return right (short(-len), padch);
+ short leng = strdata->_length;
+ if (len != leng)
+ {
+ _chksize (len);
+ if (len > leng)
+ memset (strdata->ptr() + leng, padch, leng - len);
+ strdata->_length = len;
+ }
+ return *this;
+}
+
+str &
+str::right (short len, char padch)
+{
+ if (len < 0)
+ return left(-1, padch);
+ short leng = strdata->_length;
+ if (len != leng)
+ {
+ _chksize (len);
+ if (len > leng)
+ {
+ char * buf = strdata->ptr();
+ memmove (buf + len - leng, buf, leng);
+ memset (buf, padch, len - leng);
+ }
+ strdata->_length = len;
+ }
+ return *this;
+}
+
+str &
+str::mid (short pos, short len, char padch)
+{
+ if (pos <= 0)
+ return left(len, padch);
+ short leng = strdata->_length;
+ if (pos > leng)
+ pos = leng;
+ if (leng < len) // Are we padding?
+ {
+ _chksize (len);
+ char * buf = strdata->ptr();
+ short nlen = short((len - (leng - pos)) / 2);
+ if (nlen > 0)
+ {
+ memmove (buf, buf + pos, leng - pos);
+ memset (buf + leng - pos, padch, nlen);
+ strdata->_length -= short(pos - nlen);
+ }
+ }
+ return right (len, padch);
+}
+
+
+int
+str::_concat (char const * s, short len)
+{
+ if (len < 0)
+ len = (short) strlen (s);
+ if (len)
+ {
+ _chksize (short(len + length()));
+ memcpy (c_ptr() + length(), s, len);
+ strdata->_length += len;
+ }
+ return length();
+}
+
+short
+str::removech (char const * clist)
+{
+ short result = 0;
+ if (*clist)
+ {
+ char * buf, * sub;
+ buf = sub = strdata->ptr();
+ short nlen = strdata->_length;
+ for (short i = 0; i < nlen; ++i)
+ {
+ if (strchr (clist, *buf) == 0)
+ {
+ if (result)
+ *sub = *buf;
+ ++sub;
+ }
+ else
+ {
+ if (!result)
+ _chksize (0);
+ ++result;
+ }
+ ++buf;
+ }
+ strdata->_length = short(nlen - result);
+ }
+ return result;
+}
+
+short
+str::countch (char const * clist)
+{
+ short result = 0;
+ if (*clist)
+ {
+ char * buf = strdata->ptr();
+ short nlen = strdata->_length;
+ for (short i = 0; i < nlen; ++i, ++buf)
+ if (strchr (clist, *buf) != 0)
+ ++result;
+ }
+ return result;
+}
+
+
+str
+left (str const & s, short len, char padch)
+{
+ str n(s);
+ return n.left(len, padch);
+}
+
+str
+right (str const & s, short len, char padch)
+{
+ str n(s);
+ return n.right(len, padch);
+}
+
+str
+mid (str const & s, short pos, short len, char padch)
+{
+ str n(s);
+ return n.mid(pos, len, padch);
+}