[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

[Xen-devel] [PATCH v5 04/15] libxl_qmp: Parse JSON input from QMP



Signed-off-by: Anthony PERARD <anthony.perard@xxxxxxxxxx>
---

Notes:
    v5:
        initialize len and s at declaration time
        remove old comment
    
    v4:
        simplification of the patch due to use of a single allocated space for 
the
        receive buffer.

 tools/libxl/libxl_qmp.c | 52 +++++++++++++++++++++++++++++++++++++++++
 1 file changed, 52 insertions(+)

diff --git a/tools/libxl/libxl_qmp.c b/tools/libxl/libxl_qmp.c
index 9ea303edf0..3817c70830 100644
--- a/tools/libxl/libxl_qmp.c
+++ b/tools/libxl/libxl_qmp.c
@@ -1296,6 +1296,7 @@ static int qmp_ev_callback_readable(libxl__egc *egc, 
libxl__ev_qmp *ev, int fd)
 {
     EGC_GC;
     ssize_t r;
+    char *end = NULL;
 
     if (!ev->rx_buf) {
         ev->rx_buf = libxl__malloc(NOGC, QMP_RECEIVE_BUFFER_SIZE);
@@ -1333,6 +1334,57 @@ static int qmp_ev_callback_readable(libxl__egc *egc, 
libxl__ev_qmp *ev, int fd)
     ev->buf_used += r;
     assert(ev->buf_used < ev->buf_size);
 
+    /* workaround strstr limitation */
+    ev->rx_buf[ev->buf_used] = '\0';
+
+    /*
+     * Search for the end of a QMP message: "\r\n" in the newly received
+     * bytes + the last byte on the previous read() if any
+     *
+     * end: This will point to the byte right after \r\n
+     */
+    end = strstr(ev->rx_buf + ev->buf_used - r
+                 + (ev->buf_used - r == 0 ? 0 : -1),
+                 "\r\n");
+    if (end)
+        end += 2;
+
+    while (end) {
+        libxl__json_object *o;
+        /* Start parsing from s */
+        char *s = ev->rx_buf + ev->buf_consumed;
+        /* Findout how much can be parsed */
+        size_t len = end - s;
+
+        LOG_QMP("parsing %luB: '%.*s'", len, (int)len, s);
+
+        /* Replace \n by \0 so that libxl__json_parse can use strlen */
+        s[len - 1] = '\0';
+        o = libxl__json_parse(gc, s);
+
+        if (!o) {
+            LOGD(ERROR, ev->domid, "Parse error");
+            return ERROR_FAIL;
+        }
+
+        ev->buf_consumed += len;
+
+        if (ev->buf_consumed >= ev->buf_used) {
+            free(ev->rx_buf);
+            ev->rx_buf = NULL;
+        }
+
+        /* check if there is another message received at the same time */
+        if (ev->rx_buf) {
+            end = strstr(ev->rx_buf + ev->buf_consumed, "\r\n");
+            if (end)
+                end += 2;
+        } else
+            end = NULL;
+
+        LOG_QMP("JSON object received: %s", libxl__json_object_to_json(gc, o));
+    }
+
     return 0;
 }
 
-- 
Anthony PERARD


_______________________________________________
Xen-devel mailing list
Xen-devel@xxxxxxxxxxxxxxxxxxxx
https://lists.xenproject.org/mailman/listinfo/xen-devel

 


Rackspace

Lists.xenproject.org is hosted with RackSpace, monitoring our
servers 24x7x365 and backed by RackSpace's Fanatical Support®.