aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorVsevolod Stakhov <vsevolod@highsecure.ru>2013-08-25 11:03:07 +0100
committerVsevolod Stakhov <vsevolod@highsecure.ru>2013-08-25 11:03:07 +0100
commit1c97bfe34afef6fbe6abffbe85039e4793751819 (patch)
treedf2399391fbaa877d3d9de0f4db97686b6605361
parent231c62a4d17fba802eccb2767ee0c77aa3a8ce9f (diff)
downloadrspamd-1c97bfe34afef6fbe6abffbe85039e4793751819.tar.gz
rspamd-1c97bfe34afef6fbe6abffbe85039e4793751819.zip
Add refcount to rcl objects.
-rw-r--r--src/rcl/rcl.h32
-rw-r--r--src/rcl/rcl_util.c23
-rw-r--r--test/rspamd_rcl_test.c14
3 files changed, 63 insertions, 6 deletions
diff --git a/src/rcl/rcl.h b/src/rcl/rcl.h
index 50555e248..bf22b47c5 100644
--- a/src/rcl/rcl.h
+++ b/src/rcl/rcl.h
@@ -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;
@@ -277,6 +278,16 @@ gboolean rspamd_cl_parser_add_chunk (struct rspamd_cl_parser *parser, const guch
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
* @param err if *err is NULL it is set to parser error
@@ -297,6 +308,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
* @param emit_type if type is RSPAMD_CL_EMIT_JSON then emit json, if type is
diff --git a/src/rcl/rcl_util.c b/src/rcl/rcl_util.c
index 80848e51f..b1729fd27 100644
--- a/src/rcl/rcl_util.c
+++ b/src/rcl/rcl_util.c
@@ -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;
+}
diff --git a/test/rspamd_rcl_test.c b/test/rspamd_rcl_test.c
index e5112cd59..cd02a6e2d 100644
--- a/test/rspamd_rcl_test.c
+++ b/test/rspamd_rcl_test.c
@@ -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);
}