mirror of
https://github.com/falk-werner/webfuse-provider
synced 2024-10-27 20:44:10 +00:00
added implementation of json_writer
This commit is contained in:
parent
c6c9edcd81
commit
c9f086f6cf
@ -1,17 +1,25 @@
|
||||
#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 8
|
||||
#define WFP_JSON_WRITER_MAX_LEVEL 7
|
||||
#define WFP_INT_BUFFER_SIZE 64
|
||||
|
||||
enum wfp_json_writer_state
|
||||
{
|
||||
WFP_JSON_WRITER_STATE_INIT
|
||||
WFP_JSON_WRITER_STATE_INIT,
|
||||
WFP_JSON_WRITER_STATE_ARRAY_FIRST,
|
||||
WFP_JSON_WRITER_STATE_ARRAY_NEXT,
|
||||
WFP_JSON_WRITER_STATE_OBJECT_FIRST,
|
||||
WFP_JSON_WRITER_STATE_OBJECT_NEXT
|
||||
};
|
||||
|
||||
struct wfp_json_writer
|
||||
{
|
||||
enum wfp_json_writer_state state[WFP_JSON_WRITER_MAX_LEVEL];
|
||||
enum wfp_json_writer_state state[WFP_JSON_WRITER_MAX_LEVEL + 1];
|
||||
size_t level;
|
||||
size_t capacity;
|
||||
size_t pre;
|
||||
@ -20,6 +28,34 @@ struct wfp_json_writer
|
||||
char * raw_data;
|
||||
};
|
||||
|
||||
static char
|
||||
wfp_impl_json_writer_get_esc(
|
||||
char c)
|
||||
{
|
||||
switch (c)
|
||||
{
|
||||
case '\\': return '\\';
|
||||
case '\"': return '\"';
|
||||
case '/' : return '/';
|
||||
case '\b': return 'b';
|
||||
case '\f': return 'f';
|
||||
case '\n': return 'n';
|
||||
case '\r': return 'r';
|
||||
case '\t': return 't';
|
||||
default:
|
||||
// error
|
||||
return '/';
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
wfp_impl_json_writer_write_raw_char(
|
||||
struct wfp_json_writer * writer,
|
||||
char value)
|
||||
{
|
||||
writer->data[writer->offset++] = value;
|
||||
}
|
||||
|
||||
static void
|
||||
wfp_impl_json_writer_reserve(
|
||||
struct wfp_json_writer * writer,
|
||||
@ -40,13 +76,47 @@ wfp_impl_json_writer_reserve(
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
wfp_impl_json_writer_write_raw_char(
|
||||
struct wfp_json_writer * writer,
|
||||
char value)
|
||||
static void
|
||||
wfp_impl_json_writer_begin_value(
|
||||
struct wfp_json_writer * writer)
|
||||
{
|
||||
writer->data[writer->offset] = value;
|
||||
writer->offset++;
|
||||
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
|
||||
@ -84,9 +154,20 @@ wfp_impl_json_writer_dispose(
|
||||
free(writer);
|
||||
}
|
||||
|
||||
void
|
||||
wfp_impl_json_writer_reset(
|
||||
struct wfp_json_writer * writer)
|
||||
{
|
||||
writer->level = 0;
|
||||
writer->state[writer->level] = WFP_JSON_WRITER_STATE_INIT;
|
||||
writer->offset = 0;
|
||||
}
|
||||
|
||||
|
||||
char *
|
||||
wfp_impl_json_writer_take_data(
|
||||
struct wfp_json_writer * writer)
|
||||
struct wfp_json_writer * writer,
|
||||
size_t * size)
|
||||
{
|
||||
wfp_impl_json_writer_reserve(writer, 1);
|
||||
writer->data[writer->offset] = '\0';
|
||||
@ -94,6 +175,11 @@ wfp_impl_json_writer_take_data(
|
||||
char * result = writer->raw_data;
|
||||
writer->raw_data = NULL;
|
||||
|
||||
if (NULL != size)
|
||||
{
|
||||
*size = writer->offset;
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
@ -102,7 +188,41 @@ wfp_impl_json_writer_write_int(
|
||||
struct wfp_json_writer * writer,
|
||||
int value)
|
||||
{
|
||||
wfp_impl_json_writer_begin_value(writer);
|
||||
wfp_impl_json_writer_reserve(writer, WFP_INT_BUFFER_SIZE);
|
||||
|
||||
bool const is_signed = (0 > value);
|
||||
char buffer[WFP_INT_BUFFER_SIZE];
|
||||
size_t offset = WFP_INT_BUFFER_SIZE;
|
||||
buffer[--offset] = '\0';
|
||||
if (is_signed)
|
||||
{
|
||||
if (INT_MIN == value)
|
||||
{
|
||||
char const actual = (char) abs(value % 10);
|
||||
buffer[--offset] = (char) ('0' + actual);
|
||||
value /= 10;
|
||||
}
|
||||
value = -value;
|
||||
}
|
||||
|
||||
do
|
||||
{
|
||||
char const actual = (char) (value % 10);
|
||||
buffer[--offset] = ('0' + actual);
|
||||
value /= 10;
|
||||
}
|
||||
while (0 != value);
|
||||
|
||||
if (is_signed)
|
||||
{
|
||||
buffer[--offset] = '-';
|
||||
}
|
||||
|
||||
size_t const length = (WFP_INT_BUFFER_SIZE - offset - 1);
|
||||
wfp_impl_json_writer_write_raw(writer, &(buffer[offset]), length);
|
||||
|
||||
wfp_impl_json_writer_end_value(writer);
|
||||
}
|
||||
|
||||
void
|
||||
@ -110,6 +230,41 @@ wfp_impl_json_writer_write_string(
|
||||
struct wfp_json_writer * writer,
|
||||
char const * value)
|
||||
{
|
||||
wfp_impl_json_writer_begin_value(writer);
|
||||
|
||||
size_t length = strlen(value);
|
||||
wfp_impl_json_writer_reserve(writer, length + 2);
|
||||
|
||||
wfp_impl_json_writer_write_raw_char(writer, '\"');
|
||||
for(size_t i = 0; i < length; i++)
|
||||
{
|
||||
char c = value[i];
|
||||
if ((' ' <= c) && (c != '\\') && (c != '\"'))
|
||||
{
|
||||
wfp_impl_json_writer_write_raw_char(writer, c);
|
||||
}
|
||||
else
|
||||
{
|
||||
char esc = wfp_impl_json_writer_get_esc(c);
|
||||
|
||||
wfp_impl_json_writer_reserve(writer, (length - i) + 2);
|
||||
wfp_impl_json_writer_write_raw_char(writer, '\\');
|
||||
wfp_impl_json_writer_write_raw_char(writer, esc);
|
||||
}
|
||||
|
||||
}
|
||||
wfp_impl_json_writer_write_raw_char(writer, '\"');
|
||||
|
||||
wfp_impl_json_writer_end_value(writer);
|
||||
}
|
||||
|
||||
void
|
||||
wfp_impl_json_writer_write_string_nocheck(
|
||||
struct wfp_json_writer * writer,
|
||||
char const * value)
|
||||
{
|
||||
wfp_impl_json_writer_begin_value(writer);
|
||||
|
||||
size_t length = strlen(value);
|
||||
wfp_impl_json_writer_reserve(writer, length + 2);
|
||||
|
||||
@ -117,6 +272,7 @@ wfp_impl_json_writer_write_string(
|
||||
wfp_impl_json_writer_write_raw(writer, value, length);
|
||||
wfp_impl_json_writer_write_raw_char(writer, '\"');
|
||||
|
||||
wfp_impl_json_writer_end_value(writer);
|
||||
}
|
||||
|
||||
void
|
||||
@ -125,14 +281,27 @@ wfp_impl_json_writer_write_bytes(
|
||||
char const * data,
|
||||
size_t length)
|
||||
{
|
||||
wfp_impl_json_writer_begin_value(writer);
|
||||
|
||||
size_t encoded_length = wfp_impl_base64_encoded_size(length);
|
||||
wfp_impl_json_writer_reserve(writer, encoded_length + 2);
|
||||
|
||||
wfp_impl_json_writer_write_raw_char(writer, '\"');
|
||||
wfp_impl_base64_encode((uint8_t const*) data, length, &(writer->data[writer->offset]), encoded_length);
|
||||
writer->offset += encoded_length;
|
||||
wfp_impl_json_writer_write_raw_char(writer, '\"');
|
||||
|
||||
wfp_impl_json_writer_end_value(writer);
|
||||
}
|
||||
|
||||
void
|
||||
wfp_impl_json_writer_object_begin(
|
||||
struct wfp_json_writer * writer)
|
||||
{
|
||||
wfp_impl_json_writer_begin_value(writer);
|
||||
wfp_impl_json_writer_reserve(writer, 1);
|
||||
|
||||
wfp_impl_json_writer_push(writer, WFP_JSON_WRITER_STATE_OBJECT_FIRST);
|
||||
wfp_impl_json_writer_write_raw_char(writer, '{');
|
||||
}
|
||||
|
||||
@ -142,6 +311,9 @@ wfp_impl_json_writer_object_end(
|
||||
{
|
||||
wfp_impl_json_writer_reserve(writer, 1);
|
||||
wfp_impl_json_writer_write_raw_char(writer, '}');
|
||||
|
||||
wfp_impl_json_writer_pop(writer);
|
||||
wfp_impl_json_writer_end_value(writer);
|
||||
}
|
||||
|
||||
void
|
||||
@ -150,13 +322,32 @@ wfp_impl_json_writer_object_key(
|
||||
char const * key)
|
||||
{
|
||||
wfp_impl_json_writer_reserve(writer, 1);
|
||||
wfp_impl_json_writer_write_raw_char(writer, '[');
|
||||
|
||||
size_t length = strlen(key);
|
||||
wfp_impl_json_writer_reserve(writer, length + 4);
|
||||
|
||||
if (WFP_JSON_WRITER_STATE_OBJECT_NEXT == writer->state[writer->level])
|
||||
{
|
||||
wfp_impl_json_writer_write_raw_char(writer, ',');
|
||||
}
|
||||
else
|
||||
{
|
||||
writer->state[writer->level] = WFP_JSON_WRITER_STATE_OBJECT_NEXT;
|
||||
}
|
||||
|
||||
wfp_impl_json_writer_write_raw_char(writer, '\"');
|
||||
wfp_impl_json_writer_write_raw(writer, key, length);
|
||||
wfp_impl_json_writer_write_raw_char(writer, '\"');
|
||||
wfp_impl_json_writer_write_raw_char(writer, ':');
|
||||
}
|
||||
|
||||
void
|
||||
wfp_impl_json_writer_array_begin(
|
||||
struct wfp_json_writer * writer)
|
||||
{
|
||||
wfp_impl_json_writer_begin_value(writer);
|
||||
wfp_impl_json_writer_push(writer, WFP_JSON_WRITER_STATE_ARRAY_FIRST);
|
||||
|
||||
wfp_impl_json_writer_reserve(writer, 1);
|
||||
wfp_impl_json_writer_write_raw_char(writer, '[');
|
||||
}
|
||||
@ -167,4 +358,7 @@ wfp_impl_json_writer_array_end(
|
||||
{
|
||||
wfp_impl_json_writer_reserve(writer, 1);
|
||||
wfp_impl_json_writer_write_raw_char(writer, ']');
|
||||
|
||||
wfp_impl_json_writer_pop(writer);
|
||||
wfp_impl_json_writer_end_value(writer);
|
||||
}
|
@ -4,7 +4,7 @@
|
||||
#ifndef __cplusplus
|
||||
#include <stddef.h>
|
||||
#else
|
||||
#include <cstddef.h>
|
||||
#include <cstddef>
|
||||
#endif
|
||||
|
||||
#ifdef __cplusplus
|
||||
@ -23,9 +23,14 @@ extern void
|
||||
wfp_impl_json_writer_dispose(
|
||||
struct wfp_json_writer * writer);
|
||||
|
||||
extern void
|
||||
wfp_impl_json_writer_reset(
|
||||
struct wfp_json_writer * writer);
|
||||
|
||||
extern char *
|
||||
wfp_impl_json_writer_take_data(
|
||||
struct wfp_json_writer * writer);
|
||||
struct wfp_json_writer * writer,
|
||||
size_t * size);
|
||||
|
||||
extern void
|
||||
wfp_impl_json_writer_write_int(
|
||||
@ -37,6 +42,11 @@ wfp_impl_json_writer_write_string(
|
||||
struct wfp_json_writer * writer,
|
||||
char const * value);
|
||||
|
||||
extern void
|
||||
wfp_impl_json_writer_write_string_nocheck(
|
||||
struct wfp_json_writer * writer,
|
||||
char const * value);
|
||||
|
||||
extern void
|
||||
wfp_impl_json_writer_write_bytes(
|
||||
struct wfp_json_writer * writer,
|
||||
|
@ -11,6 +11,7 @@ extern struct wfp_message * wfp_message_create(json_t const * value)
|
||||
struct wfp_message * message = (struct wfp_message *) data;
|
||||
message->data = &data[sizeof(struct wfp_message) + LWS_PRE];
|
||||
message->length = length;
|
||||
message->raw_data = NULL;
|
||||
|
||||
json_dumpb(value, message->data, length, JSON_COMPACT);
|
||||
|
||||
@ -20,5 +21,6 @@ extern struct wfp_message * wfp_message_create(json_t const * value)
|
||||
void wfp_message_dispose(
|
||||
struct wfp_message * message)
|
||||
{
|
||||
free(message->raw_data);
|
||||
free(message);
|
||||
}
|
||||
|
@ -15,6 +15,7 @@ struct wfp_message
|
||||
{
|
||||
struct wfp_slist_item item;
|
||||
char * data;
|
||||
char * raw_data;
|
||||
size_t length;
|
||||
};
|
||||
|
||||
|
@ -2,25 +2,30 @@
|
||||
#include "webfuse_provider/impl/message.h"
|
||||
#include "webfuse_provider/impl/util/base64.h"
|
||||
#include "webfuse_provider/impl/dirbuffer.h"
|
||||
#include "webfuse_provider/impl/json/writer.h"
|
||||
|
||||
#include <jansson.h>
|
||||
#include <libwebsockets.h>
|
||||
#include <stdlib.h>
|
||||
#include <stdbool.h>
|
||||
|
||||
struct wfp_message_writer
|
||||
{
|
||||
json_t * result;
|
||||
json_t * error;
|
||||
struct wfp_json_writer * json_writer;
|
||||
int id;
|
||||
bool is_finished;
|
||||
};
|
||||
|
||||
struct wfp_message_writer *
|
||||
wfp_impl_message_writer_create(int id)
|
||||
{
|
||||
struct wfp_message_writer * writer = malloc(sizeof(writer));
|
||||
writer->result = json_object();
|
||||
writer->error = NULL;
|
||||
writer->json_writer = wfp_impl_json_writer_create(1024, LWS_PRE);
|
||||
writer->id = id;
|
||||
writer->is_finished = false;
|
||||
|
||||
wfp_impl_json_writer_object_begin(writer->json_writer);
|
||||
wfp_impl_json_writer_object_key(writer->json_writer, "result");
|
||||
wfp_impl_json_writer_object_begin(writer->json_writer);
|
||||
|
||||
return writer;
|
||||
}
|
||||
@ -29,8 +34,7 @@ void
|
||||
wfp_impl_message_writer_dispose(
|
||||
struct wfp_message_writer * writer)
|
||||
{
|
||||
json_decref(writer->result);
|
||||
json_decref(writer->error);
|
||||
wfp_impl_json_writer_dispose(writer->json_writer);
|
||||
free(writer);
|
||||
}
|
||||
|
||||
@ -38,29 +42,19 @@ struct wfp_message *
|
||||
wfp_impl_message_writer_take_message(
|
||||
struct wfp_message_writer * writer)
|
||||
{
|
||||
json_t * response = json_object();
|
||||
|
||||
if (writer->result)
|
||||
if (!writer->is_finished)
|
||||
{
|
||||
json_object_set_new(response, "result", writer->result);
|
||||
wfp_impl_json_writer_object_end(writer->json_writer);
|
||||
wfp_impl_json_writer_object_key(writer->json_writer, "id");
|
||||
wfp_impl_json_writer_write_int(writer->json_writer, writer->id);
|
||||
wfp_impl_json_writer_object_end(writer->json_writer);
|
||||
writer->is_finished = true;
|
||||
}
|
||||
else
|
||||
{
|
||||
json_object_set_new(response, "error", writer->error);
|
||||
}
|
||||
json_object_set_new(response, "id", json_integer(writer->id));
|
||||
|
||||
size_t const length = json_dumpb(response, NULL, 0, JSON_COMPACT);
|
||||
struct wfp_message * message = malloc(sizeof(struct wfp_message));
|
||||
message->raw_data = wfp_impl_json_writer_take_data(writer->json_writer, &message->length);
|
||||
message->data = &(message->raw_data[LWS_PRE]);
|
||||
|
||||
char * data = malloc(sizeof(struct wfp_message) + LWS_PRE + length);
|
||||
struct wfp_message * message = (struct wfp_message *) data;
|
||||
message->data = &data[sizeof(struct wfp_message) + LWS_PRE];
|
||||
message->length = length;
|
||||
|
||||
json_dumpb(response, message->data, length, JSON_COMPACT);
|
||||
|
||||
|
||||
json_decref(response);
|
||||
return message;
|
||||
}
|
||||
|
||||
@ -70,7 +64,8 @@ wfp_impl_message_writer_add_int(
|
||||
char const * key,
|
||||
int value)
|
||||
{
|
||||
json_object_set_new(writer->result, key, json_integer(value));
|
||||
wfp_impl_json_writer_object_key(writer->json_writer, key);
|
||||
wfp_impl_json_writer_write_int(writer->json_writer, value);
|
||||
}
|
||||
|
||||
void
|
||||
@ -79,7 +74,8 @@ wfp_impl_message_writer_add_string(
|
||||
char const * key,
|
||||
char const * value)
|
||||
{
|
||||
json_object_set_new(writer->result, key, json_string(value));
|
||||
wfp_impl_json_writer_object_key(writer->json_writer, key);
|
||||
wfp_impl_json_writer_write_string(writer->json_writer, value);
|
||||
}
|
||||
|
||||
void
|
||||
@ -89,13 +85,8 @@ wfp_impl_message_writer_add_bytes(
|
||||
char const * data,
|
||||
size_t length)
|
||||
{
|
||||
size_t const size = wfp_impl_base64_encoded_size(length) + 1;
|
||||
char * buffer = malloc(size);
|
||||
wfp_impl_base64_encode((uint8_t const *) data, length, buffer, size);
|
||||
|
||||
json_object_set_new(writer->result, "data", json_string(buffer));
|
||||
|
||||
free(buffer);
|
||||
wfp_impl_json_writer_object_key(writer->json_writer, key);
|
||||
wfp_impl_json_writer_write_bytes(writer->json_writer, data, length);
|
||||
}
|
||||
|
||||
void
|
||||
@ -103,8 +94,36 @@ wfp_impl_message_writer_add_dirbuffer(
|
||||
struct wfp_message_writer * writer,
|
||||
struct wfp_dirbuffer * dirbuffer)
|
||||
{
|
||||
json_decref(writer->result);
|
||||
writer->result = wfp_impl_dirbuffer_take(dirbuffer);
|
||||
wfp_impl_json_writer_reset(writer->json_writer);
|
||||
|
||||
wfp_impl_json_writer_object_begin(writer->json_writer);
|
||||
wfp_impl_json_writer_object_key(writer->json_writer, "result");
|
||||
wfp_impl_json_writer_array_begin(writer->json_writer);
|
||||
|
||||
json_t * entries = wfp_impl_dirbuffer_take(dirbuffer);
|
||||
for (size_t i = 0; i < json_array_size(entries); i++)
|
||||
{
|
||||
json_t * entry = json_array_get(entries, i);
|
||||
char const * name = json_string_value(json_object_get(entry, "name"));
|
||||
int inode = json_integer_value(json_object_get(entry, "inode"));
|
||||
|
||||
wfp_impl_json_writer_object_begin(writer->json_writer);
|
||||
wfp_impl_json_writer_object_key(writer->json_writer, "name");
|
||||
wfp_impl_json_writer_write_string(writer->json_writer, name);
|
||||
wfp_impl_json_writer_object_key(writer->json_writer, "inode");
|
||||
wfp_impl_json_writer_write_int(writer->json_writer, inode);
|
||||
wfp_impl_json_writer_object_end(writer->json_writer);
|
||||
|
||||
}
|
||||
json_decref(entries);
|
||||
|
||||
wfp_impl_json_writer_array_end(writer->json_writer);
|
||||
|
||||
wfp_impl_json_writer_object_key(writer->json_writer, "id");
|
||||
wfp_impl_json_writer_write_int(writer->json_writer, writer->id);
|
||||
wfp_impl_json_writer_object_end(writer->json_writer);
|
||||
|
||||
writer->is_finished = true;
|
||||
}
|
||||
|
||||
void
|
||||
@ -112,10 +131,17 @@ wfp_impl_message_writer_set_error(
|
||||
struct wfp_message_writer * writer,
|
||||
int error_code)
|
||||
{
|
||||
json_decref(writer->result);
|
||||
writer->result = NULL;
|
||||
wfp_impl_json_writer_reset(writer->json_writer);
|
||||
|
||||
json_decref(writer->error);
|
||||
writer->error = json_object();
|
||||
json_object_set_new(writer->error, "code", json_integer(error_code));
|
||||
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;
|
||||
}
|
||||
|
@ -112,6 +112,7 @@ alltests = executable('alltests',
|
||||
'test/webfuse_provider/mocks/mock_provider_client.cc',
|
||||
'test/webfuse_provider/mocks/mock_provider.cc',
|
||||
'test/webfuse_provider/mocks/mock_jsonrpc_proxy.cc',
|
||||
'test/webfuse_provider/json/test_json_writer.cc',
|
||||
'test/webfuse_provider/jsonrpc/mock_timer_callback.cc',
|
||||
'test/webfuse_provider/jsonrpc/mock_timer.cc',
|
||||
'test/webfuse_provider/jsonrpc/test_is_request.cc',
|
||||
|
234
test/webfuse_provider/json/test_json_writer.cc
Normal file
234
test/webfuse_provider/json/test_json_writer.cc
Normal file
@ -0,0 +1,234 @@
|
||||
#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_key(writer, "answer");
|
||||
wfp_impl_json_writer_write_int(writer, 42);
|
||||
wfp_impl_json_writer_object_end(writer);
|
||||
|
||||
char * data = wfp_impl_json_writer_take_data(writer, nullptr);
|
||||
|
||||
ASSERT_STREQ("{\"answer\":42}", data);
|
||||
|
||||
wfp_impl_json_writer_dispose(writer);
|
||||
free(data);
|
||||
}
|
||||
|
||||
TEST(json_writer, write_mixed_object)
|
||||
{
|
||||
wfp_json_writer * writer = wfp_impl_json_writer_create(128,0);
|
||||
wfp_impl_json_writer_object_begin(writer);
|
||||
|
||||
wfp_impl_json_writer_object_key(writer, "a");
|
||||
wfp_impl_json_writer_write_int(writer, 42);
|
||||
|
||||
wfp_impl_json_writer_object_key(writer, "b");
|
||||
wfp_impl_json_writer_write_string(writer, "0");
|
||||
|
||||
wfp_impl_json_writer_object_key(writer, "c");
|
||||
wfp_impl_json_writer_array_begin(writer);
|
||||
wfp_impl_json_writer_array_end(writer);
|
||||
|
||||
wfp_impl_json_writer_object_end(writer);
|
||||
|
||||
char * data = wfp_impl_json_writer_take_data(writer, nullptr);
|
||||
|
||||
ASSERT_STREQ("{\"a\":42,\"b\":\"0\",\"c\":[]}", data);
|
||||
|
||||
wfp_impl_json_writer_dispose(writer);
|
||||
free(data);
|
||||
}
|
||||
|
||||
TEST(json_writer, write_nested_object)
|
||||
{
|
||||
wfp_json_writer * writer = wfp_impl_json_writer_create(128,0);
|
||||
wfp_impl_json_writer_object_begin(writer);
|
||||
|
||||
wfp_impl_json_writer_object_key(writer, "a");
|
||||
wfp_impl_json_writer_object_begin(writer);
|
||||
wfp_impl_json_writer_object_key(writer, "b");
|
||||
wfp_impl_json_writer_object_begin(writer);
|
||||
wfp_impl_json_writer_object_key(writer, "c");
|
||||
wfp_impl_json_writer_object_begin(writer);
|
||||
wfp_impl_json_writer_object_end(writer);
|
||||
wfp_impl_json_writer_object_end(writer);
|
||||
wfp_impl_json_writer_object_end(writer);
|
||||
|
||||
wfp_impl_json_writer_object_end(writer);
|
||||
|
||||
char * data = wfp_impl_json_writer_take_data(writer, nullptr);
|
||||
|
||||
ASSERT_STREQ("{\"a\":{\"b\":{\"c\":{}}}}", data);
|
||||
|
||||
wfp_impl_json_writer_dispose(writer);
|
||||
free(data);
|
||||
}
|
||||
|
||||
TEST(json_writer, escape_string)
|
||||
{
|
||||
wfp_json_writer * writer = wfp_impl_json_writer_create(128,0);
|
||||
wfp_impl_json_writer_write_string(writer, "\"\\/\b\f\n\r\t");
|
||||
|
||||
char * data = wfp_impl_json_writer_take_data(writer, nullptr);
|
||||
|
||||
ASSERT_STREQ("\"\\\"\\\\/\\b\\f\\n\\r\\t\"", data);
|
||||
|
||||
wfp_impl_json_writer_dispose(writer);
|
||||
free(data);
|
||||
}
|
||||
|
||||
TEST(json_writer, write_bytes)
|
||||
{
|
||||
wfp_json_writer * writer = wfp_impl_json_writer_create(128,0);
|
||||
wfp_impl_json_writer_write_bytes(writer, "1234", 4);
|
||||
|
||||
char * data = wfp_impl_json_writer_take_data(writer, nullptr);
|
||||
|
||||
ASSERT_STREQ("\"MTIzNA==\"", data);
|
||||
|
||||
wfp_impl_json_writer_dispose(writer);
|
||||
free(data);
|
||||
}
|
@ -170,7 +170,6 @@ public:
|
||||
{
|
||||
std::string response_text = future.get();
|
||||
result = json_loadb(response_text.c_str(), response_text.size(), 0, nullptr);
|
||||
|
||||
std::unique_lock<std::mutex> lock(mutex);
|
||||
message = nullptr;
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user