-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathjWrite.h
More file actions
212 lines (192 loc) · 7.87 KB
/
jWrite.h
File metadata and controls
212 lines (192 loc) · 7.87 KB
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
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
//
// jWrite.h
//
// A *really* simple JSON writer in C (C89)
// - a collection of functions to generate JSON semi-automatically
//
// The idea is to simplify writing native C values into a JSON string and
// to provide some error trapping to ensure that the result is valid JSON.
//
// Example:
// jwOpen( buffer, buflen, JW_OBJECT, JW_PRETTY ); // open root node as object
// jwObj_string( "key", "value" );
// jwObj_int( "int", 1 );
// jwObj_array( "anArray");
// jwArr_int( 0 );
// jwArr_int( 1 );
// jwArr_int( 2 );
// jwEnd();
// err= jwClose(); // close root object
//
// results in:
//
// {
// "key": "value",
// "int": 1,
// "anArray": [
// 0,
// 1,
// 2
// ]
// }
//
// Note that jWrite handles string quoting and getting commas in the right place.
// If the sequence of calls is incorrect
// e.g.
// jwOpen( buffer, buflen, JW_OBJECT, 1 );
// jwObj_string( "key", "value" );
// jwArr_int( 0 );
// ...
//
// then the error code returned from jwClose() would indicate that you attempted to
// put an array element into an object (instead of a key:value pair)
// To locate the error, the supplied buffer has the JSON created upto the error point
// and a call to jwErrorPos() would return the function call at which the error occurred
// - in this case 3, the 3rd function call "jwArr_int(0)" is not correct at this point.
//
// The root JSON type can be JW_OBJECT or JW_ARRAY.
//
// For more information on each function, see the prototypes below.
//
//
// GLOBAL vs. Application-Supplied Control Structure
// -------------------------------------------------
// jWrite requires a jWriteControl structure to save the internal state.
// For many applications it is much simpler for this to be a global variable as
// used by the above examples.
//
// To use multiple instances of jWrite, an application has to supply unique instances
// of jWriteControl structures.
//
// This feature is enabled by commenting out the definition of JW_GLOBAL_CONTROL_STRUCT
//
// All the jWrite functions then take an additional parameter: a ptr to the structure
// e.g.
// struct jWriteControl jwc;
//
// jwOpen( &jwc, buffer, buflen, JW_OBJECT, 1 );
// jwObj_string( &jwc, "key", "value" );
// jwObj_int( &jwc, "int", 1 );
// jwObj_array( &jwc, "anArray");
// jwArr_int( &jwc, 0 );
// jwArr_int( &jwc, 1 );
// jwArr_int( &jwc, 2 );
// jwEnd( &jwc );
// err= jwClose( &jwc );
//
// - which is more flexible, but a pain to type in !
//
// TonyWilk, Mar 2015
//
//
// #define JW_GLOBAL_CONTROL_STRUCT // <--- comment this out to use applic-supplied jWriteControl
#ifndef JWRITE_SINGLE_PRECISION
#define JWRITE_FLOAT double
#else
#define JWRITE_FLOAT float
#endif
#define JWRITE_STACK_DEPTH 32 // max nesting depth of objects/arrays
#define JW_COMPACT 0 // output string control for jwOpen()
#define JW_PRETTY 1 // pretty adds \n and indentation
enum jwNodeType { JW_OBJECT = 1, JW_ARRAY };
struct jwNodeStack {
enum jwNodeType nodeType;
int elementNo;
};
struct jWriteControl {
char* buffer; // pointer to application's buffer
unsigned int buflen; // length of buffer
char* bufp; // current write position in buffer
char tmpbuf[32]; // local buffer for int/float conversions
int error; // error code
int callNo; // API call on which error occurred
struct jwNodeStack nodeStack[JWRITE_STACK_DEPTH]; // stack of array/object nodes
int stackpos;
int isPretty; // 1= pretty output (inserts \n and spaces)
};
// Error Codes
// -----------
#define JWRITE_OK 0
#define JWRITE_BUF_FULL 1 // output buffer full
#define JWRITE_NOT_ARRAY 2 // tried to write Array value into Object
#define JWRITE_NOT_OBJECT 3 // tried to write Object key/value into Array
#define JWRITE_STACK_FULL 4 // array/object nesting > JWRITE_STACK_DEPTH
#define JWRITE_STACK_EMPTY 5 // stack underflow error (too many 'end's)
#define JWRITE_NEST_ERROR 6 // nesting error, not all objects closed when jwClose() called
// API functions
// -------------
// Returns '\0'-termianted string describing the error (as returned by jwClose())
//
char* jwErrorToString(int err);
#ifdef JW_GLOBAL_CONTROL_STRUCT /* USING GLOBAL g_jWriteControl */
// jwOpen
// - initialises jWrite with the application supplied 'buffer' of length 'buflen'
// in operation, the buffer will always contain a valid '\0'-terminated string
// - jWrite will not overrun the buffer (it returns an "output buffer full" error)
// - rootType is the base JSON type: JW_OBJECT or JW_ARRAY
// - isPretty controls 'prettifying' the output: JW_PRETTY or JW_COMPACT
void jwOpen(char* buffer, unsigned int buflen, enum jwNodeType rootType, int isPretty);
// jwClose
// - closes the element opened by jwOpen()
// - returns error code (0 = JWRITE_OK)
// - after an error, all following jWrite calls are skipped internally
// so the error code is for the first error detected
int jwClose();
// jwErrorPos
// - if jwClose returned an error, this function returns the number of the jWrite function call
// which caused that error.
int jwErrorPos();
// Object insertion functions
// - used to insert "key":"value" pairs into an object
//
void jwObj_string(const char* key, const char* value);
void jwObj_int(const char* key, int value);
void jwObj_number(const char* key, JWRITE_FLOAT value, int precision);
void jwObj_bool(const char* key, int oneOrZero);
void jwObj_null(const char* key);
void jwObj_object(const char* key);
void jwObj_array(const char* key);
// Array insertion functions
// - used to insert "value" elements into an array
//
void jwArr_string(const char* value);
void jwArr_int(int value);
void jwArr_number(JWRITE_FLOAT value);
void jwArr_bool(int oneOrZero);
void jwArr_null();
void jwArr_object();
void jwArr_array();
// jwEnd
// - defines the end of an Object or Array definition
int jwEnd();
// these 'raw' routines write the JSON value as the contents of rawtext
// i.e. enclosing quotes are not added
// - use if your app. supplies its own value->string functions
//
void jwObj_raw(const char* key, const char* rawtext);
void jwArr_raw(const char* rawtext);
#else /* JW_GLOBAL_CONTROL_STRUCT not defined */
// Same API functions with app-supplied control struct option
//
void jwOpen(struct jWriteControl* jwc, char* buffer, unsigned int buflen, enum jwNodeType rootType, int isPretty);
int jwClose(struct jWriteControl* jwc);
int jwErrorPos(struct jWriteControl* jwc);
void jwObj_string(struct jWriteControl* jwc, const char* key, const char* value);
void jwObj_int(struct jWriteControl* jwc, const char* key, int value);
void jwObj_number(struct jWriteControl* jwc, const char* key, JWRITE_FLOAT value, int precision);
void jwObj_bool(struct jWriteControl* jwc, const char* key, int oneOrZero);
void jwObj_null(struct jWriteControl* jwc, const char* key);
void jwObj_object(struct jWriteControl* jwc, const char* key);
void jwObj_array(struct jWriteControl* jwc, const char* key);
void jwArr_string(struct jWriteControl* jwc, const char* value);
void jwArr_int(struct jWriteControl* jwc, int value);
void jwArr_number(struct jWriteControl* jwc, JWRITE_FLOAT value);
void jwArr_bool(struct jWriteControl* jwc, int oneOrZero);
void jwArr_null(struct jWriteControl* jwc);
void jwArr_object(struct jWriteControl* jwc);
void jwArr_array(struct jWriteControl* jwc);
int jwEnd(struct jWriteControl* jwc);
void jwObj_raw(struct jWriteControl* jwc, const char* key, const char* rawtext);
void jwArr_raw(struct jWriteControl* jwc, const char* rawtext);
#endif /* JW_GLOBAL_CONTROL_STRUCT */
/* end of jWrite.h */