summaryrefslogtreecommitdiffstats
path: root/runtime
diff options
context:
space:
mode:
authorRainer Gerhards <rgerhards@adiscon.com>2009-06-16 11:36:05 +0200
committerRainer Gerhards <rgerhards@adiscon.com>2009-06-16 11:36:05 +0200
commitf7579e68a67364c8040966be57c2eae4c9550ee5 (patch)
treeb0e0eb7e54f6fb5db3b6600d0f3fe72a4a0f271e /runtime
parent015d17ca70e81ad998e32cdfeed3cd925fd7dedc (diff)
downloadrsyslog-f7579e68a67364c8040966be57c2eae4c9550ee5.tar.gz
rsyslog-f7579e68a67364c8040966be57c2eae4c9550ee5.tar.xz
rsyslog-f7579e68a67364c8040966be57c2eae4c9550ee5.zip
done various optimizations to the stringbuf and its users
Diffstat (limited to 'runtime')
-rw-r--r--runtime/cfsysline.c12
-rw-r--r--runtime/conf.c40
-rw-r--r--runtime/ctok.c4
-rw-r--r--runtime/datetime.c5
-rw-r--r--runtime/msg.c30
-rw-r--r--runtime/msg.h4
-rw-r--r--runtime/nsd_gtls.c8
-rw-r--r--runtime/obj.c6
-rw-r--r--runtime/parser.c19
-rw-r--r--runtime/stream.c2
-rw-r--r--runtime/stringbuf.c221
-rw-r--r--runtime/stringbuf.h27
-rw-r--r--runtime/vm.c2
-rw-r--r--runtime/vmop.c2
14 files changed, 152 insertions, 230 deletions
diff --git a/runtime/cfsysline.c b/runtime/cfsysline.c
index e1e4a6a4..0fb4247d 100644
--- a/runtime/cfsysline.c
+++ b/runtime/cfsysline.c
@@ -462,7 +462,7 @@ getWord(uchar **pp, cstr_t **ppStrB)
ASSERT(*pp != NULL);
ASSERT(ppStrB != NULL);
- CHKiRet(rsCStrConstruct(ppStrB));
+ CHKiRet(cstrConstruct(ppStrB));
skipWhiteSpace(pp); /* skip over any whitespace */
@@ -470,9 +470,9 @@ getWord(uchar **pp, cstr_t **ppStrB)
p = *pp;
while(*p && !isspace((int) *p)) {
- CHKiRet(rsCStrAppendChar(*ppStrB, *p++));
+ CHKiRet(cstrAppendChar(*ppStrB, *p++));
}
- CHKiRet(rsCStrFinish(*ppStrB));
+ CHKiRet(cstrFinalize(*ppStrB));
*pp = p;
@@ -506,7 +506,7 @@ static rsRetVal doGetWord(uchar **pp, rsRetVal (*pSetHdlr)(void*, uchar*), void
ASSERT(*pp != NULL);
CHKiRet(getWord(pp, &pStrB));
- CHKiRet(rsCStrConvSzStrAndDestruct(pStrB, &pNewVal, 0));
+ CHKiRet(cstrConvSzStrAndDestruct(pStrB, &pNewVal, 0));
pStrB = NULL;
/* we got the word, now set it */
@@ -525,7 +525,7 @@ static rsRetVal doGetWord(uchar **pp, rsRetVal (*pSetHdlr)(void*, uchar*), void
finalize_it:
if(iRet != RS_RET_OK) {
if(pStrB != NULL)
- rsCStrDestruct(&pStrB);
+ cstrDestruct(&pStrB);
}
RETiRet;
@@ -548,7 +548,7 @@ doSyslogName(uchar **pp, rsRetVal (*pSetHdlr)(void*, int), void *pVal, syslogNam
ASSERT(*pp != NULL);
CHKiRet(getWord(pp, &pStrB)); /* get word */
- iNewVal = decodeSyslogName(rsCStrGetSzStr(pStrB), pNameTable);
+ iNewVal = decodeSyslogName(cstrGetSzStr(pStrB), pNameTable);
if(pSetHdlr == NULL) {
/* we should set value directly to var */
diff --git a/runtime/conf.c b/runtime/conf.c
index 7cdcf5ec..65fc66f1 100644
--- a/runtime/conf.c
+++ b/runtime/conf.c
@@ -526,17 +526,15 @@ rsRetVal cflineParseTemplateName(uchar** pp, omodStringRequest_t *pOMSR, int iEn
tplName = (uchar*) strdup((char*)dfltTplName);
} else {
/* template specified, pick it up */
- if(rsCStrConstruct(&pStrB) != RS_RET_OK) {
- ABORT_FINALIZE(RS_RET_OUT_OF_MEMORY);
- }
+ CHKiRet(cstrConstruct(&pStrB));
/* now copy the string */
while(*p && *p != '#' && !isspace((int) *p)) {
- CHKiRet(rsCStrAppendChar(pStrB, *p));
+ CHKiRet(cstrAppendChar(pStrB, *p));
++p;
}
- CHKiRet(rsCStrFinish(pStrB));
- CHKiRet(rsCStrConvSzStrAndDestruct(pStrB, &tplName, 0));
+ CHKiRet(cstrFinalize(pStrB));
+ CHKiRet(cstrConvSzStrAndDestruct(pStrB, &tplName, 0));
}
iRet = OMSRsetEntry(pOMSR, iEntry, tplName, iTplOpts);
@@ -925,7 +923,7 @@ static rsRetVal cflineProcessPropFilter(uchar **pline, register selector_t *f)
*/
static rsRetVal cflineProcessHostSelector(uchar **pline)
{
- rsRetVal iRet;
+ DEFiRet;
ASSERT(pline != NULL);
ASSERT(*pline != NULL);
@@ -951,21 +949,20 @@ static rsRetVal cflineProcessHostSelector(uchar **pline)
dbgprintf("resetting BSD-like hostname filter\n");
eDfltHostnameCmpMode = HN_NO_COMP;
if(pDfltHostnameCmp != NULL) {
- if((iRet = rsCStrSetSzStr(pDfltHostnameCmp, NULL)) != RS_RET_OK)
- return(iRet);
+ CHKiRet(rsCStrSetSzStr(pDfltHostnameCmp, NULL));
}
} else {
dbgprintf("setting BSD-like hostname filter to '%s'\n", *pline);
if(pDfltHostnameCmp == NULL) {
/* create string for parser */
- if((iRet = rsCStrConstructFromszStr(&pDfltHostnameCmp, *pline)) != RS_RET_OK)
- return(iRet);
+ CHKiRet(rsCStrConstructFromszStr(&pDfltHostnameCmp, *pline));
} else { /* string objects exists, just update... */
- if((iRet = rsCStrSetSzStr(pDfltHostnameCmp, *pline)) != RS_RET_OK)
- return(iRet);
+ CHKiRet(rsCStrSetSzStr(pDfltHostnameCmp, *pline));
}
}
- return RS_RET_OK;
+
+finalize_it:
+ RETiRet;
}
@@ -976,7 +973,7 @@ static rsRetVal cflineProcessHostSelector(uchar **pline)
*/
static rsRetVal cflineProcessTagSelector(uchar **pline)
{
- rsRetVal iRet;
+ DEFiRet;
ASSERT(pline != NULL);
ASSERT(*pline != NULL);
@@ -995,21 +992,20 @@ static rsRetVal cflineProcessTagSelector(uchar **pline)
if(**pline != '\0' && **pline == '*' && *(*pline+1) == '\0') {
dbgprintf("resetting programname filter\n");
if(pDfltProgNameCmp != NULL) {
- if((iRet = rsCStrSetSzStr(pDfltProgNameCmp, NULL)) != RS_RET_OK)
- return(iRet);
+ CHKiRet(rsCStrSetSzStr(pDfltProgNameCmp, NULL));
}
} else {
dbgprintf("setting programname filter to '%s'\n", *pline);
if(pDfltProgNameCmp == NULL) {
/* create string for parser */
- if((iRet = rsCStrConstructFromszStr(&pDfltProgNameCmp, *pline)) != RS_RET_OK)
- return(iRet);
+ CHKiRet(rsCStrConstructFromszStr(&pDfltProgNameCmp, *pline));
} else { /* string objects exists, just update... */
- if((iRet = rsCStrSetSzStr(pDfltProgNameCmp, *pline)) != RS_RET_OK)
- return(iRet);
+ CHKiRet(rsCStrSetSzStr(pDfltProgNameCmp, *pline));
}
}
- return RS_RET_OK;
+
+finalize_it:
+ RETiRet;
}
diff --git a/runtime/ctok.c b/runtime/ctok.c
index d2cd8bbd..263e656c 100644
--- a/runtime/ctok.c
+++ b/runtime/ctok.c
@@ -269,7 +269,7 @@ ctokGetVar(ctok_t *pThis, ctok_token_t *pToken)
}
CHKiRet(ctokUngetCharFromStream(pThis, c)); /* put not processed char back */
- CHKiRet(rsCStrFinish(pstrVal));
+ CHKiRet(cstrFinalize(pstrVal));
CHKiRet(var.SetString(pToken->pVar, pstrVal));
pstrVal = NULL;
@@ -319,7 +319,7 @@ ctokGetSimpStr(ctok_t *pThis, ctok_token_t *pToken)
}
CHKiRet(ctokGetCharFromStream(pThis, &c));
}
- CHKiRet(rsCStrFinish(pStrB));
+ CHKiRet(cstrFinalize(pstrVal));
CHKiRet(var.SetString(pToken->pVar, pstrVal));
pstrVal = NULL;
diff --git a/runtime/datetime.c b/runtime/datetime.c
index 19e61a0a..40ab4e9c 100644
--- a/runtime/datetime.c
+++ b/runtime/datetime.c
@@ -152,11 +152,10 @@ static void getCurrTime(struct syslogTime *t, time_t *ttSeconds)
static int srSLMGParseInt32(uchar** ppsz)
{
- int i;
+ register int i;
i = 0;
- while(isdigit((int) **ppsz))
- {
+ while(isdigit((int) **ppsz)) {
i = i * 10 + **ppsz - '0';
++(*ppsz);
}
diff --git a/runtime/msg.c b/runtime/msg.c
index b3c76089..55cc48b8 100644
--- a/runtime/msg.c
+++ b/runtime/msg.c
@@ -437,11 +437,12 @@ msg_t* MsgDup(msg_t* pOld)
pNew->msgFlags = pOld->msgFlags;
pNew->iProtocolVersion = pOld->iProtocolVersion;
pNew->ttGenTime = pOld->ttGenTime;
+ memcpy(pNew->bufPRI, pOld->bufPRI, pOld->iLenPRI);
+ pNew->iLenPRI = pOld->iLenPRI;
tmpCOPYSZ(Severity);
tmpCOPYSZ(SeverityStr);
tmpCOPYSZ(Facility);
tmpCOPYSZ(FacilityStr);
- tmpCOPYSZ(PRI);
tmpCOPYSZ(RawMsg);
tmpCOPYSZ(MSG);
tmpCOPYSZ(UxTradMsg);
@@ -587,7 +588,7 @@ static rsRetVal aquirePROCIDFromTAG(msg_t *pM)
}
/* OK, finaally we could obtain a PROCID. So let's use it ;) */
- CHKiRet(rsCStrFinish(pM->pCSPROCID));
+ CHKiRet(cstrFinalize(pM->pCSPROCID));
finalize_it:
RETiRet;
@@ -629,7 +630,7 @@ static rsRetVal aquireProgramName(msg_t *pM)
; ++i) {
CHKiRet(rsCStrAppendChar(pM->pCSProgName, pM->pszTAG[i]));
}
- CHKiRet(rsCStrFinish(pM->pCSProgName));
+ CHKiRet(cstrFinalize(pM->pCSProgName));
}
finalize_it:
RETiRet;
@@ -724,31 +725,12 @@ char *getMSG(msg_t *pM)
/* Get PRI value in text form */
-static char *getPRI(msg_t *pM)
+static inline char *getPRI(msg_t *pM)
{
- int pri;
- BEGINfunc
-
if(pM == NULL)
return "";
- MsgLock(pM);
- if(pM->pszPRI == NULL) {
- /* OK, we need to construct it... we use a 5 byte buffer - as of
- * RFC 3164, it can't be longer. Should it still be, snprintf will truncate...
- * Note that we do not use the LOG_MAKEPRI macro. This macro
- * is a simple add of the two values under FreeBSD 7. So we implement
- * the logic in our own code. This is a change from a bug
- * report. -- rgerhards, 2008-07-14
- */
- pri = pM->iFacility * 8 + pM->iSeverity;
- pM->pszPRI = pM->bufPRI;
- pM->iLenPRI = snprintf((char*)pM->pszPRI, 5, "%d", pri);
- }
- MsgUnlock(pM);
-
- ENDfunc
- return (char*)pM->pszPRI;
+ return (char*)pM->bufPRI;
}
diff --git a/runtime/msg.h b/runtime/msg.h
index 1689bbbc..20360641 100644
--- a/runtime/msg.h
+++ b/runtime/msg.h
@@ -73,7 +73,8 @@ short bDoLock; /* use the mutex? */
int iLenFacility; /* ... and its length. */
uchar *pszFacilityStr; /* facility name... */
int iLenFacilityStr; /* ... and its length. */
- uchar *pszPRI; /* the PRI as a string */
+ //uchar *pszPRI; /* the PRI as a string */
+ uchar bufPRI[5];
int iLenPRI; /* and its length */
uchar *pszRawMsg; /* message as it was received on the
* wire. This is important in case we
@@ -121,7 +122,6 @@ short bDoLock; /* use the mutex? */
char *pszTIMESTAMP_SecFrac;/* TIMESTAMP fractional seconds (always 6 characters) */
int msgFlags; /* flags associated with this message */
/* now follow fixed-size buffers to safe some time otherwise used for allocs */
- uchar bufPRI[5];
};
diff --git a/runtime/nsd_gtls.c b/runtime/nsd_gtls.c
index 1a50e2f8..19dc8678 100644
--- a/runtime/nsd_gtls.c
+++ b/runtime/nsd_gtls.c
@@ -335,7 +335,7 @@ gtlsGetCertInfo(nsd_gtls_t *pThis, cstr_t **ppStr)
gnutls_x509_crt_deinit(cert);
}
- CHKiRet(rsCStrFinish(pStr));
+ CHKiRet(cstrFinalize(pStr));
*ppStr = pStr;
finalize_it:
@@ -455,7 +455,7 @@ GenFingerprintStr(uchar *pFingerprint, size_t sizeFingerprint, cstr_t **ppStr)
snprintf((char*)buf, sizeof(buf), ":%2.2X", pFingerprint[i]);
CHKiRet(rsCStrAppendStrWithLen(pStr, buf, 3));
}
- CHKiRet(rsCStrFinish(pStr));
+ CHKiRet(cstrFinalize(pStr));
*ppStr = pStr;
@@ -723,7 +723,7 @@ gtlsGetCN(nsd_gtls_t *pThis, gnutls_x509_crt *pCert, cstr_t **ppstrCN)
}
++i; /* char processed */
}
- CHKiRet(rsCStrFinish(pstrCN));
+ CHKiRet(cstrFinalize(pstrCN));
/* we got it - we ignore the rest of the DN string (if any). So we may
* not detect if it contains more than one CN
@@ -884,7 +884,7 @@ gtlsChkPeerName(nsd_gtls_t *pThis, gnutls_x509_crt *pCert)
if(!bFoundPositiveMatch) {
dbgprintf("invalid peer name, not permitted to talk to it\n");
if(pThis->bReportAuthErr == 1) {
- CHKiRet(rsCStrFinish(pStr));
+ CHKiRet(cstrFinalize(pStr));
errno = 0;
errmsg.LogError(0, RS_RET_INVALID_FINGERPRINT, "error: peer name not authorized - "
"not permitted to talk to it. Names: %s",
diff --git a/runtime/obj.c b/runtime/obj.c
index 2a9df9ed..355c0f97 100644
--- a/runtime/obj.c
+++ b/runtime/obj.c
@@ -447,7 +447,7 @@ objDeserializeEmbedStr(cstr_t **ppStr, strm_t *pStrm)
CHKiRet(rsCStrAppendChar(pStr, c));
NEXTC;
}
- CHKiRet(rsCStrFinish(pStr));
+ CHKiRet(cstrFinalize(pStr));
*ppStr = pStr;
@@ -515,7 +515,7 @@ static rsRetVal objDeserializeStr(cstr_t **ppCStr, int iLen, strm_t *pStrm)
CHKiRet(rsCStrAppendChar(pCStr, c));
NEXTC;
}
- CHKiRet(rsCStrFinish(pCStr));
+ CHKiRet(cstrFinalize(pCStr));
/* check terminator */
if(c != ':') ABORT_FINALIZE(RS_RET_INVALID_DELIMITER);
@@ -629,7 +629,7 @@ static rsRetVal objDeserializeProperty(var_t *pProp, strm_t *pStrm)
CHKiRet(rsCStrAppendChar(pProp->pcsName, c));
NEXTC;
}
- CHKiRet(rsCStrFinish(pProp->pcsName));
+ CHKiRet(cstrFinalize(pProp->pcsName));
/* property type */
CHKiRet(objDeserializeNumber(&i, pStrm));
diff --git a/runtime/parser.c b/runtime/parser.c
index 64e03094..13fb51ec 100644
--- a/runtime/parser.c
+++ b/runtime/parser.c
@@ -205,8 +205,16 @@ sanitizeMessage(msg_t *pMsg)
}
}
}
- if(bNeedSanitize == 0)
+ if(bNeedSanitize == 0) {
+ /* what a shame - we do not have a \0 byte...
+ * TODO: think about adding it or otherwise be able to use it...
+ */
+ uchar *pRaw;
+ CHKmalloc(pRaw = realloc(pMsg->pszRawMsg, pMsg->iLenRawMsg + 1));
+ pRaw[pMsg->iLenRawMsg] = '\0';
+ pMsg->pszRawMsg = pRaw;
FINALIZE;
+ }
/* now copy over the message and sanitize it */
/* TODO: can we get cheaper memory alloc? {alloca()?}*/
@@ -276,6 +284,7 @@ rsRetVal parseMsg(msg_t *pMsg)
DEFiRet;
uchar *msg;
int pri;
+ int iPriText;
CHKiRet(sanitizeMessage(pMsg));
@@ -285,11 +294,19 @@ rsRetVal parseMsg(msg_t *pMsg)
/* pull PRI */
pri = DEFUPRI;
msg = pMsg->pszRawMsg;
+ iPriText = 0;
if(*msg == '<') {
+ /* while we process the PRI, we also fill the PRI textual representation
+ * inside the msg object. This may not be ideal from an OOP point of view,
+ * but it offers us performance...
+ */
pri = 0;
while(isdigit((int) *++msg)) {
+ pMsg->bufPRI[iPriText++ % 4] = *msg; /* mod 4 to guard against malformed messages! */
pri = 10 * pri + (*msg - '0');
}
+ pMsg->bufPRI[iPriText % 4] = '\0';
+ pMsg->iLenPRI = iPriText % 4;
if(*msg == '>')
++msg;
if(pri & ~(LOG_FACMASK|LOG_PRIMASK))
diff --git a/runtime/stream.c b/runtime/stream.c
index f1f69cc8..1cff2da6 100644
--- a/runtime/stream.c
+++ b/runtime/stream.c
@@ -368,7 +368,7 @@ strmReadLine(strm_t *pThis, cstr_t **ppCStr)
CHKiRet(rsCStrAppendChar(*ppCStr, c));
CHKiRet(strmReadChar(pThis, &c));
}
- CHKiRet(rsCStrFinish(*ppCStr));
+ CHKiRet(cstrFinalize(*ppCStr));
finalize_it:
if(iRet != RS_RET_OK && *ppCStr != NULL)
diff --git a/runtime/stringbuf.c b/runtime/stringbuf.c
index f3d9aa48..a2d9c599 100644
--- a/runtime/stringbuf.c
+++ b/runtime/stringbuf.c
@@ -6,8 +6,9 @@
* Please see syslogd.c for license information.
* All functions in this "class" start with rsCStr (rsyslog Counted String).
* begun 2005-09-07 rgerhards
+ * did some optimization (read: bugs!) rgerhards, 2009-06-16
*
- * Copyright (C) 2007-2008 by Rainer Gerhards and Adiscon GmbH
+ * Copyright (C) 2007-2009 by Rainer Gerhards and Adiscon GmbH
*
* This file is part of the rsyslog runtime library.
*
@@ -40,6 +41,7 @@
#include "regexp.h"
#include "obj.h"
+uchar* rsCStrGetSzStr(cstr_t *pThis);
/* ################################################################# *
* private members *
@@ -54,15 +56,14 @@ DEFobjCurrIf(regexp)
* ################################################################# */
-rsRetVal rsCStrConstruct(cstr_t **ppThis)
+rsRetVal cstrConstruct(cstr_t **ppThis)
{
DEFiRet;
cstr_t *pThis;
ASSERT(ppThis != NULL);
- if((pThis = (cstr_t*) calloc(1, sizeof(cstr_t))) == NULL)
- ABORT_FINALIZE(RS_RET_OUT_OF_MEMORY);
+ CHKmalloc(pThis = (cstr_t*) calloc(1, sizeof(cstr_t)));
rsSETOBJTYPE(pThis, OIDrsCStr);
pThis->pBuf = NULL;
@@ -89,7 +90,7 @@ rsRetVal rsCStrConstructFromszStr(cstr_t **ppThis, uchar *sz)
CHKiRet(rsCStrConstruct(&pThis));
- pThis->iBufSize = pThis->iStrLen = strlen((char*)(char *) sz);
+ pThis->iBufSize = pThis->iStrLen = strlen((char *) sz);
if((pThis->pBuf = (uchar*) malloc(sizeof(uchar) * pThis->iStrLen)) == NULL) {
RSFREEOBJ(pThis);
ABORT_FINALIZE(RS_RET_OUT_OF_MEMORY);
@@ -137,24 +138,8 @@ void rsCStrDestruct(cstr_t **ppThis)
{
cstr_t *pThis = *ppThis;
- /* rgerhards 2005-10-19: The free of pBuf was contained in conditional compilation.
- * The code was only compiled if STRINGBUF_TRIM_ALLOCSIZE was set to 1. I honestly
- * do not know why it was so, I think it was an artifact. Anyhow, I have changed this
- * now. Should there any issue occur, this comment hopefully will shed some light
- * on what happened. I re-verified, and this function has never before been called
- * by anyone. So changing it can have no impact for obvious reasons...
- *
- * rgerhards, 2008-02-20: I changed the interface to the new calling conventions, where
- * the destructor receives a pointer to the object, so that it can set it to NULL.
- */
- if(pThis->pBuf != NULL) {
- free(pThis->pBuf);
- }
-
- if(pThis->pszBuf != NULL) {
- free(pThis->pszBuf);
- }
-
+ free(pThis->pBuf);
+ free(pThis->pszBuf);
RSFREEOBJ(pThis);
*ppThis = NULL;
}
@@ -166,12 +151,14 @@ void rsCStrDestruct(cstr_t **ppThis)
* allocated. In practice, a bit more is allocated because we envision that
* some more characters may be added after these.
* rgerhards, 2008-01-07
+ * changed to utilized realloc() -- rgerhards, 2009-06-16
*/
-static rsRetVal rsCStrExtendBuf(cstr_t *pThis, size_t iMinNeeded)
+static rsRetVal
+rsCStrExtendBuf(cstr_t *pThis, size_t iMinNeeded)
{
- DEFiRet;
uchar *pNewBuf;
size_t iNewSize;
+ DEFiRet;
/* first compute the new size needed */
if(iMinNeeded > pThis->iAllocIncrement) {
@@ -187,15 +174,9 @@ static rsRetVal rsCStrExtendBuf(cstr_t *pThis, size_t iMinNeeded)
}
iNewSize += pThis->iBufSize; /* add current size */
- /* and then allocate and copy over */
/* DEV debugging only: dbgprintf("extending string buffer, old %d, new %d\n", pThis->iBufSize, iNewSize); */
- if((pNewBuf = (uchar*) malloc(iNewSize * sizeof(uchar))) == NULL)
- ABORT_FINALIZE(RS_RET_OUT_OF_MEMORY);
- memcpy(pNewBuf, pThis->pBuf, pThis->iBufSize);
+ CHKmalloc(pNewBuf = (uchar*) realloc(pThis->pBuf, iNewSize * sizeof(uchar)));
pThis->iBufSize = iNewSize;
- if(pThis->pBuf != NULL) {
- free(pThis->pBuf);
- }
pThis->pBuf = pNewBuf;
finalize_it:
@@ -288,6 +269,29 @@ finalize_it:
}
+/* NEW VARIANT
+ * Append a character to the current string object. This may only be done until
+ * cstrFinalize() is called.
+ * rgerhards, 2009-06-16
+ */
+rsRetVal cstrAppendChar(cstr_t *pThis, uchar c)
+{
+ DEFiRet;
+
+ rsCHECKVALIDOBJECT(pThis, OIDrsCStr);
+
+ if(pThis->iStrLen >= pThis->iBufSize) {
+ CHKiRet(rsCStrExtendBuf(pThis, 1)); /* need more memory! */
+ }
+
+ /* ok, when we reach this, we have sufficient memory */
+ *(pThis->pBuf + pThis->iStrLen++) = c;
+
+finalize_it:
+ RETiRet;
+}
+
+
/* Sets the string object to the classigal sz-string provided.
* Any previously stored vlaue is discarded. If a NULL pointer
* the the new value (pszNew) is provided, an empty string is
@@ -388,35 +392,42 @@ uchar* rsCStrGetSzStr(cstr_t *pThis)
}
+/* NEW VERSION for interface without separate psz buffer! */
+/* Returns the cstr data as a classical C sz string. We use that the
+ * Finalizer did properly terminate our string (but we may stil be NULL).
+ * So it is vital that the finalizer is called BEFORe this function here!
+ * The caller must not free or otherwise manipulate the returned string and must not
+ * destroy the CStr object as long as the ascii string is used.
+ * This function may return NULL, if the string is currently NULL. This
+ * is a feature, not a bug. If you need non-NULL in any case, use
+ * cstrGetSzStrNoNULL() instead.
+ * Note that due to the new single-buffer interface this function almost does nothing!
+ * rgerhards, 2006-09-16
+ */
+uchar* cstrGetSzStr(cstr_t *pThis)
+{
+ rsCHECKVALIDOBJECT(pThis, OIDrsCStr);
+ return(pThis->pBuf);
+}
+
+
/* 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
* no memory can be allocated.
*
- * TODO:
- * This function should at some time become special. The base idea is to
- * add one extra byte to the end of the regular buffer, so that we can
- * convert it to an szString without the need to copy. The extra memory
- * footprint is not hefty, but the performance gain is potentially large.
- * To get it done now, I am not doing the optimiziation right now.
- * rgerhards, 2005-09-07
+ * This is the NEW replacement for rsCStrConvSzStrAndDestruct which does
+ * no longer utilize a special buffer but soley works on pBuf (and also
+ * assumes that cstrFinalize had been called).
*
- * rgerhards, 2007-09-04: I have changed the interface of this function. It now
- * returns an rsRetVal, so that we can communicate back if we have an error.
- * Using the standard method is much better than returning NULL. Secondly, NULL
- * was not actually an error - it was in indication if the string was empty.
- * This was needed in some parts of the code, in others not. I have now added
- * a second parameter to specify what the caller needs. I hope these changes
- * will make it less likely that the function is called incorrectly, what
- * previously happend quite often and was the cause of a number of program
- * aborts. So the parameters are now:
+ * Parameters are as follows:
* pointer to the object, pointer to string-pointer to receive string and
* bRetNULL: 0 - must not return NULL on empty string, return "" in that
* case, 1 - return NULL instead of an empty string.
* PLEASE NOTE: the caller must free the memory returned in ppSz in any case
* (except, of course, if it is NULL).
*/
-rsRetVal rsCStrConvSzStrAndDestruct(cstr_t *pThis, uchar **ppSz, int bRetNULL)
+rsRetVal cstrConvSzStrAndDestruct(cstr_t *pThis, uchar **ppSz, int bRetNULL)
{
DEFiRet;
uchar* pRetBuf;
@@ -427,14 +438,13 @@ rsRetVal rsCStrConvSzStrAndDestruct(cstr_t *pThis, uchar **ppSz, int bRetNULL)
if(pThis->pBuf == NULL) {
if(bRetNULL == 0) {
- if((pRetBuf = malloc(sizeof(uchar))) == NULL)
- ABORT_FINALIZE(RS_RET_OUT_OF_MEMORY);
+ CHKmalloc(pRetBuf = malloc(sizeof(uchar)));
*pRetBuf = '\0';
} else {
pRetBuf = NULL;
}
} else
- pRetBuf = rsCStrGetSzStr(pThis);
+ pRetBuf = pThis->pBuf;
*ppSz = pRetBuf;
@@ -443,60 +453,39 @@ finalize_it:
* that we can NOT use the rsCStrDestruct function as it would
* also free the sz String buffer, which we pass on to the user.
*/
- if(pThis->pBuf != NULL)
- free(pThis->pBuf);
RSFREEOBJ(pThis);
-
RETiRet;
}
-#if STRINGBUF_TRIM_ALLOCSIZE == 1
- /* Only in this mode, we need to trim the string. To do
- * so, we must allocate a new buffer of the exact
- * string size, and then copy the old one over.
- */
- /* WARNING
- * STRINGBUF_TRIM_ALLOCSIZE can, in theory, be used to trim
- * memory buffers. This part of the code was inherited from
- * liblogging (where it is used in a different context) but
- * never put to use in rsyslog. The reason is that it is hardly
- * imaginable where the extra performance cost is worth the save
- * in memory alloc. Then Anders Blomdel rightfully pointed out that
- * the code does not work at all - and nobody even know that it
- * probably shouldn't. Rather than removing, I deciced to somewhat
- * fix the code, so that this feature may be enabled if somebody
- * really has a need for it. Be warned, however, that I NEVER
- * tested the fix. So if you intend to use this feature, you must
- * do full testing before you rely on it. -- rgerhards, 2008-02-12
- */
-rsRetVal rsCStrFinish(cstr_t __attribute__((unused)) *pThis)
+/* Finalize the string object. This must be called after all data is added to it
+ * but before that data is used.
+ * rgerhards, 2009-06-16
+ */
+rsRetVal
+cstrFinalize(cstr_t *pThis)
{
DEFiRet;
- uchar* pBuf;
rsCHECKVALIDOBJECT(pThis, OIDrsCStr);
+
+ assert(pThis->bIsFinalized == 0);
- if((pBuf = malloc((pThis->iStrLen) * sizeof(uchar))) == NULL)
- { /* OK, in this case we use the previous buffer. At least
- * we have it ;)
- */
- }
- else
- { /* got the new buffer, so let's use it */
- memcpy(pBuf, pThis->pBuf, pThis->iStrLen);
- pThis->pBuf = pBuf;
+ if(pThis->iStrLen > 0) {
+ /* terminate string only if one exists */
+ CHKiRet(cstrAppendChar(pThis, '\0'));
+ --pThis->iStrLen; /* do NOT count the \0 byte */
}
+ pThis->bIsFinalized = 1;
+finalize_it:
RETiRet;
}
-#endif /* #if STRINGBUF_TRIM_ALLOCSIZE == 1 */
void rsCStrSetAllocIncrement(cstr_t *pThis, int iNewIncrement)
{
rsCHECKVALIDOBJECT(pThis, OIDrsCStr);
assert(iNewIncrement > 0);
-
pThis->iAllocIncrement = iNewIncrement;
}
@@ -1025,56 +1014,6 @@ int rsCStrCaseInsensitiveLocateInSzStr(cstr_t *pThis, uchar *sz)
}
-#if 0 /* read comment below why this is commented out. In short: for future use! */
-/* locate the first occurence of a standard sz string inside a rsCStr object.
- * Returns the offset (0-bound) of this first occurrence. If not found, -1 is
- * returned.
- * rgerhards 2005-09-19
- * WARNING: I accidently created this function (I later noticed I didn't relly
- * need it... I will not remove the function, as it probably is useful
- * some time later. However, it is not fully tested, so start with testing
- * it before you put it to first use).
- */
-int rsCStrLocateSzStr(cstr_t *pThis, uchar *sz)
-{
- int iLenSz;
- int i;
- int iMax;
- int bFound;
- rsCHECKVALIDOBJECT(pThis, OIDrsCStr);
-
- if(sz == NULL)
- return 0;
-
- iLenSz = strlen((char*)sz);
- if(iLenSz == 0)
- return 0;
-
- /* compute the largest index where a match could occur - after all,
- * the to-be-located string must be able to be present in the
- * searched string (it needs its size ;)).
- */
- iMax = pThis->iStrLen - iLenSz;
-
- bFound = 0;
- i = 0;
- while(i < iMax && !bFound) {
- int iCheck;
- uchar *pComp = pThis->pBuf + i;
- for(iCheck = 0 ; iCheck < iLenSz ; ++iCheck)
- if(*(pComp + iCheck) != *(sz + iCheck))
- break;
- if(iCheck == iLenSz)
- bFound = 1; /* found! - else it wouldn't be equal */
- else
- ++i; /* on to the next try */
- }
-
- return(bFound ? i : -1);
-}
-#endif /* end comment out */
-
-
/* our exit function. TODO: remove once converted to a class
* rgerhards, 2008-03-11
*/
@@ -1098,11 +1037,5 @@ finalize_it:
}
-/*
- * Local variables:
- * c-indent-level: 8
- * c-basic-offset: 8
- * tab-width: 8
- * End:
- * vi:set ai:
+/* vi:set ai:
*/
diff --git a/runtime/stringbuf.h b/runtime/stringbuf.h
index 684133bb..d28aee26 100644
--- a/runtime/stringbuf.h
+++ b/runtime/stringbuf.h
@@ -49,13 +49,15 @@ typedef struct cstr_s
size_t iBufSize; /**< current maximum size of the string buffer */
size_t iStrLen; /**< length of the string in characters. */
size_t iAllocIncrement; /**< the amount of bytes the string should be expanded if it needs to */
+ bool bIsFinalized; /**< is this object finished and ready for use? (a debug aid, may be removed later TODO 2009-06-16) */
} cstr_t;
/**
* Construct a rsCStr object.
*/
-rsRetVal rsCStrConstruct(cstr_t **ppThis);
+rsRetVal cstrConstruct(cstr_t **ppThis);
+#define rsCStrConstruct(x) cstrConstruct((x))
rsRetVal rsCStrConstructFromszStr(cstr_t **ppThis, uchar *sz);
rsRetVal rsCStrConstructFromCStr(cstr_t **ppThis, cstr_t *pFrom);
@@ -63,6 +65,7 @@ rsRetVal rsCStrConstructFromCStr(cstr_t **ppThis, cstr_t *pFrom);
* Destruct the string buffer object.
*/
void rsCStrDestruct(cstr_t **ppThis);
+#define cstrDestruct(x) rsCStrDestruct((x))
/**
* Append a character to an existing string. If necessary, the
@@ -71,6 +74,7 @@ void rsCStrDestruct(cstr_t **ppThis);
* \param c Character to append to string.
*/
rsRetVal rsCStrAppendChar(cstr_t *pThis, uchar c);
+rsRetVal cstrAppendChar(cstr_t *pThis, uchar c);
/**
* Truncate "n" number of characters from the end of the
@@ -123,10 +127,9 @@ rsRetVal rsCStrAppendInt(cstr_t *pThis, long i);
rsRetVal strExit(void); /* TODO: remove once we have a real object interface! */
-uchar* rsCStrGetSzStr(cstr_t *pThis);
+uchar* __attribute__((deprecated)) rsCStrGetSzStr(cstr_t *pThis);
uchar* rsCStrGetSzStrNoNULL(cstr_t *pThis);
rsRetVal rsCStrSetSzStr(cstr_t *pThis, uchar *pszNew);
-rsRetVal rsCStrConvSzStrAndDestruct(cstr_t *pThis, uchar **ppSz, int bRetNULL);
int rsCStrCStrCmp(cstr_t *pCS1, cstr_t *pCS2);
int rsCStrSzStrCmp(cstr_t *pCS1, uchar *psz, size_t iLenSz);
int rsCStrOffsetSzStrCmp(cstr_t *pCS1, size_t iOffset, uchar *psz, size_t iLenSz);
@@ -142,6 +145,11 @@ rsRetVal rsCStrConvertToNumber(cstr_t *pStr, number_t *pNumber);
rsRetVal rsCStrConvertToBool(cstr_t *pStr, number_t *pBool);
rsRetVal rsCStrAppendCStr(cstr_t *pThis, cstr_t *pstrAppend);
+/* new calling interface */
+rsRetVal cstrFinalize(cstr_t *pThis);
+rsRetVal cstrConvSzStrAndDestruct(cstr_t *pThis, uchar **ppSz, int bRetNULL);
+uchar* cstrGetSzStr(cstr_t *pThis);
+
/* now come inline-like functions */
#ifdef NDEBUG
# define rsCStrLen(x) ((int)((x)->iStrLen))
@@ -149,19 +157,6 @@ rsRetVal rsCStrAppendCStr(cstr_t *pThis, cstr_t *pstrAppend);
int rsCStrLen(cstr_t *pThis);
#endif
-#if STRINGBUF_TRIM_ALLOCSIZE != 1
-/* This is the normal case (see comment in rsCStrFinish!). In those cases, the function
- * simply needs to do nothing, so that we can save us the function call.
- * rgerhards, 2008-02-12
- */
-# define rsCStrFinish(pThis) RS_RET_OK
-#else
- /**
- * Finish the string buffer dynamic allocation.
- */
- rsRetVal rsCStrFinish(cstr_t *pThis);
-#endif
-
#define rsCStrGetBufBeg(x) ((x)->pBuf)
rsRetVal strInit();
diff --git a/runtime/vm.c b/runtime/vm.c
index 125b0d21..8cbf9e12 100644
--- a/runtime/vm.c
+++ b/runtime/vm.c
@@ -563,7 +563,7 @@ rsf_tolower(vmstk_t *pStk, int numOperands)
}
/* Store result and cleanup */
- CHKiRet(rsCStrFinish(pcstr));
+ CHKiRet(cstrFinalize(pcstr));
var.SetString(operand1, pcstr);
vmstk.Push(pStk, operand1);
finalize_it:
diff --git a/runtime/vmop.c b/runtime/vmop.c
index 3e001d27..acacfc9e 100644
--- a/runtime/vmop.c
+++ b/runtime/vmop.c
@@ -85,7 +85,7 @@ CODESTARTobjDebugPrint(vmop)
CHKiRet(var.Obj2Str(pThis->operand.pVar, pStrVar));
}
}
- CHKiRet(rsCStrFinish(&pStrVar));
+ CHKiRet(cstrFinalize(pStrVar));
dbgoprint((obj_t*) pThis, "%.12s\t%s\n", pOpcodeName, rsCStrGetSzStrNoNULL(pStrVar));
if(pThis->opcode != opcode_FUNC_CALL)
rsCStrDestruct(&pStrVar);