mirror of
https://github.com/rsyslog/rsyslog.git
synced 2025-12-18 05:10:43 +01:00
229 lines
7.5 KiB
C
229 lines
7.5 KiB
C
/* stringbuf.h
|
|
* The counted string object
|
|
*
|
|
* This is the byte-counted string class for rsyslog. It is a replacement
|
|
* for classical \0 terminated string functions. We introduce it in
|
|
* the hope it will make the program more secure, obtain some performance
|
|
* and, most importantly, lay they foundation for syslog-protocol, which
|
|
* requires strings to be able to handle embedded \0 characters.
|
|
*
|
|
* \author Rainer Gerhards <rgerhards@adiscon.com>
|
|
* \date 2005-09-07
|
|
* Initial version begun.
|
|
*
|
|
* Copyright 2005-2012 Adiscon GmbH. All Rights Reserved.
|
|
*
|
|
* This file is part of the rsyslog runtime library.
|
|
*
|
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
|
* you may not use this file except in compliance with the License.
|
|
* You may obtain a copy of the License at
|
|
*
|
|
* http://www.apache.org/licenses/LICENSE-2.0
|
|
* -or-
|
|
* see COPYING.ASL20 in the source distribution
|
|
*
|
|
* Unless required by applicable law or agreed to in writing, software
|
|
* distributed under the License is distributed on an "AS IS" BASIS,
|
|
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
* See the License for the specific language governing permissions and
|
|
* limitations under the License.
|
|
*/
|
|
#ifndef _STRINGBUF_H_INCLUDED__
|
|
#define _STRINGBUF_H_INCLUDED__ 1
|
|
|
|
#include <assert.h>
|
|
#include <libestr.h>
|
|
|
|
/**
|
|
* The dynamic string buffer object.
|
|
*/
|
|
typedef struct cstr_s
|
|
{
|
|
#ifndef NDEBUG
|
|
rsObjID OID; /**< object ID */
|
|
#endif
|
|
uchar *pBuf; /**< pointer to the string buffer, may be NULL if string is empty */
|
|
uchar *pszBuf; /**< pointer to the sz version of the string (after it has been created )*/
|
|
size_t iBufSize; /**< current maximum size of the string buffer */
|
|
size_t iStrLen; /**< length of the string in characters. */
|
|
} cstr_t;
|
|
|
|
|
|
/**
|
|
* Construct a rsCStr object.
|
|
*/
|
|
rsRetVal cstrConstruct(cstr_t **ppThis);
|
|
#define rsCStrConstruct(x) cstrConstruct((x))
|
|
rsRetVal cstrConstructFromESStr(cstr_t **ppThis, es_str_t *str);
|
|
rsRetVal rsCStrConstructFromszStr(cstr_t **ppThis, uchar *sz);
|
|
rsRetVal rsCStrConstructFromCStr(cstr_t **ppThis, cstr_t *pFrom);
|
|
rsRetVal rsCStrConstructFromszStrf(cstr_t **ppThis, char *fmt, ...) __attribute__((format(printf,2, 3)));
|
|
|
|
/**
|
|
* Destruct the string buffer object.
|
|
*/
|
|
void rsCStrDestruct(cstr_t **ppThis);
|
|
#define cstrDestruct(x) rsCStrDestruct((x))
|
|
|
|
|
|
/* Append a character to the current string object. This may only be done until
|
|
* cstrFinalize() is called.
|
|
* rgerhards, 2009-06-16
|
|
*/
|
|
rsRetVal rsCStrExtendBuf(cstr_t *pThis, size_t iMinNeeded); /* our helper, NOT a public interface! */
|
|
static inline rsRetVal cstrAppendChar(cstr_t *pThis, uchar c)
|
|
{
|
|
rsRetVal iRet = RS_RET_OK;
|
|
|
|
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:
|
|
return iRet;
|
|
}
|
|
|
|
|
|
/* some inline functions for things that are really frequently called... */
|
|
|
|
/* 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
|
|
*/
|
|
static inline rsRetVal
|
|
cstrFinalize(cstr_t *pThis)
|
|
{
|
|
rsRetVal iRet = RS_RET_OK;
|
|
|
|
if(pThis->iStrLen > 0) {
|
|
/* terminate string only if one exists */
|
|
CHKiRet(cstrAppendChar(pThis, '\0'));
|
|
--pThis->iStrLen; /* do NOT count the \0 byte */
|
|
}
|
|
|
|
finalize_it:
|
|
return iRet;
|
|
}
|
|
|
|
|
|
/* 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
|
|
*/
|
|
static inline uchar* cstrGetSzStr(cstr_t *pThis)
|
|
{
|
|
rsCHECKVALIDOBJECT(pThis, OIDrsCStr);
|
|
return(pThis->pBuf);
|
|
}
|
|
|
|
|
|
/* Converts the CStr object to a classical sz string and returns that.
|
|
* Same restrictions as in cstrGetSzStr() applies (see there!). This
|
|
* function here guarantees that a valid string is returned, even if
|
|
* the CStr object currently holds a NULL pointer string buffer. If so,
|
|
* "" is returned.
|
|
* rgerhards 2005-10-19
|
|
* WARNING: The returned pointer MUST NOT be freed, as it may be
|
|
* obtained from that constant memory pool (in case of NULL!)
|
|
*/
|
|
static inline uchar* cstrGetSzStrNoNULL(cstr_t *pThis)
|
|
{
|
|
rsCHECKVALIDOBJECT(pThis, OIDrsCStr);
|
|
if(pThis->pBuf == NULL)
|
|
return (uchar*) "";
|
|
else
|
|
return cstrGetSzStr(pThis);
|
|
}
|
|
|
|
|
|
/**
|
|
* Truncate "n" number of characters from the end of the
|
|
* string. The buffer remains unchanged, just the
|
|
* string length is manipulated. This is for performance
|
|
* reasons.
|
|
*/
|
|
rsRetVal rsCStrTruncate(cstr_t *pThis, size_t nTrunc);
|
|
|
|
rsRetVal cstrTrimTrailingWhiteSpace(cstr_t *pThis);
|
|
|
|
/**
|
|
* Append a string to the buffer. For performance reasons,
|
|
* use rsCStrAppenStrWithLen() if you know the length.
|
|
*
|
|
* \param psz pointer to string to be appended. Must not be NULL.
|
|
*/
|
|
rsRetVal rsCStrAppendStr(cstr_t *pThis, const uchar* psz);
|
|
|
|
/**
|
|
* Append a string to the buffer.
|
|
*
|
|
* \param psz pointer to string to be appended. Must not be NULL.
|
|
* \param iStrLen the length of the string pointed to by psz
|
|
*/
|
|
rsRetVal rsCStrAppendStrWithLen(cstr_t *pThis, const uchar* psz, size_t iStrLen);
|
|
|
|
/**
|
|
* Append a printf-style formated string to the buffer.
|
|
*
|
|
* \param fmt pointer to the format string (see man 3 printf for details). Must not be NULL.
|
|
*/
|
|
rsRetVal rsCStrAppendStrf(cstr_t *pThis, char *fmt, ...) __attribute__((format(printf,2, 3)));
|
|
|
|
/**
|
|
* Append an integer to the string. No special formatting is
|
|
* done.
|
|
*/
|
|
rsRetVal rsCStrAppendInt(cstr_t *pThis, long i);
|
|
|
|
|
|
rsRetVal strExit(void); /* TODO: remove once we have a real object interface! */
|
|
uchar* rsCStrGetSzStrNoNULL(cstr_t *pThis);
|
|
rsRetVal rsCStrSetSzStr(cstr_t *pThis, uchar *pszNew);
|
|
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);
|
|
int rsCStrLocateSzStr(cstr_t *pCStr, uchar *sz);
|
|
int rsCStrLocateInSzStr(cstr_t *pThis, uchar *sz);
|
|
int rsCStrCaseInsensitiveLocateInSzStr(cstr_t *pThis, uchar *sz);
|
|
int rsCStrStartsWithSzStr(cstr_t *pCS1, uchar *psz, size_t iLenSz);
|
|
int rsCStrCaseInsensitveStartsWithSzStr(cstr_t *pCS1, uchar *psz, size_t iLenSz);
|
|
int rsCStrSzStrStartsWithCStr(cstr_t *pCS1, uchar *psz, size_t iLenSz);
|
|
rsRetVal rsCStrSzStrMatchRegex(cstr_t *pCS1, uchar *psz, int iType, void *cache);
|
|
void rsCStrRegexDestruct(void *rc);
|
|
rsRetVal rsCStrConvertToNumber(cstr_t *pStr, number_t *pNumber);
|
|
rsRetVal rsCStrConvertToBool(cstr_t *pStr, number_t *pBool);
|
|
|
|
/* in migration */
|
|
#define rsCStrAppendCStr(pThis, pstrAppend) cstrAppendCStr(pThis, pstrAppend)
|
|
|
|
/* new calling interface */
|
|
rsRetVal cstrFinalize(cstr_t *pThis);
|
|
rsRetVal cstrConvSzStrAndDestruct(cstr_t **pThis, uchar **ppSz, int bRetNULL);
|
|
rsRetVal cstrAppendCStr(cstr_t *pThis, cstr_t *pstrAppend);
|
|
|
|
/* now come inline-like functions */
|
|
#ifdef NDEBUG
|
|
# define cstrLen(x) ((int)((x)->iStrLen))
|
|
#else
|
|
int cstrLen(cstr_t *pThis);
|
|
#endif
|
|
#define rsCStrLen(s) cstrLen((s))
|
|
|
|
#define rsCStrGetBufBeg(x) ((x)->pBuf)
|
|
|
|
rsRetVal strInit();
|
|
rsRetVal strExit();
|
|
|
|
#endif /* single include */
|