mirror of
https://github.com/falk-werner/webfuse
synced 2024-10-27 20:34:10 +00:00
added json writer
This commit is contained in:
parent
2a3d49d576
commit
c0ef47c245
516
lib/webfuse/impl/json/writer.c
Normal file
516
lib/webfuse/impl/json/writer.c
Normal file
@ -0,0 +1,516 @@
|
||||
#include "webfuse/impl/json/writer.h"
|
||||
#include "webfuse/impl/util/base64.h"
|
||||
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <limits.h>
|
||||
|
||||
#define WF_JSON_WRITER_INITIAL_MAX_LEVEL 7
|
||||
|
||||
#define WF_JSON_WRITER_SEPARATOR_SIZE ( 1)
|
||||
#define WF_JSON_WRITER_INT_SIZE (31 + WF_JSON_WRITER_SEPARATOR_SIZE)
|
||||
#define WF_JSON_WRITER_NULL_SIZE ( 4 + WF_JSON_WRITER_SEPARATOR_SIZE)
|
||||
#define WF_JSON_WRITER_BOOL_SIZE ( 5 + WF_JSON_WRITER_SEPARATOR_SIZE)
|
||||
#define WF_JSON_WRITER_ADDITIONAL_STRING_SIZE ( 2 + WF_JSON_WRITER_SEPARATOR_SIZE)
|
||||
#define WF_JSON_WRITER_BEGIN_ARRAY_SIZE ( 1 + WF_JSON_WRITER_SEPARATOR_SIZE)
|
||||
#define WF_JSON_WRITER_END_ARRAY_SIZE ( 1)
|
||||
#define WF_JSON_WRITER_BEGIN_OBJECT_SIZE ( 1 + WF_JSON_WRITER_SEPARATOR_SIZE)
|
||||
#define WF_JSON_WRITER_END_OBJECT_SIZE ( 1)
|
||||
#define WF_JSON_WRITER_ADDITIONAL_OBJECT_KEY_SIZE ( 4)
|
||||
|
||||
enum wf_json_writer_state
|
||||
{
|
||||
WF_JSON_WRITER_STATE_INIT,
|
||||
WF_JSON_WRITER_STATE_ARRAY_FIRST,
|
||||
WF_JSON_WRITER_STATE_ARRAY_NEXT,
|
||||
WF_JSON_WRITER_STATE_OBJECT_FIRST,
|
||||
WF_JSON_WRITER_STATE_OBJECT_NEXT
|
||||
};
|
||||
|
||||
struct wf_json_writer
|
||||
{
|
||||
enum wf_json_writer_state * state;
|
||||
size_t max_level;
|
||||
size_t level;
|
||||
size_t capacity;
|
||||
size_t pre;
|
||||
size_t offset;
|
||||
char * data;
|
||||
char * raw_data;
|
||||
};
|
||||
|
||||
// --
|
||||
|
||||
static char
|
||||
wf_impl_json_writer_get_esc(
|
||||
char c);
|
||||
|
||||
static void
|
||||
wf_impl_json_write_raw_char(
|
||||
struct wf_json_writer * writer,
|
||||
char value);
|
||||
|
||||
static void
|
||||
wf_impl_json_write_raw(
|
||||
struct wf_json_writer * writer,
|
||||
char const * value,
|
||||
size_t length);
|
||||
|
||||
static void
|
||||
wf_impl_json_reserve(
|
||||
struct wf_json_writer * writer,
|
||||
size_t needed);
|
||||
|
||||
static void
|
||||
wf_impl_json_begin_value(
|
||||
struct wf_json_writer * writer);
|
||||
|
||||
static void
|
||||
wf_impl_json_end_value(
|
||||
struct wf_json_writer * writer);
|
||||
|
||||
static void
|
||||
wf_impl_json_push_state(
|
||||
struct wf_json_writer * writer,
|
||||
enum wf_json_writer_state state);
|
||||
|
||||
static void
|
||||
wf_impl_json_pop_state(
|
||||
struct wf_json_writer * writer);
|
||||
|
||||
// --
|
||||
|
||||
struct wf_json_writer *
|
||||
wf_impl_json_writer_create(
|
||||
size_t initial_capacity,
|
||||
size_t pre)
|
||||
{
|
||||
struct wf_json_writer * writer = malloc(sizeof(struct wf_json_writer));
|
||||
writer->level = 0;
|
||||
writer->max_level = WF_JSON_WRITER_INITIAL_MAX_LEVEL;
|
||||
writer->state = malloc((1 + writer->max_level) * sizeof(enum wf_json_writer_state));
|
||||
writer->state[writer->level] = WF_JSON_WRITER_STATE_INIT;
|
||||
writer->pre = pre;
|
||||
writer->offset = 0;
|
||||
writer->capacity = initial_capacity;
|
||||
writer->raw_data = malloc(writer->pre + writer->capacity);
|
||||
writer->data = &(writer->raw_data[pre]);
|
||||
|
||||
return writer;
|
||||
}
|
||||
|
||||
void
|
||||
wf_impl_json_writer_dispose(
|
||||
struct wf_json_writer * writer)
|
||||
{
|
||||
free(writer->raw_data);
|
||||
free(writer->state);
|
||||
free(writer);
|
||||
}
|
||||
|
||||
void
|
||||
wf_impl_json_writer_reset(
|
||||
struct wf_json_writer * writer)
|
||||
{
|
||||
writer->level = 0;
|
||||
writer->state[writer->level] = WF_JSON_WRITER_STATE_INIT;
|
||||
writer->offset = 0;
|
||||
}
|
||||
|
||||
char *
|
||||
wf_impl_json_writer_take(
|
||||
struct wf_json_writer * writer,
|
||||
size_t * size)
|
||||
{
|
||||
wf_impl_json_reserve(writer, 1);
|
||||
writer->data[writer->offset] = '\0';
|
||||
|
||||
writer->raw_data = NULL;
|
||||
|
||||
if (NULL != size)
|
||||
{
|
||||
*size = writer->offset;
|
||||
}
|
||||
|
||||
return writer->data;
|
||||
}
|
||||
|
||||
void
|
||||
wf_impl_json_write_null(
|
||||
struct wf_json_writer * writer)
|
||||
{
|
||||
wf_impl_json_reserve(writer, WF_JSON_WRITER_NULL_SIZE);
|
||||
wf_impl_json_begin_value(writer);
|
||||
wf_impl_json_write_raw(writer, "null", 4);
|
||||
wf_impl_json_end_value(writer);
|
||||
}
|
||||
|
||||
void
|
||||
wf_impl_json_write_bool(
|
||||
struct wf_json_writer * writer,
|
||||
bool value)
|
||||
{
|
||||
wf_impl_json_reserve(writer, WF_JSON_WRITER_BOOL_SIZE);
|
||||
wf_impl_json_begin_value(writer);
|
||||
|
||||
if (value)
|
||||
{
|
||||
wf_impl_json_write_raw(writer, "true", 4);
|
||||
}
|
||||
else
|
||||
{
|
||||
wf_impl_json_write_raw(writer, "false", 5);
|
||||
}
|
||||
|
||||
wf_impl_json_end_value(writer);
|
||||
}
|
||||
|
||||
void
|
||||
wf_impl_json_write_int(
|
||||
struct wf_json_writer * writer,
|
||||
int value)
|
||||
{
|
||||
wf_impl_json_reserve(writer, WF_JSON_WRITER_INT_SIZE);
|
||||
wf_impl_json_begin_value(writer);
|
||||
|
||||
bool const is_signed = (0 > value);
|
||||
char buffer[WF_JSON_WRITER_INT_SIZE];
|
||||
size_t offset = WF_JSON_WRITER_INT_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] = (char) ('0' + actual);
|
||||
value /= 10;
|
||||
} while (0 != value);
|
||||
|
||||
if (is_signed)
|
||||
{
|
||||
buffer[--offset] = '-';
|
||||
}
|
||||
|
||||
size_t const length = (WF_JSON_WRITER_INT_SIZE - offset - 1);
|
||||
wf_impl_json_write_raw(writer, &(buffer[offset]), length);
|
||||
|
||||
wf_impl_json_end_value(writer);
|
||||
}
|
||||
|
||||
void
|
||||
wf_impl_json_write_string(
|
||||
struct wf_json_writer * writer,
|
||||
char const * value)
|
||||
{
|
||||
size_t length = strlen(value);
|
||||
wf_impl_json_reserve(writer, length + WF_JSON_WRITER_ADDITIONAL_STRING_SIZE);
|
||||
wf_impl_json_begin_value(writer);
|
||||
|
||||
wf_impl_json_write_raw_char(writer, '\"');
|
||||
for (size_t i = 0; i < length; i++)
|
||||
{
|
||||
char const c = value[i];
|
||||
if ((' ' <= c) && ('\\' != c) && ('\"' != c))
|
||||
{
|
||||
wf_impl_json_write_raw_char(writer, c);
|
||||
}
|
||||
else
|
||||
{
|
||||
char esc = wf_impl_json_writer_get_esc(c);
|
||||
|
||||
wf_impl_json_reserve(writer, (length - i) + 2);
|
||||
wf_impl_json_write_raw_char(writer, '\\');
|
||||
wf_impl_json_write_raw_char(writer, esc);
|
||||
}
|
||||
|
||||
}
|
||||
wf_impl_json_write_raw_char(writer, '\"');
|
||||
|
||||
wf_impl_json_end_value(writer);
|
||||
}
|
||||
|
||||
void
|
||||
wf_impl_json_write_string_nocheck(
|
||||
struct wf_json_writer * writer,
|
||||
char const * value)
|
||||
{
|
||||
size_t length = strlen(value);
|
||||
wf_impl_json_reserve(writer, length + WF_JSON_WRITER_ADDITIONAL_STRING_SIZE);
|
||||
wf_impl_json_begin_value(writer);
|
||||
|
||||
wf_impl_json_write_raw_char(writer, '\"');
|
||||
wf_impl_json_write_raw(writer, value, length);
|
||||
wf_impl_json_write_raw_char(writer, '\"');
|
||||
|
||||
wf_impl_json_end_value(writer);
|
||||
|
||||
}
|
||||
|
||||
void
|
||||
wf_impl_json_write_bytes(
|
||||
struct wf_json_writer * writer,
|
||||
char const * data,
|
||||
size_t length)
|
||||
{
|
||||
size_t encoded_length = wf_impl_base64_encoded_size(length);
|
||||
wf_impl_json_reserve(writer, length + WF_JSON_WRITER_ADDITIONAL_STRING_SIZE);
|
||||
wf_impl_json_begin_value(writer);
|
||||
|
||||
wf_impl_json_write_raw_char(writer, '\"');
|
||||
wf_impl_base64_encode((uint8_t const *) data, length, &(writer->data[writer->offset]), encoded_length);
|
||||
writer->offset = encoded_length;
|
||||
wf_impl_json_write_raw_char(writer, '\"');
|
||||
|
||||
wf_impl_json_end_value(writer);
|
||||
}
|
||||
|
||||
void
|
||||
wf_impl_json_write_array_begin(
|
||||
struct wf_json_writer * writer)
|
||||
{
|
||||
wf_impl_json_reserve(writer, WF_JSON_WRITER_BEGIN_ARRAY_SIZE);
|
||||
wf_impl_json_begin_value(writer);
|
||||
wf_impl_json_push_state(writer, WF_JSON_WRITER_STATE_ARRAY_FIRST);
|
||||
wf_impl_json_write_raw_char(writer, '[');
|
||||
}
|
||||
|
||||
void
|
||||
wf_impl_json_write_array_end(
|
||||
struct wf_json_writer * writer)
|
||||
{
|
||||
wf_impl_json_reserve(writer, WF_JSON_WRITER_END_ARRAY_SIZE);
|
||||
wf_impl_json_write_raw_char(writer, ']');
|
||||
wf_impl_json_pop_state(writer);
|
||||
wf_impl_json_end_value(writer);
|
||||
}
|
||||
|
||||
void
|
||||
wf_impl_json_write_object_begin(
|
||||
struct wf_json_writer * writer)
|
||||
{
|
||||
wf_impl_json_reserve(writer, WF_JSON_WRITER_BEGIN_OBJECT_SIZE);
|
||||
wf_impl_json_begin_value(writer);
|
||||
wf_impl_json_push_state(writer, WF_JSON_WRITER_STATE_OBJECT_FIRST);
|
||||
wf_impl_json_write_raw_char(writer, '{');
|
||||
}
|
||||
|
||||
void
|
||||
wf_impl_json_write_object_end(
|
||||
struct wf_json_writer * writer)
|
||||
{
|
||||
wf_impl_json_reserve(writer, WF_JSON_WRITER_END_OBJECT_SIZE);
|
||||
wf_impl_json_write_raw_char(writer, '}');
|
||||
wf_impl_json_pop_state(writer);
|
||||
wf_impl_json_end_value(writer);
|
||||
}
|
||||
|
||||
void
|
||||
wf_impl_json_write_object_key(
|
||||
struct wf_json_writer * writer,
|
||||
char const * key)
|
||||
{
|
||||
size_t length = strlen(key);
|
||||
wf_impl_json_reserve(writer, length + WF_JSON_WRITER_ADDITIONAL_OBJECT_KEY_SIZE);
|
||||
|
||||
if (WF_JSON_WRITER_STATE_OBJECT_NEXT == writer->state[writer->level])
|
||||
{
|
||||
wf_impl_json_write_raw_char(writer, ',');
|
||||
}
|
||||
else
|
||||
{
|
||||
writer->state[writer->level] = WF_JSON_WRITER_STATE_OBJECT_NEXT;
|
||||
}
|
||||
|
||||
wf_impl_json_write_raw_char(writer, '\"');
|
||||
wf_impl_json_write_raw(writer, key, length);
|
||||
wf_impl_json_write_raw_char(writer, '\"');
|
||||
wf_impl_json_write_raw_char(writer, ':');
|
||||
}
|
||||
|
||||
void
|
||||
wf_impl_json_write_object_null(
|
||||
struct wf_json_writer * writer,
|
||||
char const * key)
|
||||
{
|
||||
wf_impl_json_write_object_key(writer, key);
|
||||
wf_impl_json_write_null(writer);
|
||||
}
|
||||
|
||||
void
|
||||
wf_impl_json_write_object_bool(
|
||||
struct wf_json_writer * writer,
|
||||
char const * key,
|
||||
bool value)
|
||||
{
|
||||
wf_impl_json_write_object_key(writer, key);
|
||||
wf_impl_json_write_bool(writer, value);
|
||||
}
|
||||
|
||||
void
|
||||
wf_impl_json_write_object_int(
|
||||
struct wf_json_writer * writer,
|
||||
char const * key,
|
||||
int value)
|
||||
{
|
||||
wf_impl_json_write_object_key(writer, key);
|
||||
wf_impl_json_write_int(writer, value);
|
||||
}
|
||||
|
||||
void
|
||||
wf_impl_json_write_object_string(
|
||||
struct wf_json_writer * writer,
|
||||
char const * key,
|
||||
char const * value)
|
||||
{
|
||||
wf_impl_json_write_object_key(writer, key);
|
||||
wf_impl_json_write_string(writer, value);
|
||||
}
|
||||
|
||||
void
|
||||
wf_impl_json_write_object_string_nocheck(
|
||||
struct wf_json_writer * writer,
|
||||
char const * key,
|
||||
char const * value)
|
||||
{
|
||||
wf_impl_json_write_object_key(writer, key);
|
||||
wf_impl_json_write_string_nocheck(writer, value);
|
||||
}
|
||||
|
||||
void
|
||||
wf_impl_json_write_object_bytes(
|
||||
struct wf_json_writer * writer,
|
||||
char const * key,
|
||||
char const * data,
|
||||
size_t length)
|
||||
{
|
||||
wf_impl_json_write_object_key(writer, key);
|
||||
wf_impl_json_write_bytes(writer, data, length);
|
||||
}
|
||||
|
||||
void
|
||||
wf_impl_json_write_object_begin_array(
|
||||
struct wf_json_writer * writer,
|
||||
char const * key)
|
||||
{
|
||||
wf_impl_json_write_object_key(writer, key);
|
||||
wf_impl_json_write_array_begin(writer);
|
||||
}
|
||||
|
||||
void
|
||||
wf_impl_json_write_object_begin_object(
|
||||
struct wf_json_writer * writer,
|
||||
char const * key)
|
||||
{
|
||||
wf_impl_json_write_object_key(writer, key);
|
||||
wf_impl_json_write_array_end(writer);
|
||||
}
|
||||
|
||||
// --
|
||||
|
||||
static char
|
||||
wf_impl_json_writer_get_esc(
|
||||
char c)
|
||||
{
|
||||
switch (c)
|
||||
{
|
||||
case '\b': return 'b';
|
||||
case '\f': return 'f';
|
||||
case '\n': return 'n';
|
||||
case '\r': return 'r';
|
||||
case '\t': return 't';
|
||||
default:
|
||||
return c;
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
wf_impl_json_write_raw_char(
|
||||
struct wf_json_writer * writer,
|
||||
char value)
|
||||
{
|
||||
writer->data[writer->offset++] = value;
|
||||
}
|
||||
|
||||
static void
|
||||
wf_impl_json_write_raw(
|
||||
struct wf_json_writer * writer,
|
||||
char const * value,
|
||||
size_t length)
|
||||
{
|
||||
memcpy(&(writer->data[writer->offset]), value, length);
|
||||
writer->offset += length;
|
||||
}
|
||||
|
||||
static void
|
||||
wf_impl_json_reserve(
|
||||
struct wf_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
|
||||
wf_impl_json_begin_value(
|
||||
struct wf_json_writer * writer)
|
||||
{
|
||||
if (WF_JSON_WRITER_STATE_ARRAY_NEXT == writer->state[writer->level])
|
||||
{
|
||||
wf_impl_json_write_raw_char(writer, ',');
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
wf_impl_json_end_value(
|
||||
struct wf_json_writer * writer)
|
||||
{
|
||||
if (WF_JSON_WRITER_STATE_ARRAY_FIRST == writer->state[writer->level])
|
||||
{
|
||||
writer->state[writer->level] = WF_JSON_WRITER_STATE_ARRAY_NEXT;
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
wf_impl_json_push_state(
|
||||
struct wf_json_writer * writer,
|
||||
enum wf_json_writer_state state)
|
||||
{
|
||||
if (writer->level >= writer->max_level)
|
||||
{
|
||||
writer->max_level *= 2;
|
||||
writer->state = realloc(writer->state, (1 + writer->max_level) * sizeof(enum wf_json_writer_state));
|
||||
}
|
||||
|
||||
writer->level++;
|
||||
writer->state[writer->level] = state;
|
||||
}
|
||||
|
||||
static void
|
||||
wf_impl_json_pop_state(
|
||||
struct wf_json_writer * writer)
|
||||
{
|
||||
if (writer->level > 0)
|
||||
{
|
||||
writer->level--;
|
||||
}
|
||||
}
|
137
lib/webfuse/impl/json/writer.h
Normal file
137
lib/webfuse/impl/json/writer.h
Normal file
@ -0,0 +1,137 @@
|
||||
#ifndef WF_IMPL_JSON_WRITER_H
|
||||
#define WF_IMPL_JSON_WRITER_H
|
||||
|
||||
#ifndef __cplusplus
|
||||
#include <stddef.h>
|
||||
#include <stdbool.h>
|
||||
#else
|
||||
#include <cstddef>
|
||||
#endif
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C"
|
||||
{
|
||||
#endif
|
||||
|
||||
struct wf_json_writer;
|
||||
|
||||
extern struct wf_json_writer *
|
||||
wf_impl_json_writer_create(
|
||||
size_t initial_capacity,
|
||||
size_t pre);
|
||||
|
||||
extern void
|
||||
wf_impl_json_writer_dispose(
|
||||
struct wf_json_writer * writer);
|
||||
|
||||
extern void
|
||||
wf_impl_json_writer_reset(
|
||||
struct wf_json_writer * writer);
|
||||
|
||||
extern char *
|
||||
wf_impl_json_writer_take(
|
||||
struct wf_json_writer * writer,
|
||||
size_t * size);
|
||||
|
||||
extern void
|
||||
wf_impl_json_write_null(
|
||||
struct wf_json_writer * writer);
|
||||
|
||||
extern void
|
||||
wf_impl_json_write_bool(
|
||||
struct wf_json_writer * writer,
|
||||
bool value);
|
||||
|
||||
extern void
|
||||
wf_impl_json_write_int(
|
||||
struct wf_json_writer * writer,
|
||||
int value);
|
||||
|
||||
extern void
|
||||
wf_impl_json_write_string(
|
||||
struct wf_json_writer * writer,
|
||||
char const * value);
|
||||
|
||||
extern void
|
||||
wf_impl_json_write_string_nocheck(
|
||||
struct wf_json_writer * writer,
|
||||
char const * value);
|
||||
|
||||
extern void
|
||||
wf_impl_json_write_bytes(
|
||||
struct wf_json_writer * writer,
|
||||
char const * data,
|
||||
size_t length);
|
||||
|
||||
extern void
|
||||
wf_impl_json_write_array_begin(
|
||||
struct wf_json_writer * writer);
|
||||
|
||||
extern void
|
||||
wf_impl_json_write_array_end(
|
||||
struct wf_json_writer * writer);
|
||||
|
||||
extern void
|
||||
wf_impl_json_write_object_begin(
|
||||
struct wf_json_writer * writer);
|
||||
|
||||
extern void
|
||||
wf_impl_json_write_object_end(
|
||||
struct wf_json_writer * writer);
|
||||
|
||||
extern void
|
||||
wf_impl_json_write_object_key(
|
||||
struct wf_json_writer * writer,
|
||||
char const * key);
|
||||
|
||||
extern void
|
||||
wf_impl_json_write_object_null(
|
||||
struct wf_json_writer * writer,
|
||||
char const * key);
|
||||
|
||||
extern void
|
||||
wf_impl_json_write_object_bool(
|
||||
struct wf_json_writer * writer,
|
||||
char const * key,
|
||||
bool value);
|
||||
|
||||
extern void
|
||||
wf_impl_json_write_object_int(
|
||||
struct wf_json_writer * writer,
|
||||
char const * key,
|
||||
int value);
|
||||
|
||||
extern void
|
||||
wf_impl_json_write_object_string(
|
||||
struct wf_json_writer * writer,
|
||||
char const * key,
|
||||
char const * value);
|
||||
|
||||
extern void
|
||||
wf_impl_json_write_object_string_nocheck(
|
||||
struct wf_json_writer * writer,
|
||||
char const * key,
|
||||
char const * value);
|
||||
|
||||
extern void
|
||||
wf_impl_json_write_object_bytes(
|
||||
struct wf_json_writer * writer,
|
||||
char const * key,
|
||||
char const * data,
|
||||
size_t length);
|
||||
|
||||
extern void
|
||||
wf_impl_json_write_object_begin_array(
|
||||
struct wf_json_writer * writer,
|
||||
char const * key);
|
||||
|
||||
extern void
|
||||
wf_impl_json_write_object_begin_object(
|
||||
struct wf_json_writer * writer,
|
||||
char const * key);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif
|
@ -28,6 +28,7 @@ webfuse_static = static_library('webfuse',
|
||||
'lib/webfuse/impl/timer/manager.c',
|
||||
'lib/webfuse/impl/timer/timepoint.c',
|
||||
'lib/webfuse/impl/timer/timer.c',
|
||||
'lib/webfuse/impl/json/writer.c',
|
||||
'lib/webfuse/impl/jsonrpc/proxy.c',
|
||||
'lib/webfuse/impl/jsonrpc/proxy_request_manager.c',
|
||||
'lib/webfuse/impl/jsonrpc/proxy_variadic.c',
|
||||
@ -115,6 +116,7 @@ test_certs_dep = declare_dependency(
|
||||
sources: [test_server_certs, test_client_certs])
|
||||
|
||||
alltests = executable('alltests',
|
||||
'test/webfuse/json/test_writer.cc',
|
||||
'test/webfuse/jsonrpc/mock_timer_callback.cc',
|
||||
'test/webfuse/jsonrpc/mock_timer.cc',
|
||||
'test/webfuse/jsonrpc/test_is_request.cc',
|
||||
|
196
test/webfuse/json/test_writer.cc
Normal file
196
test/webfuse/json/test_writer.cc
Normal file
@ -0,0 +1,196 @@
|
||||
#include "webfuse/impl/json/writer.h"
|
||||
#include <gtest/gtest.h>
|
||||
#include <cstdlib>
|
||||
#include <climits>
|
||||
|
||||
namespace
|
||||
{
|
||||
|
||||
class writer
|
||||
{
|
||||
public:
|
||||
writer(size_t initial_capacity = 128)
|
||||
: writer_(wf_impl_json_writer_create(initial_capacity, 0))
|
||||
{
|
||||
}
|
||||
|
||||
~writer()
|
||||
{
|
||||
wf_impl_json_writer_dispose(writer_);
|
||||
}
|
||||
|
||||
operator wf_json_writer * ()
|
||||
{
|
||||
return writer_;
|
||||
}
|
||||
|
||||
std::string take()
|
||||
{
|
||||
char * text = wf_impl_json_writer_take(writer_, nullptr);
|
||||
std::string result = text;
|
||||
free(text);
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
private:
|
||||
wf_json_writer * writer_;
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
TEST(json_writer, write_null)
|
||||
{
|
||||
writer writer;
|
||||
|
||||
wf_impl_json_write_null(writer);
|
||||
ASSERT_STREQ("null", writer.take().c_str());
|
||||
}
|
||||
|
||||
TEST(json_writer, write_true)
|
||||
{
|
||||
writer writer;
|
||||
|
||||
wf_impl_json_write_bool(writer, true);
|
||||
ASSERT_STREQ("true", writer.take().c_str());
|
||||
}
|
||||
|
||||
TEST(json_writer, write_false)
|
||||
{
|
||||
writer writer;
|
||||
|
||||
wf_impl_json_write_bool(writer, false);
|
||||
ASSERT_STREQ("false", writer.take().c_str());
|
||||
}
|
||||
|
||||
TEST(json_writer, positive_int)
|
||||
{
|
||||
writer writer;
|
||||
|
||||
wf_impl_json_write_int(writer, 42);
|
||||
ASSERT_STREQ("42", writer.take().c_str());
|
||||
}
|
||||
|
||||
TEST(json_writer, int_max)
|
||||
{
|
||||
writer writer;
|
||||
std::string int_max = std::to_string(INT_MAX);
|
||||
|
||||
wf_impl_json_write_int(writer, INT_MAX);
|
||||
ASSERT_EQ(int_max, writer.take());
|
||||
}
|
||||
|
||||
TEST(json_writer, negative_int)
|
||||
{
|
||||
writer writer;
|
||||
|
||||
wf_impl_json_write_int(writer, -12345);
|
||||
ASSERT_STREQ("-12345", writer.take().c_str());
|
||||
}
|
||||
|
||||
TEST(json_writer, int_min)
|
||||
{
|
||||
writer writer;
|
||||
std::string int_min = std::to_string(INT_MIN);
|
||||
|
||||
wf_impl_json_write_int(writer, INT_MIN);
|
||||
ASSERT_EQ(int_min, writer.take());
|
||||
}
|
||||
|
||||
TEST(json_writer, write_string)
|
||||
{
|
||||
writer writer;
|
||||
|
||||
wf_impl_json_write_string(writer, "brummni");
|
||||
ASSERT_STREQ("\"brummni\"", writer.take().c_str());
|
||||
}
|
||||
|
||||
TEST(json_writer, write_string_escape)
|
||||
{
|
||||
writer writer;
|
||||
|
||||
wf_impl_json_write_string(writer, "_\"_\\_\r_\n_\t_\b_\f_");
|
||||
ASSERT_STREQ("\"_\\\"_\\\\_\\r_\\n_\\t_\\b_\\f_\"", writer.take().c_str());
|
||||
}
|
||||
|
||||
TEST(json_writer, write_string_nocheck)
|
||||
{
|
||||
writer writer;
|
||||
|
||||
wf_impl_json_write_string_nocheck(writer, "_\"_\\_\r_\n_\t_\b_\f_");
|
||||
ASSERT_STREQ("\"_\"_\\_\r_\n_\t_\b_\f_\"", writer.take().c_str());
|
||||
}
|
||||
|
||||
TEST(json_writer, write_empty_array)
|
||||
{
|
||||
writer writer;
|
||||
|
||||
wf_impl_json_write_array_begin(writer);
|
||||
wf_impl_json_write_array_end(writer);
|
||||
ASSERT_STREQ("[]", writer.take().c_str());
|
||||
}
|
||||
|
||||
TEST(json_writer, write_complex_array)
|
||||
{
|
||||
writer writer;
|
||||
|
||||
wf_impl_json_write_array_begin(writer);
|
||||
wf_impl_json_write_null(writer);
|
||||
wf_impl_json_write_bool(writer, true);
|
||||
|
||||
wf_impl_json_write_array_begin(writer);
|
||||
wf_impl_json_write_int(writer, 0);
|
||||
wf_impl_json_write_string(writer, "foo");
|
||||
wf_impl_json_write_array_begin(writer);
|
||||
|
||||
wf_impl_json_write_array_end(writer);
|
||||
wf_impl_json_write_array_end(writer);
|
||||
wf_impl_json_write_array_end(writer);
|
||||
|
||||
ASSERT_STREQ("[null,true,[0,\"foo\",[]]]", writer.take().c_str());
|
||||
}
|
||||
|
||||
TEST(json_writer, write_empty_object)
|
||||
{
|
||||
writer writer;
|
||||
|
||||
wf_impl_json_write_object_begin(writer);
|
||||
wf_impl_json_write_object_end(writer);
|
||||
ASSERT_STREQ("{}", writer.take().c_str());
|
||||
}
|
||||
|
||||
TEST(json_writer, write_comple_object)
|
||||
{
|
||||
writer writer;
|
||||
|
||||
wf_impl_json_write_object_begin(writer);
|
||||
wf_impl_json_write_object_string(writer, "method", "add");
|
||||
wf_impl_json_write_object_begin_array(writer, "params");
|
||||
wf_impl_json_write_int(writer, 1);
|
||||
wf_impl_json_write_int(writer, 2);
|
||||
wf_impl_json_write_array_end(writer);
|
||||
wf_impl_json_write_object_int(writer, "id", 42);
|
||||
wf_impl_json_write_object_end(writer);
|
||||
ASSERT_STREQ("{\"method\":\"add\",\"params\":[1,2],\"id\":42}", writer.take().c_str());
|
||||
}
|
||||
|
||||
TEST(json_writer, write_deep_nested_array)
|
||||
{
|
||||
writer writer;
|
||||
size_t count = 10;
|
||||
std::string expected = "";
|
||||
|
||||
for (size_t i = 0; i < count; i++)
|
||||
{
|
||||
wf_impl_json_write_array_begin(writer);
|
||||
expected += "[";
|
||||
}
|
||||
|
||||
for (size_t i = 0; i < count; i++)
|
||||
{
|
||||
wf_impl_json_write_array_end(writer);
|
||||
expected += "]";
|
||||
}
|
||||
|
||||
ASSERT_EQ(expected, writer.take());
|
||||
}
|
Loading…
Reference in New Issue
Block a user