diff --git a/changelog.md b/changelog.md index 743376d..0fd9976 100644 --- a/changelog.md +++ b/changelog.md @@ -1,5 +1,10 @@ # webfuse-provider changelog +## 0.2.0 _(unknown)_ + +* *Chore*: removed dependency to jansson (use own json implementation due to performace issues) +* *Feature*: reduce required libwebsockets version to 4.0.0 + ## 0.1.0 _(Sat Jun 26 2020)_ * initial version diff --git a/lib/webfuse_provider/impl/client_protocol.c b/lib/webfuse_provider/impl/client_protocol.c index 3359058..f67fa4a 100644 --- a/lib/webfuse_provider/impl/client_protocol.c +++ b/lib/webfuse_provider/impl/client_protocol.c @@ -4,7 +4,6 @@ #include #include -#include #include "webfuse_provider/impl/client_config.h" #include "webfuse_provider/impl/provider.h" @@ -21,28 +20,29 @@ #include "webfuse_provider/impl/jsonrpc/response.h" #include "webfuse_provider/impl/jsonrpc/request.h" #include "webfuse_provider/impl/jsonrpc/proxy.h" +#include "webfuse_provider/impl/json/doc.h" #define WFP_DEFAULT_TIMEOUT (10 * 1000) static void wfp_impl_client_protocol_respond( - json_t * response, + struct wfp_message * message, void * user_data) { struct wfp_client_protocol * protocol = (struct wfp_client_protocol *) user_data; - struct wfp_message * message = wfp_message_create(response); wfp_slist_append(&protocol->messages, &message->item); lws_callback_on_writable(protocol->wsi); } static void wfp_impl_client_protocol_process( struct wfp_client_protocol * protocol, - char const * data, + char * data, size_t length) { - json_t * message = json_loadb(data, length, 0, NULL); - if (NULL != message) + struct wfp_json_doc * doc = wfp_impl_json_doc_loadb(data, length); + if (NULL != doc) { + struct wfp_json const * message = wfp_impl_json_doc_root(doc); if (wfp_jsonrpc_is_response(message)) { wfp_jsonrpc_proxy_onresult(protocol->proxy, message); @@ -60,15 +60,15 @@ static void wfp_impl_client_protocol_process( wfp_impl_provider_invoke(&context, message); } - json_decref(message); + wfp_impl_json_doc_dispose(doc); } } static void wfp_impl_client_protocol_on_add_filesystem_finished( void * user_data, - json_t const * result, - json_t const * WFP_UNUSED_PARAM(error)) + struct wfp_json const * result, + struct wfp_jsonrpc_error const * WFP_UNUSED_PARAM(error)) { struct wfp_client_protocol * protocol = user_data; if (NULL == protocol->wsi) { return; } @@ -100,8 +100,8 @@ static void wfp_impl_client_protocol_add_filesystem( static void wfp_impl_client_protocol_on_authenticate_finished( void * user_data, - json_t const * result, - json_t const * WFP_UNUSED_PARAM(error)) + struct wfp_json const * result, + struct wfp_jsonrpc_error const * WFP_UNUSED_PARAM(error)) { struct wfp_client_protocol * protocol = user_data; if (NULL == protocol->wsi) { return; } @@ -126,8 +126,6 @@ static void wfp_impl_client_protocol_authenticate( protocol->provider.get_credentials(&credentials, protocol->user_data); char const * cred_type = wfp_impl_credentials_get_type(&credentials); - json_t * creds = wfp_impl_credentials_get(&credentials); - json_incref(creds); wfp_jsonrpc_proxy_invoke( protocol->proxy, @@ -135,7 +133,7 @@ static void wfp_impl_client_protocol_authenticate( protocol, "authenticate", "sj", - cred_type, creds); + cred_type, &wfp_impl_credentials_write, &credentials); wfp_impl_credentials_cleanup(&credentials); } @@ -216,17 +214,16 @@ static int wfp_impl_client_protocol_callback( return result; } -static bool wfp_impl_client_protocol_send( - json_t * request, +static void wfp_impl_client_protocol_send( + char * data, + size_t length, void * user_data) { struct wfp_client_protocol * protocol = user_data; - struct wfp_message * message = wfp_message_create(request); + struct wfp_message * message = wfp_message_create(data, length); wfp_slist_append(&protocol->messages, &message->item); lws_callback_on_writable(protocol->wsi); - - return true; } void wfp_impl_client_protocol_init( diff --git a/lib/webfuse_provider/impl/credentials.c b/lib/webfuse_provider/impl/credentials.c index 9c0a82c..10b45f2 100644 --- a/lib/webfuse_provider/impl/credentials.c +++ b/lib/webfuse_provider/impl/credentials.c @@ -1,20 +1,30 @@ #include "webfuse_provider/impl/credentials.h" +#include "webfuse_provider/impl/json/writer.h" #include #include +#define WFP_IMPL_CREDENTIALS_DEFAULT_SIZE 8 + void wfp_impl_credentials_init( struct wfp_credentials * credentials) { credentials->type = NULL; - credentials->contents = json_object(); + credentials->size = 0; + credentials->capacity = WFP_IMPL_CREDENTIALS_DEFAULT_SIZE; + credentials->entries = malloc(sizeof(struct wfp_credentials_entry) * credentials->capacity); } void wfp_impl_credentials_cleanup( struct wfp_credentials * credentials) { + for(size_t i = 0; i < credentials->size; i++) + { + free(credentials->entries[i].key); + free(credentials->entries[i].value); + } + free(credentials->entries); free(credentials->type); - json_decref(credentials->contents); } void wfp_impl_credentials_set_type( @@ -30,17 +40,37 @@ void wfp_impl_credentials_add( char const * key, char const * value) { - json_object_set_new(credentials->contents, key, json_string(value)); + if (credentials->size >= credentials->capacity) + { + credentials->capacity *= 2; + credentials->entries = realloc(credentials->entries, sizeof(struct wfp_credentials_entry) * credentials->capacity); + } + + credentials->entries[credentials->size].key = strdup(key); + credentials->entries[credentials->size].value = strdup(value); + credentials->size++; } -char const * wfp_impl_credentials_get_type( - struct wfp_credentials * credentials) +void +wfp_impl_credentials_write( + struct wfp_json_writer * writer, + void * data) { - return credentials->type; + struct wfp_credentials * credentials = (struct wfp_credentials *) data; + + wfp_impl_json_writer_object_begin(writer); + for(size_t i = 0; i < credentials->size; i++) + { + wfp_impl_json_writer_object_write_string(writer, + credentials->entries[i].key, + credentials->entries[i].value); + } + wfp_impl_json_writer_object_end(writer); } -json_t * wfp_impl_credentials_get( +char const * wfp_impl_credentials_get_type( struct wfp_credentials * credentials) { - return credentials->contents; + return credentials->type; } + diff --git a/lib/webfuse_provider/impl/credentials.h b/lib/webfuse_provider/impl/credentials.h index 521bbff..6ad5bf8 100644 --- a/lib/webfuse_provider/impl/credentials.h +++ b/lib/webfuse_provider/impl/credentials.h @@ -2,17 +2,33 @@ #define WFP_IMPL_CREDENTIALS_H #include "webfuse_provider/credentials.h" -#include +#include "webfuse_provider/impl/jsonrpc/proxy_intern.h" + +#ifndef __cplusplus +#include +#else +#include +#endif #ifdef __cplusplus extern "C" { #endif +struct wfp_json_writer; + +struct wfp_credentials_entry +{ + char * key; + char * value; +}; + struct wfp_credentials { char * type; - json_t * contents; + struct wfp_credentials_entry * entries; + size_t size; + size_t capacity; }; extern void wfp_impl_credentials_init( @@ -30,12 +46,16 @@ extern void wfp_impl_credentials_add( char const * key, char const * value); -extern char const * wfp_impl_credentials_get_type( - struct wfp_credentials * credentials); +extern void +wfp_impl_credentials_write( + struct wfp_json_writer * writer, + void * data); -extern json_t * wfp_impl_credentials_get( +extern char const * +wfp_impl_credentials_get_type( struct wfp_credentials * credentials); + #ifdef __cplusplus } #endif diff --git a/lib/webfuse_provider/impl/dirbuffer.c b/lib/webfuse_provider/impl/dirbuffer.c index 0d4f51c..e031adb 100644 --- a/lib/webfuse_provider/impl/dirbuffer.c +++ b/lib/webfuse_provider/impl/dirbuffer.c @@ -1,10 +1,15 @@ #include "webfuse_provider/impl/dirbuffer.h" #include +#include + +#define WFP_IMPL_DIRBUFFER_DEFAULT_CAPACITY 8 struct wfp_dirbuffer * wfp_impl_dirbuffer_create(void) { struct wfp_dirbuffer * buffer = malloc(sizeof(struct wfp_dirbuffer)); - buffer->entries = json_array(); + buffer->size = 0; + buffer->capacity = WFP_IMPL_DIRBUFFER_DEFAULT_CAPACITY; + buffer->entries = malloc(sizeof(struct wfp_dirbuffer_entry) * buffer->capacity); return buffer; } @@ -12,11 +17,12 @@ struct wfp_dirbuffer * wfp_impl_dirbuffer_create(void) void wfp_impl_dirbuffer_dispose( struct wfp_dirbuffer * buffer) { - if (NULL != buffer->entries) + for (size_t i = 0; i < buffer->size; i++) { - json_decref(buffer->entries); + free(buffer->entries[i].name); } + free(buffer->entries); free(buffer); } @@ -25,18 +31,35 @@ void wfp_impl_dirbuffer_add( char const * name, ino_t inode) { - json_t * entry = json_object(); - json_object_set_new(entry, "name", json_string(name)); - json_object_set_new(entry, "inode", json_integer(inode)); + if (buffer->size >= buffer->capacity) + { + buffer->capacity *= 2; + buffer->entries = realloc(buffer->entries, (sizeof(struct wfp_dirbuffer_entry) * buffer->capacity)); + } - json_array_append_new(buffer->entries, entry); + buffer->entries[buffer->size].name = strdup(name); + buffer->entries[buffer->size].inode = inode; + buffer->size++; } -json_t * wfp_impl_dirbuffer_take( +size_t +wfp_impl_dirbuffer_size( struct wfp_dirbuffer * buffer) { - json_t * entries = buffer->entries; + return buffer->size; +} + +struct wfp_dirbuffer_entry const * +wfp_impl_dirbuffer_entry_at( + struct wfp_dirbuffer * buffer, + size_t pos) +{ + struct wfp_dirbuffer_entry const * entry = NULL; + + if (pos < buffer->size) + { + entry = &(buffer->entries[pos]); + } - buffer->entries = NULL; - return entries; + return entry; } diff --git a/lib/webfuse_provider/impl/dirbuffer.h b/lib/webfuse_provider/impl/dirbuffer.h index eaa0278..efd76e7 100644 --- a/lib/webfuse_provider/impl/dirbuffer.h +++ b/lib/webfuse_provider/impl/dirbuffer.h @@ -4,16 +4,23 @@ #include #include #include -#include #ifdef __cplusplus extern "C" { #endif +struct wfp_dirbuffer_entry +{ + char * name; + ino_t inode; +}; + struct wfp_dirbuffer { - json_t * entries; + struct wfp_dirbuffer_entry * entries; + size_t size; + size_t capacity; }; extern struct wfp_dirbuffer * wfp_impl_dirbuffer_create(void); @@ -26,9 +33,14 @@ extern void wfp_impl_dirbuffer_add( char const * name, ino_t inode); -extern json_t * wfp_impl_dirbuffer_take( +extern size_t +wfp_impl_dirbuffer_size( struct wfp_dirbuffer * buffer); +extern struct wfp_dirbuffer_entry const * +wfp_impl_dirbuffer_entry_at( + struct wfp_dirbuffer * buffer, + size_t pos); #ifdef __cplusplus } diff --git a/lib/webfuse_provider/impl/json/doc.c b/lib/webfuse_provider/impl/json/doc.c new file mode 100644 index 0000000..20ba8c4 --- /dev/null +++ b/lib/webfuse_provider/impl/json/doc.c @@ -0,0 +1,298 @@ +#include "webfuse_provider/impl/json/doc.h" +#include "webfuse_provider/impl/json/node_intern.h" +#include "webfuse_provider/impl/json/reader.h" + +#include + +#define WFP_IMPL_JSON_DEFAULT_CAPACITY 4 + +struct wfp_json_doc +{ + struct wfp_json root; +}; + +static bool +wfp_impl_json_parse_value( + struct wfp_json_reader * reader, + struct wfp_json * json); + +static bool +wfp_impl_json_parse_null( + struct wfp_json_reader * reader, + struct wfp_json * json); + +static bool +wfp_impl_json_parse_true( + struct wfp_json_reader * reader, + struct wfp_json * json); + +static bool +wfp_impl_json_parse_false( + struct wfp_json_reader * reader, + struct wfp_json * json); + +static void +wfp_impl_json_parse_int( + struct wfp_json_reader * reader, + char first, + struct wfp_json * json); + +static bool +wfp_impl_json_parse_string( + struct wfp_json_reader * reader, + struct wfp_json * json); + +static bool +wfp_impl_json_parse_array( + struct wfp_json_reader * reader, + struct wfp_json * json); + +static bool +wfp_impl_json_parse_object( + struct wfp_json_reader * reader, + struct wfp_json * json); + + + +struct wfp_json_doc * +wfp_impl_json_doc_loadb( + char * data, + size_t length) +{ + struct wfp_json_reader reader; + wfp_impl_json_reader_init(&reader, data, length); + + struct wfp_json_doc * doc = malloc(sizeof(struct wfp_json_doc)); + if (!wfp_impl_json_parse_value(&reader, &doc->root)) + { + free(doc); + doc = NULL; + } + + return doc; +} + +void +wfp_impl_json_doc_dispose( + struct wfp_json_doc * doc) +{ + wfp_impl_json_cleanup(&doc->root); + free(doc); +} + +struct wfp_json const * +wfp_impl_json_doc_root( + struct wfp_json_doc * doc) +{ + return &(doc->root); +} + +static bool +wfp_impl_json_parse_value( + struct wfp_json_reader * reader, + struct wfp_json * json) +{ + wfp_impl_json_reader_skip_whitespace(reader); + char c = wfp_impl_json_reader_read_char(reader); + + switch (c) + { + case 'n': + return wfp_impl_json_parse_null(reader, json); + case 't': + return wfp_impl_json_parse_true(reader, json); + case 'f': + return wfp_impl_json_parse_false(reader, json); + case '\"': + wfp_impl_json_reader_unget_char(reader); + return wfp_impl_json_parse_string(reader, json); + case '{': + return wfp_impl_json_parse_object(reader, json); + case '[': + return wfp_impl_json_parse_array(reader, json); + default: + if ((('0' <= c) && (c <= '9')) || ('-' == c)) + { + wfp_impl_json_parse_int(reader, c, json); + return true; + } + else + { + return false; + } + } +} + +static bool +wfp_impl_json_parse_null( + struct wfp_json_reader * reader, + struct wfp_json * json) +{ + bool const result = wfp_impl_json_reader_read_const(reader, "ull", 3); + if (result) + { + json->type = WFP_JSON_NULL; + } + + return result; +} + +static bool +wfp_impl_json_parse_true( + struct wfp_json_reader * reader, + struct wfp_json * json) +{ + bool const result = wfp_impl_json_reader_read_const(reader, "rue", 3); + if (result) + { + json->type = WFP_JSON_BOOL; + json->value.b = true; + } + + return result; +} + +static bool +wfp_impl_json_parse_false( + struct wfp_json_reader * reader, + struct wfp_json * json) +{ + bool const result = wfp_impl_json_reader_read_const(reader, "alse", 4); + if (result) + { + json->type = WFP_JSON_BOOL; + json->value.b = false; + } + + return result; +} + +static void +wfp_impl_json_parse_int( + struct wfp_json_reader * reader, + char first, + struct wfp_json * json) +{ + json->type = WFP_JSON_INT; + json->value.i = wfp_impl_json_reader_read_int(reader, first); +} + +static bool +wfp_impl_json_parse_string( + struct wfp_json_reader * reader, + struct wfp_json * json) +{ + json->type = WFP_JSON_STRING; + return wfp_impl_json_reader_read_string(reader, &json->value.s); +} + +static bool +wfp_impl_json_parse_array( + struct wfp_json_reader * reader, + struct wfp_json * json) +{ + size_t capacity = WFP_IMPL_JSON_DEFAULT_CAPACITY; + json->type = WFP_JSON_ARRAY; + json->value.a.size = 0; + json->value.a.items = malloc(sizeof(struct wfp_json) * capacity); + + wfp_impl_json_reader_skip_whitespace(reader); + char c = wfp_impl_json_reader_peek(reader); + if (']' == c) + { + wfp_impl_json_reader_read_char(reader); + return true; + } + + bool result; + do + { + if (json->value.a.size >= capacity) + { + capacity *= 2; + json->value.a.items = realloc(json->value.a.items, sizeof(struct wfp_json) * capacity); + } + + result = wfp_impl_json_parse_value(reader, &(json->value.a.items[json->value.a.size])); + if (result) + { + json->value.a.size++; + wfp_impl_json_reader_skip_whitespace(reader); + c = wfp_impl_json_reader_read_char(reader); + } + + } while ((result) && (',' == c)); + + if ((result) && (']' != c)) + { + result = false; + } + + if (!result) + { + wfp_impl_json_cleanup(json); + } + + return result; +} + +static bool +wfp_impl_json_parse_object( + struct wfp_json_reader * reader, + struct wfp_json * json) +{ + size_t capacity = WFP_IMPL_JSON_DEFAULT_CAPACITY; + json->type = WFP_JSON_OBJECT; + json->value.o.size = 0; + json->value.o.items = malloc(sizeof(struct wfp_json_object_item) * capacity); + + wfp_impl_json_reader_skip_whitespace(reader); + char c = wfp_impl_json_reader_peek(reader); + if ('}' == c) + { + wfp_impl_json_reader_read_char(reader); + return true; + } + + bool result; + do + { + if (json->value.a.size >= capacity) + { + capacity *= 2; + json->value.a.items = realloc(json->value.a.items, sizeof(struct wfp_json_object_item) * capacity); + } + + struct wfp_json_object_item * item = &(json->value.o.items[json->value.o.size]); + result = wfp_impl_json_reader_read_string(reader, &(item->key)); + if (result) + { + wfp_impl_json_reader_skip_whitespace(reader); + result = (':' == wfp_impl_json_reader_read_char(reader)); + } + + if (result) + { + result = wfp_impl_json_parse_value(reader, &(item->json)); + } + + if (result) + { + json->value.o.size++; + wfp_impl_json_reader_skip_whitespace(reader); + c = wfp_impl_json_reader_read_char(reader); + } + } while ((result) && (',' == c)); + + if ((result) && ('}' != c)) + { + result = false; + } + + if (!result) + { + wfp_impl_json_cleanup(json); + } + + return result; +} diff --git a/lib/webfuse_provider/impl/json/doc.h b/lib/webfuse_provider/impl/json/doc.h new file mode 100644 index 0000000..b120402 --- /dev/null +++ b/lib/webfuse_provider/impl/json/doc.h @@ -0,0 +1,35 @@ +#ifndef WFP_IMPL_JSON_DOC_H +#define WFP_IMPL_JSON_DOC_H + +#ifndef __cplusplus +#include +#else +#include +#endif + +#ifdef __cplusplus +extern "C" +{ +#endif + +struct wfp_json; +struct wfp_json_doc; + +extern struct wfp_json_doc * +wfp_impl_json_doc_loadb( + char * data, + size_t length); + +extern void +wfp_impl_json_doc_dispose( + struct wfp_json_doc * doc); + +extern struct wfp_json const * +wfp_impl_json_doc_root( + struct wfp_json_doc * doc); + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/lib/webfuse_provider/impl/json/node.c b/lib/webfuse_provider/impl/json/node.c new file mode 100644 index 0000000..af668c7 --- /dev/null +++ b/lib/webfuse_provider/impl/json/node.c @@ -0,0 +1,179 @@ +#include "webfuse_provider/impl/json/node.h" +#include "webfuse_provider/impl/json/node_intern.h" + +#include +#include + +static struct wfp_json const wfp_json_null = +{ + .type = WFP_JSON_NULL, + .value = { .b = false } +}; + +bool +wfp_impl_json_is_null( + struct wfp_json const * json) +{ + return (WFP_JSON_NULL == json->type); +} + +bool +wfp_impl_json_is_bool( + struct wfp_json const * json) +{ + return (WFP_JSON_BOOL == json->type); +} + +bool +wfp_impl_json_is_int( + struct wfp_json const * json) +{ + return (WFP_JSON_INT == json->type); +} + +bool +wfp_impl_json_is_string( + struct wfp_json const * json) +{ + return (WFP_JSON_STRING == json->type); +} + +bool +wfp_impl_json_is_array( + struct wfp_json const * json) +{ + return (WFP_JSON_ARRAY == json->type); +} + +bool +wfp_impl_json_is_object( + struct wfp_json const * json) +{ + return (WFP_JSON_OBJECT == json->type); +} + +bool +wfp_impl_json_bool_get( + struct wfp_json const * json) +{ + return (WFP_JSON_BOOL == json->type) ? json->value.b : false; +} + +int +wfp_impl_json_int_get( + struct wfp_json const * json) +{ + return (WFP_JSON_INT == json->type) ? json->value.i : 0; +} + +const char * +wfp_impl_json_string_get( + struct wfp_json const * json) +{ + return (WFP_JSON_STRING == json->type) ? json->value.s : ""; +} + +struct wfp_json const * +wfp_impl_json_array_get( + struct wfp_json const * json, + size_t pos) +{ + if ((WFP_JSON_ARRAY == json->type) && (pos < json->value.a.size)) + { + return &(json->value.a.items[pos]); + } + + return &wfp_json_null; +} + +size_t +wfp_impl_json_array_size( + struct wfp_json const * json) +{ + return (WFP_JSON_ARRAY == json->type) ? json->value.a.size : 0; +} + +size_t +wfp_impl_json_object_size( + struct wfp_json const * json) +{ + return (WFP_JSON_OBJECT == json->type) ? json->value.o.size : 0; +} + +struct wfp_json const * +wfp_impl_json_object_get( + struct wfp_json const * json, + char const * key) +{ + size_t const count = wfp_impl_json_object_size(json); + for (size_t i = 0; i < count; i++) + { + if (0 == strcmp(key, json->value.o.items[i].key)) + { + return &(json->value.o.items[i].json); + } + } + + return &wfp_json_null; +} + +char const * +wfp_impl_json_object_key( + struct wfp_json const * json, + size_t pos) +{ + size_t const count = wfp_impl_json_object_size(json); + if (pos < count) + { + return json->value.o.items[pos].key; + } + + return ""; +} + +struct wfp_json const * +wfp_impl_json_object_value( + struct wfp_json const * json, + size_t pos) +{ + size_t const count = wfp_impl_json_object_size(json); + if (pos < count) + { + return &(json->value.o.items[pos].json); + } + + return &wfp_json_null; +} + +void +wfp_impl_json_cleanup( + struct wfp_json * json) +{ + switch (json->type) + { + case WFP_JSON_ARRAY: + { + size_t const count = json->value.a.size; + for (size_t i = 0; i < count; i++) + { + wfp_impl_json_cleanup(&(json->value.a.items[i])); + } + + free(json->value.a.items); + } + break; + case WFP_JSON_OBJECT: + { + size_t const count = json->value.o.size; + for (size_t i = 0; i < count; i++) + { + wfp_impl_json_cleanup(&(json->value.o.items[i].json)); + } + + free(json->value.o.items); + } + break; + default: + break; + } +} diff --git a/lib/webfuse_provider/impl/json/node.h b/lib/webfuse_provider/impl/json/node.h new file mode 100644 index 0000000..6c12410 --- /dev/null +++ b/lib/webfuse_provider/impl/json/node.h @@ -0,0 +1,87 @@ +#ifndef WFP_IMPL_JSON_NODE_H +#define WFP_IMPL_JSON_NODE_H + +#ifndef __cplusplus +#include +#include +#else +#include +#endif + +#ifdef __cplusplus +extern "C" +{ +#endif + +struct wfp_json; + +extern bool +wfp_impl_json_is_null( + struct wfp_json const * json); + +extern bool +wfp_impl_json_is_bool( + struct wfp_json const * json); + +extern bool +wfp_impl_json_is_int( + struct wfp_json const * json); + +extern bool +wfp_impl_json_is_string( + struct wfp_json const * json); + +extern bool +wfp_impl_json_is_array( + struct wfp_json const * json); + +extern bool +wfp_impl_json_is_object( + struct wfp_json const * json); + +extern bool +wfp_impl_json_bool_get( + struct wfp_json const * json); + +extern int +wfp_impl_json_int_get( + struct wfp_json const * json); + +extern const char * +wfp_impl_json_string_get( + struct wfp_json const * json); + +extern struct wfp_json const * +wfp_impl_json_array_get( + struct wfp_json const * json, + size_t pos); + +extern size_t +wfp_impl_json_array_size( + struct wfp_json const * json); + +extern size_t +wfp_impl_json_object_size( + struct wfp_json const * json); + +extern struct wfp_json const * +wfp_impl_json_object_get( + struct wfp_json const * json, + char const * key); + +extern char const * +wfp_impl_json_object_key( + struct wfp_json const * json, + size_t pos); + +extern struct wfp_json const * +wfp_impl_json_object_value( + struct wfp_json const * json, + size_t pos); + +#ifdef __cplusplus +} +#endif + + +#endif diff --git a/lib/webfuse_provider/impl/json/node_intern.h b/lib/webfuse_provider/impl/json/node_intern.h new file mode 100644 index 0000000..b30556e --- /dev/null +++ b/lib/webfuse_provider/impl/json/node_intern.h @@ -0,0 +1,76 @@ +#ifndef WFP_IMPL_JSON_NODE_INTERN_H +#define WFP_IMPL_JSON_NODE_INTERN_H + +#ifndef __cplusplus +#include +#include +#else +#include +#endif + +#ifdef __cplusplus +extern "C" +{ +#endif + +#ifdef __cplusplus +extern "C" +{ +#endif + +enum wfp_json_type +{ + WFP_JSON_NULL, + WFP_JSON_BOOL, + WFP_JSON_INT, + WFP_JSON_STRING, + WFP_JSON_ARRAY, + WFP_JSON_OBJECT +}; + +struct wfp_json_object_item; + +struct wfp_json_array +{ + size_t size; + struct wfp_json * items; +}; + +struct wfp_json_object +{ + size_t size; + struct wfp_json_object_item * items; +}; + +union wfp_json_value +{ + bool b; + int i; + char * s; + struct wfp_json_array a; + struct wfp_json_object o; +}; + +struct wfp_json +{ + enum wfp_json_type type; + union wfp_json_value value; +}; + + +struct wfp_json_object_item +{ + struct wfp_json json; + char * key; +}; + +extern void +wfp_impl_json_cleanup( + struct wfp_json * json); + +#ifdef __cplusplus +} +#endif + + +#endif diff --git a/lib/webfuse_provider/impl/json/reader.c b/lib/webfuse_provider/impl/json/reader.c new file mode 100644 index 0000000..a250f95 --- /dev/null +++ b/lib/webfuse_provider/impl/json/reader.c @@ -0,0 +1,169 @@ +#include "webfuse_provider/impl/json/reader.h" +#include + +void +wfp_impl_json_reader_init( + struct wfp_json_reader * reader, + char * contents, + size_t length) +{ + reader->contents =contents; + reader->length = length; + reader->pos = 0; +} + +void +wfp_impl_json_reader_skip_whitespace( + struct wfp_json_reader * reader) +{ + char c = reader->contents[reader->pos]; + + while ((' ' == c) || ('\n' == c) || ('\t' == c)|| ('\r' == c)) + { + reader->pos++; + c = reader->contents[reader->pos]; + } +} + + +char +wfp_impl_json_reader_peek( + struct wfp_json_reader * reader) +{ + char result = '\0'; + if (reader->pos < reader->length) + { + result = reader->contents[reader->pos]; + } + + return result; +} + +char +wfp_impl_json_reader_read_char( + struct wfp_json_reader * reader) +{ + char result = '\0'; + if (reader->pos < reader->length) + { + result = reader->contents[reader->pos]; + reader->pos++; + } + + return result; +} + +void +wfp_impl_json_reader_unget_char( + struct wfp_json_reader * reader) +{ + if (0 < reader->pos) + { + reader->pos--; + } +} + + +bool +wfp_impl_json_reader_read_const( + struct wfp_json_reader * reader, + char const * value, + size_t length) +{ + size_t const remaining = reader->length - reader->pos; + bool const result = ((remaining >= length) && (0 == strncmp(&(reader->contents[reader->pos]), value, length))); + { + reader->pos += length; + } + + return result; +} + +int +wfp_impl_json_reader_read_int( + struct wfp_json_reader * reader, + char first) +{ + bool const is_signed = ('-' == first); + int value = is_signed ? 0 : first - '0'; + + while (reader->pos < reader->length) + { + char c = reader->contents[reader->pos]; + if (('0' <= c) && (c <= '9')) + { + value *= 10; + value += (c - '0'); + reader->pos++; + } + else + { + break; + } + + } + + return (is_signed ? -value : value); +} + +extern bool +wfp_impl_json_reader_read_string( + struct wfp_json_reader * reader, + char * * value) +{ + wfp_impl_json_reader_skip_whitespace(reader); + char c = wfp_impl_json_reader_read_char(reader); + if ('\"' != c) { return false; } + + size_t p = reader->pos; + *value = &(reader->contents[p]); + c = wfp_impl_json_reader_read_char(reader); + while (('\"' != c) && ('\0' != c)) + { + if ('\\' != c) + { + reader->contents[p++] = c; + } + else + { + c = wfp_impl_json_reader_read_char(reader); + switch (c) + { + case '\"': + reader->contents[p++] = '\"'; + break; + case '\\': + reader->contents[p++] = '\\'; + break; + case '/': + reader->contents[p++] = '/'; + break; + case 'b': + reader->contents[p++] = '\b'; + break; + case 'f': + reader->contents[p++] = '\f'; + break; + case 'n': + reader->contents[p++] = '\n'; + break; + case 'r': + reader->contents[p++] = '\r'; + break; + case 't': + reader->contents[p++] = '\t'; + break; + default: + return false; + } + } + c = wfp_impl_json_reader_read_char(reader); + } + + bool const result = ('\"' == c); + if (result) + { + reader->contents[p] = '\0'; + } + return result; +} diff --git a/lib/webfuse_provider/impl/json/reader.h b/lib/webfuse_provider/impl/json/reader.h new file mode 100644 index 0000000..8bfed5e --- /dev/null +++ b/lib/webfuse_provider/impl/json/reader.h @@ -0,0 +1,65 @@ +#ifndef WFP_IMPL_JSON_READER_H +#define WFP_IMPL_JSON_READER_H + +#ifndef __cplusplus +#include +#include +#else +#include +#endif + +#ifdef __cplusplus +extern "C" +{ +#endif + +struct wfp_json_reader +{ + char * contents; + size_t length; + size_t pos; +}; + +extern void +wfp_impl_json_reader_init( + struct wfp_json_reader * reader, + char * contents, + size_t length); + +extern void +wfp_impl_json_reader_skip_whitespace( + struct wfp_json_reader * reader); + +extern char +wfp_impl_json_reader_peek( + struct wfp_json_reader * reader); + +extern char +wfp_impl_json_reader_read_char( + struct wfp_json_reader * reader); + +extern void +wfp_impl_json_reader_unget_char( + struct wfp_json_reader * reader); + +extern bool +wfp_impl_json_reader_read_const( + struct wfp_json_reader * reader, + char const * value, + size_t length); + +extern int +wfp_impl_json_reader_read_int( + struct wfp_json_reader * reader, + char first); + +extern bool +wfp_impl_json_reader_read_string( + struct wfp_json_reader * reader, + char * * value); + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/lib/webfuse_provider/impl/json/writer.c b/lib/webfuse_provider/impl/json/writer.c new file mode 100644 index 0000000..a9b60c9 --- /dev/null +++ b/lib/webfuse_provider/impl/json/writer.c @@ -0,0 +1,401 @@ +#include "webfuse_provider/impl/json/writer.h" +#include "webfuse_provider/impl/util/base64.h" +#include +#include +#include +#include + +#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_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 + 1]; + size_t level; + size_t capacity; + size_t pre; + size_t offset; + char * data; + 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, + size_t needed) +{ + if ((writer->capacity - writer->offset) < needed) + { + size_t new_capacity = 2 * writer->capacity; + + while ((new_capacity - writer->offset) < needed) + { + new_capacity *= 2; + } + + writer->raw_data = realloc(writer->raw_data, writer->pre + new_capacity); + writer->data = &(writer->raw_data[writer->pre]); + writer->capacity = new_capacity; + } +} + +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, + enum wfp_json_writer_state state) +{ + 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 +wfp_impl_json_writer_write_raw( + struct wfp_json_writer * writer, + char const * value, + size_t length) +{ + memcpy(&(writer->data[writer->offset]), value, length); + writer->offset += length; +} + +struct wfp_json_writer * +wfp_impl_json_writer_create( + size_t initial_capacity, + size_t pre) +{ + struct wfp_json_writer * writer = malloc(sizeof(struct wfp_json_writer)); + writer->level = 0; + writer->state[writer->level] = WFP_JSON_WRITER_STATE_INIT; + writer->pre = pre; + writer->capacity = initial_capacity; + writer->offset = 0; + writer->raw_data = malloc(writer->pre + writer->capacity); + writer->data = &(writer->raw_data[pre]); + + return writer; +} + +void +wfp_impl_json_writer_dispose( + struct wfp_json_writer * writer) +{ + free(writer->raw_data); + 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, + size_t * size) +{ + wfp_impl_json_writer_reserve(writer, 1); + writer->data[writer->offset] = '\0'; + + writer->raw_data = NULL; + + if (NULL != size) + { + *size = writer->offset; + } + + return writer->data; +} + +void +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 +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); + + wfp_impl_json_writer_write_raw_char(writer, '\"'); + 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 +wfp_impl_json_writer_write_bytes( + struct wfp_json_writer * writer, + 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, '{'); +} + +void +wfp_impl_json_writer_object_end( + struct wfp_json_writer * writer) +{ + 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 +wfp_impl_json_writer_object_key( + struct wfp_json_writer * writer, + char const * key) +{ + wfp_impl_json_writer_reserve(writer, 1); + + 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, '['); +} + +void +wfp_impl_json_writer_array_end( + struct wfp_json_writer * writer) +{ + 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 +wfp_impl_json_writer_object_write_int( + struct wfp_json_writer * writer, + char const * key, + int value) +{ + wfp_impl_json_writer_object_key(writer, key); + wfp_impl_json_writer_write_int(writer, value); +} + +void +wfp_impl_json_writer_object_write_string( + struct wfp_json_writer * writer, + char const * key, + char const * value) +{ + wfp_impl_json_writer_object_key(writer, key); + wfp_impl_json_writer_write_string(writer, value); +} + +void +wfp_impl_json_writer_object_begin_object( + struct wfp_json_writer * writer, + char const * key) +{ + wfp_impl_json_writer_object_key(writer, key); + wfp_impl_json_writer_object_begin(writer); +} + +void +wfp_impl_json_writer_object_begin_array( + struct wfp_json_writer * writer, + char const * key) +{ + wfp_impl_json_writer_object_key(writer, key); + wfp_impl_json_writer_array_begin(writer); +} diff --git a/lib/webfuse_provider/impl/json/writer.h b/lib/webfuse_provider/impl/json/writer.h new file mode 100644 index 0000000..84e630f --- /dev/null +++ b/lib/webfuse_provider/impl/json/writer.h @@ -0,0 +1,104 @@ +#ifndef WFP_IMPL_JSON_WRITER_H +#define WFP_IMPL_JSON_WRTIER_H + +#ifndef __cplusplus +#include +#else +#include +#endif + +#ifdef __cplusplus +extern "C" +{ +#endif + +struct wfp_json_writer; + +extern struct wfp_json_writer * +wfp_impl_json_writer_create( + size_t initial_capacity, + size_t pre); + +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, + size_t * size); + +extern void +wfp_impl_json_writer_write_int( + struct wfp_json_writer * writer, + int value); + +extern void +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, + char const * data, + size_t length); + +extern void +wfp_impl_json_writer_object_begin( + struct wfp_json_writer * writer); + +extern void +wfp_impl_json_writer_object_end( + struct wfp_json_writer * writer); + +extern void +wfp_impl_json_writer_object_key( + struct wfp_json_writer * writer, + char const * key); + +extern void +wfp_impl_json_writer_object_write_int( + struct wfp_json_writer * writer, + char const * key, + int value); + +extern void +wfp_impl_json_writer_object_write_string( + struct wfp_json_writer * writer, + char const * key, + char const * value); + +extern void +wfp_impl_json_writer_object_begin_object( + struct wfp_json_writer * writer, + char const * key); + +extern void +wfp_impl_json_writer_object_begin_array( + struct wfp_json_writer * writer, + char const * key); + +extern void +wfp_impl_json_writer_array_begin( + struct wfp_json_writer * writer); + +extern void +wfp_impl_json_writer_array_end( + struct wfp_json_writer * writer); + + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/lib/webfuse_provider/impl/jsonrpc/error.c b/lib/webfuse_provider/impl/jsonrpc/error.c index abe8a71..f36944a 100644 --- a/lib/webfuse_provider/impl/jsonrpc/error.c +++ b/lib/webfuse_provider/impl/jsonrpc/error.c @@ -1,17 +1,28 @@ #include "webfuse_provider/impl/jsonrpc/error.h" -json_t * -wfp_jsonrpc_error( +#include +#include + +struct wfp_jsonrpc_error * +wfp_jsonrpc_error_create( int code, char const * message) { - json_t * error = json_object(); - json_object_set_new(error, "code", json_integer(code)); - json_object_set_new(error, "message", json_string(message)); + struct wfp_jsonrpc_error * error = malloc(sizeof(struct wfp_jsonrpc_error)); + error->code = code; + error->message = strdup(message); return error; } +void +wfp_jsonrpc_error_dispose( + struct wfp_jsonrpc_error * error) +{ + free(error->message); + free(error); +} + void wfp_jsonrpc_propate_error( wfp_jsonrpc_proxy_finished_fn * finised, @@ -19,9 +30,10 @@ wfp_jsonrpc_propate_error( int code, char const * message) { - json_t * error = wfp_jsonrpc_error(code, message); - finised(user_data, NULL, error); + struct wfp_jsonrpc_error error; + error.code = code; + error.message = (char*) message; - json_decref(error); + finised(user_data, NULL, &error); } diff --git a/lib/webfuse_provider/impl/jsonrpc/error.h b/lib/webfuse_provider/impl/jsonrpc/error.h index dd54f0a..31576fc 100644 --- a/lib/webfuse_provider/impl/jsonrpc/error.h +++ b/lib/webfuse_provider/impl/jsonrpc/error.h @@ -1,7 +1,6 @@ #ifndef WFP_JSONRPC_ERROR_H #define WFP_JSONRPC_ERROR_H -#include #include "webfuse_provider/impl/jsonrpc/proxy_finished_fn.h" #ifdef __cplusplus @@ -9,11 +8,21 @@ extern "C" { #endif -extern json_t * -wfp_jsonrpc_error( +struct wfp_jsonrpc_error +{ + int code; + char * message; +}; + +extern struct wfp_jsonrpc_error * +wfp_jsonrpc_error_create( int code, char const * message); +extern void +wfp_jsonrpc_error_dispose( + struct wfp_jsonrpc_error * error); + extern void wfp_jsonrpc_propate_error( wfp_jsonrpc_proxy_finished_fn * finised, diff --git a/lib/webfuse_provider/impl/jsonrpc/proxy.c b/lib/webfuse_provider/impl/jsonrpc/proxy.c index cd6f64d..11be6ad 100644 --- a/lib/webfuse_provider/impl/jsonrpc/proxy.c +++ b/lib/webfuse_provider/impl/jsonrpc/proxy.c @@ -4,6 +4,9 @@ #include "webfuse_provider/status.h" #include "webfuse_provider/impl/timer/timer.h" +#include "webfuse_provider/impl/json/writer.h" + +#include #include #include @@ -48,16 +51,18 @@ static void wfp_jsonrpc_proxy_on_timeout( } } -static json_t * wfp_jsonrpc_request_create( +static char * wfp_jsonrpc_request_create( + size_t * length, char const * method, int id, char const * param_info, va_list args) { - json_t * request = json_object(); - json_object_set_new(request, "method", json_string(method)); - json_t * params = json_array(); - + struct wfp_json_writer * writer = wfp_impl_json_writer_create(128, LWS_PRE); + wfp_impl_json_writer_object_begin(writer); + + wfp_impl_json_writer_object_write_string(writer, "method", method); + wfp_impl_json_writer_object_begin_array(writer, "params"); for (char const * param_type = param_info; '\0' != *param_type; param_type++) { switch(*param_type) @@ -65,37 +70,40 @@ static json_t * wfp_jsonrpc_request_create( case 's': { char const * const value = va_arg(args, char const *); - json_array_append_new(params, json_string(value)); + wfp_impl_json_writer_write_string(writer, value); } break; case 'i': { int const value = va_arg(args, int); - json_array_append_new(params, json_integer(value)); + wfp_impl_json_writer_write_int(writer, value); } break; case 'j': { - json_t * const value = va_arg(args, json_t *); - json_array_append_new(params, value); + wfp_jsonrpc_custom_write_fn * write = va_arg(args, wfp_jsonrpc_custom_write_fn *); + void * data = va_arg(args, void *); + write(writer,data); } break; default: fprintf(stderr, "fatal: unknown param_type '%c'\n", *param_type); - json_decref(params); - json_decref(request); - return NULL; + break; } } - + wfp_impl_json_writer_array_end(writer); - json_object_set_new(request, "params", params); - if (0 != id) - { - json_object_set_new(request, "id", json_integer(id)); - } - - return request; + if (0 != id) + { + wfp_impl_json_writer_object_write_int(writer, "id", id); + } + + wfp_impl_json_writer_object_end(writer); + + char * message = wfp_impl_json_writer_take_data(writer, length); + wfp_impl_json_writer_dispose(writer); + + return message; } void wfp_jsonrpc_proxy_init( @@ -149,24 +157,10 @@ void wfp_jsonrpc_proxy_vinvoke( proxy->request.id = 42; wfp_timer_start(proxy->request.timer, proxy->timeout); - json_t * request = wfp_jsonrpc_request_create(method_name, proxy->request.id, param_info, args); - - bool const is_send = ((NULL != request) && (proxy->send(request, proxy->user_data))); - if (!is_send) - { - proxy->request.is_pending = false; - proxy->request.finished = NULL; - proxy->request.user_data = NULL; - proxy->request.id = 0; - wfp_timer_cancel(proxy->request.timer); - - wfp_jsonrpc_propate_error(finished, user_data, WFP_BAD, "Bad: requenst is not sent"); - } - - if (NULL != request) - { - json_decref(request); - } + size_t length; + char * message = wfp_jsonrpc_request_create(&length, method_name, proxy->request.id, param_info, args); + + proxy->send(message, length, proxy->user_data); } else { @@ -180,19 +174,16 @@ extern void wfp_jsonrpc_proxy_vnotify( char const * param_info, va_list args) { - json_t * request = wfp_jsonrpc_request_create(method_name, 0, param_info, args); + size_t length; + char * request = wfp_jsonrpc_request_create(&length, method_name, 0, param_info, args); - if (NULL != request) - { - proxy->send(request, proxy->user_data); - json_decref(request); - } + proxy->send(request, length, proxy->user_data); } void wfp_jsonrpc_proxy_onresult( struct wfp_jsonrpc_proxy * proxy, - json_t * message) + struct wfp_json const * message) { struct wfp_jsonrpc_response response; wfp_jsonrpc_response_init(&response, message); diff --git a/lib/webfuse_provider/impl/jsonrpc/proxy.h b/lib/webfuse_provider/impl/jsonrpc/proxy.h index 0f02edf..6bf230d 100644 --- a/lib/webfuse_provider/impl/jsonrpc/proxy.h +++ b/lib/webfuse_provider/impl/jsonrpc/proxy.h @@ -11,7 +11,6 @@ using std::size_t; #endif -#include #include "webfuse_provider/impl/jsonrpc/send_fn.h" #include "webfuse_provider/impl/jsonrpc/proxy_finished_fn.h" @@ -21,6 +20,13 @@ extern "C" { struct wfp_jsonrpc_proxy; struct wfp_timer_manager; +struct wfp_json_writer; +struct wfp_json; + +typedef void +wfp_jsonrpc_custom_write_fn( + struct wfp_json_writer * writer, + void * data); extern struct wfp_jsonrpc_proxy * wfp_jsonrpc_proxy_create( @@ -64,7 +70,7 @@ extern void wfp_jsonrpc_proxy_notify( extern void wfp_jsonrpc_proxy_onresult( struct wfp_jsonrpc_proxy * proxy, - json_t * message); + struct wfp_json const * message); #ifdef __cplusplus } diff --git a/lib/webfuse_provider/impl/jsonrpc/proxy_finished_fn.h b/lib/webfuse_provider/impl/jsonrpc/proxy_finished_fn.h index 6d2b0d3..03523ab 100644 --- a/lib/webfuse_provider/impl/jsonrpc/proxy_finished_fn.h +++ b/lib/webfuse_provider/impl/jsonrpc/proxy_finished_fn.h @@ -1,17 +1,18 @@ #ifndef WFP_JSONRPC_PROXY_FINISHED_FN_H #define WFP_JSONRPC_PROXY_FINISHED_FN_H -#include - #ifdef __cplusplus extern "C" { #endif +struct wfp_json; +struct wfp_jsonrpc_error; + typedef void wfp_jsonrpc_proxy_finished_fn( void * user_data, - json_t const * result, - json_t const * error); + struct wfp_json const * result, + struct wfp_jsonrpc_error const * error); #ifdef __cplusplus } diff --git a/lib/webfuse_provider/impl/jsonrpc/request.c b/lib/webfuse_provider/impl/jsonrpc/request.c index 9d9260d..768bc9f 100644 --- a/lib/webfuse_provider/impl/jsonrpc/request.c +++ b/lib/webfuse_provider/impl/jsonrpc/request.c @@ -1,81 +1,17 @@ #include "webfuse_provider/impl/jsonrpc/request.h" -#include "webfuse_provider/impl/jsonrpc/error.h" +#include "webfuse_provider/impl/json/node.h" #include -struct wfp_jsonrpc_request -{ - int id; - wfp_jsonrpc_send_fn * send; - void * user_data; -}; - bool wfp_jsonrpc_is_request( - json_t * message) -{ - json_t * id = json_object_get(message, "id"); - json_t * method = json_object_get(message, "method"); - json_t * params = json_object_get(message, "params"); - - return (json_is_integer(id) && json_is_string(method) && - (json_is_array(params) || json_is_object(params))); -} - - -struct wfp_jsonrpc_request * -wfp_jsonrpc_request_create( - int id, - wfp_jsonrpc_send_fn * send, - void * user_data) -{ - struct wfp_jsonrpc_request * request = malloc(sizeof(struct wfp_jsonrpc_request)); - request->id = id; - request->send = send; - request->user_data = user_data; - - return request; -} - -void -wfp_jsonrpc_request_dispose( - struct wfp_jsonrpc_request * request) + struct wfp_json const * message) { - free(request); -} - -void * -wfp_jsonrpc_request_get_userdata( - struct wfp_jsonrpc_request * request) -{ - return request->user_data; -} - + if (NULL == message) { return false; } -void -wfp_jsonrpc_respond( - struct wfp_jsonrpc_request * request, - json_t * result) -{ - json_t * response = json_object(); - json_object_set_new(response, "result", result); - json_object_set_new(response, "id", json_integer(request->id)); + struct wfp_json const * id = wfp_impl_json_object_get(message, "id"); + struct wfp_json const * method = wfp_impl_json_object_get(message, "method"); + struct wfp_json const * params = wfp_impl_json_object_get(message, "params"); - request->send(response, request->user_data); - json_decref(response); - wfp_jsonrpc_request_dispose(request); + return (wfp_impl_json_is_int(id) && wfp_impl_json_is_string(method) && + (wfp_impl_json_is_array(params) || wfp_impl_json_is_object(params))); } - -void wfp_jsonrpc_respond_error( - struct wfp_jsonrpc_request * request, - int code, - char const * message) -{ - json_t * response = json_object(); - json_object_set_new(response, "error", wfp_jsonrpc_error(code, message)); - json_object_set_new(response, "id", json_integer(request->id)); - - request->send(response, request->user_data); - json_decref(response); - wfp_jsonrpc_request_dispose(request); -} - diff --git a/lib/webfuse_provider/impl/jsonrpc/request.h b/lib/webfuse_provider/impl/jsonrpc/request.h index aa0fd2e..5f26d82 100644 --- a/lib/webfuse_provider/impl/jsonrpc/request.h +++ b/lib/webfuse_provider/impl/jsonrpc/request.h @@ -2,49 +2,18 @@ #define WFP_JSONRPC_REQUEST_H #ifndef __cplusplus -#include -#include #include -#else -#include -#include -using std::size_t; #endif -#include -#include "webfuse_provider/impl/jsonrpc/send_fn.h" - #ifdef __cplusplus extern "C" { #endif -struct wfp_jsonrpc_request; +struct wfp_json; extern bool wfp_jsonrpc_is_request( - json_t * message); - -extern struct wfp_jsonrpc_request * -wfp_jsonrpc_request_create( - int id, - wfp_jsonrpc_send_fn * send, - void * user_data); - -extern void wfp_jsonrpc_request_dispose( - struct wfp_jsonrpc_request * request); - -extern void * wfp_jsonrpc_request_get_userdata( - struct wfp_jsonrpc_request * request); - -extern void wfp_jsonrpc_respond( - struct wfp_jsonrpc_request * request, - json_t * result); - -extern void wfp_jsonrpc_respond_error( - struct wfp_jsonrpc_request * request, - int code, - char const * message); - + struct wfp_json const * message); #ifdef __cplusplus } diff --git a/lib/webfuse_provider/impl/jsonrpc/response.c b/lib/webfuse_provider/impl/jsonrpc/response.c index acc7b49..bc14c86 100644 --- a/lib/webfuse_provider/impl/jsonrpc/response.c +++ b/lib/webfuse_provider/impl/jsonrpc/response.c @@ -1,54 +1,59 @@ #include "webfuse_provider/impl/jsonrpc/response_intern.h" #include "webfuse_provider/impl/jsonrpc/error.h" #include "webfuse_provider/status.h" +#include "webfuse_provider/impl/json/node.h" bool wfp_jsonrpc_is_response( - json_t * message) + struct wfp_json const * message) { - json_t * id = json_object_get(message, "id"); - json_t * err = json_object_get(message, "error"); - json_t * result = json_object_get(message, "result"); + if (NULL == message) { return false; } - return (json_is_integer(id) && - (json_is_object(err) || (NULL != result))); + struct wfp_json const * id = wfp_impl_json_object_get(message, "id"); + struct wfp_json const * err = wfp_impl_json_object_get(message, "error"); + struct wfp_json const * result = wfp_impl_json_object_get(message, "result"); + + return (wfp_impl_json_is_int(id) && + (wfp_impl_json_is_object(err) || (NULL != result))); } void wfp_jsonrpc_response_init( struct wfp_jsonrpc_response * result, - json_t * response) + struct wfp_json const * response) { result->id = -1; result->result = NULL; result->error = NULL; - json_t * id_holder = json_object_get(response, "id"); - if (!json_is_integer(id_holder)) + struct wfp_json const * id_holder = wfp_impl_json_object_get(response, "id"); + if (!wfp_impl_json_is_int(id_holder)) { - result->error = wfp_jsonrpc_error(WFP_BAD_FORMAT, "invalid format: missing id"); + result->error = wfp_jsonrpc_error_create(WFP_BAD_FORMAT, "invalid format: missing id"); return; } - result->id = json_integer_value(id_holder); - result->result = json_object_get(response, "result"); - if (NULL != result->result) - { - json_incref(result->result); - } - else + result->id = wfp_impl_json_int_get(id_holder); + result->result = wfp_impl_json_object_get(response, "result"); + if (wfp_impl_json_is_null(result->result)) { - json_t * error = json_object_get(response, "error"); - if ((json_is_object(error)) && (json_is_integer(json_object_get(error, "code")))) - { - result->error = error; - json_incref(result->error); - } - else + result->result = NULL; + int code = WFP_BAD_FORMAT; + char const * message = "invalid format: invalid error object"; + + struct wfp_json const * error = wfp_impl_json_object_get(response, "error"); + if ((wfp_impl_json_is_object(error)) && (wfp_impl_json_is_int(wfp_impl_json_object_get(error, "code")))) { - result->error = wfp_jsonrpc_error(WFP_BAD_FORMAT, "invalid format: invalid error object"); + code = wfp_impl_json_int_get(wfp_impl_json_object_get(error, "code")); + message = ""; + if (wfp_impl_json_is_string(wfp_impl_json_object_get(error, "message"))) + { + message = wfp_impl_json_string_get(wfp_impl_json_object_get(error, "message")); + } } + + result->error = wfp_jsonrpc_error_create(code, message); } } @@ -56,13 +61,8 @@ void wfp_jsonrpc_response_cleanup( struct wfp_jsonrpc_response * response) { - if (NULL != response->result) - { - json_decref(response->result); - } - - if (NULL != response->error) - { - json_decref(response->error); - } + if (NULL != response->error) + { + wfp_jsonrpc_error_dispose(response->error); + } } diff --git a/lib/webfuse_provider/impl/jsonrpc/response.h b/lib/webfuse_provider/impl/jsonrpc/response.h index eae5cb8..94e9161 100644 --- a/lib/webfuse_provider/impl/jsonrpc/response.h +++ b/lib/webfuse_provider/impl/jsonrpc/response.h @@ -5,15 +5,16 @@ #include #endif -#include - #ifdef __cplusplus extern "C" { #endif -extern bool wfp_jsonrpc_is_response( - json_t * message); +struct wfp_json; + +extern bool +wfp_jsonrpc_is_response( + struct wfp_json const * message); #ifdef __cplusplus } diff --git a/lib/webfuse_provider/impl/jsonrpc/response_intern.h b/lib/webfuse_provider/impl/jsonrpc/response_intern.h index e03dea7..012fbd3 100644 --- a/lib/webfuse_provider/impl/jsonrpc/response_intern.h +++ b/lib/webfuse_provider/impl/jsonrpc/response_intern.h @@ -14,16 +14,19 @@ using std::size_t; extern "C" { #endif +struct wfp_json; +struct wfp_jsonrpc_error; + struct wfp_jsonrpc_response { - json_t * result; - json_t * error; + struct wfp_json const * result; + struct wfp_jsonrpc_error * error; int id; }; extern void wfp_jsonrpc_response_init( struct wfp_jsonrpc_response * response, - json_t * message); + struct wfp_json const * message); extern void wfp_jsonrpc_response_cleanup( struct wfp_jsonrpc_response * response); diff --git a/lib/webfuse_provider/impl/jsonrpc/send_fn.h b/lib/webfuse_provider/impl/jsonrpc/send_fn.h index 9c4ea1a..35277ee 100644 --- a/lib/webfuse_provider/impl/jsonrpc/send_fn.h +++ b/lib/webfuse_provider/impl/jsonrpc/send_fn.h @@ -3,17 +3,19 @@ #ifndef __cplusplus #include +#include +#else +#include #endif -#include - #ifdef __cplusplus extern "C" { #endif -typedef bool wfp_jsonrpc_send_fn( - json_t * request, +typedef void wfp_jsonrpc_send_fn( + char * message, + size_t length, void * user_data); #ifdef __cplusplus diff --git a/lib/webfuse_provider/impl/message.c b/lib/webfuse_provider/impl/message.c index 7943a5d..f929b5b 100644 --- a/lib/webfuse_provider/impl/message.c +++ b/lib/webfuse_provider/impl/message.c @@ -3,16 +3,14 @@ #include #include -extern struct wfp_message * wfp_message_create(json_t const * value) +extern struct wfp_message * wfp_message_create( + char * data, + size_t length) { - size_t const length = json_dumpb(value, 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]; + struct wfp_message * message = malloc(sizeof(struct wfp_message)); + message->data = data; message->length = length; - - json_dumpb(value, message->data, length, JSON_COMPACT); + message->raw_data = data - LWS_PRE; return message; } @@ -20,5 +18,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..ae1d029 100644 --- a/lib/webfuse_provider/impl/message.h +++ b/lib/webfuse_provider/impl/message.h @@ -8,13 +8,13 @@ using std::size_t; #endif -#include #include "webfuse_provider/impl/util/slist.h" struct wfp_message { struct wfp_slist_item item; char * data; + char * raw_data; size_t length; }; @@ -23,8 +23,10 @@ extern "C" { #endif -extern struct wfp_message * wfp_message_create( - json_t const * value); +extern struct wfp_message * +wfp_message_create( + char * data, + size_t length); extern void wfp_message_dispose( struct wfp_message * message); diff --git a/lib/webfuse_provider/impl/message_writer.c b/lib/webfuse_provider/impl/message_writer.c new file mode 100644 index 0000000..ebc51dc --- /dev/null +++ b/lib/webfuse_provider/impl/message_writer.c @@ -0,0 +1,143 @@ +#include "webfuse_provider/impl/message_writer.h" +#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 + +struct wfp_message_writer +{ + 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(struct wfp_message_writer)); + 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; +} + +void +wfp_impl_message_writer_dispose( + struct wfp_message_writer * writer) +{ + wfp_impl_json_writer_dispose(writer->json_writer); + free(writer); +} + +struct wfp_message * +wfp_impl_message_writer_take_message( + struct wfp_message_writer * writer) +{ + if (!writer->is_finished) + { + 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; + } + + size_t length; + char * data = wfp_impl_json_writer_take_data(writer->json_writer, &length); + + return wfp_message_create(data, length); +} + +void +wfp_impl_message_writer_add_int( + struct wfp_message_writer * writer, + char const * key, + int value) +{ + wfp_impl_json_writer_object_key(writer->json_writer, key); + wfp_impl_json_writer_write_int(writer->json_writer, value); +} + +void +wfp_impl_message_writer_add_string( + struct wfp_message_writer * writer, + char const * key, + char const * value) +{ + wfp_impl_json_writer_object_key(writer->json_writer, key); + wfp_impl_json_writer_write_string(writer->json_writer, value); +} + +void +wfp_impl_message_writer_add_bytes( + struct wfp_message_writer * writer, + char const * key, + char const * data, + size_t length) +{ + wfp_impl_json_writer_object_key(writer->json_writer, key); + wfp_impl_json_writer_write_bytes(writer->json_writer, data, length); +} + +void +wfp_impl_message_writer_add_dirbuffer( + struct wfp_message_writer * writer, + struct wfp_dirbuffer * 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); + + size_t const count = wfp_impl_dirbuffer_size(dirbuffer); + for (size_t i = 0; i < count; i++) + { + struct wfp_dirbuffer_entry const * entry = wfp_impl_dirbuffer_entry_at(dirbuffer, i); + + 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, entry->name); + wfp_impl_json_writer_object_key(writer->json_writer, "inode"); + wfp_impl_json_writer_write_int(writer->json_writer, entry->inode); + wfp_impl_json_writer_object_end(writer->json_writer); + + } + + 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 +wfp_impl_message_writer_set_error( + struct wfp_message_writer * writer, + int 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/lib/webfuse_provider/impl/message_writer.h b/lib/webfuse_provider/impl/message_writer.h new file mode 100644 index 0000000..24c4c91 --- /dev/null +++ b/lib/webfuse_provider/impl/message_writer.h @@ -0,0 +1,63 @@ +#ifndef WFP_IMPL_MESSAGE_WRITER_H +#define WFP_IMPL_MESSAGE_WRITER_H + +#ifndef _cplusplus +#include +#else +#include +#endif + +#ifdef __cplusplus +extern "C" +{ +#endif + +struct wfp_message_writer; +struct wfp_message; +struct wfp_dirbuffer; + +extern struct wfp_message_writer * +wfp_impl_message_writer_create(int id); + +extern void +wfp_impl_message_writer_dispose( + struct wfp_message_writer * writer); + +extern struct wfp_message * +wfp_impl_message_writer_take_message( + struct wfp_message_writer * writer); + +extern void +wfp_impl_message_writer_add_int( + struct wfp_message_writer * writer, + char const * key, + int value); + +extern void +wfp_impl_message_writer_add_string( + struct wfp_message_writer * writer, + char const * key, + char const * value); + +extern void +wfp_impl_message_writer_add_bytes( + struct wfp_message_writer * writer, + char const * key, + char const * data, + size_t length); + +extern void +wfp_impl_message_writer_add_dirbuffer( + struct wfp_message_writer * writer, + struct wfp_dirbuffer * dirbuffer); + +extern void +wfp_impl_message_writer_set_error( + struct wfp_message_writer * writer, + int code); + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/lib/webfuse_provider/impl/operation/close.c b/lib/webfuse_provider/impl/operation/close.c index 3b87a49..58218b5 100644 --- a/lib/webfuse_provider/impl/operation/close.c +++ b/lib/webfuse_provider/impl/operation/close.c @@ -1,26 +1,27 @@ #include "webfuse_provider/impl/operation/close.h" #include #include "webfuse_provider/impl/util/util.h" +#include "webfuse_provider/impl/json/node.h" void wfp_impl_close( struct wfp_impl_invokation_context * context, - json_t * params, + struct wfp_json const * params, int WFP_UNUSED_PARAM(id)) { - size_t const param_count = json_array_size(params); + size_t const param_count = wfp_impl_json_array_size(params); if (4 == param_count) { - json_t * inode_holder = json_array_get(params, 1); - json_t * handle_holder = json_array_get(params, 2); - json_t * flags_holder = json_array_get(params, 3); + struct wfp_json const * inode_holder = wfp_impl_json_array_get(params, 1); + struct wfp_json const * handle_holder = wfp_impl_json_array_get(params, 2); + struct wfp_json const * flags_holder = wfp_impl_json_array_get(params, 3); - if (json_is_integer(inode_holder) && - json_is_integer(handle_holder) && - json_is_integer(flags_holder)) + if (wfp_impl_json_is_int(inode_holder) && + wfp_impl_json_is_int(handle_holder) && + wfp_impl_json_is_int(flags_holder)) { - ino_t inode = (ino_t) json_integer_value(inode_holder); - uint32_t handle = (uint32_t) (json_integer_value(handle_holder) & UINT32_MAX); - int flags = json_integer_value(flags_holder); + ino_t inode = (ino_t) wfp_impl_json_int_get(inode_holder); + uint32_t handle = (uint32_t) (wfp_impl_json_int_get(handle_holder) & UINT32_MAX); + int flags = wfp_impl_json_int_get(flags_holder); context->provider->close(inode, handle, flags, context->user_data); } diff --git a/lib/webfuse_provider/impl/operation/close.h b/lib/webfuse_provider/impl/operation/close.h index 7c6fd7b..f769906 100644 --- a/lib/webfuse_provider/impl/operation/close.h +++ b/lib/webfuse_provider/impl/operation/close.h @@ -10,7 +10,7 @@ extern "C" extern void wfp_impl_close( struct wfp_impl_invokation_context * context, - json_t * params, + struct wfp_json const * params, int id); extern void wfp_impl_close_default( diff --git a/lib/webfuse_provider/impl/operation/getattr.c b/lib/webfuse_provider/impl/operation/getattr.c index 7c71f08..1642d58 100644 --- a/lib/webfuse_provider/impl/operation/getattr.c +++ b/lib/webfuse_provider/impl/operation/getattr.c @@ -4,22 +4,24 @@ #include "webfuse_provider/impl/operation/error.h" #include "webfuse_provider/impl/request.h" +#include "webfuse_provider/impl/message_writer.h" #include "webfuse_provider/impl/util/util.h" +#include "webfuse_provider/impl/json/node.h" void wfp_impl_getattr( struct wfp_impl_invokation_context * context, - json_t * params, + struct wfp_json const * params, int id) { - size_t const count = json_array_size(params); + size_t const count = wfp_impl_json_array_size(params); if (2 == count) { - json_t * inode_holder = json_array_get(params, 1); + struct wfp_json const * inode_holder = wfp_impl_json_array_get(params, 1); - if (json_is_integer(inode_holder)) + if (wfp_impl_json_is_int(inode_holder)) { - ino_t inode = (ino_t) json_integer_value(inode_holder); + ino_t inode = (ino_t) wfp_impl_json_int_get(inode_holder); struct wfp_request * request = wfp_impl_request_create(context->request, id); context->provider->getattr(request, inode, context->user_data); @@ -42,23 +44,23 @@ void wfp_impl_respond_getattr( bool const is_file = (0 != (stat->st_mode & S_IFREG)); bool const is_dir = (0 != (stat->st_mode & S_IFDIR)); - json_t * result = json_object(); - json_object_set_new(result, "inode", json_integer(stat->st_ino)); - json_object_set_new(result, "mode", json_integer(stat->st_mode & 0777)); - json_object_set_new(result, "atime", json_integer(stat->st_atime)); - json_object_set_new(result, "mtime", json_integer(stat->st_mtime)); - json_object_set_new(result, "ctime", json_integer(stat->st_ctime)); + struct wfp_message_writer * writer = wfp_impl_request_get_writer(request); + wfp_impl_message_writer_add_int(writer, "inode", stat->st_ino); + wfp_impl_message_writer_add_int(writer, "mode" , stat->st_mode & 0777); + wfp_impl_message_writer_add_int(writer, "atime", stat->st_atime); + wfp_impl_message_writer_add_int(writer, "mtime", stat->st_mtime); + wfp_impl_message_writer_add_int(writer, "ctime", stat->st_ctime); if (is_file) { - json_object_set_new(result, "type", json_string("file")); - json_object_set_new(result, "size", json_integer(stat->st_size)); + wfp_impl_message_writer_add_string(writer, "type", "file"); + wfp_impl_message_writer_add_int(writer, "size", stat->st_size); } if (is_dir) { - json_object_set_new(result, "type", json_string("dir")); + wfp_impl_message_writer_add_string(writer, "type", "dir"); } - wfp_impl_respond(request, result); + wfp_impl_respond(request); } diff --git a/lib/webfuse_provider/impl/operation/getattr.h b/lib/webfuse_provider/impl/operation/getattr.h index a14f8de..fd65c94 100644 --- a/lib/webfuse_provider/impl/operation/getattr.h +++ b/lib/webfuse_provider/impl/operation/getattr.h @@ -14,7 +14,7 @@ extern void wfp_impl_respond_getattr( extern void wfp_impl_getattr( struct wfp_impl_invokation_context * context, - json_t * params, + struct wfp_json const * params, int id); extern void wfp_impl_getattr_default( diff --git a/lib/webfuse_provider/impl/operation/lookup.c b/lib/webfuse_provider/impl/operation/lookup.c index 3f39c4a..c1af3dd 100644 --- a/lib/webfuse_provider/impl/operation/lookup.c +++ b/lib/webfuse_provider/impl/operation/lookup.c @@ -4,24 +4,26 @@ #include "webfuse_provider/impl/operation/error.h" #include "webfuse_provider/impl/request.h" +#include "webfuse_provider/impl/message_writer.h" #include "webfuse_provider/impl/util/util.h" +#include "webfuse_provider/impl/json/node.h" void wfp_impl_lookup( struct wfp_impl_invokation_context * context, - json_t * params, + struct wfp_json const * params, int id) { - size_t const count = json_array_size(params); + size_t const count = wfp_impl_json_array_size(params); if (3 == count) { - json_t * inode_holder = json_array_get(params, 1); - json_t * name_holder = json_array_get(params, 2); + struct wfp_json const * inode_holder = wfp_impl_json_array_get(params, 1); + struct wfp_json const * name_holder = wfp_impl_json_array_get(params, 2); - if (json_is_integer(inode_holder) && - json_is_string(name_holder)) + if (wfp_impl_json_is_int(inode_holder) && + wfp_impl_json_is_string(name_holder)) { - ino_t inode = json_integer_value(inode_holder); - char const * name = json_string_value(name_holder); + ino_t inode = wfp_impl_json_int_get(inode_holder); + char const * name = wfp_impl_json_string_get(name_holder); struct wfp_request * request = wfp_impl_request_create(context->request, id); context->provider->lookup(request, inode, name, context->user_data); @@ -36,25 +38,25 @@ void wfp_impl_respond_lookup( bool const is_file = (0 != (stat->st_mode & S_IFREG)); bool const is_dir = (0 != (stat->st_mode & S_IFDIR)); - json_t * result = json_object(); - json_object_set_new(result, "inode", json_integer(stat->st_ino)); - json_object_set_new(result, "mode", json_integer(stat->st_mode & 0777)); - json_object_set_new(result, "atime", json_integer(stat->st_atime)); - json_object_set_new(result, "mtime", json_integer(stat->st_mtime)); - json_object_set_new(result, "ctime", json_integer(stat->st_ctime)); + struct wfp_message_writer * writer = wfp_impl_request_get_writer(request); + wfp_impl_message_writer_add_int(writer, "inode", stat->st_ino); + wfp_impl_message_writer_add_int(writer, "mode", stat->st_mode & 0777); + wfp_impl_message_writer_add_int(writer, "atime", stat->st_atime); + wfp_impl_message_writer_add_int(writer, "mtime", stat->st_mtime); + wfp_impl_message_writer_add_int(writer, "ctime", stat->st_ctime); if (is_file) { - json_object_set_new(result, "type", json_string("file")); - json_object_set_new(result, "size", json_integer(stat->st_size)); + wfp_impl_message_writer_add_string(writer, "type", "file"); + wfp_impl_message_writer_add_int(writer, "size", stat->st_size); } if (is_dir) { - json_object_set_new(result, "type", json_string("dir")); + wfp_impl_message_writer_add_string(writer, "type", "dir"); } - wfp_impl_respond(request, result); + wfp_impl_respond(request); } void wfp_impl_lookup_default( diff --git a/lib/webfuse_provider/impl/operation/lookup.h b/lib/webfuse_provider/impl/operation/lookup.h index c4caf6c..67c451a 100644 --- a/lib/webfuse_provider/impl/operation/lookup.h +++ b/lib/webfuse_provider/impl/operation/lookup.h @@ -14,7 +14,7 @@ extern void wfp_impl_respond_lookup( extern void wfp_impl_lookup( struct wfp_impl_invokation_context * context, - json_t * params, + struct wfp_json const * params, int id); extern void wfp_impl_lookup_default( diff --git a/lib/webfuse_provider/impl/operation/open.c b/lib/webfuse_provider/impl/operation/open.c index 4803cfc..5b7ba0e 100644 --- a/lib/webfuse_provider/impl/operation/open.c +++ b/lib/webfuse_provider/impl/operation/open.c @@ -1,24 +1,26 @@ #include "webfuse_provider/impl/operation/open.h" #include "webfuse_provider/impl/operation/error.h" #include "webfuse_provider/impl/request.h" +#include "webfuse_provider/impl/message_writer.h" #include "webfuse_provider/impl/util/util.h" +#include "webfuse_provider/impl/json/node.h" void wfp_impl_open( struct wfp_impl_invokation_context * context, - json_t * params, + struct wfp_json const * params, int id) { - size_t const count = json_array_size(params); + size_t const count = wfp_impl_json_array_size(params); if (3 == count) { - json_t * inode_holder = json_array_get(params, 1); - json_t * flags_holder = json_array_get(params, 2); + struct wfp_json const * inode_holder = wfp_impl_json_array_get(params, 1); + struct wfp_json const * flags_holder = wfp_impl_json_array_get(params, 2); - if (json_is_integer(inode_holder) && - json_is_integer(flags_holder)) + if (wfp_impl_json_is_int(inode_holder) && + wfp_impl_json_is_int(flags_holder)) { - ino_t inode = (ino_t) json_integer_value(inode_holder); - int flags = (ino_t) json_integer_value(flags_holder); + ino_t inode = (ino_t) wfp_impl_json_int_get(inode_holder); + int flags = (ino_t) wfp_impl_json_int_get(flags_holder); struct wfp_request * request = wfp_impl_request_create(context->request, id); @@ -40,8 +42,8 @@ void wfp_impl_respond_open( struct wfp_request * request, uint32_t handle) { - json_t * result = json_object(); - json_object_set_new(result, "handle", json_integer((int) handle)); + struct wfp_message_writer * writer = wfp_impl_request_get_writer(request); + wfp_impl_message_writer_add_int(writer, "handle", (int) handle); - wfp_impl_respond(request, result); + wfp_impl_respond(request); } diff --git a/lib/webfuse_provider/impl/operation/open.h b/lib/webfuse_provider/impl/operation/open.h index 052d185..637bebe 100644 --- a/lib/webfuse_provider/impl/operation/open.h +++ b/lib/webfuse_provider/impl/operation/open.h @@ -14,7 +14,7 @@ extern void wfp_impl_respond_open( extern void wfp_impl_open( struct wfp_impl_invokation_context * context, - json_t * params, + struct wfp_json const * params, int id); extern void wfp_impl_open_default( diff --git a/lib/webfuse_provider/impl/operation/read.c b/lib/webfuse_provider/impl/operation/read.c index 0383eb2..08ad6f9 100644 --- a/lib/webfuse_provider/impl/operation/read.c +++ b/lib/webfuse_provider/impl/operation/read.c @@ -4,31 +4,32 @@ #include "webfuse_provider/impl/operation/error.h" #include "webfuse_provider/impl/request.h" +#include "webfuse_provider/impl/message_writer.h" #include "webfuse_provider/impl/util/util.h" -#include "webfuse_provider/impl/util/base64.h" +#include "webfuse_provider/impl/json/node.h" void wfp_impl_read( struct wfp_impl_invokation_context * context, - json_t * params, + struct wfp_json const * params, int id) { - size_t const count = json_array_size(params); + size_t const count = wfp_impl_json_array_size(params); if (5 == count) { - json_t * inode_holder = json_array_get(params, 1); - json_t * handle_holder = json_array_get(params, 2); - json_t * offset_holder = json_array_get(params, 3); - json_t * length_holder = json_array_get(params, 4); + struct wfp_json const * inode_holder = wfp_impl_json_array_get(params, 1); + struct wfp_json const * handle_holder = wfp_impl_json_array_get(params, 2); + struct wfp_json const * offset_holder = wfp_impl_json_array_get(params, 3); + struct wfp_json const * length_holder = wfp_impl_json_array_get(params, 4); - if (json_is_integer(inode_holder) && - json_is_integer(handle_holder) && - json_is_integer(offset_holder) && - json_is_integer(length_holder)) + if (wfp_impl_json_is_int(inode_holder) && + wfp_impl_json_is_int(handle_holder) && + wfp_impl_json_is_int(offset_holder) && + wfp_impl_json_is_int(length_holder)) { - ino_t inode = (ino_t) json_integer_value(inode_holder); - int handle = json_integer_value(handle_holder); - size_t offset = json_integer_value(offset_holder); - size_t length = json_integer_value(length_holder); + ino_t inode = (ino_t) wfp_impl_json_int_get(inode_holder); + int handle = wfp_impl_json_int_get(handle_holder); + size_t offset = wfp_impl_json_int_get(offset_holder); + size_t length = wfp_impl_json_int_get(length_holder); struct wfp_request * request = wfp_impl_request_create(context->request, id); context->provider->read(request, inode, handle, offset, length, context->user_data); @@ -52,27 +53,19 @@ void wfp_impl_respond_read( char const * data, size_t length) { + struct wfp_message_writer * writer = wfp_impl_request_get_writer(request); + if (0 < 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_t * result = json_object(); - json_object_set_new(result, "data", json_string(buffer)); - json_object_set_new(result, "format", json_string("base64")); - json_object_set_new(result, "count", json_integer((int) length)); - - wfp_impl_respond(request, result); - free(buffer); + wfp_impl_message_writer_add_bytes(writer, "data", data, length); + wfp_impl_message_writer_add_string(writer, "format", "base64"); } else { - json_t * result = json_object(); - json_object_set_new(result, "data", json_string("")); - json_object_set_new(result, "format", json_string("identity")); - json_object_set_new(result, "count", json_integer(0)); - - wfp_impl_respond(request, result); + wfp_impl_message_writer_add_string(writer, "data", ""); + wfp_impl_message_writer_add_string(writer, "format", "identity"); } + + wfp_impl_message_writer_add_int(writer, "count", ((int) length)); + wfp_impl_respond(request); } \ No newline at end of file diff --git a/lib/webfuse_provider/impl/operation/read.h b/lib/webfuse_provider/impl/operation/read.h index be6f734..bf8f189 100644 --- a/lib/webfuse_provider/impl/operation/read.h +++ b/lib/webfuse_provider/impl/operation/read.h @@ -15,7 +15,7 @@ extern void wfp_impl_respond_read( extern void wfp_impl_read( struct wfp_impl_invokation_context * context, - json_t * params, + struct wfp_json const * params, int id); extern void wfp_impl_read_default( diff --git a/lib/webfuse_provider/impl/operation/readdir.c b/lib/webfuse_provider/impl/operation/readdir.c index 6813f2d..7fb8de9 100644 --- a/lib/webfuse_provider/impl/operation/readdir.c +++ b/lib/webfuse_provider/impl/operation/readdir.c @@ -2,21 +2,23 @@ #include "webfuse_provider/impl/operation/error.h" #include "webfuse_provider/impl/dirbuffer.h" #include "webfuse_provider/impl/request.h" +#include "webfuse_provider/impl/message_writer.h" #include "webfuse_provider/impl/util/util.h" +#include "webfuse_provider/impl/json/node.h" void wfp_impl_readdir( struct wfp_impl_invokation_context * context, - json_t * params, + struct wfp_json const * params, int id) { - size_t const count = json_array_size(params); + size_t const count = wfp_impl_json_array_size(params); if (2 == count) { - json_t * inode_holder = json_array_get(params, 1); + struct wfp_json const * inode_holder = wfp_impl_json_array_get(params, 1); - if (json_is_integer(inode_holder)) + if (wfp_impl_json_is_int(inode_holder)) { - ino_t inode = (ino_t) json_integer_value(inode_holder); + ino_t inode = (ino_t) wfp_impl_json_int_get(inode_holder); struct wfp_request * request = wfp_impl_request_create(context->request, id); context->provider->readdir(request, inode, context->user_data); @@ -36,7 +38,8 @@ void wfp_impl_respond_readdir( struct wfp_request * request, struct wfp_dirbuffer * dirbuffer) { - json_t * result = wfp_impl_dirbuffer_take(dirbuffer); - wfp_impl_respond(request, result); + struct wfp_message_writer * writer = wfp_impl_request_get_writer(request); + wfp_impl_message_writer_add_dirbuffer(writer, dirbuffer); + wfp_impl_respond(request); } diff --git a/lib/webfuse_provider/impl/operation/readdir.h b/lib/webfuse_provider/impl/operation/readdir.h index 8884e9e..fa9d53e 100644 --- a/lib/webfuse_provider/impl/operation/readdir.h +++ b/lib/webfuse_provider/impl/operation/readdir.h @@ -14,7 +14,7 @@ extern void wfp_impl_respond_readdir( extern void wfp_impl_readdir( struct wfp_impl_invokation_context * context, - json_t * params, + struct wfp_json const * params, int id); extern void wfp_impl_readdir_default( diff --git a/lib/webfuse_provider/impl/provider.c b/lib/webfuse_provider/impl/provider.c index 1042802..2686c5f 100644 --- a/lib/webfuse_provider/impl/provider.c +++ b/lib/webfuse_provider/impl/provider.c @@ -1,8 +1,5 @@ #include "webfuse_provider/impl/provider.h" -#include -#include - #include "webfuse_provider/impl/request.h" #include "webfuse_provider/impl/operation/lookup.h" #include "webfuse_provider/impl/operation/getattr.h" @@ -10,10 +7,16 @@ #include "webfuse_provider/impl/operation/open.h" #include "webfuse_provider/impl/operation/close.h" #include "webfuse_provider/impl/operation/read.h" +#include "webfuse_provider/impl/json/node.h" + +#include +#include + +struct wfp_json; typedef void wfp_impl_invoke_fn( struct wfp_impl_invokation_context * context, - json_t * params, + struct wfp_json const * params, int id); @@ -27,7 +30,7 @@ struct wfp_impl_method static void wfp_impl_provider_invoke_method( struct wfp_impl_invokation_context * context, char const * method_name, - json_t * params, + struct wfp_json const * params, int id) { static struct wfp_impl_method const methods[] = @@ -86,16 +89,16 @@ void wfp_impl_provider_init_from_prototype( void wfp_impl_provider_invoke( struct wfp_impl_invokation_context * context, - json_t * request) + struct wfp_json const * request) { - json_t * method_holder = json_object_get(request, "method"); - json_t * params = json_object_get(request, "params"); - json_t * id_holder = json_object_get(request, "id"); + struct wfp_json const * method_holder = wfp_impl_json_object_get(request, "method"); + struct wfp_json const * params = wfp_impl_json_object_get(request, "params"); + struct wfp_json const * id_holder = wfp_impl_json_object_get(request, "id"); - if ((json_is_string(method_holder)) && (json_is_array(params))) + if ((wfp_impl_json_is_string(method_holder)) && (wfp_impl_json_is_array(params))) { - char const * method = json_string_value(method_holder); - int id = json_is_integer(id_holder) ? json_integer_value(id_holder) : 0; + char const * method = wfp_impl_json_string_get(method_holder); + int id = wfp_impl_json_is_int(id_holder) ? wfp_impl_json_int_get(id_holder) : 0; wfp_impl_provider_invoke_method(context, method, params, id); } diff --git a/lib/webfuse_provider/impl/provider.h b/lib/webfuse_provider/impl/provider.h index f3c00c7..16579ef 100644 --- a/lib/webfuse_provider/impl/provider.h +++ b/lib/webfuse_provider/impl/provider.h @@ -5,7 +5,6 @@ #include #endif -#include #include "webfuse_provider/client_config.h" @@ -14,6 +13,8 @@ extern "C" { #endif +struct wfp_json; + struct wfp_provider { wfp_connected_fn * connected; @@ -44,7 +45,7 @@ extern void wfp_impl_provider_init_from_prototype( extern void wfp_impl_provider_invoke( struct wfp_impl_invokation_context * context, - json_t * request); + struct wfp_json const * request); extern bool wfp_impl_provider_is_authentication_enabled( struct wfp_provider * provider); diff --git a/lib/webfuse_provider/impl/request.c b/lib/webfuse_provider/impl/request.c index 85f5087..f2a2feb 100644 --- a/lib/webfuse_provider/impl/request.c +++ b/lib/webfuse_provider/impl/request.c @@ -1,7 +1,8 @@ #include "webfuse_provider/impl/request.h" +#include "webfuse_provider/impl/operation/error.h" +#include "webfuse_provider/impl/message_writer.h" #include -#include "webfuse_provider/impl/operation/error.h" struct wfp_request * wfp_impl_request_create( struct wfp_request * prototype, @@ -10,7 +11,7 @@ struct wfp_request * wfp_impl_request_create( struct wfp_request * request = malloc(sizeof(struct wfp_request)); request->respond = prototype->respond; request->user_data = prototype->user_data; - request->id = id; + request->writer = wfp_impl_message_writer_create(id); return request; } @@ -18,20 +19,24 @@ struct wfp_request * wfp_impl_request_create( void wfp_impl_request_dispose( struct wfp_request * request) { + wfp_impl_message_writer_dispose(request->writer); free(request); } -extern void wfp_impl_respond( - struct wfp_request * request, - json_t * result) +struct wfp_message_writer * +wfp_impl_request_get_writer( + struct wfp_request * request) { - json_t * response = json_object(); - json_object_set_new(response, "result", result); - json_object_set_new(response, "id", json_integer(request->id)); + return request->writer; +} + +extern void wfp_impl_respond( + struct wfp_request * request) +{ + struct wfp_message * response = wfp_impl_message_writer_take_message(request->writer); request->respond(response, request->user_data); - json_decref(response); wfp_impl_request_dispose(request); } @@ -39,14 +44,6 @@ void wfp_impl_respond_error( struct wfp_request * request, wfp_status status) { - json_t * response = json_object(); - json_t * error = json_object(); - json_object_set_new(error, "code", json_integer(status)); - json_object_set_new(response, "error", error); - json_object_set_new(response, "id", json_integer(request->id)); - - request->respond(response, request->user_data); - - json_decref(response); - wfp_impl_request_dispose(request); + wfp_impl_message_writer_set_error(request->writer, status); + wfp_impl_respond(request); } \ No newline at end of file diff --git a/lib/webfuse_provider/impl/request.h b/lib/webfuse_provider/impl/request.h index 5945c1e..337bfac 100644 --- a/lib/webfuse_provider/impl/request.h +++ b/lib/webfuse_provider/impl/request.h @@ -1,7 +1,6 @@ #ifndef WFP_IMPL_REQUEST_H #define WFP_IMPL_REQUEST_H -#include #include "webfuse_provider/impl/provider.h" #include "webfuse_provider/status.h" @@ -10,8 +9,11 @@ extern "C" { #endif +struct wfp_message; +struct wfp_message_writer; + typedef void wfp_impl_request_respond_fn( - json_t * response, + struct wfp_message * response, void * user_data); struct wfp_request @@ -19,8 +21,13 @@ struct wfp_request wfp_impl_request_respond_fn * respond; void * user_data; int id; + struct wfp_message_writer * writer; }; +extern struct wfp_message_writer * +wfp_impl_request_get_writer( + struct wfp_request * request); + extern void wfp_impl_respond_error( struct wfp_request * request, wfp_status status); @@ -33,8 +40,7 @@ extern void wfp_impl_request_dispose( struct wfp_request * request); extern void wfp_impl_respond( - struct wfp_request * request, - json_t * result); + struct wfp_request * request); #ifdef __cplusplus } diff --git a/lib/webfuse_provider/impl/util/json_util.c b/lib/webfuse_provider/impl/util/json_util.c deleted file mode 100644 index 4ea81d5..0000000 --- a/lib/webfuse_provider/impl/util/json_util.c +++ /dev/null @@ -1,27 +0,0 @@ -#include "webfuse_provider/impl/util/json_util.h" - -int wfp_impl_json_get_int(json_t const * object, char const * key, int default_value) -{ - int result = default_value; - - json_t * holder = json_object_get(object, key); - if (json_is_integer(holder)) - { - result = json_integer_value(holder); - } - - return result; -} - -wfp_status -wfp_impl_jsonrpc_get_status( - json_t const * error) -{ - wfp_status status = WFP_GOOD; - if (NULL != error) - { - status = wfp_impl_json_get_int(error, "code", WFP_BAD_FORMAT); - } - - return status; -} diff --git a/lib/webfuse_provider/impl/util/json_util.h b/lib/webfuse_provider/impl/util/json_util.h deleted file mode 100644 index fcc47df..0000000 --- a/lib/webfuse_provider/impl/util/json_util.h +++ /dev/null @@ -1,26 +0,0 @@ -#ifndef WFP_JSON_UTIL_H -#define WFP_JSON_UTIL_H - -#include -#include "webfuse_provider/status.h" - -#ifdef __cplusplus -extern "C" -{ -#endif - -extern int -wfp_impl_json_get_int( - json_t const * object, - char const * key, - int default_value); - -extern wfp_status -wfp_impl_jsonrpc_get_status( - json_t const * error); - -#ifdef __cplusplus -} -#endif - -#endif diff --git a/meson.build b/meson.build index 333695c..f0c0313 100644 --- a/meson.build +++ b/meson.build @@ -3,31 +3,33 @@ project('webfuse-provider', 'c', 'cpp', version: '0.4.0', license: 'LGPL-3.0+') without_tests = get_option('without_tests') without_examples = get_option('without_examples') -libwebsockets_dep = dependency('libwebsockets', version: '>=4.0.13', required: false) +libwebsockets_dep = dependency('libwebsockets', version: '>=4.0.0', required: false) if not libwebsockets_dep.found() cmake = import('cmake') libwebsockets = cmake.subproject('libwebsockets') libwebsockets_dep = libwebsockets.dependency('websockets_shared') endif -jansson_dep = dependency('jansson', version: '>=2.11', fallback: ['jansson', 'jansson_dep']) - pkg_config = import('pkgconfig') # Webfuse provider webfuse_provider_static = static_library('webfuse_provider', 'lib/webfuse_provider/impl/message.c', + 'lib/webfuse_provider/impl/message_writer.c', 'lib/webfuse_provider/impl/message_queue.c', 'lib/webfuse_provider/impl/status.c', 'lib/webfuse_provider/impl/util/slist.c', 'lib/webfuse_provider/impl/util/base64.c', 'lib/webfuse_provider/impl/util/lws_log.c', - 'lib/webfuse_provider/impl/util/json_util.c', 'lib/webfuse_provider/impl/util/url.c', 'lib/webfuse_provider/impl/timer/manager.c', 'lib/webfuse_provider/impl/timer/timepoint.c', 'lib/webfuse_provider/impl/timer/timer.c', + 'lib/webfuse_provider/impl/json/writer.c', + 'lib/webfuse_provider/impl/json/node.c', + 'lib/webfuse_provider/impl/json/reader.c', + 'lib/webfuse_provider/impl/json/doc.c', 'lib/webfuse_provider/impl/jsonrpc/proxy.c', 'lib/webfuse_provider/impl/jsonrpc/proxy_variadic.c', 'lib/webfuse_provider/impl/jsonrpc/request.c', @@ -49,31 +51,31 @@ webfuse_provider_static = static_library('webfuse_provider', 'lib/webfuse_provider/impl/operation/read.c', c_args: ['-fvisibility=hidden'], include_directories: ['include', 'lib'], - dependencies: [libwebsockets_dep, jansson_dep]) + dependencies: [libwebsockets_dep]) webfuse_provider_static_dep = declare_dependency( include_directories: ['include'], link_with: webfuse_provider_static, - dependencies: [libwebsockets_dep, jansson_dep]) + dependencies: [libwebsockets_dep]) webfuse_provider = shared_library('webfuse_provider', 'lib/webfuse_provider/api.c', version: meson.project_version(), c_args: ['-fvisibility=hidden', '-DWFP_API=WFP_EXPORT'], include_directories: ['include', 'lib'], - dependencies: [webfuse_provider_static_dep, libwebsockets_dep, jansson_dep], + dependencies: [webfuse_provider_static_dep, libwebsockets_dep], install: true) webfuse_provider_dep = declare_dependency( include_directories: ['include'], link_with: [webfuse_provider], - dependencies: [libwebsockets_dep, jansson_dep]) + dependencies: [libwebsockets_dep]) install_subdir('include/webfuse_provider', install_dir: 'include') pkg_config.generate( libraries: [webfuse_provider], - requires: ['libwebsockets', 'jansson'], + requires: ['libwebsockets'], subdirs: '.', version: meson.project_version(), name: 'libwebfuse_provider', @@ -104,12 +106,14 @@ alltests = executable('alltests', 'test/webfuse_provider/test_util/ws_server.cc', 'test/webfuse_provider/test_util/webfuse_server.cc', 'test/webfuse_provider/test_util/client.cc', - 'test/webfuse_provider/test_util/jansson_test_environment.cc', + 'test/webfuse_provider/test_util/json_doc.cc', 'test/webfuse_provider/mocks/fake_invokation_context.cc', 'test/webfuse_provider/mocks/mock_request.cc', '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/json/test_json_parser.cc', 'test/webfuse_provider/jsonrpc/mock_timer_callback.cc', 'test/webfuse_provider/jsonrpc/mock_timer.cc', 'test/webfuse_provider/jsonrpc/test_is_request.cc', @@ -120,7 +124,6 @@ alltests = executable('alltests', 'test/webfuse_provider/jsonrpc/test_response_parser.cc', 'test/webfuse_provider/timer/test_timepoint.cc', 'test/webfuse_provider/timer/test_timer.cc', - 'test/webfuse_provider/util/test_util.cc', 'test/webfuse_provider/util/test_container_of.cc', 'test/webfuse_provider/util/test_slist.cc', 'test/webfuse_provider/util/test_base64.cc', @@ -153,7 +156,6 @@ alltests = executable('alltests', dependencies: [ webfuse_provider_static_dep, libwebsockets_dep, - jansson_dep, gtest_dep, gmock_main_dep, test_certs_dep diff --git a/subprojects/jansson.wrap b/subprojects/jansson.wrap deleted file mode 100644 index 6282afd..0000000 --- a/subprojects/jansson.wrap +++ /dev/null @@ -1,10 +0,0 @@ -[wrap-file] -directory = jansson-2.11 - -source_url = http://www.digip.org/jansson/releases/jansson-2.11.tar.bz2 -source_filename = jansson-2.11.tar.bz2 -source_hash = 783132e2fc970feefc2fa54199ef65ee020bd8e0e991a78ea44b8586353a0947 - -patch_url = https://wrapdb.mesonbuild.com/v1/projects/jansson/2.11/3/get_zip -patch_filename = jansson-2.11-3-wrap.zip -patch_hash = 0bcac510994890048d42658c674e33dd7d88715fc1e3bf49d10012f57b0e0020 \ No newline at end of file diff --git a/test/webfuse_provider/json/test_json_parser.cc b/test/webfuse_provider/json/test_json_parser.cc new file mode 100644 index 0000000..4e6e14d --- /dev/null +++ b/test/webfuse_provider/json/test_json_parser.cc @@ -0,0 +1,303 @@ +#include "webfuse_provider/impl/json/doc.h" +#include "webfuse_provider/impl/json/node.h" +#include +#include + +namespace +{ + wfp_json_doc * parse_json(char * text) + { + return wfp_impl_json_doc_loadb(text, strlen(text)); + } +} + +TEST(json_parser, parse_null) +{ + char text[] = "null"; + wfp_json_doc * doc = parse_json(text); + ASSERT_NE(nullptr, doc); + wfp_json const * root = wfp_impl_json_doc_root(doc); + ASSERT_TRUE(wfp_impl_json_is_null(root)); + + wfp_impl_json_doc_dispose(doc); +} + +TEST(json_parser, parse_true) +{ + char text[] = "true"; + wfp_json_doc * doc = parse_json(text); + ASSERT_NE(nullptr, doc); + wfp_json const * root = wfp_impl_json_doc_root(doc); + ASSERT_TRUE(wfp_impl_json_is_bool(root)); + ASSERT_TRUE(wfp_impl_json_bool_get(root)); + + wfp_impl_json_doc_dispose(doc); +} + +TEST(json_parser, parse_false) +{ + char text[] = "false"; + wfp_json_doc * doc = parse_json(text); + ASSERT_NE(nullptr, doc); + wfp_json const * root = wfp_impl_json_doc_root(doc); + ASSERT_TRUE(wfp_impl_json_is_bool(root)); + ASSERT_FALSE(wfp_impl_json_bool_get(root)); + + wfp_impl_json_doc_dispose(doc); +} + +TEST(json_parser, parse_int) +{ + char text[] = "42"; + wfp_json_doc * doc = parse_json(text); + ASSERT_NE(nullptr, doc); + wfp_json const * root = wfp_impl_json_doc_root(doc); + ASSERT_TRUE(wfp_impl_json_is_int(root)); + ASSERT_EQ(42, wfp_impl_json_int_get(root)); + + wfp_impl_json_doc_dispose(doc); +} + +TEST(json_parser, parse_negative_int) +{ + char text[] = "-1234"; + wfp_json_doc * doc = parse_json(text); + ASSERT_NE(nullptr, doc); + wfp_json const * root = wfp_impl_json_doc_root(doc); + ASSERT_TRUE(wfp_impl_json_is_int(root)); + ASSERT_EQ(-1234, wfp_impl_json_int_get(root)); + + wfp_impl_json_doc_dispose(doc); +} + +TEST(json_parser, parse_string) +{ + char text[] = "\"brummni\""; + wfp_json_doc * doc = parse_json(text); + ASSERT_NE(nullptr, doc); + wfp_json const * root = wfp_impl_json_doc_root(doc); + ASSERT_TRUE(wfp_impl_json_is_string(root)); + ASSERT_STREQ("brummni", wfp_impl_json_string_get(root)); + + wfp_impl_json_doc_dispose(doc); +} + +TEST(json_parser, unescape_string) +{ + char text[] = "\"\\\"_\\\\_\\/_\\b_\\f_\\n_\\r_\\t\""; + wfp_json_doc * doc = parse_json(text); + ASSERT_NE(nullptr, doc); + wfp_json const * root = wfp_impl_json_doc_root(doc); + ASSERT_TRUE(wfp_impl_json_is_string(root)); + ASSERT_STREQ("\"_\\_/_\b_\f_\n_\r_\t", wfp_impl_json_string_get(root)); + + wfp_impl_json_doc_dispose(doc); +} + +TEST(json_parser, skip_whitespace) +{ + char text[] = " \t\r\n\"42\""; + wfp_json_doc * doc = parse_json(text); + ASSERT_NE(nullptr, doc); + wfp_json const * root = wfp_impl_json_doc_root(doc); + ASSERT_TRUE(wfp_impl_json_is_string(root)); + ASSERT_STREQ("42", wfp_impl_json_string_get(root)); + + wfp_impl_json_doc_dispose(doc); +} + +TEST(json_parser, parse_array) +{ + char text[] = "[true,1,\"foo\",[42]]"; + wfp_json_doc * doc = parse_json(text); + ASSERT_NE(nullptr, doc); + wfp_json const * root = wfp_impl_json_doc_root(doc); + ASSERT_TRUE(wfp_impl_json_is_array(root)); + ASSERT_EQ(4, wfp_impl_json_array_size(root)); + + ASSERT_TRUE(wfp_impl_json_is_bool(wfp_impl_json_array_get(root, 0))); + ASSERT_TRUE(wfp_impl_json_is_int(wfp_impl_json_array_get(root, 1))); + ASSERT_TRUE(wfp_impl_json_is_string(wfp_impl_json_array_get(root, 2))); + ASSERT_TRUE(wfp_impl_json_is_array(wfp_impl_json_array_get(root, 3))); + ASSERT_TRUE(wfp_impl_json_is_null(wfp_impl_json_array_get(root, 4))); + + wfp_impl_json_doc_dispose(doc); +} + +TEST(json_parser, parse_empty_array) +{ + char text[] = "[]"; + wfp_json_doc * doc = parse_json(text); + ASSERT_NE(nullptr, doc); + wfp_json const * root = wfp_impl_json_doc_root(doc); + ASSERT_TRUE(wfp_impl_json_is_array(root)); + ASSERT_EQ(0, wfp_impl_json_array_size(root)); + + wfp_impl_json_doc_dispose(doc); +} + +TEST(json_parser, parse_object) +{ + char text[] = "{\"method\":\"add\",\"params\":[1,2],\"id\":42}"; + wfp_json_doc * doc = parse_json(text); + ASSERT_NE(nullptr, doc); + wfp_json const * root = wfp_impl_json_doc_root(doc); + ASSERT_TRUE(wfp_impl_json_is_object(root)); + ASSERT_EQ(3, wfp_impl_json_object_size(root)); + + ASSERT_STREQ("method", wfp_impl_json_object_key(root, 0)); + ASSERT_TRUE(wfp_impl_json_is_string(wfp_impl_json_object_value(root, 0))); + + ASSERT_STREQ("params", wfp_impl_json_object_key(root, 1)); + ASSERT_TRUE(wfp_impl_json_is_array(wfp_impl_json_object_value(root, 1))); + + ASSERT_STREQ("id", wfp_impl_json_object_key(root, 2)); + ASSERT_TRUE(wfp_impl_json_is_int(wfp_impl_json_object_value(root, 2))); + + ASSERT_STREQ("", wfp_impl_json_object_key(root, 3)); + ASSERT_TRUE(wfp_impl_json_is_null(wfp_impl_json_object_value(root, 3))); + + + wfp_impl_json_doc_dispose(doc); +} + +TEST(json_parser, default_values) +{ + char text[] = "[true]"; + wfp_json_doc * doc = parse_json(text); + ASSERT_NE(nullptr, doc); + + wfp_json const * json_array = wfp_impl_json_doc_root(doc); + ASSERT_FALSE(wfp_impl_json_bool_get(json_array)); + ASSERT_EQ(0, wfp_impl_json_int_get(json_array)); + ASSERT_STREQ("", wfp_impl_json_string_get(json_array)); + ASSERT_EQ(0, wfp_impl_json_object_size(json_array)); + ASSERT_TRUE(wfp_impl_json_is_null(wfp_impl_json_object_get(json_array, "foo"))); + ASSERT_STREQ("", wfp_impl_json_object_key(json_array, 0)); + ASSERT_TRUE(wfp_impl_json_is_null(wfp_impl_json_object_value(json_array, 0))); + + wfp_json const * json_bool = wfp_impl_json_array_get(json_array, 0); + ASSERT_EQ(0, wfp_impl_json_array_size(json_bool)); + ASSERT_TRUE(wfp_impl_json_is_null(wfp_impl_json_array_get(json_bool, 0))); + + wfp_impl_json_doc_dispose(doc); + +} + +TEST(json_parser, parse_fail_invalid_json) +{ + { + char text[] = ""; + wfp_json_doc * doc = parse_json(text); + ASSERT_EQ(nullptr, doc); + } + + { + char text[] = "invalid"; + wfp_json_doc * doc = parse_json(text); + ASSERT_EQ(nullptr, doc); + } + + { + char text[] = "nul"; + wfp_json_doc * doc = parse_json(text); + ASSERT_EQ(nullptr, doc); + } + + { + char text[] = "tru"; + wfp_json_doc * doc = parse_json(text); + ASSERT_EQ(nullptr, doc); + } + + { + char text[] = "flas"; + wfp_json_doc * doc = parse_json(text); + ASSERT_EQ(nullptr, doc); + } + + { + char text[] = "+1"; + wfp_json_doc * doc = parse_json(text); + ASSERT_EQ(nullptr, doc); + } + + { + char text[] = "\"unterminated_string"; + wfp_json_doc * doc = parse_json(text); + ASSERT_EQ(nullptr, doc); + } + + { + char text[] = "\"invale_\\escape_\\sequence\""; + wfp_json_doc * doc = parse_json(text); + ASSERT_EQ(nullptr, doc); + } + + { + char text[] = "[1,2,3}"; + wfp_json_doc * doc = parse_json(text); + ASSERT_EQ(nullptr, doc); + } + + { + char text[] = "[1 2 3]"; + wfp_json_doc * doc = parse_json(text); + ASSERT_EQ(nullptr, doc); + } + + { + char text[] = "[1,2,3"; + wfp_json_doc * doc = parse_json(text); + ASSERT_EQ(nullptr, doc); + } + + { + char text[] = "[1,2,]"; + wfp_json_doc * doc = parse_json(text); + ASSERT_EQ(nullptr, doc); + } + + { + char text[] = "{\"method\":\"add\",\"params\":[1,2],\"id\":42"; + wfp_json_doc * doc = parse_json(text); + ASSERT_EQ(nullptr, doc); + } + + { + char text[] = "[\"method\",[], {}, \"params\":,42]"; + wfp_json_doc * doc = parse_json(text); + ASSERT_EQ(nullptr, doc); + } + + { + char text[] = "{\"key\" \"value\"}"; + wfp_json_doc * doc = parse_json(text); + ASSERT_EQ(nullptr, doc); + } + + { + char text[] = "{\"key\": }"; + wfp_json_doc * doc = parse_json(text); + ASSERT_EQ(nullptr, doc); + } + + { + char text[] = "{\"key\": \"value\""; + wfp_json_doc * doc = parse_json(text); + ASSERT_EQ(nullptr, doc); + } + + { + char text[] = "{\"key\" \"value\"]"; + wfp_json_doc * doc = parse_json(text); + ASSERT_EQ(nullptr, doc); + } + + { + char text[] = "{\"key\": \"value\", }"; + wfp_json_doc * doc = parse_json(text); + ASSERT_EQ(nullptr, doc); + } + +} \ No newline at end of file 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..5ce9802 --- /dev/null +++ b/test/webfuse_provider/json/test_json_writer.cc @@ -0,0 +1,252 @@ +#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_write_int(writer, "answer", 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_write_int(writer, "a", 42); + wfp_impl_json_writer_object_write_string(writer, "b", "0"); + wfp_impl_json_writer_object_begin_array(writer, "c"); + 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_begin_object(writer, "a"); + wfp_impl_json_writer_object_begin_object(writer, "b"); + wfp_impl_json_writer_object_begin_object(writer, "c"); + 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, dont_escape_string_uncecked) +{ + wfp_json_writer * writer = wfp_impl_json_writer_create(128,0); + wfp_impl_json_writer_write_string_nocheck(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); +} + +TEST(json_writer, expand_buffer) +{ + wfp_json_writer * writer = wfp_impl_json_writer_create(1,0); + wfp_impl_json_writer_write_string(writer, "very large contents"); + + char * data = wfp_impl_json_writer_take_data(writer, nullptr); + + ASSERT_STREQ("\"very large contents\"", data); + + wfp_impl_json_writer_dispose(writer); + free(data); +} \ No newline at end of file diff --git a/test/webfuse_provider/jsonrpc/test_is_request.cc b/test/webfuse_provider/jsonrpc/test_is_request.cc index 945ec04..3b05df8 100644 --- a/test/webfuse_provider/jsonrpc/test_is_request.cc +++ b/test/webfuse_provider/jsonrpc/test_is_request.cc @@ -1,28 +1,22 @@ -#include #include "webfuse_provider/impl/jsonrpc/request.h" +#include "webfuse_provider/test_util/json_doc.hpp" + +#include + +using webfuse_test::JsonDoc; TEST(wfp_jsonrpc_is_request, request_with_object_params) { - json_t * request = json_object(); - json_object_set_new(request, "method", json_string("method")); - json_object_set_new(request, "params", json_object()); - json_object_set_new(request, "id", json_integer(42)); - - ASSERT_TRUE(wfp_jsonrpc_is_request(request)); + JsonDoc doc("{\"method\": \"method\", \"params\": {}, \"id\": 42}"); - json_decref(request); + ASSERT_TRUE(wfp_jsonrpc_is_request(doc.root())); } TEST(wfp_jsonrpc_is_request, request_with_array_params) { - json_t * request = json_object(); - json_object_set_new(request, "method", json_string("method")); - json_object_set_new(request, "params", json_array()); - json_object_set_new(request, "id", json_integer(42)); + JsonDoc doc("{\"method\": \"method\", \"params\": [], \"id\": 42}"); - ASSERT_TRUE(wfp_jsonrpc_is_request(request)); - - json_decref(request); + ASSERT_TRUE(wfp_jsonrpc_is_request(doc.root())); } TEST(wfp_jsonrpc_is_request, null_request) @@ -32,81 +26,49 @@ TEST(wfp_jsonrpc_is_request, null_request) TEST(wfp_jsonrpc_is_request, invalid_request) { - json_t * request = json_array(); - json_array_append_new(request, json_string("method")); - json_array_append_new(request, json_object()); - json_array_append_new(request, json_integer(42)); - - ASSERT_FALSE(wfp_jsonrpc_is_request(request)); - - json_decref(request); + JsonDoc doc("[\"method\", { }, 42]"); + + ASSERT_FALSE(wfp_jsonrpc_is_request(doc.root())); } TEST(wfp_jsonrpc_is_request, invalid_request_without_id) { - json_t * request = json_object(); - json_object_set_new(request, "method", json_string("method")); - json_object_set_new(request, "params", json_object()); - - ASSERT_FALSE(wfp_jsonrpc_is_request(request)); - - json_decref(request); + JsonDoc doc("{\"method\": \"method\", \"params\": { }}"); + + ASSERT_FALSE(wfp_jsonrpc_is_request(doc.root())); } TEST(wfp_jsonrpc_is_request, invalid_request_due_to_invalid_id) { - json_t * request = json_object(); - json_object_set_new(request, "method", json_string("method")); - json_object_set_new(request, "params", json_object()); - json_object_set_new(request, "id", json_string("42")); - - ASSERT_FALSE(wfp_jsonrpc_is_request(request)); - - json_decref(request); + JsonDoc doc("{\"method\": \"method\", \"params\": { }, \"id\": \"42\"}"); + + ASSERT_FALSE(wfp_jsonrpc_is_request(doc.root())); } TEST(wfp_jsonrpc_is_request, invalid_request_without_method) { - json_t * request = json_object(); - json_object_set_new(request, "params", json_object()); - json_object_set_new(request, "id", json_integer(42)); - - ASSERT_FALSE(wfp_jsonrpc_is_request(request)); - - json_decref(request); + JsonDoc doc("{\"params\": { }, \"id\": 42}"); + + ASSERT_FALSE(wfp_jsonrpc_is_request(doc.root())); } TEST(wfp_jsonrpc_is_request, invalid_request_due_to_invalid_method) { - json_t * request = json_object(); - json_object_set_new(request, "method", json_integer(42)); - json_object_set_new(request, "params", json_object()); - json_object_set_new(request, "id", json_integer(42)); - - ASSERT_FALSE(wfp_jsonrpc_is_request(request)); - - json_decref(request); + JsonDoc doc("{\"method\": 42, \"params\": {}, \"id\": 42}"); + + ASSERT_FALSE(wfp_jsonrpc_is_request(doc.root())); } TEST(wfp_jsonrpc_is_request, invalid_request_without_params) { - json_t * request = json_object(); - json_object_set_new(request, "method", json_string("method")); - json_object_set_new(request, "id", json_integer(42)); - - ASSERT_FALSE(wfp_jsonrpc_is_request(request)); - - json_decref(request); + JsonDoc doc("{\"method\": \"method\", \"id\": 42}"); + + ASSERT_FALSE(wfp_jsonrpc_is_request(doc.root())); } TEST(wfp_jsonrpc_is_request, invalid_request_due_to_invalid_params) { - json_t * request = json_object(); - json_object_set_new(request, "methdo", json_string("method")); - json_object_set_new(request, "params", json_string("params")); - json_object_set_new(request, "id", json_integer(42)); - - ASSERT_FALSE(wfp_jsonrpc_is_request(request)); - - json_decref(request); + JsonDoc doc("{\"method\": \"method\", \"params\": \"params\", \"id\": 42}"); + + ASSERT_FALSE(wfp_jsonrpc_is_request(doc.root())); } diff --git a/test/webfuse_provider/jsonrpc/test_is_response.cc b/test/webfuse_provider/jsonrpc/test_is_response.cc index 856f350..4165dde 100644 --- a/test/webfuse_provider/jsonrpc/test_is_response.cc +++ b/test/webfuse_provider/jsonrpc/test_is_response.cc @@ -1,37 +1,28 @@ #include #include "webfuse_provider/impl/jsonrpc/response.h" +#include "webfuse_provider/test_util/json_doc.hpp" + +using webfuse_test::JsonDoc; TEST(wfp_jsonrpc_is_response, valid_result) { - json_t * message = json_object(); - json_object_set_new(message, "result", json_object()); - json_object_set_new(message, "id", json_integer(42)); - - ASSERT_TRUE(wfp_jsonrpc_is_response(message)); + JsonDoc doc("{\"result\": {}, \"id\": 42}"); - json_decref(message); + ASSERT_TRUE(wfp_jsonrpc_is_response(doc.root())); } TEST(wfp_jsonrpc_is_response, valid_result_string) { - json_t * message = json_object(); - json_object_set_new(message, "result", json_string("also valid")); - json_object_set_new(message, "id", json_integer(42)); - - ASSERT_TRUE(wfp_jsonrpc_is_response(message)); + JsonDoc doc("{\"result\": \"also valid\", \"id\": 42}"); - json_decref(message); + ASSERT_TRUE(wfp_jsonrpc_is_response(doc.root())); } TEST(wfp_jsonrpc_is_response, valid_error) { - json_t * message = json_object(); - json_object_set_new(message, "error", json_object()); - json_object_set_new(message, "id", json_integer(42)); + JsonDoc doc("{\"error\": { }, \"id\": 42}"); - ASSERT_TRUE(wfp_jsonrpc_is_response(message)); - - json_decref(message); + ASSERT_TRUE(wfp_jsonrpc_is_response(doc.root())); } TEST(wfp_jsonrpc_is_response, invalid_null) @@ -41,54 +32,36 @@ TEST(wfp_jsonrpc_is_response, invalid_null) TEST(wfp_jsonrpc_is_response, invalid_message) { - json_t * message = json_array(); - json_array_append_new(message, json_object()); - json_array_append_new(message, json_integer(42)); - - ASSERT_FALSE(wfp_jsonrpc_is_response(message)); + JsonDoc doc("[{ }, 42]"); - json_decref(message); + ASSERT_FALSE(wfp_jsonrpc_is_response(doc.root())); } TEST(wfp_jsonrpc_is_response, invalid_missing_id) { - json_t * message = json_object(); - json_object_set_new(message, "result", json_object()); + JsonDoc doc("{\"result\": { } }"); - ASSERT_FALSE(wfp_jsonrpc_is_response(message)); - - json_decref(message); + ASSERT_FALSE(wfp_jsonrpc_is_response(doc.root())); } TEST(wfp_jsonrpc_is_response, invalid_id_wrong_type) { - json_t * message = json_object(); - json_object_set_new(message, "result", json_object()); - json_object_set_new(message, "id", json_string("42")); - - ASSERT_FALSE(wfp_jsonrpc_is_response(message)); + JsonDoc doc("{\"result\": { }, \"id\": \"42\"}"); - json_decref(message); + ASSERT_FALSE(wfp_jsonrpc_is_response(doc.root())); } TEST(wfp_jsonrpc_is_response, invalid_missing_result_and_error) { - json_t * message = json_object(); - json_object_set_new(message, "id", json_integer(42)); + JsonDoc doc("{\"id\": \"42\"}"); - ASSERT_FALSE(wfp_jsonrpc_is_response(message)); - - json_decref(message); + ASSERT_FALSE(wfp_jsonrpc_is_response(doc.root())); } TEST(wfp_jsonrpc_is_response, invalid_error_wrong_type) { - json_t * message = json_object(); - json_object_set_new(message, "error", json_array()); - json_object_set_new(message, "id", json_integer(42)); - - ASSERT_FALSE(wfp_jsonrpc_is_response(message)); + JsonDoc doc("{\"error\": [], \"id\": \"42\"}"); - json_decref(message); + ASSERT_FALSE(wfp_jsonrpc_is_response(doc.root())); } diff --git a/test/webfuse_provider/jsonrpc/test_proxy.cc b/test/webfuse_provider/jsonrpc/test_proxy.cc index 3ecbb8e..575fdf1 100644 --- a/test/webfuse_provider/jsonrpc/test_proxy.cc +++ b/test/webfuse_provider/jsonrpc/test_proxy.cc @@ -1,15 +1,20 @@ #include #include "webfuse_provider/impl/jsonrpc/proxy.h" +#include "webfuse_provider/impl/jsonrpc/error.h" #include "webfuse_provider/status.h" #include "webfuse_provider/impl/timer/manager.h" #include "webfuse_provider/jsonrpc/mock_timer.hpp" +#include "webfuse_provider/test_util/json_doc.hpp" + +#include #include #include using namespace std::chrono_literals; using wfp_jsonrpc_test::MockTimer; +using webfuse_test::JsonDoc; using testing::Return; using testing::_; using testing::DoAll; @@ -19,51 +24,39 @@ using testing::SaveArg; namespace { - int jsonrpc_get_status(json_t * error) - { - json_t * code = json_object_get(error, "code"); - return (json_is_integer(code)) ? json_integer_value(code) : WFP_BAD_FORMAT; - } - struct SendContext { - json_t * response; - bool result; + std::string response; bool is_called; - explicit SendContext(bool result_ = true) - : response(nullptr) - , result(result_) - , is_called(false) + explicit SendContext() + : is_called(false) { } ~SendContext() { - if (nullptr != response) - { - json_decref(response); - } } }; - bool jsonrpc_send( - json_t * request, + void jsonrpc_send( + char * request, + size_t length, void * user_data) { SendContext * context = reinterpret_cast(user_data); context->is_called = true; context->response = request; - json_incref(request); - return context->result; + char * raw_data = request - LWS_PRE; + free(raw_data); } struct FinishedContext { bool is_called; - json_t * result; - json_t * error; + wfp_json const * result; + wfp_jsonrpc_error * error; FinishedContext() : is_called(false) @@ -75,27 +68,25 @@ namespace ~FinishedContext() { - if (nullptr != result) - { - json_decref(result); - } - if (nullptr != error) { - json_decref(error); + wfp_jsonrpc_error_dispose(error); } } }; void jsonrpc_finished( void * user_data, - json_t const * result, - json_t const * error) + wfp_json const * result, + wfp_jsonrpc_error const * error) { FinishedContext * context = reinterpret_cast(user_data); context->is_called = true; - context->result = json_deep_copy(result); - context->error = json_deep_copy(error); + context->result = result; + if (nullptr != error) + { + context->error = wfp_jsonrpc_error_create(error->code, error->message); + } } } @@ -126,22 +117,7 @@ TEST(wfp_jsonrpc_proxy, invoke) wfp_jsonrpc_proxy_invoke(proxy, &jsonrpc_finished, finished_data, "foo", "si", "bar", 42); ASSERT_TRUE(send_context.is_called); - ASSERT_TRUE(json_is_object(send_context.response)); - - json_t * method = json_object_get(send_context.response, "method"); - ASSERT_TRUE(json_is_string(method)); - ASSERT_STREQ("foo", json_string_value(method)); - - json_t * params = json_object_get(send_context.response, "params"); - ASSERT_TRUE(json_is_array(params)); - ASSERT_EQ(2, json_array_size(params)); - ASSERT_TRUE(json_is_string(json_array_get(params, 0))); - ASSERT_STREQ("bar", json_string_value(json_array_get(params, 0))); - ASSERT_TRUE(json_is_integer(json_array_get(params, 1))); - ASSERT_EQ(42, json_integer_value(json_array_get(params, 1))); - - json_t * id = json_object_get(send_context.response, "id"); - ASSERT_TRUE(json_is_integer(id)); + ASSERT_STREQ("{\"method\":\"foo\",\"params\":[\"bar\",42],\"id\":42}", send_context.response.c_str()); ASSERT_FALSE(finished_context.is_called); @@ -152,28 +128,6 @@ TEST(wfp_jsonrpc_proxy, invoke) ASSERT_FALSE(nullptr == finished_context.error); } -TEST(wfp_jsonrpc_proxy, invoke_calls_finish_if_send_fails) -{ - struct wfp_timer_manager * timer_manager = wfp_timer_manager_create(); - - SendContext send_context(false); - void * send_data = reinterpret_cast(&send_context); - struct wfp_jsonrpc_proxy * proxy = wfp_jsonrpc_proxy_create(timer_manager, WFP_DEFAULT_TIMEOUT, &jsonrpc_send, send_data); - - FinishedContext finished_context; - void * finished_data = reinterpret_cast(&finished_context); - wfp_jsonrpc_proxy_invoke(proxy, &jsonrpc_finished, finished_data, "foo", "si", "bar", 42); - - ASSERT_TRUE(send_context.is_called); - ASSERT_TRUE(json_is_object(send_context.response)); - - ASSERT_TRUE(finished_context.is_called); - ASSERT_FALSE(nullptr == finished_context.error); - - wfp_jsonrpc_proxy_dispose(proxy); - wfp_timer_manager_dispose(timer_manager); -} - TEST(wfp_jsonrpc_proxy, invoke_fails_if_another_request_is_pending) { struct wfp_timer_manager * timer_manager = wfp_timer_manager_create(); @@ -191,18 +145,17 @@ TEST(wfp_jsonrpc_proxy, invoke_fails_if_another_request_is_pending) wfp_jsonrpc_proxy_invoke(proxy, &jsonrpc_finished, finished_data2, "foo", ""); ASSERT_TRUE(send_context.is_called); - ASSERT_TRUE(json_is_object(send_context.response)); ASSERT_FALSE(finished_context.is_called); ASSERT_TRUE(finished_context2.is_called); - ASSERT_EQ(WFP_BAD_BUSY, jsonrpc_get_status(finished_context2.error)); + ASSERT_EQ(WFP_BAD_BUSY, finished_context2.error->code); wfp_jsonrpc_proxy_dispose(proxy); wfp_timer_manager_dispose(timer_manager); } -TEST(wfp_jsonrpc_proxy, invoke_fails_if_request_is_invalid) +TEST(wfp_jsonrpc_proxy, invoke_invalid_request) { struct wfp_timer_manager * timer_manager = wfp_timer_manager_create(); @@ -214,10 +167,9 @@ TEST(wfp_jsonrpc_proxy, invoke_fails_if_request_is_invalid) void * finished_data = reinterpret_cast(&finished_context); wfp_jsonrpc_proxy_invoke(proxy, &jsonrpc_finished, finished_data, "foo", "?", "error"); - ASSERT_FALSE(send_context.is_called); + ASSERT_TRUE(send_context.is_called); - ASSERT_TRUE(finished_context.is_called); - ASSERT_EQ(WFP_BAD, jsonrpc_get_status(finished_context.error)); + ASSERT_FALSE(finished_context.is_called); wfp_jsonrpc_proxy_dispose(proxy); wfp_timer_manager_dispose(timer_manager); @@ -236,22 +188,13 @@ TEST(wfp_jsonrpc_proxy, on_result) wfp_jsonrpc_proxy_invoke(proxy, &jsonrpc_finished, finished_data, "foo", "si", "bar", 42); ASSERT_TRUE(send_context.is_called); - ASSERT_TRUE(json_is_object(send_context.response)); - - json_t * id = json_object_get(send_context.response, "id"); - ASSERT_TRUE(json_is_number(id)); - json_t * response = json_object(); - json_object_set_new(response, "result", json_string("okay")); - json_object_set(response, "id", id); - - wfp_jsonrpc_proxy_onresult(proxy, response); - json_decref(response); + JsonDoc doc("{\"result\": \"okay\", \"id\": 42}"); + wfp_jsonrpc_proxy_onresult(proxy, doc.root()); ASSERT_TRUE(finished_context.is_called); ASSERT_EQ(nullptr, finished_context.error); - ASSERT_TRUE(json_is_string(finished_context.result)); - ASSERT_STREQ("okay", json_string_value(finished_context.result)); + ASSERT_NE(nullptr, finished_context.result); wfp_jsonrpc_proxy_dispose(proxy); wfp_timer_manager_dispose(timer_manager); @@ -270,17 +213,9 @@ TEST(wfp_jsonrpc_proxy, on_result_reject_response_with_unknown_id) wfp_jsonrpc_proxy_invoke(proxy, &jsonrpc_finished, finished_data, "foo", "si", "bar", 42); ASSERT_TRUE(send_context.is_called); - ASSERT_TRUE(json_is_object(send_context.response)); - - json_t * id = json_object_get(send_context.response, "id"); - ASSERT_TRUE(json_is_number(id)); - - json_t * response = json_object(); - json_object_set_new(response, "result", json_string("okay")); - json_object_set_new(response, "id", json_integer(1 + json_integer_value(id))); - wfp_jsonrpc_proxy_onresult(proxy, response); - json_decref(response); + JsonDoc doc("{\"result\": \"okay\", \"id\": 1234}"); + wfp_jsonrpc_proxy_onresult(proxy, doc.root()); ASSERT_FALSE(finished_context.is_called); @@ -301,13 +236,12 @@ TEST(wfp_jsonrpc_proxy, timeout) wfp_jsonrpc_proxy_invoke(proxy, &jsonrpc_finished, finished_data, "foo", "si", "bar", 42); ASSERT_TRUE(send_context.is_called); - ASSERT_TRUE(json_is_object(send_context.response)); std::this_thread::sleep_for(10ms); wfp_timer_manager_check(timer_manager); ASSERT_TRUE(finished_context.is_called); - ASSERT_EQ(WFP_BAD_TIMEOUT, jsonrpc_get_status(finished_context.error)); + ASSERT_EQ(WFP_BAD_TIMEOUT, finished_context.error->code); wfp_jsonrpc_proxy_dispose(proxy); wfp_timer_manager_dispose(timer_manager); @@ -326,7 +260,6 @@ TEST(wfp_jsonrpc_proxy, cleanup_pending_request) wfp_jsonrpc_proxy_invoke(proxy, &jsonrpc_finished, finished_data, "foo", "si", "bar", 42); ASSERT_TRUE(send_context.is_called); - ASSERT_TRUE(json_is_object(send_context.response)); ASSERT_FALSE(finished_context.is_called); @@ -350,28 +283,13 @@ TEST(wfp_jsonrpc_proxy, notify) wfp_jsonrpc_proxy_notify(proxy, "foo", "si", "bar", 42); ASSERT_TRUE(send_context.is_called); - ASSERT_TRUE(json_is_object(send_context.response)); - - json_t * method = json_object_get(send_context.response, "method"); - ASSERT_TRUE(json_is_string(method)); - ASSERT_STREQ("foo", json_string_value(method)); - - json_t * params = json_object_get(send_context.response, "params"); - ASSERT_TRUE(json_is_array(params)); - ASSERT_EQ(2, json_array_size(params)); - ASSERT_TRUE(json_is_string(json_array_get(params, 0))); - ASSERT_STREQ("bar", json_string_value(json_array_get(params, 0))); - ASSERT_TRUE(json_is_integer(json_array_get(params, 1))); - ASSERT_EQ(42, json_integer_value(json_array_get(params, 1))); - - json_t * id = json_object_get(send_context.response, "id"); - ASSERT_EQ(nullptr, id); + ASSERT_STREQ("{\"method\":\"foo\",\"params\":[\"bar\",42]}", send_context.response.c_str()); wfp_jsonrpc_proxy_dispose(proxy); wfp_timer_manager_dispose(timer_manager); } -TEST(wfp_jsonrpc_proxy, notify_dont_send_invalid_request) +TEST(wfp_jsonrpc_proxy, notify_send_invalid_request) { struct wfp_timer_manager * timer_manager = wfp_timer_manager_create(); @@ -381,7 +299,7 @@ TEST(wfp_jsonrpc_proxy, notify_dont_send_invalid_request) wfp_jsonrpc_proxy_notify(proxy, "foo", "?"); - ASSERT_FALSE(send_context.is_called); + ASSERT_TRUE(send_context.is_called); wfp_jsonrpc_proxy_dispose(proxy); wfp_timer_manager_dispose(timer_manager); @@ -417,12 +335,8 @@ TEST(wfp_jsonrpc_proxy, on_result_swallow_if_no_request_pending) void * send_data = reinterpret_cast(&send_context); struct wfp_jsonrpc_proxy * proxy = wfp_jsonrpc_proxy_create(timer_manager, WFP_DEFAULT_TIMEOUT, &jsonrpc_send, send_data); - json_t * response = json_object(); - json_object_set_new(response, "result", json_string("okay")); - json_object_set_new(response, "id", json_integer(42)); - - wfp_jsonrpc_proxy_onresult(proxy, response); - json_decref(response); + JsonDoc doc("{\"result\": \"okay\", \"id\": 42}"); + wfp_jsonrpc_proxy_onresult(proxy, doc.root()); wfp_jsonrpc_proxy_dispose(proxy); wfp_timer_manager_dispose(timer_manager); diff --git a/test/webfuse_provider/jsonrpc/test_request.cc b/test/webfuse_provider/jsonrpc/test_request.cc index 5e8a66d..9c90340 100644 --- a/test/webfuse_provider/jsonrpc/test_request.cc +++ b/test/webfuse_provider/jsonrpc/test_request.cc @@ -1,138 +1,26 @@ -#include #include "webfuse_provider/impl/jsonrpc/request.h" -#include "webfuse_provider/status.h" - -namespace -{ - -struct Context -{ - json_t * response; -}; - -bool jsonrpc_send( - json_t * request, - void * user_data) -{ - Context * context = reinterpret_cast(user_data); - context->response = request; - json_incref(request); - - return true; -} - -} - -TEST(wfp_jsonrpc_request, create_dispose) -{ - Context context{nullptr}; - void * user_data = reinterpret_cast(&context); - - struct wfp_jsonrpc_request * request = - wfp_jsonrpc_request_create(42, &jsonrpc_send, user_data); - - ASSERT_NE(nullptr, request); - ASSERT_EQ(user_data, wfp_jsonrpc_request_get_userdata(request)); - - wfp_jsonrpc_request_dispose(request); -} - -TEST(wfp_jsonrpc_request, respond) -{ - Context context{nullptr}; - void * user_data = reinterpret_cast(&context); - - struct wfp_jsonrpc_request * request = - wfp_jsonrpc_request_create(42, &jsonrpc_send, user_data); - - wfp_jsonrpc_respond(request, json_string("okay")); - - ASSERT_NE(nullptr, context.response); - - - json_t * response = reinterpret_cast(context.response); - ASSERT_TRUE(json_is_object(response)); - - json_t * id = json_object_get(response, "id"); - ASSERT_TRUE(json_is_integer(id)); - ASSERT_EQ(42, json_integer_value(id)); - - json_t * result = json_object_get(response, "result"); - ASSERT_TRUE(json_is_string(result)); - ASSERT_STREQ("okay", json_string_value(result)); - - ASSERT_EQ(nullptr, json_object_get(response, "error")); - - json_decref(response); -} - -TEST(wfp_jsonrpc_request, respond_error) -{ - Context context{nullptr}; - void * user_data = reinterpret_cast(&context); - - struct wfp_jsonrpc_request * request = - wfp_jsonrpc_request_create(42, &jsonrpc_send, user_data); - - wfp_jsonrpc_respond_error(request, WFP_BAD, "Bad"); - - ASSERT_NE(nullptr, context.response); - - - json_t * response = reinterpret_cast(context.response); - ASSERT_TRUE(json_is_object(response)); - - json_t * id = json_object_get(response, "id"); - ASSERT_TRUE(json_is_integer(id)); - ASSERT_EQ(42, json_integer_value(id)); - - ASSERT_EQ(nullptr, json_object_get(response, "result")); - - json_t * err = json_object_get(response, "error"); - ASSERT_TRUE(json_is_object(err)); - - json_t * err_code = json_object_get(err, "code"); - ASSERT_TRUE(json_is_integer(err_code)); - ASSERT_EQ(WFP_BAD, json_integer_value(err_code)); - - json_t * err_message = json_object_get(err, "message"); - ASSERT_TRUE(json_is_string(err_message)); - ASSERT_STREQ("Bad", json_string_value(err_message)); +#include "webfuse_provider/test_util/json_doc.hpp" +#include - json_decref(response); -} +using webfuse_test::JsonDoc; TEST(wfp_jsonrpc_request, is_request_object_params) { - json_t * request = json_object(); - json_object_set_new(request, "method", json_string("some_method")); - json_object_set_new(request, "params", json_object()); - json_object_set_new(request, "id", json_integer(42)); - - ASSERT_TRUE(wfp_jsonrpc_is_request(request)); + JsonDoc doc("{\"method\": \"some_method\", \"params\": { }, \"id\": 42}"); - json_decref(request); + ASSERT_TRUE(wfp_jsonrpc_is_request(doc.root())); } TEST(wfp_jsonrpc_request, is_request_fail_missing_params) { - json_t * request = json_object(); - json_object_set_new(request, "method", json_string("some_method")); - json_object_set_new(request, "id", json_integer(42)); + JsonDoc doc("{\"method\": \"some_method\", \"id\": 42}"); - ASSERT_FALSE(wfp_jsonrpc_is_request(request)); - - json_decref(request); + ASSERT_FALSE(wfp_jsonrpc_is_request(doc.root())); } TEST(wfp_jsonrpc_request, is_request_fail_params_wrong_type) { - json_t * request = json_object(); - json_object_set_new(request, "method", json_string("some_method")); - json_object_set_new(request, "params", json_string("invalid_params")); - json_object_set_new(request, "id", json_integer(42)); - - ASSERT_FALSE(wfp_jsonrpc_is_request(request)); + JsonDoc doc("{\"method\": \"some_method\", \"params\": \"invalid_params\", \"id\": 42}"); - json_decref(request); + ASSERT_FALSE(wfp_jsonrpc_is_request(doc.root())); } diff --git a/test/webfuse_provider/jsonrpc/test_response.cc b/test/webfuse_provider/jsonrpc/test_response.cc index 9ab7c31..1f43de1 100644 --- a/test/webfuse_provider/jsonrpc/test_response.cc +++ b/test/webfuse_provider/jsonrpc/test_response.cc @@ -1,147 +1,122 @@ #include #include "webfuse_provider/impl/jsonrpc/response_intern.h" #include "webfuse_provider/status.h" +#include "webfuse_provider/test_util/json_doc.hpp" +#include "webfuse_provider/impl/json/node.h" +#include "webfuse_provider/impl/jsonrpc/error.h" + +using webfuse_test::JsonDoc; TEST(wfp_json_response, init_result) { - json_t * message = json_object(); - json_object_set_new(message, "result", json_integer(47)); - json_object_set_new(message, "id", json_integer(11)); + JsonDoc doc("{\"result\": 47, \"id\": 11}"); struct wfp_jsonrpc_response response; - wfp_jsonrpc_response_init(&response, message); + wfp_jsonrpc_response_init(&response,doc.root()); ASSERT_EQ(nullptr, response.error); - ASSERT_TRUE(json_is_integer(response.result)); - ASSERT_EQ(47, json_integer_value(response.result)); + ASSERT_TRUE(wfp_impl_json_is_int(response.result)); + ASSERT_EQ(47, wfp_impl_json_int_get(response.result)); ASSERT_EQ(11, response.id); wfp_jsonrpc_response_cleanup(&response); - json_decref(message); } TEST(wfp_json_response, init_error) { - json_t * message = json_object(); - json_t * err = json_object(); - json_object_set_new(err, "code", json_integer(42)); - json_object_set_new(err, "message", json_string("Don't Panic!")); - json_object_set_new(message, "error", err); - json_object_set_new(message, "id", json_integer(23)); + JsonDoc doc("{\"error\": {\"code\": 42, \"message\": \"Don't Panic!\"}, \"id\": 23}"); struct wfp_jsonrpc_response response; - wfp_jsonrpc_response_init(&response, message); + wfp_jsonrpc_response_init(&response, doc.root()); - ASSERT_EQ(42, json_integer_value(json_object_get(response.error, "code"))); - ASSERT_STREQ("Don't Panic!", json_string_value(json_object_get(response.error, "message"))); + ASSERT_EQ(42, response.error->code); + ASSERT_STREQ("Don't Panic!", response.error->message); ASSERT_EQ(nullptr, response.result); ASSERT_EQ(23, response.id); wfp_jsonrpc_response_cleanup(&response); - json_decref(message); } TEST(wfp_json_response, init_fail_missing_result_and_error) { - json_t * message = json_object(); - json_object_set_new(message, "id", json_integer(12)); + JsonDoc doc("{\"id\": 12}"); struct wfp_jsonrpc_response response; - wfp_jsonrpc_response_init(&response, message); + wfp_jsonrpc_response_init(&response, doc.root()); - ASSERT_EQ(WFP_BAD_FORMAT, json_integer_value(json_object_get(response.error, "code"))); + ASSERT_EQ(WFP_BAD_FORMAT, response.error->code); ASSERT_EQ(nullptr, response.result); ASSERT_EQ(12, response.id); wfp_jsonrpc_response_cleanup(&response); - json_decref(message); } TEST(wfp_json_response, init_fail_missing_id) { - json_t * message = json_object(); - json_object_set_new(message, "result", json_integer(47)); + JsonDoc doc("{\"result\": 47}"); struct wfp_jsonrpc_response response; - wfp_jsonrpc_response_init(&response, message); + wfp_jsonrpc_response_init(&response, doc.root()); - ASSERT_EQ(WFP_BAD_FORMAT, json_integer_value(json_object_get(response.error, "code"))); + ASSERT_EQ(WFP_BAD_FORMAT, response.error->code); ASSERT_EQ(nullptr, response.result); ASSERT_EQ(-1, response.id); wfp_jsonrpc_response_cleanup(&response); - json_decref(message); } TEST(wfp_json_response, init_fail_wrong_id_type) { - json_t * message = json_object(); - json_object_set_new(message, "result", json_integer(47)); - json_object_set_new(message, "id", json_string("42")); + JsonDoc doc("{\"result\": 47, \"id\": \"42\"}"); struct wfp_jsonrpc_response response; - wfp_jsonrpc_response_init(&response, message); + wfp_jsonrpc_response_init(&response, doc.root()); - ASSERT_EQ(WFP_BAD_FORMAT, json_integer_value(json_object_get(response.error, "code"))); + ASSERT_EQ(WFP_BAD_FORMAT, response.error->code); ASSERT_EQ(nullptr, response.result); ASSERT_EQ(-1, response.id); wfp_jsonrpc_response_cleanup(&response); - json_decref(message); } TEST(wfp_json_response, init_fail_error_missing_code) { - json_t * message = json_object(); - json_t * err = json_object(); - json_object_set_new(err, "message", json_string("Don't Panic!")); - json_object_set_new(message, "error", err); - json_object_set_new(message, "id", json_integer(23)); + JsonDoc doc("{\"error\": {\"message\": \"Don't Panic!\"}, \"id\": 23}"); struct wfp_jsonrpc_response response; - wfp_jsonrpc_response_init(&response, message); + wfp_jsonrpc_response_init(&response, doc.root()); - ASSERT_EQ(WFP_BAD_FORMAT, json_integer_value(json_object_get(response.error, "code"))); + ASSERT_EQ(WFP_BAD_FORMAT,response.error->code); ASSERT_EQ(nullptr, response.result); ASSERT_EQ(23, response.id); wfp_jsonrpc_response_cleanup(&response); - json_decref(message); } TEST(wfp_json_response, init_fail_error_wrong_code_type) { - json_t * message = json_object(); - json_t * err = json_object(); - json_object_set_new(err, "code", json_string("42")); - json_object_set_new(err, "message", json_string("Don't Panic!")); - json_object_set_new(message, "error", err); - json_object_set_new(message, "id", json_integer(23)); + JsonDoc doc("{\"error\": {\"code\": \"42\", \"message\": \"Don't Panic!\"}, \"id\": 23}"); struct wfp_jsonrpc_response response; - wfp_jsonrpc_response_init(&response, message); + wfp_jsonrpc_response_init(&response, doc.root()); - ASSERT_EQ(WFP_BAD_FORMAT, json_integer_value(json_object_get(response.error, "code"))); + ASSERT_EQ(WFP_BAD_FORMAT, response.error->code); ASSERT_EQ(nullptr, response.result); ASSERT_EQ(23, response.id); wfp_jsonrpc_response_cleanup(&response); - json_decref(message); } TEST(wfp_json_response, init_fail_error_wrong_type) { - json_t * message = json_object(); - json_object_set_new(message, "error", json_string("invalid error type")); - json_object_set_new(message, "id", json_integer(23)); + JsonDoc doc("{\"error\": \"invalid error type\", \"id\": 23}"); struct wfp_jsonrpc_response response; - wfp_jsonrpc_response_init(&response, message); + wfp_jsonrpc_response_init(&response, doc.root()); - ASSERT_EQ(WFP_BAD_FORMAT, json_integer_value(json_object_get(response.error, "code"))); + ASSERT_EQ(WFP_BAD_FORMAT, response.error->code); ASSERT_EQ(nullptr, response.result); ASSERT_EQ(23, response.id); wfp_jsonrpc_response_cleanup(&response); - json_decref(message); } diff --git a/test/webfuse_provider/jsonrpc/test_response_parser.cc b/test/webfuse_provider/jsonrpc/test_response_parser.cc index 69a2e43..b93417b 100644 --- a/test/webfuse_provider/jsonrpc/test_response_parser.cc +++ b/test/webfuse_provider/jsonrpc/test_response_parser.cc @@ -1,58 +1,73 @@ -#include -#include - #include "webfuse_provider/impl/jsonrpc/response_intern.h" +#include "webfuse_provider/impl/jsonrpc/error.h" +#include "webfuse_provider/test_util/json_doc.hpp" +#include -static void response_parse_str( - std::string const & buffer, - struct wfp_jsonrpc_response * response) -{ - json_t * message = json_loadb(buffer.c_str(), buffer.size(), 0, nullptr); - if (nullptr != message) - { - wfp_jsonrpc_response_init(response, message); - json_decref(message); - } -} +using webfuse_test::JsonDoc; -TEST(response_parser, test) +TEST(response_parser, fail_no_object) { + JsonDoc doc("[]"); struct wfp_jsonrpc_response response; + wfp_jsonrpc_response_init(&response, doc.root()); - // no object - response_parse_str("[]", &response); ASSERT_NE(nullptr, response.error); ASSERT_EQ(-1, response.id); ASSERT_EQ(nullptr, response.result); + wfp_jsonrpc_response_cleanup(&response); +} + +TEST(response_error, fail_empty_object) +{ + JsonDoc doc("{}"); + struct wfp_jsonrpc_response response; + wfp_jsonrpc_response_init(&response, doc.root()); - // empty - response_parse_str("{}", &response); ASSERT_NE(nullptr, response.error); ASSERT_EQ(-1, response.id); ASSERT_EQ(nullptr, response.result); + wfp_jsonrpc_response_cleanup(&response); +} + +TEST(response_error, fail_no_data) +{ + JsonDoc doc("{\"id\":42}"); + struct wfp_jsonrpc_response response; + wfp_jsonrpc_response_init(&response, doc.root()); - // no data - response_parse_str("{\"id\":42}", &response); ASSERT_NE(nullptr, response.error); ASSERT_EQ(42, response.id); ASSERT_EQ(nullptr, response.result); + wfp_jsonrpc_response_cleanup(&response); +} + +TEST(response_error, fail_with_custom_error_code) +{ + JsonDoc doc("{\"error\":{\"code\": 42}, \"id\": 42}"); + struct wfp_jsonrpc_response response; + wfp_jsonrpc_response_init(&response, doc.root()); - // custom error code - response_parse_str("{\"error\":{\"code\": 42}, \"id\": 42}", &response); ASSERT_NE(nullptr, response.error); - ASSERT_EQ(42, json_integer_value(json_object_get(response.error, "code"))); + ASSERT_EQ(42, response.error->code); ASSERT_EQ(42, response.id); ASSERT_EQ(nullptr, response.result); + wfp_jsonrpc_response_cleanup(&response); +} + +TEST(response_parser, fail_invalid_response) +{ + JsonDoc doc("{\"result\": true, \"id\": 42}"); + struct wfp_jsonrpc_response response; + wfp_jsonrpc_response_init(&response, doc.root()); - // valid response - response_parse_str("{\"result\": true, \"id\": 42}", &response); ASSERT_EQ(nullptr, response.error); ASSERT_EQ(42, response.id); ASSERT_NE(nullptr, response.result); + wfp_jsonrpc_response_cleanup(&response); } diff --git a/test/webfuse_provider/mocks/mock_request.cc b/test/webfuse_provider/mocks/mock_request.cc index c1423d0..1337148 100644 --- a/test/webfuse_provider/mocks/mock_request.cc +++ b/test/webfuse_provider/mocks/mock_request.cc @@ -1,33 +1,61 @@ #include "webfuse_provider/mocks/mock_request.hpp" +#include "webfuse_provider/impl/json/doc.h" +#include "webfuse_provider/impl/message.h" +#include "webfuse_provider/impl/message_writer.h" +#include "webfuse_provider/status.h" #include extern "C" { static void webfuse_test_MockRequest_respond( - json_t * response, + struct wfp_message * response, void * user_data) { auto * request = reinterpret_cast(user_data); - - json_t * result = json_object_get(response, "result"); - json_t * error = json_object_get(response, "error"); - json_t * id_holder = json_object_get(response, "id"); - + int error_code = WFP_BAD; int id = -1; - if (json_is_integer(id_holder)) - { - id = json_integer_value(id_holder); - } - if (nullptr != result) + wfp_json_doc * doc = wfp_impl_json_doc_loadb(response->data, response->length); + if (NULL != doc) { - request->respond(result, id); + wfp_json const * response = wfp_impl_json_doc_root(doc); + wfp_json const * result = wfp_impl_json_object_get(response, "result"); + wfp_json const * id_holder = wfp_impl_json_object_get(response, "id"); + if (wfp_impl_json_is_int(id_holder)) + { + id = wfp_impl_json_int_get(id_holder); + } + + if (!wfp_impl_json_is_null(result)) + { + error_code = WFP_GOOD; + request->respond(result, id); + } + else + { + wfp_json const * error = wfp_impl_json_object_get(response, "error"); + if (wfp_impl_json_is_object(error)) + { + wfp_json const * error_code_holder = wfp_impl_json_object_get(response, "error"); + if (wfp_impl_json_is_int(error_code_holder)) + { + error_code = wfp_impl_json_int_get(error_code_holder); + } + } + + } + + wfp_impl_json_doc_dispose(doc); } - else + + + if (WFP_GOOD != error_code) { - request->respond_error(error, id); + request->respond_error(error_code, id); } + + wfp_message_dispose(response); } } @@ -41,6 +69,7 @@ struct wfp_request * MockRequest::create_request(int id) request->respond = &webfuse_test_MockRequest_respond; request->user_data = reinterpret_cast(this); request->id = id; + request->writer = wfp_impl_message_writer_create(id); return request; } diff --git a/test/webfuse_provider/mocks/mock_request.hpp b/test/webfuse_provider/mocks/mock_request.hpp index eb25d3e..a860038 100644 --- a/test/webfuse_provider/mocks/mock_request.hpp +++ b/test/webfuse_provider/mocks/mock_request.hpp @@ -1,10 +1,10 @@ #ifndef WFP_MOCK_REQUEST_HPP #define WFP_MOCK_REQUEST_HPP +#include "webfuse_provider/impl/request.h" +#include "webfuse_provider/impl/json/node.h" #include -#include #include -#include "webfuse_provider/impl/request.h" namespace webfuse_test @@ -14,28 +14,28 @@ class MockRequest { public: struct wfp_request * create_request(int id); - MOCK_METHOD2(respond, void(json_t * result, int id)); - MOCK_METHOD2(respond_error, void(json_t * error, int id)); + MOCK_METHOD2(respond, void(wfp_json const * result, int id)); + MOCK_METHOD2(respond_error, void(int error_code, int id)); }; MATCHER_P3(StatMatcher, inode, mode, file_type, "") { - json_t * inode_holder = json_object_get(arg, "inode"); - if ((!json_is_integer(inode_holder)) || (inode != json_integer_value(inode_holder))) + wfp_json const * inode_holder = wfp_impl_json_object_get(arg, "inode"); + if ((!wfp_impl_json_is_int(inode_holder)) || (inode != wfp_impl_json_int_get(inode_holder))) { *result_listener << "missing inode"; return false; } - json_t * mode_holder = json_object_get(arg, "mode"); - if ((!json_is_integer(mode_holder)) || (mode != json_integer_value(mode_holder))) + wfp_json const * mode_holder = wfp_impl_json_object_get(arg, "mode"); + if ((!wfp_impl_json_is_int(mode_holder)) || (mode != wfp_impl_json_int_get(mode_holder))) { *result_listener << "missing mode"; return false; } - json_t * type_holder = json_object_get(arg, "type"); - if ((!json_is_string(type_holder)) || (0 != strcmp(file_type, json_string_value(type_holder)))) + wfp_json const * type_holder = wfp_impl_json_object_get(arg, "type"); + if ((!wfp_impl_json_is_string(type_holder)) || (0 != strcmp(file_type, wfp_impl_json_string_get(type_holder)))) { *result_listener << "missing type"; return false; @@ -46,8 +46,8 @@ MATCHER_P3(StatMatcher, inode, mode, file_type, "") MATCHER_P(OpenMatcher, handle, "") { - json_t * handle_holder = json_object_get(arg, "handle"); - if ((!json_is_integer(handle_holder)) || (handle != json_integer_value(handle_holder))) + wfp_json const * handle_holder = wfp_impl_json_object_get(arg, "handle"); + if ((!wfp_impl_json_is_int(handle_holder)) || (handle != wfp_impl_json_int_get(handle_holder))) { *result_listener << "missing handle"; return false; @@ -58,24 +58,24 @@ MATCHER_P(OpenMatcher, handle, "") MATCHER_P3(ReadResultMatcher, data, format, count, "") { - json_t * format_holder = json_object_get(arg, "format"); - if ((!json_is_string(format_holder)) || (0 != strcmp(format, json_string_value(format_holder)))) + wfp_json const * format_holder = wfp_impl_json_object_get(arg, "format"); + if ((!wfp_impl_json_is_string(format_holder)) || (0 != strcmp(format, wfp_impl_json_string_get(format_holder)))) { - *result_listener << "invalid or missing format: " << json_string_value(format_holder); + *result_listener << "invalid or missing format: " << wfp_impl_json_string_get(format_holder); return false; } - json_t * count_holder = json_object_get(arg, "count"); - if ((!json_is_integer(count_holder)) || (count != json_integer_value(count_holder))) + wfp_json const * count_holder = wfp_impl_json_object_get(arg, "count"); + if ((!wfp_impl_json_is_int(count_holder)) || (count != wfp_impl_json_int_get(count_holder))) { - *result_listener << "invalid or missing count: " << json_integer_value(count_holder); + *result_listener << "invalid or missing count: " << wfp_impl_json_int_get(count_holder); return false; } - json_t * data_holder = json_object_get(arg, "data"); - if ((!json_is_string(data_holder)) || (0 != strcmp(data, json_string_value(data_holder)))) + wfp_json const * data_holder = wfp_impl_json_object_get(arg, "data"); + if ((!wfp_impl_json_is_string(data_holder)) || (0 != strcmp(data, wfp_impl_json_string_get(data_holder)))) { - *result_listener << "invalid or missing data: " << json_string_value(data_holder); + *result_listener << "invalid or missing data: " << wfp_impl_json_string_get(data_holder); return false; } @@ -84,28 +84,26 @@ MATCHER_P3(ReadResultMatcher, data, format, count, "") MATCHER_P(ReaddirMatcher, contained_elements , "") { - if (!json_is_array(arg)) + if (!wfp_impl_json_is_array(arg)) { *result_listener << "result is not array"; return false; } { - size_t i; - json_t * value; - - json_array_foreach(arg, i, value) + for(size_t i = 0; i < wfp_impl_json_array_size(arg); i++) { - json_t * inode = json_object_get(value, "inode"); - json_t * name = json_object_get(value, "name"); + wfp_json const * value = wfp_impl_json_array_get(arg, i); + wfp_json const * inode = wfp_impl_json_object_get(value, "inode"); + wfp_json const * name = wfp_impl_json_object_get(value, "name"); - if(!json_is_integer(inode)) + if(!wfp_impl_json_is_int(inode)) { *result_listener << "invalid result: missing inode"; return false; } - if (!json_is_string(name)) + if (!wfp_impl_json_is_string(name)) { *result_listener << "invalid result: missing name"; return false; @@ -117,14 +115,13 @@ MATCHER_P(ReaddirMatcher, contained_elements , "") { char const * element = contained_elements[i]; bool found = false; - size_t j; - json_t * value; - json_array_foreach(arg, j, value) + for(size_t j = 0; j < wfp_impl_json_array_size(arg); j++) { - json_t * name = json_object_get(value, "name"); + wfp_json const * value = wfp_impl_json_array_get(arg, j); + wfp_json const * name = wfp_impl_json_object_get(value, "name"); - found = (0 == strcmp(element, json_string_value(name))); + found = (0 == strcmp(element, wfp_impl_json_string_get(name))); if (found) { break; diff --git a/test/webfuse_provider/provider/operation/test_close.cc b/test/webfuse_provider/provider/operation/test_close.cc index 503bb80..609cea1 100644 --- a/test/webfuse_provider/provider/operation/test_close.cc +++ b/test/webfuse_provider/provider/operation/test_close.cc @@ -1,32 +1,25 @@ #include "webfuse_provider/impl/operation/close.h" #include "webfuse_provider/mocks/mock_provider.hpp" #include "webfuse_provider/mocks/fake_invokation_context.hpp" +#include "webfuse_provider/test_util/json_doc.hpp" #include using ::webfuse_test::MockProvider; using ::webfuse_test::create_context; +using ::webfuse_test::JsonDoc; using ::testing::_; TEST(wfp_close, close) { - int inode = 42; - int handle = 0xdeadbeef; - int flags = 23; - MockProvider provider; - EXPECT_CALL(provider, close(inode, handle, flags)).Times(1); + EXPECT_CALL(provider, close(42, 101, 23)).Times(1); wfp_impl_invokation_context context = create_context(provider); - json_t * params = json_array(); - json_array_append_new(params, json_string("test.filesystem")); - json_array_append_new(params, json_integer(inode)); - json_array_append_new(params, json_integer(handle)); - json_array_append_new(params, json_integer(flags)); + JsonDoc doc("[\"test.filesystem\", 42, 101, 23]"); - wfp_impl_close(&context, params, 42); - json_decref(params); + wfp_impl_close(&context, doc.root(), 42); } TEST(wfp_close, close_fail_invalid_param_count) @@ -36,9 +29,9 @@ TEST(wfp_close, close_fail_invalid_param_count) wfp_impl_invokation_context context = create_context(provider); - json_t * params = json_array(); - wfp_impl_close(&context, params, 42); - json_decref(params); + JsonDoc doc("[]"); + + wfp_impl_close(&context, doc.root(), 42); } TEST(wfp_close, close_fail_inode_invalid_type) @@ -48,14 +41,9 @@ TEST(wfp_close, close_fail_inode_invalid_type) wfp_impl_invokation_context context = create_context(provider); - json_t * params = json_array(); - json_array_append_new(params, json_string("test.filesystem")); - json_array_append_new(params, json_string("42")); - json_array_append_new(params, json_integer(0)); - json_array_append_new(params, json_integer(0)); + JsonDoc doc("[\"test.filesystem\", \"42\", 0, 0]"); - wfp_impl_close(&context, params, 42); - json_decref(params); + wfp_impl_close(&context, doc.root(), 42); } TEST(wfp_close, close_fail_handle_invalid_type) @@ -65,14 +53,9 @@ TEST(wfp_close, close_fail_handle_invalid_type) wfp_impl_invokation_context context = create_context(provider); - json_t * params = json_array(); - json_array_append_new(params, json_string("test.filesystem")); - json_array_append_new(params, json_integer(0)); - json_array_append_new(params, json_string("42")); - json_array_append_new(params, json_integer(0)); + JsonDoc doc("[\"test.filesystem\", 0, \"42\", 0]"); - wfp_impl_close(&context, params, 42); - json_decref(params); + wfp_impl_close(&context, doc.root(), 42); } TEST(wfp_close, close_fail_flags_invalid_type) @@ -82,14 +65,9 @@ TEST(wfp_close, close_fail_flags_invalid_type) wfp_impl_invokation_context context = create_context(provider); - json_t * params = json_array(); - json_array_append_new(params, json_string("test.filesystem")); - json_array_append_new(params, json_integer(0)); - json_array_append_new(params, json_integer(0)); - json_array_append_new(params, json_string("42")); + JsonDoc doc("[\"test.filesystem\", 0, 0, \"42\"]"); - wfp_impl_close(&context, params, 42); - json_decref(params); + wfp_impl_close(&context, doc.root(), 42); } diff --git a/test/webfuse_provider/provider/operation/test_getattr.cc b/test/webfuse_provider/provider/operation/test_getattr.cc index 5346f33..26dcc93 100644 --- a/test/webfuse_provider/provider/operation/test_getattr.cc +++ b/test/webfuse_provider/provider/operation/test_getattr.cc @@ -2,6 +2,7 @@ #include "webfuse_provider/mocks/mock_request.hpp" #include "webfuse_provider/mocks/mock_provider.hpp" #include "webfuse_provider/mocks/fake_invokation_context.hpp" +#include "webfuse_provider/test_util/json_doc.hpp" #include #include @@ -10,6 +11,7 @@ using ::webfuse_test::MockProvider; using ::webfuse_test::MockRequest; using ::webfuse_test::StatMatcher; using ::webfuse_test::create_context; +using ::webfuse_test::JsonDoc; using ::testing::_; using ::testing::Invoke; @@ -18,7 +20,7 @@ namespace void free_request(wfp_request * request, ino_t) { - free(request); + wfp_impl_request_dispose(request); } } @@ -60,19 +62,14 @@ TEST(wfp_impl_getattr, respond_dir) TEST(wfp_impl_getattr, invoke_provider) { - ino_t inode = 23; MockProvider provider; - EXPECT_CALL(provider,getattr(_, inode)).Times(1).WillOnce(Invoke(free_request)); + EXPECT_CALL(provider,getattr(_, 23)).Times(1).WillOnce(Invoke(free_request)); wfp_request request = {nullptr, nullptr, 0}; wfp_impl_invokation_context context = create_context(provider, &request); - json_t * params = json_array(); - json_array_append_new(params, json_string("test.filesystem")); - json_array_append_new(params, json_integer(inode)); - - wfp_impl_getattr(&context, params, 42); - json_decref(params); + JsonDoc doc("[\"test.filesystem\", 23]"); + wfp_impl_getattr(&context, doc.root(), 42); } TEST(wfp_impl_getattr, fail_invalid_param_count) @@ -83,11 +80,8 @@ TEST(wfp_impl_getattr, fail_invalid_param_count) wfp_request request = {nullptr, nullptr, 0}; wfp_impl_invokation_context context = create_context(provider, &request); - json_t * params = json_array(); - json_array_append_new(params, json_string("test.filesystem")); - - wfp_impl_getattr(&context, params, 42); - json_decref(params); + JsonDoc doc("[\"test.filesystem\"]"); + wfp_impl_getattr(&context, doc.root(), 42); } TEST(wfp_impl_getattr, fail_invalid_inode_type) @@ -98,10 +92,6 @@ TEST(wfp_impl_getattr, fail_invalid_inode_type) wfp_request request = {nullptr, nullptr, 0}; wfp_impl_invokation_context context = create_context(provider, &request); - json_t * params = json_array(); - json_array_append_new(params, json_string("test.filesystem")); - json_array_append_new(params, json_string("42")); - - wfp_impl_getattr(&context, params, 42); - json_decref(params); + JsonDoc doc("[\"test.filesystem\", \"42\"]"); + wfp_impl_getattr(&context, doc.root(), 42); } diff --git a/test/webfuse_provider/provider/operation/test_lookup.cc b/test/webfuse_provider/provider/operation/test_lookup.cc index b4db6f9..550416a 100644 --- a/test/webfuse_provider/provider/operation/test_lookup.cc +++ b/test/webfuse_provider/provider/operation/test_lookup.cc @@ -2,6 +2,7 @@ #include "webfuse_provider/mocks/mock_request.hpp" #include "webfuse_provider/mocks/mock_provider.hpp" #include "webfuse_provider/mocks/fake_invokation_context.hpp" +#include "webfuse_provider/test_util/json_doc.hpp" #include #include @@ -10,6 +11,7 @@ using ::webfuse_test::MockProvider; using ::webfuse_test::MockRequest; using ::webfuse_test::StatMatcher; using ::webfuse_test::create_context; +using ::webfuse_test::JsonDoc; using ::testing::_; using ::testing::Invoke; using ::testing::StrEq; @@ -19,28 +21,22 @@ namespace void free_request(wfp_request * request, ino_t, char const *) { - free(request); + wfp_impl_request_dispose(request); } } TEST(wfp_impl_lookup, invoke_provider) { - ino_t inode = 42; MockProvider provider; - EXPECT_CALL(provider,lookup(_, inode,StrEq("some.file"))).Times(1) + EXPECT_CALL(provider,lookup(_, 42,StrEq("some.file"))).Times(1) .WillOnce(Invoke(free_request)); wfp_request request = {nullptr, nullptr, 0}; wfp_impl_invokation_context context = create_context(provider, &request); - json_t * params = json_array(); - json_array_append_new(params, json_string("test.filesystem")); - json_array_append_new(params, json_integer(inode)); - json_array_append_new(params, json_string("some.file")); - - wfp_impl_lookup(&context, params, 42); - json_decref(params); + JsonDoc doc("[\"test.filesystem\", 42, \"some.file\"]"); + wfp_impl_lookup(&context, doc.root(), 42); } TEST(wfp_impl_lookup, fail_invalid_param_count) @@ -51,12 +47,8 @@ TEST(wfp_impl_lookup, fail_invalid_param_count) wfp_request request = {nullptr, nullptr, 0}; wfp_impl_invokation_context context = create_context(provider, &request); - json_t * params = json_array(); - json_array_append_new(params, json_string("test.filesystem")); - json_array_append_new(params, json_integer(23)); - - wfp_impl_lookup(&context, params, 42); - json_decref(params); + JsonDoc doc("[\"test.filesystem\", 23]"); + wfp_impl_lookup(&context, doc.root(), 42); } TEST(wfp_impl_lookup, fail_invalid_inode_type) @@ -67,13 +59,8 @@ TEST(wfp_impl_lookup, fail_invalid_inode_type) wfp_request request = {nullptr, nullptr, 0}; wfp_impl_invokation_context context = create_context(provider, &request); - json_t * params = json_array(); - json_array_append_new(params, json_string("test.filesystem")); - json_array_append_new(params, json_string("23")); - json_array_append_new(params, json_string("some.file")); - - wfp_impl_lookup(&context, params, 42); - json_decref(params); + JsonDoc doc("[\"test.filesystem\", \"23\", \"some.file\"]"); + wfp_impl_lookup(&context, doc.root(), 42); } TEST(wfp_impl_lookup, fail_invalid_name_type) @@ -84,13 +71,8 @@ TEST(wfp_impl_lookup, fail_invalid_name_type) wfp_request request = {nullptr, nullptr, 0}; wfp_impl_invokation_context context = create_context(provider, &request); - json_t * params = json_array(); - json_array_append_new(params, json_string("test.filesystem")); - json_array_append_new(params, json_integer(23)); - json_array_append_new(params, json_integer(1)); - - wfp_impl_lookup(&context, params, 42); - json_decref(params); + JsonDoc doc("[\"test.filesystem\", 23, 1]"); + wfp_impl_lookup(&context, doc.root(), 42); } TEST(wfp_impl_lookup, default_responds_error) diff --git a/test/webfuse_provider/provider/operation/test_open.cc b/test/webfuse_provider/provider/operation/test_open.cc index 3689941..e810d32 100644 --- a/test/webfuse_provider/provider/operation/test_open.cc +++ b/test/webfuse_provider/provider/operation/test_open.cc @@ -2,6 +2,7 @@ #include "webfuse_provider/mocks/mock_request.hpp" #include "webfuse_provider/mocks/mock_provider.hpp" #include "webfuse_provider/mocks/fake_invokation_context.hpp" +#include "webfuse_provider/test_util/json_doc.hpp" #include #include @@ -10,6 +11,7 @@ using ::webfuse_test::MockProvider; using ::webfuse_test::MockRequest; using ::webfuse_test::OpenMatcher; using ::webfuse_test::create_context; +using ::webfuse_test::JsonDoc; using ::testing::_; using ::testing::Invoke; using ::testing::StrEq; @@ -19,29 +21,22 @@ namespace void free_request(wfp_request * request, ino_t, int) { - free(request); + wfp_impl_request_dispose(request); } } TEST(wfp_impl_open, invoke_provider) { - ino_t inode = 42; - int flags = 0; MockProvider provider; - EXPECT_CALL(provider,open(_, inode, flags)).Times(1) + EXPECT_CALL(provider,open(_, 42, 0)).Times(1) .WillOnce(Invoke(free_request)); wfp_request request = {nullptr, nullptr, 0}; wfp_impl_invokation_context context = create_context(provider, &request); - json_t * params = json_array(); - json_array_append_new(params, json_string("test.filesystem")); - json_array_append_new(params, json_integer(inode)); - json_array_append_new(params, json_integer(flags)); - - wfp_impl_open(&context, params, 42); - json_decref(params); + JsonDoc doc("[\"test.filesystem\",42,0]"); + wfp_impl_open(&context, doc.root(), 42); } TEST(wfp_impl_open, fail_invalid_param_count) @@ -52,12 +47,8 @@ TEST(wfp_impl_open, fail_invalid_param_count) wfp_request request = {nullptr, nullptr, 0}; wfp_impl_invokation_context context = create_context(provider, &request); - json_t * params = json_array(); - json_array_append_new(params, json_string("test.filesystem")); - json_array_append_new(params, json_integer(23)); - - wfp_impl_open(&context, params, 42); - json_decref(params); + JsonDoc doc("[\"test.filesystem\", 23]"); + wfp_impl_open(&context, doc.root(), 42); } TEST(wfp_impl_open, fail_invalid_inode_type) @@ -68,13 +59,8 @@ TEST(wfp_impl_open, fail_invalid_inode_type) wfp_request request = {nullptr, nullptr, 0}; wfp_impl_invokation_context context = create_context(provider, &request); - json_t * params = json_array(); - json_array_append_new(params, json_string("test.filesystem")); - json_array_append_new(params, json_string("")); - json_array_append_new(params, json_integer(0)); - - wfp_impl_open(&context, params, 42); - json_decref(params); + JsonDoc doc("[\"test.filesystem\", \"\", 0]"); + wfp_impl_open(&context, doc.root(), 42); } TEST(wfp_impl_open, fail_invalid_flags_type) @@ -85,13 +71,8 @@ TEST(wfp_impl_open, fail_invalid_flags_type) wfp_request request = {nullptr, nullptr, 0}; wfp_impl_invokation_context context = create_context(provider, &request); - json_t * params = json_array(); - json_array_append_new(params, json_string("test.filesystem")); - json_array_append_new(params, json_integer(23)); - json_array_append_new(params, json_string("")); - - wfp_impl_open(&context, params, 42); - json_decref(params); + JsonDoc doc("[\"test.filesystem\", 23, \"\"]"); + wfp_impl_open(&context, doc.root(), 42); } TEST(wfp_impl_open, default_responds_error) diff --git a/test/webfuse_provider/provider/operation/test_read.cc b/test/webfuse_provider/provider/operation/test_read.cc index 5b818ff..5b0f064 100644 --- a/test/webfuse_provider/provider/operation/test_read.cc +++ b/test/webfuse_provider/provider/operation/test_read.cc @@ -2,6 +2,7 @@ #include "webfuse_provider/mocks/mock_request.hpp" #include "webfuse_provider/mocks/mock_provider.hpp" #include "webfuse_provider/mocks/fake_invokation_context.hpp" +#include "webfuse_provider/test_util/json_doc.hpp" #include #include @@ -10,6 +11,7 @@ using ::webfuse_test::MockProvider; using ::webfuse_test::MockRequest; using ::webfuse_test::ReadResultMatcher; using ::webfuse_test::create_context; +using ::webfuse_test::JsonDoc; using ::testing::_; using ::testing::Invoke; using ::testing::StrEq; @@ -19,33 +21,22 @@ namespace void free_request(wfp_request * request, ino_t, uint32_t, size_t ,size_t) { - free(request); + wfp_impl_request_dispose(request); } } TEST(wfp_impl_read, invoke_provider) { - ino_t inode = 42; - uint32_t handle = 5; - size_t offset = 2; - size_t length = 1; MockProvider provider; - EXPECT_CALL(provider, read(_, inode, handle, offset, length)).Times(1) + EXPECT_CALL(provider, read(_, 42, 5, 2, 1)).Times(1) .WillOnce(Invoke(free_request)); wfp_request request = {nullptr, nullptr, 0}; wfp_impl_invokation_context context = create_context(provider, &request); - json_t * params = json_array(); - json_array_append_new(params, json_string("test.filesystem")); - json_array_append_new(params, json_integer(inode)); - json_array_append_new(params, json_integer(handle)); - json_array_append_new(params, json_integer(offset)); - json_array_append_new(params, json_integer(length)); - - wfp_impl_read(&context, params, 42); - json_decref(params); + JsonDoc doc("[\"test.filesystem\",42,5,2,1]"); + wfp_impl_read(&context, doc.root(), 42); } TEST(wfp_impl_read, fail_invalid_param_count) @@ -56,16 +47,8 @@ TEST(wfp_impl_read, fail_invalid_param_count) wfp_request request = {nullptr, nullptr, 0}; wfp_impl_invokation_context context = create_context(provider, &request); - json_t * params = json_array(); - json_array_append_new(params, json_string("test.filesystem")); - json_array_append_new(params, json_integer(1)); - json_array_append_new(params, json_integer(2)); - json_array_append_new(params, json_integer(3)); - json_array_append_new(params, json_integer(4)); - json_array_append_new(params, json_integer(5)); - - wfp_impl_read(&context, params, 42); - json_decref(params); + JsonDoc doc("[\"test.filesyste\",1,2,3,4,5]"); + wfp_impl_read(&context, doc.root(), 42); } TEST(wfp_impl_read, fail_invalid_inode_type) @@ -76,15 +59,8 @@ TEST(wfp_impl_read, fail_invalid_inode_type) wfp_request request = {nullptr, nullptr, 0}; wfp_impl_invokation_context context = create_context(provider, &request); - json_t * params = json_array(); - json_array_append_new(params, json_string("test.filesystem")); - json_array_append_new(params, json_string("42")); - json_array_append_new(params, json_integer(2)); - json_array_append_new(params, json_integer(3)); - json_array_append_new(params, json_integer(4)); - - wfp_impl_read(&context, params, 42); - json_decref(params); + JsonDoc doc("[\"test.filesyste\",\"42\",2,3,4]"); + wfp_impl_read(&context, doc.root(), 42); } TEST(wfp_impl_read, fail_invalid_handle_type) @@ -95,15 +71,8 @@ TEST(wfp_impl_read, fail_invalid_handle_type) wfp_request request = {nullptr, nullptr, 0}; wfp_impl_invokation_context context = create_context(provider, &request); - json_t * params = json_array(); - json_array_append_new(params, json_string("test.filesystem")); - json_array_append_new(params, json_integer(1)); - json_array_append_new(params, json_string("42")); - json_array_append_new(params, json_integer(3)); - json_array_append_new(params, json_integer(4)); - - wfp_impl_read(&context, params, 42); - json_decref(params); + JsonDoc doc("[\"test.filesyste\",1,\"42\",3,4]"); + wfp_impl_read(&context, doc.root(), 42); } TEST(wfp_impl_read, fail_invalid_offset_type) @@ -114,15 +83,8 @@ TEST(wfp_impl_read, fail_invalid_offset_type) wfp_request request = {nullptr, nullptr, 0}; wfp_impl_invokation_context context = create_context(provider, &request); - json_t * params = json_array(); - json_array_append_new(params, json_string("test.filesystem")); - json_array_append_new(params, json_integer(1)); - json_array_append_new(params, json_integer(2)); - json_array_append_new(params, json_string("42")); - json_array_append_new(params, json_integer(4)); - - wfp_impl_read(&context, params, 42); - json_decref(params); + JsonDoc doc("[\"test.filesyste\",1,2,\"42\",4]"); + wfp_impl_read(&context, doc.root(), 42); } TEST(wfp_impl_read, fail_invalid_length_type) @@ -133,15 +95,8 @@ TEST(wfp_impl_read, fail_invalid_length_type) wfp_request request = {nullptr, nullptr, 0}; wfp_impl_invokation_context context = create_context(provider, &request); - json_t * params = json_array(); - json_array_append_new(params, json_string("test.filesystem")); - json_array_append_new(params, json_integer(1)); - json_array_append_new(params, json_integer(2)); - json_array_append_new(params, json_integer(3)); - json_array_append_new(params, json_string("42")); - - wfp_impl_read(&context, params, 42); - json_decref(params); + JsonDoc doc("[\"test.filesyste\",1,2,3,\"42\"]"); + wfp_impl_read(&context, doc.root(), 42); } TEST(wfp_impl_read, default_responds_error) diff --git a/test/webfuse_provider/provider/operation/test_readdir.cc b/test/webfuse_provider/provider/operation/test_readdir.cc index 6a14f8d..5b13331 100644 --- a/test/webfuse_provider/provider/operation/test_readdir.cc +++ b/test/webfuse_provider/provider/operation/test_readdir.cc @@ -3,6 +3,7 @@ #include "webfuse_provider/mocks/mock_provider.hpp" #include "webfuse_provider/mocks/fake_invokation_context.hpp" #include "webfuse_provider/dirbuffer.h" +#include "webfuse_provider/test_util/json_doc.hpp" #include #include @@ -11,6 +12,7 @@ using ::webfuse_test::MockProvider; using ::webfuse_test::MockRequest; using ::webfuse_test::ReaddirMatcher; using ::webfuse_test::create_context; +using ::webfuse_test::JsonDoc; using ::testing::_; using ::testing::Invoke; @@ -19,26 +21,21 @@ namespace void free_request(wfp_request * request, ino_t) { - free(request); + wfp_impl_request_dispose(request); } } TEST(wfp_impl_readdir, invoke_provider) { - ino_t inode = 23; MockProvider provider; - EXPECT_CALL(provider,readdir(_, inode)).Times(1).WillOnce(Invoke(free_request)); + EXPECT_CALL(provider,readdir(_, 23)).Times(1).WillOnce(Invoke(free_request)); wfp_request request = {nullptr, nullptr, 0}; wfp_impl_invokation_context context = create_context(provider, &request); - json_t * params = json_array(); - json_array_append_new(params, json_string("test.filesystem")); - json_array_append_new(params, json_integer(inode)); - - wfp_impl_readdir(&context, params, 42); - json_decref(params); + JsonDoc doc("[\"test.filesystem\",23]"); + wfp_impl_readdir(&context, doc.root(), 42); } TEST(wfp_impl_readdir, fail_invalid_param_count) @@ -49,13 +46,8 @@ TEST(wfp_impl_readdir, fail_invalid_param_count) wfp_request request = {nullptr, nullptr, 0}; wfp_impl_invokation_context context = create_context(provider, &request); - json_t * params = json_array(); - json_array_append_new(params, json_string("test.filesystem")); - json_array_append_new(params, json_integer(1)); - json_array_append_new(params, json_integer(1)); - - wfp_impl_readdir(&context, params, 42); - json_decref(params); + JsonDoc doc("[\"test.filesystem\",1,1]"); + wfp_impl_readdir(&context, doc.root(), 42); } TEST(wfp_impl_readdir, fail_invalid_inode_type) @@ -66,12 +58,8 @@ TEST(wfp_impl_readdir, fail_invalid_inode_type) wfp_request request = {nullptr, nullptr, 0}; wfp_impl_invokation_context context = create_context(provider, &request); - json_t * params = json_array(); - json_array_append_new(params, json_string("test.filesystem")); - json_array_append_new(params, json_string("1")); - - wfp_impl_readdir(&context, params, 42); - json_decref(params); + JsonDoc doc("[\"test.filesystem\",\"1\"]"); + wfp_impl_readdir(&context, doc.root(), 42); } TEST(wfp_impl_readdir, default_responds_error) diff --git a/test/webfuse_provider/provider/test_client.cc b/test/webfuse_provider/provider/test_client.cc index 32843c9..5580203 100644 --- a/test/webfuse_provider/provider/test_client.cc +++ b/test/webfuse_provider/provider/test_client.cc @@ -2,6 +2,8 @@ #include "webfuse_provider/test_util/webfuse_server.hpp" #include "webfuse_provider/mocks/mock_provider_client.hpp" #include "webfuse_provider/test_util/client.hpp" +#include "webfuse_provider/test_util/json_doc.hpp" +#include "webfuse_provider/impl/json/node.h" #include #include @@ -10,6 +12,7 @@ using webfuse_test::WebfuseServer; using webfuse_test::MockProviderClient; using webfuse_test::Client; +using webfuse_test::JsonDoc; using testing::Invoke; using testing::_; using testing::StrEq; @@ -146,20 +149,19 @@ TEST(Client, Lookup) ASSERT_EQ(std::future_status::ready, connected.get_future().wait_for(TIMEOUT)); - json_t * response = server.Lookup(1, "foo"); - ASSERT_TRUE(json_is_object(response)); - json_t * result = json_object_get(response, "result"); + JsonDoc doc(server.Lookup(1, "foo")); + wfp_json const * response = doc.root(); + ASSERT_TRUE(wfp_impl_json_is_object(response)); + wfp_json const * result = wfp_impl_json_object_get(response, "result"); - json_t * inode = json_object_get(result, "inode"); - ASSERT_EQ(42, json_integer_value(inode)); + wfp_json const * inode = wfp_impl_json_object_get(result, "inode"); + ASSERT_EQ(42, wfp_impl_json_int_get(inode)); - json_t * mode = json_object_get(result, "mode"); - ASSERT_EQ(0644, json_integer_value(mode)); + wfp_json const * mode = wfp_impl_json_object_get(result, "mode"); + ASSERT_EQ(0644, wfp_impl_json_int_get(mode)); - json_t * type = json_object_get(result, "type"); - ASSERT_STREQ("file", json_string_value(type)); - - json_decref(response); + wfp_json const * type = wfp_impl_json_object_get(result, "type"); + ASSERT_STREQ("file", wfp_impl_json_string_get(type)); client.Disconnect(); ASSERT_EQ(std::future_status::ready, disconnected.get_future().wait_for(TIMEOUT)); @@ -194,14 +196,14 @@ TEST(Client, LookupFail) ASSERT_EQ(std::future_status::ready, connected.get_future().wait_for(TIMEOUT)); - json_t * response = server.Lookup(1, "foo"); - ASSERT_TRUE(json_is_object(response)); - json_t * error = json_object_get(response, "error"); + JsonDoc doc(server.Lookup(1, "foo")); + wfp_json const * response = doc.root(); - json_t * code = json_object_get(error, "code"); - ASSERT_NE(0, json_integer_value(code)); + ASSERT_TRUE(wfp_impl_json_is_object(response)); + wfp_json const * error = wfp_impl_json_object_get(response, "error"); - json_decref(response); + wfp_json const * code = wfp_impl_json_object_get(error, "code"); + ASSERT_NE(0, wfp_impl_json_int_get(code)); client.Disconnect(); ASSERT_EQ(std::future_status::ready, disconnected.get_future().wait_for(TIMEOUT)); @@ -236,14 +238,14 @@ TEST(Client, Open) ASSERT_EQ(std::future_status::ready, connected.get_future().wait_for(TIMEOUT)); - json_t * response = server.Open(1, 0); - ASSERT_TRUE(json_is_object(response)); - json_t * result = json_object_get(response, "result"); + JsonDoc doc(server.Open(1, 0)); + wfp_json const * response = doc.root(); - json_t * handle = json_object_get(result, "handle"); - ASSERT_EQ(4711, json_integer_value(handle)); + ASSERT_TRUE(wfp_impl_json_is_object(response)); + wfp_json const * result = wfp_impl_json_object_get(response, "result"); - json_decref(response); + wfp_json const * handle = wfp_impl_json_object_get(result, "handle"); + ASSERT_EQ(4711, wfp_impl_json_int_get(handle)); client.Disconnect(); ASSERT_EQ(std::future_status::ready, disconnected.get_future().wait_for(TIMEOUT)); @@ -279,20 +281,20 @@ TEST(Client, Read) ASSERT_EQ(std::future_status::ready, connected.get_future().wait_for(TIMEOUT)); - json_t * response = server.Read(42, 5, 0, 1); - ASSERT_TRUE(json_is_object(response)); - json_t * result = json_object_get(response, "result"); + JsonDoc doc(server.Read(42, 5, 0, 1)); + wfp_json const * response = doc.root(); - json_t * format = json_object_get(result, "format"); - ASSERT_STREQ("base64", json_string_value(format)); + ASSERT_TRUE(wfp_impl_json_is_object(response)); + wfp_json const * result = wfp_impl_json_object_get(response, "result"); - json_t * count = json_object_get(result, "count"); - ASSERT_EQ(1, json_integer_value(count)); + wfp_json const * format = wfp_impl_json_object_get(result, "format"); + ASSERT_STREQ("base64", wfp_impl_json_string_get(format)); - json_t * data = json_object_get(result, "data"); - ASSERT_STREQ("Kg==", json_string_value(data)); + wfp_json const * count = wfp_impl_json_object_get(result, "count"); + ASSERT_EQ(1, wfp_impl_json_int_get(count)); - json_decref(response); + wfp_json const * data = wfp_impl_json_object_get(result, "data"); + ASSERT_STREQ("Kg==", wfp_impl_json_string_get(data)); client.Disconnect(); ASSERT_EQ(std::future_status::ready, disconnected.get_future().wait_for(TIMEOUT)); @@ -329,14 +331,14 @@ TEST(Client, ReadDir) ASSERT_EQ(std::future_status::ready, connected.get_future().wait_for(TIMEOUT)); - json_t * response = server.ReadDir(42); - ASSERT_TRUE(json_is_object(response)); - json_t * result = json_object_get(response, "result"); + JsonDoc doc(server.ReadDir(42)); + wfp_json const * response = doc.root(); - ASSERT_TRUE(json_is_array(result)); - ASSERT_EQ(3, json_array_size(result)); + ASSERT_TRUE(wfp_impl_json_is_object(response)); + wfp_json const * result = wfp_impl_json_object_get(response, "result"); - json_decref(response); + ASSERT_TRUE(wfp_impl_json_is_array(result)); + ASSERT_EQ(3, wfp_impl_json_array_size(result)); client.Disconnect(); ASSERT_EQ(std::future_status::ready, disconnected.get_future().wait_for(TIMEOUT)); diff --git a/test/webfuse_provider/provider/test_client_protocol.cc b/test/webfuse_provider/provider/test_client_protocol.cc index 318b832..6507359 100644 --- a/test/webfuse_provider/provider/test_client_protocol.cc +++ b/test/webfuse_provider/provider/test_client_protocol.cc @@ -7,17 +7,20 @@ #include "webfuse_provider/mocks/mock_provider_client.hpp" #include "webfuse_provider/protocol_names.h" #include "webfuse_provider/test_util/timeout_watcher.hpp" +#include "webfuse_provider/test_util/json_doc.hpp" +#include "webfuse_provider/impl/json/node.h" #include #include +#include #include -#include using webfuse_test::WsServer; using webfuse_test::MockProviderClient; using webfuse_test::IProviderClient; using webfuse_test::TimeoutWatcher; +using webfuse_test::JsonDoc; using testing::_; using testing::AtMost; using testing::Invoke; @@ -77,16 +80,16 @@ public: wfp_client_protocol_disconnect(protocol); } - void SendToClient(json_t * request) + void SendToClient(std::string const & request) { server->SendMessage(request); } - json_t * ReceiveMessageFromClient() + std::string ReceiveMessageFromClient() { TimeoutWatcher watcher(DEFAULT_TIMEOUT); - json_t * result = server->ReceiveMessage(); - while (nullptr == result) + std::string result = server->ReceiveMessage(); + while (result.empty()) { watcher.check(); lws_service(context, 0); @@ -100,73 +103,65 @@ public: std::string const & expected_username, std::string const & expected_password) { - json_t * request = ReceiveMessageFromClient(); - ASSERT_TRUE(json_is_object(request)); + JsonDoc doc(ReceiveMessageFromClient()); + wfp_json const * request = doc.root(); + ASSERT_TRUE(wfp_impl_json_is_object(request)); - json_t * method = json_object_get(request, "method"); - ASSERT_TRUE(json_is_string(method)); - ASSERT_STREQ("authenticate", json_string_value(method)); + wfp_json const * method = wfp_impl_json_object_get(request, "method"); + ASSERT_TRUE(wfp_impl_json_is_string(method)); + ASSERT_STREQ("authenticate", wfp_impl_json_string_get(method)); - json_t * id = json_object_get(request, "id"); - ASSERT_TRUE(json_is_integer(id)); + wfp_json const * id = wfp_impl_json_object_get(request, "id"); + ASSERT_TRUE(wfp_impl_json_is_int(id)); - json_t * params = json_object_get(request, "params"); - ASSERT_TRUE(json_is_array(params)); - ASSERT_EQ(2, json_array_size(params)); + wfp_json const * params = wfp_impl_json_object_get(request, "params"); + ASSERT_TRUE(wfp_impl_json_is_array(params)); + ASSERT_EQ(2, wfp_impl_json_array_size(params)); - json_t * type = json_array_get(params, 0); - ASSERT_TRUE(json_is_string(type)); - ASSERT_STREQ("username", json_string_value(type)); + wfp_json const * type = wfp_impl_json_array_get(params, 0); + ASSERT_TRUE(wfp_impl_json_is_string(type)); + ASSERT_STREQ("username", wfp_impl_json_string_get(type)); - json_t * credentials = json_array_get(params, 1); - ASSERT_TRUE(json_is_object(credentials)); + wfp_json const * credentials = wfp_impl_json_array_get(params, 1); + ASSERT_TRUE(wfp_impl_json_is_object(credentials)); - json_t * username = json_object_get(credentials, "username"); - ASSERT_TRUE(json_is_string(username)); - ASSERT_STREQ(expected_username.c_str(), json_string_value(username)); + wfp_json const * username = wfp_impl_json_object_get(credentials, "username"); + ASSERT_TRUE(wfp_impl_json_is_string(username)); + ASSERT_STREQ(expected_username.c_str(), wfp_impl_json_string_get(username)); - json_t * password = json_object_get(credentials, "password"); - ASSERT_TRUE(json_is_string(password)); - ASSERT_STREQ(expected_password.c_str(), json_string_value(password)); + wfp_json const * password = wfp_impl_json_object_get(credentials, "password"); + ASSERT_TRUE(wfp_impl_json_is_string(password)); + ASSERT_STREQ(expected_password.c_str(), wfp_impl_json_string_get(password)); - json_t * response = json_object(); - json_object_set_new(response, "result", json_object()); - json_object_set(response, "id", id); - SendToClient(response); - - json_decref(request); + std::ostringstream response; + response << "{\"result\": {}, \"id\": " << wfp_impl_json_int_get(id) << "}"; + SendToClient(response.str()); } void AwaitAddFilesystem(std::string& filesystemName) { - json_t * addFilesystemRequest = ReceiveMessageFromClient(); - ASSERT_NE(nullptr, addFilesystemRequest); - ASSERT_TRUE(json_is_object(addFilesystemRequest)); - - json_t * method = json_object_get(addFilesystemRequest, "method"); - ASSERT_TRUE(json_is_string(method)); - ASSERT_STREQ("add_filesystem", json_string_value(method)); + JsonDoc doc(ReceiveMessageFromClient()); + wfp_json const * request = doc.root(); + ASSERT_TRUE(wfp_impl_json_is_object(request)); - json_t * params = json_object_get(addFilesystemRequest, "params"); - ASSERT_TRUE(json_is_array(params)); - ASSERT_EQ(1, json_array_size(params)); + wfp_json const * method = wfp_impl_json_object_get(request, "method"); + ASSERT_TRUE(wfp_impl_json_is_string(method)); + ASSERT_STREQ("add_filesystem", wfp_impl_json_string_get(method)); - json_t * filesystem = json_array_get(params, 0); - ASSERT_TRUE(json_is_string(filesystem)); - filesystemName = json_string_value(filesystem); + wfp_json const * params = wfp_impl_json_object_get(request, "params"); + ASSERT_TRUE(wfp_impl_json_is_array(params)); + ASSERT_EQ(1, wfp_impl_json_array_size(params)); - json_t * id = json_object_get(addFilesystemRequest, "id"); - ASSERT_TRUE(json_is_integer(id)); + wfp_json const * filesystem = wfp_impl_json_array_get(params, 0); + ASSERT_TRUE(wfp_impl_json_is_string(filesystem)); - json_t * response = json_object(); - json_t * result = json_object(); - json_object_set(result, "id", filesystem); - json_object_set_new(response, "result", result); - json_object_set(response, "id", id); + wfp_json const * id = wfp_impl_json_object_get(request, "id"); + ASSERT_TRUE(wfp_impl_json_is_int(id)); - SendToClient(response); + std::ostringstream response; + response << "{\"result\": {\"id\": \"" << wfp_impl_json_string_get(filesystem) << "\"}, \"id\": " << wfp_impl_json_int_get(id) << "}"; - json_decref(addFilesystemRequest); + SendToClient(response.str()); } private: @@ -250,19 +245,12 @@ TEST(client_protocol, getattr) fixture.AwaitAddFilesystem(filesystem); if (HasFatalFailure()) { return; } - json_t * params = json_array(); - json_array_append_new(params, json_string(filesystem.c_str())); - json_array_append_new(params, json_integer(1)); - json_t * request = json_object(); - json_object_set_new(request, "method", json_string("getattr")); - json_object_set_new(request, "params", params); - json_object_set_new(request, "id", json_integer(42)); - - fixture.SendToClient(request); - json_t * response = fixture.ReceiveMessageFromClient(); - ASSERT_TRUE(json_is_object(response)); + std::ostringstream request; + request << "{\"method\": \"getattr\", \"params\": [\"" << filesystem << "\", 1], \"id\": 42}"; - json_decref(response); + fixture.SendToClient(request.str()); + std::string response = fixture.ReceiveMessageFromClient(); + ASSERT_FALSE(response.empty()); fixture.Disconnect(); } \ No newline at end of file diff --git a/test/webfuse_provider/provider/test_dirbuffer.cc b/test/webfuse_provider/provider/test_dirbuffer.cc index 639b0ef..6912879 100644 --- a/test/webfuse_provider/provider/test_dirbuffer.cc +++ b/test/webfuse_provider/provider/test_dirbuffer.cc @@ -12,21 +12,19 @@ TEST(DirBuffer, Add) wfp_dirbuffer * buffer = wfp_impl_dirbuffer_create(); wfp_impl_dirbuffer_add(buffer, "answer", 42); - ASSERT_EQ(1, json_array_size(buffer->entries)); + ASSERT_EQ(1, wfp_impl_dirbuffer_size(buffer)); - json_t * entry = json_array_get(buffer->entries, 0); - ASSERT_STREQ("answer", json_string_value(json_object_get(entry, "name"))); - ASSERT_EQ(42, json_integer_value(json_object_get(entry, "inode"))); + auto * entry = wfp_impl_dirbuffer_entry_at(buffer, 0); + ASSERT_STREQ("answer", entry->name); + ASSERT_EQ(42, entry->inode); wfp_impl_dirbuffer_dispose(buffer); } -TEST(DirBuffer, Take) +TEST(DirBuffer, EntryAt) { wfp_dirbuffer * buffer = wfp_impl_dirbuffer_create(); - json_t * entries = wfp_impl_dirbuffer_take(buffer); + auto * entry = wfp_impl_dirbuffer_entry_at(buffer, 0); + ASSERT_EQ(nullptr, entry); wfp_impl_dirbuffer_dispose(buffer); - - ASSERT_TRUE(json_is_array(entries)); - json_decref(entries); } diff --git a/test/webfuse_provider/test_util/jansson_test_environment.cc b/test/webfuse_provider/test_util/jansson_test_environment.cc deleted file mode 100644 index 24d091f..0000000 --- a/test/webfuse_provider/test_util/jansson_test_environment.cc +++ /dev/null @@ -1,16 +0,0 @@ -#include -#include - -namespace webfuse_test -{ - -class JanssonTestEnvironment: public ::testing::Environment -{ -public: - void SetUp() - { - json_object_seed(0); - } -}; -# -} \ No newline at end of file diff --git a/test/webfuse_provider/test_util/json_doc.cc b/test/webfuse_provider/test_util/json_doc.cc new file mode 100644 index 0000000..e6176fb --- /dev/null +++ b/test/webfuse_provider/test_util/json_doc.cc @@ -0,0 +1,22 @@ +#include "webfuse_provider/test_util/json_doc.hpp" + +namespace webfuse_test +{ + +JsonDoc::JsonDoc(std::string const & json) +: contents(json) +{ + doc = wfp_impl_json_doc_loadb(const_cast(contents.data()), json.size()); +} + +JsonDoc::~JsonDoc() +{ + wfp_impl_json_doc_dispose(doc); +} + +wfp_json const * JsonDoc::root() +{ + return wfp_impl_json_doc_root(doc); +} + +} \ No newline at end of file diff --git a/test/webfuse_provider/test_util/json_doc.hpp b/test/webfuse_provider/test_util/json_doc.hpp new file mode 100644 index 0000000..d24f98e --- /dev/null +++ b/test/webfuse_provider/test_util/json_doc.hpp @@ -0,0 +1,25 @@ +#ifndef WFP_TEST_UTIL_JSON_DOC_HPP +#define WFP_TEST_UTIL_JSON_DOC_HPP + +#include "webfuse_provider/impl/json/doc.h" +#include "webfuse_provider/impl/json/node.h" + +#include + +namespace webfuse_test +{ + +class JsonDoc +{ +public: + JsonDoc(std::string const & json); + ~JsonDoc(); + wfp_json const * root(); +private: + std::string contents; + wfp_json_doc * doc; +}; + +} + +#endif diff --git a/test/webfuse_provider/test_util/webfuse_server.cc b/test/webfuse_provider/test_util/webfuse_server.cc index b57f247..1b85ac8 100644 --- a/test/webfuse_provider/test_util/webfuse_server.cc +++ b/test/webfuse_provider/test_util/webfuse_server.cc @@ -1,6 +1,8 @@ #include "webfuse_provider/test_util/webfuse_server.hpp" #include "webfuse_provider/impl/util/lws_log.h" #include "webfuse_provider/protocol_names.h" +#include "webfuse_provider/impl/json/doc.h" +#include "webfuse_provider/impl/json/node.h" #include #include @@ -10,6 +12,7 @@ #include #include #include +#include #define TIMEOUT (std::chrono::seconds(10)) @@ -22,7 +25,7 @@ public: virtual ~IServer() = default; virtual void OnConnected(lws * wsi) = 0; virtual void OnConnectionClosed(lws * wsi) = 0; - virtual void OnMessageReceived(lws * wsi, char const * data, size_t length) = 0; + virtual void OnMessageReceived(lws * wsi, char * data, size_t length) = 0; virtual void OnWritable(lws * wsi) = 0; }; @@ -54,7 +57,7 @@ static int wfp_test_utils_webfuse_server_callback( break; case LWS_CALLBACK_RECEIVE: { - auto * data = reinterpret_cast(in); + auto * data = reinterpret_cast(in); server->OnMessageReceived(wsi, data, len); } break; @@ -143,7 +146,7 @@ public: return filesystem; } - json_t * Invoke(std::string const & method, json_t * params) + std::string Invoke(std::string const & method, std::string const & params) { std::promise response; { @@ -151,28 +154,23 @@ public: message = &response; id++; - json_t * request = json_object(); - json_object_set_new(request, "method", json_string(method.c_str())); - json_object_set_new(request, "params", params); - json_object_set_new(request, "id", json_integer(id)); + std::ostringstream request; + request << "{" + << "\"method\": \"" << method << "\"," + << "\"params\": " << params << "," + << "\"id\": " << id + << "}"; - char * request_text = json_dumps(request, 0); - write_queue.push(request_text); - free(request_text); - json_decref(request); + write_queue.push(request.str()); } lws_callback_on_writable(client); - json_t * result = nullptr; + std::string result; auto future = response.get_future(); auto state = future.wait_for(TIMEOUT); if (std::future_status::ready == state) { - 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; + result = future.get(); } return result; @@ -190,7 +188,7 @@ public: client = nullptr; } - void OnMessageReceived(lws * wsi, char const * data, size_t length) override + void OnMessageReceived(lws * wsi, char * data, size_t length) override { { std::unique_lock lock(mutex); @@ -200,35 +198,30 @@ public: } } - json_t * message = json_loadb(data, length, 0, nullptr); - if (message) + wfp_json_doc * doc = wfp_impl_json_doc_loadb(data, length); + if (doc) { - json_t * method = json_object_get(message, "method"); - if (json_is_string(method)) + wfp_json const * message = wfp_impl_json_doc_root(doc); + wfp_json const * method = wfp_impl_json_object_get(message, "method"); + if (wfp_impl_json_is_string(method)) { - if (0 == strcmp("add_filesystem", json_string_value(method))) + if (0 == strcmp("add_filesystem", wfp_impl_json_string_get(method))) { - json_t * id = json_object_get(message, "id"); - - json_t * response = json_object(); - json_t * result = json_object(); - json_object_set_new(result, "id", json_string(GetFilesystem().c_str())); - json_object_set_new(response, "result", result); - json_object_set(response, "id", id); + wfp_json const * id = wfp_impl_json_object_get(message, "id"); - char * response_text = json_dumps(response, 0); + std::ostringstream response; + response << "{\"result\": {\"id\": \"" << GetFilesystem() << "\"}, " + << "\"id\": " << wfp_impl_json_int_get(id) << "}"; { std::unique_lock lock(mutex); - write_queue.push(response_text); + write_queue.push(response.str()); } - free(response_text); - json_decref(response); lws_callback_on_writable(wsi); } } - json_decref(message); + wfp_impl_json_doc_dispose(doc); } } @@ -307,56 +300,41 @@ std::string const & WebfuseServer::GetUrl() return d->GetUrl(); } -json_t * WebfuseServer::Invoke(std::string const & method, json_t * params) +std::string WebfuseServer::Invoke(std::string const & method, std::string const & params) { return d->Invoke(method, params); } -json_t * WebfuseServer::Invoke(std::string const & method, std::string const & params) +std::string WebfuseServer::Lookup(int parent, std::string const & name) { - json_t * params_json = json_loads(params.c_str(), 0, nullptr); - return d->Invoke(method, params_json); -} - -json_t * WebfuseServer::Lookup(int parent, std::string const & name) -{ - json_t * params = json_array(); - json_array_append_new(params, json_string(d->GetFilesystem().c_str())); - json_array_append_new(params, json_integer(parent)); - json_array_append_new(params, json_string(name.c_str())); + std::ostringstream params; + params << "[\"" << d->GetFilesystem() << "\", " << parent << ", \"" << name << "\"]"; - return d->Invoke("lookup", params); + return d->Invoke("lookup", params.str()); } -json_t * WebfuseServer::Open(int inode, int flags) +std::string WebfuseServer::Open(int inode, int flags) { - json_t * params = json_array(); - json_array_append_new(params, json_string(d->GetFilesystem().c_str())); - json_array_append_new(params, json_integer(inode)); - json_array_append_new(params, json_integer(flags)); + std::ostringstream params; + params << "[\"" << d->GetFilesystem() << "\", " << inode << ", " << flags << "]"; - return d->Invoke("open", params); + return d->Invoke("open", params.str()); } -json_t * WebfuseServer::Read(int inode, int handle, int offset, int length) +std::string WebfuseServer::Read(int inode, int handle, int offset, int length) { - json_t * params = json_array(); - json_array_append_new(params, json_string(d->GetFilesystem().c_str())); - json_array_append_new(params, json_integer(inode)); - json_array_append_new(params, json_integer(handle)); - json_array_append_new(params, json_integer(offset)); - json_array_append_new(params, json_integer(length)); - - return d->Invoke("read", params); + std::ostringstream params; + params << "[\"" << d->GetFilesystem() << "\", " << inode << ", " << handle << ", " << offset << ", " << length << "]"; + + return d->Invoke("read", params.str()); } -json_t * WebfuseServer::ReadDir(int inode) +std::string WebfuseServer::ReadDir(int inode) { - json_t * params = json_array(); - json_array_append_new(params, json_string(d->GetFilesystem().c_str())); - json_array_append_new(params, json_integer(inode)); + std::ostringstream params; + params << "[\"" << d->GetFilesystem() << "\", " << inode << "]"; - return d->Invoke("readdir", params); + return d->Invoke("readdir", params.str()); } } \ No newline at end of file diff --git a/test/webfuse_provider/test_util/webfuse_server.hpp b/test/webfuse_provider/test_util/webfuse_server.hpp index ec16dc4..88ef2bc 100644 --- a/test/webfuse_provider/test_util/webfuse_server.hpp +++ b/test/webfuse_provider/test_util/webfuse_server.hpp @@ -2,7 +2,6 @@ #define WFP_TEST_UTIL_WEBFUSE_SERVER_HPP #include -#include namespace webfuse_test { @@ -15,12 +14,11 @@ public: WebfuseServer(bool use_tls = false); ~WebfuseServer(); std::string const & GetUrl(); - json_t * Invoke(std::string const & method, json_t * params); - json_t * Invoke(std::string const & method, std::string const & params); - json_t * Lookup(int parent, std::string const & name); - json_t * Open(int inode, int flags); - json_t * Read(int inode, int handle, int offset, int length); - json_t * ReadDir(int inode); + std::string Invoke(std::string const & method, std::string const & params); + std::string Lookup(int parent, std::string const & name); + std::string Open(int inode, int flags); + std::string Read(int inode, int handle, int offset, int length); + std::string ReadDir(int inode); private: class Private; Private * d; diff --git a/test/webfuse_provider/test_util/ws_server.cc b/test/webfuse_provider/test_util/ws_server.cc index 2386894..865a5f8 100644 --- a/test/webfuse_provider/test_util/ws_server.cc +++ b/test/webfuse_provider/test_util/ws_server.cc @@ -35,8 +35,8 @@ public: ~Private(); bool IsConnected(); std::string GetUrl() const; - void SendMessage(json_t * message); - json_t * ReceiveMessage(); + void SendMessage(std::string const & message); + std::string ReceiveMessage(); void OnConnected(lws * wsi) override; void OnConnectionClosed(lws * wsi) override; void OnMessageReceived(struct lws * wsi, char const * data, size_t length) override; @@ -123,12 +123,12 @@ bool WsServer::IsConnected() return d->IsConnected(); } -void WsServer::SendMessage(json_t * message) +void WsServer::SendMessage(std::string const & message) { d->SendMessage(message); } -json_t * WsServer::ReceiveMessage() +std::string WsServer::ReceiveMessage() { return d->ReceiveMessage(); } @@ -248,7 +248,7 @@ void WsServer::Private::OnWritable(struct lws * wsi) } -void WsServer::Private::SendMessage(json_t * message) +void WsServer::Private::SendMessage(std::string const & message) { lws * wsi = nullptr; @@ -257,10 +257,7 @@ void WsServer::Private::SendMessage(json_t * message) if (nullptr != wsi_) { - char* message_text = json_dumps(message, JSON_COMPACT); - writeQueue.push(message_text); - json_decref(message); - free(message_text); + writeQueue.push(message); wsi = wsi_; } } @@ -280,19 +277,18 @@ void WsServer::Private::OnMessageReceived(struct lws * wsi, char const * data, s } } -json_t * WsServer::Private::ReceiveMessage() +std::string WsServer::Private::ReceiveMessage() { std::unique_lock lock(mutex); - json_t * result = nullptr; + std::string message; if (!recvQueue.empty()) { - std::string const & message_text = recvQueue.front(); - result = json_loads(message_text.c_str(), JSON_DECODE_ANY, nullptr); + message = recvQueue.front(); recvQueue.pop(); } - return result; + return message; } std::string WsServer::Private::GetUrl() const diff --git a/test/webfuse_provider/test_util/ws_server.h b/test/webfuse_provider/test_util/ws_server.h index 8c28005..94a62f2 100644 --- a/test/webfuse_provider/test_util/ws_server.h +++ b/test/webfuse_provider/test_util/ws_server.h @@ -1,7 +1,6 @@ #ifndef WFP_TEST_UTILS_WS_SERVER_HPP #define WFP_TEST_UTILS_WS_SERVER_HPP -#include #include namespace webfuse_test @@ -16,8 +15,8 @@ public: ~WsServer(); bool IsConnected(); std::string GetUrl() const; - void SendMessage(json_t * message); - json_t * ReceiveMessage(); + void SendMessage(std::string const & message); + std::string ReceiveMessage(); private: class Private; Private * d; diff --git a/test/webfuse_provider/util/test_message.cc b/test/webfuse_provider/util/test_message.cc index ae46b2f..a4ab4be 100644 --- a/test/webfuse_provider/util/test_message.cc +++ b/test/webfuse_provider/util/test_message.cc @@ -1,16 +1,22 @@ +#include "webfuse_provider/impl/message.h" + #include +#include + +#include #include -#include "webfuse_provider/impl/message.h" TEST(wfp_message, create) { - json_t * value = json_object(); - - struct wfp_message * message = wfp_message_create(value); + size_t length = 3; + char * raw_data = reinterpret_cast(malloc(LWS_PRE + length)); + char * data = raw_data + LWS_PRE; + snprintf(data, length, "{}"); + + struct wfp_message * message = wfp_message_create(data, length); ASSERT_NE(nullptr, message); - ASSERT_EQ(2, message->length); - ASSERT_TRUE(0 == strncmp("{}", message->data, 2)); + ASSERT_EQ(3, message->length); + ASSERT_STREQ("{}", message->data); wfp_message_dispose(message); - json_decref(value); } diff --git a/test/webfuse_provider/util/test_message_queue.cc b/test/webfuse_provider/util/test_message_queue.cc index 3f135c2..ead767c 100644 --- a/test/webfuse_provider/util/test_message_queue.cc +++ b/test/webfuse_provider/util/test_message_queue.cc @@ -3,16 +3,22 @@ #include "webfuse_provider/impl/message.h" #include "webfuse_provider/impl/util/slist.h" +#include +#include +#include + namespace { struct wfp_slist_item * create_message(char const * content) { - json_t * value = json_object(); - json_object_set_new(value, "content", json_string(content)); - struct wfp_message * message = wfp_message_create(value); + size_t length = strlen(content); + char * raw_data = reinterpret_cast(malloc(LWS_PRE + length)); + char * data = raw_data + LWS_PRE; + + memcpy(data, content, length); + struct wfp_message * message = wfp_message_create(data, length); - json_decref(value); return &message->item; } diff --git a/test/webfuse_provider/util/test_util.cc b/test/webfuse_provider/util/test_util.cc deleted file mode 100644 index c9982ea..0000000 --- a/test/webfuse_provider/util/test_util.cc +++ /dev/null @@ -1,72 +0,0 @@ -#include -#include "webfuse_provider/impl/util/json_util.h" - -TEST(jsonrpc_util, get_int) -{ - json_t * object = json_object(); - json_object_set_new(object, "key", json_integer(23)); - int value = wfp_impl_json_get_int(object, "key", 42); - ASSERT_EQ(23, value); - - json_decref(object); -} - -TEST(jsonrpc_util, failed_to_get_null_object) -{ - int value = wfp_impl_json_get_int(nullptr, "key", 42); - - ASSERT_EQ(42, value); -} - -TEST(jsonrpc_util, failed_to_get_not_object) -{ - json_t * object = json_array(); - int value = wfp_impl_json_get_int(nullptr, "key", 42); - ASSERT_EQ(42, value); - - json_decref(object); -} - -TEST(jsonrpc_util, failed_to_get_invalid_key) -{ - json_t * object = json_object(); - int value = wfp_impl_json_get_int(object, "key", 42); - ASSERT_EQ(42, value); - - json_decref(object); -} - -TEST(jsonrpc_util, failed_to_get_invalid_value_type) -{ - json_t * object = json_object(); - json_object_set_new(object, "key", json_string("42")); - int value = wfp_impl_json_get_int(object, "key", 42); - ASSERT_EQ(42, value); - - json_decref(object); -} - -TEST(jsonrpc_util, get_status_good_if_no_error) -{ - json_t * error = nullptr; - wfp_status status = wfp_impl_jsonrpc_get_status(error); - ASSERT_EQ(WFP_GOOD, status); -} - -TEST(jsonrpc_util, get_status) -{ - json_t * error = json_object(); - json_object_set_new(error, "code", json_integer(WFP_BAD_BUSY)); - wfp_status status = wfp_impl_jsonrpc_get_status(error); - ASSERT_EQ(WFP_BAD_BUSY, status); - json_decref(error); -} - -TEST(jsonrpc_util, get_status_bad_format) -{ - json_t * error = json_array(); - json_array_append_new(error, json_integer(WFP_BAD_BUSY)); - wfp_status status = wfp_impl_jsonrpc_get_status(error); - ASSERT_EQ(WFP_BAD_FORMAT, status); - json_decref(error); -}