From b083f699422e08c192130e6f020d7fb002131dda Mon Sep 17 00:00:00 2001 From: Rainer Gerhards Date: Sun, 6 Jan 2008 12:12:57 +0000 Subject: worked a bit on object serialization --- msg.c | 35 ++++++++++------- obj.c | 123 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++- obj.h | 24 ++++++++++-- queue.c | 6 +-- stringbuf.c | 2 +- stringbuf.h | 2 +- 6 files changed, 170 insertions(+), 22 deletions(-) diff --git a/msg.c b/msg.c index e8d253f0..7a10af50 100644 --- a/msg.c +++ b/msg.c @@ -391,29 +391,35 @@ dbgprintf("MsgSerialize in\n"); assert(pLenBuf != NULL); assert(pThis != NULL); - if((pCStr = rsCStrConstruct()) == NULL) - ABORT_FINALIZE(RS_RET_OUT_OF_MEMORY); - CHKiRet(rsCStrAppendStr(pCStr, (uchar*) "$MSG v1\n")); +# define mySerializeINT(propName) \ + CHKiRet(objSerializeProp(pCStr, (uchar*) #propName, PROPTYPE_SHORT, (void*) &pThis->propName)); + CHKiRet(objBeginSerialize(&pCStr, (obj_t*) pThis)); +dbgprintf("syslog vers: %d, bparsehost: %d, sever %d\n", pThis->iSyslogVers, pThis->bParseHOSTNAME, pThis->iSeverity); + mySerializeINT(iSyslogVers); + mySerializeINT(bParseHOSTNAME); + mySerializeINT(iSeverity); + + CHKiRet(objSerializeProp(pCStr, (uchar*) "pszRawMsg", PROPTYPE_PSZ, (void*) pThis->pszRawMsg)); + CHKiRet(objSerializeProp(pCStr, (uchar*) "pszMSG", PROPTYPE_PSZ, (void*) pThis->pszMSG)); + CHKiRet(objSerializeProp(pCStr, (uchar*) "pszUxTradMsg", PROPTYPE_PSZ, (void*) pThis->pszUxTradMsg)); + CHKiRet(objSerializeProp(pCStr, (uchar*) "pszTAG", PROPTYPE_PSZ, (void*) pThis->pszTAG)); + CHKiRet(objSerializeProp(pCStr, (uchar*) "pszHOSTNAME", PROPTYPE_PSZ, (void*) pThis->pszHOSTNAME)); + CHKiRet(objSerializeProp(pCStr, (uchar*) "pszRcvFrom", PROPTYPE_PSZ, (void*) pThis->pszRcvFrom)); + //CHKiRet(objSerializeProp(pCStr, (uchar*) "psz", PROPTYPE_PSZ, (void*) pThis->psz)); + CHKiRet(objEndSerialize(pCStr, ppOutBuf)); + pCStr = NULL; +# undef mySerialize /* if(rsCStrAppendChar(pStrB, (escapeMode == 0) ? '\'' : '\\') != RS_RET_OK) - pNew->iSyslogVers = pOld->iSyslogVers; - pNew->bParseHOSTNAME = pOld->bParseHOSTNAME; - pNew->iSeverity = pOld->iSeverity; pNew->iFacility = pOld->iFacility; pNew->bParseHOSTNAME = pOld->bParseHOSTNAME; pNew->msgFlags = pOld->msgFlags; pNew->iProtocolVersion = pOld->iProtocolVersion; memcpy(&pNew->tRcvdAt, &pOld->tRcvdAt, sizeof(struct syslogTime)); memcpy(&pNew->tTIMESTAMP, &pOld->tTIMESTAMP, sizeof(struct syslogTime)); - tmpCOPYSZ(RawMsg); - tmpCOPYSZ(MSG); - tmpCOPYSZ(UxTradMsg); - tmpCOPYSZ(TAG); - tmpCOPYSZ(HOSTNAME); - tmpCOPYSZ(RcvFrom); tmpCOPYCSTR(ProgName); tmpCOPYCSTR(StrucData); @@ -422,6 +428,9 @@ dbgprintf("MsgSerialize in\n"); tmpCOPYCSTR(MSGID); */ finalize_it: + if(pCStr != NULL) + rsCStrDestruct(pCStr); + return iRet; } @@ -2087,7 +2096,7 @@ char *MsgGetProp(msg_t *pMsg, struct templateEntry *pTpe, * before anything else is called inside this class. * rgerhards, 2008-01-04 */ -BEGINObjClassInit(Msg) +BEGINObjClassInit(Msg, 1) OBJSetMethodHandler(objMethod_SERIALIZE, MsgSerialize); /* initially, we have no need to lock message objects */ funcLock = MsgLockingDummy; diff --git a/obj.c b/obj.c index db9b5f24..87b84359 100644 --- a/obj.c +++ b/obj.c @@ -32,6 +32,7 @@ #include #include "rsyslog.h" +#include "srUtils.h" #include "obj.h" /* static data */ @@ -55,7 +56,7 @@ static rsRetVal objInfoNotImplementedDummy(void __attribute__((unused)) *pThis) * objects, thus it is in the parameter list. * pszName must point to constant pool memory. It is never freed. */ -rsRetVal objInfoConstruct(objInfo_t **ppThis, objID_t objID, uchar *pszName, rsRetVal (*pDestruct)(void *)) +rsRetVal objInfoConstruct(objInfo_t **ppThis, objID_t objID, uchar *pszName, int iObjVers, rsRetVal (*pDestruct)(void *)) { DEFiRet; int i; @@ -68,6 +69,7 @@ rsRetVal objInfoConstruct(objInfo_t **ppThis, objID_t objID, uchar *pszName, rsR ABORT_FINALIZE(RS_RET_OUT_OF_MEMORY); pThis->pszName = pszName; + pThis->iObjVers = iObjVers; pThis->objID = objID; pThis->objMethods[0] = pDestruct; @@ -93,6 +95,125 @@ rsRetVal objInfoSetMethod(objInfo_t *pThis, objMethod_t objMethod, rsRetVal (*pH return RS_RET_OK; } + +/* --------------- object serializiation / deserialization support --------------- */ + +/* begin serialization of an object + */ +rsRetVal objBeginSerialize(rsCStrObj **ppCStr, obj_t *pObj) +{ + DEFiRet; + rsCStrObj *pCStr; + + assert(ppCStr != NULL); + assert(pObj != NULL); + + if((pCStr = rsCStrConstruct()) == NULL) + ABORT_FINALIZE(RS_RET_OUT_OF_MEMORY); + + /* cookie-char */ + CHKiRet(rsCStrAppendChar(pCStr, '$')); + /* serializer version (so far always 1) */ + CHKiRet(rsCStrAppendChar(pCStr, '1')); + CHKiRet(rsCStrAppendChar(pCStr, ':')); + + /* object Name */ + CHKiRet(rsCStrAppendStr(pCStr, objGetName(pObj))); + CHKiRet(rsCStrAppendChar(pCStr, ':')); + /* object version */ + CHKiRet(rsCStrAppendInt(pCStr, objGetVersion(pObj))); + + /* record trailer */ + CHKiRet(rsCStrAppendChar(pCStr, '\n')); + + *ppCStr = pCStr; + +finalize_it: + return iRet; +} + + +/* append a property + */ +rsRetVal objSerializeProp(rsCStrObj *pCStr, uchar *pszPropName, propertyType_t propType, void *pUsr) +{ + DEFiRet; + uchar *pszBuf; + size_t lenBuf; + uchar szBuf[64]; + + assert(pCStr != NULL); + assert(pszPropName != NULL); + + /* if we have no user pointer, there is no need to write this property. + * TODO: think if that's the righ point of view + * rgerhards, 2008-01-06 + */ + if(pUsr == NULL) + ABORT_FINALIZE(RS_RET_OK); + + switch(propType) { + case PROPTYPE_PSZ: + pszBuf = (uchar*) pUsr; + lenBuf = strlen((char*) pszBuf); + break; + case PROPTYPE_SHORT: + CHKiRet(srUtilItoA((char*) szBuf, sizeof(szBuf), (long) *((short*) pUsr))); + pszBuf = szBuf; + lenBuf = strlen((char*) szBuf); + break; + case PROPTYPE_INT: + CHKiRet(srUtilItoA((char*) szBuf, sizeof(szBuf), (long) *((int*) pUsr))); + pszBuf = szBuf; + lenBuf = strlen((char*) szBuf); + break; + } + + /* name */ + CHKiRet(rsCStrAppendStr(pCStr, pszPropName)); + CHKiRet(rsCStrAppendChar(pCStr, ':')); + /* type */ + CHKiRet(rsCStrAppendInt(pCStr, (int) propType)); + CHKiRet(rsCStrAppendChar(pCStr, ':')); + /* length */ + CHKiRet(rsCStrAppendInt(pCStr, lenBuf)); + CHKiRet(rsCStrAppendChar(pCStr, ':')); + + /* data */ + CHKiRet(rsCStrAppendStrWithLen(pCStr, (uchar*) pszBuf, lenBuf)); + + /* trailer */ + CHKiRet(rsCStrAppendChar(pCStr, '\n')); + +finalize_it: + return iRet; +} + + +/* end serialization of an object. The caller receives a + * standard C string, which he must free when no longer needed. + */ +rsRetVal objEndSerialize(rsCStrObj *pCStr, uchar **ppSz) +{ + DEFiRet; + assert(pCStr != NULL); + + assert(pCStr != NULL); + CHKiRet(rsCStrAppendStr(pCStr, (uchar*) ".EndObj.\n")); + CHKiRet(rsCStrFinish(pCStr)); + CHKiRet(rsCStrConvSzStrAndDestruct(pCStr, ppSz, 0)); + + pCStr = NULL; + +finalize_it: + if(pCStr != NULL) + rsCStrDestruct(pCStr); + + return iRet; +} + +/* --------------- end object serializiation / deserialization support --------------- */ + /* * vi:set ai: */ diff --git a/obj.h b/obj.h index 43d45bb6..394d93b1 100644 --- a/obj.h +++ b/obj.h @@ -26,6 +26,17 @@ #ifndef OBJ_H_INCLUDED #define OBJ_H_INCLUDED +#include "stringbuf.h" + +/* property types */ +typedef enum { /* do NOT start at 0 to detect uninitialized types after calloc() */ + PROPTYPE_PSZ = 1, + PROPTYPE_SHORT = 2, + PROPTYPE_INT = 3, + PROPTYPE_LONG = 4 +} propertyType_t; + +/* object Types */ typedef enum { /* IDs of known object "types/classes" */ objNull = 0, /* no valid object (we do not start at zero so we can detect calloc()) */ objMsg = 1 @@ -43,6 +54,7 @@ typedef enum { /* IDs of base methods supported by all objects - used for jump t typedef struct objInfo_s { objID_t objID; + int iObjVers; uchar *pszName; rsRetVal (*objMethods[OBJ_NUM_METHODS])(); } objInfo_t; @@ -55,17 +67,19 @@ typedef struct obj { /* the dummy struct that each derived class can be casted t /* macros */ #define DEFobjStaticHelpers static objInfo_t *pObjInfoOBJ = NULL; #define BEGINobjInstance objInfo_t *pObjInfo +#define objGetName(pThis) (((obj_t*) (pThis))->pObjInfo->pszName) +#define objGetVersion(pThis) (((obj_t*) (pThis))->pObjInfo->iObjVers) /* must be called in Constructor: */ #define objConstructSetObjInfo(pThis) ((obj_t*) (pThis))->pObjInfo = pObjInfoOBJ; #define objDestruct(pThis) (((obj_t*) (pThis))->pObjInfo->objMethods[objMethod_DESTRUCT])(pThis) #define objSerialize(pThis) (((obj_t*) (pThis))->pObjInfo->objMethods[objMethod_SERIALIZE]) /* class initializer */ #define PROTOTYPEObjClassInit(objName) rsRetVal objName##ClassInit(void) -#define BEGINObjClassInit(objName) \ +#define BEGINObjClassInit(objName, objVers) \ rsRetVal objName##ClassInit(void) \ { \ DEFiRet; \ - CHKiRet(objInfoConstruct(&pObjInfoOBJ, obj##objName, (uchar*) #objName, (rsRetVal (*)(void*))objName##Destruct)); + CHKiRet(objInfoConstruct(&pObjInfoOBJ, obj##objName, (uchar*) #objName, objVers, (rsRetVal (*)(void*))objName##Destruct)); #define ENDObjClassInit \ finalize_it: \ @@ -77,7 +91,11 @@ finalize_it: \ /* prototypes */ -rsRetVal objInfoConstruct(objInfo_t **ppThis, objID_t objID, uchar *pszName, rsRetVal (*pDestruct)(void *)); +rsRetVal objInfoConstruct(objInfo_t **ppThis, objID_t objID, uchar *pszName, int iObjVers, rsRetVal (*pDestruct)(void *)); rsRetVal objInfoSetMethod(objInfo_t *pThis, objMethod_t objMethod, rsRetVal (*pHandler)(void*)); +rsRetVal objBeginSerialize(rsCStrObj **ppCStr, obj_t *pObj); +rsRetVal objSerializePsz(rsCStrObj *pCStr, uchar *psz, size_t len); +rsRetVal objEndSerialize(rsCStrObj *pCStr, uchar **ppSz); +rsRetVal objSerializeProp(rsCStrObj *pCStr, uchar *pszPropName, propertyType_t propType, void *pUsr); #endif /* #ifndef OBJ_H_INCLUDED */ diff --git a/queue.c b/queue.c index 4c0a46c1..ffd007e2 100644 --- a/queue.c +++ b/queue.c @@ -238,15 +238,15 @@ rsRetVal qAddDisk(queue_t *pThis, void* pUsr) assert(pThis != NULL); dbgprintf("writing to file %d\n", pThis->tVars.disk.fd); - CHKiRet((objSerialize(pUsr))(pUsr, pBuf, &lenBuf)); // TODO: hier weiter machen! - i = write(pThis->tVars.disk.fd, "entry\n", 6); + CHKiRet((objSerialize(pUsr))(pUsr, &pBuf, &lenBuf)); // TODO: hier weiter machen! + i = write(pThis->tVars.disk.fd, pBuf, strlen((char*) pBuf)); dbgprintf("write wrote %d bytes, errno: %d, err %s\n", i, errno, strerror(errno)); finalize_it: return iRet; } -rsRetVal qDelDisk(queue_t *pThis, void **ppUsr) +rsRetVal qDelDisk(queue_t __attribute__((unused)) *pThis, void __attribute__((unused)) **ppUsr) { DEFiRet; diff --git a/stringbuf.c b/stringbuf.c index f4743e73..525a65b0 100755 --- a/stringbuf.c +++ b/stringbuf.c @@ -185,7 +185,7 @@ rsRetVal rsCStrAppendStr(rsCStrObj *pThis, uchar* psz) } -rsRetVal rsCStrAppendInt(rsCStrObj *pThis, int i) +rsRetVal rsCStrAppendInt(rsCStrObj *pThis, long i) { rsRetVal iRet; uchar szBuf[32]; diff --git a/stringbuf.h b/stringbuf.h index e116e4b5..b345dd47 100755 --- a/stringbuf.h +++ b/stringbuf.h @@ -123,7 +123,7 @@ void rsCStrSetAllocIncrement(rsCStrObj *pThis, int iNewIncrement); * Append an integer to the string. No special formatting is * done. */ -rsRetVal rsCStrAppendInt(rsCStrObj *pThis, int i); +rsRetVal rsCStrAppendInt(rsCStrObj *pThis, long i); uchar* rsCStrGetSzStr(rsCStrObj *pThis); -- cgit