commit b95348c666e7c6345f2e4c33168f7df4e5abeba8
parent d2b8e200ce1dbac663adab7bb9cbe46a90da157b
Author: Vincent Forest <vincent.forest@meso-star.com>
Date: Mon, 23 May 2022 16:14:02 +0200
[De]serialize the mixture
Add the functions sln_mixture_write and sln_mixture_create_from_stream.
Diffstat:
3 files changed, 164 insertions(+), 13 deletions(-)
diff --git a/src/sln.h b/src/sln.h
@@ -48,6 +48,7 @@
/* Forwar declaration of external data structures */
struct logger;
struct mem_allocator;
+struct shtr;
struct shtr_line;
struct shtr_isotope_metadata;
struct shtr_line_list;
@@ -188,6 +189,14 @@ sln_mixture_create
const struct sln_mixture_create_args* args,
struct sln_mixture** mixture);
+/* Load a mixture serialized with the "shtr_mixture_write" function */
+SLN_API res_T
+sln_mixture_create_from_stream
+ (struct sln_device* sln,
+ struct shtr* shtr,
+ FILE* stream,
+ struct sln_mixture** mixture);
+
SLN_API res_T
sln_mixture_ref_get
(struct sln_mixture* mixture);
@@ -201,6 +210,11 @@ sln_mixture_get_desc
(const struct sln_mixture* mixture,
struct sln_mixture_desc* desc);
+SLN_API res_T
+sln_mixture_write
+ (const struct sln_mixture* mixture,
+ FILE* stream);
+
/*******************************************************************************
* Tree API
******************************************************************************/
diff --git a/src/sln_mixture.c b/src/sln_mixture.c
@@ -22,6 +22,7 @@
#include "sln_mixture_c.h"
#include <star/shtr.h>
+#include <rsys/cstr.h>
STATIC_ASSERT(SLN_MAX_MOLECULES_COUNT <= SHTR_MAX_MOLECULES_COUNT,
Invalid_SLN_MAX_MOLECULES_COUNT);
@@ -192,6 +193,33 @@ check_sln_mixture_create_args
}
static res_T
+create_mixture(struct sln_device* sln, struct sln_mixture** out_mixture)
+{
+ struct sln_mixture* mixture = NULL;
+ res_T res = RES_OK;
+ ASSERT(sln && out_mixture);
+
+ mixture = MEM_CALLOC(sln->allocator, 1, sizeof(struct sln_mixture));
+ if(!mixture) {
+ log_err(sln, "%s: could not allocate the mixture data structure.\n",
+ FUNC_NAME);
+ res = RES_MEM_ERR;
+ goto error;
+ }
+ ref_init(&mixture->ref);
+ SLN(device_ref_get(sln));
+ mixture->sln = sln;
+ darray_line_init(sln->allocator, &mixture->lines);
+
+exit:
+ *out_mixture = mixture;
+ return res;
+error:
+ if(mixture) { SLN(mixture_ref_put(mixture)); mixture = NULL; }
+ goto exit;
+}
+
+static res_T
create_line_view
(struct sln_device* sln,
const struct sln_mixture_create_args* mixture_args,
@@ -326,7 +354,6 @@ error:
goto exit;
}
-
static void
release_mixture(ref_T* ref)
{
@@ -356,18 +383,8 @@ sln_mixture_create
if(!sln || !out_mixture) { res = RES_BAD_ARG; goto error; }
res = check_sln_mixture_create_args(sln, FUNC_NAME, args);
if(res != RES_OK) goto error;
-
- mixture = MEM_CALLOC(sln->allocator, 1, sizeof(struct sln_mixture));
- if(!mixture) {
- log_err(sln, "%s: could not allocate the mixture data structure.\n",
- FUNC_NAME);
- res = RES_MEM_ERR;
- goto error;
- }
- ref_init(&mixture->ref);
- SLN(device_ref_get(sln));
- mixture->sln = sln;
- darray_line_init(sln->allocator, &mixture->lines);
+ res = create_mixture(sln, &mixture);
+ if(res != RES_OK) goto error;
#define CALL(Func) { if(RES_OK != (res = Func)) goto error; } (void)0
CALL(create_line_view(sln, args, &mixture->line_view));
@@ -385,6 +402,82 @@ error:
}
res_T
+sln_mixture_create_from_stream
+ (struct sln_device* sln,
+ struct shtr* shtr,
+ FILE* stream,
+ struct sln_mixture** out_mixture)
+{
+ struct sln_mixture* mixture = NULL;
+ size_t nlines = 0;
+ int version = 0;
+ res_T res = RES_OK;
+
+ if(!sln || !shtr || !stream || !out_mixture) {
+ res = RES_BAD_ARG;
+ goto error;
+ }
+
+ res = create_mixture(sln, &mixture);
+ 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 mixture data -- %s.\n", \
+ FUNC_NAME, res_to_cstr(res)); \
+ goto error; \
+ } \
+ } (void)0
+ READ(&version, 1);
+ if(version != SLN_MIXTURE_VERSION) {
+ log_err(sln,
+ "%s: unexpected mixture version %d. "
+ "Expecting a mixture in version %d.\n",
+ FUNC_NAME, version, SLN_MIXTURE_VERSION);
+ res = RES_BAD_ARG;
+ goto error;
+ }
+ READ(mixture->molecules_params, SLN_MAX_MOLECULES_COUNT);
+
+ res = shtr_isotope_metadata_create_from_stream(shtr, stream, &mixture->metadata);
+ if(res != RES_OK) goto error;
+ res = shtr_line_view_create_from_stream(shtr, stream, &mixture->line_view);
+ if(res != RES_OK) goto error;
+
+ READ(&nlines, 1);
+ res = darray_line_resize(&mixture->lines, nlines);
+ if(res != RES_OK) {
+ log_err(sln, "%s: error allocating mixture lines -- %s.\n",
+ FUNC_NAME, res_to_cstr(res));
+ goto error;
+ }
+ READ(darray_line_data_get(&mixture->lines), nlines);
+#ifndef NDEBUG
+ SHTR(line_view_get_size(mixture->line_view, &nlines));
+ ASSERT(darray_line_size_get(&mixture->lines) == nlines);
+#endif
+
+ READ(&mixture->temperature, 1);
+ READ(&mixture->pressure, 1);
+ READ(&mixture->wavenumber_range, 1);
+ #undef READ
+
+exit:
+ if(out_mixture) *out_mixture = mixture;
+ return res;
+error:
+ if(mixture) { SLN(mixture_ref_put(mixture)); mixture = NULL; }
+ goto exit;
+}
+
+res_T
sln_mixture_ref_get(struct sln_mixture* mixture)
{
if(!mixture) return RES_BAD_ARG;
@@ -413,3 +506,43 @@ sln_mixture_get_desc
desc->nlines = darray_line_size_get(&mixture->lines);
return RES_OK;
}
+
+res_T
+sln_mixture_write(const struct sln_mixture* mixture, FILE* stream)
+{
+ size_t nlines = 0;
+ res_T res = RES_OK;
+
+ if(!mixture || !stream) {
+ res = RES_BAD_ARG;
+ goto error;
+ }
+
+ #define WRITE(Var, Nb) { \
+ if(fwrite((Var), sizeof(*(Var)), (Nb), stream) != (Nb)) { \
+ log_err(mixture->sln, "%s: error writing the mixture.\n", FUNC_NAME); \
+ res = RES_IO_ERR; \
+ goto error; \
+ } \
+ } (void)0
+ WRITE(&SLN_MIXTURE_VERSION, 1);
+ WRITE(mixture->molecules_params, SLN_MAX_MOLECULES_COUNT);
+
+ res = shtr_isotope_metadata_write(mixture->metadata, stream);
+ if(res != RES_OK) goto error;
+ res = shtr_line_view_write(mixture->line_view, stream);
+ if(res != RES_OK) goto error;
+
+ nlines = darray_line_size_get(&mixture->lines);
+ WRITE(&nlines, 1);
+ WRITE(darray_line_cdata_get(&mixture->lines), nlines);
+ WRITE(&mixture->temperature, 1);
+ WRITE(&mixture->pressure, 1);
+ WRITE(mixture->wavenumber_range, 2);
+ #undef WRITE
+
+exit:
+ return res;
+error:
+ goto exit;
+}
diff --git a/src/sln_mixture_c.h b/src/sln_mixture_c.h
@@ -41,6 +41,10 @@ struct molecule_params {
double cutoff;
};
+/* Current version of the mixture. One should increment it and perform a
+ * version management onto serialized data when muxture structure is updated. */
+static const int SLN_MIXTURE_VERSION = 0;
+
struct sln_mixture {
/* Map the molecule id to its parameters (i.e. concentration, cutoff,
* isotopes abundance) */