Skip to content

Commit

Permalink
adt: api refactor
Browse files Browse the repository at this point in the history
  • Loading branch information
zpl-zak committed May 27, 2022
1 parent 88708ec commit 00ab808
Show file tree
Hide file tree
Showing 11 changed files with 409 additions and 155 deletions.
5 changes: 5 additions & 0 deletions CHANGELOG
Original file line number Diff line number Diff line change
@@ -1,3 +1,8 @@
17.0.0 - ADT API changes
zpl_adt_inset_* -> zpl_adt_append_*
zpl_adt_node now holds a parent field, methods no longer require a pointer to the parent
methods are now documented

16.1.1 - fix scientific notation parsing
16.1.0 - introduce ZPL_PARSER_DISABLE_ANALYSIS that disables extra parsing capabilities to offer better raw performance
at a cost of lack of node metadata.
Expand Down
2 changes: 1 addition & 1 deletion code/apps/examples/json.c
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,7 @@ int main(void) {
zpl_adt_set_arr(replace, "i_am_replaced", zpl_heap());

for (size_t i = 0; i < 5; i++)
zpl_adt_inset_int(replace, NULL, (zpl_i64)i+1);
zpl_adt_append_int(replace, NULL, (zpl_i64)i+1);
}

zpl_json_object *first = zpl_adt_alloc_at(&root, 0);
Expand Down
2 changes: 1 addition & 1 deletion code/apps/examples/json_create.c
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@
int main(void) {
zpl_json_object root = {0};
root.cfg_mode = 1;
zpl_adt_make_branch(&root, zpl_heap(), "<root>" /* unused for root object */, ZPL_ADT_TYPE_OBJECT);
zpl_adt_make_branch(&root, zpl_heap(), "<root>" /* unused for root object */, 0);

zpl_random rng={0};
zpl_random_init(&rng);
Expand Down
2 changes: 1 addition & 1 deletion code/apps/examples/json_create_string.c
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@

int main(void) {
zpl_json_object root = {0};
zpl_adt_make_branch(&root, zpl_heap(), "<root>" /* unused for root object */, ZPL_ADT_TYPE_OBJECT);
zpl_adt_make_branch(&root, zpl_heap(), "<root>" /* unused for root object */, 0);

zpl_random rng={0};
zpl_random_init(&rng);
Expand Down
284 changes: 259 additions & 25 deletions code/header/adt.h
Original file line number Diff line number Diff line change
Expand Up @@ -46,8 +46,16 @@ typedef enum zpl_adt_delim_style {
ZPL_ADT_DELIM_STYLE_NEWLINE,
} zpl_adt_delim_style;

typedef enum zpl_adt_error {
ZPL_ADT_ERROR_NONE,
ZPL_ADT_ERROR_INTERNAL,
ZPL_ADT_ERROR_ALREADY_CONVERTED,
ZPL_ADT_ERROR_INVALID_TYPE,
} zpl_adt_error;

typedef struct zpl_adt_node {
char const *name;
struct zpl_adt_node *parent;

/* properties */
zpl_u8 type :4;
Expand Down Expand Up @@ -90,9 +98,33 @@ typedef struct zpl_adt_node {
* real number exponent is limited to 64 digits.
*/

ZPL_DEF zpl_u8 zpl_adt_make_branch(zpl_adt_node *node, zpl_allocator backing, char const *name, zpl_u8 type);
/**
* @brief Initialise an ADT object or array
*
* @param node
* @param backing Memory allocator used for descendants
* @param name Node's name
* @param is_array
* @return error code
*/
ZPL_DEF zpl_u8 zpl_adt_make_branch(zpl_adt_node *node, zpl_allocator backing, char const *name, zpl_b32 is_array);

/**
* @brief Destroy an ADT branch and its descendants
*
* @param node
* @return error code
*/
ZPL_DEF zpl_u8 zpl_adt_destroy_branch(zpl_adt_node *node);

/**
* @brief Initialise an ADT leaf
*
* @param node
* @param name Node's name
* @param type Node's type (use zpl_adt_make_branch for container nodes)
* @return error code
*/
ZPL_DEF zpl_u8 zpl_adt_make_leaf(zpl_adt_node *node, char const *name, zpl_u8 type);


Expand All @@ -101,10 +133,11 @@ ZPL_DEF zpl_u8 zpl_adt_make_leaf(zpl_adt_node *node, char const *name, zpl_u8 ty
*
* This method uses a basic syntax to fetch a node from the ADT. The following features are available
* to retrieve the data:
* 1) "a/b/c" navigates through objects "a" and "b" to get to "c"
* 2) "arr/[foo=123]/bar" iterates over "arr" to find any object with param "foo" that matches the value "123", then gets its field called "bar"
* 3) "arr/3" retrieves the 4th element in "arr"
* 4) "arr/[apple]" retrieves the first element of value "apple" in "arr"
*
* - "a/b/c" navigates through objects "a" and "b" to get to "c"
* - "arr/[foo=123]/bar" iterates over "arr" to find any object with param "foo" that matches the value "123", then gets its field called "bar"
* - "arr/3" retrieves the 4th element in "arr"
* - "arr/[apple]" retrieves the first element of value "apple" in "arr"
*
* @param node ADT node
* @param uri Locator string as described above
Expand All @@ -114,44 +147,220 @@ ZPL_DEF zpl_u8 zpl_adt_make_leaf(zpl_adt_node *node, char const *name, zpl_u8 ty
*/
ZPL_DEF zpl_adt_node *zpl_adt_get(zpl_adt_node *node, char const *uri);

/**
* @brief Find a field node within an object by the given name.
*
* @param node
* @param name
* @param deep_search Perform search recursively
* @return zpl_adt_node * node
*/
ZPL_DEF zpl_adt_node *zpl_adt_find(zpl_adt_node *node, char const *name, zpl_b32 deep_search);

/**
* @brief Allocate an unitialised node within a container at a specified index.
*
* @param parent
* @param index
* @return zpl_adt_node * node
*/
ZPL_DEF zpl_adt_node *zpl_adt_alloc_at(zpl_adt_node *parent, zpl_isize index);

/**
* @brief Allocate an unitialised node within a container.
*
* @param parent
* @return zpl_adt_node * node
*/
ZPL_DEF zpl_adt_node *zpl_adt_alloc(zpl_adt_node *parent);

ZPL_DEF zpl_adt_node *zpl_adt_move_node_at(zpl_adt_node *node, zpl_adt_node *old_parent, zpl_adt_node *new_parent, zpl_isize index);
ZPL_DEF zpl_adt_node *zpl_adt_move_node(zpl_adt_node *node, zpl_adt_node *old_parent, zpl_adt_node *new_parent);
ZPL_DEF void zpl_adt_swap_nodes(zpl_adt_node *node, zpl_adt_node *other_node, zpl_adt_node *parent);
ZPL_DEF void zpl_adt_swap_nodes_between_parents(zpl_adt_node *node, zpl_adt_node *other_node, zpl_adt_node *parent, zpl_adt_node *other_parent);
ZPL_DEF void zpl_adt_remove_node(zpl_adt_node *node, zpl_adt_node *parent);
/**
* @brief Move an existing node to a new container at a specified index.
*
* @param node
* @param new_parent
* @param index
* @return zpl_adt_node * node
*/
ZPL_DEF zpl_adt_node *zpl_adt_move_node_at(zpl_adt_node *node, zpl_adt_node *new_parent, zpl_isize index);

/**
* @brief Move an existing node to a new container.
*
* @param node
* @param new_parent
* @return zpl_adt_node * node
*/
ZPL_DEF zpl_adt_node *zpl_adt_move_node(zpl_adt_node *node, zpl_adt_node *new_parent);

/**
* @brief Swap two nodes.
*
* @param node
* @param other_node
* @return
*/
ZPL_DEF void zpl_adt_swap_nodes(zpl_adt_node *node, zpl_adt_node *other_node);

/**
* @brief Remove node from container.
*
* @param node
* @return
*/
ZPL_DEF void zpl_adt_remove_node(zpl_adt_node *node);

/**
* @brief Initialise a node as an object
*
* @param obj
* @param name
* @param backing
* @return
*/
ZPL_DEF void zpl_adt_set_obj(zpl_adt_node *obj, char const *name, zpl_allocator backing);

/**
* @brief Initialise a node as an array
*
* @param obj
* @param name
* @param backing
* @return
*/
ZPL_DEF void zpl_adt_set_arr(zpl_adt_node *obj, char const *name, zpl_allocator backing);

/**
* @brief Initialise a node as a string
*
* @param obj
* @param name
* @param value
* @return
*/
ZPL_DEF void zpl_adt_set_str(zpl_adt_node *obj, char const *name, char const *value);

/**
* @brief Initialise a node as a float
*
* @param obj
* @param name
* @param value
* @return
*/
ZPL_DEF void zpl_adt_set_flt(zpl_adt_node *obj, char const *name, zpl_f64 value);

/**
* @brief Initialise a node as a signed integer
*
* @param obj
* @param name
* @param value
* @return
*/
ZPL_DEF void zpl_adt_set_int(zpl_adt_node *obj, char const *name, zpl_i64 value);

ZPL_DEF zpl_adt_node *zpl_adt_inset_obj(zpl_adt_node *parent, char const *name);
ZPL_DEF zpl_adt_node *zpl_adt_inset_arr(zpl_adt_node *parent, char const *name);
ZPL_DEF zpl_adt_node *zpl_adt_inset_str(zpl_adt_node *parent, char const *name, char const *value);
ZPL_DEF zpl_adt_node *zpl_adt_inset_flt(zpl_adt_node *parent, char const *name, zpl_f64 value);
ZPL_DEF zpl_adt_node *zpl_adt_inset_int(zpl_adt_node *parent, char const *name, zpl_i64 value);
/**
* @brief Append a new node to a container as an object
*
* @param parent
* @param name
* @return*
*/
ZPL_DEF zpl_adt_node *zpl_adt_append_obj(zpl_adt_node *parent, char const *name);

/**
* @brief Append a new node to a container as an array
*
* @param parent
* @param name
* @return*
*/
ZPL_DEF zpl_adt_node *zpl_adt_append_arr(zpl_adt_node *parent, char const *name);

/**
* @brief Append a new node to a container as a string
*
* @param parent
* @param name
* @param value
* @return*
*/
ZPL_DEF zpl_adt_node *zpl_adt_append_str(zpl_adt_node *parent, char const *name, char const *value);

/**
* @brief Append a new node to a container as a float
*
* @param parent
* @param name
* @param value
* @return*
*/
ZPL_DEF zpl_adt_node *zpl_adt_append_flt(zpl_adt_node *parent, char const *name, zpl_f64 value);

/**
* @brief Append a new node to a container as a signed integer
*
* @param parent
* @param name
* @param value
* @return*
*/
ZPL_DEF zpl_adt_node *zpl_adt_append_int(zpl_adt_node *parent, char const *name, zpl_i64 value);

/* parser helpers */

ZPL_DEF char *zpl_adt_parse_number(zpl_adt_node *node, char* base);
ZPL_DEF void zpl_adt_str_to_number(zpl_adt_node *node);
ZPL_DEF void zpl_adt_print_number(zpl_file *file, zpl_adt_node *node);
ZPL_DEF void zpl_adt_print_string(zpl_file *file, zpl_adt_node *node, char const* escaped_chars, char escape_symbol);
/**
* @brief Parses a text and stores the result into an unitialised node.
*
* @param node
* @param base
* @return*
*/
ZPL_DEF char *zpl_adt_parse_number(zpl_adt_node *node, char* base);

/**
* @brief Parses and converts an existing string node into a number.
*
* @param node
* @return
*/
ZPL_DEF zpl_adt_error zpl_adt_str_to_number(zpl_adt_node *node);

/**
* @brief Prints a number into a file stream.
*
* The provided file handle can also be a memory mapped stream.
*
* @see zpl_file_stream_new
* @param file
* @param node
* @return
*/
ZPL_DEF zpl_adt_error zpl_adt_print_number(zpl_file *file, zpl_adt_node *node);

/**
* @brief Prints a string into a file stream.
*
* The provided file handle can also be a memory mapped stream.
*
* @see zpl_file_stream_new
* @param file
* @param node
* @param escaped_chars
* @param escape_symbol
* @return
*/
ZPL_DEF zpl_adt_error zpl_adt_print_string(zpl_file *file, zpl_adt_node *node, char const *escaped_chars, char const *escape_symbol);

/* extensions */

#if defined(__STDC_VERSION__) && __STDC_VERSION__ >= 201112L
#define zpl_adt_inset(parent, name, value) _Generic((value), \
char*: zpl_adt_inset_str, \
char const*: zpl_adt_inset_str, \
zpl_f64: zpl_adt_inset_flt, \
default: zpl_adt_inset_int)(parent, name, value)
#define zpl_adt_append(parent, name, value) _Generic((value), \
char*: zpl_adt_append_str, \
char const*: zpl_adt_append_str, \
zpl_f64: zpl_adt_append_flt, \
default: zpl_adt_append_int)(parent, name, value)
#define zpl_adt_set(obj, name, value) _Generic((value), \
char*: zpl_adt_set_str, \
char const*: zpl_adt_set_str, \
Expand All @@ -163,7 +372,32 @@ ZPL_DEF void zpl_adt_print_string(zpl_file *file, zpl_adt_node *node, char const

ZPL_DEPRECATED_FOR(13.3.0, zpl_adt_str_to_number)
ZPL_IMPL_INLINE void zpl_adt_str_to_flt(zpl_adt_node *node) {
zpl_adt_str_to_number(node);
(void)zpl_adt_str_to_number(node);
}

ZPL_DEPRECATED_FOR(17.0.0, zpl_adt_append_obj)
ZPL_IMPL_INLINE zpl_adt_node *zpl_adt_inset_obj(zpl_adt_node *parent, char const *name) {
return zpl_adt_append_obj(parent, name);
}

ZPL_DEPRECATED_FOR(17.0.0, zpl_adt_append_arr)
ZPL_IMPL_INLINE zpl_adt_node *zpl_adt_inset_arr(zpl_adt_node *parent, char const *name) {
return zpl_adt_append_arr(parent, name);
}

ZPL_DEPRECATED_FOR(17.0.0, zpl_adt_append_str)
ZPL_IMPL_INLINE zpl_adt_node *zpl_adt_inset_str(zpl_adt_node *parent, char const *name, char const *value) {
return zpl_adt_append_str(parent, name, value);
}

ZPL_DEPRECATED_FOR(17.0.0, zpl_adt_append_flt)
ZPL_IMPL_INLINE zpl_adt_node *zpl_adt_inset_flt(zpl_adt_node *parent, char const *name, zpl_f64 value) {
return zpl_adt_append_flt(parent, name, value);
}

ZPL_DEPRECATED_FOR(17.0.0, zpl_adt_append_int)
ZPL_IMPL_INLINE zpl_adt_node *zpl_adt_inset_int(zpl_adt_node *parent, char const *name, zpl_i64 value) {
return zpl_adt_append_int(parent, name, value);
}

ZPL_END_C_DECLS
Loading

0 comments on commit 00ab808

Please sign in to comment.