commit e85353a90720761364e6c00cc09bfe1e768b6cb7
parent ed8d57093903a9bfa96aafed621b934631805589
Author: Vincent Forest <vincent.forest@meso-star.com>
Date: Thu, 12 Feb 2026 12:15:32 +0100
Update to the tree serialization function profile
The caller can now provide the name of the file to be written. A stream
can still be provided if available. However, this update simplifies the
way the function can be called, as opening and closing the destination
file is no longer necessarily the responsibility of the caller.
Diffstat:
3 files changed, 70 insertions(+), 24 deletions(-)
diff --git a/src/sln.h b/src/sln.h
@@ -137,6 +137,20 @@ struct sln_tree_read_args {
static const struct sln_tree_read_args SLN_TREE_READ_ARGS_NULL =
SLN_TREE_READ_ARGS_NULL__;
+struct sln_tree_write_args {
+ /* Name of the file in which the tree is serialized.
+ * NULL <=> uses a default name for the stream to be written, which must
+ * therefore be defined. */
+ const char* filename; /* Name of the file to read */
+
+ /* Stream where data is written.
+ * NULL <=> write to the file defined by "filename" */
+ FILE* file;
+};
+#define SLN_TREE_WRITE_ARGS_NULL__ {NULL,NULL}
+static const struct sln_tree_write_args SLN_TREE_WRITE_ARGS_NULL =
+ SLN_TREE_WRITE_ARGS_NULL__;
+
struct sln_tree_desc {
size_t max_nlines_per_leaf;
double mesh_decimation_err;
@@ -307,7 +321,7 @@ sln_mesh_eval
SLN_API res_T
sln_tree_write
(const struct sln_tree* tree,
- FILE* stream);
+ const struct sln_tree_write_args* args);
/*******************************************************************************
* Helper functions
diff --git a/src/sln_tree.c b/src/sln_tree.c
@@ -253,6 +253,24 @@ check_sln_tree_read_args
return RES_OK;
}
+static res_T
+check_sln_tree_write_args
+ (struct sln_device* sln,
+ const char* caller,
+ const struct sln_tree_write_args* args)
+{
+ if(!args) return RES_BAD_ARG;
+
+ if(!args->file && !args->filename) {
+ ERROR(sln,
+ "%s: the destination file is missing. "
+ "No file name or stream is provided.\n",
+ caller);
+ return RES_BAD_ARG;
+ }
+
+ return RES_OK;
+}
static INLINE void
stream_release(struct stream* stream)
{
@@ -617,16 +635,27 @@ sln_mesh_eval(const struct sln_mesh* mesh, const double wavenumber)
}
res_T
-sln_tree_write(const struct sln_tree* tree, FILE* stream)
+sln_tree_write
+ (const struct sln_tree* tree,
+ const struct sln_tree_write_args* args)
{
struct shtr_line_list_write_args wlines_args = SHTR_LINE_LIST_WRITE_ARGS_NULL;
+ struct stream stream = STREAM_NULL;
size_t nnodes, nverts;
res_T res = RES_OK;
- if(!tree || !stream) { res = RES_BAD_ARG; goto error; }
+ if(!tree) { res = RES_BAD_ARG; goto error; }
+ res = check_sln_tree_write_args(tree->sln, FUNC_NAME, args);
+ if(res != RES_OK) goto error;
+
+ res = stream_init
+ (tree->sln, FUNC_NAME, args->filename, args->file, "w", &stream);
+ if(res != RES_OK) goto error;
#define WRITE(Var, Nb) { \
- if(fwrite((Var), sizeof(*(Var)), (Nb), stream) != (Nb)) { \
+ if(fwrite((Var), sizeof(*(Var)), (Nb), stream.fp) != (Nb)) { \
+ ERROR(tree->sln, "%s:%s: error writing the tree -- %s\n", \
+ FUNC_NAME, stream.name, strerror(errno)); \
res = RES_IO_ERR; \
goto error; \
} \
@@ -650,19 +679,16 @@ sln_tree_write(const struct sln_tree* tree, FILE* stream)
WRITE(&tree->args.mesh_type, 1);
#undef WRITE
- res = shtr_isotope_metadata_write(tree->args.metadata, stream);
+ res = shtr_isotope_metadata_write(tree->args.metadata, stream.fp);
if(res != RES_OK) goto error;
- wlines_args.file = stream;
+ wlines_args.file = stream.fp;
res = shtr_line_list_write(tree->args.lines, &wlines_args);
if(res != RES_OK) goto error;
exit:
+ stream_release(&stream);
return res;
error:
- if(tree) {
- ERROR(tree->sln, "%s: error writing the tree -- %s\n",
- FUNC_NAME, res_to_cstr(res));
- }
goto exit;
}
diff --git a/src/test_sln_tree.c b/src/test_sln_tree.c
@@ -314,7 +314,8 @@ test_tree_serialization
const struct sln_tree_create_args* tree_args,
struct shtr* shtr)
{
- struct sln_tree_read_args args = SLN_TREE_READ_ARGS_NULL;
+ struct sln_tree_write_args wargs = SLN_TREE_WRITE_ARGS_NULL;
+ struct sln_tree_read_args rargs = SLN_TREE_READ_ARGS_NULL;
struct sln_tree* tree1 = NULL;
struct sln_tree* tree2 = NULL;
FILE* fp = NULL;
@@ -322,23 +323,28 @@ test_tree_serialization
CHK(sln_tree_create(sln, tree_args, &tree1) == RES_OK);
CHK(fp = tmpfile());
- CHK(sln_tree_write(NULL, fp) == RES_BAD_ARG);
+
+ wargs.file = fp;
+ CHK(sln_tree_write(NULL, &wargs) == RES_BAD_ARG);
CHK(sln_tree_write(tree1, NULL) == RES_BAD_ARG);
- CHK(sln_tree_write(tree1, fp) == RES_OK);
+ wargs.file = NULL;
+ CHK(sln_tree_write(tree1, &wargs) == RES_BAD_ARG);
+ wargs.file = fp;
+ CHK(sln_tree_write(tree1, &wargs) == RES_OK);
rewind(fp);
- args.shtr = shtr;
- args.file = fp;
- CHK(sln_tree_read(NULL, &args, &tree2) == RES_BAD_ARG);
+ rargs.shtr = shtr;
+ rargs.file = fp;
+ CHK(sln_tree_read(NULL, &rargs, &tree2) == RES_BAD_ARG);
CHK(sln_tree_read(sln, NULL, &tree2) == RES_BAD_ARG);
- args.shtr = NULL;
- CHK(sln_tree_read(sln, &args, &tree2) == RES_BAD_ARG);
- args.shtr = shtr;
- args.file = NULL;
- CHK(sln_tree_read(sln, &args, &tree2) == RES_BAD_ARG);
- args.file = fp;
- CHK(sln_tree_read(sln, &args, NULL) == RES_BAD_ARG);
- CHK(sln_tree_read(sln, &args, &tree2) == RES_OK);
+ rargs.shtr = NULL;
+ CHK(sln_tree_read(sln, &rargs, &tree2) == RES_BAD_ARG);
+ rargs.shtr = shtr;
+ rargs.file = NULL;
+ CHK(sln_tree_read(sln, &rargs, &tree2) == RES_BAD_ARG);
+ rargs.file = fp;
+ CHK(sln_tree_read(sln, &rargs, NULL) == RES_BAD_ARG);
+ CHK(sln_tree_read(sln, &rargs, &tree2) == RES_OK);
fclose(fp);
check_tree_equality(tree1, tree2);