diff --git a/lib/webfuse_provider/impl/json/writer.c b/lib/webfuse_provider/impl/json/writer.c index 817ef39..9b151e4 100644 --- a/lib/webfuse_provider/impl/json/writer.c +++ b/lib/webfuse_provider/impl/json/writer.c @@ -1,17 +1,25 @@ #include "webfuse_provider/impl/json/writer.h" +#include "webfuse_provider/impl/util/base64.h" #include #include +#include +#include -#define WFP_JSON_WRITER_MAX_LEVEL 8 +#define WFP_JSON_WRITER_MAX_LEVEL 7 +#define WFP_INT_BUFFER_SIZE 64 enum wfp_json_writer_state { - WFP_JSON_WRITER_STATE_INIT + WFP_JSON_WRITER_STATE_INIT, + WFP_JSON_WRITER_STATE_ARRAY_FIRST, + WFP_JSON_WRITER_STATE_ARRAY_NEXT, + WFP_JSON_WRITER_STATE_OBJECT_FIRST, + WFP_JSON_WRITER_STATE_OBJECT_NEXT }; struct wfp_json_writer { - enum wfp_json_writer_state state[WFP_JSON_WRITER_MAX_LEVEL]; + enum wfp_json_writer_state state[WFP_JSON_WRITER_MAX_LEVEL + 1]; size_t level; size_t capacity; size_t pre; @@ -20,6 +28,34 @@ struct wfp_json_writer char * raw_data; }; +static char +wfp_impl_json_writer_get_esc( + char c) +{ + switch (c) + { + case '\\': return '\\'; + case '\"': return '\"'; + case '/' : return '/'; + case '\b': return 'b'; + case '\f': return 'f'; + case '\n': return 'n'; + case '\r': return 'r'; + case '\t': return 't'; + default: + // error + return '/'; + } +} + +static void +wfp_impl_json_writer_write_raw_char( + struct wfp_json_writer * writer, + char value) +{ + writer->data[writer->offset++] = value; +} + static void wfp_impl_json_writer_reserve( struct wfp_json_writer * writer, @@ -40,13 +76,47 @@ wfp_impl_json_writer_reserve( } } -void -wfp_impl_json_writer_write_raw_char( +static void +wfp_impl_json_writer_begin_value( + struct wfp_json_writer * writer) +{ + wfp_impl_json_writer_reserve(writer, 1); + if (writer->state[writer->level] == WFP_JSON_WRITER_STATE_ARRAY_NEXT) + { + wfp_impl_json_writer_write_raw_char(writer, ','); + } +} + +static void +wfp_impl_json_writer_end_value( + struct wfp_json_writer * writer) +{ + if (WFP_JSON_WRITER_STATE_ARRAY_FIRST == writer->state[writer->level]) + { + writer->state[writer->level] = WFP_JSON_WRITER_STATE_ARRAY_NEXT; + } +} + +static void +wfp_impl_json_writer_push( struct wfp_json_writer * writer, - char value) + enum wfp_json_writer_state state) { - writer->data[writer->offset] = value; - writer->offset++; + if (writer->level < WFP_JSON_WRITER_MAX_LEVEL) + { + writer->level++; + writer->state[writer->level] = state; + } +} + +static void +wfp_impl_json_writer_pop( + struct wfp_json_writer * writer) +{ + if (writer->level > 0) + { + writer->level--; + } } void @@ -84,9 +154,20 @@ wfp_impl_json_writer_dispose( free(writer); } +void +wfp_impl_json_writer_reset( + struct wfp_json_writer * writer) +{ + writer->level = 0; + writer->state[writer->level] = WFP_JSON_WRITER_STATE_INIT; + writer->offset = 0; +} + + char * wfp_impl_json_writer_take_data( - struct wfp_json_writer * writer) + struct wfp_json_writer * writer, + size_t * size) { wfp_impl_json_writer_reserve(writer, 1); writer->data[writer->offset] = '\0'; @@ -94,6 +175,11 @@ wfp_impl_json_writer_take_data( char * result = writer->raw_data; writer->raw_data = NULL; + if (NULL != size) + { + *size = writer->offset; + } + return result; } @@ -102,7 +188,41 @@ wfp_impl_json_writer_write_int( struct wfp_json_writer * writer, int value) { + wfp_impl_json_writer_begin_value(writer); + wfp_impl_json_writer_reserve(writer, WFP_INT_BUFFER_SIZE); + + bool const is_signed = (0 > value); + char buffer[WFP_INT_BUFFER_SIZE]; + size_t offset = WFP_INT_BUFFER_SIZE; + buffer[--offset] = '\0'; + if (is_signed) + { + if (INT_MIN == value) + { + char const actual = (char) abs(value % 10); + buffer[--offset] = (char) ('0' + actual); + value /= 10; + } + value = -value; + } + + do + { + char const actual = (char) (value % 10); + buffer[--offset] = ('0' + actual); + value /= 10; + } + while (0 != value); + + if (is_signed) + { + buffer[--offset] = '-'; + } + + size_t const length = (WFP_INT_BUFFER_SIZE - offset - 1); + wfp_impl_json_writer_write_raw(writer, &(buffer[offset]), length); + wfp_impl_json_writer_end_value(writer); } void @@ -110,6 +230,41 @@ wfp_impl_json_writer_write_string( struct wfp_json_writer * writer, char const * value) { + wfp_impl_json_writer_begin_value(writer); + + size_t length = strlen(value); + wfp_impl_json_writer_reserve(writer, length + 2); + + wfp_impl_json_writer_write_raw_char(writer, '\"'); + for(size_t i = 0; i < length; i++) + { + char c = value[i]; + if ((' ' <= c) && (c != '\\') && (c != '\"')) + { + wfp_impl_json_writer_write_raw_char(writer, c); + } + else + { + char esc = wfp_impl_json_writer_get_esc(c); + + wfp_impl_json_writer_reserve(writer, (length - i) + 2); + wfp_impl_json_writer_write_raw_char(writer, '\\'); + wfp_impl_json_writer_write_raw_char(writer, esc); + } + + } + wfp_impl_json_writer_write_raw_char(writer, '\"'); + + wfp_impl_json_writer_end_value(writer); +} + +void +wfp_impl_json_writer_write_string_nocheck( + struct wfp_json_writer * writer, + char const * value) +{ + wfp_impl_json_writer_begin_value(writer); + size_t length = strlen(value); wfp_impl_json_writer_reserve(writer, length + 2); @@ -117,6 +272,7 @@ wfp_impl_json_writer_write_string( wfp_impl_json_writer_write_raw(writer, value, length); wfp_impl_json_writer_write_raw_char(writer, '\"'); + wfp_impl_json_writer_end_value(writer); } void @@ -125,14 +281,27 @@ wfp_impl_json_writer_write_bytes( char const * data, size_t length) { + wfp_impl_json_writer_begin_value(writer); + + size_t encoded_length = wfp_impl_base64_encoded_size(length); + wfp_impl_json_writer_reserve(writer, encoded_length + 2); + + wfp_impl_json_writer_write_raw_char(writer, '\"'); + wfp_impl_base64_encode((uint8_t const*) data, length, &(writer->data[writer->offset]), encoded_length); + writer->offset += encoded_length; + wfp_impl_json_writer_write_raw_char(writer, '\"'); + wfp_impl_json_writer_end_value(writer); } void wfp_impl_json_writer_object_begin( struct wfp_json_writer * writer) { + wfp_impl_json_writer_begin_value(writer); wfp_impl_json_writer_reserve(writer, 1); + + wfp_impl_json_writer_push(writer, WFP_JSON_WRITER_STATE_OBJECT_FIRST); wfp_impl_json_writer_write_raw_char(writer, '{'); } @@ -142,6 +311,9 @@ wfp_impl_json_writer_object_end( { wfp_impl_json_writer_reserve(writer, 1); wfp_impl_json_writer_write_raw_char(writer, '}'); + + wfp_impl_json_writer_pop(writer); + wfp_impl_json_writer_end_value(writer); } void @@ -150,13 +322,32 @@ wfp_impl_json_writer_object_key( char const * key) { wfp_impl_json_writer_reserve(writer, 1); - wfp_impl_json_writer_write_raw_char(writer, '['); + + size_t length = strlen(key); + wfp_impl_json_writer_reserve(writer, length + 4); + + if (WFP_JSON_WRITER_STATE_OBJECT_NEXT == writer->state[writer->level]) + { + wfp_impl_json_writer_write_raw_char(writer, ','); + } + else + { + writer->state[writer->level] = WFP_JSON_WRITER_STATE_OBJECT_NEXT; + } + + wfp_impl_json_writer_write_raw_char(writer, '\"'); + wfp_impl_json_writer_write_raw(writer, key, length); + wfp_impl_json_writer_write_raw_char(writer, '\"'); + wfp_impl_json_writer_write_raw_char(writer, ':'); } void wfp_impl_json_writer_array_begin( struct wfp_json_writer * writer) { + wfp_impl_json_writer_begin_value(writer); + wfp_impl_json_writer_push(writer, WFP_JSON_WRITER_STATE_ARRAY_FIRST); + wfp_impl_json_writer_reserve(writer, 1); wfp_impl_json_writer_write_raw_char(writer, '['); } @@ -167,4 +358,7 @@ wfp_impl_json_writer_array_end( { wfp_impl_json_writer_reserve(writer, 1); wfp_impl_json_writer_write_raw_char(writer, ']'); + + wfp_impl_json_writer_pop(writer); + wfp_impl_json_writer_end_value(writer); } \ No newline at end of file diff --git a/lib/webfuse_provider/impl/json/writer.h b/lib/webfuse_provider/impl/json/writer.h index c779dcf..9f01e10 100644 --- a/lib/webfuse_provider/impl/json/writer.h +++ b/lib/webfuse_provider/impl/json/writer.h @@ -4,7 +4,7 @@ #ifndef __cplusplus #include #else -#include +#include #endif #ifdef __cplusplus @@ -23,9 +23,14 @@ extern void wfp_impl_json_writer_dispose( struct wfp_json_writer * writer); +extern void +wfp_impl_json_writer_reset( + struct wfp_json_writer * writer); + extern char * wfp_impl_json_writer_take_data( - struct wfp_json_writer * writer); + struct wfp_json_writer * writer, + size_t * size); extern void wfp_impl_json_writer_write_int( @@ -37,6 +42,11 @@ wfp_impl_json_writer_write_string( struct wfp_json_writer * writer, char const * value); +extern void +wfp_impl_json_writer_write_string_nocheck( + struct wfp_json_writer * writer, + char const * value); + extern void wfp_impl_json_writer_write_bytes( struct wfp_json_writer * writer, diff --git a/lib/webfuse_provider/impl/message.c b/lib/webfuse_provider/impl/message.c index 7943a5d..f82a2e0 100644 --- a/lib/webfuse_provider/impl/message.c +++ b/lib/webfuse_provider/impl/message.c @@ -11,6 +11,7 @@ extern struct wfp_message * wfp_message_create(json_t const * value) struct wfp_message * message = (struct wfp_message *) data; message->data = &data[sizeof(struct wfp_message) + LWS_PRE]; message->length = length; + message->raw_data = NULL; json_dumpb(value, message->data, length, JSON_COMPACT); @@ -20,5 +21,6 @@ extern struct wfp_message * wfp_message_create(json_t const * value) void wfp_message_dispose( struct wfp_message * message) { + free(message->raw_data); free(message); } diff --git a/lib/webfuse_provider/impl/message.h b/lib/webfuse_provider/impl/message.h index 776f848..1d55ddb 100644 --- a/lib/webfuse_provider/impl/message.h +++ b/lib/webfuse_provider/impl/message.h @@ -15,6 +15,7 @@ struct wfp_message { struct wfp_slist_item item; char * data; + char * raw_data; size_t length; }; diff --git a/lib/webfuse_provider/impl/message_writer.c b/lib/webfuse_provider/impl/message_writer.c index df83ada..b7fd77a 100644 --- a/lib/webfuse_provider/impl/message_writer.c +++ b/lib/webfuse_provider/impl/message_writer.c @@ -2,25 +2,30 @@ #include "webfuse_provider/impl/message.h" #include "webfuse_provider/impl/util/base64.h" #include "webfuse_provider/impl/dirbuffer.h" +#include "webfuse_provider/impl/json/writer.h" -#include #include #include +#include struct wfp_message_writer { - json_t * result; - json_t * error; + struct wfp_json_writer * json_writer; int id; + bool is_finished; }; struct wfp_message_writer * wfp_impl_message_writer_create(int id) { struct wfp_message_writer * writer = malloc(sizeof(writer)); - writer->result = json_object(); - writer->error = NULL; + writer->json_writer = wfp_impl_json_writer_create(1024, LWS_PRE); writer->id = id; + writer->is_finished = false; + + wfp_impl_json_writer_object_begin(writer->json_writer); + wfp_impl_json_writer_object_key(writer->json_writer, "result"); + wfp_impl_json_writer_object_begin(writer->json_writer); return writer; } @@ -29,8 +34,7 @@ void wfp_impl_message_writer_dispose( struct wfp_message_writer * writer) { - json_decref(writer->result); - json_decref(writer->error); + wfp_impl_json_writer_dispose(writer->json_writer); free(writer); } @@ -38,29 +42,19 @@ struct wfp_message * wfp_impl_message_writer_take_message( struct wfp_message_writer * writer) { - json_t * response = json_object(); - - if (writer->result) + if (!writer->is_finished) { - json_object_set_new(response, "result", writer->result); + wfp_impl_json_writer_object_end(writer->json_writer); + wfp_impl_json_writer_object_key(writer->json_writer, "id"); + wfp_impl_json_writer_write_int(writer->json_writer, writer->id); + wfp_impl_json_writer_object_end(writer->json_writer); + writer->is_finished = true; } - else - { - json_object_set_new(response, "error", writer->error); - } - json_object_set_new(response, "id", json_integer(writer->id)); - - size_t const length = json_dumpb(response, NULL, 0, JSON_COMPACT); - char * data = malloc(sizeof(struct wfp_message) + LWS_PRE + length); - struct wfp_message * message = (struct wfp_message *) data; - message->data = &data[sizeof(struct wfp_message) + LWS_PRE]; - message->length = length; + struct wfp_message * message = malloc(sizeof(struct wfp_message)); + message->raw_data = wfp_impl_json_writer_take_data(writer->json_writer, &message->length); + message->data = &(message->raw_data[LWS_PRE]); - json_dumpb(response, message->data, length, JSON_COMPACT); - - - json_decref(response); return message; } @@ -70,7 +64,8 @@ wfp_impl_message_writer_add_int( char const * key, int value) { - json_object_set_new(writer->result, key, json_integer(value)); + wfp_impl_json_writer_object_key(writer->json_writer, key); + wfp_impl_json_writer_write_int(writer->json_writer, value); } void @@ -79,7 +74,8 @@ wfp_impl_message_writer_add_string( char const * key, char const * value) { - json_object_set_new(writer->result, key, json_string(value)); + wfp_impl_json_writer_object_key(writer->json_writer, key); + wfp_impl_json_writer_write_string(writer->json_writer, value); } void @@ -89,13 +85,8 @@ wfp_impl_message_writer_add_bytes( char const * data, size_t length) { - size_t const size = wfp_impl_base64_encoded_size(length) + 1; - char * buffer = malloc(size); - wfp_impl_base64_encode((uint8_t const *) data, length, buffer, size); - - json_object_set_new(writer->result, "data", json_string(buffer)); - - free(buffer); + wfp_impl_json_writer_object_key(writer->json_writer, key); + wfp_impl_json_writer_write_bytes(writer->json_writer, data, length); } void @@ -103,8 +94,36 @@ wfp_impl_message_writer_add_dirbuffer( struct wfp_message_writer * writer, struct wfp_dirbuffer * dirbuffer) { - json_decref(writer->result); - writer->result = wfp_impl_dirbuffer_take(dirbuffer); + wfp_impl_json_writer_reset(writer->json_writer); + + wfp_impl_json_writer_object_begin(writer->json_writer); + wfp_impl_json_writer_object_key(writer->json_writer, "result"); + wfp_impl_json_writer_array_begin(writer->json_writer); + + json_t * entries = wfp_impl_dirbuffer_take(dirbuffer); + for (size_t i = 0; i < json_array_size(entries); i++) + { + json_t * entry = json_array_get(entries, i); + char const * name = json_string_value(json_object_get(entry, "name")); + int inode = json_integer_value(json_object_get(entry, "inode")); + + wfp_impl_json_writer_object_begin(writer->json_writer); + wfp_impl_json_writer_object_key(writer->json_writer, "name"); + wfp_impl_json_writer_write_string(writer->json_writer, name); + wfp_impl_json_writer_object_key(writer->json_writer, "inode"); + wfp_impl_json_writer_write_int(writer->json_writer, inode); + wfp_impl_json_writer_object_end(writer->json_writer); + + } + json_decref(entries); + + wfp_impl_json_writer_array_end(writer->json_writer); + + wfp_impl_json_writer_object_key(writer->json_writer, "id"); + wfp_impl_json_writer_write_int(writer->json_writer, writer->id); + wfp_impl_json_writer_object_end(writer->json_writer); + + writer->is_finished = true; } void @@ -112,10 +131,17 @@ wfp_impl_message_writer_set_error( struct wfp_message_writer * writer, int error_code) { - json_decref(writer->result); - writer->result = NULL; - - json_decref(writer->error); - writer->error = json_object(); - json_object_set_new(writer->error, "code", json_integer(error_code)); + wfp_impl_json_writer_reset(writer->json_writer); + + wfp_impl_json_writer_object_begin(writer->json_writer); + wfp_impl_json_writer_object_key(writer->json_writer, "error"); + wfp_impl_json_writer_object_begin(writer->json_writer); + wfp_impl_json_writer_object_key(writer->json_writer, "code"); + wfp_impl_json_writer_write_int(writer->json_writer, error_code); + wfp_impl_json_writer_object_end(writer->json_writer); + wfp_impl_json_writer_object_key(writer->json_writer, "id"); + wfp_impl_json_writer_write_int(writer->json_writer, writer->id); + wfp_impl_json_writer_object_end(writer->json_writer); + + writer->is_finished = true; } diff --git a/meson.build b/meson.build index fde6a39..6289195 100644 --- a/meson.build +++ b/meson.build @@ -112,6 +112,7 @@ alltests = executable('alltests', 'test/webfuse_provider/mocks/mock_provider_client.cc', 'test/webfuse_provider/mocks/mock_provider.cc', 'test/webfuse_provider/mocks/mock_jsonrpc_proxy.cc', + 'test/webfuse_provider/json/test_json_writer.cc', 'test/webfuse_provider/jsonrpc/mock_timer_callback.cc', 'test/webfuse_provider/jsonrpc/mock_timer.cc', 'test/webfuse_provider/jsonrpc/test_is_request.cc', diff --git a/test/webfuse_provider/json/test_json_writer.cc b/test/webfuse_provider/json/test_json_writer.cc new file mode 100644 index 0000000..78d2b6b --- /dev/null +++ b/test/webfuse_provider/json/test_json_writer.cc @@ -0,0 +1,234 @@ +#include "webfuse_provider/impl/json/writer.h" +#include +#include +#include + +namespace +{ + +std::string write_int(int value) +{ + wfp_json_writer * writer = wfp_impl_json_writer_create(128,0); + wfp_impl_json_writer_write_int(writer, value); + char * data = wfp_impl_json_writer_take_data(writer, nullptr); + std::string result = data; + + wfp_impl_json_writer_dispose(writer); + free(data); + + return result; +} + +} + +TEST(json_writer, create_dispose) +{ + wfp_json_writer * writer = wfp_impl_json_writer_create(128,0); + wfp_impl_json_writer_dispose(writer); +} + +TEST(json_writer, write_int) +{ + + ASSERT_EQ("0", write_int(0)); + + ASSERT_EQ("5", write_int(5)); + ASSERT_EQ("23", write_int(23)); + ASSERT_EQ("42", write_int(42)); + + char int_max[80]; + snprintf(int_max, 80, "%d", INT_MAX); + ASSERT_EQ(int_max, write_int(INT_MAX)); + + ASSERT_EQ("-1", write_int(-1)); + ASSERT_EQ("-69", write_int(-69)); + ASSERT_EQ("-1091", write_int(-1091)); + ASSERT_EQ("-123456", write_int(-123456)); + ASSERT_EQ("-2147483647", write_int(-2147483647)); + + char int_min[80]; + snprintf(int_min, 80, "%d", INT_MIN); + ASSERT_EQ(int_min, write_int(INT_MIN)); + +} + +TEST(json_writer, write_empty_array) +{ + wfp_json_writer * writer = wfp_impl_json_writer_create(128,0); + wfp_impl_json_writer_array_begin(writer); + wfp_impl_json_writer_array_end(writer); + + char * data = wfp_impl_json_writer_take_data(writer, nullptr); + + ASSERT_STREQ("[]", data); + + wfp_impl_json_writer_dispose(writer); + free(data); +} + +TEST(json_writer, write_one_element_array) +{ + wfp_json_writer * writer = wfp_impl_json_writer_create(128,0); + wfp_impl_json_writer_array_begin(writer); + wfp_impl_json_writer_write_int(writer, 42); + wfp_impl_json_writer_array_end(writer); + + char * data = wfp_impl_json_writer_take_data(writer, nullptr); + + ASSERT_STREQ("[42]", data); + + wfp_impl_json_writer_dispose(writer); + free(data); +} + +TEST(json_writer, write_int_array) +{ + wfp_json_writer * writer = wfp_impl_json_writer_create(128,0); + wfp_impl_json_writer_array_begin(writer); + wfp_impl_json_writer_write_int(writer, 1); + wfp_impl_json_writer_write_int(writer, 2); + wfp_impl_json_writer_write_int(writer, 3); + wfp_impl_json_writer_array_end(writer); + + char * data = wfp_impl_json_writer_take_data(writer, nullptr); + + ASSERT_STREQ("[1,2,3]", data); + + wfp_impl_json_writer_dispose(writer); + free(data); +} + +TEST(json_writer, write_nested_array) +{ + wfp_json_writer * writer = wfp_impl_json_writer_create(128,0); + wfp_impl_json_writer_array_begin(writer); + + wfp_impl_json_writer_array_begin(writer); + wfp_impl_json_writer_array_end(writer); + + wfp_impl_json_writer_array_begin(writer); + wfp_impl_json_writer_write_int(writer, 1); + wfp_impl_json_writer_array_end(writer); + + wfp_impl_json_writer_array_begin(writer); + wfp_impl_json_writer_array_begin(writer); + wfp_impl_json_writer_write_int(writer, 1); + wfp_impl_json_writer_array_end(writer); + wfp_impl_json_writer_array_end(writer); + + wfp_impl_json_writer_array_end(writer); + + char * data = wfp_impl_json_writer_take_data(writer, nullptr); + + ASSERT_STREQ("[[],[1],[[1]]]", data); + + wfp_impl_json_writer_dispose(writer); + free(data); +} + + +TEST(json_writer, write_empty_object) +{ + wfp_json_writer * writer = wfp_impl_json_writer_create(128,0); + wfp_impl_json_writer_object_begin(writer); + wfp_impl_json_writer_object_end(writer); + + char * data = wfp_impl_json_writer_take_data(writer, nullptr); + + ASSERT_STREQ("{}", data); + + wfp_impl_json_writer_dispose(writer); + free(data); +} + +TEST(json_writer, write_one_element_object) +{ + wfp_json_writer * writer = wfp_impl_json_writer_create(128,0); + wfp_impl_json_writer_object_begin(writer); + wfp_impl_json_writer_object_key(writer, "answer"); + wfp_impl_json_writer_write_int(writer, 42); + wfp_impl_json_writer_object_end(writer); + + char * data = wfp_impl_json_writer_take_data(writer, nullptr); + + ASSERT_STREQ("{\"answer\":42}", data); + + wfp_impl_json_writer_dispose(writer); + free(data); +} + +TEST(json_writer, write_mixed_object) +{ + wfp_json_writer * writer = wfp_impl_json_writer_create(128,0); + wfp_impl_json_writer_object_begin(writer); + + wfp_impl_json_writer_object_key(writer, "a"); + wfp_impl_json_writer_write_int(writer, 42); + + wfp_impl_json_writer_object_key(writer, "b"); + wfp_impl_json_writer_write_string(writer, "0"); + + wfp_impl_json_writer_object_key(writer, "c"); + wfp_impl_json_writer_array_begin(writer); + wfp_impl_json_writer_array_end(writer); + + wfp_impl_json_writer_object_end(writer); + + char * data = wfp_impl_json_writer_take_data(writer, nullptr); + + ASSERT_STREQ("{\"a\":42,\"b\":\"0\",\"c\":[]}", data); + + wfp_impl_json_writer_dispose(writer); + free(data); +} + +TEST(json_writer, write_nested_object) +{ + wfp_json_writer * writer = wfp_impl_json_writer_create(128,0); + wfp_impl_json_writer_object_begin(writer); + + wfp_impl_json_writer_object_key(writer, "a"); + wfp_impl_json_writer_object_begin(writer); + wfp_impl_json_writer_object_key(writer, "b"); + wfp_impl_json_writer_object_begin(writer); + wfp_impl_json_writer_object_key(writer, "c"); + wfp_impl_json_writer_object_begin(writer); + wfp_impl_json_writer_object_end(writer); + wfp_impl_json_writer_object_end(writer); + wfp_impl_json_writer_object_end(writer); + + wfp_impl_json_writer_object_end(writer); + + char * data = wfp_impl_json_writer_take_data(writer, nullptr); + + ASSERT_STREQ("{\"a\":{\"b\":{\"c\":{}}}}", data); + + wfp_impl_json_writer_dispose(writer); + free(data); +} + +TEST(json_writer, escape_string) +{ + wfp_json_writer * writer = wfp_impl_json_writer_create(128,0); + wfp_impl_json_writer_write_string(writer, "\"\\/\b\f\n\r\t"); + + char * data = wfp_impl_json_writer_take_data(writer, nullptr); + + ASSERT_STREQ("\"\\\"\\\\/\\b\\f\\n\\r\\t\"", data); + + wfp_impl_json_writer_dispose(writer); + free(data); +} + +TEST(json_writer, write_bytes) +{ + wfp_json_writer * writer = wfp_impl_json_writer_create(128,0); + wfp_impl_json_writer_write_bytes(writer, "1234", 4); + + char * data = wfp_impl_json_writer_take_data(writer, nullptr); + + ASSERT_STREQ("\"MTIzNA==\"", data); + + wfp_impl_json_writer_dispose(writer); + free(data); +} diff --git a/test/webfuse_provider/test_util/webfuse_server.cc b/test/webfuse_provider/test_util/webfuse_server.cc index b57f247..6e4527a 100644 --- a/test/webfuse_provider/test_util/webfuse_server.cc +++ b/test/webfuse_provider/test_util/webfuse_server.cc @@ -170,7 +170,6 @@ public: { std::string response_text = future.get(); result = json_loadb(response_text.c_str(), response_text.size(), 0, nullptr); - std::unique_lock lock(mutex); message = nullptr; }