summaryrefslogtreecommitdiffstats
path: root/lib/csv.h
diff options
context:
space:
mode:
Diffstat (limited to '')
-rw-r--r--lib/csv.h181
1 files changed, 181 insertions, 0 deletions
diff --git a/lib/csv.h b/lib/csv.h
new file mode 100644
index 0000000..c780ab6
--- /dev/null
+++ b/lib/csv.h
@@ -0,0 +1,181 @@
+// SPDX-License-Identifier: GPL-2.0-or-later
+/* CSV
+ * Copyright (C) 2013 Cumulus Networks, Inc.
+ */
+
+#ifndef __CSV_H__
+#define __CSV_H__
+
+/*
+ * CSV encoding and decoding routines.
+ *
+ * Example:
+ * Encoding side:
+ *
+ * csv_t *csv;
+ * csv_record_t *fstrec;
+ * csv_record_t *rec;
+ * char buf[BUFSIZ];
+ *
+ * csv = csv_init(csv, buf, BUFSIZ);
+ * ...
+ * fstrec = csv_encode(csv, 2, "hello", "world");
+ * rec = csv_encode(csv, 2, "foo", "bar");
+ * ...
+ * fstrec = csv_encode_record(csv, fstrec, 2, "HELLO", "WORLD");
+ * ...
+ * csv_clean(csv);
+ *
+ * Decoding side:
+ *
+ * csv_t *csv;
+ * csv_record_t *rec;
+ * csv_field_t *fld;
+ * char *rcvdbuf;
+ *
+ * csv = csv_init(csv, rcvdbuf, BUFSIZ);
+ * ...
+ * csv_decode(csv);
+ * csv_dump(csv);
+ *
+ * for (rec = csv_record_iter(csv); rec;
+ * rec = csv_record_iter_next(rec)) {
+ * ...
+ * for (str = csv_field_iter(rec, &fld); str;
+ * str = csv_field_iter_next(&fld)) {
+ * ...
+ * }
+ * }
+ * ...
+ * csv_clean(csv);
+ */
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <stdarg.h>
+#include <sys/queue.h>
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+typedef struct _csv_field_t_ csv_field_t;
+typedef struct _csv_record_t_ csv_record_t;
+typedef struct _csv_t_ csv_t;
+
+/**
+ * Initialize the CSV structure (if necessary, allocate first). Point to
+ * the passed string buffer.
+ */
+csv_t *csv_init(csv_t *csv, char *buf, int buflen);
+
+/**
+ * Encode the variable list of arguments as CSV fields. The csv structure
+ * should have been initialized (with the string buffer). The fields get
+ * concatenated into the string.
+ */
+csv_record_t *csv_encode(csv_t *csv, int count, ...);
+
+/**
+ * Encode the variable list arguments into an existing record, essentially
+ * overwriting the record. No checking is done for consistency. The number
+ * of fields should be the same as what was encoded and the length of each
+ * field should also be the same as what was encoded before. The "rec"
+ * parameter should be the same as what was returned from a previous call
+ * to csv_encode().
+ *
+ * Useful for message encoding/decoding that get passed around between
+ * processes/nodes - e.g. the message header record can be rewritten AFTER
+ * encoding all other records, with new information such as total length.
+ */
+csv_record_t *csv_encode_record(csv_t *csv, csv_record_t *rec, int count, ...);
+
+/**
+ * Decode a CSV formatted string. The csv structure should have been
+ * initialized (with the string). The function creates a LIST of records
+ * (csv_record_t structure) where each record is in turn a LIST of fields
+ * (csv_field_t structure). The record points to the string containing the
+ * list of fields. Similarly, the field points to the field string.
+ * NB: csv initialized for discrete buf , caller will pass inbuf
+ */
+void csv_decode(csv_t *csv, char *inbuf);
+
+/**
+ * Dump all fields of a decoded CSV to stderr
+ */
+void csv_dump(csv_t *csv);
+
+/**
+ * Total length of all characters encoded in the CSV.
+ */
+int csvlen(csv_t *csv);
+
+void csv_clean(csv_t *csv);
+void csv_free(csv_t *csv);
+
+/**
+ * Iterate through the records and fields of an encoded/decoded CSV.
+ */
+csv_record_t *csv_record_iter(csv_t *csv);
+csv_record_t *csv_record_iter_next(csv_record_t *rec);
+char *csv_field_iter(csv_record_t *rec, csv_field_t **fld);
+char *csv_field_iter_next(csv_field_t **fld);
+
+/**
+ * Return the length of field
+ */
+int csv_field_len(csv_field_t *fld);
+
+/**
+ * Checks to see if a record belongs to a csv
+ */
+int csv_is_record_valid(csv_t *csv, csv_record_t *in_rec);
+
+/**
+ * concat two records in a csv
+ * Returns the newly formed record which includes fields from rec1 and rec2
+ * rec1 and rec2 are removed
+ */
+csv_record_t *csv_concat_record(csv_t *csv, csv_record_t *rec1,
+ csv_record_t *rec2);
+
+/**
+ * Remove a record from csv
+ * Only works when csv has discrete record bufs
+ */
+void csv_remove_record(csv_t *csv, csv_record_t *rec);
+
+/**
+ * Insert a record into csv
+ * Only works when csv has discrete record bufs
+ */
+void csv_insert_record(csv_t *csv, csv_record_t *rec);
+
+/**
+ * append fields to a record
+ * Only works when csv has discrete record bufs
+ */
+csv_record_t *csv_append_record(csv_t *csv, csv_record_t *rec, int count, ...);
+
+/**
+ * Serialize contents of csv into string
+ * Only works when csv has discrete record bufs
+ */
+int csv_serialize(csv_t *csv, char *msgbuf, int msglen);
+
+/**
+ * Clone a record.
+ * Only works when csv has discrete record bufs
+ */
+void csv_clone_record(csv_t *csv, csv_record_t *in_rec, csv_record_t **out_rec);
+
+/**
+ * Return number of records
+ */
+int csv_num_records(csv_t *csv);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif