UniRec  2.9.3
example_unirec.c
Go to the documentation of this file.
1 // ** Put header + licence here **
2 
3 /* Example of a module with a fixed set of input and output UniRec fields.
4  Input requires two numbers: FOO and BAR. Output contains fields FOO, BAR
5  and BAZ, where BAZ = FOO + BAR.
6  If input contains some other fields besides FOO and BAR, they are NOT copied
7  to the output. Output always consists of FOO, BAR, BAZ only.
8 */
9 
10 #include <stdio.h>
11 #include <stdlib.h>
12 #include <signal.h>
13 
14 #include <string.h>
15 #include "fields.c"
16 //Example of usage Unirec library
17 UR_FIELDS(
18  uint32 FOO,
19  uint32 BAR,
20  ipaddr IP,
21  string STR1,
22  string STR2,
23 )
24 
25 int main(int argc, char **argv)
26 {
27  char *buffer, *buffer2;
28 
29  // Create a record and store it to the buffer
30  {
31  // Create template
32  ur_template_t *tmplt = ur_create_template("FOO,BAR,IP,STR1", NULL);
33 
34  // Allocate memory for a record
35  void *rec = ur_create_record(tmplt, 512); // Pre-allocate 512 bytes for strings
36 
37  // Fill values into the record
38  ur_set(tmplt, rec, F_FOO, 12345);
39  ur_set(tmplt, rec, F_BAR, 54321);
40  ur_set(tmplt, rec, F_IP, ip_from_int(12345678));
41  ur_set_string(tmplt, rec, F_STR1, "Hello World!");
42  // Store record into a buffer
43  buffer = malloc(ur_rec_size(tmplt, rec));
44  memcpy(buffer, rec, ur_rec_size(tmplt, rec));
45 
46  // Free memory
47  free(rec);
48  ur_free_template(tmplt);
49  }
50 
51  // -----
52 
53  // Read data from the record in the buffer
54  {
55  // Create another template with the same set of fields (the set of fields MUST be the same, even if we don't need to work with all fields)
56  ur_template_t *tmplt = ur_create_template("FOO,BAR,IP,STR1", NULL);
57 
58  // Read FOO, IP and STR1 fields from the record in the buffer
59  // (to keep it simple, ip address is printed as a number)
60  printf("%u %u %u %s\n",
61  ur_get(tmplt, buffer, F_FOO), // Access to plain integer is simple
62  ip_get_v4_as_int(&(ur_get(tmplt, buffer, F_IP))), // IP address must be converted before print
63  ur_get_var_len(tmplt, buffer, F_STR1), // Returns length of the string (it is neccessary to use "%*s" since string in UniRec don't contain terminating '\0')
64  ur_get_ptr(tmplt, buffer, F_STR1) // Returns pointer to the beginning of the string
65  );
66  // -> should print "12345 12345678 13 Hello World!"
67 
68  ur_free_template(tmplt);
69  }
70 
71  // -----
72 
73  // Copy selected fields of the record into a new one and add two new fields,
74  // one is known before (STR2), one is newly defined (NEW)
75  {
76  // Define the field NEW
78  if (new_id < 0) {
79  fprintf(stderr, "ERROR: Can't define new unirec field 'NEW'");
80  exit(1);
81  }
82 
83  // Create templates matching the old and the new record
84  ur_template_t *tmplt1 = ur_create_template("FOO,BAR,IP,STR1", NULL);
85  ur_template_t *tmplt2 = ur_create_template("BAR,STR1,STR2,NEW", NULL);
86 
87  // Allocate buffer for the new record
88  buffer2 = ur_create_record(tmplt2, ur_get_var_len(tmplt1, buffer, F_STR1) + 64); // Allocate 64B for STR2
89 
90  // This function copies all fields present in both templates from buffer to buffer2
92  // TODO speciální funkce pro kopírovaní celé tmplt1, pokud víme, že tmplt2 je nadmonožinou tmplt1 (a pokud to tak bude efektivnější)
93 
94  // Record in buffer2 now contains fields BAR and STR1 with the same values as in buffer.
95  // Values of STR2 and NEW are undefined.
96 
97  // Set value of str2
98  ur_set_string(tmplt2, buffer2, F_STR2, "The second string");
99 
100  // Set value of NEW
101  // (we can't use ur_set because type of the field is not known at compile time)
102  *(uint16_t*)(ur_get_ptr_by_id(tmplt2, buffer2, new_id)) = 1;
105  }
106 
107  // -----
108 
109  // Read data from the record in the second buffer
110  {
111  // Create template with the second set of fields (we can use different order of fields, it doesn't matter)
112  ur_template_t *tmplt = ur_create_template("BAR,NEW,STR2,STR1", NULL);
113 
114  // The NEW field is already defined (it is stored globally) but we don't know its ID here
116  printf(" new field %d\n", new_id);
117 
118  // Read FOO, IP, STR1 and NEW fields from the record in the buffer
119  printf("%u %u %s %u %s %u\n",
120  ur_get(tmplt, buffer2, F_BAR),
121  ur_get_var_len(tmplt, buffer2, F_STR1),
122  ur_get_ptr(tmplt, buffer2, F_STR1),
123  ur_get_var_len(tmplt, buffer2, F_STR2),
124  ur_get_ptr(tmplt, buffer2, F_STR2),
125  *(uint16_t*)ur_get_ptr_by_id(tmplt, buffer2, new_id) // Access to dynamically defined fields is a little more complicated
126  );
127  // -> should print "54321 13 Hello World! 18 The second string 1"
128 
129  ur_free_template(tmplt);
130  }
131 
132  free(buffer);
133  free(buffer2);
134  ur_finalize();
135  return 0;
136 }
INLINE uint32_t ip_get_v4_as_int(ip_addr_t *addr)
Definition: ipaddr.h:157
ur_template_t * tmplt1
UR_FIELDS(uint32 FOO, uint32 BAR, ipaddr IP, string STR1, string STR2,) int main(int argc
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...
Definition: unirec.c:900
unsigned int (16b)
Definition: unirec.h:101
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...
Definition: unirec.c:636
ur_set(tmplt, rec, F_FOO, 12345)
#define ur_get(tmplt, data, field_id)
Get value of UniRec field Get value of a fixed-length UniRec field. For variable-length fields...
Definition: unirec.h:418
#define ur_get_ptr(tmplt, data, field_id)
Get pointer to UniRec field Get pointer to fixed or varible length statically defined UniRec field...
Definition: unirec.h:430
*uint16_t * ur_get_ptr_by_id(tmplt2, buffer2, new_id))
ur_free_template(tmplt)
free(rec)
#define ur_rec_size(tmplt, rec)
Get size of UniRec record (static and variable length) Get total size of whole UniRec record...
Definition: unirec.h:680
ur_copy_fields(tmplt2, buffer2, tmplt1, buffer)
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))
void * rec
void * ur_create_record(const ur_template_t *tmplt, uint16_t max_var_size)
Definition: unirec.c:1214
#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...
Definition: unirec.h:474
int16_t ur_field_id_t
Type of UniRec field identifiers.
Definition: unirec.h:136
INLINE ip_addr_t ip_from_int(uint32_t i)
Definition: ipaddr.h:183
ur_finalize()
Definition: unirec.c:734
char ** argv
buffer
buffer2
memcpy(buffer, rec, ur_rec_size(tmplt, rec))
UniRec template. It contains a table mapping a field to its position in an UniRec record...
Definition: unirec.h:191
ur_field_id_t new_id
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.
Definition: unirec.c:774
ur_template_t * tmplt2
ur_set_string(tmplt, rec, F_STR1, "Hello World!")