summaryrefslogtreecommitdiffstats
path: root/stringbuf.c
diff options
context:
space:
mode:
Diffstat (limited to 'stringbuf.c')
-rwxr-xr-xstringbuf.c121
1 files changed, 100 insertions, 21 deletions
diff --git a/stringbuf.c b/stringbuf.c
index 85763f27..1f6d6316 100755
--- a/stringbuf.c
+++ b/stringbuf.c
@@ -343,6 +343,9 @@ rsRetVal rsCStrTrimTrailingWhiteSpace(rsCStrObj *pThis)
* faster in the majority of cases, simply because it can
* rely on StrLen.
* rgerhards 2005-09-19
+ * fixed bug, in which only the last byte was actually compared
+ * in equal-size strings.
+ * rgerhards, 2005-09-26
*/
int rsCStrCStrCmp(rsCStrObj *pCS1, rsCStrObj *pCS2)
{
@@ -351,37 +354,113 @@ int rsCStrCStrCmp(rsCStrObj *pCS1, rsCStrObj *pCS2)
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 { /* we now have two non-empty strings of equal
+ * length, so we need to actually check if they
+ * are equal.
+ */
+ register int i;
+ for(i = 0 ; i < pCS1->iStrLen ; ++i) {
+ if(pCS1->pBuf[i] != pCS2->pBuf[i])
+ return pCS1->pBuf[i] - pCS2->pBuf[i];
+ }
+ /* if we arrive here, the strings are equal */
+ return 0;
+ }
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
+
+/* compare a rsCStr object with a classical sz string. This function
+ * is almost identical to rsCStrZsStrCmp(), but it also takes an offset
+ * to the CStr object from where the comparison is to start.
+ * I have thought quite a while if it really makes sense to more or
+ * less duplicate the code. After all, if you call it with an offset of
+ * zero, the functionality is exactly the same. So it looks natural to
+ * just have a single function. However, supporting the offset requires
+ * some (few) additional integer operations. While they are few, they
+ * happen at places in the code that is run very frequently. All in all,
+ * I have opted for performance and thus duplicated the code. I hope
+ * this is a good, or at least acceptable, compromise.
+ * rgerhards, 2005-09-26
+ * This function also has an offset-pointer which allows to
+ * specify *where* the compare operation should begin in
+ * the CStr. If everything is to be compared, it must be set
+ * to 0. If some leading bytes are to be skipped, it must be set
+ * to the first index that is to be compared. It must not be
+ * set higher than the string length (this is considered a
+ * program bug and will lead to unpredictable results and program aborts).
+ * rgerhards 2005-09-26
*/
-int rsCStrSzCmp(rsCStrObj *pCStr, char *sz)
+int rsCStrOffsetSzStrCmp(rsCStrObj *pCS1, int iOffset, char *psz, int iLenSz)
{
- int iszLen;
-
- rsCHECKVALIDOBJECT(pCStr, OIDrsCStr);
- assert(sz != NULL);
+ rsCHECKVALIDOBJECT(pCS1, OIDrsCStr);
+ assert(iOffset >= 0);
+ assert(iOffset < pCS1->iStrLen);
+ assert(psz != NULL);
+ assert(iLenSz == strlen(psz)); /* just make sure during debugging! */
+ if((pCS1->iStrLen - iOffset) == iLenSz) {
+ /* we are using iLenSz below, because the lengths
+ * are equal and iLenSz is faster to access
+ */
+ if(iLenSz == 0)
+ return 0; /* zero-sized strings are equal ;) */
+ else { /* we now have two non-empty strings of equal
+ * length, so we need to actually check if they
+ * are equal.
+ */
+ register int i;
+ for(i = 0 ; i < iLenSz ; ++i) {
+ if(pCS1->pBuf[i+iOffset] != psz[i])
+ return pCS1->pBuf[i+iOffset] - psz[i];
+ }
+ /* if we arrive here, the strings are equal */
+ return 0;
+ }
+ }
+ else
+ return pCS1->iStrLen - iOffset - iLenSz;
+}
- 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...
+/* compare a rsCStr object with a classical sz string.
+ * Just like rsCStrCStrCmp, just for a different data type.
+ * There must not only the sz string but also its length be
+ * provided. If the caller does not know the length he can
+ * call with
+ * rsCstrSzStrCmp(pCS, psz, strlen(psz));
+ * we are not doing the strlen() ourselfs as the caller might
+ * already know the length and in such cases we can save the
+ * overhead of doing it one more time (strelen() is costly!).
+ * The bottom line is that the provided length MUST be correct!
+ * The to sz string pointer must not be NULL!
+ * rgerhards 2005-09-26
+ */
+int rsCStrSzStrCmp(rsCStrObj *pCS1, char *psz, int iLenSz)
+{
+ rsCHECKVALIDOBJECT(pCS1, OIDrsCStr);
+ assert(psz != NULL);
+ assert(iLenSz == strlen(psz)); /* just make sure during debugging! */
+ if(pCS1->iStrLen == iLenSz)
+ /* we are using iLenSz below, because the lengths
+ * are equal and iLenSz is faster to access
*/
- if(iszLen == 0)
- return 0; /* zero-sized string are equal ;) */
- else
- return pCStr->pBuf[iszLen - 1] - sz[iszLen - 1];
+ if(iLenSz == 0)
+ return 0; /* zero-sized strings are equal ;) */
+ else { /* we now have two non-empty strings of equal
+ * length, so we need to actually check if they
+ * are equal.
+ */
+ register int i;
+ for(i = 0 ; i < iLenSz ; ++i) {
+ if(pCS1->pBuf[i] != psz[i])
+ return pCS1->pBuf[i] - psz[i];
+ }
+ /* if we arrive here, the strings are equal */
+ return 0;
+ }
else
- return pCStr->iStrLen - iszLen;
+ return pCS1->iStrLen - iLenSz;
}