char *name;
/** currently enumerating value */
chunk_t value;
+ /** section nesting level of callback parser */
+ int level;
};
/**
*len = res->value.len;
return res->value.ptr;
default:
+ *len = 0;
errno = EINVAL;
return NULL;
}
}
}
+int vici_parse_cb(vici_res_t *res, vici_parse_section_cb_t section,
+ vici_parse_value_cb_t kv, vici_parse_value_cb_t li,
+ void *user)
+{
+ char *name, *list = NULL;
+ void *value;
+ int base, len, ret;
+
+ base = res->level;
+
+ while (TRUE)
+ {
+ switch (vici_parse(res))
+ {
+ case VICI_PARSE_KEY_VALUE:
+ if (res->level == base)
+ {
+ if (kv)
+ {
+ name = vici_parse_name(res);
+ value = vici_parse_value(res, &len);
+ if (name && value)
+ {
+ ret = kv(user, res, name, value, len);
+ if (ret)
+ {
+ return ret;
+ }
+ }
+ }
+ }
+ break;
+ case VICI_PARSE_BEGIN_SECTION:
+ if (res->level++ == base)
+ {
+ if (section)
+ {
+ name = vici_parse_name(res);
+ if (name)
+ {
+ ret = section(user, res, name);
+ if (ret)
+ {
+ return ret;
+ }
+ }
+ }
+ }
+ break;
+ case VICI_PARSE_END_SECTION:
+ if (res->level-- == base)
+ {
+ return 0;
+ }
+ break;
+ case VICI_PARSE_END:
+ res->level = 0;
+ return 0;
+ case VICI_PARSE_BEGIN_LIST:
+ if (res->level == base)
+ {
+ list = vici_parse_name(res);
+ }
+ break;
+ case VICI_PARSE_LIST_ITEM:
+ if (list && li)
+ {
+ value = vici_parse_value(res, &len);
+ if (value)
+ {
+ ret = li(user, res, list, value, len);
+ if (ret)
+ {
+ return ret;
+ }
+ }
+ }
+ break;
+ case VICI_PARSE_END_LIST:
+ if (res->level == base)
+ {
+ list = NULL;
+ }
+ break;
+ case VICI_PARSE_ERROR:
+ res->level = 0;
+ errno = EBADMSG;
+ return 1;
+ }
+ }
+}
+
void* vici_find(vici_res_t *res, int *len, char *fmt, ...)
{
va_list args;
typedef void (*vici_event_cb_t)(void *user, char *name, vici_res_t *msg);
/**
+ * Callback function for key/value and list items, invoked by vici_parse_cb().
+ *
+ * @param user user data, as passed to vici_parse_cb()
+ * @param res message currently parsing
+ * @param name name of key or list
+ * @param value value buffer
+ * @param len length of value buffer
+ * @return 0 if parsed successfully
+ */
+typedef int (*vici_parse_value_cb_t)(void *user, vici_res_t *res, char *name,
+ void *value, int len);
+
+/**
+ * Callback function for sections, invoked by vici_parse_cb().
+ *
+ * @param user user data, as passed to vici_parse_cb()
+ * @param res message currently parsing
+ * @param name name of the section
+ * @return 0 if parsed successfully
+ */
+typedef int (*vici_parse_section_cb_t)(void *user, vici_res_t *res, char *name);
+
+/**
* Open a new vici connection.
*
* On error, NULL is returned and errno is set appropriately.
char* vici_parse_value_str(vici_res_t *res);
/**
+ * Parse a complete message with callbacks.
+ *
+ * Any of the callbacks may be NULL to skip this kind of item. Callbacks are
+ * invoked for the current section level only. To descent into sections, call
+ * vici_parse_cb() from within a section callback.
+ *
+ * @param res message to parse
+ * @param section callback invoked for each section
+ * @param kv callback invoked for key/value pairs
+ * @param li callback invoked for list items
+ * @param user user data to pass to callbacks
+ * @return 0 if parsing successful
+ */
+int vici_parse_cb(vici_res_t *res, vici_parse_section_cb_t section,
+ vici_parse_value_cb_t kv, vici_parse_value_cb_t li,
+ void *user);
+
+/*
* Find a blob value in a message for a given key.
*
* Sections can be selected by prefixing them separated by dots.