master
Aaron 5 days ago
parent eb9ae4316f
commit b791fdf841

Binary file not shown.

@ -17,6 +17,9 @@
namespace ams
{
static const int amsstring_success = 1;
static const int amsstring_failure = -1;
//wraps the functions strcpy_s and strncpy in a portable manner
//between linux and microsoft standard C libraries.
int amsstrcpy_s(char *dest, int size, const char *src);
@ -39,9 +42,8 @@ static const ams_chartype ams_char_nt = (ams_chartype) '\0'; //null terminator
class amsstring
{
public:
ams_chartype blank; // null terminator returned for accessing index out of bounds
ams_chartype *cstring;
ams_chartype blank; // null terminator returned for accessing index out of bounds
int length;
//length will be set to the length of the cstring not including the null terminating char
@ -49,20 +51,13 @@ public:
amsstring();
~amsstring();
amsstring(amsstring &other);
amsstring& operator=(amsstring &other);
amsstring(const amsstring &other);
const amsstring& operator=(const amsstring &other);
amsstring(ams_chartype *other);
amsstring& operator=(const amsstring& other);
amsstring(amsstring &&other) noexcept;
amsstring& operator=(amsstring &&other) noexcept;
amsstring(const ams_chartype *other);
const amsstring& operator=(const ams_chartype *other);
amsstring& operator=(ams_chartype *other);
const amsstring& operator=(const ams_chartype *other); //assign string constant to amsstring
//const amsstring& operator=(const ams_chartype *other) const; //assign string constant to amsstring
//const is a disease!
//
//amsstring(int length);
//amsstring(int length, const ams_chartype initchar);

@ -4,20 +4,20 @@
namespace ams
{
void amsstring3_basic_string_test1();
void amsstring3_sscanf_test1();
void amsstring3_basic_string_test2();
void amsstring3_memoryleakcheck1();
void amsstring3_memoryleakcheck2();
void amsstring3_stringtests2();
void amsstring3_test_find();
void amsstring3_test_splitlines();
void amsstring3_test_split();
void amsstring3_test_strip();
void amsstring3_test_freadwrite();
void amsstring3_test_concatenation_operators();
void amsstring4_basic_string_test1();
void amsstring4_sscanf_test1();
void amsstring4_basic_string_test2();
void amsstring4_memoryleakcheck1();
void amsstring4_memoryleakcheck2();
void amsstring4_stringtests2();
void amsstring4_test_find();
void amsstring4_test_splitlines();
void amsstring4_test_split();
void amsstring4_test_strip();
void amsstring4_test_freadwrite();
void amsstring4_test_concatenation_operators();

@ -528,7 +528,7 @@ void test_base64encode_fuzztest()
bytes.resize(I);
for(J=0;J<bytes.size();J++)
{
bytes.data[J] = randd()*255;
bytes.data[J] = ams::rand::rand()*255;
}
base64encode(&bytes,&str);
base64decode(&str,&bytes2,1);

@ -33,7 +33,7 @@ namespace ams
return ret;
}
static int localstrlen(const ams_chartype *c)
static int amsstring_strlen(const ams_chartype *c)
{
int I;
if(c!=NULL)
@ -46,7 +46,6 @@ namespace ams
return I;
//return strlen((const char*) c);
}
else
return 0;
}
@ -54,8 +53,8 @@ namespace ams
bool amsstrneq(const ams_chartype *s1, const ams_chartype *s2, const bool casesens=1)
{
bool ret = 0;
int N1 = localstrlen(s1);
int N2 = localstrlen(s2);
int N1 = amsstring_strlen(s1);
int N2 = amsstring_strlen(s2);
bool b1,b2;
if(N1==N2)
@ -85,25 +84,29 @@ namespace ams
}
static void amsstring_init(amsstring* str)
void _amsstring_init(amsstring* str)
{
str->blank = (ams_chartype) '\0';
str->cstring = NULL;
str->length = 0;
str->cstring = new(std::nothrow) ams_chartype[1];
if(str->cstring==NULL)
{
printf("_amsstring_init error: cstring buffer failed to initialize.\n");
}
else
{
str->cstring[0] = (ams_chartype) '\0';
str->length = 0;
}
return;
}
amsstring::amsstring()
{
//amsstring_init(this);
_amsstring_init(this);
blank = (ams_chartype) '\0';
cstring = NULL;
cstring = new(std::nothrow) ams_chartype[1];
cstring[0] = (ams_chartype) '\0';
length = 0;
return;
}
@ -126,320 +129,173 @@ namespace ams
return length;
}
//Rewrite amsstring::resize() - valgrind is still complaining!
int amsstring::resize(const int newlen)
int amsstring::resize(int _newlen)
{
int ret = 0;
int I = 0;
ams_chartype *newbuff = NULL;
int ret = amsstring_success;
ams_chartype *newcstring = NULL;
int I;
_newlen = (_newlen<0) ? 0 : _newlen;
if(newlen == length)
newcstring = new(std::nothrow) ams_chartype[_newlen+1];
if(newcstring==NULL)
{
//sizes are the same, do nothing
ret = 1;
ret = amsstring_failure;
return ret;
}
if(newlen<=0) //if new length <0
if(cstring!=NULL)
{
newbuff = new(std::nothrow) ams_chartype[1];
if(newbuff==NULL)
for(I=0;I<(_newlen+1) && I<(length+1);I++)
{
ret = -1;
return ret;
newcstring[I] = cstring[I];
}
newbuff[0] = '\0';
if(cstring!=NULL) {delete[] cstring; cstring = NULL;}
cstring = newbuff;
length = 0;
ret = 1;
return ret;
}
newbuff = new(std::nothrow) ams_chartype[newlen+1];
if(newbuff==NULL)
for(I=length;I<_newlen+1;I++)
{
ret = -1;
return ret;
newcstring[I] = (ams_chartype) '\0';
}
//Copy old data
for(I=0;I<length && I<newlen;I++)
{
newcstring[_newlen] = '\0';
if(cstring!=NULL)
{
newbuff[I] = cstring[I];
}
else
{
newbuff[I] = '\0';
}
}
for(I=length;I<newlen;I++)
{
newbuff[I] = '\0';
delete[] cstring;
cstring=NULL;
}
newbuff[newlen] = '\0';
if(cstring!=NULL) {delete[] cstring; cstring = NULL;}
cstring = newbuff;
length = newlen;
ret = 1;
blank = (ams_chartype) '\0';
cstring = newcstring;
length = _newlen;
return ret;
}
// int amsstring::resize(const int newlen)
// {
// int ret = 0;
// int I = 0;
// ams_chartype *newbuf = NULL;
// //printf("DEBUG: cstring=%ld,newbuf=%ld, cstring='%s'\n",cstring,newbuf,cstring);
// //printf("DEBUG: length=%d, newlen=%d\n",length,newlen);
// if(newlen>=0)
// {
// newbuf = new(std::nothrow) ams_chartype[newlen+1];
// if(newbuf==NULL)
// {
// ret = -1; //new buffer would not allocate
// }
// else
// {
// for(I=0;I<newlen+1;I++)
// {
// newbuf[I] = (ams_chartype) '\0';
// }
// if(cstring!=NULL)
// {
// amsstrcpy_s(newbuf,newlen+1,cstring);
// for(I=length;I<newlen+1;I++) //pad additional spaces with 0
// {
// newbuf[I] = (ams_chartype) '\0';
// }
// //newbuf[newlen] = (ams_chartype) '\0';
// if(cstring!=NULL) {delete[] cstring; cstring = NULL;}
// cstring = newbuf;
// length = newlen;
// ret = 1;
// }
// else
// {
// cstring = newbuf;
// length = newlen;
// ret = 1;
// }
// } //if newbuf!=NULL
// }
// else //if(newlen>=0)
// {
// ret = this->resize(0);
// }
// //printf("DEBUG: ret = %d\n",ret);
// return ret;
// }
amsstring::amsstring(const amsstring &other)
{
//amsstring_init(this);
blank = (ams_chartype) '\0';
cstring = NULL;
cstring = new(std::nothrow) ams_chartype[1];
cstring[0] = (ams_chartype) '\0';
length = 0;
int I;
int res;
_amsstring_init(this);
if(this!=&other)
{
*this=other;
res = this->resize(other.length);
if(res==amsstring_success)
{
for(I=0;I<other.length;I++)
{
this->cstring[I] = other.cstring[I];
}
this->cstring[length] = '\0';
blank = '\0';
}
}
return;
}
amsstring::amsstring(amsstring &other)
amsstring& amsstring::operator=(const amsstring& other)
{
//amsstring_init(this);
blank = (ams_chartype) '\0';
cstring = NULL;
cstring = new(std::nothrow) ams_chartype[1];
cstring[0] = (ams_chartype) '\0';
length = 0;
int I;
int res;
if(this!=&other)
{
*this=other;
}
return;
}
const amsstring& amsstring::operator=(const amsstring &other)
res = this->resize(other.length);
if(res==amsstring_success)
{
if(this!=&other)
for(I=0;I<other.length;I++)
{
this->resize(other.length);
amsstrcpy_s(cstring,length+1,other.cstring);
cstring[length] = (ams_chartype) '\0';
shrinktofit(); //shrinks if the other cstring was corrupted with internal null terminators
// N = strlen(cstring); //if string is actually shorter (contains null terminating character elsewhere than at the end)
// //then resize to string's size
// if(N<length)
// {
// this->resize(N);
// }
this->cstring[I] = other.cstring[I];
}
return *this;
this->cstring[length] = '\0';
blank = '\0';
}
amsstring& amsstring::operator=(amsstring &other)
{
if(this!=&other)
{
this->resize(other.length);
amsstrcpy_s(cstring,length+1,other.cstring);
cstring[length] = (ams_chartype) '\0';
shrinktofit(); //shrinks if the other cstring was corrupted with internal null terminators
// N = strlen(cstring); //if string is actually shorter (contains null terminating character elsewhere than at the end)
// //then resize to string's size
// if(N<length)
// {
// this->resize(N);
// }
}
return *this;
}
amsstring::amsstring(ams_chartype *other)
amsstring::amsstring(amsstring &&other) noexcept
{
//amsstring_init(this);
blank = (ams_chartype) '\0';
cstring = NULL;
cstring = new(std::nothrow) ams_chartype[1];
cstring[0] = (ams_chartype) '\0';
length = 0;
*this = other;
return;
}
this->length = 0;
this->blank = '\0';
this->cstring = NULL;
amsstring::amsstring(const ams_chartype *other)
if(this!=&other)
{
//amsstring_init(this);
blank = (ams_chartype) '\0';
cstring = NULL;
cstring = new(std::nothrow) ams_chartype[1];
cstring[0] = (ams_chartype) '\0';
length = 0;
this->length = other.length;
this->blank = other.blank;
this->cstring = other.cstring;
*this = other;
other.length = 0;
other.blank = '\0';
other.cstring = NULL;
}
return;
}
const amsstring& amsstring::operator=(const ams_chartype *other)
amsstring& amsstring::operator=(amsstring &&other) noexcept
{
//amsstring_init(this); <-- init only on a constructor, otherwise memory leak
int nl,q;
nl = localstrlen(other);
if(nl>=0)
{
q = this->resize(nl);
if(q>=0)
{
//printf("DEBUG: q=%d, length=%d",q,length);
amsstrcpy_s(cstring,length+1,other);
cstring[length] = (ams_chartype) '\0';
}
else
{
this->resize(0);
}
}
else
if(this!=&other)
{
//already of zero size
this->length = other.length;
this->blank = other.blank;
this->cstring = other.cstring;
other.length = 0;
other.blank = '\0';
other.cstring = NULL;
}
return *this;
}
amsstring& amsstring::operator=(ams_chartype *other)
amsstring::amsstring(const ams_chartype *other)
{
//amsstring_init(this); <-- init only on a constructor, otherwise memory leak
int len = amsstring_strlen(other);
int res;
int I;
int nl,q;
nl = localstrlen(other);
if(nl>=0)
{
q = this->resize(nl);
if(q>=0)
{
//printf("DEBUG: q=%d, length=%d",q,length);
amsstrcpy_s(cstring,length+1,other);
cstring[length] = (ams_chartype) '\0';
}
else
_amsstring_init(this);
len = amsstring_strlen(other);
res = this->resize(len);
if(res==amsstring_success)
{
this->resize(0);
for(I=0;I<length;I++) cstring[I] = other[I];
cstring[length] = '\0';
blank = '\0';
}
return;
}
else
const amsstring& amsstring::operator=(const ams_chartype *other)
{
//already of zero size
int len = amsstring_strlen(other);
int res;
int I;
len = amsstring_strlen(other);
res = this->resize(len);
if(res==amsstring_success)
{
for(I=0;I<length;I++) cstring[I] = other[I];
cstring[length] = '\0';
blank = '\0';
}
return *this;
}
// const amsstring& amsstring::operator=(const ams_chartype *other) const
// {
// amsstring_init(this);
// int nl,q;
// nl = strlen(other);
// if(nl>=0)
// {
// q = this->resize(nl);
// if(q>=0)
// {
// printf("DEBUG: q=%d, length=%d",q,length);
// amsstrcpy_s(cstring,length+1,other);
// cstring[length] = (ams_chartype) '\0';
// }
// else
// {
// this->resize(0);
// }
// }
// else
// {
// //already of zero size
// }
// return *this;
// }
ams_chartype& amsstring::operator[](const int ind)
{
// if(ind<0 || ind>length-1)
// {
// blank = (ams_chartype) '\0';
// return blank;
// }
// else
// {
// return cstring[ind];
// }
if(ind<0 || ind>=(length+1))
{
blank = (ams_chartype) '\0';
@ -514,7 +370,7 @@ namespace ams
//to the null terminator (actual c string length)
void amsstring::shrinktofit()
{
int N = localstrlen(cstring);
int N = amsstring_strlen(cstring);
this->resize(N);
return;
}
@ -841,7 +697,7 @@ namespace ams
int I;
int ret = -1;
int J = 0;
int N = ams::localstrlen(str);
int N = ams::amsstring_strlen(str);
bool cs;
ams_chartype c1,c2;
@ -934,7 +790,7 @@ namespace ams
vsnprintf(buff,bufflen,formatstring,varargs);
va_end(varargs);
buff[bufflen] = '\0';
//int N = ams::localstrlen(buff);
//int N = ams::amsstring_strlen(buff);
*this = buff;
delete[] buff; buff=NULL;
@ -1219,7 +1075,7 @@ namespace ams
int cs;
int cnt;
ams_chartype c;
int N = localstrlen(delimitstr);
int N = amsstring_strlen(delimitstr);
if(lns!=NULL && delimitstr!=NULL)
{
@ -1297,7 +1153,7 @@ namespace ams
int cs;
int cnt;
ams_chartype c;
int N = localstrlen(delimitstr);
int N = amsstring_strlen(delimitstr);
if(lns!=NULL && delimitstr!=NULL)
{
@ -1548,7 +1404,7 @@ namespace ams
if(!feof(fp))
{
fgets(buff,BUFFSZ,fp);
N = ams::localstrlen(buff);
N = ams::amsstring_strlen(buff);
if((N-1)>=0&&(buff[N-1]=='\n'))
{
buff[N-1] = '\0';
@ -1559,7 +1415,7 @@ namespace ams
buff[N-1] = '\0';
N = N-1;
}
N = ams::localstrlen(buff);
N = ams::amsstring_strlen(buff);
*s = buff; //s->copy(buff);
}
else

@ -3,7 +3,7 @@
namespace ams
{
void amsstring3_basic_string_test1()
void amsstring4_basic_string_test1()
{
char q1,c;
unsigned char q2;
@ -23,7 +23,7 @@ namespace ams
printf("\nLF: %c After LF %c After LF2 \n",q2,q2);
}
void amsstring3_sscanf_test1()
void amsstring4_sscanf_test1()
{
char buf[500];
double d;
@ -104,7 +104,7 @@ namespace ams
printf("String %s reads as %1.4g\n",buf,d);
}
void amsstring3_basic_string_test2()
void amsstring4_basic_string_test2()
{
amsstring s1,s2;
//const amsstring s3; //don't do this - just accept that strings must be mutable
@ -156,7 +156,7 @@ namespace ams
}
void amsstring3_memoryleakcheck1()
void amsstring4_memoryleakcheck1()
{
amsstring q1,q2,q3;
int I;
@ -186,7 +186,7 @@ namespace ams
return;
}
void amsstring3_memoryleakcheck2()
void amsstring4_memoryleakcheck2()
{
int I;
amsstring q1;
@ -198,7 +198,7 @@ namespace ams
printf("q1=%s\n",q1.cstring);
}
void amsstring3_stringtests2()
void amsstring4_stringtests2()
{
amsstring q1,q2;
int I;
@ -272,7 +272,7 @@ namespace ams
return;
}
void amsstring3_test_find()
void amsstring4_test_find()
{
amsstring q1,q2,q3;
int I;
@ -308,7 +308,7 @@ namespace ams
return;
}
void amsstring3_test_splitlines()
void amsstring4_test_splitlines()
{
int I;
amsstring q1;
@ -328,7 +328,7 @@ namespace ams
return;
}
void amsstring3_test_split()
void amsstring4_test_split()
{
amsstring q1;
std::vector<amsstring> strs;
@ -393,7 +393,7 @@ namespace ams
return;
}
void amsstring3_test_strip()
void amsstring4_test_strip()
{
amsstring q1;
std::vector<amsstring> strs;
@ -419,7 +419,7 @@ namespace ams
return;
}
void amsstring3_test_freadwrite()
void amsstring4_test_freadwrite()
{
FILE *fp = NULL;
FILE *fp2 = NULL;
@ -457,7 +457,7 @@ namespace ams
return;
}
void amsstring3_test_concatenation_operators()
void amsstring4_test_concatenation_operators()
{
ams::amsstring a,b,c,d;

@ -579,7 +579,7 @@ namespace ams
cp->resize(len+1);
for(I=0;I<len;I++)
{
cp->at(I) = ams::randi(1,0x0010FFFF);
cp->at(I) = ams::rand::randint(1,0x0010FFFF+1);
}
cp->at(len) = 0;

@ -1,9 +1,26 @@
#include <amsstring4/amsstring4.hpp>
using namespace ams;
int main(int argc, char* argv[])
{
int ret = 0;
printf("ams string4 library tests.\n");
amsstring4_basic_string_test1();
amsstring4_sscanf_test1();
amsstring4_basic_string_test2();
amsstring4_memoryleakcheck1();
amsstring4_memoryleakcheck2();
amsstring4_stringtests2();
amsstring4_test_find();
amsstring4_test_splitlines();
amsstring4_test_split();
amsstring4_test_strip();
//amsstring4_test_freadwrite();
amsstring4_test_concatenation_operators();
return ret;
}
Loading…
Cancel
Save