green-input.c (4448B)
1 /* Copyright (C) 2020-2022, 2024 |Méso|Star> (contact@meso-star.com) 2 * 3 * This program is free software: you can redistribute it and/or modify 4 * it under the terms of the GNU General Public License as published by 5 * the Free Software Foundation, either version 3 of the License, or 6 * (at your option) any later version. 7 * 8 * This program is distributed in the hope that it will be useful, 9 * but WITHOUT ANY WARRANTY; without even the implied warranty of 10 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 11 * GNU General Public License for more details. 12 * 13 * You should have received a copy of the GNU General Public License 14 * along with this program. If not, see <http://www.gnu.org/licenses/>. */ 15 16 #include "green-compute.h" 17 #include "green-types.h" 18 19 #include <rsys/rsys.h> 20 #include <rsys/str.h> 21 #include <rsys/logger.h> 22 #include <rsys/mem_allocator.h> 23 #include <rsys/text_reader.h> 24 25 #include <stdlib.h> 26 27 #define FR(Ptr, Count) \ 28 if((Count) != fread((Ptr), sizeof(*(Ptr)), (Count), stream)) { \ 29 logger_print(green->logger, LOG_ERROR, \ 30 "Could not read expected data.\n"); \ 31 res = RES_IO_ERR; \ 32 goto error; \ 33 } 34 35 static res_T 36 read_sample 37 (struct sample* sample, 38 struct mem_allocator* alloc, 39 struct green* green, 40 FILE* stream) 41 { 42 res_T res = RES_OK; 43 ASSERT(sample && stream); 44 45 /* Read counts */ 46 FR(&sample->header, 1); 47 /* Alloc buffers */ 48 ERR(alloc_sample_buffers(alloc, sample)); 49 /* Read Ids and weights */ 50 READ_SAMPLE_BUFFER(sample); 51 52 end: 53 return res; 54 error: 55 release_sample(alloc, sample); 56 goto end; 57 } 58 59 res_T 60 read_green_function 61 (struct green* green, 62 FILE* stream) 63 { 64 res_T res = RES_OK; 65 unsigned i; 66 67 ASSERT(green && stream); 68 69 /* Read header */ 70 FR(&green->header, 1); 71 72 /* Check Green string and file format version */ 73 if(strcmp(green->header.green_string, BIN_FILE_IDENT_STRING)) { 74 logger_print(green->logger, LOG_ERROR, 75 "File is not a binary Green file.\n"); 76 res = RES_BAD_ARG; 77 goto error; 78 } 79 if(green->header.file_format_version != GREEN_FILE_FORMAT_VERSION) { 80 logger_print(green->logger, LOG_ERROR, 81 "Incompatible file format version (%u VS expected %u).\n", 82 green->header.file_format_version, GREEN_FILE_FORMAT_VERSION); 83 res = RES_BAD_ARG; 84 goto error; 85 } 86 87 /* Check counts */ 88 if(green->header.description_count != 89 (green->header.solid_count + green->header.fluid_count 90 + green->header.tbound_count + green->header.hbound_count 91 + green->header.fbound_count + green->header.sfconnect_count 92 + green->header.ssconnect_count)) 93 { 94 logger_print(green->logger, LOG_ERROR, 95 "Inconsistant description counts (%u).\n", 96 green->header.description_count); 97 res = RES_BAD_ARG; 98 goto error; 99 } 100 101 /* Read descriptions*/ 102 green->descriptions = MEM_CALLOC(green->allocator, 103 green->header.description_count, sizeof(*green->descriptions)); 104 if(!green->descriptions) { 105 res = RES_MEM_ERR; 106 goto error; 107 } 108 FR(green->descriptions, green->header.description_count); 109 110 /* Read samples*/ 111 green->samples = MEM_CALLOC(green->allocator, green->header.ok_count, 112 sizeof(*green->samples)); 113 if(!green->samples) { 114 res = RES_MEM_ERR; 115 goto error; 116 } 117 FOR_EACH(i, 0, green->header.ok_count) { 118 ERR(read_sample(green->samples + i, green->allocator, green, stream)); 119 } 120 121 /* Build table */ 122 ERR(build_green_table(green)); 123 124 end: 125 return res; 126 error: 127 goto end; 128 } 129 130 res_T 131 green_read_settings 132 (struct green* green, 133 const char* in_name) 134 { 135 res_T res = RES_OK; 136 struct txtrdr* txtrdr = NULL; 137 FILE* stream = NULL; 138 139 ASSERT(green && in_name); 140 141 stream = fopen(in_name, "r"); 142 if(!stream) { 143 logger_print(green->logger, LOG_ERROR, 144 "Cannot open settings file '%s'\n", 145 in_name); 146 res = RES_IO_ERR; 147 goto error; 148 } 149 txtrdr_stream(green->allocator, stream, in_name, '#', &txtrdr); 150 for(;;) { 151 char* line; 152 size_t sz; 153 ERR(txtrdr_read_line(txtrdr)); 154 line = txtrdr_get_line(txtrdr); 155 if(!line) break; 156 sz = darray_str_size_get(&green->settings); 157 ERR(darray_str_resize(&green->settings, 1 + sz)); 158 ERR(str_set(darray_str_data_get(&green->settings) + sz, line)); 159 } 160 ERR(darray_result_resize(&green->results, 161 darray_str_size_get(&green->settings))); 162 txtrdr_ref_put(txtrdr); 163 txtrdr = NULL; 164 165 exit: 166 if(stream) fclose(stream); 167 if(txtrdr) txtrdr_ref_put(txtrdr); 168 return res; 169 error: 170 goto exit; 171 }