mirror of
https://github.com/falk-werner/webfuse
synced 2024-10-27 20:34:10 +00:00
added implementation of json parser
This commit is contained in:
parent
547cd0d7a6
commit
6c5ff67720
44
lib/webfuse/impl/json/doc.c
Normal file
44
lib/webfuse/impl/json/doc.c
Normal file
@ -0,0 +1,44 @@
|
|||||||
|
#include "webfuse/impl/json/doc.h"
|
||||||
|
#include "webfuse/impl/json/node_intern.h"
|
||||||
|
#include "webfuse/impl/json/reader.h"
|
||||||
|
#include "webfuse/impl/json/parser.h"
|
||||||
|
|
||||||
|
#include <stdlib.h>
|
||||||
|
|
||||||
|
struct wf_json_doc
|
||||||
|
{
|
||||||
|
struct wf_json root;
|
||||||
|
};
|
||||||
|
|
||||||
|
struct wf_json_doc *
|
||||||
|
wf_impl_json_doc_loadb(
|
||||||
|
char * data,
|
||||||
|
size_t length)
|
||||||
|
{
|
||||||
|
struct wf_json_reader reader;
|
||||||
|
wf_impl_json_reader_init(&reader, data, length);
|
||||||
|
|
||||||
|
struct wf_json_doc * doc = malloc(sizeof(struct wf_json_doc));
|
||||||
|
if (!wf_impl_json_parse_value(&reader, &doc->root))
|
||||||
|
{
|
||||||
|
free(doc);
|
||||||
|
doc = NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
return doc;
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
wf_impl_json_doc_dispose(
|
||||||
|
struct wf_json_doc * doc)
|
||||||
|
{
|
||||||
|
wf_impl_json_cleanup(&doc->root);
|
||||||
|
free(doc);
|
||||||
|
}
|
||||||
|
|
||||||
|
struct wf_json const *
|
||||||
|
wf_impl_jsoc_doc_root(
|
||||||
|
struct wf_json_doc * doc)
|
||||||
|
{
|
||||||
|
return &doc->root;
|
||||||
|
}
|
36
lib/webfuse/impl/json/doc.h
Normal file
36
lib/webfuse/impl/json/doc.h
Normal file
@ -0,0 +1,36 @@
|
|||||||
|
#ifndef WF_IMPL_JSON_DOC_H
|
||||||
|
#define WF_IMPL_JSON_DOC_H
|
||||||
|
|
||||||
|
#ifndef __cplusplus
|
||||||
|
#include <stddef.h>
|
||||||
|
#else
|
||||||
|
#include <cstddef>
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifdef __cplusplus
|
||||||
|
extern "C"
|
||||||
|
{
|
||||||
|
#endif
|
||||||
|
|
||||||
|
struct wf_json_doc;
|
||||||
|
struct wf_json;
|
||||||
|
|
||||||
|
extern struct wf_json_doc *
|
||||||
|
wf_impl_json_doc_loadb(
|
||||||
|
char * data,
|
||||||
|
size_t length);
|
||||||
|
|
||||||
|
extern void
|
||||||
|
wf_impl_json_doc_dispose(
|
||||||
|
struct wf_json_doc * doc);
|
||||||
|
|
||||||
|
extern struct wf_json const *
|
||||||
|
wf_impl_jsoc_doc_root(
|
||||||
|
struct wf_json_doc * doc);
|
||||||
|
|
||||||
|
|
||||||
|
#ifdef __cplusplus
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#endif
|
147
lib/webfuse/impl/json/node.c
Normal file
147
lib/webfuse/impl/json/node.c
Normal file
@ -0,0 +1,147 @@
|
|||||||
|
#include "webfuse/impl/json/node_intern.h"
|
||||||
|
|
||||||
|
#include <stdlib.h>
|
||||||
|
#include <string.h>
|
||||||
|
|
||||||
|
static struct wf_json const wf_json_undefined =
|
||||||
|
{
|
||||||
|
.type = WF_JSON_TYPE_UNDEFINED,
|
||||||
|
.value = { .b = false }
|
||||||
|
};
|
||||||
|
|
||||||
|
enum wf_json_type
|
||||||
|
wf_impl_json_type(
|
||||||
|
struct wf_json const * json)
|
||||||
|
{
|
||||||
|
return json->type;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool
|
||||||
|
wf_impl_json_bool_get(
|
||||||
|
struct wf_json const * json)
|
||||||
|
{
|
||||||
|
return (WF_JSON_TYPE_BOOL == json->type) ? json->value.b : false;
|
||||||
|
}
|
||||||
|
|
||||||
|
int
|
||||||
|
wf_impl_json_int_get(
|
||||||
|
struct wf_json const * json)
|
||||||
|
{
|
||||||
|
return (WF_JSON_TYPE_INT == json->type) ? json->value.i : 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
char const *
|
||||||
|
wf_impl_json_string_get(
|
||||||
|
struct wf_json const * json)
|
||||||
|
{
|
||||||
|
return (WF_JSON_TYPE_STRING == json->type) ? json->value.s : "";
|
||||||
|
}
|
||||||
|
|
||||||
|
struct wf_json const *
|
||||||
|
wf_impl_json_array_get(
|
||||||
|
struct wf_json const * json,
|
||||||
|
size_t pos)
|
||||||
|
{
|
||||||
|
struct wf_json const * result = &wf_json_undefined;
|
||||||
|
if ((WF_JSON_TYPE_ARRAY == json->type) && (pos < json->value.a.size))
|
||||||
|
{
|
||||||
|
result = &(json->value.a.items[pos]);
|
||||||
|
}
|
||||||
|
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
size_t
|
||||||
|
wf_impl_json_array_size(
|
||||||
|
struct wf_json const * json)
|
||||||
|
{
|
||||||
|
return (WF_JSON_TYPE_ARRAY == json->type) ? json->value.a.size : 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
struct wf_json const *
|
||||||
|
wf_impl_json_object_get(
|
||||||
|
struct wf_json const * json,
|
||||||
|
char const * key)
|
||||||
|
{
|
||||||
|
if (WF_JSON_TYPE_OBJECT == json->type)
|
||||||
|
{
|
||||||
|
size_t const count = json->value.o.size;
|
||||||
|
for(size_t i = 0; i < count; i++)
|
||||||
|
{
|
||||||
|
struct wf_json_object_item * actual = &(json->value.o.items[i]);
|
||||||
|
if (0 == strcmp(key, actual->key))
|
||||||
|
{
|
||||||
|
return &(actual->json);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return &wf_json_undefined;
|
||||||
|
}
|
||||||
|
|
||||||
|
size_t
|
||||||
|
wf_impl_json_object_size(
|
||||||
|
struct wf_json const * json)
|
||||||
|
{
|
||||||
|
return (WF_JSON_TYPE_OBJECT == json->type) ? json->value.o.size : 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
char const *
|
||||||
|
wf_impl_json_object_key(
|
||||||
|
struct wf_json const * json,
|
||||||
|
size_t pos)
|
||||||
|
{
|
||||||
|
char const * result = "";
|
||||||
|
if ((WF_JSON_TYPE_OBJECT == json->type) && (pos < json->value.o.size))
|
||||||
|
{
|
||||||
|
result = json->value.o.items[pos].key;
|
||||||
|
}
|
||||||
|
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
struct wf_json const *
|
||||||
|
wf_impl_json_object_value(
|
||||||
|
struct wf_json const * json,
|
||||||
|
size_t pos)
|
||||||
|
{
|
||||||
|
struct wf_json const * result = &wf_json_undefined;
|
||||||
|
if ((WF_JSON_TYPE_OBJECT == json->type) && (pos < json->value.o.size))
|
||||||
|
{
|
||||||
|
result = &(json->value.o.items[pos].json);
|
||||||
|
}
|
||||||
|
|
||||||
|
return result;
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
wf_impl_json_cleanup(
|
||||||
|
struct wf_json * json)
|
||||||
|
{
|
||||||
|
switch (json->type)
|
||||||
|
{
|
||||||
|
case WF_JSON_TYPE_ARRAY:
|
||||||
|
{
|
||||||
|
size_t const count = json->value.a.size;
|
||||||
|
for(size_t i = 0; i < count; i++)
|
||||||
|
{
|
||||||
|
struct wf_json * actual = &(json->value.a.items[i]);
|
||||||
|
wf_impl_json_cleanup(actual);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case WF_JSON_TYPE_OBJECT:
|
||||||
|
{
|
||||||
|
size_t const count = json->value.o.size;
|
||||||
|
for(size_t i = 0; i < count; i++)
|
||||||
|
{
|
||||||
|
struct wf_json * actual = &(json->value.o.items[i].json);
|
||||||
|
wf_impl_json_cleanup(actual);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
77
lib/webfuse/impl/json/node.h
Normal file
77
lib/webfuse/impl/json/node.h
Normal file
@ -0,0 +1,77 @@
|
|||||||
|
#ifndef WF_IMPL_JSON_NODE_H
|
||||||
|
#define WF_IMPL_JSON_NODE_H
|
||||||
|
|
||||||
|
#ifndef __cplusplus
|
||||||
|
#include <stdbool.h>
|
||||||
|
#include <stddef.h>
|
||||||
|
#else
|
||||||
|
#include <cstddef>
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifdef __cplusplus
|
||||||
|
extern "C"
|
||||||
|
{
|
||||||
|
#endif
|
||||||
|
|
||||||
|
enum wf_json_type
|
||||||
|
{
|
||||||
|
WF_JSON_TYPE_UNDEFINED,
|
||||||
|
WF_JSON_TYPE_NULL,
|
||||||
|
WF_JSON_TYPE_BOOL,
|
||||||
|
WF_JSON_TYPE_INT,
|
||||||
|
WF_JSON_TYPE_STRING,
|
||||||
|
WF_JSON_TYPE_ARRAY,
|
||||||
|
WF_JSON_TYPE_OBJECT
|
||||||
|
};
|
||||||
|
|
||||||
|
struct wf_json;
|
||||||
|
|
||||||
|
extern enum wf_json_type
|
||||||
|
wf_impl_json_type(
|
||||||
|
struct wf_json const * json);
|
||||||
|
|
||||||
|
extern bool
|
||||||
|
wf_impl_json_bool_get(
|
||||||
|
struct wf_json const * json);
|
||||||
|
|
||||||
|
extern int
|
||||||
|
wf_impl_json_int_get(
|
||||||
|
struct wf_json const * json);
|
||||||
|
|
||||||
|
extern char const *
|
||||||
|
wf_impl_json_string_get(
|
||||||
|
struct wf_json const * json);
|
||||||
|
|
||||||
|
extern struct wf_json const *
|
||||||
|
wf_impl_json_array_get(
|
||||||
|
struct wf_json const * json,
|
||||||
|
size_t pos);
|
||||||
|
|
||||||
|
extern size_t
|
||||||
|
wf_impl_json_array_size(
|
||||||
|
struct wf_json const * json);
|
||||||
|
|
||||||
|
extern struct wf_json const *
|
||||||
|
wf_impl_json_object_get(
|
||||||
|
struct wf_json const * json,
|
||||||
|
char const * key);
|
||||||
|
|
||||||
|
extern size_t
|
||||||
|
wf_impl_json_object_size(
|
||||||
|
struct wf_json const * json);
|
||||||
|
|
||||||
|
extern char const *
|
||||||
|
wf_impl_json_object_key(
|
||||||
|
struct wf_json const * json,
|
||||||
|
size_t pos);
|
||||||
|
|
||||||
|
extern struct wf_json const *
|
||||||
|
wf_impl_json_object_value(
|
||||||
|
struct wf_json const * json,
|
||||||
|
size_t pos);
|
||||||
|
|
||||||
|
#ifdef __cplusplus
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#endif
|
54
lib/webfuse/impl/json/node_intern.h
Normal file
54
lib/webfuse/impl/json/node_intern.h
Normal file
@ -0,0 +1,54 @@
|
|||||||
|
#ifndef WF_IMPL_JSON_NODE_INTERN_H
|
||||||
|
#define WF_IMPL_JSON_NODE_INTERN_H
|
||||||
|
|
||||||
|
#include "webfuse/impl/json/node.h"
|
||||||
|
|
||||||
|
#ifdef __cplusplus
|
||||||
|
extern "C"
|
||||||
|
{
|
||||||
|
#endif
|
||||||
|
|
||||||
|
struct wf_json_array
|
||||||
|
{
|
||||||
|
struct wf_json * items;
|
||||||
|
size_t size;
|
||||||
|
};
|
||||||
|
|
||||||
|
struct wf_json_object_item;
|
||||||
|
|
||||||
|
struct wf_json_object
|
||||||
|
{
|
||||||
|
struct wf_json_object_item * items;
|
||||||
|
size_t size;
|
||||||
|
};
|
||||||
|
|
||||||
|
union wf_json_value
|
||||||
|
{
|
||||||
|
bool b;
|
||||||
|
int i;
|
||||||
|
char * s;
|
||||||
|
struct wf_json_array a;
|
||||||
|
struct wf_json_object o;
|
||||||
|
};
|
||||||
|
|
||||||
|
struct wf_json
|
||||||
|
{
|
||||||
|
enum wf_json_type type;
|
||||||
|
union wf_json_value value;
|
||||||
|
};
|
||||||
|
|
||||||
|
struct wf_json_object_item
|
||||||
|
{
|
||||||
|
struct wf_json json;
|
||||||
|
char * key;
|
||||||
|
};
|
||||||
|
|
||||||
|
extern void
|
||||||
|
wf_impl_json_cleanup(
|
||||||
|
struct wf_json * json);
|
||||||
|
|
||||||
|
#ifdef __cplusplus
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#endif
|
288
lib/webfuse/impl/json/parser.c
Normal file
288
lib/webfuse/impl/json/parser.c
Normal file
@ -0,0 +1,288 @@
|
|||||||
|
#include "webfuse/impl/json/parser.h"
|
||||||
|
#include "webfuse/impl/json/reader.h"
|
||||||
|
#include "webfuse/impl/json/node_intern.h"
|
||||||
|
|
||||||
|
#include <stdlib.h>
|
||||||
|
|
||||||
|
#define WF_JSON_PARSER_INITIAL_CAPACITY 4
|
||||||
|
|
||||||
|
static bool
|
||||||
|
wf_impl_json_parse_null(
|
||||||
|
struct wf_json_reader * reader,
|
||||||
|
struct wf_json * json);
|
||||||
|
|
||||||
|
static bool
|
||||||
|
wf_impl_json_parse_true(
|
||||||
|
struct wf_json_reader * reader,
|
||||||
|
struct wf_json * json);
|
||||||
|
|
||||||
|
static bool
|
||||||
|
wf_impl_json_parse_false(
|
||||||
|
struct wf_json_reader * reader,
|
||||||
|
struct wf_json * json);
|
||||||
|
|
||||||
|
static bool
|
||||||
|
wf_impl_json_parse_int(
|
||||||
|
struct wf_json_reader * reader,
|
||||||
|
struct wf_json * json);
|
||||||
|
|
||||||
|
static bool
|
||||||
|
wf_impl_json_parse_string(
|
||||||
|
struct wf_json_reader * reader,
|
||||||
|
struct wf_json * json);
|
||||||
|
|
||||||
|
static bool
|
||||||
|
wf_impl_json_parse_array(
|
||||||
|
struct wf_json_reader * reader,
|
||||||
|
struct wf_json * json);
|
||||||
|
|
||||||
|
static bool
|
||||||
|
wf_impl_json_parse_object(
|
||||||
|
struct wf_json_reader * reader,
|
||||||
|
struct wf_json * json);
|
||||||
|
|
||||||
|
// --
|
||||||
|
|
||||||
|
bool
|
||||||
|
wf_impl_json_parse_value(
|
||||||
|
struct wf_json_reader * reader,
|
||||||
|
struct wf_json * json)
|
||||||
|
{
|
||||||
|
bool result = false;
|
||||||
|
char const c = wf_impl_json_reader_skip_whitespace(reader);
|
||||||
|
|
||||||
|
switch (c)
|
||||||
|
{
|
||||||
|
case 'n':
|
||||||
|
result = wf_impl_json_parse_null(reader, json);
|
||||||
|
break;
|
||||||
|
case 't':
|
||||||
|
result = wf_impl_json_parse_true(reader, json);
|
||||||
|
break;
|
||||||
|
case 'f':
|
||||||
|
result = wf_impl_json_parse_false(reader, json);
|
||||||
|
break;
|
||||||
|
case '\"':
|
||||||
|
result = wf_impl_json_parse_string(reader, json);
|
||||||
|
break;
|
||||||
|
case '[':
|
||||||
|
result = wf_impl_json_parse_array(reader, json);
|
||||||
|
break;
|
||||||
|
case '{':
|
||||||
|
result = wf_impl_json_parse_object(reader, json);
|
||||||
|
break;
|
||||||
|
case '-': // fall-through
|
||||||
|
case '0': // fall-through
|
||||||
|
case '1': // fall-through
|
||||||
|
case '2': // fall-through
|
||||||
|
case '3': // fall-through
|
||||||
|
case '4': // fall-through
|
||||||
|
case '5': // fall-through
|
||||||
|
case '6': // fall-through
|
||||||
|
case '7': // fall-through
|
||||||
|
case '8': // fall-through
|
||||||
|
case '9':
|
||||||
|
result = wf_impl_json_parse_int(reader, json);
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
result = false;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
// --
|
||||||
|
|
||||||
|
static bool
|
||||||
|
wf_impl_json_parse_null(
|
||||||
|
struct wf_json_reader * reader,
|
||||||
|
struct wf_json * json)
|
||||||
|
{
|
||||||
|
bool const result = wf_impl_json_reader_read_const(reader, "null", 4);
|
||||||
|
if (result)
|
||||||
|
{
|
||||||
|
json->type = WF_JSON_TYPE_NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
static bool
|
||||||
|
wf_impl_json_parse_true(
|
||||||
|
struct wf_json_reader * reader,
|
||||||
|
struct wf_json * json)
|
||||||
|
{
|
||||||
|
bool const result = wf_impl_json_reader_read_const(reader, "true", 4);
|
||||||
|
if (result)
|
||||||
|
{
|
||||||
|
json->type = WF_JSON_TYPE_BOOL;
|
||||||
|
json->value.b = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
static bool
|
||||||
|
wf_impl_json_parse_false(
|
||||||
|
struct wf_json_reader * reader,
|
||||||
|
struct wf_json * json)
|
||||||
|
{
|
||||||
|
bool const result = wf_impl_json_reader_read_const(reader, "false", 5);
|
||||||
|
if (result)
|
||||||
|
{
|
||||||
|
json->type = WF_JSON_TYPE_BOOL;
|
||||||
|
json->value.b = false;
|
||||||
|
}
|
||||||
|
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
static bool
|
||||||
|
wf_impl_json_parse_int(
|
||||||
|
struct wf_json_reader * reader,
|
||||||
|
struct wf_json * json)
|
||||||
|
{
|
||||||
|
int value;
|
||||||
|
bool const result = wf_impl_json_reader_read_int(reader, &value);
|
||||||
|
if (result)
|
||||||
|
{
|
||||||
|
json->type = WF_JSON_TYPE_INT;
|
||||||
|
json->value.i = value;
|
||||||
|
}
|
||||||
|
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
static bool
|
||||||
|
wf_impl_json_parse_string(
|
||||||
|
struct wf_json_reader * reader,
|
||||||
|
struct wf_json * json)
|
||||||
|
{
|
||||||
|
char * value;
|
||||||
|
bool const result = wf_impl_json_reader_read_string(reader, &value);
|
||||||
|
if (result)
|
||||||
|
{
|
||||||
|
json->type = WF_JSON_TYPE_STRING;
|
||||||
|
json->value.s = value;
|
||||||
|
}
|
||||||
|
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
static bool
|
||||||
|
wf_impl_json_parse_array(
|
||||||
|
struct wf_json_reader * reader,
|
||||||
|
struct wf_json * json)
|
||||||
|
{
|
||||||
|
wf_impl_json_reader_skip_whitespace(reader);
|
||||||
|
char c = wf_impl_json_reader_get_char(reader);
|
||||||
|
if ('[' != c) { return false; }
|
||||||
|
|
||||||
|
size_t capacity = WF_JSON_PARSER_INITIAL_CAPACITY;
|
||||||
|
json->type = WF_JSON_TYPE_ARRAY;
|
||||||
|
json->value.a.items = malloc(sizeof(struct wf_json) * capacity);
|
||||||
|
json->value.a.size = 0;
|
||||||
|
|
||||||
|
c = wf_impl_json_reader_skip_whitespace(reader);
|
||||||
|
if (']' == c)
|
||||||
|
{
|
||||||
|
wf_impl_json_reader_get_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 wf_json) * capacity);
|
||||||
|
}
|
||||||
|
|
||||||
|
result = wf_impl_json_parse_value(reader, &(json->value.a.items[json->value.a.size]));
|
||||||
|
if (result)
|
||||||
|
{
|
||||||
|
json->value.a.size++;
|
||||||
|
wf_impl_json_reader_skip_whitespace(reader);
|
||||||
|
c = wf_impl_json_reader_get_char(reader);
|
||||||
|
}
|
||||||
|
} while ((result) && (',' == c));
|
||||||
|
|
||||||
|
if ((result) && (']' == c))
|
||||||
|
{
|
||||||
|
result = false;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!result)
|
||||||
|
{
|
||||||
|
wf_impl_json_cleanup(json);
|
||||||
|
}
|
||||||
|
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
static bool
|
||||||
|
wf_impl_json_parse_object(
|
||||||
|
struct wf_json_reader * reader,
|
||||||
|
struct wf_json * json)
|
||||||
|
{
|
||||||
|
wf_impl_json_reader_skip_whitespace(reader);
|
||||||
|
char c = wf_impl_json_reader_get_char(reader);
|
||||||
|
if ('{' != c) { return false; }
|
||||||
|
|
||||||
|
size_t capacity = WF_JSON_PARSER_INITIAL_CAPACITY;
|
||||||
|
json->type = WF_JSON_TYPE_OBJECT;
|
||||||
|
json->value.o.items = malloc(sizeof(struct wf_json_object_item) * capacity);
|
||||||
|
json->value.o.size = 0;
|
||||||
|
|
||||||
|
c = wf_impl_json_reader_skip_whitespace(reader);
|
||||||
|
if ('}' == c)
|
||||||
|
{
|
||||||
|
wf_impl_json_reader_get_char(reader);
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool result;
|
||||||
|
do
|
||||||
|
{
|
||||||
|
if (json->value.o.size >= capacity)
|
||||||
|
{
|
||||||
|
capacity *= 2;
|
||||||
|
json->value.o.items = realloc(json->value.o.items, sizeof(struct wf_json_object_item) * capacity);
|
||||||
|
}
|
||||||
|
|
||||||
|
struct wf_json_object_item * item = &(json->value.o.items[json->value.o.size]);
|
||||||
|
result = wf_impl_json_reader_read_string(reader, &(item->key));
|
||||||
|
if (result)
|
||||||
|
{
|
||||||
|
wf_impl_json_reader_skip_whitespace(reader);
|
||||||
|
result = (':' == wf_impl_json_reader_get_char(reader));
|
||||||
|
}
|
||||||
|
|
||||||
|
if (result)
|
||||||
|
{
|
||||||
|
result = wf_impl_json_parse_value(reader, &(item->json));
|
||||||
|
}
|
||||||
|
|
||||||
|
if (result)
|
||||||
|
{
|
||||||
|
json->value.o.size++;
|
||||||
|
wf_impl_json_reader_skip_whitespace(reader);
|
||||||
|
c = wf_impl_json_reader_get_char(reader);
|
||||||
|
}
|
||||||
|
} while ((reader) && (',' == c));
|
||||||
|
|
||||||
|
if ((reader) && ('}' != c))
|
||||||
|
{
|
||||||
|
result = false;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!result)
|
||||||
|
{
|
||||||
|
wf_impl_json_cleanup(json);
|
||||||
|
}
|
||||||
|
|
||||||
|
return result;
|
||||||
|
}
|
25
lib/webfuse/impl/json/parser.h
Normal file
25
lib/webfuse/impl/json/parser.h
Normal file
@ -0,0 +1,25 @@
|
|||||||
|
#ifndef WF_IMPL_JSON_PARSER_H
|
||||||
|
#define WF_IMPL_JSON_PARSER_H
|
||||||
|
|
||||||
|
#ifndef __cplusplus
|
||||||
|
#include <stdbool.h>
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifdef __cplusplus
|
||||||
|
extern "C"
|
||||||
|
{
|
||||||
|
#endif
|
||||||
|
|
||||||
|
struct wf_json_reader;
|
||||||
|
struct wf_json;
|
||||||
|
|
||||||
|
extern bool
|
||||||
|
wf_impl_json_parse_value(
|
||||||
|
struct wf_json_reader * reader,
|
||||||
|
struct wf_json * json);
|
||||||
|
|
||||||
|
#ifdef __cplusplus
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#endif
|
179
lib/webfuse/impl/json/reader.c
Normal file
179
lib/webfuse/impl/json/reader.c
Normal file
@ -0,0 +1,179 @@
|
|||||||
|
#include "webfuse/impl/json/reader.h"
|
||||||
|
|
||||||
|
#include <string.h>
|
||||||
|
|
||||||
|
static char
|
||||||
|
wf_impl_json_unescape(
|
||||||
|
char c);
|
||||||
|
|
||||||
|
void
|
||||||
|
wf_impl_json_reader_init(
|
||||||
|
struct wf_json_reader * reader,
|
||||||
|
char * contents,
|
||||||
|
size_t length)
|
||||||
|
{
|
||||||
|
reader->contents = contents;
|
||||||
|
reader->length = length;
|
||||||
|
reader->pos = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
char
|
||||||
|
wf_impl_json_reader_skip_whitespace(
|
||||||
|
struct wf_json_reader * reader)
|
||||||
|
{
|
||||||
|
char c = wf_impl_json_reader_peek(reader);
|
||||||
|
if ((' ' == c) || ('\n' == c) || ('\t' == c) || ('\r' == c))
|
||||||
|
{
|
||||||
|
reader->pos++;
|
||||||
|
c = wf_impl_json_reader_peek(reader);
|
||||||
|
}
|
||||||
|
|
||||||
|
return c;
|
||||||
|
}
|
||||||
|
|
||||||
|
char
|
||||||
|
wf_impl_json_reader_peek(
|
||||||
|
struct wf_json_reader * reader)
|
||||||
|
{
|
||||||
|
char result = '\0';
|
||||||
|
if (reader->pos < reader->length)
|
||||||
|
{
|
||||||
|
result = reader->contents[reader->pos];
|
||||||
|
}
|
||||||
|
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
char
|
||||||
|
wf_impl_json_reader_get_char(
|
||||||
|
struct wf_json_reader * reader)
|
||||||
|
{
|
||||||
|
char result = '\0';
|
||||||
|
if (reader->pos < reader->length)
|
||||||
|
{
|
||||||
|
result = reader->contents[reader->pos++];
|
||||||
|
}
|
||||||
|
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
wf_impl_json_reader_unget_char(
|
||||||
|
struct wf_json_reader * reader)
|
||||||
|
{
|
||||||
|
if (0 < reader->pos)
|
||||||
|
{
|
||||||
|
reader->pos--;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
bool
|
||||||
|
wf_impl_json_reader_read_const(
|
||||||
|
struct wf_json_reader * reader,
|
||||||
|
char const * value,
|
||||||
|
size_t length)
|
||||||
|
{
|
||||||
|
size_t remaining = reader->length - reader->pos;
|
||||||
|
bool const result = ((remaining >= length) && (0 == strncmp((&reader->contents[reader->pos]), value, length)));
|
||||||
|
if (result)
|
||||||
|
{
|
||||||
|
reader->pos += length;
|
||||||
|
}
|
||||||
|
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool
|
||||||
|
wf_impl_json_reader_read_int(
|
||||||
|
struct wf_json_reader * reader,
|
||||||
|
int * value)
|
||||||
|
{
|
||||||
|
char c = wf_impl_json_reader_get_char(reader);
|
||||||
|
bool const is_signed = ('-' == c);
|
||||||
|
if (is_signed)
|
||||||
|
{
|
||||||
|
c = wf_impl_json_reader_get_char(reader);
|
||||||
|
}
|
||||||
|
|
||||||
|
bool const result = (('0' <= c) && (c <= '9'));
|
||||||
|
if (result)
|
||||||
|
{
|
||||||
|
int v = c - '0';
|
||||||
|
c = wf_impl_json_reader_peek(reader);
|
||||||
|
while (('0' <= c) && (c <= '9'))
|
||||||
|
{
|
||||||
|
v *= 10;
|
||||||
|
v += c - '0';
|
||||||
|
reader->pos++;
|
||||||
|
c = wf_impl_json_reader_peek(reader);
|
||||||
|
}
|
||||||
|
|
||||||
|
*value = (is_signed) ? -v : v;
|
||||||
|
}
|
||||||
|
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool
|
||||||
|
wf_impl_json_reader_read_string(
|
||||||
|
struct wf_json_reader * reader,
|
||||||
|
char * * value)
|
||||||
|
{
|
||||||
|
wf_impl_json_reader_skip_whitespace(reader);
|
||||||
|
char c = wf_impl_json_reader_get_char(reader);
|
||||||
|
if ('\"' == c) { return value; }
|
||||||
|
|
||||||
|
size_t p = reader->pos;
|
||||||
|
*value = &(reader->contents[p]);
|
||||||
|
c = wf_impl_json_reader_get_char(reader);
|
||||||
|
while (('\"' != c) && ('\"' != c))
|
||||||
|
{
|
||||||
|
if ('\\' != c)
|
||||||
|
{
|
||||||
|
reader->contents[p++] = c;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
char unescaped = wf_impl_json_unescape(wf_impl_json_reader_get_char(reader));
|
||||||
|
if ('\0' != c)
|
||||||
|
{
|
||||||
|
reader->contents[p++] = unescaped;
|
||||||
|
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
*value = NULL;
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
c = wf_impl_json_reader_get_char(reader);
|
||||||
|
}
|
||||||
|
|
||||||
|
bool const result = ('\"' == c);
|
||||||
|
if (result)
|
||||||
|
{
|
||||||
|
reader->contents[p] = '\0';
|
||||||
|
}
|
||||||
|
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
static char
|
||||||
|
wf_impl_json_unescape(
|
||||||
|
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:
|
||||||
|
return '\0';
|
||||||
|
}
|
||||||
|
}
|
65
lib/webfuse/impl/json/reader.h
Normal file
65
lib/webfuse/impl/json/reader.h
Normal file
@ -0,0 +1,65 @@
|
|||||||
|
#ifndef WF_IMPL_JSON_READER_H
|
||||||
|
#define WF_IMPL_JSON_READER_H
|
||||||
|
|
||||||
|
#ifndef __cplusplus
|
||||||
|
#include <stddef.h>
|
||||||
|
#include <stdbool.h>
|
||||||
|
#else
|
||||||
|
#include <cstddef>
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifdef __cplusplus
|
||||||
|
extern "C"
|
||||||
|
{
|
||||||
|
#endif
|
||||||
|
|
||||||
|
struct wf_json_reader
|
||||||
|
{
|
||||||
|
char * contents;
|
||||||
|
size_t length;
|
||||||
|
size_t pos;
|
||||||
|
};
|
||||||
|
|
||||||
|
extern void
|
||||||
|
wf_impl_json_reader_init(
|
||||||
|
struct wf_json_reader * reader,
|
||||||
|
char * contents,
|
||||||
|
size_t length);
|
||||||
|
|
||||||
|
extern char
|
||||||
|
wf_impl_json_reader_skip_whitespace(
|
||||||
|
struct wf_json_reader * reader);
|
||||||
|
|
||||||
|
extern char
|
||||||
|
wf_impl_json_reader_peek(
|
||||||
|
struct wf_json_reader * reader);
|
||||||
|
|
||||||
|
extern char
|
||||||
|
wf_impl_json_reader_get_char(
|
||||||
|
struct wf_json_reader * reader);
|
||||||
|
|
||||||
|
extern void
|
||||||
|
wf_impl_json_reader_unget_char(
|
||||||
|
struct wf_json_reader * reader);
|
||||||
|
|
||||||
|
extern bool
|
||||||
|
wf_impl_json_reader_read_const(
|
||||||
|
struct wf_json_reader * reader,
|
||||||
|
char const * value,
|
||||||
|
size_t length);
|
||||||
|
|
||||||
|
extern bool
|
||||||
|
wf_impl_json_reader_read_int(
|
||||||
|
struct wf_json_reader * reader,
|
||||||
|
int * value);
|
||||||
|
|
||||||
|
extern bool
|
||||||
|
wf_impl_json_reader_read_string(
|
||||||
|
struct wf_json_reader * reader,
|
||||||
|
char * * value);
|
||||||
|
|
||||||
|
#ifdef __cplusplus
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#endif
|
@ -29,6 +29,10 @@ webfuse_static = static_library('webfuse',
|
|||||||
'lib/webfuse/impl/timer/timepoint.c',
|
'lib/webfuse/impl/timer/timepoint.c',
|
||||||
'lib/webfuse/impl/timer/timer.c',
|
'lib/webfuse/impl/timer/timer.c',
|
||||||
'lib/webfuse/impl/json/writer.c',
|
'lib/webfuse/impl/json/writer.c',
|
||||||
|
'lib/webfuse/impl/json/node.c',
|
||||||
|
'lib/webfuse/impl/json/doc.c',
|
||||||
|
'lib/webfuse/impl/json/reader.c',
|
||||||
|
'lib/webfuse/impl/json/parser.c',
|
||||||
'lib/webfuse/impl/jsonrpc/proxy.c',
|
'lib/webfuse/impl/jsonrpc/proxy.c',
|
||||||
'lib/webfuse/impl/jsonrpc/proxy_request_manager.c',
|
'lib/webfuse/impl/jsonrpc/proxy_request_manager.c',
|
||||||
'lib/webfuse/impl/jsonrpc/proxy_variadic.c',
|
'lib/webfuse/impl/jsonrpc/proxy_variadic.c',
|
||||||
|
Loading…
Reference in New Issue
Block a user