commit aebdade527ef087332bafcc6e328c63d7a30444c
parent af80b87f0dffb12f0429229c64f8725f65c0b49e
Author: Vincent Forest <vincent.forest@meso-star.com>
Date: Mon, 23 May 2022 16:36:59 +0200
[De]serialize the tree
Add the functions sln_tree_write and sln_tree_create_from_stream
Diffstat:
| M | src/sln.h | | | 8 | ++++++++ |
| M | src/sln_tree.c | | | 164 | +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++-------- |
2 files changed, 156 insertions(+), 16 deletions(-)
diff --git a/src/sln.h b/src/sln.h
@@ -224,6 +224,14 @@ sln_tree_create
const struct sln_tree_create_args* args,
struct sln_tree** tree);
+/* Load a tree serialized with the "sln_tree_write" function */
+SLN_API res_T
+sln_tree_create_from_stream
+ (struct sln_device* sln,
+ struct shtr* shtr,
+ FILE* stream,
+ struct sln_tree** tree);
+
SLN_API res_T
sln_tree_ref_get
(struct sln_tree* tree);
diff --git a/src/sln_tree.c b/src/sln_tree.c
@@ -23,6 +23,7 @@
#include "sln_tree_c.h"
#include <star/shtr.h>
+#include <rsys/cstr.h>
/*******************************************************************************
* Helper functions
@@ -38,7 +39,7 @@ check_sln_tree_create_args
/* Currently only 1 line per leaf is accepted */
if(args->max_nlines_per_leaf != 1) {
- log_err(sln,
+ log_err(sln,
"%s: invalid maximum number of lines per leaf %lu. "
"Currently it must be set to 1.\n",
caller, (unsigned long)args->max_nlines_per_leaf);
@@ -67,6 +68,35 @@ check_sln_tree_create_args
return RES_OK;
}
+static res_T
+create_tree
+ (struct sln_device* sln,
+ const char* caller,
+ struct sln_tree** out_tree)
+{
+ struct sln_tree* tree = NULL;
+ res_T res = RES_OK;
+ ASSERT(sln && caller && out_tree);
+
+ tree = MEM_CALLOC(sln->allocator, 1, sizeof(struct sln_tree));
+ if(!tree) {
+ log_err(sln, "%s: could not allocate the tree data structure.\n",
+ caller);
+ res = RES_MEM_ERR;
+ goto error;
+ }
+ ref_init(&tree->ref);
+ darray_node_init(sln->allocator, &tree->nodes);
+ darray_vertex_init(sln->allocator, &tree->vertices);
+
+exit:
+ *out_tree = tree;
+ return res;
+error:
+ if(tree) { SLN(tree_ref_put(tree)); tree = NULL; }
+ goto exit;
+}
+
static INLINE res_T
store_input_args
(struct sln_tree* tree,
@@ -108,23 +138,92 @@ sln_tree_create
res = check_sln_tree_create_args(mixture->sln, FUNC_NAME, args);
if(res != RES_OK) goto error;
- tree = MEM_CALLOC(mixture->sln->allocator, 1, sizeof(struct sln_tree));
- if(!tree) {
- log_err(mixture->sln, "%s: could not allocate the tree data structure.\n",
- FUNC_NAME);
- res = RES_MEM_ERR;
- goto error;
- }
- ref_init(&tree->ref);
+ res = create_tree(mixture->sln, FUNC_NAME, &tree);
+ if(res != RES_OK) goto error;
SLN(mixture_ref_get(mixture));
tree->mixture = mixture;
- darray_node_init(mixture->sln->allocator, &tree->nodes);
- darray_vertex_init(mixture->sln->allocator, &tree->vertices);
- #define CALL(Func) { if(RES_OK != (res = Func)) goto error; } (void)0
- CALL(store_input_args(tree, args));
- CALL(tree_build(tree, args));
- #undef CALL
+ res = store_input_args(tree, args);
+ if(res != RES_OK) goto error;
+ res = tree_build(tree, args);
+ if(res != RES_OK) goto error;
+
+exit:
+ if(out_tree) *out_tree = tree;
+ return res;
+error:
+ if(tree) { SLN(tree_ref_put(tree)); tree = NULL; }
+ goto exit;
+}
+
+res_T
+sln_tree_create_from_stream
+ (struct sln_device* sln,
+ struct shtr* shtr,
+ FILE* stream,
+ struct sln_tree** out_tree)
+{
+ struct sln_tree* tree = NULL;
+ size_t n = 0;
+ int version = 0;
+ res_T res = RES_OK;
+
+ if(!sln || !shtr || !stream || !out_tree) {
+ res = RES_BAD_ARG;
+ goto error;
+ }
+
+ res = create_tree(sln, FUNC_NAME, &tree);
+ if(res != RES_OK) goto error;
+
+ #define READ(Var, Nb) { \
+ if(fread((Var), sizeof(*(Var)), (Nb), stream) != (Nb)) { \
+ if(feof(stream)) { \
+ res = RES_BAD_ARG; \
+ } else if(ferror(stream)) { \
+ res = RES_IO_ERR; \
+ } else { \
+ res = RES_UNKNOWN_ERR; \
+ } \
+ log_err(sln, "%s: error reading tree data -- %s.\n", \
+ FUNC_NAME, res_to_cstr(res)); \
+ goto error; \
+ } \
+ } (void)0
+ READ(&version, 1);
+ if(version != SLN_TREE_VERSION) {
+ log_err(sln,
+ "%s: unexpected tree version %d. Expecting a tree in version %d.\n",
+ FUNC_NAME, version, SLN_TREE_VERSION);
+ res = RES_BAD_ARG;
+ goto error;
+ }
+
+ READ(&n, 1);
+ res = darray_node_resize(&tree->nodes, n);
+ if(res != RES_OK) {
+ log_err(sln, "%s: error allocating the tree nodes -- %s.\n",
+ FUNC_NAME, res_to_cstr(res));
+ goto error;
+ }
+ READ(darray_node_data_get(&tree->nodes), n);
+
+ READ(&n, 1);
+ res = darray_vertex_resize(&tree->vertices, n);
+ if(res != RES_OK) {
+ log_err(sln, "%s: error allocatiing the tree vertices -- %s.\n",
+ FUNC_NAME, res_to_cstr(res));
+ goto error;
+ }
+ READ(darray_vertex_data_get(&tree->vertices), n);
+
+ READ(&tree->max_nlines_per_leaf, 1);
+ READ(&tree->mesh_decimation_err, 1);
+ READ(&tree->line_profile, 1);
+ #undef READ
+
+ res = sln_mixture_create_from_stream(sln, shtr, stream, &tree->mixture);
+ if(res != RES_OK) goto error;
exit:
if(out_tree) *out_tree = tree;
@@ -221,5 +320,38 @@ sln_node_get_mesh
res_T
sln_tree_write(const struct sln_tree* tree, FILE* stream)
{
-}
+ size_t n;
+ res_T res = RES_OK;
+
+ if(!tree || !stream) { res = RES_BAD_ARG; goto error; }
+
+ #define WRITE(Var, Nb) { \
+ if(fwrite((Var), sizeof(*(Var)), (Nb), stream) != (Nb)) { \
+ log_err(tree->mixture->sln, "%s: error writing the tree.\n", FUNC_NAME); \
+ res = RES_IO_ERR; \
+ goto error; \
+ } \
+ } (void)0
+ WRITE(&SLN_TREE_VERSION, 1);
+
+ n = darray_node_size_get(&tree->nodes);
+ WRITE(&n, 1);
+ WRITE(darray_node_cdata_get(&tree->nodes), n);
+ n = darray_vertex_size_get(&tree->vertices);
+ WRITE(&n, 1);
+ WRITE(darray_vertex_cdata_get(&tree->vertices), n);
+
+ WRITE(&tree->max_nlines_per_leaf, 1);
+ WRITE(&tree->mesh_decimation_err, 1);
+ WRITE(&tree->line_profile, 1);
+ #undef WRITE
+
+ res = sln_mixture_write(tree->mixture, stream);
+ if(res != RES_OK) goto error;
+
+exit:
+ return res;
+error:
+ goto exit;
+}