|
funkalicious 0.1
|
00001 /* 00002 ** grid1.c 00003 ** 00004 00005 Copyright (C) 2009 Joseph Pingenot 00006 00007 This program is free software: you can redistribute it and/or modify 00008 it under the terms of the GNU Affero General Public License as published by 00009 the Free Software Foundation, either version 3 of the License, or 00010 (at your option) any later version. 00011 00012 This program is distributed in the hope that it will be useful, 00013 but WITHOUT ANY WARRANTY; without even the implied warranty of 00014 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 00015 GNU Affero General Public License for more details. 00016 00017 You should have received a copy of the GNU Affero General Public License 00018 along with this program. If not, see <http://www.gnu.org/licenses/>. 00019 00020 ** Made by (Johnny Q. Hacker) 00021 ** Login <solarion@borkborkbork> 00022 ** 00023 ** Started on Mon Nov 23 16:18:25 2009 Johnny Q. Hacker 00024 ** Last update Sun May 12 01:17:25 2002 Speed Blue 00025 */ 00026 #include <stdio.h> 00027 #include <stdlib.h> 00028 #include <glib-2.0/glib.h> 00029 #include <gio/gio.h> 00030 #include <libdotcode/dotcode_generic.h> 00031 #include <libdotcode/grid1.h> 00032 #include <libdotcode/read_binary_data.h> 00033 #include <libdotcode/matdb.h> 00034 #include <libdotcode/matdb-dotcode.h> 00035 #include "gcc_hints.h" 00036 00037 #define DOTCODE_GRID1_GERROR_DOMAIN 9132 00038 00039 hotfunc ___const ___always_inline long unsigned int get_assignment_index(int x, int y, int z, int Nx, int Ny) { 00040 return x + Nx*(y + Ny*(z)); 00041 } 00042 00043 long unsigned int dotcode_grid1_get_assignment_index(int x, int y, int z, int Nx, int Ny) { 00044 return get_assignment_index(x, y, z, Nx, Ny); 00045 } 00046 00047 /*Just a stub for now*/ 00048 GError* dotcode_grid1_write_to_GFile(GFile* f, const struct dotcode_grid1* grid) { 00049 return g_error_new(DOTCODE_GRID1_GERROR_DOMAIN, DOTCODE_ERROR_NOTIMPLEMENTED, "dotcode::grid1::write_to_GFile: ERROR: this functionality is not yet implemented."); 00050 } 00051 void dotcode_grid1_free(struct dotcode_grid1* grid) { 00052 g_strfreev(grid->materials); 00053 if(grid->assignments != NULL) free(grid->assignments); 00054 free(grid); 00055 } 00056 00057 00058 00059 struct dotcode_grid1* dotcode_grid1_get_from_gfile(GFile* f, GError **error) { 00060 struct dotcode_grid1* grid = (struct dotcode_grid1*)malloc(sizeof(struct dotcode_grid1)); 00061 if(grid == NULL) { 00062 *error = g_error_new(DOTCODE_GRID1_GERROR_DOMAIN, DOTCODE_ERROR_MALLOCFAIL, "dotcode::grid1::get_from_GFile: Failed to allocate a new struct dotcode_grid1"); 00063 return NULL; 00064 } 00065 GError *e = NULL; 00066 GFileInputStream *fis = g_file_read(f, NULL, &e); 00067 if((e != NULL) || (fis == NULL)) { 00068 if(e == NULL) { 00069 char* str = g_file_get_uri(f); 00070 *error = g_error_new(DOTCODE_GRID1_GERROR_DOMAIN, 12, "dotcode::grid1::get_from_GFile: Failed to open the grid file (%s), but no further error was given.\n", str); 00071 g_free(str); 00072 }else{ 00073 *error = e; 00074 } 00075 free(grid); 00076 return NULL; 00077 } 00078 /*The file is now open.*/ 00079 char endian; 00080 gsize sz; 00081 if((!g_input_stream_read_all((GInputStream*)fis, &endian, 1, &sz, NULL, &e)) || (sz != 1)) { 00082 if(e == NULL) { 00083 *error = g_error_new(DOTCODE_GRID1_GERROR_DOMAIN, 12, "dotcode::grid1::get_from_GFile: Failed to read endianness from the stream: didn't get a single byte; got %lu", (long unsigned int)sz); 00084 }else{ 00085 *error = e; 00086 } 00087 free(grid); 00088 return NULL; 00089 } 00090 gboolean little_endian; 00091 switch(endian) { 00092 case 'l': 00093 little_endian = TRUE; 00094 break; 00095 case 'b': 00096 little_endian = FALSE; 00097 break; 00098 default: 00099 *error = g_error_new(DOTCODE_GRID1_GERROR_DOMAIN, 12, "dotcode::grid1::get_from_GFile: Failed to read endianness from the stream: got invalid character (%d)", (int)endian); 00100 free(grid); 00101 return NULL; 00102 } 00103 e = NULL; 00104 char *grid1_string = dotcode_read_sstring(little_endian, (GInputStream*)fis, &e); 00105 if((grid1_string == NULL) || (e != NULL)) { 00106 if(e == NULL) { 00107 *error = g_error_new(DOTCODE_GRID1_GERROR_DOMAIN, 12, "dotcode::grid1::get_from_GFile: Failed to read \"Grid1\" sstring from input stream.\n"); 00108 }else{ 00109 *error = e; 00110 } 00111 free(grid); 00112 return NULL; 00113 } 00114 if(g_strcmp0(grid1_string, "Grid1")) { 00115 *error = g_error_new(DOTCODE_GRID1_GERROR_DOMAIN, 12, "dotcode::grid1::get_from_GFile: Failure reading grid1 stream: string (%s) did not match expected string (%s)\n", grid1_string, "Grid1"); 00116 free(grid); 00117 return NULL; 00118 } 00119 e = NULL; 00120 free(grid1_string); 00121 grid1_string = dotcode_read_sstring(little_endian, (GInputStream*)fis, &e); 00122 if((grid1_string == NULL) || (e != NULL)) { 00123 if(e == NULL) { 00124 *error = g_error_new(DOTCODE_GRID1_GERROR_DOMAIN, 12, "dotcode::grid1::get_from_GFile: Failed to read \"1\" sstring from input stream.\n"); 00125 }else{ 00126 *error = e; 00127 } 00128 free(grid); 00129 return NULL; 00130 } 00131 if(g_strcmp0(grid1_string, "1")) { 00132 *error = g_error_new(DOTCODE_GRID1_GERROR_DOMAIN, 12, "dotcode::grid1::get_from_GFile: Failure reading grid1 stream: string (%s) did not match expected string (%s)\n", grid1_string, "1"); 00133 free(grid); 00134 return NULL; 00135 } 00136 free(grid1_string); 00137 /*Read in ignored int, Nxyz, and number of materials*/ 00138 int N_materials = -1; 00139 for(int i=0; i<5; i++) { 00140 e = NULL; 00141 int j = dotcode_read_int(little_endian, (GInputStream*)fis, &e); 00142 if(e != NULL) { 00143 *error = g_error_new(DOTCODE_GRID1_GERROR_DOMAIN, 12, "dotcode::grid1::get_from_GFile: Failed to read header int %d from input stream. (error=%s)", i, e->message); 00144 g_error_free(e); 00145 free(grid); 00146 return NULL; 00147 } 00148 if((i > 0) && (i < 4)) { 00149 grid->N[i-1]=j; 00150 }else if(i==4) { 00151 N_materials = j; 00152 } 00153 } 00154 /*Set up the materials storage.*/ 00155 grid->materials = (char**)malloc((N_materials+1)*sizeof(char*)); 00156 if(grid->materials == NULL) { 00157 *error = g_error_new(DOTCODE_GRID1_GERROR_DOMAIN, DOTCODE_ERROR_MALLOCFAIL, "dotcode::grid1::get_from_GFile: Failed to allocate material name storage.\n"); 00158 free(grid); 00159 return NULL; 00160 } 00161 /*allocate storage for the unsigned chars.*/ 00162 grid->assignments = (unsigned char*)malloc(sizeof(unsigned char)*(grid->N[0])*(grid->N[1])*(grid->N[2])); 00163 if(grid->assignments == NULL) { 00164 *error = g_error_new(DOTCODE_GRID1_GERROR_DOMAIN, DOTCODE_ERROR_MALLOCFAIL, "dotcode::grid1::get_from_GFile: Failed to allocate material assignment storage.\n"); 00165 free(grid->materials); 00166 free(grid); 00167 return NULL; 00168 } 00169 /*Set the last pointer to NULL to indicate the last one.*/ 00170 (grid->materials)[N_materials] = NULL; 00171 /*Now read in N_materials materials*/ 00172 #ifdef DEBUG3 00173 fprintf(stderr, "N_materials=%d:", N_materials); 00174 #endif 00175 for(int i=0; i<N_materials; i++) { 00176 e = NULL; 00177 (grid->materials)[i] = dotcode_read_sstring(little_endian, (GInputStream*)fis, &e); 00178 if(e != NULL) { 00179 *error = g_error_new(DOTCODE_GRID1_GERROR_DOMAIN, 12, "dotcode::grid1::get_from_GFile: Failed to read %d-th material sstring in header (error=%s)", i, e->message); 00180 g_error_free(e); 00181 for(int j=0; j<i; j++) { 00182 free(grid->materials[j]); 00183 } 00184 free(grid->assignments); 00185 free(grid); 00186 return NULL; 00187 } 00188 #ifdef DEBUG3 00189 fprintf(stderr, "%s, ", grid->materials[i]); 00190 #endif 00191 } 00192 #ifdef DEBUG3 00193 fprintf(stderr, "\n"); 00194 #endif 00195 /*We read in another, identical-number-of-sstrings section that's ignored.*/ 00196 for(int i=0; i<N_materials; i++) { 00197 e = NULL; 00198 free(dotcode_read_sstring(little_endian, (GInputStream*)fis, &e)); 00199 if(e != NULL) { 00200 *error = g_error_new(DOTCODE_GRID1_GERROR_DOMAIN, 12, "dotcode::grid1::get_from_GFile: Failed to read %d-th ignored sstring in header (error=%s)", i, e->message); 00201 g_error_free(e); 00202 g_strfreev(grid->materials); 00203 free(grid->assignments); 00204 free(grid); 00205 return NULL; 00206 } 00207 } 00208 /*We now read in 3 ignored ints*/ 00209 for(int i=0; i<3; i++) { 00210 e = NULL; 00211 dotcode_read_int(little_endian, (GInputStream*)fis, &e); 00212 if(e != NULL) { 00213 *error = g_error_new(DOTCODE_GRID1_GERROR_DOMAIN, 12, "dotcode::grid1::get_from_GFile: Failed to read ignored header int %d from input stream (error=%s)", i, e->message); 00214 g_error_free(e); 00215 g_strfreev(grid->materials); 00216 free(grid->assignments); 00217 free(grid); 00218 return NULL; 00219 } 00220 } 00221 /*And 15 float8s, which starts with 12 ignored ones and then 3 that have the grid spacings*/ 00222 for(int i=0; i<15; i++) { 00223 double j = dotcode_read_float8(little_endian, (GInputStream*)fis, &e); 00224 #ifdef DEBUG3 00225 fprintf(stderr, "%d=%g\n", i, j); 00226 #else 00227 j=j; 00228 #endif 00229 if(e != NULL) { 00230 *error = g_error_new(DOTCODE_GRID1_GERROR_DOMAIN, 12, "dotcode::grid1::get_from_GFile: Failed to read header double %d from input stream (error=%s)", i, e->message); 00231 g_error_free(e); 00232 g_strfreev(grid->materials); 00233 free(grid->assignments); 00234 free(grid); 00235 return NULL; 00236 } 00237 } 00238 for(int j=0; j<3; j++) { 00239 for(int i=0; i<grid->N[j]; i++) { 00240 double val = dotcode_read_float8(little_endian, (GInputStream*)fis, &e); 00241 if(e != NULL) { 00242 *error = g_error_new(DOTCODE_GRID1_GERROR_DOMAIN, 12, "dotcode::grid1::get_from_GFile: Failed to read header double %d from input stream (error=%s)", i, e->message); 00243 g_error_free(e); 00244 g_strfreev(grid->materials); 00245 free(grid->assignments); 00246 free(grid); 00247 return NULL; 00248 } 00249 /*There are a sequence of floats which we assume will be the 00250 *same (same grid spacing for each grid site along a given 00251 *direction; otherwise, we'd need a list of dx[3][N[i]] to store 00252 *the grid site lengths 00253 */ 00254 if(i != 0) { 00255 /*Precision is irrelevant; we put the bits in there, and they 00256 should be the same for every point along the axis*/ 00257 if(grid->dx[j] != val) { 00258 *error = g_error_new(DOTCODE_GRID1_GERROR_DOMAIN, 12, "dotcode::grid1::get_from_GFile: Error while processing dx[%d]: set value is %g, but the %dth value is %g", j, grid->dx[j], i, val); 00259 g_error_free(e); 00260 g_strfreev(grid->materials); 00261 free(grid->assignments); 00262 free(grid); 00263 return NULL; 00264 } 00265 }else{ 00266 grid->dx[j] = val; 00267 } 00268 #ifdef DEBUG3 00269 fprintf(stderr, "dx[%d](%d/%d)=%g(%g)\n", j, i, grid->N[j], grid->dx[j], val); 00270 #endif 00271 } 00272 } 00273 00274 /*We now have a giant array of unsigned chars, but we can just read them in all at once.*/ 00275 00276 e = NULL; 00277 if((!g_input_stream_read_all((GInputStream*)fis, grid->assignments, (grid->N[0])*(grid->N[1])*(grid->N[2]), &sz, NULL, &e)) || (sz != (grid->N[0])*(grid->N[1])*(grid->N[2]))) { 00278 if(e == NULL) { 00279 *error = g_error_new(DOTCODE_GRID1_GERROR_DOMAIN, 12, "dotcode::grid1::get_from_GFile: Failed to read material assignments (%lu bytes) from the stream: got %lu bytes", (long unsigned int)(grid->N[0])*(grid->N[1])*(grid->N[2]), (long unsigned int)sz ); 00280 }else{ 00281 *error = e; 00282 } 00283 g_strfreev(grid->materials); 00284 free(grid->assignments); 00285 free(grid); 00286 return NULL; 00287 } 00288 00289 /*Close the file; we're done*/ 00290 g_input_stream_close((GInputStream*)fis, NULL, &e); 00291 /*Be paranoid. An error here means we have corrupted data somewhere. 00292 It seems likely to me that this will be true. And paranoia when it comes 00293 to data integrity is Good. In fact, I should probably look into HDF 00294 checksumming.*/ 00295 if(e != NULL) { 00296 g_strfreev(grid->materials); 00297 free(grid->assignments); 00298 free(grid); 00299 *error = e; 00300 return NULL; 00301 } 00302 return grid; 00303 } 00304 00305 00306 double* dotcode_grid1_get_property_grid(const struct dotcode_grid1* grid, const struct matdb *mdb, const char* property, GError **err) { 00307 double* props = (double*)malloc((grid->N[0])*(grid->N[1])*(grid->N[2])*sizeof(double)); 00308 if(props == NULL) { 00309 *err = g_error_new(DOTCODE_GRID1_GERROR_DOMAIN, DOTCODE_ERROR_MALLOCFAIL, "libdotcode::grid1::dotcode_grid1_get_property_grid: ERROR: failed to allocate memory for the property grid"); 00310 return NULL; 00311 } 00312 GError *e = NULL; 00313 double *propcache = dotcode_grid1_get_property_cache(grid, mdb, property, &e); 00314 if((propcache == NULL) || (e != NULL)) { 00315 g_propagate_prefixed_error(err, e, "libdotcode::grid1::get_property_grid: Unable to set up the property cache!"); 00316 free(props); 00317 return NULL; 00318 } 00319 int N_mats; 00320 for(N_mats=0; grid->materials[N_mats]!=NULL; N_mats++); 00321 int ierror; 00322 for(int i=0; i<N_mats; i++) { 00323 propcache[i] = get_property(mdb, property, grid->materials[i], &ierror); 00324 if(ierror != 0) { 00325 *err = g_error_new(DOTCODE_GRID1_GERROR_DOMAIN, DOTCODE_GRID1_ERROR_NOSUCHPROPERTY, "libdotcode::grid1::dotcode_grid1_get_property_grid: ERROR: unable to find property %s in for material %s in the material database.", property, grid->materials[i]); 00326 free(propcache); 00327 free(props); 00328 return NULL; 00329 } 00330 } 00331 for(int k=0; k<(grid->N[2]); k++) { 00332 for(int j=0; j<(grid->N[1]); j++) { 00333 for(int i=0; i<(grid->N[0]); i++) { 00334 props[get_assignment_index(i, j, k, grid->N[0], grid->N[1])] = propcache[grid->assignments[get_assignment_index(i, j, k, grid->N[0], grid->N[1])]]; 00335 } 00336 } 00337 } 00338 free(propcache); 00339 return props; 00340 } 00341 00342 double dotcode_grid1_get_property_at_site(const struct dotcode_grid1* grid, const struct matdb *mdb, const char* property, const int* index, GError **err) { 00343 int mat = grid->assignments[get_assignment_index(index[0], index[1], index[2], grid->N[0], grid->N[1])]; 00344 int ierror=0; 00345 double ppt = get_property(mdb, property, grid->materials[mat], &ierror); 00346 if(ierror != 0) { 00347 *err = g_error_new(DOTCODE_GRID1_GERROR_DOMAIN, DOTCODE_GRID1_ERROR_NOSUCHPROPERTY, "libdotcode::grid1::dotcode_grid1_get_property_at_site: ERROR: got error %d (probably couldn't find property %s in for material %s in the material database).", ierror, property, grid->materials[mat]); 00348 } 00349 return ppt; 00350 } 00351 00352 double dotcode_grid1_get_property_at_site_cached(const struct dotcode_grid1* grid, const double* propcache, const int* index) { 00353 return propcache[grid->assignments[get_assignment_index(index[0], index[1], index[2], grid->N[0], grid->N[1])]]; 00354 } 00355 00356 void dotcode_grid1_write_assignments_slice_text(const struct dotcode_grid1* grid, GFile* base, enum dotcode_coord coord, int index, GError **err) { 00357 GError *e; 00358 GString *s = g_string_new("matslice_");; 00359 switch(coord) { 00360 case DOTCODE_COORD_X: 00361 g_string_append_printf(s, "X=%d.pdata", index); 00362 break; 00363 case DOTCODE_COORD_Y: 00364 g_string_append_printf(s, "Y=%d.pdata", index); 00365 break; 00366 case DOTCODE_COORD_Z: 00367 g_string_append_printf(s, "Z=%d.pdata", index); 00368 break; 00369 } 00370 GFile* f; 00371 if(base == NULL) { 00372 f = g_file_new_for_path(s->str); 00373 }else{ 00374 f = g_file_resolve_relative_path(base, s->str); 00375 } 00376 e = NULL; 00377 GFileIOStream *gfos = g_file_create_readwrite(f, G_FILE_CREATE_REPLACE_DESTINATION, NULL, &e); 00378 if(e != NULL) { 00379 *err = e; 00380 return; 00381 } 00382 GOutputStream *os = g_io_stream_get_output_stream((GIOStream*)gfos); 00383 GDataOutputStream *dos = g_data_output_stream_new(os); 00384 g_string_printf(s, "#index\tmaterial\n"); 00385 e=NULL; 00386 char *str; 00387 g_data_output_stream_put_string(dos, s->str, NULL, &e); 00388 if(e != NULL) { 00389 *err = e; 00390 g_string_free(s, TRUE); 00391 e=NULL; 00392 g_io_stream_close((GIOStream*)gfos, NULL, &e); 00393 if(e != NULL) { 00394 *err = g_error_new(DOTCODE_GRID1_GERROR_DOMAIN, DOTCODE_ERROR_ERRORED_THEN_CLOSED_ERROR, "libdotcode::grid1::dotcode_grid1_write_assignment_text: had an error (%s) while writing string (%s), but had another error (%s) while closing the file (%s)!\n", (*err)->message, s->str, e->message, str=g_file_get_uri(f)); 00395 g_free(str); 00396 } 00397 return; 00398 } 00399 for(int i=0; (grid->materials)[i] != NULL; i++) { 00400 g_string_printf(s, "#%i\t%s\n", i, (grid->materials)[i]); 00401 e=NULL; 00402 char *str; 00403 g_data_output_stream_put_string(dos, s->str, NULL, &e); 00404 if(e != NULL) { 00405 *err = e; 00406 g_string_free(s, TRUE); 00407 e=NULL; 00408 g_io_stream_close((GIOStream*)gfos, NULL, &e); 00409 if(e != NULL) { 00410 *err = g_error_new(DOTCODE_GRID1_GERROR_DOMAIN, DOTCODE_ERROR_ERRORED_THEN_CLOSED_ERROR, "libdotcode::grid1::dotcode_grid1_write_assignment_text: had an error (%s) while writing string (%s), but had another error (%s) while closing the file (%s)!\n", (*err)->message, s->str, e->message, str=g_file_get_uri(f)); 00411 g_free(str); 00412 } 00413 return; 00414 } 00415 } 00416 switch(coord) { 00417 case DOTCODE_COORD_X: 00418 g_string_printf(s, "#Y()\tZ(sites)\tmaterial index\n"); 00419 break; 00420 case DOTCODE_COORD_Y: 00421 g_string_printf(s, "#X(sites)\tZ(sites)\tmaterial index\n"); 00422 break; 00423 case DOTCODE_COORD_Z: 00424 g_string_printf(s, "#X(sites)\tY(sites)\tmaterial index\n"); 00425 break; 00426 } 00427 e=NULL; 00428 g_data_output_stream_put_string(dos, s->str, NULL, &e); 00429 if(e != NULL) { 00430 *err = e; 00431 g_string_free(s, TRUE); 00432 e=NULL; 00433 g_io_stream_close((GIOStream*)gfos, NULL, &e); 00434 if(e != NULL) { 00435 *err = g_error_new(DOTCODE_GRID1_GERROR_DOMAIN, DOTCODE_ERROR_ERRORED_THEN_CLOSED_ERROR, "libdotcode::grid1::dotcode_grid1_write_assignment_text: had an error (%s) while writing string (%s), but had another error (%s) while closing the file (%s)!\n", (*err)->message, s->str, e->message, str=g_file_get_uri(f)); 00436 g_free(str); 00437 } 00438 return; 00439 } 00440 for(int k=0; k<grid->N[2]; k++) { 00441 if((coord == DOTCODE_COORD_Z) && (k != index)) continue; 00442 for(int j=0; j<grid->N[1]; j++) { 00443 if((coord == DOTCODE_COORD_Y) && (j != index)) continue; 00444 for(int i=0; i<grid->N[0]; i++) { 00445 if((coord == DOTCODE_COORD_X) && (i != index)) continue; 00446 e=NULL; 00447 switch(coord) { 00448 case DOTCODE_COORD_X: 00449 g_string_printf(s, "%d\t%d\t%d\n", j, k, grid->assignments[get_assignment_index(i, j, k, grid->N[0], grid->N[1])]); 00450 break; 00451 case DOTCODE_COORD_Y: 00452 g_string_printf(s, "%d\t%d\t%d\n", i, k, grid->assignments[get_assignment_index(i, j, k, grid->N[0], grid->N[1])]); 00453 break; 00454 case DOTCODE_COORD_Z: 00455 g_string_printf(s, "%d\t%d\t%d\n", i, j, grid->assignments[get_assignment_index(i, j, k, grid->N[0], grid->N[1])]); 00456 break; 00457 } 00458 g_data_output_stream_put_string(dos, s->str, NULL, &e); 00459 if(e != NULL) { 00460 *err = e; 00461 g_string_free(s, TRUE); 00462 e=NULL; 00463 g_io_stream_close((GIOStream*)gfos, NULL, &e); 00464 if(e != NULL) { 00465 *err = g_error_new(DOTCODE_GRID1_GERROR_DOMAIN, DOTCODE_ERROR_ERRORED_THEN_CLOSED_ERROR, "libdotcode::grid1::dotcode_grid1_write_assignment_text: had an error (%s) while writing string (%s), but had another error (%s) while closing the file (%s)!\n", (*err)->message, s->str, e->message, str=g_file_get_uri(f)); 00466 g_free(str); 00467 } 00468 return; 00469 } 00470 } 00471 } 00472 } 00473 g_io_stream_close((GIOStream*)gfos, NULL, &e); 00474 if(e != NULL) { 00475 *err = e; 00476 } 00477 g_string_free(s, TRUE); 00478 } 00479 00480 void dotcode_grid1_write_property_slice_text(const struct dotcode_grid1* grid, const double* property_array, const char* property_name, GFile* base, enum dotcode_coord coord, int index, GError **err) { 00481 GError *e; 00482 GString *s = g_string_new("propslice_");; 00483 switch(coord) { 00484 case DOTCODE_COORD_X: 00485 g_string_append_printf(s, "X=%d.pdata", index); 00486 break; 00487 case DOTCODE_COORD_Y: 00488 g_string_append_printf(s, "Y=%d.pdata", index); 00489 break; 00490 case DOTCODE_COORD_Z: 00491 g_string_append_printf(s, "Z=%d.pdata", index); 00492 break; 00493 } 00494 GFile* f; 00495 if(base == NULL) { 00496 f = g_file_new_for_path(s->str); 00497 }else{ 00498 f = g_file_resolve_relative_path(base, s->str); 00499 } 00500 e = NULL; 00501 GFileIOStream *gfos = g_file_create_readwrite(f, G_FILE_CREATE_REPLACE_DESTINATION, NULL, &e); 00502 if(e != NULL) { 00503 *err = e; 00504 return; 00505 } 00506 GOutputStream *os = g_io_stream_get_output_stream((GIOStream*)gfos); 00507 GDataOutputStream *dos = g_data_output_stream_new(os); 00508 switch(coord) { 00509 case DOTCODE_COORD_X: 00510 g_string_printf(s, "#Y()\tZ(sites)\t%s\n", property_name); 00511 break; 00512 case DOTCODE_COORD_Y: 00513 g_string_printf(s, "#X(sites)\tZ(sites)\t%s\n", property_name); 00514 break; 00515 case DOTCODE_COORD_Z: 00516 g_string_printf(s, "#X(sites)\tY(sites)\t%s\n", property_name); 00517 break; 00518 } 00519 e=NULL; 00520 g_data_output_stream_put_string(dos, s->str, NULL, &e); 00521 char* str; 00522 if(e != NULL) { 00523 *err = e; 00524 g_string_free(s, TRUE); 00525 e=NULL; 00526 g_io_stream_close((GIOStream*)gfos, NULL, &e); 00527 if(e != NULL) { 00528 *err = g_error_new(DOTCODE_GRID1_GERROR_DOMAIN, DOTCODE_ERROR_ERRORED_THEN_CLOSED_ERROR, "libdotcode::grid1::dotcode_grid1_write_property_text: had an error (%s) while writing string (%s), but had another error (%s) while closing the file (%s)!\n", (*err)->message, s->str, e->message, str=g_file_get_uri(f)); 00529 g_free(str); 00530 } 00531 return; 00532 } 00533 for(int k=0; k<grid->N[2]; k++) { 00534 if((coord == DOTCODE_COORD_Z) && (k != index)) continue; 00535 for(int j=0; j<grid->N[1]; j++) { 00536 if((coord == DOTCODE_COORD_Y) && (j != index)) continue; 00537 for(int i=0; i<grid->N[0]; i++) { 00538 if((coord == DOTCODE_COORD_X) && (i != index)) continue; 00539 e=NULL; 00540 switch(coord) { 00541 case DOTCODE_COORD_X: 00542 g_string_printf(s, "%d\t%d\t%g\n", j, k, property_array[get_assignment_index(i, j, k, grid->N[0], grid->N[1])]); 00543 break; 00544 case DOTCODE_COORD_Y: 00545 g_string_printf(s, "%d\t%d\t%g\n", i, k, property_array[get_assignment_index(i, j, k, grid->N[0], grid->N[1])]); 00546 break; 00547 case DOTCODE_COORD_Z: 00548 g_string_printf(s, "%d\t%d\t%g\n", i, j, property_array[get_assignment_index(i, j, k, grid->N[0], grid->N[1])]); 00549 break; 00550 } 00551 g_data_output_stream_put_string(dos, s->str, NULL, &e); 00552 if(e != NULL) { 00553 *err = e; 00554 g_string_free(s, TRUE); 00555 e=NULL; 00556 g_io_stream_close((GIOStream*)gfos, NULL, &e); 00557 if(e != NULL) { 00558 *err = g_error_new(DOTCODE_GRID1_GERROR_DOMAIN, DOTCODE_ERROR_ERRORED_THEN_CLOSED_ERROR, "libdotcode::grid1::dotcode_grid1_write_property_text: had an error (%s) while writing string (%s), but had another error (%s) while closing the file (%s)!\n", (*err)->message, s->str, e->message, str=g_file_get_uri(f)); 00559 g_free(str); 00560 } 00561 return; 00562 } 00563 } 00564 } 00565 } 00566 g_io_stream_close((GIOStream*)gfos, NULL, &e); 00567 if(e != NULL) { 00568 *err = e; 00569 } 00570 g_string_free(s, TRUE); 00571 } 00572 00573 double* dotcode_grid1_get_property_cache(const struct dotcode_grid1* grid, const struct matdb* mdb, const char* property_name, GError **err) { 00574 int N_mats; 00575 for(N_mats=0; grid->materials[N_mats]!=NULL; N_mats++); 00576 double* cache = (double*)malloc(N_mats*sizeof(double)); 00577 if(cache == NULL) { 00578 *err = g_error_new(DOTCODE_GRID1_GERROR_DOMAIN, DOTCODE_ERROR_MALLOCFAIL, "libdotcode::grid1::dotcode_grid1_get_property_cache: ERROR: unable to allocate memory for the property cache (property=%s)", property_name); 00579 return NULL; 00580 } 00581 int ierror=0; 00582 for(int i=0; i<N_mats; i++) { 00583 cache[i] = get_property(mdb, property_name, grid->materials[i], &ierror); 00584 if(ierror != 0) { 00585 *err = g_error_new(DOTCODE_GRID1_GERROR_DOMAIN, DOTCODE_GRID1_ERROR_NOSUCHPROPERTY, "libdotcode::grid1::dotcode_grid1_get_property_cache: ERROR: %d; probably unable to find property %s in for material %s in the material database.", ierror, property_name, grid->materials[i]); 00586 free(cache); 00587 return NULL; 00588 } 00589 } 00590 return cache; 00591 }