blob: 90a9d83c889de7b6fe3879e0a6d6195fc120bff1 (
plain)
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
|
/**
* @file csv.h
* @brief Minimal RFC 4180 CSV reader, internal to this library.
*
* The batch endpoint answers `text/csv`, and its values may contain commas and
* are then double-quoted with `""` escaping. Splitting on commas would corrupt
* exactly the street names most likely to matter, so this reads the real
* grammar: quoted fields, embedded commas, embedded newlines, CRLF or LF line
* endings, and a leading UTF-8 BOM.
*/
#ifndef CEPIS_CSV_H
#define CEPIS_CSV_H
#include <stddef.h>
/** One parsed record. Owns its fields. */
typedef struct csv_row {
char **fields;
size_t count;
} csv_row_t;
typedef struct csv_reader csv_reader_t;
/**
* @brief Start reading @p len bytes of CSV.
* @return A reader borrowing @p data, or `NULL` on allocation failure. @p data
* must outlive the reader.
*/
csv_reader_t *csv_reader_new(const char *data, size_t len);
/**
* @brief Read the next record into @p out.
* @return 1 when a record was read, 0 at end of input, -1 on a malformed
* record or allocation failure. @p out is only valid after 1, and the
* caller releases it with ::csv_row_free.
*/
int csv_reader_next(csv_reader_t *reader, csv_row_t *out);
/** @brief Release a record's fields and zero it. `NULL` is ignored. */
void csv_row_free(csv_row_t *row);
/** @brief Release a reader. `NULL` is ignored. */
void csv_reader_free(csv_reader_t *reader);
#endif
|