summaryrefslogtreecommitdiffstats
path: root/stringbuf.c
diff options
context:
space:
mode:
Diffstat (limited to 'stringbuf.c')
-rwxr-xr-xstringbuf.c139
1 files changed, 107 insertions, 32 deletions
diff --git a/stringbuf.c b/stringbuf.c
index aa35a6c7..ccd2c184 100755
--- a/stringbuf.c
+++ b/stringbuf.c
@@ -38,7 +38,6 @@ rsCStrObj *rsCStrConstruct(void)
pThis->pBuf = NULL;
pThis->pszBuf = NULL;
pThis->iBufSize = 0;
- pThis->iBufPtr = 0;
pThis->iStrLen = 0;
pThis->iAllocIncrement = STRINGBUF_ALLOC_INCREMENT;
@@ -125,7 +124,7 @@ rsRetVal rsCStrAppendChar(rsCStrObj *pThis, char c)
rsCHECKVALIDOBJECT(pThis, OIDrsCStr);
- if(pThis->iBufPtr >= pThis->iBufSize)
+ if(pThis->iStrLen >= pThis->iBufSize)
{ /* need more memory! */
if((pNewBuf = (char*) malloc((pThis->iBufSize + pThis->iAllocIncrement) * sizeof(char))) == NULL)
return RS_RET_OUT_OF_MEMORY;
@@ -138,13 +137,59 @@ rsRetVal rsCStrAppendChar(rsCStrObj *pThis, char c)
}
/* ok, when we reach this, we have sufficient memory */
- *(pThis->pBuf + pThis->iBufPtr++) = c;
- pThis->iStrLen++;
+ *(pThis->pBuf + pThis->iStrLen++) = c;
+
+ /* check if we need to invalidate an sz representation! */
+ if(pThis->pszBuf != NULL) {
+ free(pThis->pszBuf);
+ pThis->pszBuf = NULL;
+ }
return RS_RET_OK;
}
+/* Converts the CStr object to a classical zero-terminated C string
+ * and returns that string. The caller must not free it and must not
+ * destroy the CStr object as long as the ascii string is used.
+ * rgerhards, 2005-09-15
+ */
+char* rsCStrGetSzStr(rsCStrObj *pThis)
+{
+ int i;
+
+ rsCHECKVALIDOBJECT(pThis, OIDrsCStr);
+
+ if(pThis->pBuf != NULL)
+ if(pThis->pszBuf == NULL) {
+ /* we do not yet have a usable sz version - so create it... */
+ if((pThis->pszBuf = malloc(pThis->iStrLen + 1 * sizeof(char))) == NULL) {
+ /* TODO: think about what to do - so far, I have no bright
+ * idea... rgerhards 2005-09-07
+ */
+ }
+ else { /* we can create the sz String */
+ /* now copy it while doing a sanity check. The string might contain a
+ * \0 byte. There is no way how a sz string can handle this. For
+ * the time being, we simply replace it with space - something that
+ * could definitely be improved (TODO).
+ * 2005-09-15 rgerhards
+ */
+ for(i = 0 ; i < pThis->iStrLen ; ++i) {
+ if(pThis->pBuf[i] == '\0')
+ pThis->pszBuf[i] = ' ';
+ else
+ pThis->pszBuf[i] = pThis->pBuf[i];
+ }
+ /* write terminator... */
+ pThis->pszBuf[i] = '\0';
+ }
+ }
+
+ return(pThis->pszBuf);
+}
+
+
/* Converts the CStr object to a classical zero-terminated C string,
* returns that string and destroys the CStr object. The returned string
* MUST be freed by the caller. The function might return NULL if
@@ -162,40 +207,15 @@ rsRetVal rsCStrAppendChar(rsCStrObj *pThis, char c)
char* rsCStrConvSzStrAndDestruct(rsCStrObj *pThis)
{
char* pRetBuf;
- int i;
rsCHECKVALIDOBJECT(pThis, OIDrsCStr);
- if(pThis->pszBuf == NULL) {
- /* we do not yet have a usable sz version - so create it... */
- if((pThis->pszBuf = malloc(pThis->iStrLen + 1 * sizeof(char))) == NULL) {
- /* TODO: think about what to do - so far, I have no bright
- * idea... rgerhards 2005-09-07
- */
- }
- else {
- /* we can create the sz String */
- if(pThis->pBuf != NULL)
- memcpy(pThis->pszBuf, pThis->pBuf, pThis->iStrLen);
- *(pThis->pszBuf + pThis->iStrLen) = '\0';
- }
- }
- /* we now need to do a sanity check. The string mgiht contain a
- * \0 byte. There is no way how a sz string can handle this. For
- * the time being, we simply replace it with space - something that
- * could definitely be improved (TODO).
- * 2005-09-09 rgerhards
- */
- for(i = 0 ; i < pThis->iStrLen ; ++i) {
- if(*(pThis->pszBuf + i) == '\0')
- *(pThis->pszBuf + i) = ' ';
- }
+ pRetBuf = rsCStrGetSzStr(pThis);
/* We got it, now free the object ourselfs. Please note
* that we can NOT use the rsCStrDestruct function as it would
* also free the sz String buffer, which we pass on to the user.
*/
- pRetBuf = pThis->pszBuf;
if(pThis->pBuf != NULL)
free(pThis->pBuf);
RSFREEOBJ(pThis);
@@ -229,7 +249,6 @@ rsRetVal rsCStrFinish(rsCStrObj *pThis)
/* here, we need to do ... nothing ;)
*/
# endif
-
return RS_RET_OK;
}
@@ -268,6 +287,15 @@ rsRetVal rsCStrTruncate(rsCStrObj *pThis, int nTrunc)
pThis->iStrLen -= nTrunc;
+ if(pThis->pszBuf != NULL) {
+ /* in this case, we adjust the psz representation
+ * by writing a new \0 terminator - this is by far
+ * the fastest way and outweights the additional memory
+ * required. 2005-9-19 rgerhards.
+ */
+ pThis->pszBuf[pThis->iStrLen] = '\0';
+ }
+
return RS_RET_OK;
}
@@ -281,7 +309,7 @@ rsRetVal rsCStrTrimTrailingWhiteSpace(rsCStrObj *pThis)
i = pThis->iStrLen;
pC = pThis->pBuf + i - 1;
- while(i > 0 && !isspace(*pC)) {
+ while(i > 0 && isspace(*pC)) {
--pC;
--i;
}
@@ -291,6 +319,53 @@ rsRetVal rsCStrTrimTrailingWhiteSpace(rsCStrObj *pThis)
return RS_RET_OK;
}
+/* compare two string objects - works like strcmp(), but operates
+ * on CStr objects. Please note that this version here is
+ * faster in the majority of cases, simply because it can
+ * rely on StrLen.
+ * rgerhards 2005-09-19
+ */
+int rsCStrCStrCmp(rsCStrObj *pCS1, rsCStrObj *pCS2)
+{
+ rsCHECKVALIDOBJECT(pCS1, OIDrsCStr);
+ rsCHECKVALIDOBJECT(pCS2, OIDrsCStr);
+ if(pCS1->iStrLen == pCS2->iStrLen)
+ if(pCS1->iStrLen == 0)
+ return 0; /* zero-sized string are equal ;) */
+ else
+ return pCS1->pBuf[pCS1->iStrLen - 1]
+ - pCS2->pBuf[pCS2->iStrLen - 1];
+ else
+ return pCS1->iStrLen - pCS2->iStrLen;
+}
+
+/* compare a string object with a classical zero-terminated C-string.
+ * this function is primarily meant to support comparisons with constants.
+ * It should not be used for variables (except with a very good reason).
+ * rgerhards 2005-09-19
+ */
+int rsCStrSzCmp(rsCStrObj *pCStr, char *sz)
+{
+ int iszLen;
+
+ rsCHECKVALIDOBJECT(pCStr, OIDrsCStr);
+ assert(sz != NULL);
+
+ iszLen = strlen(sz);
+
+ if(pCStr->iStrLen == iszLen)
+ /* note: we are using iszLen below, because it doesn't matter
+ * and the simple integer is faster to derefence...
+ */
+ if(iszLen == 0)
+ return 0; /* zero-sized string are equal ;) */
+ else
+ return pCStr->pBuf[iszLen - 1] - sz[iszLen - 1];
+ else
+ return pCStr->iStrLen - iszLen;
+}
+
+
/*
* Local variables:
* c-indent-level: 8