RTI Connext C API Version 7.1.0
Creating Custom Content Filters

Working with custom content filters.

Working with custom content filters.

Introduction

By default, RTI Connext creates content filters with the DDS_SQL_FILTER, which implements a superset of the DDS-specified SQL WHERE clause. However, in many cases this filter may not be what you want. Some examples are:

This HOWTO explains how to write your own custom filter and is divided into the following sections:

The Custom Content Filter API

A custom content filter is created by calling the DDS_DomainParticipant_register_contentfilter function with a DDS_ContentFilter that contains a compile, an evaluate function and a finalize function. DDS_ContentFilteredTopic can be created with DDS_DomainParticipant_create_contentfilteredtopic_with_filter to use this filter.

A custom content filter is used by RTI Connext at the following times during the life-time of a DDS_ContentFilteredTopic (the function called is shown in parenthesis).

The compile function

The compile function is used to compile a filter expression and expression parameters. Please note that the term compile is intentionally loosely defined. It is up to the user to decide what this function should do and return.

See DDS_ContentFilter::compile for details.

The evaluate function

The evaluate function is called each time a sample is received to determine if a sample should be filtered out and discarded.

See DDS_ContentFilter::evaluate for details.

The finalize function

The finalize function is called when an instance of the custom content filter is no longer needed. When this function is called, it is safe to free all resources used by this particular instance of the custom content filter.

See DDS_ContentFilter::finalize for details.

Example Using C format strings

Assume that you have a type Foo.

You want to write a custom filter function that will drop all samples where the value of Foo.x > x and x is a value determined by an expression parameter. The filter will only be used to filter samples of type Foo.

Writing the Compile Function

The first thing to note is that we can ignore the filter expression, since we already know what the expression is. The second is that x is a parameter that can be changed. By using this information, the compile function is very easy to implement. Simply return the parameter string. This string will then be passed to the evaluate function every time a sample of this type is filtered.

Below is the entire compile function.

howto_write_simple_compile_function(void *handle,
void **new_compile_data,
const char *expression,
const struct DDS_StringSeq *parameters,
const struct DDS_TypeCode *type_code,
const char *type_class_name,
void *old_compile_data)
{
*new_compile_data = (void*)DDS_String_dup(*DDS_StringSeq_get_reference(parameters,0));
}
DDS_ReturnCode_t
Type for return codes.
Definition: infrastructure.ifc:1336
@ DDS_RETCODE_OK
Successful return.
Definition: infrastructure.ifc:1339
char * DDS_String_dup(const char *str)
Clone a string. Creates a new string that duplicates the value of string.
Instantiates FooSeq < char* > with value type semantics.
Definition: infrastructure.ifc:430
The definition of a particular data type, which you can use to inspect the name, members,...
Definition: typecode.ifc:442

Writing the Evaluate Function

The next step is to implement the evaluate function. The evaluate function receives the parameter string with the actual value to test against. Thus the evaluate function must read the actual value from the parameter string before evaluating the expression. Below is the entire evaluate function.

howto_write_simple_evaluate_function(void *filter_data,
void *compile_data,
const void *sample,
const struct DDS_FilterSampleInfo * meta_data)
{
char *parameter = (char*)compile_data;
Foo *foo_sample = (Foo*)sample;
sscanf(parameter,"%d",&x);
return (foo_sample->x > x ? DDS_BOOLEAN_FALSE : DDS_BOOLEAN_TRUE);
}
#define DDS_BOOLEAN_TRUE
Defines "true" value of DDS_Boolean data type.
Definition: dds_c.1.0/interface/common.ifc:290
RTICdrBoolean DDS_Boolean
Defines a Boolean data type, equivalent to IDL/CDR boolean.
Definition: dds_c.1.0/interface/common.ifc:279
#define DDS_BOOLEAN_FALSE
Defines "false" value of DDS_Boolean data type.
Definition: dds_c.1.0/interface/common.ifc:297
RTICdrLong DDS_Long
Defines a long integer data type, equivalent to IDL/CDR long.
Definition: dds_c.1.0/interface/common.ifc:244
Provides meta information associated with the sample.
Definition: topic.ifc:969
A representative user-defined data type.
Definition: data.ifc:112

Writing the Finalize Function

The last function to write is the finalize function. It is safe to free all resources used by this particular instance of the custom content filter that is allocated in compile. Below is the entire finalize function.

void
howto_write_simple_finalize_function(void *filter_data,
void *compile_data)
{
/* free parameter string from compile function */
DDS_String_free((char *)compile_data);
}
void DDS_String_free(char *str)
Delete a string.

Registering the Filter

Before the custom filter can be used, it must be registered with RTI Connext:

filter.compile = howto_write_simple_compile_function;
filter.evaluate = howto_write_simple_evaluate_function;
filter.finalize = howto_write_simple_finalize_function;
filter.filter_data = NULL;
participant, "MyCustomFilter", &filter) != DDS_RETCODE_OK) {
printf("Failed to register custom filter\n");
}
DDS_ReturnCode_t DDS_DomainParticipant_register_contentfilter(DDS_DomainParticipant *self, const char *filter_name, const struct DDS_ContentFilter *contentfilter)
<<extension>> Register a content filter which can be used to create a DDS_ContentFilteredTopic.
#define DDS_ContentFilter_INITIALIZER
Initializer for new DDS_ContentFilter.
Definition: topic.ifc:829
<<interface>> Interface to be used by a custom filter of a DDS_ContentFilteredTopic
Definition: topic.ifc:783
DDS_ContentFilterEvaluateFunction evaluate
Evaluate whether the sample is passing the filter or not according to the sample content.
Definition: topic.ifc:795
DDS_ContentFilterCompileFunction compile
Compile an instance of the content filter according to the filter expression and parameters of the gi...
Definition: topic.ifc:787
DDS_ContentFilterFinalizeFunction finalize
A previously compiled instance of the content filter is no longer in use and resources can now be cle...
Definition: topic.ifc:803
void * filter_data
A place for filter implementors to keep a pointer to data that may be needed by their filter.
Definition: topic.ifc:823

Unregistering the Filter

When the filter is no longer needed, it can be unregistered from RTI Connext:

participant, "MyCustomFilter" ) != DDS_RETCODE_OK) {
printf("Failed to unregister custom filter\n");
}
DDS_ReturnCode_t DDS_DomainParticipant_unregister_contentfilter(DDS_DomainParticipant *self, const char *filter_name)
<<extension>> Unregister a content filter previously registered with DDS_DomainParticipant_register_...