aboutsummaryrefslogtreecommitdiff
path: root/any_json.h
diff options
context:
space:
mode:
authorFederico Angelilli <code@fedang.net>2025-01-15 03:04:23 +0100
committerFederico Angelilli <code@fedang.net>2025-01-15 03:04:23 +0100
commit752fae256623eb55f257ffd88c14b91f605770d3 (patch)
treeefdf08031fbed270023e436e65d47496bf30d041 /any_json.h
parent97e75f4ed2d6a3d9ad8f87547e14f36cbdf72826 (diff)
Add any_json write api
Diffstat (limited to 'any_json.h')
-rw-r--r--any_json.h158
1 files changed, 158 insertions, 0 deletions
diff --git a/any_json.h b/any_json.h
new file mode 100644
index 0000000..021a997
--- /dev/null
+++ b/any_json.h
@@ -0,0 +1,158 @@
+#ifndef ANY_JSON_INCLUDE
+#define ANY_JSON_INCLUDE
+
+#include <stdbool.h>
+
+typedef int (*any_json_write_fputs_t)(const char *string, void *stream);
+
+typedef struct {
+ void *stream;
+ any_json_write_fputs_t fputs;
+ int indent;
+ bool first;
+ bool pretty;
+} any_json_write_t;
+
+void any_json_write_init(any_json_write_t *json, void *stream,
+ any_json_write_fputs_t fputs, bool pretty);
+
+bool any_json_write_open_object(any_json_write_t *json);
+
+bool any_json_write_close_object(any_json_write_t *json);
+
+bool any_json_write_open_array(any_json_write_t *json);
+
+bool any_json_write_close_array(any_json_write_t *json);
+
+bool any_json_write_member(any_json_write_t *json, const char *key);
+
+bool any_json_write_string(any_json_write_t *json, const char *string);
+
+bool any_json_write_number(any_json_write_t *json, double value);
+
+bool any_json_write_bool(any_json_write_t *json, bool value);
+
+bool any_json_write_null(any_json_write_t *json);
+
+#endif
+
+#ifdef ANY_JSON_IMPLEMENT
+
+#include <string.h>
+
+#ifndef ANY_JSON_INDENT
+#define ANY_JSON_INDENT 4
+#endif
+
+static void any_json_write_indent(any_json_write_t *json, bool newline)
+{
+ if (json->pretty) {
+ if (newline)
+ json->fputs("\n", json->stream);
+
+ for (int i = 0; i < json->indent; i++)
+ json->fputs(" ", json->stream);
+ }
+}
+
+void any_json_write_init(any_json_write_t *json, void *stream,
+ any_json_write_fputs_t fputs, bool pretty)
+{
+ memset(json, 0, sizeof(any_json_write_t));
+ json->stream = stream;
+ json->fputs = fputs;
+ json->pretty = pretty;
+}
+
+bool any_json_write_open_object(any_json_write_t *json)
+{
+ json->indent += ANY_JSON_INDENT;
+ json->first = true;
+ json->fputs("{", json->stream);
+}
+
+bool any_json_write_close_object(any_json_write_t *json)
+{
+ json->indent -= ANY_JSON_INDENT;
+ json->first = false;
+ any_json_write_indent(json, true);
+ json->fputs("}", json->stream);
+}
+
+bool any_json_write_open_array(any_json_write_t *json)
+{
+ json->indent += ANY_JSON_INDENT;
+ json->first = true;
+ json->fputs("[", json->stream);
+}
+
+bool any_json_write_close_array(any_json_write_t *json)
+{
+ json->indent -= ANY_JSON_INDENT;
+ json->first = false;
+ any_json_write_indent(json, true);
+ json->fputs("]", json->stream);
+}
+
+bool any_json_write_member(any_json_write_t *json, const char *key)
+{
+ if (!json->first)
+ json->fputs(",", json->stream);
+
+ any_json_write_indent(json, true);
+ json->first = false;
+
+ if (key != NULL) {
+ any_json_write_string(json, key);
+ json->fputs(json->pretty ? ": " : ":", json->stream);
+ }
+}
+
+bool any_json_write_string(any_json_write_t *json, const char *string)
+{
+ json->fputs("\"", json->stream);
+ json->fputs(string, json->stream);
+ json->fputs("\"", json->stream);
+}
+
+bool any_json_write_number(any_json_write_t *json, double value)
+{
+ char buffer[1080] = { 0 };
+ snprintf(buffer, sizeof(buffer), "%lf", value);
+ json->fputs(buffer, json->stream);
+}
+
+bool any_json_write_bool(any_json_write_t *json, bool value)
+{
+ json->fputs(value ? "true" : "false", json->stream);
+}
+
+bool any_json_write_null(any_json_write_t *json)
+{
+ json->fputs("null", json->stream);
+}
+
+#endif
+
+// MIT License
+//
+// Copyright (c) 2025 Federico Angelilli
+//
+// Permission is hereby granted, free of charge, to any person obtaining a copy
+// of this software and associated documentation files (the "Software"), to deal
+// in the Software without restriction, including without limitation the rights
+// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+// copies of the Software, and to permit persons to whom the Software is
+// furnished to do so, subject to the following conditions:
+//
+// The above copyright notice and this permission notice shall be included in all
+// copies or substantial portions of the Software.
+//
+// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+// SOFTWARE.
+//