31e6dbee5fc7d6c33b44c75c7e18ea576f44184bTimo Sirainen#ifndef JSON_TREE_H
31e6dbee5fc7d6c33b44c75c7e18ea576f44184bTimo Sirainen#define JSON_TREE_H
31e6dbee5fc7d6c33b44c75c7e18ea576f44184bTimo Sirainen
31e6dbee5fc7d6c33b44c75c7e18ea576f44184bTimo Sirainen#include "json-parser.h"
31e6dbee5fc7d6c33b44c75c7e18ea576f44184bTimo Sirainen
fcd3d6214ce1b8169b6481c78e02d9054901fed3Phil Carmody/* Direct access to this structure is not encouraged, use the inline
fcd3d6214ce1b8169b6481c78e02d9054901fed3Phil Carmody function accessors where possible, so that the implementation
fcd3d6214ce1b8169b6481c78e02d9054901fed3Phil Carmody details can remain fluid, or, even better, hidden. */
31e6dbee5fc7d6c33b44c75c7e18ea576f44184bTimo Sirainenstruct json_tree_node {
31e6dbee5fc7d6c33b44c75c7e18ea576f44184bTimo Sirainen /* object key, or NULL if we're in a list */
31e6dbee5fc7d6c33b44c75c7e18ea576f44184bTimo Sirainen const char *key;
31e6dbee5fc7d6c33b44c75c7e18ea576f44184bTimo Sirainen struct json_tree_node *parent, *next;
31e6dbee5fc7d6c33b44c75c7e18ea576f44184bTimo Sirainen
31e6dbee5fc7d6c33b44c75c7e18ea576f44184bTimo Sirainen enum json_type value_type;
31e6dbee5fc7d6c33b44c75c7e18ea576f44184bTimo Sirainen struct {
31e6dbee5fc7d6c33b44c75c7e18ea576f44184bTimo Sirainen /* for JSON_TYPE_OBJECT and JSON_TYPE_ARRAY */
31e6dbee5fc7d6c33b44c75c7e18ea576f44184bTimo Sirainen struct json_tree_node *child;
31e6dbee5fc7d6c33b44c75c7e18ea576f44184bTimo Sirainen /* for other types */
31e6dbee5fc7d6c33b44c75c7e18ea576f44184bTimo Sirainen const char *str;
31e6dbee5fc7d6c33b44c75c7e18ea576f44184bTimo Sirainen } value;
31e6dbee5fc7d6c33b44c75c7e18ea576f44184bTimo Sirainen};
fcd3d6214ce1b8169b6481c78e02d9054901fed3Phil Carmodystatic inline ATTR_PURE const struct json_tree_node *json_tree_get_child(const struct json_tree_node *node)
fcd3d6214ce1b8169b6481c78e02d9054901fed3Phil Carmody{
fcd3d6214ce1b8169b6481c78e02d9054901fed3Phil Carmody return node->value.child;
fcd3d6214ce1b8169b6481c78e02d9054901fed3Phil Carmody}
fcd3d6214ce1b8169b6481c78e02d9054901fed3Phil Carmodystatic inline ATTR_PURE const char *json_tree_get_value_str(const struct json_tree_node *node)
fcd3d6214ce1b8169b6481c78e02d9054901fed3Phil Carmody{
fcd3d6214ce1b8169b6481c78e02d9054901fed3Phil Carmody return node->value.str;
fcd3d6214ce1b8169b6481c78e02d9054901fed3Phil Carmody}
fcd3d6214ce1b8169b6481c78e02d9054901fed3Phil Carmody
fcd3d6214ce1b8169b6481c78e02d9054901fed3Phil Carmody/* You can build a list or an object, nothing else. */
fcd3d6214ce1b8169b6481c78e02d9054901fed3Phil Carmodystruct json_tree *json_tree_init_type(enum json_type container);
fcd3d6214ce1b8169b6481c78e02d9054901fed3Phil Carmodystatic inline struct json_tree *json_tree_init(void)
fcd3d6214ce1b8169b6481c78e02d9054901fed3Phil Carmody{
fcd3d6214ce1b8169b6481c78e02d9054901fed3Phil Carmody return json_tree_init_type(JSON_TYPE_OBJECT);
fcd3d6214ce1b8169b6481c78e02d9054901fed3Phil Carmody}
fcd3d6214ce1b8169b6481c78e02d9054901fed3Phil Carmodystatic inline struct json_tree *json_tree_init_array(void)
fcd3d6214ce1b8169b6481c78e02d9054901fed3Phil Carmody{
fcd3d6214ce1b8169b6481c78e02d9054901fed3Phil Carmody return json_tree_init_type(JSON_TYPE_ARRAY);
fcd3d6214ce1b8169b6481c78e02d9054901fed3Phil Carmody}
31e6dbee5fc7d6c33b44c75c7e18ea576f44184bTimo Sirainen
31e6dbee5fc7d6c33b44c75c7e18ea576f44184bTimo Sirainenvoid json_tree_deinit(struct json_tree **tree);
31e6dbee5fc7d6c33b44c75c7e18ea576f44184bTimo Sirainen
31e6dbee5fc7d6c33b44c75c7e18ea576f44184bTimo Sirainen/* Append data to a tree. The type/value should normally come from json-parser.
31e6dbee5fc7d6c33b44c75c7e18ea576f44184bTimo Sirainen Returns 0 on success, -1 if the input was invalid (which should never happen
31e6dbee5fc7d6c33b44c75c7e18ea576f44184bTimo Sirainen if it's coming from json-parser). */
31e6dbee5fc7d6c33b44c75c7e18ea576f44184bTimo Sirainenint json_tree_append(struct json_tree *tree, enum json_type type,
31e6dbee5fc7d6c33b44c75c7e18ea576f44184bTimo Sirainen const char *value);
31e6dbee5fc7d6c33b44c75c7e18ea576f44184bTimo Sirainen
31e6dbee5fc7d6c33b44c75c7e18ea576f44184bTimo Sirainen/* Return the root node. */
fcd3d6214ce1b8169b6481c78e02d9054901fed3Phil Carmodyconst struct json_tree_node *
fcd3d6214ce1b8169b6481c78e02d9054901fed3Phil Carmodyjson_tree_root(const struct json_tree *tree);
fcd3d6214ce1b8169b6481c78e02d9054901fed3Phil Carmody/* Find a node with the specified key from an OBJECT node */
fcd3d6214ce1b8169b6481c78e02d9054901fed3Phil Carmodyconst struct json_tree_node *
fcd3d6214ce1b8169b6481c78e02d9054901fed3Phil Carmodyjson_tree_find_key(const struct json_tree_node *node, const char *key);
31e6dbee5fc7d6c33b44c75c7e18ea576f44184bTimo Sirainen/* Find an object node (from an array), which contains the specified key=value
31e6dbee5fc7d6c33b44c75c7e18ea576f44184bTimo Sirainen in its values. */
fcd3d6214ce1b8169b6481c78e02d9054901fed3Phil Carmodyconst struct json_tree_node *
fcd3d6214ce1b8169b6481c78e02d9054901fed3Phil Carmodyjson_tree_find_child_with(const struct json_tree_node *node,
31e6dbee5fc7d6c33b44c75c7e18ea576f44184bTimo Sirainen const char *key, const char *value);
31e6dbee5fc7d6c33b44c75c7e18ea576f44184bTimo Sirainen
31e6dbee5fc7d6c33b44c75c7e18ea576f44184bTimo Sirainen#endif