commit
39357ff9ae
@ -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
|
||||
|
@ -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 <stdlib.h>
|
||||
|
||||
#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;
|
||||
}
|
@ -0,0 +1,35 @@
|
||||
#ifndef WFP_IMPL_JSON_DOC_H
|
||||
#define WFP_IMPL_JSON_DOC_H
|
||||
|
||||
#ifndef __cplusplus
|
||||
#include <stddef.h>
|
||||
#else
|
||||
#include <cstddef>
|
||||
#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
|
@ -0,0 +1,179 @@
|
||||
#include "webfuse_provider/impl/json/node.h"
|
||||
#include "webfuse_provider/impl/json/node_intern.h"
|
||||
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
|
||||
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;
|
||||
}
|
||||
}
|
@ -0,0 +1,87 @@
|
||||
#ifndef WFP_IMPL_JSON_NODE_H
|
||||
#define WFP_IMPL_JSON_NODE_H
|
||||
|
||||
#ifndef __cplusplus
|
||||
#include <stddef.h>
|
||||
#include <stdbool.h>
|
||||
#else
|
||||
#include <cstddef>
|
||||
#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
|
@ -0,0 +1,76 @@
|
||||
#ifndef WFP_IMPL_JSON_NODE_INTERN_H
|
||||
#define WFP_IMPL_JSON_NODE_INTERN_H
|
||||
|
||||
#ifndef __cplusplus
|
||||
#include <stddef.h>
|
||||
#include <stdbool.h>
|
||||
#else
|
||||
#include <cstddef>
|
||||
#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
|
@ -0,0 +1,169 @@
|
||||
#include "webfuse_provider/impl/json/reader.h"
|
||||
#include <string.h>
|
||||
|
||||
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;
|
||||
}
|
@ -0,0 +1,65 @@
|
||||
#ifndef WFP_IMPL_JSON_READER_H
|
||||
#define WFP_IMPL_JSON_READER_H
|
||||
|
||||
#ifndef __cplusplus
|
||||
#include <stddef.h>
|
||||
#include <stdbool.h>
|
||||
#else
|
||||
#include <cstddef>
|
||||
#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
|
@ -0,0 +1,401 @@
|
||||
#include "webfuse_provider/impl/json/writer.h"
|
||||
#include "webfuse_provider/impl/util/base64.h"
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <stdbool.h>
|
||||
#include <limits.h>
|
||||
|
||||
#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);
|
||||
}
|
@ -0,0 +1,104 @@
|
||||
#ifndef WFP_IMPL_JSON_WRITER_H
|
||||
#define WFP_IMPL_JSON_WRTIER_H
|
||||
|
||||
#ifndef __cplusplus
|
||||
#include <stddef.h>
|
||||
#else
|
||||
#include <cstddef>
|
||||
#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
|
@ -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 <libwebsockets.h>
|
||||
#include <stdlib.h>
|
||||
#include <stdbool.h>
|
||||
|
||||
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;
|
||||
}
|
@ -0,0 +1,63 @@
|
||||
#ifndef WFP_IMPL_MESSAGE_WRITER_H
|
||||
#define WFP_IMPL_MESSAGE_WRITER_H
|
||||
|
||||
#ifndef _cplusplus
|
||||
#include <stddef.h>
|
||||
#else
|
||||
#include <cstddef>
|
||||
#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
|
@ -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;
|
||||
}
|
@ -1,26 +0,0 @@
|
||||
#ifndef WFP_JSON_UTIL_H
|
||||
#define WFP_JSON_UTIL_H
|
||||
|
||||
#include <jansson.h>
|
||||
#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
|
@ -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
|
@ -0,0 +1,303 @@
|
||||
#include "webfuse_provider/impl/json/doc.h"
|
||||
#include "webfuse_provider/impl/json/node.h"
|
||||
#include <gtest/gtest.h>
|
||||
#include <cstring>
|
||||
|
||||
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);
|
||||
}
|
||||
|
||||
}
|
@ -0,0 +1,252 @@
|
||||
#include "webfuse_provider/impl/json/writer.h"
|
||||
#include <gtest/gtest.h>
|
||||
#include <string>
|
||||
#include <climits>
|
||||
|
||||
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);
|
||||
}
|
@ -1,138 +1,26 @@
|
||||
#include <gtest/gtest.h>
|
||||
#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<Context*>(user_data);
|
||||
context->response = request;
|
||||
json_incref(request);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
TEST(wfp_jsonrpc_request, create_dispose)
|
||||
{
|
||||
Context context{nullptr};
|
||||
void * user_data = reinterpret_cast<void*>(&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<void*>(&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<json_t*>(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<void*>(&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<json_t*>(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 <gtest/gtest.h>
|
||||
|
||||
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()));
|
||||
}
|
||||
|
@ -1,147 +1,122 @@
|
||||
#include <gtest/gtest.h>
|
||||
#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);
|
||||
}
|
||||
|
@ -1,58 +1,73 @@
|
||||
#include <string>
|
||||
#include <gtest/gtest.h>
|
||||
|
||||
#include "webfuse_provider/impl/jsonrpc/response_intern.h"
|
||||
#include "webfuse_provider/impl/jsonrpc/error.h"
|
||||
#include "webfuse_provider/test_util/json_doc.hpp"
|
||||
|
||||
#include <gtest/gtest.h>
|
||||
|
||||
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);
|
||||
}
|
||||
|
@ -1,16 +0,0 @@
|
||||
#include <gtest/gtest.h>
|
||||
#include <jansson.h>
|
||||
|
||||
namespace webfuse_test
|
||||
{
|
||||
|
||||
class JanssonTestEnvironment: public ::testing::Environment
|
||||
{
|
||||
public:
|
||||
void SetUp()
|
||||
{
|
||||
json_object_seed(0);
|
||||
}
|
||||
};
|
||||
#
|
||||
}
|
@ -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<char*>(contents.data()), json.size());
|
||||
}
|
||||
|
||||
JsonDoc::~JsonDoc()
|
||||
{
|
||||
wfp_impl_json_doc_dispose(doc);
|
||||
}
|
||||
|
||||
wfp_json const * JsonDoc::root()
|
||||
{
|
||||
return wfp_impl_json_doc_root(doc);
|
||||
}
|
||||
|
||||
}
|
@ -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 <string>
|
||||
|
||||
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
|
@ -1,16 +1,22 @@
|
||||
#include "webfuse_provider/impl/message.h"
|
||||
|
||||
#include <gtest/gtest.h>
|
||||
#include <libwebsockets.h>
|
||||
|
||||
#include <cstdlib>
|
||||
#include <cstring>
|
||||
#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<char*>(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);
|
||||
}
|
||||
|
@ -1,72 +0,0 @@
|
||||
#include <gtest/gtest.h>
|
||||
#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);
|
||||
}
|
Loading…
Reference in new issue