diff options
author | Vsevolod Stakhov <vsevolod@highsecure.ru> | 2013-08-25 11:03:07 +0100 |
---|---|---|
committer | Vsevolod Stakhov <vsevolod@highsecure.ru> | 2013-08-25 11:03:07 +0100 |
commit | 1c97bfe34afef6fbe6abffbe85039e4793751819 (patch) | |
tree | df2399391fbaa877d3d9de0f4db97686b6605361 | |
parent | 231c62a4d17fba802eccb2767ee0c77aa3a8ce9f (diff) | |
download | rspamd-1c97bfe34afef6fbe6abffbe85039e4793751819.tar.gz rspamd-1c97bfe34afef6fbe6abffbe85039e4793751819.zip |
Add refcount to rcl objects.
-rw-r--r-- | src/rcl/rcl.h | 32 | ||||
-rw-r--r-- | src/rcl/rcl_util.c | 23 | ||||
-rw-r--r-- | test/rspamd_rcl_test.c | 14 |
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); } |