Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

filterx: add format_json() #4871

Merged
merged 11 commits into from
Apr 9, 2024
8 changes: 8 additions & 0 deletions lib/filterx/filterx-object.h
Original file line number Diff line number Diff line change
Expand Up @@ -134,6 +134,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);
MrAnno marked this conversation as resolved.
Show resolved Hide resolved
*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 @@ -59,4 +59,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
Loading