1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 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
|