diff options
Diffstat (limited to 'runtime/msg.c')
-rw-r--r-- | runtime/msg.c | 73 |
1 files changed, 73 insertions, 0 deletions
diff --git a/runtime/msg.c b/runtime/msg.c index 6725203c..0d01f5e1 100644 --- a/runtime/msg.c +++ b/runtime/msg.c @@ -3445,6 +3445,79 @@ uchar *MsgGetProp(msg_t *pMsg, struct templateEntry *pTpe, return(pRes); } +rsRetVal FBSensureSpace(struct fieldBuildingState *state) +{ + DEFiRet; + + if(state->nextField == state->allocatedFields) { + struct templateField *p; + size_t newSize; + + newSize = state->allocatedFields * 2 + 4; + CHKmalloc(p = realloc(state->fields, + newSize * sizeof(*state->fields))); + state->fields = p; + state->allocatedFields = newSize; + } + +finalize_it: + RETiRet; +} + +/* Append fields designated by PROPID to (pFields, pAllocatedFields, + pNextField) */ +rsRetVal MsgAppendFields(msg_t *pMsg, struct templateEntry *pTpe, + struct fieldBuildingState *state) +{ + DEFiRet; + struct templateField *dst; + uchar *pVal; + size_t propLen; + unsigned short bMustBeFreed; + struct ee_fieldbucket_listnode *node; + struct ee_field *src; + + if(pTpe->data.field.propid == PROP_CEE_ALL_JSON) { /* Special case - multiple fields */ + if(pMsg->event != NULL && pMsg->event->fields != NULL) { + /* FIXME: should there be an libee API allowing enumeration + instead of these direct accesses? */ + for (node = pMsg->event->fields->root; node != NULL; + node = node->next) { + CHKiRet(FBSensureSpace(state)); + + src = node->field; + dst = state->fields + state->nextField; + dst->fieldName = src->name; + if (src->nVals == 0) { + CHKmalloc(dst->value = (uchar*)strdup("")); + } else { + /* FIXME: are there other types to consider? */ + assert(src->val->valtype == ee_valtype_str); + /* FIXME: This corrupts embedded NULs - can we do better? The only current user to consider is mongodb */ + CHKmalloc(dst->value = (uchar *)es_str2cstr(src->val->val.str, NULL)); + } + state->nextField++; + } + } + } else { + CHKiRet(FBSensureSpace(state)); + + dst = state->fields + state->nextField; + dst->fieldName = pTpe->data.field.fieldName; + pVal = MsgGetProp(pMsg, pTpe, pTpe->data.field.propid, + pTpe->data.field.propName, &propLen, + &bMustBeFreed); + if(bMustBeFreed) { /* if it must be freed, it is our own private copy... */ + dst->value = pVal; /* ... so we can use it! */ + } else { + CHKmalloc(dst->value = (uchar*)strdup((char*)pVal)); + } + state->nextField++; + } +finalize_it: + RETiRet; +} + /* The function returns a cee variable suitable for use with RainerScript. * Note: caller must free the returned string. |