summaryrefslogtreecommitdiffstats
path: root/runtime/msg.c
diff options
context:
space:
mode:
Diffstat (limited to 'runtime/msg.c')
-rw-r--r--runtime/msg.c73
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.