aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorFederico Angelilli <code@fedang.net>2025-01-15 20:49:07 +0100
committerFederico Angelilli <code@fedang.net>2025-01-15 20:49:07 +0100
commit944f6d5425c0e8dbb85e82f810b313434ae703a2 (patch)
tree96d870fb187a3632a2719f57e5a7e108103e83a1
parentdf7832c999e48fcaf9d6815420b307a77b046868 (diff)
Implement string escape for any_json
-rw-r--r--any_json.h59
-rw-r--r--test/json.c10
-rw-r--r--test/log.c2
3 files changed, 62 insertions, 9 deletions
diff --git a/any_json.h b/any_json.h
index 021a997..e7e4419 100644
--- a/any_json.h
+++ b/any_json.h
@@ -39,6 +39,7 @@ bool any_json_write_null(any_json_write_t *json);
#ifdef ANY_JSON_IMPLEMENT
#include <string.h>
+#include <ctype.h>
#ifndef ANY_JSON_INDENT
#define ANY_JSON_INDENT 4
@@ -108,17 +109,69 @@ bool any_json_write_member(any_json_write_t *json, const char *key)
}
}
+#ifndef ANY_JSON_BUFFER_SIZE
+#define ANY_JSON_BUFFER_SIZE 512
+#endif
+
bool any_json_write_string(any_json_write_t *json, const char *string)
{
json->fputs("\"", json->stream);
- json->fputs(string, json->stream);
+
+ char buffer[ANY_JSON_BUFFER_SIZE] = { 0 };
+ size_t t = 0;
+
+ for (size_t i = 0; string[i] != '\0'; ++i) {
+ if (t + 6 >= sizeof(buffer)) {
+ buffer[t] = '\0';
+ json->fputs(buffer, json->stream);
+ t = 0;
+ }
+
+ if (iscntrl(string[i])) {
+ buffer[t++] = '\\';
+
+ switch (string[i]) {
+ case '\b':
+ buffer[t++] = 'b';
+ break;
+ case '\f':
+ buffer[t++] = 'f';
+ break;
+ case '\n':
+ buffer[t++] = 'n';
+ break;
+ case '\r':
+ buffer[t++] = 'r';
+ break;
+ case '\t':
+ buffer[t++] = 't';
+ break;
+ default:
+ t += sprintf(buffer + t, "u%04x", string[i]);
+ break;
+ }
+ } else {
+ if (string[i] == '"' || string[i] == '\\' || string[i] == '/')
+ buffer[t++] = '\\';
+
+ buffer[t++] = string[i];
+ }
+ }
+
+ buffer[t] = '\0';
+ json->fputs(buffer, json->stream);
+
json->fputs("\"", json->stream);
}
+#ifndef ANY_JSON_NUMBER_FORMAT
+#define ANY_JSON_NUMBER_FORMAT "%.17g"
+#endif
+
bool any_json_write_number(any_json_write_t *json, double value)
{
- char buffer[1080] = { 0 };
- snprintf(buffer, sizeof(buffer), "%lf", value);
+ char buffer[ANY_JSON_BUFFER_SIZE] = { 0 };
+ snprintf(buffer, sizeof(buffer), ANY_JSON_NUMBER_FORMAT, value);
json->fputs(buffer, json->stream);
}
diff --git a/test/json.c b/test/json.c
index 635f474..e491c44 100644
--- a/test/json.c
+++ b/test/json.c
@@ -55,9 +55,9 @@ void test_write(bool pretty)
const char *props[][2] = {
{ "name", "test" },
- { "scope", "local" },
- { "project", "any_json" },
- { "author", "me" },
+ { "scope", "local \x1f" },
+ { "project", "any_json とてもクールで縮みません" },
+ { "author", "me \"trying\" hard" },
{ 0 },
};
@@ -82,10 +82,10 @@ void test_write(bool pretty)
any_json_write_open_array(&json);
{
any_json_write_member(&json, NULL);
- any_json_write_string(&json, "nested");
+ any_json_write_string(&json, "nested \\ \" /");
any_json_write_member(&json, NULL);
- any_json_write_string(&json, "array");
+ any_json_write_string(&json, "array \f \b \n \r \t o");
}
any_json_write_close_array(&json);
}
diff --git a/test/log.c b/test/log.c
index c3e0dd5..7f7d889 100644
--- a/test/log.c
+++ b/test/log.c
@@ -1,6 +1,6 @@
#include <stdbool.h>
-#define ANY_LOG_LOCKING
+//#define ANY_LOG_LOCKING
#define ANY_LOG_IMPLEMENT
#define ANY_LOG_MODULE "test"