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:
| M | src/atrri.c | | | 189 | +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ |
| M | src/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 */