This commit is contained in:
2025-06-02 20:47:27 -04:00
parent eb9ae4316f
commit b791fdf841
15 changed files with 214 additions and 346 deletions
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
+8 -13
View File
@@ -17,6 +17,9 @@
namespace ams 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 //wraps the functions strcpy_s and strncpy in a portable manner
//between linux and microsoft standard C libraries. //between linux and microsoft standard C libraries.
int amsstrcpy_s(char *dest, int size, const char *src); 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 class amsstring
{ {
public: public:
ams_chartype blank; // null terminator returned for accessing index out of bounds
ams_chartype *cstring; ams_chartype *cstring;
ams_chartype blank; // null terminator returned for accessing index out of bounds
int length; int length;
//length will be set to the length of the cstring not including the null terminating char //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();
amsstring(amsstring &other);
amsstring& operator=(amsstring &other);
amsstring(const amsstring &other); amsstring(const amsstring &other);
const amsstring& operator=(const amsstring &other); amsstring& operator=(const amsstring& other);
amsstring(amsstring &&other) noexcept;
amsstring(ams_chartype *other); amsstring& operator=(amsstring &&other) noexcept;
amsstring(const ams_chartype *other); 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);
//amsstring(int length, const ams_chartype initchar); //amsstring(int length, const ams_chartype initchar);
+12 -12
View File
@@ -4,20 +4,20 @@
namespace ams namespace ams
{ {
void amsstring3_basic_string_test1(); void amsstring4_basic_string_test1();
void amsstring3_sscanf_test1(); void amsstring4_sscanf_test1();
void amsstring3_basic_string_test2(); void amsstring4_basic_string_test2();
void amsstring3_memoryleakcheck1(); void amsstring4_memoryleakcheck1();
void amsstring3_memoryleakcheck2(); void amsstring4_memoryleakcheck2();
void amsstring3_stringtests2(); void amsstring4_stringtests2();
void amsstring3_test_find(); void amsstring4_test_find();
void amsstring3_test_splitlines(); void amsstring4_test_splitlines();
void amsstring3_test_split(); void amsstring4_test_split();
void amsstring3_test_strip(); void amsstring4_test_strip();
void amsstring3_test_freadwrite(); void amsstring4_test_freadwrite();
void amsstring3_test_concatenation_operators(); void amsstring4_test_concatenation_operators();
@@ -528,7 +528,7 @@ void test_base64encode_fuzztest()
bytes.resize(I); bytes.resize(I);
for(J=0;J<bytes.size();J++) for(J=0;J<bytes.size();J++)
{ {
bytes.data[J] = randd()*255; bytes.data[J] = ams::rand::rand()*255;
} }
base64encode(&bytes,&str); base64encode(&bytes,&str);
base64decode(&str,&bytes2,1); base64decode(&str,&bytes2,1);
+124 -268
View File
@@ -33,7 +33,7 @@ namespace ams
return ret; return ret;
} }
static int localstrlen(const ams_chartype *c) static int amsstring_strlen(const ams_chartype *c)
{ {
int I; int I;
if(c!=NULL) if(c!=NULL)
@@ -46,7 +46,6 @@ namespace ams
return I; return I;
//return strlen((const char*) c); //return strlen((const char*) c);
} }
else else
return 0; return 0;
} }
@@ -54,8 +53,8 @@ namespace ams
bool amsstrneq(const ams_chartype *s1, const ams_chartype *s2, const bool casesens=1) bool amsstrneq(const ams_chartype *s1, const ams_chartype *s2, const bool casesens=1)
{ {
bool ret = 0; bool ret = 0;
int N1 = localstrlen(s1); int N1 = amsstring_strlen(s1);
int N2 = localstrlen(s2); int N2 = amsstring_strlen(s2);
bool b1,b2; bool b1,b2;
if(N1==N2) 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->blank = (ams_chartype) '\0';
str->cstring = NULL; str->cstring = NULL;
str->cstring = new(std::nothrow) ams_chartype[1];
str->cstring[0] = (ams_chartype) '\0';
str->length = 0; 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';
}
return; return;
} }
amsstring::amsstring() 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; return;
} }
@@ -126,320 +129,173 @@ namespace ams
return length; return length;
} }
//Rewrite amsstring::resize() - valgrind is still complaining! int amsstring::resize(int _newlen)
int amsstring::resize(const int newlen)
{ {
int ret = 0; int ret = amsstring_success;
int I = 0; ams_chartype *newcstring = NULL;
ams_chartype *newbuff = NULL; int I;
if(newlen == length) _newlen = (_newlen<0) ? 0 : _newlen;
newcstring = new(std::nothrow) ams_chartype[_newlen+1];
if(newcstring==NULL)
{ {
//sizes are the same, do nothing ret = amsstring_failure;
ret = 1;
return ret; return ret;
} }
if(newlen<=0) //if new length <0
{
newbuff = new(std::nothrow) ams_chartype[1];
if(newbuff==NULL)
{
ret = -1;
return ret;
}
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)
{
ret = -1;
return ret;
}
//Copy old data
for(I=0;I<length && I<newlen;I++)
{
if(cstring!=NULL) if(cstring!=NULL)
{ {
newbuff[I] = cstring[I]; for(I=0;I<(_newlen+1) && I<(length+1);I++)
}
else
{ {
newbuff[I] = '\0'; newcstring[I] = cstring[I];
} }
} }
for(I=length;I<newlen;I++) for(I=length;I<_newlen+1;I++)
{ {
newbuff[I] = '\0'; newcstring[I] = (ams_chartype) '\0';
} }
newbuff[newlen] = '\0';
if(cstring!=NULL) {delete[] cstring; cstring = NULL;} newcstring[_newlen] = '\0';
cstring = newbuff;
length = newlen;
ret = 1; if(cstring!=NULL)
{
delete[] cstring;
cstring=NULL;
}
blank = (ams_chartype) '\0';
cstring = newcstring;
length = _newlen;
return ret; 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::amsstring(const amsstring &other)
{ {
//amsstring_init(this); int I;
blank = (ams_chartype) '\0'; int res;
cstring = NULL; _amsstring_init(this);
cstring = new(std::nothrow) ams_chartype[1];
cstring[0] = (ams_chartype) '\0';
length = 0;
if(this!=&other) 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; return;
} }
amsstring::amsstring(amsstring &other) amsstring& amsstring::operator=(const amsstring& other)
{ {
//amsstring_init(this); int I;
int res;
blank = (ams_chartype) '\0';
cstring = NULL;
cstring = new(std::nothrow) ams_chartype[1];
cstring[0] = (ams_chartype) '\0';
length = 0;
if(this!=&other) 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;
} }
const amsstring& amsstring::operator=(const 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; return *this;
} }
amsstring& amsstring::operator=(amsstring &other) amsstring::amsstring(amsstring &&other) noexcept
{ {
this->length = 0;
this->blank = '\0';
this->cstring = NULL;
if(this!=&other) if(this!=&other)
{ {
this->resize(other.length); this->length = other.length;
amsstrcpy_s(cstring,length+1,other.cstring); this->blank = other.blank;
cstring[length] = (ams_chartype) '\0'; this->cstring = other.cstring;
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) other.length = 0;
// //then resize to string's size other.blank = '\0';
// if(N<length) other.cstring = NULL;
// {
// this->resize(N);
// }
} }
return *this;
}
amsstring::amsstring(ams_chartype *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 = other;
return; return;
} }
amsstring& amsstring::operator=(amsstring &&other) noexcept
{
if(this!=&other)
{
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(const ams_chartype *other) amsstring::amsstring(const ams_chartype *other)
{ {
//amsstring_init(this); int len = amsstring_strlen(other);
blank = (ams_chartype) '\0'; int res;
cstring = NULL; int I;
cstring = new(std::nothrow) ams_chartype[1];
cstring[0] = (ams_chartype) '\0';
length = 0;
*this = other; _amsstring_init(this);
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; return;
} }
const amsstring& amsstring::operator=(const ams_chartype *other) const amsstring& amsstring::operator=(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; len = amsstring_strlen(other);
nl = localstrlen(other); res = this->resize(len);
if(nl>=0) if(res==amsstring_success)
{ {
q = this->resize(nl); for(I=0;I<length;I++) cstring[I] = other[I];
if(q>=0) cstring[length] = '\0';
{ blank = '\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; return *this;
} }
amsstring& amsstring::operator=(ams_chartype *other)
{
//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
{
//already of zero size
}
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) 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)) if(ind<0 || ind>=(length+1))
{ {
blank = (ams_chartype) '\0'; blank = (ams_chartype) '\0';
@@ -514,7 +370,7 @@ namespace ams
//to the null terminator (actual c string length) //to the null terminator (actual c string length)
void amsstring::shrinktofit() void amsstring::shrinktofit()
{ {
int N = localstrlen(cstring); int N = amsstring_strlen(cstring);
this->resize(N); this->resize(N);
return; return;
} }
@@ -841,7 +697,7 @@ namespace ams
int I; int I;
int ret = -1; int ret = -1;
int J = 0; int J = 0;
int N = ams::localstrlen(str); int N = ams::amsstring_strlen(str);
bool cs; bool cs;
ams_chartype c1,c2; ams_chartype c1,c2;
@@ -934,7 +790,7 @@ namespace ams
vsnprintf(buff,bufflen,formatstring,varargs); vsnprintf(buff,bufflen,formatstring,varargs);
va_end(varargs); va_end(varargs);
buff[bufflen] = '\0'; buff[bufflen] = '\0';
//int N = ams::localstrlen(buff); //int N = ams::amsstring_strlen(buff);
*this = buff; *this = buff;
delete[] buff; buff=NULL; delete[] buff; buff=NULL;
@@ -1219,7 +1075,7 @@ namespace ams
int cs; int cs;
int cnt; int cnt;
ams_chartype c; ams_chartype c;
int N = localstrlen(delimitstr); int N = amsstring_strlen(delimitstr);
if(lns!=NULL && delimitstr!=NULL) if(lns!=NULL && delimitstr!=NULL)
{ {
@@ -1297,7 +1153,7 @@ namespace ams
int cs; int cs;
int cnt; int cnt;
ams_chartype c; ams_chartype c;
int N = localstrlen(delimitstr); int N = amsstring_strlen(delimitstr);
if(lns!=NULL && delimitstr!=NULL) if(lns!=NULL && delimitstr!=NULL)
{ {
@@ -1548,7 +1404,7 @@ namespace ams
if(!feof(fp)) if(!feof(fp))
{ {
fgets(buff,BUFFSZ,fp); fgets(buff,BUFFSZ,fp);
N = ams::localstrlen(buff); N = ams::amsstring_strlen(buff);
if((N-1)>=0&&(buff[N-1]=='\n')) if((N-1)>=0&&(buff[N-1]=='\n'))
{ {
buff[N-1] = '\0'; buff[N-1] = '\0';
@@ -1559,7 +1415,7 @@ namespace ams
buff[N-1] = '\0'; buff[N-1] = '\0';
N = N-1; N = N-1;
} }
N = ams::localstrlen(buff); N = ams::amsstring_strlen(buff);
*s = buff; //s->copy(buff); *s = buff; //s->copy(buff);
} }
else else
+12 -12
View File
@@ -3,7 +3,7 @@
namespace ams namespace ams
{ {
void amsstring3_basic_string_test1() void amsstring4_basic_string_test1()
{ {
char q1,c; char q1,c;
unsigned char q2; unsigned char q2;
@@ -23,7 +23,7 @@ namespace ams
printf("\nLF: %c After LF %c After LF2 \n",q2,q2); printf("\nLF: %c After LF %c After LF2 \n",q2,q2);
} }
void amsstring3_sscanf_test1() void amsstring4_sscanf_test1()
{ {
char buf[500]; char buf[500];
double d; double d;
@@ -104,7 +104,7 @@ namespace ams
printf("String %s reads as %1.4g\n",buf,d); printf("String %s reads as %1.4g\n",buf,d);
} }
void amsstring3_basic_string_test2() void amsstring4_basic_string_test2()
{ {
amsstring s1,s2; amsstring s1,s2;
//const amsstring s3; //don't do this - just accept that strings must be mutable //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; amsstring q1,q2,q3;
int I; int I;
@@ -186,7 +186,7 @@ namespace ams
return; return;
} }
void amsstring3_memoryleakcheck2() void amsstring4_memoryleakcheck2()
{ {
int I; int I;
amsstring q1; amsstring q1;
@@ -198,7 +198,7 @@ namespace ams
printf("q1=%s\n",q1.cstring); printf("q1=%s\n",q1.cstring);
} }
void amsstring3_stringtests2() void amsstring4_stringtests2()
{ {
amsstring q1,q2; amsstring q1,q2;
int I; int I;
@@ -272,7 +272,7 @@ namespace ams
return; return;
} }
void amsstring3_test_find() void amsstring4_test_find()
{ {
amsstring q1,q2,q3; amsstring q1,q2,q3;
int I; int I;
@@ -308,7 +308,7 @@ namespace ams
return; return;
} }
void amsstring3_test_splitlines() void amsstring4_test_splitlines()
{ {
int I; int I;
amsstring q1; amsstring q1;
@@ -328,7 +328,7 @@ namespace ams
return; return;
} }
void amsstring3_test_split() void amsstring4_test_split()
{ {
amsstring q1; amsstring q1;
std::vector<amsstring> strs; std::vector<amsstring> strs;
@@ -393,7 +393,7 @@ namespace ams
return; return;
} }
void amsstring3_test_strip() void amsstring4_test_strip()
{ {
amsstring q1; amsstring q1;
std::vector<amsstring> strs; std::vector<amsstring> strs;
@@ -419,7 +419,7 @@ namespace ams
return; return;
} }
void amsstring3_test_freadwrite() void amsstring4_test_freadwrite()
{ {
FILE *fp = NULL; FILE *fp = NULL;
FILE *fp2 = NULL; FILE *fp2 = NULL;
@@ -457,7 +457,7 @@ namespace ams
return; return;
} }
void amsstring3_test_concatenation_operators() void amsstring4_test_concatenation_operators()
{ {
ams::amsstring a,b,c,d; ams::amsstring a,b,c,d;
+1 -1
View File
@@ -579,7 +579,7 @@ namespace ams
cp->resize(len+1); cp->resize(len+1);
for(I=0;I<len;I++) 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; cp->at(len) = 0;
+17
View File
@@ -1,9 +1,26 @@
#include <amsstring4/amsstring4.hpp> #include <amsstring4/amsstring4.hpp>
using namespace ams;
int main(int argc, char* argv[]) int main(int argc, char* argv[])
{ {
int ret = 0; int ret = 0;
printf("ams string4 library tests.\n"); 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; return ret;
} }