]> git.ipfire.org Git - thirdparty/rspamd.git/commitdiff
Add compacted json and config rcl emitters.
authorVsevolod Stakhov <vsevolod@highsecure.ru>
Tue, 13 Aug 2013 00:00:57 +0000 (01:00 +0100)
committerVsevolod Stakhov <vsevolod@highsecure.ru>
Tue, 13 Aug 2013 00:00:57 +0000 (01:00 +0100)
src/rcl/rcl.h
src/rcl/rcl_emitter.c

index 545dd19f9d73a70cdf110c712699e02d55b81eda..8d49cc8ad9458b17aaa2bb796ee35291823b6ce8 100644 (file)
@@ -54,6 +54,7 @@ enum rspamd_cl_type {
 
 enum rspamd_cl_emitter {
        RSPAMD_CL_EMIT_JSON = 0,
+       RSPAMD_CL_EMIT_JSON_COMPACT,
        RSPAMD_CL_EMIT_CONFIG
 };
 
index c8edf0d9e24759b89c56e230738f724c09ef155e..05ca87da69adf811f26fd0fcaf31ea0b4ecbc0ad 100644 (file)
@@ -31,8 +31,9 @@
  */
 
 
-static void rspamd_cl_elt_write_json (rspamd_cl_object_t *obj, GString *buf, guint tabs, gboolean start_tabs);
-static void rspamd_cl_obj_write_json (rspamd_cl_object_t *obj, GString *buf, guint tabs, gboolean start_tabs);
+static void rspamd_cl_elt_write_json (rspamd_cl_object_t *obj, GString *buf, guint tabs, gboolean start_tabs, gboolean compact);
+static void rspamd_cl_obj_write_json (rspamd_cl_object_t *obj, GString *buf, guint tabs, gboolean start_tabs, gboolean compact);
+static void rspamd_cl_elt_write_rcl (rspamd_cl_object_t *obj, GString *buf, guint tabs, gboolean start_tabs, gboolean is_top);
 
 /**
  * Add tabulation to the output buffer
@@ -40,9 +41,9 @@ static void rspamd_cl_obj_write_json (rspamd_cl_object_t *obj, GString *buf, gui
  * @param tabs number of tabs to add
  */
 static inline void
-rspamd_cl_add_tabs (GString *buf, guint tabs)
+rspamd_cl_add_tabs (GString *buf, guint tabs, gboolean compact)
 {
-       while (tabs--) {
+       while (!compact && tabs--) {
                g_string_append_len (buf, "    ", 4);
        }
 }
@@ -96,27 +97,42 @@ rspamd_cl_elt_string_write_json (const gchar *str, GString *buf)
  * @param buf target buffer
  */
 static void
-rspamd_cl_elt_obj_write_json (rspamd_cl_object_t *obj, GString *buf, guint tabs, gboolean start_tabs)
+rspamd_cl_elt_obj_write_json (rspamd_cl_object_t *obj, GString *buf, guint tabs, gboolean start_tabs, gboolean compact)
 {
        rspamd_cl_object_t *cur, *tmp;
 
        if (start_tabs) {
-               rspamd_cl_add_tabs (buf, tabs);
+               rspamd_cl_add_tabs (buf, tabs, compact);
+       }
+       if (compact) {
+               g_string_append_c (buf, '{');
+       }
+       else {
+               g_string_append_len (buf, "{\n", 2);
        }
-       g_string_append_len (buf, "{\n", 2);
        HASH_ITER (hh, obj, cur, tmp) {
-               rspamd_cl_add_tabs (buf, tabs + 1);
+               rspamd_cl_add_tabs (buf, tabs + 1, compact);
                rspamd_cl_elt_string_write_json (cur->key, buf);
-               g_string_append_len (buf, ": ", 2);
-               rspamd_cl_obj_write_json (cur, buf, tabs + 1, FALSE);
-               if (cur->hh.next != NULL) {
-                       g_string_append_len (buf, ",\n", 2);
+               if (compact) {
+                       g_string_append_c (buf, ':');
                }
                else {
+                       g_string_append_len (buf, ": ", 2);
+               }
+               rspamd_cl_obj_write_json (cur, buf, tabs + 1, FALSE, compact);
+               if (cur->hh.next != NULL) {
+                       if (compact) {
+                               g_string_append_c (buf, ',');
+                       }
+                       else {
+                               g_string_append_len (buf, ",\n", 2);
+                       }
+               }
+               else if (!compact) {
                        g_string_append_c (buf, '\n');
                }
        }
-       rspamd_cl_add_tabs (buf, tabs);
+       rspamd_cl_add_tabs (buf, tabs, compact);
        g_string_append_c (buf, '}');
 }
 
@@ -126,25 +142,35 @@ rspamd_cl_elt_obj_write_json (rspamd_cl_object_t *obj, GString *buf, guint tabs,
  * @param buf target buffer
  */
 static void
-rspamd_cl_elt_array_write_json (rspamd_cl_object_t *obj, GString *buf, guint tabs, gboolean start_tabs)
+rspamd_cl_elt_array_write_json (rspamd_cl_object_t *obj, GString *buf, guint tabs, gboolean start_tabs, gboolean compact)
 {
        rspamd_cl_object_t *cur = obj;
 
        if (start_tabs) {
-               rspamd_cl_add_tabs (buf, tabs);
+               rspamd_cl_add_tabs (buf, tabs, compact);
+       }
+       if (compact) {
+               g_string_append_c (buf, '[');
+       }
+       else {
+               g_string_append_len (buf, "[\n", 2);
        }
-       g_string_append_len (buf, "[\n", 2);
        while (cur) {
-               rspamd_cl_elt_write_json (cur, buf, tabs + 1, TRUE);
+               rspamd_cl_elt_write_json (cur, buf, tabs + 1, TRUE, compact);
                if (cur->next != NULL) {
-                       g_string_append_len (buf, ",\n", 2);
+                       if (compact) {
+                               g_string_append_c (buf, ',');
+                       }
+                       else {
+                               g_string_append_len (buf, ",\n", 2);
+                       }
                }
-               else {
+               else if (!compact) {
                        g_string_append_c (buf, '\n');
                }
                cur = cur->next;
        }
-       rspamd_cl_add_tabs (buf, tabs);
+       rspamd_cl_add_tabs (buf, tabs, compact);
        g_string_append_c (buf, ']');
 }
 
@@ -154,44 +180,44 @@ rspamd_cl_elt_array_write_json (rspamd_cl_object_t *obj, GString *buf, guint tab
  * @param buf buffer
  */
 static void
-rspamd_cl_elt_write_json (rspamd_cl_object_t *obj, GString *buf, guint tabs, gboolean start_tabs)
+rspamd_cl_elt_write_json (rspamd_cl_object_t *obj, GString *buf, guint tabs, gboolean start_tabs, gboolean compact)
 {
        switch (obj->type) {
        case RSPAMD_CL_INT:
                if (start_tabs) {
-                       rspamd_cl_add_tabs (buf, tabs);
+                       rspamd_cl_add_tabs (buf, tabs, compact);
                }
                g_string_append_printf (buf, "%ld", (long int)rspamd_cl_obj_toint (obj));
                break;
        case RSPAMD_CL_FLOAT:
                if (start_tabs) {
-                       rspamd_cl_add_tabs (buf, tabs);
+                       rspamd_cl_add_tabs (buf, tabs, compact);
                }
                g_string_append_printf (buf, "%lf", rspamd_cl_obj_todouble (obj));
                break;
        case RSPAMD_CL_TIME:
                if (start_tabs) {
-                       rspamd_cl_add_tabs (buf, tabs);
+                       rspamd_cl_add_tabs (buf, tabs, compact);
                }
                g_string_append_printf (buf, "%lf", rspamd_cl_obj_todouble (obj));
                break;
        case RSPAMD_CL_BOOLEAN:
                if (start_tabs) {
-                       rspamd_cl_add_tabs (buf, tabs);
+                       rspamd_cl_add_tabs (buf, tabs, compact);
                }
                g_string_append_printf (buf, "%s", rspamd_cl_obj_toboolean (obj) ? "true" : "false");
                break;
        case RSPAMD_CL_STRING:
                if (start_tabs) {
-                       rspamd_cl_add_tabs (buf, tabs);
+                       rspamd_cl_add_tabs (buf, tabs, compact);
                }
                rspamd_cl_elt_string_write_json (rspamd_cl_obj_tostring (obj), buf);
                break;
        case RSPAMD_CL_OBJECT:
-               rspamd_cl_elt_obj_write_json (obj->value.ov, buf, tabs, start_tabs);
+               rspamd_cl_elt_obj_write_json (obj->value.ov, buf, tabs, start_tabs, compact);
                break;
        case RSPAMD_CL_ARRAY:
-               rspamd_cl_elt_array_write_json (obj->value.ov, buf, tabs, start_tabs);
+               rspamd_cl_elt_array_write_json (obj->value.ov, buf, tabs, start_tabs, compact);
                break;
        }
 }
@@ -202,7 +228,7 @@ rspamd_cl_elt_write_json (rspamd_cl_object_t *obj, GString *buf, guint tabs, gbo
  * @param buf target buffer
  */
 static void
-rspamd_cl_obj_write_json (rspamd_cl_object_t *obj, GString *buf, guint tabs, gboolean start_tabs)
+rspamd_cl_obj_write_json (rspamd_cl_object_t *obj, GString *buf, guint tabs, gboolean start_tabs, gboolean compact)
 {
        rspamd_cl_object_t *cur;
        gboolean is_array = (obj->next != NULL);
@@ -210,23 +236,31 @@ rspamd_cl_obj_write_json (rspamd_cl_object_t *obj, GString *buf, guint tabs, gbo
        if (is_array) {
                /* This is an array actually */
                if (start_tabs) {
-                       rspamd_cl_add_tabs (buf, tabs);
+                       rspamd_cl_add_tabs (buf, tabs, compact);
+               }
+
+               if (compact) {
+                       g_string_append_c (buf, '[');
+               }
+               else {
+                       g_string_append_len (buf, "[\n", 2);
                }
-               g_string_append_len (buf, "[\n", 2);
                cur = obj;
                while (cur != NULL) {
-                       rspamd_cl_elt_write_json (cur, buf, tabs + 1, TRUE);
+                       rspamd_cl_elt_write_json (cur, buf, tabs + 1, TRUE, compact);
                        if (cur->next) {
                                g_string_append_c (buf, ',');
                        }
-                       g_string_append_c (buf, '\n');
+                       if (!compact) {
+                               g_string_append_c (buf, '\n');
+                       }
                        cur = cur->next;
                }
-               rspamd_cl_add_tabs (buf, tabs);
+               rspamd_cl_add_tabs (buf, tabs, compact);
                g_string_append_c (buf, ']');
        }
        else {
-               rspamd_cl_elt_write_json (obj, buf, tabs, start_tabs);
+               rspamd_cl_elt_write_json (obj, buf, tabs, start_tabs, compact);
        }
 
 }
@@ -237,7 +271,144 @@ rspamd_cl_obj_write_json (rspamd_cl_object_t *obj, GString *buf, guint tabs, gbo
  * @return json output (should be freed after using)
  */
 static guchar *
-rspamd_cl_object_emit_json (rspamd_cl_object_t *obj)
+rspamd_cl_object_emit_json (rspamd_cl_object_t *obj, gboolean compact)
+{
+       GString *buf;
+       guchar *res;
+
+       /* Allocate large enough buffer */
+       buf = g_string_sized_new (BUFSIZ);
+
+       rspamd_cl_obj_write_json (obj, buf, 0, FALSE, compact);
+
+       res = buf->str;
+       g_string_free (buf, FALSE);
+
+       return res;
+}
+
+/**
+ * Write a single object to the buffer
+ * @param obj object to write
+ * @param buf target buffer
+ */
+static void
+rspamd_cl_elt_obj_write_rcl (rspamd_cl_object_t *obj, GString *buf, guint tabs, gboolean start_tabs, gboolean is_top)
+{
+       rspamd_cl_object_t *cur, *tmp;
+
+       if (start_tabs) {
+               rspamd_cl_add_tabs (buf, tabs, is_top);
+       }
+       if (!is_top) {
+               g_string_append_len (buf, "{\n", 2);
+       }
+
+       while (obj) {
+               HASH_ITER (hh, obj, cur, tmp) {
+                       rspamd_cl_add_tabs (buf, tabs + 1, is_top);
+                       g_string_append (buf, cur->key);
+                       if (cur->type != RSPAMD_CL_OBJECT && cur->type != RSPAMD_CL_ARRAY) {
+                               g_string_append_len (buf, " = ", 3);
+                       }
+                       else {
+                               g_string_append_c (buf, ' ');
+                       }
+                       rspamd_cl_elt_write_rcl (cur, buf, is_top ? tabs : tabs + 1, FALSE, FALSE);
+                       if (cur->type != RSPAMD_CL_OBJECT && cur->type != RSPAMD_CL_ARRAY) {
+                               g_string_append_len (buf, ";\n", 2);
+                       }
+                       else {
+                               g_string_append_c (buf, '\n');
+                       }
+               }
+               obj = obj->next;
+       }
+       rspamd_cl_add_tabs (buf, tabs, is_top);
+       if (!is_top) {
+               g_string_append_c (buf, '}');
+       }
+}
+
+/**
+ * Write a single array to the buffer
+ * @param obj array to write
+ * @param buf target buffer
+ */
+static void
+rspamd_cl_elt_array_write_rcl (rspamd_cl_object_t *obj, GString *buf, guint tabs, gboolean start_tabs, gboolean is_top)
+{
+       rspamd_cl_object_t *cur = obj;
+
+       if (start_tabs) {
+               rspamd_cl_add_tabs (buf, tabs, FALSE);
+       }
+
+       g_string_append_len (buf, "[\n", 2);
+       while (cur) {
+               rspamd_cl_elt_write_rcl (cur, buf, tabs + 1, TRUE, FALSE);
+               g_string_append_len (buf, ",\n", 2);
+               cur = cur->next;
+       }
+       rspamd_cl_add_tabs (buf, tabs, FALSE);
+       g_string_append_c (buf, ']');
+}
+
+/**
+ * Emit a single element
+ * @param obj object
+ * @param buf buffer
+ */
+static void
+rspamd_cl_elt_write_rcl (rspamd_cl_object_t *obj, GString *buf, guint tabs, gboolean start_tabs, gboolean is_top)
+{
+       switch (obj->type) {
+       case RSPAMD_CL_INT:
+               if (start_tabs) {
+                       rspamd_cl_add_tabs (buf, tabs, FALSE);
+               }
+               g_string_append_printf (buf, "%ld", (long int)rspamd_cl_obj_toint (obj));
+               break;
+       case RSPAMD_CL_FLOAT:
+               if (start_tabs) {
+                       rspamd_cl_add_tabs (buf, tabs, FALSE);
+               }
+               g_string_append_printf (buf, "%.4lf", rspamd_cl_obj_todouble (obj));
+               break;
+       case RSPAMD_CL_TIME:
+               if (start_tabs) {
+                       rspamd_cl_add_tabs (buf, tabs, FALSE);
+               }
+               g_string_append_printf (buf, "%.4lf", rspamd_cl_obj_todouble (obj));
+               break;
+       case RSPAMD_CL_BOOLEAN:
+               if (start_tabs) {
+                       rspamd_cl_add_tabs (buf, tabs, FALSE);
+               }
+               g_string_append_printf (buf, "%s", rspamd_cl_obj_toboolean (obj) ? "true" : "false");
+               break;
+       case RSPAMD_CL_STRING:
+               if (start_tabs) {
+                       rspamd_cl_add_tabs (buf, tabs, FALSE);
+               }
+               rspamd_cl_elt_string_write_json (rspamd_cl_obj_tostring (obj), buf);
+               break;
+       case RSPAMD_CL_OBJECT:
+               rspamd_cl_elt_obj_write_rcl (obj->value.ov, buf, tabs, start_tabs, is_top);
+               break;
+       case RSPAMD_CL_ARRAY:
+               rspamd_cl_elt_array_write_rcl (obj->value.ov, buf, tabs, start_tabs, is_top);
+               break;
+       }
+}
+
+/**
+ * Emit an object to rcl
+ * @param obj object
+ * @return rcl output (should be freed after using)
+ */
+static guchar *
+rspamd_cl_object_emit_rcl (rspamd_cl_object_t *obj)
 {
        GString *buf;
        guchar *res;
@@ -245,7 +416,7 @@ rspamd_cl_object_emit_json (rspamd_cl_object_t *obj)
        /* Allocate large enough buffer */
        buf = g_string_sized_new (BUFSIZ);
 
-       rspamd_cl_obj_write_json (obj, buf, 0, FALSE);
+       rspamd_cl_elt_write_rcl (obj, buf, 0, FALSE, TRUE);
 
        res = buf->str;
        g_string_free (buf, FALSE);
@@ -257,7 +428,13 @@ guchar *
 rspamd_cl_object_emit (rspamd_cl_object_t *obj, enum rspamd_cl_emitter emit_type)
 {
        if (emit_type == RSPAMD_CL_EMIT_JSON) {
-               return rspamd_cl_object_emit_json (obj);
+               return rspamd_cl_object_emit_json (obj, FALSE);
+       }
+       else if (emit_type == RSPAMD_CL_EMIT_JSON_COMPACT) {
+               return rspamd_cl_object_emit_json (obj, TRUE);
+       }
+       else {
+               return rspamd_cl_object_emit_rcl (obj);
        }
 
        return NULL;