atrri

Refractive indices varying with wavelength
git clone git://git.meso-star.fr/atrri.git
Log | Files | Refs | README | LICENSE

commit 8248d8cd48cb8022075f88e845f84660e95f2165
parent 2195594752e7f9a8dc10a93bcda2a9d8c8232f82
Author: Vincent Forest <vincent.forest@meso-star.com>
Date:   Wed, 13 Jan 2021 09:34:01 +0100

Implement the atrri_load[_stream] functions

Diffstat:
Msrc/atrri.c | 189+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Msrc/atrri_c.h | 16++++++++++++++++
2 files changed, 205 insertions(+), 0 deletions(-)

diff --git a/src/atrri.c b/src/atrri.c @@ -13,19 +13,158 @@ * You should have received a copy of the GNU General Public License * along with this program. If not, see <http://www.gnu.org/licenses/>. */ +#define _POSIX_C_SOURCE 200112L /* strtok_r support */ + #include "atrri.h" #include "atrri_c.h" #include "atrri_log.h" +#include <rsys/cstr.h> +#include <rsys/text_reader.h> + +#include <errno.h> +#include <string.h> + /******************************************************************************* * Local functions ******************************************************************************/ +static res_T +parse_line(struct atrri* atrri, struct txtrdr* txtrdr) +{ + struct refractive_index refract_id = REFRACTIVE_INDEX_NULL; + char* tk = NULL; + char* tk_ctx = NULL; + size_t nrefract_ids = 0; + res_T res = RES_OK; + ASSERT(atrri && txtrdr); + + /* Parse the wavelength */ + tk = strtok_r(txtrdr_get_line(txtrdr), " \t", &tk_ctx); + ASSERT(tk); /* A line should exist since it was parsed by txtrdr */ + res = cstr_to_double(tk, &refract_id.wavelength); + if(res == RES_OK && refract_id.wavelength < 0) res = RES_BAD_ARG; + if(res != RES_OK) { + log_err(atrri, "%s:%lu: invalid wavelength `%g' -- %s.\n", + txtrdr_get_name(txtrdr), (unsigned long)txtrdr_get_line_num(txtrdr), + refract_id.wavelength, res_to_cstr(res)); + goto error; + } + + nrefract_ids = darray_refractive_id_size_get(&atrri->refract_ids); + if(nrefract_ids != 0) { + /* Check that the indices are sorted in ascending order wrt wavelength */ + const struct refractive_index* prev_refract_id = + darray_refractive_id_cdata_get(&atrri->refract_ids) + nrefract_ids - 1; + if(prev_refract_id->wavelength <= refract_id.wavelength) { + log_err(atrri, + "%s:%lu: refractive indices must be sorted in ascending order.\n,", + txtrdr_get_name(txtrdr), (unsigned long)txtrdr_get_line_num(txtrdr)); + res = RES_BAD_ARG; + goto error; + } + } + + /* Parse the real part */ + tk = strtok_r(NULL, " \t", &tk_ctx); + if(!tk) { + log_err(atrri, + "%s:%lu: could not read the real part of the refractive index.\n", + txtrdr_get_name(txtrdr), (unsigned long)txtrdr_get_line_num(txtrdr)); + res = RES_BAD_ARG; + goto error; + } + res = cstr_to_double(tk, &refract_id.n); + if(res == RES_OK && refract_id.n < 0) res = RES_BAD_ARG; + if(res != RES_OK) { + log_err(atrri, + "%s:%lu: invalid real part of the refractive index `%g' -- %s.\n", + txtrdr_get_name(txtrdr), (unsigned long)txtrdr_get_line_num(txtrdr), + refract_id.n, res_to_cstr(res)); + goto error; + } + + /* Parse the imaginary part */ + tk = strtok_r(NULL, " \t", &tk_ctx); + if(!tk) { + log_err(atrri, + "%s:%lu: could not read the imaginary part of the refractive index.\n", + txtrdr_get_name(txtrdr), (unsigned long)txtrdr_get_line_num(txtrdr)); + res = RES_BAD_ARG; + goto error; + } + res = cstr_to_double(tk, &refract_id.kappa); + if(res == RES_OK && refract_id.kappa < 0) res = RES_BAD_ARG; + if(res != RES_OK) { + log_err(atrri, + "%s:%lu: invalid imaginary part of the refractive index `%g' -- %s.\n", + txtrdr_get_name(txtrdr), (unsigned long)txtrdr_get_line_num(txtrdr), + refract_id.kappa, res_to_cstr(res)); + goto error; + } + + tk = strtok_r(NULL, " \t", &tk_ctx); + if(tk) { + log_warn(atrri, "%s:%lu: unexpected text `%s'.\n", + txtrdr_get_name(txtrdr), (unsigned long)txtrdr_get_line_num(txtrdr), tk); + } + + /* Register the parsed refractive index */ + res = darray_refractive_id_push_back(&atrri->refract_ids, &refract_id); + if(res != RES_OK) { + log_err(atrri, "%s:%lu: could not register the refractive index -- %s.\n", + txtrdr_get_name(txtrdr), (unsigned long)txtrdr_get_line_num(txtrdr), + res_to_cstr(res)); + goto error; + } + +exit: + return res; +error: + goto exit; +} + +static res_T +load_stream(struct atrri* atrri, FILE* stream, const char* stream_name) +{ + struct txtrdr* txtrdr = NULL; + res_T res = RES_OK; + ASSERT(atrri && stream && stream_name); + + res = txtrdr_stream(atrri->allocator, stream, stream_name, '#', &txtrdr); + if(res != RES_OK) { + log_err(atrri, "%s: could not create the text reader -- %s.\n", + stream_name, res_to_cstr(res)); + } + + for(;;) { + res = txtrdr_read_line(txtrdr); + if(res != RES_OK) { + log_err(atrri, "%s: could not read the line `%lu' -- %s.\n", + txtrdr_get_name(txtrdr), (unsigned long)txtrdr_get_line_num(txtrdr), + res_to_cstr(res)); + goto error; + } + + if(!txtrdr_get_cline(txtrdr)) break; /* No more parsed line */ + + res = parse_line(atrri, txtrdr); + if(res != RES_OK) goto error; + } + +exit: + if(txtrdr) txtrdr_ref_put(txtrdr); + return res; +error: + goto exit; +} + static void release_atrri(ref_T* ref) { struct atrri* atrri; ASSERT(ref); atrri = CONTAINER_OF(ref, struct atrri, ref); + darray_refractive_id_release(&atrri->refract_ids); if(atrri->logger == &atrri->logger__) logger_release(&atrri->logger__); MEM_RM(atrri->allocator, atrri); } @@ -73,6 +212,8 @@ atrri_create setup_log_default(atrri); } + darray_refractive_id_init(atrri->allocator, &atrri->refract_ids); + exit: if(out_atrri) *out_atrri = atrri; return res; @@ -100,3 +241,51 @@ atrri_ref_put(struct atrri* atrri) return RES_OK; } +res_T +atrri_load(struct atrri* atrri, const char* path) +{ + FILE* file = NULL; + res_T res = RES_OK; + + if(!atrri || !path) { + res = RES_BAD_ARG; + goto error; + } + + file = fopen(path, "r"); + if(!file) { + log_err(atrri, "%s: error opening file -- %s.\n", + path, strerror(errno)); + res = RES_IO_ERR; + goto error; + } + + res = load_stream(atrri, file, path); + if(res != RES_OK) goto error; + +exit: + if(file) fclose(file); + return res; +error: + goto exit; +} + +res_T +atrri_load_stream(struct atrri* atrri, FILE* stream, const char* stream_name) +{ + res_T res = RES_OK; + + if(!atrri || !stream) { + res = RES_BAD_ARG; + goto error; + } + + res = load_stream(atrri, stream, stream_name ? stream_name : "stream"); + if(res != RES_OK) goto error; + +exit: + return res; +error: + goto exit; +} + diff --git a/src/atrri_c.h b/src/atrri_c.h @@ -16,12 +16,28 @@ #ifndef ATRRI_C_H #define ATRRI_C_H +#include <rsys/dynamic_array.h> #include <rsys/logger.h> #include <rsys/ref_count.h> +struct refractive_index { + double wavelength; /* In nanometers */ + double n; /* Real part */ + double kappa; /* Imaginary part */ +}; +#define REFRACTIVE_INDEX_NULL__ {0,0,0} +static const struct refractive_index REFRACTIVE_INDEX_NULL = + REFRACTIVE_INDEX_NULL__; + +#define DARRAY_NAME refractive_id +#define DARRAY_DATA struct refractive_index +#include <rsys/dynamic_array.h> + struct mem_allocator; struct atrri { + struct darray_refractive_id refract_ids; + struct mem_allocator* allocator; struct logger* logger; struct logger logger__; /* Default logger */