diff options
| -rw-r--r-- | any_json.h | 158 | ||||
| -rw-r--r-- | test/json.c | 139 |
2 files changed, 297 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. +// diff --git a/test/json.c b/test/json.c new file mode 100644 index 0000000..635f474 --- /dev/null +++ b/test/json.c @@ -0,0 +1,139 @@ +#include <string.h> +#include <stdio.h> + +#define ANY_JSON_IMPLEMENT +#include "any_json.h" + +// TODO +void test_read() +{ + const char *src = + "{\n" + "\t\"hello\": 1,\n" + "\t\"key2\": true,\n" + "\t\"_aaa__\": { },\n" + "\t\"dict\": [1, 2, { \"key\": \"value\" }],\n" + "\t\"varx\": 1.1\n" + "}\n"; + + //any_json_reader_t json; + //any_json_reader_init(&json, src, strlen(src)); + + //while ((key = any_json_reader_key(&json)) != NULL) { + // switch (any_json_reader_type(&json)) { + // case ANY_JSON_STRING: + // break; + + // case ANY_JSON_NUMBER: + // break; + + // case ANY_JSON_BOOL: + // break; + + // case ANY_JSON_NULL: + // break; + // } + //} + + //if (any_json_next_object(&json)) { + // char *key; + // while ((key = any_json_next_key(&json)) != NULL) { + // printf("KEY: %s\n", key); + + // any_json_ + // } + // any_json_end(&json); + //} +} + +void test_write(bool pretty) +{ + any_json_write_t json; + any_json_write_init(&json, stdout, (any_json_write_fputs_t)fputs, pretty); + + any_json_write_open_object(&json); + + const char *props[][2] = { + { "name", "test" }, + { "scope", "local" }, + { "project", "any_json" }, + { "author", "me" }, + { 0 }, + }; + + for (int i = 0; props[i][0] != NULL; i++) { + any_json_write_member(&json, props[i][0]); + any_json_write_string(&json, props[i][1]); + } + + any_json_write_member(&json, "list"); + any_json_write_open_array(&json); + { + any_json_write_member(&json, NULL); + any_json_write_number(&json, 1111111); + + any_json_write_member(&json, NULL); + any_json_write_number(&json, 49e32); + + any_json_write_member(&json, NULL); + any_json_write_number(&json, 99.99); + + any_json_write_member(&json, NULL); + any_json_write_open_array(&json); + { + any_json_write_member(&json, NULL); + any_json_write_string(&json, "nested"); + + any_json_write_member(&json, NULL); + any_json_write_string(&json, "array"); + } + any_json_write_close_array(&json); + } + any_json_write_close_array(&json); + + any_json_write_member(&json, "sub"); + any_json_write_open_object(&json); + { + any_json_write_member(&json, "data"); + any_json_write_open_object(&json); + { + any_json_write_member(&json, "handle"); + any_json_write_null(&json); + + any_json_write_member(&json, "version"); + any_json_write_number(&json, 1.1); + } + any_json_write_close_object(&json); + + any_json_write_member(&json, "pack"); + any_json_write_open_array(&json); + { + any_json_write_member(&json, NULL); + any_json_write_string(&json, "bin"); + + any_json_write_member(&json, NULL); + any_json_write_string(&json, "lib"); + + any_json_write_member(&json, NULL); + any_json_write_bool(&json, true); + } + any_json_write_close_array(&json); + } + any_json_write_close_object(&json); + + any_json_write_close_object(&json); + + puts("\n"); +} + +int main() +{ + printf("JSON WRITE TEST\n"); + test_write(false); + + printf("JSON PRETTY WRITE TEST\n"); + test_write(true); + + return 0; +} + |
