cwist
Modern C web framework with libttak runtime
Loading...
Searching...
No Matches
json_builder.c
Go to the documentation of this file.
4#include <stdlib.h>
5#include <stdio.h>
6#include <string.h>
7
23 if (!b) return NULL;
25 if (!b->buffer) {
26 cwist_free(b);
27 return NULL;
28 }
29 b->needs_comma = false;
30 return b;
31}
32
38 if (b) {
39 if (b->buffer) {
41 }
42 cwist_free(b);
43 }
44}
45
56static void append_comma_if_needed(cwist_json_builder *b) {
57 if (b && b->buffer && b->needs_comma) {
59 }
60}
61
74static void append_json_escaped_str(cwist_sstring *buf, const char *str) {
75 if (!str) return;
76 cwist_sstring_append(buf, "\"");
77 const char *start = str;
78 const char *p = str;
79 while (*p) {
80 const char *esc = NULL;
81 char ucode[8];
82 switch (*p) {
83 case '"': esc = "\\\""; break;
84 case '\\': esc = "\\\\"; break;
85 case '\b': esc = "\\b"; break;
86 case '\f': esc = "\\f"; break;
87 case '\n': esc = "\\n"; break;
88 case '\r': esc = "\\r"; break;
89 case '\t': esc = "\\t"; break;
90 default:
91 if ((unsigned char)*p < 0x20) {
92 snprintf(ucode, sizeof(ucode), "\\u%04x", (unsigned char)*p);
93 esc = ucode;
94 }
95 break;
96 }
97 if (esc) {
98 if (p > start) {
99 char tmp[4096];
100 size_t seg_len = (size_t)(p - start);
101 while (seg_len > 0) {
102 size_t chunk = seg_len < sizeof(tmp) - 1 ? seg_len : sizeof(tmp) - 1;
104 tmp[chunk] = '\0';
106 start += chunk;
107 seg_len -= chunk;
108 }
109 }
111 start = p + 1;
112 }
113 p++;
114 }
115 if (p > start) {
117 }
118 cwist_sstring_append(buf, "\"");
119}
120
131static void append_key_if_present(cwist_json_builder *b, const char *key) {
132 if (key) {
133 append_json_escaped_str(b->buffer, key);
135 }
136}
137
143 if (!b || !b->buffer) return;
144 append_comma_if_needed(b);
146 b->needs_comma = false;
147}
148
154 if (!b || !b->buffer) return;
156 b->needs_comma = true;
157}
158
165 if (!b || !b->buffer) return;
166 append_comma_if_needed(b);
167 if (key) {
168 append_json_escaped_str(b->buffer, key);
170 } else {
172 }
173 b->needs_comma = false;
174}
175
181 if (!b || !b->buffer) return;
183 b->needs_comma = true;
184}
185
192void cwist_json_add_string(cwist_json_builder *b, const char *key, const char *value) {
193 if (!b || !b->buffer) return;
194 append_comma_if_needed(b);
195 append_key_if_present(b, key);
196 if (value) {
197 append_json_escaped_str(b->buffer, value);
198 } else {
199 cwist_sstring_append(b->buffer, "null");
200 }
201 b->needs_comma = true;
202}
203
210void cwist_json_add_int(cwist_json_builder *b, const char *key, int value) {
211 if (!b || !b->buffer) return;
212 append_comma_if_needed(b);
213 append_key_if_present(b, key);
214 char buf[32];
215 snprintf(buf, sizeof(buf), "%d", value);
217 b->needs_comma = true;
218}
219
226void cwist_json_add_bool(cwist_json_builder *b, const char *key, bool value) {
227 if (!b || !b->buffer) return;
228 append_comma_if_needed(b);
229 append_key_if_present(b, key);
230 cwist_sstring_append(b->buffer, value ? "true" : "false");
231 b->needs_comma = true;
232}
233
239void cwist_json_add_null(cwist_json_builder *b, const char *key) {
240 if (!b || !b->buffer) return;
241 append_comma_if_needed(b);
242 append_key_if_present(b, key);
243 cwist_sstring_append(b->buffer, "null");
244 b->needs_comma = true;
245}
246
253 if (!b || !b->buffer) return NULL;
254 return b->buffer->data;
255}
Memory allocation wrappers backed by libttak.
void cwist_free(void *ptr)
Free memory obtained via cwist_alloc/cwist_strdup/etc.
Definition alloc.c:52
void * cwist_alloc(size_t size)
Allocate zeroed memory tracked by libttak.
Definition alloc.c:17
Safe string type with helper methods.
cwist_sstring * cwist_sstring_create(void)
Create a new sstring instance.
Definition sstring.c:802
cwist_error_t cwist_sstring_append(cwist_sstring *str, const char *data)
Append a C string.
Definition sstring.c:559
void cwist_sstring_destroy(cwist_sstring *str)
Destroy an sstring instance.
Definition sstring.c:823
Simple JSON string builder utility.
const char * cwist_json_get_raw(cwist_json_builder *b)
Expose the builder's raw character buffer.
void cwist_json_add_string(cwist_json_builder *b, const char *key, const char *value)
Append a JSON string value.
void cwist_json_begin_object(cwist_json_builder *b)
Begin a JSON object in the current builder context.
void cwist_json_end_object(cwist_json_builder *b)
Close the current JSON object.
void cwist_json_add_int(cwist_json_builder *b, const char *key, int value)
Append a JSON integer value.
void cwist_json_builder_destroy(cwist_json_builder *b)
Release a builder and its owned string buffer.
void cwist_json_add_bool(cwist_json_builder *b, const char *key, bool value)
Append a JSON boolean literal.
cwist_json_builder * cwist_json_builder_create(void)
Allocate a new JSON builder with an empty output buffer.
void cwist_json_add_null(cwist_json_builder *b, const char *key)
Append a JSON null literal.
void cwist_json_begin_array(cwist_json_builder *b, const char *key)
Begin a JSON array, optionally as the value for an object key.
void cwist_json_end_array(cwist_json_builder *b)
Close the current JSON array.
size_t cap
Definition otel.c:56
Simple JSON string builder utility.
cwist_sstring * buffer
char * data
Access directly only when raw handling is necessary.
Definition sstring.h:15