star-hitran

Load line-by-line data from the HITRAN database
git clone git://git.meso-star.fr/star-hitran.git
Log | Files | Refs | README | LICENSE

commit 2ea5b1880382e72eb995ad13ef53295caf65ed93
parent 631c84414d0fe0204349f5c6d8336cf047fbccb9
Author: Vincent Forest <vincent.forest@meso-star.com>
Date:   Mon, 23 May 2022 10:50:33 +0200

[De]serialize the isotope metadata

Add the shtr_isotope_metadata_write, and
shtr_isotope_metadata_create_from_stream function.

Diffstat:
Msrc/shtr.h | 15++++++++++++++-
Msrc/shtr_isotope_metadata.c | 263++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++-
2 files changed, 275 insertions(+), 3 deletions(-)

diff --git a/src/shtr.h b/src/shtr.h @@ -85,7 +85,7 @@ struct shtr_line { * isotopic index read from the HITRAN file. The original value is in [0, 9] * with 0 actually meaning 10. Thus, once decoded, the index is located in * [1, 10]. The next member variable simply stores this index but decremented - * by one in order to make it compatible with C indexeing. As a result, it + * by one in order to make it compatible with C indexing. As a result, it * can be used directly to index the 'isotopes' array of a 'shtr_molecule' * data structure loaded from an isotope metadata file */ int32_t isotope_id_local; @@ -188,6 +188,14 @@ shtr_isotope_metadata_load_stream const char* stream_name, /* NULL <=> use default stream name */ struct shtr_isotope_metadata** metadata); +/* Load the isotope metadata serialized with the "shtr_isotope_metadata_write" + * function */ +SHTR_API res_T +shtr_isotope_metadata_create_from_stream + (struct shtr* shtr, + FILE* stream, + struct shtr_isotope_metadata** metadata); + SHTR_API res_T shtr_isotope_metadata_ref_get (struct shtr_isotope_metadata* metadata); @@ -219,6 +227,11 @@ shtr_isotope_metadata_find_molecule const int molecule_id, /* Unique identifier of the molecule <=> Global index */ struct shtr_molecule* molecule); +SHTR_API res_T +shtr_isotope_metadata_write + (const struct shtr_isotope_metadata* metadata, + FILE* stream); + /******************************************************************************* * Lines API ******************************************************************************/ diff --git a/src/shtr_isotope_metadata.c b/src/shtr_isotope_metadata.c @@ -24,8 +24,7 @@ #include "shtr_param.h" #include <rsys/cstr.h> -#include <rsys/dynamic_array.h> -#include <rsys/hash_table.h> +#include <rsys/dynamic_array_char.h> #include <rsys/ref_count.h> #include <rsys/str.h> #include <rsys/text_reader.h> @@ -33,6 +32,11 @@ #include <ctype.h> #include <string.h> +/* Version of the isotope metadata. One should increment it and perform a + * version management onto serialized data when the isotope metadata structure + * are updated. */ +static const int SHTR_ISOTOPE_METADATA_VERSION = 0; + /* Generate the dynamic array of isotopes */ #define DARRAY_NAME isotope #define DARRAY_DATA struct shtr_isotope @@ -456,6 +460,172 @@ error: goto exit; } +static res_T +write_molecules + (const struct shtr_isotope_metadata* metadata, + const char* caller, + FILE* stream) +{ + const struct molecule* molecules = NULL; + size_t i, nmolecules; + res_T res = RES_OK; + ASSERT(metadata && caller && stream); + + molecules = darray_molecule_cdata_get(&metadata->molecules); + nmolecules = darray_molecule_size_get(&metadata->molecules); + + #define WRITE(Var, Nb) { \ + if(fwrite((Var), sizeof(*(Var)), (Nb), stream) != (Nb)) { \ + res = RES_IO_ERR; \ + goto error; \ + } \ + } (void)0 + WRITE(&nmolecules, 1); + + FOR_EACH(i, 0, nmolecules) { + const struct molecule* molecule = molecules + i; + const size_t len = str_len(&molecule->name); + WRITE(&len, 1); + WRITE(str_cget(&molecule->name), len); + WRITE(molecule->isotopes_range, 2); + WRITE(&molecule->id, 1); + } + #undef WRITE + +exit: + return res; +error: + log_err(metadata->shtr, "%s: error writing molecules\n", caller); + goto exit; +} + +static res_T +read_molecules + (struct shtr_isotope_metadata* metadata, + const char* caller, + FILE* stream) +{ + struct darray_char name; + struct molecule* molecules = NULL; + size_t i, nmolecules; + res_T res = RES_OK; + ASSERT(metadata && caller && stream); + + darray_char_init(metadata->shtr->allocator, &name); + + #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; \ + } \ + goto error; \ + } \ + } (void)0 + + READ(&nmolecules, 1); + + res = darray_molecule_resize(&metadata->molecules, nmolecules); + if(res != RES_OK) goto error; + + molecules = darray_molecule_data_get(&metadata->molecules); + FOR_EACH(i, 0, nmolecules) { + struct molecule* molecule = molecules + i; + size_t len = 0; + + READ(&len, 1); + res = darray_char_resize(&name, len+1); + if(res != RES_OK) goto error; + + READ(darray_char_data_get(&name), len); + darray_char_data_get(&name)[len] = '\0'; + res = str_set(&molecule->name, darray_char_data_get(&name)); + if(res != RES_OK) goto error; + + READ(molecule->isotopes_range, 2); + READ(&molecule->id, 1); + } + #undef READ + +exit: + darray_char_release(&name); + return res; +error: + log_err(metadata->shtr, "%s: error reading molecules -- %s.\n", + caller, res_to_cstr(res)); + goto exit; +} + +static res_T +write_isotopes + (const struct shtr_isotope_metadata* metadata, + const char* caller, + FILE* stream) +{ + const struct shtr_isotope* isotopes = NULL; + size_t nisotopes = 0; + res_T res = RES_OK; + ASSERT(metadata && caller && stream); + + isotopes = darray_isotope_cdata_get(&metadata->isotopes); + nisotopes = darray_isotope_size_get(&metadata->isotopes); + + #define WRITE(Var, Nb) { \ + if(fwrite((Var), sizeof(*(Var)), (Nb), stream) != (Nb)) { \ + log_err(metadata->shtr, "%s: error writing isotopes\n", caller); \ + res = RES_IO_ERR; \ + goto error; \ + } \ + } (void)0 + WRITE(&nisotopes, 1); + WRITE(isotopes, nisotopes); + #undef WRITE + +exit: + return res; +error: + goto exit; +} + +static res_T +read_isotopes + (struct shtr_isotope_metadata* metadata, + const char* caller, + FILE* stream) +{ + size_t nisotopes = 0; + res_T res = RES_OK; + ASSERT(metadata && caller && stream); + + #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; \ + } \ + goto error; \ + } \ + } (void)0 + READ(&nisotopes, 1); + res = darray_isotope_resize(&metadata->isotopes, nisotopes); + if(res != RES_OK) goto error; + READ(darray_isotope_data_get(&metadata->isotopes), nisotopes); + #undef READ + +exit: + return res; +error: + log_err(metadata->shtr, "%s: error reading isotopes -- %s.\n", + caller, res_to_cstr(res)); + goto exit; +} + static void release_isotope_metadata(ref_T* ref) { @@ -517,6 +687,61 @@ shtr_isotope_metadata_load_stream } res_T +shtr_isotope_metadata_create_from_stream + (struct shtr* shtr, + FILE* stream, + struct shtr_isotope_metadata** out_metadata) +{ + struct shtr_isotope_metadata* metadata = NULL; + int version = 0; + res_T res = RES_OK; + + if(!shtr || !out_metadata || !stream) { + res = RES_BAD_ARG; + goto error; + } + + res = create_isotope_metadata(shtr, &metadata); + 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; \ + } \ + goto error; \ + } \ + } (void)0 + READ(&version, 1); + if(version != SHTR_ISOTOPE_METADATA_VERSION) { + log_err(shtr, + "%s: unexpected isotope metadata version %d. " + "Experting a isotope metadata in version %d.\n", + FUNC_NAME, version, SHTR_ISOTOPE_METADATA_VERSION); + res = RES_BAD_ARG; + goto error; + } + + res = read_molecules(metadata, FUNC_NAME, stream); + if(res != RES_OK) goto error; + res = read_isotopes(metadata, FUNC_NAME, stream); + if(res != RES_OK) goto error; + + READ(metadata->molid2idx, SHTR_MAX_MOLECULES_COUNT); + #undef READ + +exit: + if(out_metadata) *out_metadata = metadata; + return res; +error: + goto exit; +} + +res_T shtr_isotope_metadata_ref_get (struct shtr_isotope_metadata* metadata) { @@ -617,3 +842,37 @@ error: goto exit; } +res_T +shtr_isotope_metadata_write + (const struct shtr_isotope_metadata* metadata, + FILE* stream) +{ + res_T res = RES_OK; + + if(!metadata || !stream) { + res = RES_BAD_ARG; + goto error; + } + + #define WRITE(Var, Nb) { \ + if(fwrite((Var), sizeof(*(Var)), (Nb), stream) != (Nb)) { \ + log_err(metadata->shtr, "%s: error writing metadata\n", FUNC_NAME); \ + res = RES_IO_ERR; \ + goto error; \ + } \ + } (void)0 + WRITE(&SHTR_ISOTOPE_METADATA_VERSION, 1); + + res = write_molecules(metadata, FUNC_NAME, stream); + if(res != RES_OK) goto error; + res = write_isotopes(metadata, FUNC_NAME, stream); + if(res != RES_OK) goto error; + + WRITE(metadata->molid2idx, SHTR_MAX_MOLECULES_COUNT); + #undef WRITE + +exit: + return res; +error: + goto exit; +}