Skip to content

Commit

Permalink
Merge pull request #4871 from alltilla/filterx-format-json
Browse files Browse the repository at this point in the history
filterx: add `format_json()`
  • Loading branch information
MrAnno committed Apr 9, 2024
2 parents 5735532 + 2c16742 commit dc0258b
Show file tree
Hide file tree
Showing 23 changed files with 831 additions and 8 deletions.
8 changes: 8 additions & 0 deletions lib/filterx/filterx-object.h
Original file line number Diff line number Diff line change
Expand Up @@ -139,6 +139,14 @@ filterx_object_marshal(FilterXObject *self, GString *repr, LogMessageValueType *
return FALSE;
}

static inline gboolean
filterx_object_marshal_append(FilterXObject *self, GString *repr, LogMessageValueType *t)
{
if (self->type->marshal)
return self->type->marshal(self, repr, t);
return FALSE;
}

static inline FilterXObject *
filterx_object_clone(FilterXObject *self)
{
Expand Down
9 changes: 9 additions & 0 deletions lib/filterx/object-dict-interface.c
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,15 @@ filterx_dict_len(FilterXObject *s)
return self->len(self);
}

gboolean
filterx_dict_iter(FilterXObject *s, FilterXDictIterFunc func, gpointer user_data)
{
FilterXDict *self = (FilterXDict *) s;
if (!self->iter)
return FALSE;
return self->iter(self, func, user_data);
}

static FilterXObject *
_get_subscript(FilterXObject *s, FilterXObject *key)
{
Expand Down
4 changes: 4 additions & 0 deletions lib/filterx/object-dict-interface.h
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,8 @@

typedef struct FilterXDict_ FilterXDict;

typedef gboolean (*FilterXDictIterFunc)(FilterXObject *, FilterXObject *, gpointer);

struct FilterXDict_
{
FilterXObject super;
Expand All @@ -37,9 +39,11 @@ struct FilterXDict_
gboolean (*set_subscript)(FilterXDict *s, FilterXObject *key, FilterXObject *new_value);
gboolean (*has_subscript)(FilterXDict *s, FilterXObject *key);
guint64 (*len)(FilterXDict *s);
gboolean (*iter)(FilterXDict *s, FilterXDictIterFunc func, gpointer user_data);
};

guint64 filterx_dict_len(FilterXObject *s);
gboolean filterx_dict_iter(FilterXObject *s, FilterXDictIterFunc func, gpointer user_data);

void filterx_dict_init_instance(FilterXDict *self, FilterXType *type);

Expand Down
1 change: 0 additions & 1 deletion lib/filterx/object-json-array.c
Original file line number Diff line number Diff line change
Expand Up @@ -49,7 +49,6 @@ _truthy(FilterXObject *s)
static gboolean
_marshal_to_json_literal(FilterXJsonArray *self, GString *repr, LogMessageValueType *t)
{
g_string_truncate(repr, 0);
*t = LM_VT_JSON;

const gchar *json_repr = json_object_to_json_string_ext(self->object, JSON_C_TO_STRING_PLAIN);
Expand Down
30 changes: 30 additions & 0 deletions lib/filterx/object-json-object.c
Original file line number Diff line number Diff line change
Expand Up @@ -130,6 +130,35 @@ _len(FilterXDict *s)
return json_object_object_length(self->object);
}

static gboolean
_iter_inner(FilterXJsonObject *self, const gchar *obj_key, struct json_object *obj_value,
FilterXDictIterFunc func, gpointer user_data)
{
FilterXObject *key = filterx_string_new(obj_key, -1);
FilterXObject *value = filterx_json_convert_json_to_object_cached(&self->super.super, &self->root_container,
obj_value);

gboolean result = func(key, value, user_data);

filterx_object_unref(key);
filterx_object_unref(value);
return result;
}

static gboolean
_iter(FilterXDict *s, FilterXDictIterFunc func, gpointer user_data)
{
FilterXJsonObject *self = (FilterXJsonObject *) s;

struct json_object_iter itr;
json_object_object_foreachC(self->object, itr)
{
if (!_iter_inner(self, itr.key, itr.val, func, user_data))
return FALSE;
}
return TRUE;
}

/* NOTE: consumes root ref */
FilterXObject *
filterx_json_object_new_sub(struct json_object *json_obj, FilterXObject *root)
Expand All @@ -140,6 +169,7 @@ filterx_json_object_new_sub(struct json_object *json_obj, FilterXObject *root)
self->super.get_subscript = _get_subscript;
self->super.set_subscript = _set_subscript;
self->super.len = _len;
self->super.iter = _iter;

filterx_weakref_set(&self->root_container, root);
filterx_object_unref(root);
Expand Down
22 changes: 19 additions & 3 deletions lib/filterx/object-message-value.c
Original file line number Diff line number Diff line change
Expand Up @@ -139,8 +139,6 @@ _map_to_json(FilterXObject *s, struct json_object **jso)
return FALSE;
}



static gboolean
_truthy(FilterXObject *s)
{
Expand All @@ -166,6 +164,23 @@ _unmarshal(FilterXObject *s)
return _unmarshal_repr(self->repr, self->repr_len, self->type);
}

LogMessageValueType
filterx_message_value_get_type(FilterXObject *s)
{
FilterXMessageValue *self = (FilterXMessageValue *) s;
return self->type;
}

const gchar *
filterx_message_value_get_value(FilterXObject *s, gsize *len)
{
FilterXMessageValue *self = (FilterXMessageValue *) s;

g_assert(len);
*len = self->repr_len;
return self->repr;
}

/* NOTE: the caller must ensure that repr lives as long as the constructed object, avoids copying */
FilterXObject *
filterx_message_value_new_borrowed(const gchar *repr, gssize repr_len, LogMessageValueType type)
Expand All @@ -184,7 +199,8 @@ FilterXObject *
filterx_message_value_new(const gchar *repr, gssize repr_len, LogMessageValueType type)
{
gssize len = repr_len < 0 ? strlen(repr) : repr_len;
gchar *buf = g_memdup2(repr, len);
gssize alloc_len = repr_len < 0 ? len + 1 : repr_len;
gchar *buf = g_memdup2(repr, alloc_len);
FilterXMessageValue *self = (FilterXMessageValue *) filterx_message_value_new_borrowed(buf, len, type);
self->buf = buf;
return &self->super;
Expand Down
3 changes: 3 additions & 0 deletions lib/filterx/object-message-value.h
Original file line number Diff line number Diff line change
Expand Up @@ -31,4 +31,7 @@ FilterXObject *filterx_message_value_new_borrowed(const gchar *repr, gssize repr
FilterXObject *filterx_message_value_new_ref(gchar *repr, gssize repr_len, LogMessageValueType type);
FilterXObject *filterx_message_value_new(const gchar *repr, gssize repr_len, LogMessageValueType type);

LogMessageValueType filterx_message_value_get_type(FilterXObject *s);
const gchar *filterx_message_value_get_value(FilterXObject *s, gsize *len);

#endif
22 changes: 22 additions & 0 deletions lib/filterx/object-primitive.h
Original file line number Diff line number Diff line change
Expand Up @@ -63,4 +63,26 @@ filterx_integer_unwrap(FilterXObject *s, gint64 *value)
return TRUE;
}

static inline gboolean
filterx_double_unwrap(FilterXObject *s, gdouble *value)
{
FilterXPrimitive *self = (FilterXPrimitive *) s;

if (!filterx_object_is_type(s, &FILTERX_TYPE_NAME(double)))
return FALSE;
*value = gn_as_double(&self->value);
return TRUE;
}

static inline gboolean
filterx_boolean_unwrap(FilterXObject *s, gboolean *value)
{
FilterXPrimitive *self = (FilterXPrimitive *) s;

if (!filterx_object_is_type(s, &FILTERX_TYPE_NAME(boolean)))
return FALSE;
*value = !!gn_as_int64(&self->value);
return TRUE;
}

#endif
2 changes: 2 additions & 0 deletions libtest/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@ set(LIBTEST_HEADERS
stopwatch.h
cr_template.h
grab-logging.h
filterx.h
)

set(LIBTEST_SOURCES
Expand All @@ -27,6 +28,7 @@ set(LIBTEST_SOURCES
stopwatch.c
cr_template.c
grab-logging.c
filterx.c
)

add_library(libtest STATIC ${LIBTEST_SOURCES})
Expand Down
11 changes: 7 additions & 4 deletions libtest/Makefile.am
Original file line number Diff line number Diff line change
Expand Up @@ -32,9 +32,11 @@ libtest_libsyslog_ng_test_a_SOURCES = \
libtest/queue_utils_lib.c \
libtest/queue_utils_lib.h \
libtest/stopwatch.c \
libtest/stopwatch.h
libtest/stopwatch.h \
libtest/filterx.c \
libtest/filterx.h

libtest_libsyslog_ng_test_a_CFLAGS = $(AM_CFLAGS) $(CRITERION_CFLAGS)
libtest_libsyslog_ng_test_a_CFLAGS = $(AM_CFLAGS) $(CRITERION_CFLAGS) $(JSON_CFLAGS)

libtestinclude_HEADERS = \
libtest/config_parse_lib.h \
Expand All @@ -47,11 +49,12 @@ libtestinclude_HEADERS = \
libtest/persist_lib.h \
libtest/proto_lib.h \
libtest/queue_utils_lib.h \
libtest/stopwatch.h
libtest/stopwatch.h \
libtest/filterx.h

pkgconfig_DATA += \
libtest/syslog-ng-test.pc

LIBTEST_LIBS = $(top_builddir)/libtest/libsyslog-ng-test.a
LIBTEST_LIBS = $(top_builddir)/libtest/libsyslog-ng-test.a $(JSON_LIBS)

include libtest/tests/Makefile.am
106 changes: 106 additions & 0 deletions libtest/filterx.c
Original file line number Diff line number Diff line change
@@ -0,0 +1,106 @@
/*
* Copyright (c) 2024 Attila Szakacs
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 2.1 of the License, or (at your option) any later version.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library; if not, write to the Free Software
* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
*
* As an additional exemption you are allowed to compile & link against the
* OpenSSL libraries as published by the OpenSSL project. See the file
* COPYING for details.
*
*/

#include "filterx.h"
#include "filterx/object-json.h"

FilterXObject *
filterx_test_dict_new(void)
{
FilterXObject *result = filterx_json_object_new_empty();
result->type = &FILTERX_TYPE_NAME(test_dict);
return result;
}

FilterXObject *
filterx_test_list_new(void)
{
FilterXObject *result = filterx_json_array_new_empty();
result->type = &FILTERX_TYPE_NAME(test_list);
return result;
}

const gchar *
filterx_test_unknown_object_marshaled_repr(gssize *len)
{
static const gchar *marshalled = "test_unknown_object";
if (len)
*len = strlen(marshalled);
return marshalled;
}

static gboolean
_unknown_marshal(FilterXObject *s, GString *repr, LogMessageValueType *t)
{
*t = LM_VT_STRING;
g_string_append(repr, filterx_test_unknown_object_marshaled_repr(NULL));
return TRUE;
}

static gboolean
_unknown_truthy(FilterXObject *s)
{
return TRUE;
}

static gboolean
_unknown_map_to_json(FilterXObject *s, struct json_object **object)
{
gssize len;
const gchar *repr = filterx_test_unknown_object_marshaled_repr(&len);
*object = json_object_new_string_len(repr, len);
return TRUE;
}

FilterXObject *
filterx_test_unknown_object_new(void)
{
return filterx_object_new(&FILTERX_TYPE_NAME(test_unknown_object));
}

void
init_libtest_filterx(void)
{
filterx_type_init(&FILTERX_TYPE_NAME(test_unknown_object));

/* These will use the json implementations, but won't be json typed. */
filterx_type_init(&FILTERX_TYPE_NAME(test_dict));
filterx_type_init(&FILTERX_TYPE_NAME(test_list));
FILTERX_TYPE_NAME(test_dict) = FILTERX_TYPE_NAME(json_object);
FILTERX_TYPE_NAME(test_list) = FILTERX_TYPE_NAME(json_array);
}

void
deinit_libtest_filterx(void)
{
}

FILTERX_DEFINE_TYPE(test_dict, FILTERX_TYPE_NAME(object));
FILTERX_DEFINE_TYPE(test_list, FILTERX_TYPE_NAME(object));
FILTERX_DEFINE_TYPE(test_unknown_object, FILTERX_TYPE_NAME(object),
.is_mutable = FALSE,
.truthy = _unknown_truthy,
.marshal = _unknown_marshal,
.map_to_json = _unknown_map_to_json,
.list_factory = filterx_test_list_new,
.dict_factory = filterx_test_dict_new);
42 changes: 42 additions & 0 deletions libtest/filterx.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,42 @@
/*
* Copyright (c) 2024 Attila Szakacs
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 2.1 of the License, or (at your option) any later version.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library; if not, write to the Free Software
* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
*
* As an additional exemption you are allowed to compile & link against the
* OpenSSL libraries as published by the OpenSSL project. See the file
* COPYING for details.
*
*/

#ifndef LIBTEST_FILTERX_H_INCLUDED
#define LIBTEST_FILTERX_H_INCLUDED

#include "filterx/filterx-object.h"

FILTERX_DECLARE_TYPE(test_dict);
FILTERX_DECLARE_TYPE(test_list);
FILTERX_DECLARE_TYPE(test_unknown_object);

FilterXObject *filterx_test_dict_new(void);
FilterXObject *filterx_test_list_new(void);
FilterXObject *filterx_test_unknown_object_new(void);

const gchar *filterx_test_unknown_object_marshaled_repr(gssize *len);

void init_libtest_filterx(void);
void deinit_libtest_filterx(void);

#endif
Loading

0 comments on commit dc0258b

Please sign in to comment.