Today I done / almost done writing fast & light C lib for strings.
What's implemented:
assign text to STR
append text to front/back to STR
insert text to given id to STR
Here is code:
typedef unsigned long STR_U32;
typedef struct STR
{
char *pszBuf;
STR_U32 uSize;
STR_U32 uMaxSize;
} STR;
#define STR_OK 0
#define STR_ALLOC_FAILED 1
void STR_Init(STR *this)
{
this->pszBuf = NULL;
this->uSize = 0;
this->uMaxSize = 0;
}
void STR_Free(STR *this)
{
if(this->pszBuf)
free(this->pszBuf);
this->pszBuf = NULL;
this->uSize = 0;
this->uMaxSize =0;
}
int STR_Set(STR *this, const char *pszText)
{
STR_U32 uLen;
char *pTmp;
// Get pszText lenth
uLen = 0;
pTmp = (char*)pszText;
while(*pTmp++) ++uLen;
// check that our buffer is long enought to accommodate given text
if(this->uMaxSize <= uLen)
{
this->pszBuf = malloc(uLen + 1);
if(!this->pszBuf) return STR_ALLOC_FAILED;
this->uMaxSize = uLen + 1;
}
// copy given text to our buffer
pTmp = this->pszBuf;
while(*pszText) *pTmp++ = *pszText++;
*pTmp = '\0';
this->uSize = uLen;
return STR_OK;
}
#define STR_GET(this) (this).pszBuf
#define STR_LEN(this) (this).uSize
const char *STR_Get(STR *this)
{
return this->pszBuf;
}
STR_U32 STR_Len(STR *this)
{
return this->uSize;
}
int STR_AppendE(STR *this, const char *pszText)
{
STR_U32 uLen;
char *pTmp;
// Get pszText lenth
uLen = 0;
pTmp = (char*)pszText;
while(*pTmp++) ++uLen;
// now add to given len our
uLen += this->uSize;
// check that our buffer is long enought to accommodate given text
if(this->uMaxSize <= uLen)
{
this->pszBuf = realloc(this->pszBuf, uLen + 1);
if(!this->pszBuf) return STR_ALLOC_FAILED;
this->uMaxSize = uLen + 1;
}
// copy given text to our buffer
pTmp = this->pszBuf + this->uSize;
while(*pszText) *pTmp++ = *pszText++;
*pTmp = '\0';
this->uSize = uLen;
return STR_OK;
}
int STR_AppendB(STR *this, const char *pszText)
{
STR_U32 uLen;
STR_U32 uTotalLen;
STR_U32 uTmp;
char *pTmp;
// Get pszText lenth
uLen = 0;
pTmp = (char*)pszText;
while(*pTmp++) ++uLen;
// now add to given len our
uTotalLen = this->uSize + uLen;
// check that our buffer is long enought to accommodate given text
if(this->uMaxSize <= uTotalLen)
{
this->pszBuf = realloc(this->pszBuf, uTotalLen + 1);
if(!this->pszBuf) return STR_ALLOC_FAILED;
this->uMaxSize = uTotalLen + 1;
}
// move the inside of our buffer fowoard uLen pos
uTmp = 1;
while(this->uSize--) this->pszBuf[uTotalLen - uTmp++] = this->pszBuf[this->uSize];
this->pszBuf[uTotalLen] = '\0';
// copy given text to our buffer
pTmp = this->pszBuf;
while(*pszText) *pTmp++ = *pszText++;
this->uSize = uTotalLen;
return STR_OK;
}
int STR_Insert(STR *this, const char *pszText, STR_U32 uId)
{
STR_U32 uLen;
STR_U32 uTotalLen;
STR_U32 uTmp;
char *pTmp;
if(uId > this->uSize) uId = this->uSize;
// Get pszText lenth
uLen = 0;
pTmp = (char*)pszText;
while(*pTmp++) ++uLen;
uTotalLen = this->uSize + uLen;
// check that our buffer is long enought to accommodate given text
if(this->uMaxSize <= uTotalLen)
{
this->pszBuf = realloc(this->pszBuf, uTotalLen + 1);
if(!this->pszBuf) return STR_ALLOC_FAILED;
this->uMaxSize = uTotalLen + 1;
}
// move all our buffer from the right side of id to end
uTmp = this->uMaxSize - 2;
while(uId != this->uSize) this->pszBuf[uTmp--] = this->pszBuf[--this->uSize];
this->pszBuf[this->uMaxSize-1] = '\0';
// copy given text
pTmp = this->pszBuf + uId;
while(uLen--) *pTmp++ = *pszText++;
return STR_OK;
}
exsample usage:
STR s;
STR_Init(&s);
STR_Set(&s, "abc");
STR_AppendE(&s, "def");
STR_AppendB(&s, "789");
will create "789abcdef" string that can be printed withs std puts
puts(STR_Get(&s));
or directly puts(s.pszBuf);
What do you guys think about it ?
Any sugestions or request?
What do you guys think about error handing in this mini lib?
Add some macro to handle all occured errors, or just quit when error occured?