/*--------------------------------------------------------------------*/
/* U s t r . c p p */
/* */
/* Implementation of "Str" class */
/*--------------------------------------------------------------------*/
/* Copyright (c) 2002 by Fyodor Ustinov */
/* FIDONet 2:5020/79 */
/* */
/* All rights reserved. */
/*--------------------------------------------------------------------*/
// #include <iostream.h>
#include <string.h>
#include <stdlib.h>
#include "ustr.hpp"
#define CHUNK_SIZE 512
/*--------------------------------------------------------------------*/
/* Constructors & destructor */
/*--------------------------------------------------------------------*/
Str::Str() {
MemLen = 0;
Len = 0;
Ptr = NULL;
_Base = 10;
alloc(1);
}
Str::Str(char const *Nstr) {
MemLen = 0;
_Base = 10;
Ptr = NULL;
if (Nstr == NULL) {
Len = 0;
alloc(1);
} else {
Len = strlen(Nstr);
alloc(Len+1);
strncpy(Ptr,Nstr,Len);
}
}
Str::Str(const Str &s) {
Len = s.Len;
_Base = 10;
MemLen = 0;
Ptr = NULL;
alloc(Len+1);
strncpy(Ptr,s.Ptr,Len+1);
}
Str & Str::operator=(const Str &s) {
if (&s != this) {
free();
alloc(s.Len+1);
Len = s.Len;
memcpy(Ptr,s.Ptr,Len);
}
return *this;
}
Str & Str::operator=(const char *s) {
free();
alloc(1);
if (s == NULL) return *this;
if (*s == '\0') return *this;
Len = strlen(s);
alloc(Len+1);
strncpy(Ptr,s,Len);
return *this;
}
Str & Str::operator=(const char c) {
free();
alloc(1);
*Ptr = c;
Len = 1;
return *this;
}
Str::~Str() {
free();
}
/*--------------------------------------------------------------------*/
/* Allocate and free memory */
/*--------------------------------------------------------------------*/
void Str::alloc(size_t sz) {
char *tmt;
size_t rsz;
if (sz == 0) throw "Str: Attempt to allocate 0 bytes";
// cout << "MemLen == " << MemLen << " sz == " << sz << "\n";
if (MemLen != 0 && sz < MemLen && sz >= MemLen-CHUNK_SIZE) return;
tmt = Ptr;
rsz = (((sz / CHUNK_SIZE) + 1) * CHUNK_SIZE) + 1;
Ptr = (char *) malloc(rsz);
if (Ptr == NULL) throw "Str: Unable to allocate memory";
if (tmt != NULL) {
if (rsz > MemLen) {
memmove(Ptr,tmt,MemLen);
} else {
memmove(Ptr,tmt,rsz);
Len = rsz-1;
}
::free(tmt);
}
MemLen = rsz;
// cout << "at end MemLen == " << MemLen << " Len == " << Len << "\n";
}
void Str::free(void) {
if (Ptr != NULL) {
::free(Ptr);
Ptr = NULL;
Len = 0;
MemLen = 0;
}
}
/*--------------------------------------------------------------------*/
/* Return pointers to c string */
/*--------------------------------------------------------------------*/
Str::operator char const *(){
Ptr[Len] = '\0';
return Ptr;
}
Str::operator char const *() const {
Ptr[Len] = '\0';
return Ptr;
}
Str::operator char*() {
Ptr[Len] = '\0';
return Ptr;
}
/*--------------------------------------------------------------------*/
/* Add to string */
/*--------------------------------------------------------------------*/
void Str::AddChar(char const c) {
alloc(Len + 1);
Ptr[Len++] = c;
}
static char digits[] = "0123456789abcdefghijklmnopqrstuvwxyz";
void Str::ParseDig(signed long n) {
int i;
char s[128];
if (n < 0L) {
n = -n;
AddChar('-');
}
i = 0;
do {
s[i++] = digits[(int)(n % _Base)];
} while (n /= _Base);
do {
AddChar(s[--i]);
} while (i != 0);
}
void Str::ParseDig(unsigned long n) {
int i;
char s[128];
i = 0;
do {
s[i++] = digits[(int)(n % _Base)];
} while (n /= _Base);
do {
i--;
AddChar(s[i]);
} while (i != 0);
}
Str & Str::operator += (Str const &s) {
alloc(Len + s.Len + 1);
memcpy(Ptr+Len,s.Ptr,s.Len);
Len += s.Len;
return *this;
}
Str & Str::operator += (char const *s) {
int slen;
if (s == NULL) return *this;
if (*s == '\0') return *this;
slen = strlen(s);
alloc(Len + slen + 1);
strncpy(Ptr+Len,s,slen);
Len += slen;
return *this;
}
/*--------------------------------------------------------------------*/
/* Substrings */
/*--------------------------------------------------------------------*/
Str Str::operator () ( size_t _p, size_t _l) const {
Str s;
if (_p == 0 || _p > Len || (_p + _l - 1) > Len) throw "Diapason out of range";
if (_l == 0) {
s.Len = Len - _p + 1;
} else {
s.Len = _l;
}
if (s.Len != 0) {
s.alloc(s.Len + 1);
memcpy(s.Ptr,Ptr+_p-1,s.Len);
}
return s;
}
/*--------------------------------------------------------------------*/
/* Comparasion */
/*--------------------------------------------------------------------*/
int operator == (Str const &s1, Str const &s2) {
if (s1.Len != s2.Len) return 0;
if (memcmp(s1.Ptr,s2.Ptr,s1.Len) != 0) return 0;
return -1;
}
int operator == (Str const &s1, char const *s2) {
if (s2 == NULL) return 0;
if (s1.Len != strlen(s2)) return 0;
if (memcmp(s1.Ptr,s2,s1.Len) != 0) return 0;
return -1;
}
int operator == (char const *s2, Str const &s1) {
if (s2 == NULL) return 0;
if (s1.Len != strlen(s2)) return 0;
if (memcmp(s1.Ptr,s2,s1.Len) != 0) return 0;
return -1;
}
/*--------------------------------------------------------------------*/
/* Characters */
/*--------------------------------------------------------------------*/
char & Str::operator [] (size_t _p) {
if (_p == 0) throw "Index is 0";
if (_p > Len) throw "Index out of range";
return *(Ptr+_p-1);
}
char const & Str::operator [] (size_t _p) const {
if (Ptr == NULL) throw "Str is NULL";
if (_p == 0) throw "Index is 0";
if (_p > Len) throw "Index out of range";
return *(Ptr+_p-1);
}
Str &Str::Trim(char const *Del) {
char *tmt;
if (Del == NULL) return *this;
while (Len != 0 && strchr(Del,Ptr[Len-1]) != NULL) Len--;
if (Len == 0) return *this;
for (tmt = Ptr; strchr(Del,*tmt) != NULL && Len != 0; Len--,tmt++);
if (Len == 0) return *this;
memmove(Ptr,tmt,Len);
return *this;
}
size_t Str::Pos(char const *s) {
char *tmt;
if (s == NULL) return 0;
Ptr[Len] = '\0';
if ((tmt = strstr(Ptr,s)) == NULL) return 0;
return (tmt-Ptr+1);
}
Str &Str::Cut(size_t _p, size_t _l) {
if (_p == 0 || _p > Len || (_p + _l - 1) > Len) throw "Diapason out of range";
if (_l == 0) {
Len = _p - 1;
} else {
Len -= _l;
memmove(Ptr+_p-1,Ptr+_p+_l-1,Len-_p+1);
}
return *this;
}
Str &Str::Upper(void) {
for (unsigned int i = 0; i < Len; i++) {
Ptr[i] = toupper(Ptr[i]);
}
return *this;
}
/*--------------------------------------------------------------------*/
/* In/Out */
/*--------------------------------------------------------------------*/
ostream & operator << (ostream &io, Str const &s) {
if (s.Len != 0) io.write(s.Ptr,s.Len);
return io;
}
/*--------------------------------------------------------------------*/
#if 0
void main(void) {
try {
Str a;
Str b("123456");
b = b;
a = b;
cout << b << "\n";
b[2] = 'c';
a += b;
a += " This is a test!";
cout << b << "\n";
cout << a << "\n";
a = NULL;
cout << a << "\n";
a = "Test";
cout << a << "\n";
a.Base(16);
a += 'c';
a += 'd';
a += ' ';
a += 255;
a += ' ';
a += -255;
a += ' ';
a += 255L;
a += ' ';
a += -255L;
cout << a << "\n";
for (int i = 1; i < 4; i++) {
cout << "i == " << i << " c == " << b[i] << "\n";
}
cout << "5" << "\n";
cout <<"->"<< b(5,2) << "<-\n";
}
catch (char *s) {
cout << "\nException: " << s << "\n";
}
catch (...) {
cout << "\nException: " << "\n";
}
}
#endif
syntax highlighted by Code2HTML, v. 0.9.1