home *** CD-ROM | disk | FTP | other *** search
-
- #include <string.h>
- #include <stdlib.h>
-
- #include "NString.h"
- #include "NString_Misc.h"
-
- //_________________________________________________________________________________
-
- NString& NString::operator+= (const char *s)
- {
- const char *fname = "operator+= (const char *)";
- unsigned long int new_length;
-
- if ((s == NULL) || (s[0] == '\0')) // empty string given to add
- return (*this);
- new_length = strlen(s) + sb->len; // the new NString's length
- if (sb->refs > 1) // string body is used by someone else
- {
- strbody *old_sb = sb;
-
- if (! GetNewSB(new_length))
- OUT_OF_MEM(fname);
- strcpy(sb->str, old_sb->str); // copy the original part of the string
- strcpy(sb->str + old_sb->len, s); // copy the new part of the string
- }
- else // the string body may be modified freely
- {
- if (! ReallocStrBuf(new_length)) // will NOT modify "sb->len" :-)
- OUT_OF_MEM(fname);
- strcpy(sb->str + sb->len, s); // add the new part to the string
- sb->len = new_length;
- }
- return (*this);
- }
-
- //_________________________________________________________________________________
-
- NString& NString::operator+= (const NString& s)
- {
- const char *fname = "operator+= (const NString&)";
- unsigned long int new_length;
-
- if (s.sb->len == 0) // empty NString given to add
- return (*this);
- new_length = s.sb->len + sb->len; // the new NString's length
- if (sb->refs > 1) // my string body is used by someone else
- {
- strbody *old_sb = sb;
- unsigned long int old_s_len = s.sb->len;
-
- if (! GetNewSB(new_length))
- OUT_OF_MEM(fname);
- strcpy(sb->str, old_sb->str); // copy the original part of the string
- memmove(sb->str + old_sb->len, s.sb->str, old_s_len); // copy the new part of the string
- // memmove() MUST be used instead of strcpy() to protect against "s += s" !!!
- // Moreover, "old_s_len" must be used as move-length, not "s.sb->len",
- // otherwise memmove() overwrites innocent memory in the case of "s += s" !
- }
- else // the string body may be modified freely
- {
- if (! ReallocStrBuf(new_length)) // will NOT modify "sb->len"
- OUT_OF_MEM(fname);
- memmove(sb->str + sb->len, s.sb->str, s.sb->len+1); // add the new part to the string
- // memmove() MUST be used instead of strcpy() to protect against "s += s" !!!
- sb->len = new_length;
- // new length must be inscribed AFTER the call to memmove() !
- }
- return (*this);
- }
-
- //_________________________________________________________________________________
-
- NString& NString::operator+= (const char c)
- {
- const char *fname = "operator+= (const char)"; // the method's name (for error handling purposes)
- unsigned long int new_length;
-
- if (c == '\0') // tried to add NUL character
- USAGE_ERR(fname, "Attempted to add NUL character to NString");
- new_length = sb->len + 1; // the new NString's length
- if (sb->refs > 1) // string body is used by someone else
- {
- strbody *old_sb = sb;
-
- if (! GetNewSB(new_length))
- OUT_OF_MEM(fname);
- strcpy(sb->str, old_sb->str); // copy the original part of the string
- sb->str[old_sb->len] = c; // add the character
- }
- else // the string body may be modified freely
- {
- if (! ReallocStrBuf(new_length)) // will NOT modify "sb->len" :-)
- OUT_OF_MEM(fname);
- sb->str[sb->len] = c; // add the character
- sb->str[sb->len+1] = '\0'; // terminate the new string
- sb->len = new_length;
- }
- return (*this);
- }
-
- //_________________________________________________________________________________
-
- NString NString::operator+ (const char *s) const
- {
- unsigned long int new_length = strlen(s) + sb->len;
- NString result(new_length); // create an uninitialized NString
-
- strcpy(result.sb->str, sb->str); // copy my own string part
- strcpy(result.sb->str + sb->len, s); // copy the C-String part
- return (result);
- }
-
- //_________________________________________________________________________________
-
- NString NString::operator+ (NString& s) const
- {
- unsigned long int new_length = s.sb->len + sb->len;
- NString result(new_length); // create an uninitialized NString
-
- strcpy(result.sb->str, sb->str); // copy my own string part
- strcpy(result.sb->str + sb->len, s.sb->str); // copy the other NString's part
- return (result);
- }
-
- //_________________________________________________________________________________
-
- NString NString::operator+ (const char c) const
- {
- unsigned long int new_length = sb->len + 1;
- NString result(new_length); // create an uninitialized NString
-
- if (c == '\0')
- USAGE_ERR("operator+ (const char)", "Attempted to add NUL character to NString");
- strcpy(result.sb->str, sb->str); // copy my own string part
- result.sb->str[sb->len] = c; // copy the character
- return (result);
- }
-
- //_________________________________________________________________________________
-
- NString operator+ (const char *s, const NString& ns)
- {
- size_t s_length = strlen(s);
- unsigned long int new_length = s_length + ns.sb->len;
- NString result(new_length); // create an uninitialized NString
-
- strcpy(result.sb->str, s); // copy the C-String part
- strcpy(result.sb->str + s_length, ns.sb->str); // copy the NString part
- return (result);
- }
-
- //_________________________________________________________________________________
-
- NString operator+ (const char c, const NString& ns)
- {
- unsigned long int new_length = ns.sb->len + 1;
- NString result(new_length); // create an uninitialized NString
-
- if (c == '\0')
- USAGE_ERR("operator+ (const char, const NString&)", "Attempted to add NUL character to NString");
- result.sb->str[0] = c; // copy the character
- strcpy(result.sb->str + 1, ns.sb->str); // copy the NString part
- return (result);
- }
-
- //_________________________________________________________________________________
-
- NString& NString::operator*= (const unsigned long int k)
- {
- const char *fname = "operator*= (const unsigned long int)";
- unsigned long int new_length = k * sb->len;
- unsigned long int i;
-
- if (new_length == sb->len) // either k==1 or NString is empty
- return (*this);
- if (sb->refs > 1)
- {
- strbody *old_sb = sb;
-
- if (! GetNewSB(new_length))
- OUT_OF_MEM(fname);
- if (new_length != 0)
- for (i=0; i < k; i++) // copy my string k times
- strcpy(sb->str + i*old_sb->len, old_sb->str);
- }
- else
- {
- if (! ReallocStrBuf(new_length)) // will NOT modify "sb->len"
- OUT_OF_MEM(fname);
- if (new_length == 0)
- sb->str[0] = '\0'; // initialize empty string
- else
- {
- for (i=1; i < k; i++) // concatenate my string k-1 times
- memmove(sb->str + i*sb->len, sb->str, sb->len);
- // "memmove()" must be used instead of "strcpy()" or "memcpy()" as the terminator
- // of the source is overwritten by the copy
- sb->str[new_length] = '\0';
- // must terminate the new string manually, as during the nth call to "memcpy()"
- // the NUL terminator of the source has already been overwritten.
- }
- sb->len = new_length;
- }
- return (*this);
- }
-
- //_________________________________________________________________________________
-
- NString NString::operator* (const unsigned long int k) const
- {
- unsigned long int new_length = k * sb->len;
- NString result(new_length);
- unsigned long int i;
-
- if (new_length == sb->len) // either k==1 or NString is empty
- return (*this);
- if (new_length == 0)
- return (result);
-
- for (i=0; i < k; i++)
- strcpy(result.sb->str + i*sb->len, sb->str);
- return (result);
- }
-
-