]> source.dussan.org Git - rspamd.git/commitdiff
Add refcount to rcl objects.
authorVsevolod Stakhov <vsevolod@highsecure.ru>
Sun, 25 Aug 2013 10:03:07 +0000 (11:03 +0100)
committerVsevolod Stakhov <vsevolod@highsecure.ru>
Sun, 25 Aug 2013 10:03:07 +0000 (11:03 +0100)
src/rcl/rcl.h
src/rcl/rcl_util.c
test/rspamd_rcl_test.c

index 50555e2489b437720d635c1e559ce2a469beabe0..bf22b47c5bcaed954c12b22c9b0aa7d29b964e1d 100644 (file)
@@ -75,6 +75,7 @@ typedef struct rspamd_cl_object_s {
                struct rspamd_cl_object_s *ov;          /**< array or hash                      */
        } value;
        enum rspamd_cl_type type;                               /**< real type                          */
+       gint ref;                                                               /**< reference count            */
        struct rspamd_cl_object_s *next;                /**< array handle                       */
        UT_hash_handle hh;                                              /**< hash handle                        */
 } rspamd_cl_object_t;
@@ -276,6 +277,16 @@ void rspamd_cl_parser_register_macro (struct rspamd_cl_parser *parser, const gch
 gboolean rspamd_cl_parser_add_chunk (struct rspamd_cl_parser *parser, const guchar *data,
                gsize len, GError **err);
 
+/**
+ * Load and add data from a file
+ * @param parser parser structure
+ * @param filename the name of file
+ * @param err if *err is NULL it is set to parser error
+ * @return TRUE if chunk has been added and FALSE in case of error
+ */
+gboolean rspamd_cl_parser_add_file (struct rspamd_cl_parser *parser, const gchar *filename,
+               GError **err);
+
 /**
  * Get a top object for a parser
  * @param parser parser structure
@@ -296,6 +307,27 @@ void rspamd_cl_parser_free (struct rspamd_cl_parser *parser);
  */
 void rspamd_cl_obj_free (rspamd_cl_object_t *obj);
 
+/**
+ * Icrease reference count for an object
+ * @param obj object to ref
+ */
+static inline rspamd_cl_object_t *
+rspamd_cl_obj_ref (rspamd_cl_object_t *obj) {
+       obj->ref ++;
+       return obj;
+}
+
+/**
+ * Decrease reference count for an object
+ * @param obj object to unref
+ */
+static inline void
+rspamd_cl_obj_unref (rspamd_cl_object_t *obj) {
+       if (--obj->ref <= 0) {
+               rspamd_cl_obj_free (obj);
+       }
+}
+
 /**
  * Emit object to a string
  * @param obj object
index 80848e51f4759af64dab9370245150967f15a6bd..b1729fd279eba128337c1e9cdf71af0d3f569634 100644 (file)
@@ -175,7 +175,7 @@ rspamd_cl_object_t*
 rspamd_cl_parser_get_object (struct rspamd_cl_parser *parser, GError **err)
 {
        if (parser->state != RSPAMD_RCL_STATE_INIT && parser->state != RSPAMD_RCL_STATE_ERROR) {
-               return parser->top_obj;
+               return rspamd_cl_obj_ref (parser->top_obj);
        }
 
        return NULL;
@@ -190,7 +190,7 @@ rspamd_cl_parser_free (struct rspamd_cl_parser *parser)
        struct rspamd_cl_pubkey *key, *ktmp;
 
        if (parser->top_obj != NULL) {
-               rspamd_cl_obj_free (parser->top_obj);
+               rspamd_cl_obj_unref (parser->top_obj);
        }
 
        LL_FOREACH_SAFE (parser->stack, stack, stmp) {
@@ -595,3 +595,22 @@ rspamd_cl_includes_handler (const guchar *data, gsize len, gpointer ud, GError *
 
        return rspamd_cl_include_url (data, len, parser, TRUE, err);
 }
+
+gboolean
+rspamd_cl_parser_add_file (struct rspamd_cl_parser *parser, const gchar *filename,
+               GError **err)
+{
+       guchar *buf;
+       gsize len;
+       gboolean ret;
+
+       if (!rspamd_cl_fetch_file (filename, &buf, &len, err)) {
+               return FALSE;
+       }
+
+       ret = rspamd_cl_parser_add_chunk (parser, buf, len, err);
+
+       munmap (buf, len);
+
+       return ret;
+}
index e5112cd594d17d38bf9656bca887705b75dd2197..cd02a6e2de1122c5c1d6309dcc2d4fa4080e244b 100644 (file)
@@ -78,7 +78,7 @@ rspamd_rcl_test_func (void)
 
        cur = rcl_test_valid;
        while (*cur != NULL) {
-               parser = rspamd_cl_parser_new ();
+               parser = rspamd_cl_parser_new (RSPAMD_CL_FLAG_KEY_LOWERCASE);
                rspamd_cl_pubkey_add (parser, test_pubkey, sizeof (test_pubkey) - 1, &err);
                g_assert_no_error (err);
                g_assert (parser != NULL);
@@ -90,7 +90,7 @@ rspamd_rcl_test_func (void)
                emitted = rspamd_cl_object_emit (obj, RSPAMD_CL_EMIT_CONFIG);
                g_assert (emitted != NULL);
                msg_debug ("got config output: %s", emitted);
-               parser2 = rspamd_cl_parser_new ();
+               parser2 = rspamd_cl_parser_new (RSPAMD_CL_FLAG_KEY_LOWERCASE);
                g_assert (parser2 != NULL);
                rspamd_cl_parser_add_chunk (parser2, emitted, strlen (emitted), &err);
                g_assert_no_error (err);
@@ -100,7 +100,7 @@ rspamd_rcl_test_func (void)
                emitted = rspamd_cl_object_emit (obj, RSPAMD_CL_EMIT_JSON);
                g_assert (emitted != NULL);
                msg_debug ("got json output: %s", emitted);
-               parser2 = rspamd_cl_parser_new ();
+               parser2 = rspamd_cl_parser_new (RSPAMD_CL_FLAG_KEY_LOWERCASE);
                g_assert (parser2 != NULL);
                rspamd_cl_parser_add_chunk (parser2, emitted, strlen (emitted), &err);
                g_assert_no_error (err);
@@ -110,7 +110,7 @@ rspamd_rcl_test_func (void)
                emitted = rspamd_cl_object_emit (obj, RSPAMD_CL_EMIT_JSON_COMPACT);
                g_assert (emitted != NULL);
                msg_debug ("got json compacted output: %s", emitted);
-               parser2 = rspamd_cl_parser_new ();
+               parser2 = rspamd_cl_parser_new (RSPAMD_CL_FLAG_KEY_LOWERCASE);
                g_assert (parser2 != NULL);
                rspamd_cl_parser_add_chunk (parser2, emitted, strlen (emitted), &err);
                g_assert_no_error (err);
@@ -119,7 +119,13 @@ rspamd_rcl_test_func (void)
 
                /* Cleanup */
                rspamd_cl_parser_free (parser);
+               rspamd_cl_obj_unref (obj);
                cur ++;
        }
 
+       /* Load a big json */
+       parser = rspamd_cl_parser_new (RSPAMD_CL_FLAG_KEY_LOWERCASE);
+       rspamd_cl_parser_add_file (parser, "./rcl_test.json", &err);
+       g_assert_no_error (err);
+       rspamd_cl_parser_free (parser);
 }