cg_catalog_parsing.c (5659B)
1 /* Copyright (C) 2022 Université de Pau et des Pays de l'Adour UPPA 2 * Copyright (C) 2022 CNRS 3 * Copyright (C) 2022 Sorbonne Université 4 * Copyright (C) 2022 Université Paul Sabatier 5 * Copyright (C) 2022 |Meso|Star> (contact@meso-star.com) 6 * 7 * This program is free software: you can redistribute it and/or modify 8 * it under the terms of the GNU General Public License as published by 9 * the Free Software Foundation, either version 3 of the License, or 10 * (at your option) any later version. 11 * 12 * This program is distributed in the hope that it will be useful, 13 * but WITHOUT ANY WARRANTY; without even the implied warranty of 14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 15 * GNU General Public License for more details. 16 * 17 * You should have received a copy of the GNU General Public License 18 * along with this program. If not, see <http://www.gnu.org/licenses/>. */ 19 20 #include "cg.h" 21 #include "cg_args.h" 22 #include "cg_catalog_parsing.h" 23 #include "cg_construction_mode_0_parsing_schemas.h" 24 #include "cg_construction_mode_1_parsing_schemas.h" 25 #include "cg_construction_mode_2_parsing_schemas.h" 26 #include "cg_city_parsing_schemas.h" 27 #include "cg_cyaml.h" 28 29 #include <rsys/logger.h> 30 #include <rsys/str.h> 31 #include <rsys/clock_time.h> 32 33 static const struct cyaml_schema_value* 34 get_schema_from_parsed_cmode 35 (const enum parsed_cmode_type parsed_cmode) 36 { 37 switch(parsed_cmode) { 38 case PARSED_CMODE_0: 39 return &construction_mode_0_schema; 40 case PARSED_CMODE_1: 41 return &construction_mode_1_schema; 42 case PARSED_CMODE_2: 43 return &construction_mode_2_schema; 44 default: FATAL("Invalid enum value.\n"); 45 } 46 } 47 48 res_T 49 parse_catalog 50 (const struct darray_names* files_array, 51 struct mem_allocator* allocator, 52 struct logger* logger, 53 const struct cyaml_config* config, 54 struct parsed_catalog** out_parsed) 55 { 56 res_T res = RES_OK; 57 cyaml_err_t err; 58 size_t i, files_count; 59 struct parsed_catalog_items* items; 60 struct parsed_catalog* parsed; 61 struct parsed_cmode* parsed_cmode = NULL; 62 const char* filename = NULL; 63 FILE* f; 64 struct time t0, dt; 65 char buf[128]; 66 (void)logger; 67 68 ASSERT(files_array && allocator && logger && out_parsed); 69 70 parsed = MEM_ALLOC(allocator, sizeof(*parsed)); 71 if(!parsed) { 72 res = RES_MEM_ERR; 73 goto error; 74 } 75 76 parsed->allocator = allocator; 77 parsed->logger = logger; 78 79 files_count = darray_names_size_get(files_array); 80 81 darray_parsed_catalog_items_init(allocator, &parsed->catalog); 82 ERR(darray_parsed_catalog_items_resize(&parsed->catalog, files_count)); 83 items = darray_parsed_catalog_items_data_get(&parsed->catalog); 84 for(i = 0; i < files_count; i++) { 85 const struct cyaml_schema_value* schema; 86 size_t set_count; 87 88 time_current(&t0); 89 /* Parse construction mode only */ 90 filename = darray_names_cdata_get(files_array)[i]; 91 err = cyaml_load_file(filename, config, &construction_mode_schema, 92 (void**)&parsed_cmode, NULL); 93 ERR(cyaml_err_to_res_T(err)); 94 95 /* Parse catalog items according to construction mode */ 96 schema = get_schema_from_parsed_cmode(parsed_cmode->cmode_type); 97 err = cyaml_load_file(filename, config, schema, &items[i].parsed_data, NULL); 98 ERR(cyaml_err_to_res_T(err)); 99 100 /* Set other fields*/ 101 items[i].filename = filename; 102 items[i].construction_mode = parsed_cmode->cmode_type; 103 104 /* Log outcome */ 105 switch(items[i].construction_mode) { 106 case PARSED_CMODE_0: 107 set_count = 108 ((struct parsed_catalog_cmode_0*)items[i].parsed_data)->datasets_count; 109 break; 110 case PARSED_CMODE_1: 111 set_count = 112 ((struct parsed_catalog_cmode_1*)items[i].parsed_data)->datasets_count; 113 break; 114 case PARSED_CMODE_2: 115 set_count = 116 ((struct parsed_catalog_cmode_2*)items[i].parsed_data)->datasets_count; 117 break; 118 default: FATAL("Invalid enum value.\n"); 119 } 120 time_sub(&dt, time_current(&dt), &t0); 121 time_dump(&dt, TIME_SEC | TIME_MSEC, NULL, buf, sizeof(buf)); 122 logger_print(logger, LOG_OUTPUT, 123 "Catalog file '%s' parsed: mode '%s', %zu dataset(s) read. in %s\n", 124 filename, 125 city_building_types_strings[items[i].construction_mode].str, 126 set_count, 127 buf); 128 129 /* Free tmp struct */ 130 err = cyaml_free(config, &construction_mode_schema, parsed_cmode, 1); 131 CHK(RES_OK == cyaml_err_to_res_T(err)); 132 parsed_cmode = NULL; 133 filename = NULL; 134 } 135 136 exit: 137 if(parsed_cmode) { 138 err = cyaml_free(config, &city_schema, parsed_cmode, 1); 139 CHK(RES_OK == cyaml_err_to_res_T(err)); 140 } 141 *out_parsed = parsed; 142 return res; 143 error: 144 if(filename) { 145 logger_print(logger, LOG_ERROR, 146 "Error parsing catalog file '%s'.\n", filename); 147 } 148 f = fopen(filename, "r"); 149 if(f) { 150 fclose(f); 151 } else { 152 logger_print(logger, LOG_ERROR, "Could not open file.\n"); 153 } 154 release_parsed_catalog(config, parsed); 155 parsed = NULL; 156 goto exit; 157 } 158 159 void 160 release_parsed_catalog 161 (const struct cyaml_config* config, 162 struct parsed_catalog* parsed) 163 { 164 struct parsed_catalog_items* items; 165 size_t i, count; 166 167 if(!parsed) return; 168 169 ASSERT(config); 170 171 count = darray_parsed_catalog_items_size_get(&parsed->catalog); 172 items = darray_parsed_catalog_items_data_get(&parsed->catalog); 173 for(i = 0; i < count; i++) { 174 const struct cyaml_schema_value* schema 175 = get_schema_from_parsed_cmode(items[i].construction_mode); 176 cyaml_err_t err = cyaml_free(config, schema, items[i].parsed_data, 1); 177 CHK(RES_OK == cyaml_err_to_res_T(err)); 178 } 179 darray_parsed_catalog_items_release(&parsed->catalog); 180 MEM_RM(parsed->allocator, parsed); 181 }