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
|
/**
* @file internal.h
* @brief Helpers shared between the translation units of this library.
*
* Nothing here is part of the public ABI.
*/
#ifndef CEPIS_INTERNAL_H
#define CEPIS_INTERNAL_H
#include <stdarg.h>
#include <stdbool.h>
#include <stddef.h>
#include "cepis.h"
#include "csv.h"
#include "json.h"
/** A growable, always NUL-terminated byte buffer. */
typedef struct cepis_buf {
char *data;
size_t len;
size_t cap;
} cepis_buf_t;
/** @brief Put @p buf into the empty state. Allocates nothing. */
void cepis_buf_init(cepis_buf_t *buf);
/** @brief Append @p len bytes. @return `false` on allocation failure. */
bool cepis_buf_append(cepis_buf_t *buf, const char *data, size_t len);
/** @brief Append a NUL-terminated string. */
bool cepis_buf_append_str(cepis_buf_t *buf, const char *text);
/** @brief Release the buffer and return it to the empty state. */
void cepis_buf_free(cepis_buf_t *buf);
/** @brief `strdup`, tolerating a `NULL` argument by copying `""`. */
char *cepis_strdup(const char *text);
/**
* @brief Fill @p err, tolerating `NULL`.
* @return @p status, so callers can `return cepis_set_error(...)`.
*/
cepis_status_t cepis_set_error(cepis_error_t *err, cepis_status_t status,
long http_status, double retry_after,
const char *fmt, ...);
/**
* @brief Build an address from a parsed JSON object.
* @param object The decoded body.
* @param raw The body as it arrived, copied into
* ::cepis_address_t::raw. May be `NULL`.
* @param raw_len Length of @p raw.
* @return An owned address, or `NULL` on allocation failure.
*
* Unknown members are ignored but preserved in `raw`, so a field the API grows
* cannot break this client. A malformed `geo` block yields `geo == NULL` rather
* than failing the whole address: the rest of the response is still useful.
*/
cepis_address_t *cepis_address_from_json(const json_value_t *object,
const char *raw, size_t raw_len);
/**
* @brief Build an address from one CSV record and the header record.
* @return An owned address, or `NULL` on allocation failure. The result never
* carries a coordinate: the CSV has no `geo` column.
*/
cepis_address_t *cepis_address_from_csv(const csv_row_t *header,
const csv_row_t *record);
/** @brief Build a health report from a parsed JSON object. */
cepis_health_t *cepis_health_from_json(const json_value_t *object);
/**
* @brief Read the `faixa` block of a 404 body into @p out.
* @param object The decoded body, which may be `NULL`.
* @param out Filled and returning `true`, or untouched and returning
* `false`.
* @return `true` only when the block is present, is an object and names a
* municipality.
*
* Deliberately total: a body that is not JSON, a `faixa` that is null, a
* string, an array or an object without `localidade` all mean "the API named
* no municipality". A 404 is already the answer, and failing to read the
* garnish must never turn it into a different one.
*/
bool cepis_faixa_from_json(const json_value_t *object, cepis_faixa_t *out);
#endif
|