From 44ee69eda32b09d48cad540b658f93c75170c9c2 Mon Sep 17 00:00:00 2001 From: Nicolas Favre-Felix Date: Thu, 27 Jan 2011 10:00:37 +0100 Subject: [PATCH] Parse INFO output and convert to a JSON object. --- README.markdown | 1 + formats/json.c | 51 ++++++++++++++++++++++++++++++++++++++++++++++++- 2 files changed, 51 insertions(+), 1 deletion(-) diff --git a/README.markdown b/README.markdown index 9129d67..4727b40 100644 --- a/README.markdown +++ b/README.markdown @@ -33,6 +33,7 @@ curl -d "GET/hello" http://127.0.0.1:7379/ * Logs, with a configurable verbosity. * Cross-origin XHR, if compiled with libevent2 (for `OPTIONS` support). * File upload with PUT, if compiled with libevent2 (for `PUT` support). +* With the JSON output, the return value of INFO is parsed and transformed into an object. # Ideas, TODO... * Add better support for PUT, DELETE, HEAD, OPTIONS? How? For which commands? diff --git a/formats/json.c b/formats/json.c index 5a63f73..6f8f839 100644 --- a/formats/json.c +++ b/formats/json.c @@ -42,6 +42,50 @@ json_reply(redisAsyncContext *c, void *r, void *privdata) { free(jstr); } +/** + * Parse info message and return object. + */ +static json_t * +json_info_reply(const char *s) { + const char *p = s; + size_t sz = strlen(s); + + json_t *jroot = json_object(); + + /* TODO: handle new format */ + + while(p < s + sz) { + char *key, *val, *nl, *colon; + + /* find key */ + colon = strchr(p, ':'); + if(!colon) { + break; + } + key = calloc(colon - p + 1, 1); + memcpy(key, p, colon - p); + p = colon + 1; + + /* find value */ + nl = strchr(p, '\r'); + if(!nl) { + free(key); + break; + } + val = calloc(nl - p + 1, 1); + memcpy(val, p, nl - p); + p = nl + 1; + if(*p == '\n') p++; + + /* add to object */ + json_object_set_new(jroot, key, json_string(val)); + free(key); + free(val); + } + + return jroot; +} + static json_t * json_wrap_redis_reply(const struct cmd *cmd, const redisReply *r) { @@ -54,6 +98,7 @@ json_wrap_redis_reply(const struct cmd *cmd, const redisReply *r) { verb = calloc(cmd->argv_len[0]+1, 1); memcpy(verb, cmd->argv[0], cmd->argv_len[0]); + switch(r->type) { case REDIS_REPLY_STATUS: case REDIS_REPLY_ERROR: @@ -65,7 +110,11 @@ json_wrap_redis_reply(const struct cmd *cmd, const redisReply *r) { break; case REDIS_REPLY_STRING: - json_object_set_new(jroot, verb, json_string(r->str)); + if(strcasecmp(verb, "INFO") == 0) { + json_object_set_new(jroot, verb, json_info_reply(r->str)); + } else { + json_object_set_new(jroot, verb, json_string(r->str)); + } break; case REDIS_REPLY_INTEGER: