Skip to content

Commit

Permalink
Merge pull request #217 from bshifter/filterx-expr-plus
Browse files Browse the repository at this point in the history
FilterXObject class method add implementation for base types and list/dict variables #1
  • Loading branch information
alltilla authored Jul 24, 2024
2 parents 695f19c + d1d8b71 commit 51145fc
Show file tree
Hide file tree
Showing 15 changed files with 611 additions and 30 deletions.
26 changes: 5 additions & 21 deletions lib/filterx/expr-plus.c
Original file line number Diff line number Diff line change
Expand Up @@ -35,37 +35,21 @@ _eval(FilterXExpr *s)
{
FilterXOperatorPlus *self = (FilterXOperatorPlus *) s;

FilterXObject *lhs_object = filterx_expr_eval(self->super.lhs);
FilterXObject *lhs_object = filterx_expr_eval_typed(self->super.lhs);
if (!lhs_object)
{
return NULL;
}
return NULL;

FilterXObject *rhs_object = filterx_expr_eval(self->super.rhs);
FilterXObject *rhs_object = filterx_expr_eval_typed(self->super.rhs);
if (!rhs_object)
{
filterx_object_unref(lhs_object);
return NULL;
}

if (filterx_object_is_type(lhs_object, &FILTERX_TYPE_NAME(string)) &&
filterx_object_is_type(rhs_object, &FILTERX_TYPE_NAME(string)))
{
gsize lhs_len, rhs_len;
const gchar *lhs_value = filterx_string_get_value(lhs_object, &lhs_len);
const gchar *rhs_value = filterx_string_get_value(rhs_object, &rhs_len);
GString *buffer = scratch_buffers_alloc();

g_string_append_len(buffer, lhs_value, lhs_len);
g_string_append_len(buffer, rhs_value, rhs_len);
/* FIXME: support taking over the already allocated space */
return filterx_string_new(buffer->str, buffer->len);
}

filterx_eval_push_error("operator+ only works on strings", s, NULL);
FilterXObject *res = filterx_object_add_object(lhs_object, rhs_object);
filterx_object_unref(lhs_object);
filterx_object_unref(rhs_object);
return NULL;
return res;
}

FilterXExpr *
Expand Down
1 change: 1 addition & 0 deletions lib/filterx/filterx-object.c
Original file line number Diff line number Diff line change
Expand Up @@ -78,6 +78,7 @@ filterx_type_init(FilterXType *type)
INIT_TYPE_METHOD(type, dict_factory);
INIT_TYPE_METHOD(type, repr);
INIT_TYPE_METHOD(type, len);
INIT_TYPE_METHOD(type, add);
INIT_TYPE_METHOD(type, free_fn);

if (!filterx_type_register(type->name, type))
Expand Down
14 changes: 14 additions & 0 deletions lib/filterx/filterx-object.h
Original file line number Diff line number Diff line change
Expand Up @@ -51,6 +51,7 @@ struct _FilterXType
FilterXObject *(*dict_factory)(void);
gboolean (*repr)(FilterXObject *self, GString *repr);
gboolean (*len)(FilterXObject *self, guint64 *len);
FilterXObject *(*add)(FilterXObject *self, FilterXObject *object);
void (*free_fn)(FilterXObject *self);
};

Expand Down Expand Up @@ -293,4 +294,17 @@ filterx_object_create_dict(FilterXObject *self)
return self->type->dict_factory();
}

static inline FilterXObject *
filterx_object_add_object(FilterXObject *self, FilterXObject *object)
{
if (!self->type->add)
{
msg_error("The add method is not supported for the given type",
evt_tag_str("type", self->type->name));
return NULL;
}

return self->type->add(self, object);
}

#endif
23 changes: 23 additions & 0 deletions lib/filterx/object-datetime.c
Original file line number Diff line number Diff line change
Expand Up @@ -205,6 +205,28 @@ _repr(FilterXObject *s, GString *repr)
return datetime_repr(&ut, repr);
}

static FilterXObject *
_add(FilterXObject *self, FilterXObject *object)
{
UnixTime result;
UnixTime base = filterx_datetime_get_value(self);
if (filterx_object_is_type(object, &FILTERX_TYPE_NAME(integer)))
{
GenericNumber gn = filterx_primitive_get_value(object);
result = unix_time_add_duration(base, gn_as_int64(&gn));
}
else if (filterx_object_is_type(object, &FILTERX_TYPE_NAME(double)))
{
GenericNumber gn = filterx_primitive_get_value(object);
result = unix_time_add_duration(base, (gint64)(gn_as_double(&gn) * USEC_PER_SEC));
}
else
return NULL;


return filterx_datetime_new(&result);
}

const gchar *
_strptime_get_time_str_from_object(FilterXObject *obj, gsize *len)
{
Expand Down Expand Up @@ -381,4 +403,5 @@ FILTERX_DEFINE_TYPE(datetime, FILTERX_TYPE_NAME(object),
.map_to_json = _map_to_json,
.marshal = _marshal,
.repr = _repr,
.add = _add,
);
19 changes: 19 additions & 0 deletions lib/filterx/object-dict-interface.c
Original file line number Diff line number Diff line change
Expand Up @@ -207,6 +207,24 @@ filterx_dict_init_instance(FilterXDict *self, FilterXType *type)
self->support_attr = TRUE;
}

static FilterXObject *
_add(FilterXObject *lhs_object, FilterXObject *rhs_object)
{
if (!filterx_object_is_type(lhs_object, &FILTERX_TYPE_NAME(dict)) ||
!filterx_object_is_type(rhs_object, &FILTERX_TYPE_NAME(dict)))
return NULL;

FilterXObject *cloned = filterx_object_clone(lhs_object);

if (!filterx_dict_merge(cloned, rhs_object))
goto error;

return cloned;
error:
filterx_object_unref(cloned);
return NULL;
}

FILTERX_DEFINE_TYPE(dict, FILTERX_TYPE_NAME(object),
.is_mutable = TRUE,
.len = _len,
Expand All @@ -217,4 +235,5 @@ FILTERX_DEFINE_TYPE(dict, FILTERX_TYPE_NAME(object),
.getattr = _getattr,
.setattr = _setattr,
.map_to_json = _map_to_json,
.add = _add,
);
19 changes: 19 additions & 0 deletions lib/filterx/object-list-interface.c
Original file line number Diff line number Diff line change
Expand Up @@ -298,6 +298,24 @@ filterx_list_init_instance(FilterXList *self, FilterXType *type)
filterx_object_init_instance(&self->super, type);
}

static FilterXObject *
_add(FilterXObject *lhs_object, FilterXObject *rhs_object)
{
if (!filterx_object_is_type(lhs_object, &FILTERX_TYPE_NAME(list)) ||
!filterx_object_is_type(rhs_object, &FILTERX_TYPE_NAME(list)))
return NULL;

FilterXObject *cloned = filterx_object_clone(lhs_object);

if(!filterx_list_merge(cloned, rhs_object))
goto error;

return cloned;
error:
filterx_object_unref(cloned);
return NULL;
}

FILTERX_DEFINE_TYPE(list, FILTERX_TYPE_NAME(object),
.is_mutable = TRUE,
.len = _len,
Expand All @@ -306,4 +324,5 @@ FILTERX_DEFINE_TYPE(list, FILTERX_TYPE_NAME(object),
.is_key_set = _is_key_set,
.unset_key = _unset_key,
.map_to_json = _map_to_json,
.add = _add,
);
36 changes: 36 additions & 0 deletions lib/filterx/object-primitive.c
Original file line number Diff line number Diff line change
Expand Up @@ -63,6 +63,23 @@ _integer_map_to_json(FilterXObject *s, struct json_object **object, FilterXObjec
return TRUE;
}

static FilterXObject *
_integer_add(FilterXObject *self, FilterXObject *object)
{
GenericNumber base = filterx_primitive_get_value(self);
if (filterx_object_is_type(object, &FILTERX_TYPE_NAME(integer)))
{
GenericNumber add = filterx_primitive_get_value(object);
return filterx_integer_new(gn_as_int64(&base) + gn_as_int64(&add));
}
if (filterx_object_is_type(object, &FILTERX_TYPE_NAME(double)))
{
GenericNumber add = filterx_primitive_get_value(object);
return filterx_double_new(gn_as_int64(&base) + gn_as_double(&add));
}
return NULL;
}

gboolean
integer_repr(gint64 val, GString *repr)
{
Expand Down Expand Up @@ -103,6 +120,23 @@ _double_map_to_json(FilterXObject *s, struct json_object **object, FilterXObject
return TRUE;
}

static FilterXObject *
_double_add(FilterXObject *self, FilterXObject *object)
{
GenericNumber base = filterx_primitive_get_value(self);
if (filterx_object_is_type(object, &FILTERX_TYPE_NAME(integer)))
{
GenericNumber add = filterx_primitive_get_value(object);
return filterx_double_new(gn_as_double(&base) + gn_as_int64(&add));
}
else if (filterx_object_is_type(object, &FILTERX_TYPE_NAME(double)))
{
GenericNumber add = filterx_primitive_get_value(object);
return filterx_double_new(gn_as_double(&base) + gn_as_double(&add));
}
return NULL;
}

gboolean
double_repr(double val, GString *repr)
{
Expand Down Expand Up @@ -326,13 +360,15 @@ FILTERX_DEFINE_TYPE(integer, FILTERX_TYPE_NAME(object),
.marshal = _integer_marshal,
.map_to_json = _integer_map_to_json,
.repr = _repr,
.add = _integer_add,
);

FILTERX_DEFINE_TYPE(double, FILTERX_TYPE_NAME(object),
.truthy = _truthy,
.marshal = _double_marshal,
.map_to_json = _double_map_to_json,
.repr = _repr,
.add = _double_add,
);

FILTERX_DEFINE_TYPE(boolean, FILTERX_TYPE_NAME(object),
Expand Down
43 changes: 42 additions & 1 deletion lib/filterx/object-string.c
Original file line number Diff line number Diff line change
Expand Up @@ -120,6 +120,26 @@ _string_repr(FilterXObject *s, GString *repr)
return TRUE;
}

static FilterXObject *
_string_add(FilterXObject *self, FilterXObject *object)
{

if (filterx_object_is_type(object, &FILTERX_TYPE_NAME(string)))
{
gsize lhs_len, rhs_len;
const gchar *lhs_value = filterx_string_get_value(self, &lhs_len);
const gchar *rhs_value = filterx_string_get_value(object, &rhs_len);
GString *buffer = scratch_buffers_alloc();

g_string_append_len(buffer, lhs_value, lhs_len);
g_string_append_len(buffer, rhs_value, rhs_len);
/* FIXME: support taking over the already allocated space */
return filterx_string_new(buffer->str, buffer->len);
}

return NULL;
}

FilterXObject *
filterx_string_new(const gchar *str, gssize str_len)
{
Expand Down Expand Up @@ -190,6 +210,26 @@ _bytes_repr(FilterXObject *s, GString *repr)
return TRUE;
}

static FilterXObject *
_bytes_add(FilterXObject *self, FilterXObject *object)
{

if (filterx_object_is_type(object, &FILTERX_TYPE_NAME(bytes)))
{
gsize lhs_len, rhs_len;
const gchar *lhs_value = filterx_bytes_get_value(self, &lhs_len);
const gchar *rhs_value = filterx_bytes_get_value(object, &rhs_len);
GString *buffer = scratch_buffers_alloc();

g_string_append_len(buffer, lhs_value, lhs_len);
g_string_append_len(buffer, rhs_value, rhs_len);
/* FIXME: support taking over the already allocated space */
return filterx_bytes_new(buffer->str, buffer->len);
}

return NULL;
}

FilterXObject *
filterx_bytes_new(const gchar *mem, gssize mem_len)
{
Expand Down Expand Up @@ -294,7 +334,6 @@ filterx_typecast_protobuf(FilterXExpr *s, GPtrArray *args)
return NULL;
}


/* these types are independent type-wise but share a lot of the details */

FILTERX_DEFINE_TYPE(string, FILTERX_TYPE_NAME(object),
Expand All @@ -303,6 +342,7 @@ FILTERX_DEFINE_TYPE(string, FILTERX_TYPE_NAME(object),
.map_to_json = _map_to_json,
.truthy = _truthy,
.repr = _string_repr,
.add = _string_add,
);

FILTERX_DEFINE_TYPE(bytes, FILTERX_TYPE_NAME(object),
Expand All @@ -311,6 +351,7 @@ FILTERX_DEFINE_TYPE(bytes, FILTERX_TYPE_NAME(object),
.map_to_json = _bytes_map_to_json,
.truthy = _truthy,
.repr = _bytes_repr,
.add = _bytes_add,
);

FILTERX_DEFINE_TYPE(protobuf, FILTERX_TYPE_NAME(object),
Expand Down
1 change: 1 addition & 0 deletions lib/filterx/tests/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -20,3 +20,4 @@ add_unit_test(LIBTEST CRITERION TARGET test_func_unset_empties DEPENDS json-plug
add_unit_test(LIBTEST CRITERION TARGET test_expr_function DEPENDS json-plugin ${JSONC_LIBRARY})
add_unit_test(LIBTEST CRITERION TARGET test_expr_regexp DEPENDS json-plugin ${JSONC_LIBRARY})
add_unit_test(LIBTEST CRITERION TARGET test_expr_null_coalesce DEPENDS json-plugin ${JSONC_LIBRARY})
add_unit_test(LIBTEST CRITERION TARGET test_expr_plus DEPENDS json-plugin ${JSONC_LIBRARY})
6 changes: 5 additions & 1 deletion lib/filterx/tests/Makefile.am
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,8 @@ lib_filterx_tests_TESTS = \
lib/filterx/tests/test_func_istype \
lib/filterx/tests/test_func_unset_empties \
lib/filterx/tests/test_expr_regexp \
lib/filterx/tests/test_expr_null_coalesce
lib/filterx/tests/test_expr_null_coalesce \
lib/filterx/tests/test_expr_plus

EXTRA_DIST += lib/filterx/tests/CMakeLists.txt

Expand Down Expand Up @@ -92,3 +93,6 @@ lib_filterx_tests_test_expr_regexp_LDADD = $(TEST_LDADD) $(JSON_LIBS)

lib_filterx_tests_test_expr_null_coalesce_CFLAGS = $(TEST_CFLAGS)
lib_filterx_tests_test_expr_null_coalesce_LDADD = $(TEST_LDADD) $(JSON_LIBS)

lib_filterx_tests_test_expr_plus_CFLAGS = $(TEST_CFLAGS)
lib_filterx_tests_test_expr_plus_LDADD = $(TEST_LDADD) $(JSON_LIBS)
Loading

0 comments on commit 51145fc

Please sign in to comment.