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
{
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);
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!
const amsstring& operator=(const ams_chartype *other);
//
//amsstring(int length);
//amsstring(int length, const ams_chartype initchar);
+12 -12
View File
@@ -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 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 amsstring3_test_splitlines();
void amsstring3_test_split();
void amsstring3_test_strip();
void amsstring3_test_freadwrite();
void amsstring4_test_splitlines();
void amsstring4_test_split();
void amsstring4_test_strip();
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);
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);
+163 -307
View File
@@ -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->cstring = new(std::nothrow) ams_chartype[1];
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;
}
return;
}
amsstring::amsstring()
{
//amsstring_init(this);
blank = (ams_chartype) '\0';
cstring = NULL;
cstring = new(std::nothrow) ams_chartype[1];
cstring[0] = (ams_chartype) '\0';
length = 0;
_amsstring_init(this);
return;
}
@@ -125,321 +128,174 @@ 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;
if(newlen == length)
int ret = amsstring_success;
ams_chartype *newcstring = NULL;
int I;
_newlen = (_newlen<0) ? 0 : _newlen;
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;
}
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)
{
newbuff[I] = cstring[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;}
cstring = newbuff;
length = newlen;
ret = 1;
newcstring[_newlen] = '\0';
if(cstring!=NULL)
{
delete[] cstring;
cstring=NULL;
}
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;
if(this!=&other)
{
*this=other;
int I;
int res;
_amsstring_init(this);
if(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);
blank = (ams_chartype) '\0';
cstring = NULL;
cstring = new(std::nothrow) ams_chartype[1];
cstring[0] = (ams_chartype) '\0';
length = 0;
if(this!=&other)
{
*this=other;
int I;
int res;
if(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 *this;
}
const amsstring& amsstring::operator=(const amsstring &other)
amsstring::amsstring(amsstring &&other) noexcept
{
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;
this->length = 0;
this->blank = '\0';
this->cstring = NULL;
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;
}
amsstring& amsstring::operator=(amsstring &other)
amsstring& amsstring::operator=(amsstring &&other) noexcept
{
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;
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(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;
}
amsstring::amsstring(const 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;
int len = amsstring_strlen(other);
int res;
int I;
_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;
}
const amsstring& amsstring::operator=(const 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;
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;
}
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)
{
// 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
+12 -12
View File
@@ -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;
+1 -1
View File
@@ -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;
+17
View File
@@ -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;
}