-
Notifications
You must be signed in to change notification settings - Fork 1
/
jsonwriter.h
136 lines (113 loc) · 5.7 KB
/
jsonwriter.h
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
#ifndef JSONWRITER_H
#define JSONWRITER_H
#include <stdlib.h>
#include <stdint.h>
#include <stdio.h>
#include <inttypes.h>
#define JSW_STRLEN(x) strlen((const char *)x)
#ifdef __cplusplus
extern "C" {
#endif
# ifdef _WIN32
# define jsw_int64 __int64
# define JSW_INT64_MIN _I64_MIN
# define JSW_INT64_MAX _I64_MAX
# define JSW_INT64_PRINTF_FMT "%"PRId64
# else // not WIN
# define jsw_int64 int64_t
# define JSW_INT64_MIN INT64_MIN
# define JSW_INT64_MAX INT64_MAX
# define JSW_INT64_PRINTF_FMT "%" PRId64
# endif
enum jsonwriter_option {
jsonwriter_option_pretty = 0,
jsonwriter_option_compact = 1
};
enum jsonwriter_status {
jsonwriter_status_ok = 0, // no error
jsonwriter_status_out_of_memory = 1,
jsonwriter_status_invalid_value,
jsonwriter_status_misconfiguration,
jsonwriter_status_unrecognized_variant_type,
jsonwriter_status_invalid_end
};
struct jsonwriter_data;
typedef struct jsonwriter_data * jsonwriter_handle;
jsonwriter_handle jsonwriter_new(FILE *f);
jsonwriter_handle jsonwriter_new_stream(size_t (*write)(const void *restrict, size_t, size_t, void *restrict),
void *write_arg);
void jsonwriter_set_option(jsonwriter_handle h, enum jsonwriter_option opt);
void jsonwriter_flush(jsonwriter_handle h);
void jsonwriter_delete(jsonwriter_handle h);
int jsonwriter_start_object(jsonwriter_handle h);
int jsonwriter_start_array(jsonwriter_handle h);
enum jsonwriter_status jsonwriter_end_array(jsonwriter_handle h); // end an error, or return err
enum jsonwriter_status jsonwriter_end_object(jsonwriter_handle h); // end an object, or return err
enum jsonwriter_status jsonwriter_end(jsonwriter_handle h); // end either an array or an object, or return err
// to do: jsonwriter_end_array() and jsonwriter_end_object(): same as jsonwriter_end, but
// return an error if no matching open array/obj
int jsonwriter_end_all(jsonwriter_handle h);
int jsonwriter_object_keyn(jsonwriter_handle data, const char *key, size_t len_or_zero);
int jsonwriter_object_key(jsonwriter_handle h, const char *key);
#define jsonwriter_object_str(h, key, v) jsonwriter_object_key(h, key), jsonwriter_str(h, v)
#define jsonwriter_object_strn(h, key, v, len) jsonwriter_object_key(h, key), jsonwriter_strn(h, v, len)
#define jsonwriter_object_cstr(h, key, v) jsonwriter_object_key(h, key), jsonwriter_cstr(h, v)
#define jsonwriter_object_cstrn(h, key, v, len) jsonwriter_object_key(h, key), jsonwriter_cstrn(h, v, len)
#define jsonwriter_object_bool(h, key, v) jsonwriter_object_key(h, key), jsonwriter_bool(h, v)
#define jsonwriter_object_dbl(h, key, v) jsonwriter_object_key(h, key), jsonwriter_dbl(h, v)
#define jsonwriter_object_dblf(h, key, v, fmt, t) jsonwriter_object_key(h, key), jsonwriter_dblf(h, v, fmt, t)
#define jsonwriter_object_int(h, key, v) jsonwriter_object_key(h, key), jsonwriter_int(h, v)
#define jsonwriter_object_size_t(h, key, v) jsonwriter_object_key(h, key), jsonwriter_size_t(h, v)
#define jsonwriter_object_null(h, key) jsonwriter_object_key(h, key), jsonwriter_null(h)
#define jsonwriter_object_array(h, key) jsonwriter_object_key(h, key), jsonwriter_start_array(h)
#define jsonwriter_object_object(h, key) jsonwriter_object_key(h, key), jsonwriter_start_object(h)
int jsonwriter_str(jsonwriter_handle h, const unsigned char *s);
int jsonwriter_strn(jsonwriter_handle h, const unsigned char *s, size_t len);
int jsonwriter_cstr(jsonwriter_handle data, const char *s);
int jsonwriter_cstrn(jsonwriter_handle data, const char *s, size_t len);
int jsonwriter_bool(jsonwriter_handle h, unsigned char value);
int jsonwriter_dbl(jsonwriter_handle h, long double d);
int jsonwriter_dblf(jsonwriter_handle h, long double d, const char *format_string, unsigned char trim_trailing_zeros_after_dec);
int jsonwriter_size_t(jsonwriter_handle data, size_t sz);
int jsonwriter_int(jsonwriter_handle h, jsw_int64 i);
int jsonwriter_null(jsonwriter_handle h);
// optionally, you can configure jsonwriter to handle custom variant types
enum jsonwriter_datatype {
jsonwriter_datatype_null = 0,
jsonwriter_datatype_string = 1,
jsonwriter_datatype_integer = 2,
jsonwriter_datatype_float = 3,
jsonwriter_datatype_bool = 4,
jsonwriter_datatype_raw = 5, // already stringified, output verbatim
// possible to do:
// array
// object
};
struct jsonwriter_variant {
enum jsonwriter_datatype type;
union {
unsigned char b; // bool
long int i; // integer
long double dbl; // double
unsigned char *str; // string
// possible to do:
// void *array; // will require corresponding function pointers to get array size and elements
// void *object; // will require corresponding function pointers to get object keys and elements
} value;
};
// jsonwriter_set_variant_handler(): provide jsonwriter with a custom function that converts your data to a jsonwriter_variant
// with an optional cleanup callback
// returns 0 on success, nonzero on error
enum jsonwriter_status
jsonwriter_set_variant_handler(jsonwriter_handle h,
struct jsonwriter_variant (*to_jsw_variant)(void *),
void (*cleanup)(void *, struct jsonwriter_variant *));
// write a variant. will use custom to_jsw_variant() to convert data to jsonwriter_variant
enum jsonwriter_status jsonwriter_variant(jsonwriter_handle h, void *data);
// write raw data to the output stream. Note: caller is responsible for ensuring that
// the raw data is valid JSON
size_t jsonwriter_write_raw(jsonwriter_handle jsw, const unsigned char *s, size_t len);
#ifdef __cplusplus
}
#endif
#endif // #ifndef JSONWRITER_H