46 #define _DEFAULT_SOURCE    59 #include <libtrap/trap.h>   236    for (i = 0; i < field_specs_static.
ur_last_id; i++) {
   241          for (j = 0; j < i; j++) {
   255    char *str = NULL, *strmove = NULL, *str_new = NULL;
   262    str = (
char *) calloc(
sizeof(
char), len);
   267    for (
int i = 0; i < tmplt->
count; i++) {
   269       if (act_len >= len) {
   271          str_new = (
char *) realloc(str, 
sizeof(
char) * len);
   272          if (str_new == NULL) {
   276          strmove = str_new + (strmove - str);
   280       strmove += strlen(strmove);
   282    if (tmplt->
count != 0) {
   290    ur_field_id_linked_list_t * first;
   294       if (init_val != 
UR_OK) {
   316          char **ur_field_names_new;
   317          short *ur_field_sizes_new;
   324          if (ur_field_types_new == NULL) {
   330          if (ur_field_sizes_new == NULL) {
   331             free(ur_field_types_new);
   337          if (ur_field_names_new == NULL) {
   338             free(ur_field_types_new);
   339             free(ur_field_sizes_new);
   370    int length_type_2 = 0, length_name_2 = 0;
   371    const char *source_cpy;
   373    while (*source != 0 && isspace(*source)) {
   378    while (*source != 0 && !isspace(*source)) {
   385    if (length_type_2 >= *length_type) {
   389       *type = (
char *) malloc(
sizeof(
char) * (length_type_2 + 1));
   393       *length_type = length_type_2 + 1;
   395    memcpy(*type, source_cpy, length_type_2);
   396    (*type)[length_type_2] = 0;
   399    while (*source != 0 && isspace(*source)) {
   404    while (*source != 0 && !isspace(*source) && *source != 
',') {
   411    if (length_name_2 >= *length_name) {
   415       *name = (
char *) malloc(
sizeof(
char) * (length_name_2 + 1));
   419       *length_name = length_name_2 + 1;
   421    memcpy(*name, source_cpy, length_name_2);
   422    (*name)[length_name_2] = 0;
   424    while (*source != 0 && isspace(*source)) {
   428    if (*source == 
',') {
   436    const char *source_cpy = NULL, *p = ifc_data_fmt;
   438    int name_len = 0, act_len = 0, str_len;
   439    str_len = strlen(ifc_data_fmt);
   440    out_str = (
char *) calloc(str_len + 1, 
sizeof(
char));
   441    if (out_str == NULL) {
   446       while (*p != 0 && isspace(*p)) {
   450       while (*p != 0 && *p != 
' ') {
   454       while (*p != 0 && isspace(*p)) {
   461       while (*p != 0 && *p != 
',' && !isspace(*p)) {
   465       assert(name_len + act_len + 1 <= str_len);
   466       memcpy(out_str + act_len, source_cpy, name_len);
   469       while (*p != 0 && isspace(*p)) {
   474       } 
else if (*p == 0) {
   480       out_str[act_len] = 
',';
   488    int name_len = 0, act_len = 0, concat_str_len = strlen(ifc_data_fmt);
   490    const char *source_cpy, *p = ifc_data_fmt;
   492    uint32_t ifc_out = 0;
   493    concat_str = (
char *) malloc(
sizeof(
char) * concat_str_len);
   494    if (concat_str == NULL) {
   498       while (*p != 0 && !isspace(*p)) {
   505       while (*p != 0 && *p != 
',') {
   509       if (name_len + act_len + 1 > concat_str_len) {
   511          str_new = (
char *) realloc(concat_str, 
sizeof(
char) * (concat_str_len * 2));
   512          if (str_new == NULL) {
   517          concat_str = str_new;
   519       memcpy(concat_str + act_len, source_cpy, name_len);
   521       concat_str[act_len] = 
',';
   527       for (
int i = 0; i < tmplt->
count; i++) {
   529          name_len = strlen(f_name);
   530          if (name_len + act_len + 1 > concat_str_len) {
   532             str_new = (
char *) realloc(concat_str, 
sizeof(
char) * (concat_str_len * 2));
   533             if (str_new == NULL) {
   538             concat_str = str_new;
   540          memcpy(concat_str + act_len, f_name, name_len);
   542          *(concat_str + act_len) = 
',';
   549       concat_str[act_len] = 0;
   560    const char *new_fields_move;
   561    new_fields_move = ifc_data_fmt;
   562    char *field_name, *field_type;
   564    int field_id = 0, field_type_id = 0;
   565    field_name = (
char *) malloc(
sizeof(
char) * field_name_length);
   566    if (field_name == NULL) {
   569    field_type = (
char *) malloc(
sizeof(
char) * field_type_length);
   570    if (field_type == NULL) {
   574    while (*new_fields_move != 0) {
   576       if (new_fields_move == NULL) {
   577          if (field_name != NULL) {
   580          if (field_type != NULL) {
   587       if (field_type_id < 0) {
   588          if (field_name != NULL) {
   592          return field_type_id;
   596          if (field_name != NULL) {
   603    if (field_name != NULL) {
   617    if (new_tmplt != NULL && tmplt != NULL) {
   628    if (field_names == NULL) {
   645    name_len = strlen(name);
   649    if (!((name[0] >= 
'A' && name[0] <= 
'Z') || (name[0] >= 
'a' && name[0] <= 
'z'))) {
   652    for (
int i = 1; i < name_len; i++) {
   653       if (!((name[i] >= 
'A' && name[i] <= 
'Z') || (name[i] >= 
'a' && name[i] <= 
'z') || (name[i] >= 
'0' && name[i] <= 
'9') || name[i] == 
'_')) {
   677    name_copy = (
char *) calloc(
sizeof(
char), strlen(name) + 1);
   678    if (name_copy == NULL) {
   682    strcpy(name_copy, name);
   705       ur_field_id_linked_list_t *undefined_item;
   706       undefined_item = (ur_field_id_linked_list_t *) calloc(
sizeof(ur_field_id_linked_list_t), 1);
   707       if (undefined_item == NULL) {
   713       undefined_item->id = field_id;
   749       ur_field_id_linked_list_t *next, * act_del;
   751       while (act_del != NULL) {
   752          next = act_del->next;
   805       if (errstr != NULL) {
   807          if (*errstr != NULL) {
   824       if (errstr != NULL) {
   826          if (*errstr != NULL) {
   848    if (tmplt_str == NULL) {
   851    trap_ctx_set_data_fmt(ctx, ifc, TRAP_FMT_UNIREC, tmplt_str);
   867    if (tmplt_str == NULL) {
   870    trap_ctx_set_required_fmt(ctx, ifc, TRAP_FMT_UNIREC, tmplt_str);
   884    if (tmplt_str == NULL) {
   885       if (errstr != NULL) {
   887          if (*errstr != NULL) {
   894    trap_ctx_set_required_fmt(ctx, ifc_in, TRAP_FMT_UNIREC, tmplt_str);
   895    trap_ctx_set_data_fmt(ctx, ifc_out, TRAP_FMT_UNIREC, tmplt_str);
   903    int n_fields = 0, written_fields = 0;
   906       while (*fields != 
'\0' && isspace(*fields)) {
   910       if (*fields != 
'\0') {
   912          const char *tmp = fields;
   913          while (*tmp != 
'\0') {
   914             if (*(tmp++) == 
',') {
   922    if (fields_spec == NULL && n_fields > 0) {
   923       if (errstr != NULL) {
   925          if (*errstr != NULL) {
   932    const char *start_ptr = fields;
   934    for (
int i = 0; i < n_fields; i++) {
   938       while (!isspace(*end_ptr) && *end_ptr != 
',' && *end_ptr != 
'\0') {
   941       int len = end_ptr - start_ptr;
   942       fields_spec[written_fields].
name = malloc(len + 1);
   943       if (fields_spec[written_fields].name == NULL) {
   944          if (errstr != NULL) {
   946             if (*errstr != NULL) {
   950          for (
int j = 0; j < i; j++) {
   951             free(fields_spec[j].name);
   956       memcpy(fields_spec[written_fields].name, start_ptr, len);
   957       fields_spec[written_fields].
name[len] = 0;
   959       while ((isspace(*start_ptr) || *start_ptr == 
',') && *start_ptr != 
'\0') {
   966          if (errstr != NULL) {
   967             *errstr = (
char *) malloc(100);
   968             if (*errstr != NULL) {
   970                n = snprintf(*errstr, 100, 
"field: %s is not defined.", fields_spec[written_fields].name);
   972                   strcpy(*errstr, 
"given field is not defined");
   976          for (
int j = 0; j <= written_fields; j++) {
   977             free(fields_spec[j].name);
   983       int in_the_template = 0;
   984       for (
int j = 0; j < written_fields; j++) {
   985          if (fields_spec[j].
id == id_by_name) {
   991       if (in_the_template == 0) {
   992          fields_spec[written_fields].
id = id_by_name;
   994          fields_spec[written_fields].
size = 
ur_get_size(fields_spec[written_fields].
id);
   997          free(fields_spec[written_fields].name);
   998          fields_spec[written_fields].
name = NULL;
  1007    if (tmplt == NULL) {
  1008       for (
int i = 0; i < written_fields; i++) {
  1009          free(fields_spec[i].name);
  1012       if (errstr != NULL) {
  1014          if (*errstr != NULL) {
  1025    if (tmplt->
offset == NULL) {
  1026       for (
int i = 0; i < written_fields; i++) {
  1027          free(fields_spec[i].name);
  1031       if (errstr != NULL) {
  1033          if (*errstr != NULL) {
  1042    uint16_t offset = 0;
  1044    for (
int i = 0; i < written_fields; i++) {
  1046       if (fields_spec[i].size < 0) { 
  1047          tmplt->
offset[fields_spec[i].
id] = offset;
  1053          tmplt->
offset[fields_spec[i].
id] = offset;
  1054          offset += fields_spec[i].
size;
  1062    if (tmplt->
ids == NULL) {
  1063       for (
int i = 0; i < written_fields; i++) {
  1064          free(fields_spec[i].name);
  1068       if (errstr != NULL) {
  1070          if (*errstr != NULL) {
  1076    tmplt->
count = written_fields;
  1077    for (
int i = 0; i < written_fields; i++) {
  1078       tmplt->
ids[i] = fields_spec[i].
id;
  1081    for (
int i = 0; i < written_fields; i++) {
  1082       free(fields_spec[i].name);
  1089    if (tmplt == NULL) {
  1093    if (tmplt->
offset != NULL) {
  1097    if (tmplt->
ids != NULL) {
  1107       return memcmp(tmpltA->
ids, tmpltB->
ids, 
sizeof(uint16_t) * tmpltA->
count) == 0;
  1120           "ID\t%-30s\toffset\n",
"name");
  1121    for (
int i = 0; i < tmplt->
count; i++) {
  1132    if (old_size_of_field != new_val_len) {
  1133       uint16_t size = new_val_len;
  1137       for (
int i = 0; i< tmplt->
count; i++) {
  1138          if (field_id == tmplt->
ids[i]) {
  1143       for (
int i = index + 1; i < tmplt->
count; i++) {
  1147       memmove(out_ptr + new_val_len, out_ptr + old_size_of_field, size - new_val_len);
  1166    memcpy(out_ptr, val_ptr, val_len);
  1216    unsigned int size = (
unsigned int)tmplt->
static_size + max_var_size;
  1219    return (
void *) calloc(size, 1);
  1232    char *str = malloc(size + 1);
  1255    int size_of_field = 0;
  1256    void * ptr_dst = NULL;
  1257    void * ptr_src = NULL;
  1260    if (src_tmplt == dst_tmplt) {
  1266    for (
int i = 0; i < size; i++) {
  1270          if (size_of_field > 0) {
  1274             memcpy(ptr_dst, ptr_src, size_of_field);
  1279             ur_set_var(dst_tmplt, dst, i, ptr_src, size_of_field);
  1295    while (id < tmplt->offset_size) {
  1309    if (index >= tmplt->
count || index < 0) {
  1312    return tmplt->
ids[index];
  1322    int elems_parsed = 0;
  1324    const char *scan_format = NULL;
  1338       scan_format = 
"%" SCNu8;
  1341       scan_format = 
"%" SCNu16;
  1344       scan_format = 
"%" SCNu32;
  1347       scan_format = 
"%" SCNu64;
  1350       scan_format = 
"%" SCNi8;
  1353       scan_format = 
"%" SCNi16;
  1356       scan_format = 
"%" SCNi32;
  1359       scan_format = 
"%" SCNi64;
  1365       scan_format = 
"%lf";
  1371          const char *ip = tmp;
  1388          ((
ip_addr_t *) ptr)[elems_parsed] = addr;
  1390          if (elems_parsed >= elems_allocated) {
  1408          ((
mac_addr_t *) ptr)[elems_parsed] = macaddr;
  1410          if (elems_parsed >= elems_allocated) {
  1426          const char *time = tmp;
  1442          ((
ur_time_t *) ptr)[elems_parsed] = urtime;
  1444          if (elems_parsed >= elems_allocated) {
  1457       fprintf(stderr, 
"Unsupported UniRec field type, skipping.\n");
  1462    if (scan_format != NULL) {
  1464          if (sscanf(v, scan_format, (
void *) ((
char*) ptr + elems_parsed * element_size)) != 1) {
  1469          if (elems_parsed >= elems_allocated) {
  1482    if (elems_allocated > elems_parsed) {
  1500       if (sscanf(v, 
"%" SCNu8, (uint8_t *) ptr) != 1) {
  1505       if (sscanf(v, 
"%" SCNu16 , (uint16_t *) ptr) != 1) {
  1510       if (sscanf(v, 
"%" SCNu32, (uint32_t *) ptr) != 1) {
  1515       if (sscanf(v, 
"%" SCNu64, (uint64_t *) ptr) != 1) {
  1520       if (sscanf(v, 
"%" SCNi8, (int8_t *) ptr) != 1) {
  1525       if (sscanf(v, 
"%" SCNi16, (int16_t *) ptr) != 1) {
  1530       if (sscanf(v, 
"%" SCNi32, (int32_t *) ptr) != 1) {
  1535       if (sscanf(v, 
"%" SCNi64, (int64_t *) ptr) != 1) {
  1540       if (sscanf(v, 
"%c", (
char *) ptr) != 1) {
  1545       if (sscanf(v, 
"%f", (
float *) ptr) != 1) {
  1550       if (sscanf(v, 
"%lf", (
double *) ptr) != 1) {
  1570       (*macaddr_p) = macaddr;
  1575          fprintf(stderr, 
"Failed to parse time.\n");
  1586          int size = strlen(v)/2;
  1589          for ( ; size > 0; --size, v += 2, ++data_ptr) {
  1590             if (sscanf(v, 
"%2hhx", data_ptr) != 1) {
  1600       fprintf(stderr, 
"Unsupported UniRec field type, skipping.\n");
  1613    if (ur == NULL || str == NULL) {
  1617    res = strptime(str, 
"%Y-%m-%dT%T", &t);
  1619    if ((res != NULL) && ((*res == 
'.') || (*res == 0) || (*res == 
'z') || (*res == 
'Z'))) {
  1622          if (*res != 0 && *++res != 0) {
  1623             char frac_buffer[10];
  1624             memset(frac_buffer, 
'0', 9);
  1631             size_t frac_len = strlen(res);
  1632             if (frac_len > 0 && (res[frac_len - 1] == 
'z' || res[frac_len - 1] == 
'Z')) {
  1638             memcpy(frac_buffer, res, frac_len);
  1639             nsec = strtoul(frac_buffer, NULL, 10); 
  1643          goto failed_time_parsing;
  1648 failed_time_parsing:
  1657    int str_len = strlen(str) + 1;
  1658    char *new_str = malloc(
sizeof(
char) * str_len);
  1659    if (new_str == NULL) {
  1662    memcpy(new_str, str, str_len);
  1668    for (
int i = start; i < end; i++) {
  1678    for (
int i = start; i < end; i++) {
  1692    unsigned int indexer;
  1702    if (sscanf(mask, 
"%"SCNx64, &lm->
link_mask) < 1) {
  1743    if (links != NULL) {
 var-len fields (string where only printable characters are expected; '\0' at the end should NOT be in...
#define UR_FIELD_ID_MAX
Max ID of a field. 
INLINE_IMPL void mac_to_bytes(const mac_addr_t *addr, uint8_t *array)
INLINE_IMPL ip_addr_t ip_from_16_bytes_le(char b[16])
ur_iter_t ur_iter_fields(const ur_template_t *tmplt, ur_iter_t id)
Iterate over fields of a template in order of a record This function can be used to iterate over all ...
#define UR_E_INVALID_FIELD_ID
The field ID is not present in a template. 
int ur_set_array_from_string(const ur_template_t *tmpl, void *data, ur_field_id_t f_id, const char *v)
Set value of a UniRec array field. 
ur_tmplt_direction direction
Direction of data input, output, bidirection, no direction. 
Sorting fields structure This structure is used to sort fields by their size and name. The structure is passed to the sorting algorithm. 
INLINE_IMPL uint32_t ip_get_v4_as_int(ip_addr_t *addr)
#define ur_get_type(field_id)
Get type of UniRec field Get type of any UniRec defined field. 
int ur_define_set_of_fields(const char *ifc_data_fmt)
Define set of new UniRec fields Define new UniRec fields at run-time. It adds new fields into existin...
void * ur_clone_record(const ur_template_t *tmplt, const void *src)
Create new UniRec and copy the source UniRec into it. Function creates new UniRec record and fills it...
uint8_t ur_time_from_string(ur_time_t *ur, const char *str)
INLINE_IMPL mac_addr_t mac_from_bytes(uint8_t *array)
#define ur_get_name(field_id)
Get name of UniRec field Get name of any UniRec defined field. 
ur_field_id_t ur_allocated_fields
#define ur_get_var_offset(tmplt, rec, field_id)
Get offset of variable-length field in the record. Get offset of a specified variable-length field in...
INLINE_IMPL uint64_t ur_get_link_mask(ur_links_t *links)
Get link mask. 
ur_field_id_t id
ID of a field. 
int ur_get_empty_id()
Return first empty id for new UniRec field Return first empty id for new UniRec field. If there is no space in the UniRec structures, it will increase space in the existing structures. 
char * name
Name of Value. 
ur_template_t * ur_create_template(const char *fields, char **errstr)
Create UniRec template Create new UniRec template specified by a string containing names of its field...
#define UR_INITIAL_SIZE_FIELDS_TABLE
Initial size of free space in fields tables. 
char * description
Description of Value. 
const char * ur_get_type_and_name_from_string(const char *source, char **name, char **type, int *length_name, int *length_type)
void ur_clear_varlen(const ur_template_t *tmplt, void *rec)
Clear variable-length part of a record. For better performance of setting content to variable-length ...
int ur_define_field(const char *name, ur_field_type_t type)
Define new UniRec field Define new UniRec field at run-time. It adds new field into existing structur...
#define ur_set_var_len(tmplt, rec, field_id, len)
Set size of variable-length field in the record. Set size of specified variable-length field in the r...
const char * ur_values_get_description_start_end(uint32_t start, uint32_t end, int32_t value)
Returns description of specified value (Helper function) Helper function for ur_values_get_descriptio...
#define ur_is_array(field_id)
void ur_free_links(ur_links_t *links)
Destroy links structure. Free all memory allocated for a links structure created previously by ur_cre...
ur_static_field_specs_t UR_FIELD_SPECS_STATIC
Structure that lists staticaly defined UniRec field specifications such as names, types...
short * ur_field_sizes
Array of sizes of fields. 
int ur_ctx_set_output_template(trap_ctx_t *ctx, int ifc, ur_template_t *tmplt)
Set UniRec template to ouput interface on specified context. 
char * ur_cpy_string(const char *str)
Duplicates given string. Helper function which returns pointer to duplicated string. New string has to be freed by user. 
*uint16_t * ur_get_ptr_by_id(tmplt2, buffer2, new_id))
INLINE_IMPL unsigned int ur_get_link_count(ur_links_t *links)
Get link count. 
short * ur_field_sizes
Array of sizes of fields. 
int ur_set_from_string(const ur_template_t *tmpl, void *data, ur_field_id_t f_id, const char *v)
Set value of a UniRec field. 
ur_template_t * ur_ctx_create_output_template(trap_ctx_t *ctx, int ifc, const char *fields, char **errstr)
Create UniRec template and set it to output interface on specified context Creates UniRec template...
INLINE_IMPL ip_addr_t ip_from_16_bytes_be(char b[16])
int ur_field_array_elem_type[]
UniRec array element data types. 
#define UR_INITIALIZED
Indicator if the UniRec has been initialized by calling function ur_init. 
INLINE_IMPL void mac_to_str(const mac_addr_t *addr, char *str)
#define ur_is_static(field_id)
Alias for ur_is_fixlen (for backwards compatibility only) 
#define UR_E_INVALID_PARAMETER
The given parameter is wrong. 
char ** ur_field_names
Array of names of fields. 
uint64_t ur_time_t
Type of timestamps used in UniRec Timestamps in UniRec are stored as number of seconds from Unix epoc...
#define UR_ARRAY_ALLOC
Default alloc size increment for ur_set_array_from_string. 
char ** ur_field_names
Array of names of fields. 
#define ur_rec_size(tmplt, rec)
Get size of UniRec record (static and variable length) Get total size of whole UniRec record...
INLINE_IMPL int ip_from_str(const char *str, ip_addr_t *addr)
char * name
Name of a field. 
#define UR_ITER_BEGIN
First value in iterating through the fields. 
INLINE_IMPL int ip_cmp(const ip_addr_t *addr1, const ip_addr_t *addr2)
UniRec default field list It contains all fields which are specified statically in source code of a m...
#define UR_E_MEMORY
Problem during allocating memory. 
const int ur_field_type_size[]
Sizes of UniRec data types. 
int ur_get_field_type_from_str(const char *type)
char * ur_array_append_get_ptr(const ur_template_t *tmplt, void *rec, int field_id)
Allocate new element at the end of array and return its pointer. 
INLINE_IMPL ip_addr_t ip_from_4_bytes_be(char b[4])
ur_template_t * ur_expand_template(const char *ifc_data_fmt, ur_template_t *tmplt)
Expand UniRec template Expand existing UniRec template by a string containing types and names of its ...
ur_template_t * ur_define_fields_and_update_template(const char *ifc_data_fmt, ur_template_t *tmplt)
Defined new fields and expand an UniRec template Define new fields (function ur_define_set_of_fields)...
#define ur_get_len(tmplt, rec, field)
Get length of UniRec field Get actual length of fixed or variable-length UniRec field. 
void ur_finalize()
Deallocate UniRec structures Deallocate UniRec structures at the end of a program. This function SHOULD be called after all UniRec functions and macros invocations, typically during a cleanup phase before the program's end. This function has to be called if some fields are defined during run-time, otherwise this function is needless. 
Links structure. It contains a link count, link mask and link indexes. Array link_indexes stores posi...
ur_template_t * ur_ctx_create_input_template(trap_ctx_t *ctx, int ifc, const char *fields, char **errstr)
Create UniRec template and set it to input interface on specified context Creates UniRec template...
int ur_set_var(const ur_template_t *tmplt, void *rec, int field_id, const void *val_ptr, int val_len)
Set content of variable-length UniRec field Copy given data into variable-length UniRec field...
printf("%u %u %u %s\, ur_get(tmplt, buffer, F_FOO), ip_get_v4_as_int(&(ur_get(tmplt, buffer, F_IP))), ur_get_var_len(tmplt, buffer, F_STR1), ur_get_ptr(tmplt, buffer, F_STR1))
char * ur_get_var_as_str(const ur_template_t *tmplt, const void *rec, ur_field_id_t field_id)
Get variable-length UniRec field as a C string Copy data of a variable-length field from UniRec recor...
#define UR_ARRAY_DELIMITER
Delimiter of array elements in string. 
const ur_values_t ur_values[]
template is not used for sending data 
#define UR_E_TYPE_MISMATCH
The type of a field is different. 
#define ur_array_allocate(tmplt, rec, field_id, elem_cnt)
Preallocates UniRec array field to have requested number of elements. 
#define UR_COUNT_OF_TYPES
Constants for all possible types of UniRec fields. 
ur_field_type_t * ur_field_types
Array of types of fields. 
ur_field_specs_t ur_field_specs
Structure that lists UniRec field specifications such as names, types, id. 
INLINE_IMPL uint64_t ur_get_link_bit_field_position(ur_links_t *links, unsigned int index)
Get position in link_bit_field of link. Get position in link_bit_field of link specified by index of ...
#define UR_E_INVALID_TYPE
The type of a field is not defined. 
#define ur_array_get_elem_size(field_id)
Get size of a single element of UniRec field. 
int ur_undefine_field_by_id(ur_field_id_t field_id)
Undefine UniRec field by its id Undefine UniRec field created at run-time. It erases given field from...
void * ur_create_record(const ur_template_t *tmplt, uint16_t max_var_size)
uint16_t count
Count of fields in template. 
#define UR_DEFAULT_LENGTH_OF_TEMPLATE
#define UR_E_INVALID_NAME
The given name is not present in a template. 
UniRec fields structure It contains all fields which are statically defined by UR_FIELDS(...) and run-time generated fields. This structure can be modified during run-time by generating new fields and erasing existing fields. 
int ur_undefine_field(const char *name)
Undefine UniRec field by its name Undefine UniRec field created at run-time. It erases given field fr...
ur_template_t * ur_create_template_from_ifc_spec(const char *ifc_data_fmt)
Create UniRec template from data format string. Creates new UniRec template (function ur_create_templ...
#define UR_NO_DYNAMIC_VALUES
Value of variable "first_dynamic" if no dynamic values are present. 
int16_t * ids
Array of ids in template. 
#define ur_is_present(tmplt, field_id)
Is given field present in given template? Return true (non-zero value) if given template contains fie...
#define UR_ITER_END
Last value in iterating through the fields. 
#define ur_get_var_len(tmplt, rec, field_id)
Get size of a variable sized field in the record. Get size of a variable-length field in the record...
void ur_free_record(void *record)
int16_t ur_field_id_t
Type of UniRec field identifiers. 
#define UR_INVALID_OFFSET
Default value of all offsets (value is not in the record) 
INLINE_IMPL ip_addr_t ip_from_int(uint32_t i)
uint16_t ur_rec_varlen_size(const ur_template_t *tmplt, const void *rec)
Get size of variable sized part of UniRec record Get total size of all variable-length fields in an U...
void ur_free_template(ur_template_t *tmplt)
Destroy UniRec template Free all memory allocated for a template created previously by ur_create_temp...
ur_field_id_t ur_last_id
Last specified ID. 
Definition of UniRec structures and functions. 
ur_template_t * ur_ctx_create_bidirectional_template(trap_ctx_t *ctx, int ifc_in, int ifc_out, const char *fields, char **errstr)
Create UniRec template and set it to input and output interface on specified context Creates UniRec t...
#define ur_array_get_elem_cnt(tmplt, rec, field_id)
Get number of elements stored in an UniRec array. 
INLINE_IMPL int ip_is6(const ip_addr_t *addr)
#define ur_rec_fixlen_size(tmplt)
Get size of fixed-length part of UniRec record Get total size of UniRec record except variable-length...
INLINE_IMPL int mac_cmp(const mac_addr_t *addr1, const mac_addr_t *addr2)
var-len fields (generic string of bytes) 
uint16_t static_size
Size of static part. 
INLINE_IMPL int ur_get_link_index(ur_links_t *links, uint64_t link_bit_field)
Get index of link (0 - (n-1)) Function gets search link_indexes array for value corresponding to pass...
uint32_t ifc_out
output interface number (stored only if the direction == UR_TMPLT_DIRECTION_BI) 
int ur_array_resize(const ur_template_t *tmplt, void *rec, int field_id, int len)
Change length of a array field. 
#define ur_time_from_sec_nsec(sec, nsec)
Convert seconds and nanoseconds to ur_time_t. 
ur_field_id_t ur_last_statically_defined_id
Last statically defined field by UR_FIELDS(...) 
ur_field_id_t ur_last_id
The highest ID of a field + 1. 
memcpy(buffer, rec, ur_rec_size(tmplt, rec))
int ur_init(ur_static_field_specs_t field_specs_static)
Initialize UniRec structures Initialize UniRec structures. Function is called during defining first o...
#define ur_get_size(field_id)
Get size of UniRec field Get size of a fixed-length UniRec field. When variable-length field is passe...
int ur_ctx_set_input_template(trap_ctx_t *ctx, int ifc, ur_template_t *tmplt)
Set UniRec template to input interface on specified context. 
ur_field_id_t ur_iter_t
Type for identifying iteration id through all fields. 
#define UR_DEFAULT_LENGTH_OF_FIELD_TYPE
INLINE_IMPL int mac_from_str(const char *str, mac_addr_t *addr)
void ur_print_template(ur_template_t *tmplt)
Print UniRec template Print static_size, first_dynamic and table of offsets to stdout (for debugging)...
ur_field_id_linked_list_t * ur_undefine_fields
linked list of free (undefined) IDs 
char * ur_ifc_data_fmt_to_field_names(const char *ifc_data_fmt)
Parses field names from data format Function parses field names from data format and returns pointer ...
INLINE_IMPL void ip_to_str(const ip_addr_t *addr, char *str)
int compare_fields(const void *field1, const void *field2)
Compare fields Compare two fields. This function is for sorting the fields in the right order...
char * ur_template_string_delimiter(const ur_template_t *tmplt, int delimiter)
Get UniRec specifier of the tmplt template with delimiter between fields. 
uint16_t * offset
Table of offsets. 
#define UR_UNINITIALIZED
Indicator if the UniRec has not been initialized by calling function ur_init. 
ur_links_t * ur_create_links(const char *mask)
Create and initialize links structure. Create new links structure and initialize it from link mask in...
uint8_t intialized
If the UniRec is initialized by function ur_init variable is set to UR_INITIALIZED, otherwise 0. 
uint16_t first_dynamic
First dynamic (variable-length) field. Index to the ids array. 
ur_field_type_t * ur_field_types
Array of types of fields. 
INLINE_IMPL int ip_is4(const ip_addr_t *addr)
void ur_copy_fields(const ur_template_t *dst_tmplt, void *dst, const ur_template_t *src_tmplt, const void *src)
Copy data from one UniRec record to another. Copies all fields present in both templates from src to ...
void ur_var_change_size(const ur_template_t *tmplt, void *rec, int field_id, int new_val_len)
#define ur_set_var_offset(tmplt, rec, field_id, offset_val)
Set offset of variable-length field in the record. Set offset of specified variable-length field in t...
UniRec template. It contains a table mapping a field to its position in an UniRec record...
const char UR_MEMORY_ERROR[]
#define ur_size_of(type)
Get size of UniRec type Get size of fixed-length UniRec type. For variable-length type return value <...
uint16_t offset_size
size of offset table. 
INLINE_IMPL ip_addr_t ip_from_4_bytes_le(char b[4])
int ur_template_compare(const ur_template_t *tmpltA, const ur_template_t *tmpltB)
Compares fields of two UniRec templates Function compares only sets of UniRec fields (direction is no...
ur_iter_t ur_iter_fields_record_order(const ur_template_t *tmplt, int index)
Iterate over fields of a template This function can be used to iterate over all fields of a given tem...
int ur_get_id_by_name(const char *name)
Get ID of a field by its name Get ID of a field by its name. 
const char * ur_field_type_str[]
UniRec data types. 
#define UR_DEFAULT_LENGTH_OF_FIELD_NAME
const char * ur_values_get_name_start_end(uint32_t start, uint32_t end, int32_t value)
Returns name of specified value (Helper function) Helper function for ur_values_get_name. This function returns name of specified value and field, which is defined in values file. Function needs start and end index of a field. 
#define ur_template_string(tmplt)
Get string of a template Get names and sizes of fields separated by comma. Return string has to be fr...
INLINE_IMPL char * ip_get_v4_as_bytes(const ip_addr_t *addr)