]> git.proxmox.com Git - mirror_frr.git/blob - lib/csv.h
Merge pull request #12798 from donaldsharp/rib_match_multicast
[mirror_frr.git] / lib / csv.h
1 // SPDX-License-Identifier: GPL-2.0-or-later
2 /* CSV
3 * Copyright (C) 2013 Cumulus Networks, Inc.
4 */
5
6 #ifndef __CSV_H__
7 #define __CSV_H__
8
9 /*
10 * CSV encoding and decoding routines.
11 *
12 * Example:
13 * Encoding side:
14 *
15 * csv_t *csv;
16 * csv_record_t *fstrec;
17 * csv_record_t *rec;
18 * char buf[BUFSIZ];
19 *
20 * csv = csv_init(csv, buf, BUFSIZ);
21 * ...
22 * fstrec = csv_encode(csv, 2, "hello", "world");
23 * rec = csv_encode(csv, 2, "foo", "bar");
24 * ...
25 * fstrec = csv_encode_record(csv, fstrec, 2, "HELLO", "WORLD");
26 * ...
27 * csv_clean(csv);
28 *
29 * Decoding side:
30 *
31 * csv_t *csv;
32 * csv_record_t *rec;
33 * csv_field_t *fld;
34 * char *rcvdbuf;
35 *
36 * csv = csv_init(csv, rcvdbuf, BUFSIZ);
37 * ...
38 * csv_decode(csv);
39 * csv_dump(csv);
40 *
41 * for (rec = csv_record_iter(csv); rec;
42 * rec = csv_record_iter_next(rec)) {
43 * ...
44 * for (str = csv_field_iter(rec, &fld); str;
45 * str = csv_field_iter_next(&fld)) {
46 * ...
47 * }
48 * }
49 * ...
50 * csv_clean(csv);
51 */
52 #include <stdio.h>
53 #include <stdlib.h>
54 #include <string.h>
55 #include <stdarg.h>
56 #include <sys/queue.h>
57
58 #ifdef __cplusplus
59 extern "C" {
60 #endif
61
62 typedef struct _csv_field_t_ csv_field_t;
63 typedef struct _csv_record_t_ csv_record_t;
64 typedef struct _csv_t_ csv_t;
65
66 /**
67 * Initialize the CSV structure (if necessary, allocate first). Point to
68 * the passed string buffer.
69 */
70 csv_t *csv_init(csv_t *csv, char *buf, int buflen);
71
72 /**
73 * Encode the variable list of arguments as CSV fields. The csv structure
74 * should have been initialized (with the string buffer). The fields get
75 * concatenated into the string.
76 */
77 csv_record_t *csv_encode(csv_t *csv, int count, ...);
78
79 /**
80 * Encode the variable list arguments into an existing record, essentially
81 * overwriting the record. No checking is done for consistency. The number
82 * of fields should be the same as what was encoded and the length of each
83 * field should also be the same as what was encoded before. The "rec"
84 * parameter should be the same as what was returned from a previous call
85 * to csv_encode().
86 *
87 * Useful for message encoding/decoding that get passed around between
88 * processes/nodes - e.g. the message header record can be rewritten AFTER
89 * encoding all other records, with new information such as total length.
90 */
91 csv_record_t *csv_encode_record(csv_t *csv, csv_record_t *rec, int count, ...);
92
93 /**
94 * Decode a CSV formatted string. The csv structure should have been
95 * initialized (with the string). The function creates a LIST of records
96 * (csv_record_t structure) where each record is in turn a LIST of fields
97 * (csv_field_t structure). The record points to the string containing the
98 * list of fields. Similarly, the field points to the field string.
99 * NB: csv initialized for discrete buf , caller will pass inbuf
100 */
101 void csv_decode(csv_t *csv, char *inbuf);
102
103 /**
104 * Dump all fields of a decoded CSV to stderr
105 */
106 void csv_dump(csv_t *csv);
107
108 /**
109 * Total length of all characters encoded in the CSV.
110 */
111 int csvlen(csv_t *csv);
112
113 void csv_clean(csv_t *csv);
114 void csv_free(csv_t *csv);
115
116 /**
117 * Iterate through the records and fields of an encoded/decoded CSV.
118 */
119 csv_record_t *csv_record_iter(csv_t *csv);
120 csv_record_t *csv_record_iter_next(csv_record_t *rec);
121 char *csv_field_iter(csv_record_t *rec, csv_field_t **fld);
122 char *csv_field_iter_next(csv_field_t **fld);
123
124 /**
125 * Return the length of field
126 */
127 int csv_field_len(csv_field_t *fld);
128
129 /**
130 * Checks to see if a record belongs to a csv
131 */
132 int csv_is_record_valid(csv_t *csv, csv_record_t *in_rec);
133
134 /**
135 * concat two records in a csv
136 * Returns the newly formed record which includes fields from rec1 and rec2
137 * rec1 and rec2 are removed
138 */
139 csv_record_t *csv_concat_record(csv_t *csv, csv_record_t *rec1,
140 csv_record_t *rec2);
141
142 /**
143 * Remove a record from csv
144 * Only works when csv has discrete record bufs
145 */
146 void csv_remove_record(csv_t *csv, csv_record_t *rec);
147
148 /**
149 * Insert a record into csv
150 * Only works when csv has discrete record bufs
151 */
152 void csv_insert_record(csv_t *csv, csv_record_t *rec);
153
154 /**
155 * append fields to a record
156 * Only works when csv has discrete record bufs
157 */
158 csv_record_t *csv_append_record(csv_t *csv, csv_record_t *rec, int count, ...);
159
160 /**
161 * Serialize contents of csv into string
162 * Only works when csv has discrete record bufs
163 */
164 int csv_serialize(csv_t *csv, char *msgbuf, int msglen);
165
166 /**
167 * Clone a record.
168 * Only works when csv has discrete record bufs
169 */
170 void csv_clone_record(csv_t *csv, csv_record_t *in_rec, csv_record_t **out_rec);
171
172 /**
173 * Return number of records
174 */
175 int csv_num_records(csv_t *csv);
176
177 #ifdef __cplusplus
178 }
179 #endif
180
181 #endif