diff options
| author | dautor <karlo98.m@gmail.com> | 2024-11-16 13:22:54 +0100 |
|---|---|---|
| committer | dautor <karlo98.m@gmail.com> | 2024-11-16 17:54:38 +0100 |
| commit | 47778ccd67cbb3fb70dda706911d3166038ca010 (patch) | |
| tree | 906bf0537d14f5ce8e2528736fb89a3499ada214 /src/base/state.c | |
Import project
Diffstat (limited to 'src/base/state.c')
| -rw-r--r-- | src/base/state.c | 380 |
1 files changed, 380 insertions, 0 deletions
diff --git a/src/base/state.c b/src/base/state.c new file mode 100644 index 0000000..50ebe4e --- /dev/null +++ b/src/base/state.c @@ -0,0 +1,380 @@ +#include "state.h" + +// FREE + +void +Free_endpoint(endpoint *E) +{ + free(E->Address); + free(E->Hook); +} + +void +Free_endpoint_configuration(endpoint_configuration *E) +{ + free(E->Node); + free(E->Interface); +} + +void +Free_link_configuration(link_configuration *E) +{ + Free_endpoint_configuration(E->Peer + 0); + Free_endpoint_configuration(E->Peer + 1); +} + +void +Free_link(link_ *E) +{ + free(E->Name); + Free_link_configuration(&E->Configuration); + Free_endpoint(E->Peer + 0); + Free_endpoint(E->Peer + 1); +} + +void +Free_node_configuration(node_configuration *E) +{ + free(E->Module); + ucl_object_unref(E->Configuration); +} + +void +Free_node(node *E) +{ + free(E->Name); + Free_node_configuration(&E->Configuration); + ucl_object_unref(E->Data); +} + +void +Free_experiment(experiment *E) +{ + for(size_t i = 0; i < E->NodeCount; ++i) Free_node(E->Node + i); + free(E->Node); + for(size_t i = 0; i < E->LinkCount; ++i) Free_link(E->Link + i); + free(E->Link); +} + +// PARSE + +char * +Parse_endpoint(endpoint *E, ucl_object_t const *root, char const *Position) +{ + char *Error; + if(root == NULL || root->type != UCL_OBJECT) + { + if(*Position == '\0') Position = "."; + asprintf(&Error, "%s is not an object", Position); + goto error; + } + ucl_object_t const *address = ucl_object_lookup(root, "address"); + if(address == NULL || address->type != UCL_STRING) + { + asprintf(&Error, "%s.address is not a string", Position); + goto error; + } + ucl_object_t const *hook = ucl_object_lookup(root, "hook"); + if(hook == NULL || hook->type != UCL_STRING) + { + asprintf(&Error, "%s.hook is not a string", Position); + goto error; + } + E->Address = strdup(ucl_object_tostring(address)); + E->Hook = strdup(ucl_object_tostring(hook)); + return NULL; +error: + return Error; +} + +char * +Parse_endpoint_configuration(endpoint_configuration *E, ucl_object_t const *root, char const *Position) +{ + char *Error; + UCL_CHECK_ROOT(OBJECT); + ucl_object_t const *node = ucl_object_lookup(root, "node"); + UCL_CHECK(node, STRING); + ucl_object_t const *interface = ucl_object_lookup(root, "interface"); + UCL_CHECK(interface, STRING); + E->Node = strdup(ucl_object_tostring(node)); + E->Interface = strdup(ucl_object_tostring(interface)); + return NULL; +error: + return Error; +} + +char * +Parse_link_configuration(link_configuration *E, ucl_object_t const *root, char const *Position) +{ + char *Error; + size_t EndpointAt = 0; + UCL_CHECK_ROOT(OBJECT); + ucl_object_t const *peer0 = ucl_object_lookup(root, "peer0"); + { + char *NewPosition; + asprintf(&NewPosition, "%s.peer0", Position); + Error = Parse_endpoint_configuration(&E->Peer[EndpointAt], peer0, NewPosition); + free(NewPosition); + if(Error != NULL) goto error; + ++EndpointAt; + } + ucl_object_t const *peer1 = ucl_object_lookup(root, "peer1"); + { + char *NewPosition; + asprintf(&NewPosition, "%s.peer1", Position); + Error = Parse_endpoint_configuration(&E->Peer[EndpointAt], peer1, NewPosition); + free(NewPosition); + if(Error != NULL) goto error; + ++EndpointAt; + } + return NULL; +error: + for(size_t i = 0; i < EndpointAt; ++i) Free_endpoint_configuration(E->Peer + i); + return Error; +} + +char * +Parse_link(link_ *E, ucl_object_t const *root, char const *Position) +{ + char *Error; + size_t EndpointAt = 0; + bool Configuration = false; + UCL_CHECK_ROOT(OBJECT); + ucl_object_t const *configuration = ucl_object_lookup(root, "configuration"); + { + char *NewPosition; + asprintf(&NewPosition, "%s.configuration", Position); + Error = Parse_link_configuration(&E->Configuration, configuration, NewPosition); + free(NewPosition); + if(Error != NULL) goto error; + Configuration = true; + } + ucl_object_t const *peer0 = ucl_object_lookup(root, "peer0"); + { + char *NewPosition; + asprintf(&NewPosition, "%s.peer0", Position); + Error = Parse_endpoint(E->Peer + EndpointAt, peer0, NewPosition); + free(NewPosition); + if(Error != NULL) goto error; + ++EndpointAt; + } + ucl_object_t const *peer1 = ucl_object_lookup(root, "peer1"); + { + char *NewPosition; + asprintf(&NewPosition, "%s.peer1", Position); + Error = Parse_endpoint(E->Peer + EndpointAt, peer1, NewPosition); + free(NewPosition); + if(Error != NULL) goto error; + ++EndpointAt; + } + return NULL; +error: + for(size_t i = 0; i < EndpointAt; ++i) Free_endpoint(E->Peer + i); + if(Configuration == true) Free_link_configuration(&E->Configuration); + return Error; +} + +char * +Parse_node_configuration(node_configuration *E, ucl_object_t const *root, char const *Position) +{ + char *Error; + UCL_CHECK_ROOT(OBJECT); + ucl_object_t const *module = ucl_object_lookup(root, "module"); + UCL_CHECK(module, STRING); + ucl_object_t const *configuration = ucl_object_lookup(root, "configuration"); + if(configuration == NULL) + { + asprintf(&Error, "%s.configuration does not exist", Position); + goto error; + } + E->Module = strdup(ucl_object_tostring(module)); + E->Configuration = ucl_object_copy(configuration); + return NULL; +error: + return Error; +} + +char * +Parse_node(node *E, ucl_object_t const *root, char const *Position) +{ + char *Error; + bool Configuration = false; + UCL_CHECK_ROOT(OBJECT); + ucl_object_t const *configuration = ucl_object_lookup(root, "configuration"); + { + char *NewPosition; + asprintf(&NewPosition, "%s.configuration", Position); + Error = Parse_node_configuration(&E->Configuration, configuration, NewPosition); + free(NewPosition); + if(Error != NULL) goto error; + Configuration = true; + } + ucl_object_t const *data = ucl_object_lookup(root, "data"); + if(data == NULL) + { + asprintf(&Error, "%s.does not exist", Position); + goto error; + } + E->Data = ucl_object_copy(data); + return NULL; +error: + if(Configuration == true) Free_node_configuration(&E->Configuration); + return Error; +} + +char * +Parse_experiment(experiment *E, ucl_object_t const *root, char const *Position) +{ + char *Error; + size_t NodeAt = 0; + size_t LinkAt = 0; + if(root == NULL) return NULL; + UCL_CHECK_ROOT(OBJECT); + { + ucl_object_t const *nodes = ucl_object_lookup(root, "nodes"); + UCL_CHECK(nodes, OBJECT); + E->NodeCount = nodes->len; + E->Node = calloc(sizeof(node), E->NodeCount); + ucl_object_t const *v; + ucl_object_iter_t it = NULL; + while((v = ucl_iterate_object(nodes, &it, true))) + { + char const *k = ucl_object_key(v); + if(k == NULL) continue; + node *I = E->Node + NodeAt; + char *NewPosition; + asprintf(&NewPosition, "%s.nodes['%s']", Position, k); + Error = Parse_node(I, v, NewPosition); + free(NewPosition); + if(Error != NULL) goto error; + I->Name = strdup(k); + NodeAt++; + } + } + { + ucl_object_t const *links = ucl_object_lookup(root, "links"); + UCL_CHECK(links, OBJECT); + E->LinkCount = links->len; + E->Link = calloc(sizeof(link_), E->LinkCount); + ucl_object_t const *v; + ucl_object_iter_t it = NULL; + while((v = ucl_iterate_object(links, &it, true))) + { + char const *k = ucl_object_key(v); + if(k == NULL) continue; + link_ *I = E->Link + LinkAt; + char *NewPosition; + asprintf(&NewPosition, "%s.links['%s']", Position, k); + Error = Parse_link(I, v, NewPosition); + free(NewPosition); + if(Error != NULL) goto error; + I->Name = strdup(k); + LinkAt++; + } + } + return NULL; +error: + E->NodeCount = NodeAt; + E->LinkCount = LinkAt; + Free_experiment(E); + return Error; +} + +// SAVE + +void +Save_endpoint(jprint_state *S, endpoint const *E) +{ + JPrintObjectBegin(S); + JPrintMember(S, "address"); + JPrint_string(S, E->Address); + JPrintMember(S, "hook"); + JPrint_string(S, E->Hook); + JPrintObjectEnd(S); +} + +void +Save_endpoint_configuration(jprint_state *S, endpoint_configuration const *E) +{ + JPrintObjectBegin(S); + JPrintMember(S, "node"); + JPrint_string(S, E->Node); + JPrintMember(S, "interface"); + JPrint_string(S, E->Interface); + JPrintObjectEnd(S); +} + +void +Save_link_configuration(jprint_state *S, link_configuration const *E) +{ + JPrintObjectBegin(S); + JPrintMember(S, "peer0"); + Save_endpoint_configuration(S, E->Peer + 0); + JPrintMember(S, "peer1"); + Save_endpoint_configuration(S, E->Peer + 1); + JPrintObjectEnd(S); +} + +void +Save_link(jprint_state *S, link_ const *E) +{ + JPrintObjectBegin(S); + JPrintMember(S, "configuration"); + Save_link_configuration(S, &E->Configuration); + JPrintMember(S, "peer0"); + Save_endpoint(S, E->Peer + 0); + JPrintMember(S, "peer1"); + Save_endpoint(S, E->Peer + 1); + JPrintObjectEnd(S); +} + +void +Save_node_configuration(jprint_state *S, node_configuration const *E) +{ + JPrintObjectBegin(S); + JPrintMember(S, "module"); + JPrint_string(S, E->Module); + JPrintMember(S, "configuration"); + JPrint_ucl_object_t(S, E->Configuration); + JPrintObjectEnd(S); +} + +void +Save_node(jprint_state *S, node const *E) +{ + JPrintObjectBegin(S); + JPrintMember(S, "configuration"); + Save_node_configuration(S, &E->Configuration); + JPrintMember(S, "data"); + JPrint_ucl_object_t(S, E->Data); + JPrintObjectEnd(S); +} + +void +Save_experiment(jprint_state *S, experiment const *E) +{ + JPrintObjectBegin(S); + { + JPrintMember(S, "nodes"); + JPrintObjectBegin(S); + for(size_t i = 0; i < E->NodeCount; ++i) + { + node *I = E->Node + i; + JPrintMember(S, I->Name); + Save_node(S, I); + } + JPrintObjectEnd(S); + } + { + JPrintMember(S, "links"); + JPrintObjectBegin(S); + for(size_t i = 0; i < E->LinkCount; ++i) + { + link_ *I = E->Link + i; + JPrintMember(S, I->Name); + Save_link(S, E->Link + i); + } + JPrintObjectEnd(S); + } + JPrintObjectEnd(S); +} |
