00001
00031 static char *SCCSID = "@(#)grid_io.c 1.10 05/22/00 SFWMD Research and Planning Departments";
00032
00033
00034
00035
00036
00037
00038
00039
00040
00041
00042
00043
00044
00045
00046
00047
00048
00049
00050
00051
00052
00053
00054
00055
00056
00057
00058
00059
00060
00061
00062
00063
00064
00065
00066
00067
00068
00069
00070
00071
00072
00073
00074
00075
00076
00077
00078
00079
00080 #define GCC_COMPILER 1
00081 #include <stdio.h>
00082 #include <string.h>
00083 #include <ctype.h>
00084
00085 #include <stdarg.h>
00086 #include <stdlib.h>
00087
00088 #include "grid_io.h"
00089
00090 #define TOO_MANY_NODES 10000
00091 #ifndef TRUE
00092 #define TRUE 1
00093 #define FALSE 0
00094 #endif
00095
00096
00097
00115 #ifdef i386
00116 #define Flip_int16(type) ((((type) >>8) & 0x00ff) | (((type) <<8) & 0xff00))
00117 #define Flip_int16_ip(type) (*(type)=(((*(type) >>8) & 0x00ff) | ((*(type) <<8) & 0xff00)))
00118 #define Flip_int32(type) ((((type) >>24) & 0x000000ff) | (((type) >> 8) & 0x0000ff00) | (((type) << 8) & 0x00ff0000) | (((type) << 24) & 0xff000000) )
00119 #define Flip_int32_ip(type) (*(type)=(((*(type) >>24) & 0x000000ff) | ((*(type) >> 8) & 0x0000ff00) | ((*(type) << 8) & 0x00ff0000) | ((*(type) << 24) & 0xff000000) ))
00120 #define Flip_float_ip(type) (Flip_int32_ip((long *)(type)))
00121 #else
00122 #define Flip_int16(type) (type)
00123 #define Flip_int16_ip(type) (*(type))
00124 #define Flip_int32(type) (type)
00125 #define Flip_int32_ip(type) (*(type))
00126 #define Flip_float_ip(type) (*(type))
00127 #endif
00128
00129
00130 void grid_io_fatal(char *name, char *message);
00131 void F77_to_C_string(char *dest, char *src, int length);
00132 void C_to_F77_string(char *dest, char *src, int length);
00133 int openfilef77_(int *unit, char *filename, char *access, int filename_len, int access_len);
00134 int closefilef77_(int *unit);
00135 FILE *getfilep_(int *unit);
00136
00137 static GRID fortran_grid = {0};
00138 GR_FORTRAN_FILE *gr_fortran_file_list = 0;
00139
00140
00141
00142
00143
00144
00146 int grid_write_header(FILE *file, GRID *grid)
00147 {
00148 int array_size, errs;
00149 int *tmp_xstart, *tmp_xend, *tmp_cum_node_count;
00150 errs = 0;
00151 tmp_xstart = grid->config.xstart;
00152 tmp_xend = grid->config.xend;
00153 tmp_cum_node_count = grid->config.cum_node_count;
00154
00155 {
00156 GR_HEADER tmpHeader;
00157 strncpy(tmpHeader.title, grid->header.title, GRID_TITLE_LENGTH);
00158 tmpHeader.number_of_rows = Flip_int32(grid->header.number_of_rows);
00159 tmpHeader.number_of_nodes = Flip_int32(grid->header.number_of_nodes);
00160 tmpHeader.size.x = grid->header.size.x;
00161 Flip_float_ip(&(tmpHeader.size.x));
00162 tmpHeader.size.y = grid->header.size.y;
00163 Flip_float_ip(&(tmpHeader.size.y));
00164 if (fwrite(&tmpHeader, sizeof(GR_HEADER), 1, file) == 0)
00165 ++errs;
00166 }
00167
00168 if (grid->header.number_of_rows < MAX_GRID_ROWS)
00169 array_size = MAX_GRID_ROWS;
00170 else
00171 array_size = grid->header.number_of_rows;
00172
00173 #ifdef i386
00174 {
00175 int i;
00176 tmp_xstart = (int *) malloc(array_size * sizeof(int));
00177 memcpy(tmp_xstart, grid->config.xstart, array_size * sizeof(int));
00178
00179 tmp_xend = (int *) malloc(array_size * sizeof(int));
00180 memcpy(tmp_xend, grid->config.xend, array_size * sizeof(int));
00181
00182 tmp_cum_node_count = (int *) malloc(array_size * sizeof(int));
00183 memcpy(tmp_cum_node_count, grid->config.cum_node_count, array_size * sizeof(int));
00184
00185 for (i=0; i<array_size; ++i) {
00186 Flip_int32_ip(tmp_xstart+i);
00187 Flip_int32_ip(tmp_xend+i);
00188 Flip_int32_ip(tmp_cum_node_count+i);
00189 }
00190 }
00191 #endif
00192 if (fwrite(tmp_xstart, sizeof(int), array_size, file) == 0)
00193 ++errs;
00194 if (fwrite(tmp_xend, sizeof(int), array_size, file) == 0)
00195 ++errs;
00196 if (fwrite(tmp_cum_node_count, sizeof(int), array_size, file) == 0)
00197 ++errs;
00198
00199 if (errs)
00200 grid_io_fatal("write_grid_header", "Unable to write file header\n");
00201
00202 #ifdef i386
00203 free(tmp_xstart); free(tmp_xend); free(tmp_cum_node_count);
00204 #endif
00205
00206 return (0);
00207 }
00208
00209
00210
00211
00212
00213
00214
00216 void gridwhd_(int *fd, int *errs)
00217 {
00218 FILE *file;
00219 file = getfilep_(fd);
00220
00221 *errs = grid_write_header(file, &fortran_grid);
00222 }
00223
00224
00225
00226
00227
00228
00229
00230
00235 int grid_read_header(FILE *file, GRID *grid)
00236 {
00237 int errs = 0, num_read, array_size;
00238
00239 if ((num_read = fread(&grid->header, sizeof(GR_HEADER), 1, file)) == 0) {
00240 if (feof(file))
00241 errs = -1;
00242 else
00243 grid_io_fatal("read_grid_header", "Unable to read header from file\n");
00244 }
00245 Flip_int32_ip(&(grid->header.number_of_rows));
00246 Flip_int32_ip(&(grid->header.number_of_nodes));
00247 Flip_float_ip(&(grid->header.size.x));
00248 Flip_float_ip(&(grid->header.size.y));
00249
00250 if (grid->header.number_of_rows < MAX_GRID_ROWS)
00251 array_size = MAX_GRID_ROWS;
00252 else
00253 array_size = grid->header.number_of_rows;
00254
00255
00256 grid->config.xstart = (int *) malloc(array_size * sizeof(int));
00257
00258 grid->config.xend = (int *) malloc(array_size * sizeof(int));
00259
00260 grid->config.cum_node_count = (int *) malloc(array_size * sizeof(int));
00261
00262 if ((num_read = fread(grid->config.xstart, sizeof(int), array_size, file)) == 0) {
00263 if (feof(file))
00264 errs = -1;
00265 else
00266 grid_io_fatal("read_grid_header", "Unable to read header from file\n");
00267 }
00268
00269 if ((num_read = fread(grid->config.xend, sizeof(int), array_size, file)) == 0) {
00270 if (feof(file))
00271 errs = -1;
00272 else
00273 grid_io_fatal("read_grid_header", "Unable to read header from file\n");
00274 }
00275
00276 if ((num_read = fread(grid->config.cum_node_count, sizeof(int), array_size, file)) == 0) {
00277 if (feof(file))
00278 errs = -1;
00279 else
00280 grid_io_fatal("read_grid_header", "Unable to read header from file\n");
00281 }
00282
00283 #ifdef i386
00284 {
00285 int i;
00286 for (i=0; i<array_size; ++i) {
00287 Flip_int32_ip(grid->config.xstart+i);
00288 Flip_int32_ip(grid->config.xend+i);
00289 Flip_int32_ip(grid->config.cum_node_count+i);
00290 }
00291 }
00292 #endif
00293 return(errs);
00294 }
00295
00296
00304 void gridrhd_(int *fd, int *errs)
00305 {
00306 FILE *file;
00307 file = getfilep_(fd);
00308 *errs = grid_read_header(file, &fortran_grid);
00309 }
00310
00311
00312
00313
00314
00315
00317 int grid_write(FILE *file, GRID *grid, char *tag, float *values)
00318 {
00319 char *char_ptr;
00320 int written, errs = 0;
00321 float *tmp_values = values;
00322
00323 if ((written = fwrite(tag, sizeof(char), GRID_TAG_LENGTH, file)) == 0)
00324 grid_io_fatal("grid_write", "Unable to write grid tag\n");
00325 if (written < GRID_TAG_LENGTH) errs++;
00326 #ifdef i386
00327 {
00328 int i;
00329 tmp_values = (float *) malloc(grid->header.number_of_nodes * sizeof(float));
00330 memcpy(tmp_values, values, grid->header.number_of_nodes * sizeof(float));
00331 for (i=0; i<grid->header.number_of_nodes; ++i) {
00332 Flip_float_ip(tmp_values+i);
00333 }
00334 }
00335 #endif
00336 if ((written = fwrite(tmp_values, sizeof(float), grid->header.number_of_nodes, file)) == 0)
00337 grid_io_fatal("grid_write", "Unable to write grid data\n");
00338
00339 if (written < grid->header.number_of_nodes) errs++;
00340 #ifdef i386
00341 free (tmp_values);
00342 #endif
00343 return(errs);
00344
00345 }
00346
00347
00348
00349
00350
00352 void gwrite_(int *fd, char *tag, float *values, int *errs, int tag_len)
00353 {
00354 char buf[GRID_TAG_LENGTH];
00355 FILE *file;
00356
00357 file = getfilep_(fd);
00358 F77_to_C_string(buf, tag, ((tag_len < GRID_TAG_LENGTH) ? tag_len : GRID_TAG_LENGTH));
00359 *errs = grid_write(file, &fortran_grid, buf, values);
00360 }
00361
00362
00363
00364
00365
00366
00367
00374 int grid_read(FILE *file, GRID *grid, char *tag, float *values)
00375 {
00376 int num_read, errs = 0;
00377
00378
00379 if ((num_read = fread(tag, sizeof(char), GRID_TAG_LENGTH, file)) == 0) {
00380 if (feof(file))
00381 return (-1);
00382 else
00383 grid_io_fatal("grid_read", "Uable to read grid tag\n");
00384 }
00385 if (num_read != GRID_TAG_LENGTH) errs++;
00386
00387
00388 if ((num_read = fread(values, sizeof(float), grid->header.number_of_nodes, file)) == 0)
00389 grid_io_fatal("grid_read", "Unable to read data\n");
00390 #ifdef i386
00391 {
00392 int i;
00393 for (i=0; i<grid->header.number_of_nodes; ++i) {
00394 Flip_float_ip(values+i);
00395 }
00396 }
00397 #endif
00398 if (num_read != grid->header.number_of_nodes) errs++;
00399 return (errs);
00400 }
00401
00402
00403
00404
00405
00407 void gread_(int *fd, char *tag, float *values, int *errs, int tag_len)
00408 {
00409 char buf[GRID_TAG_LENGTH];
00410 FILE *file;
00411
00412 file = getfilep_(fd);
00413 *errs = grid_read(file, &fortran_grid, buf, values);
00414 C_to_F77_string(tag, buf, ((tag_len < GRID_TAG_LENGTH) ? tag_len : GRID_TAG_LENGTH));
00415 }
00416
00417
00418
00419
00420
00421
00427 int grid_skip(FILE *file, GRID *grid, int count)
00428 {
00429 int header_size, array_size;
00430 int errs = 0;
00431 long int rec_len = GRID_TAG_LENGTH*sizeof(char) +
00432 grid->header.number_of_nodes*sizeof(float);
00433 long int end, current;
00434
00435 if (count < 0) {
00436 if (grid->header.number_of_rows < MAX_GRID_ROWS)
00437 array_size = MAX_GRID_ROWS;
00438 else
00439 array_size = grid->header.number_of_rows;
00440 header_size = sizeof(GRID) + 3 * sizeof(int) * array_size;
00441 if (ftell(file) < header_size + abs(count)*rec_len)
00442 errs = grid_top(file, grid);
00443 else
00444 fseek(file, count*rec_len, 1);
00445 } else if (count > 0) {
00446 current = ftell(file);
00447 fseek(file, 0, 2);
00448 end = ftell(file);
00449 if ((end - current)/rec_len < count)
00450 errs = grid_bottom(file, grid);
00451 else
00452 errs = fseek(file, (long)(current + count*rec_len), 0);
00453 }
00454
00455 return(errs);
00456 }
00457
00458
00459
00460
00461
00462
00463
00465 void gridskp_(int *fd, int *cnt, int *errs)
00466 {
00467 FILE *file;
00468 file = getfilep_(fd);
00469 *errs = grid_skip(file, &fortran_grid, *cnt);
00470 }
00471
00472
00473
00474
00475
00476
00481 int grid_top(FILE *file, GRID *grid)
00482 {
00483 fseek(file, 0L, 0);
00484 return(grid_read_header(file, grid));
00485 }
00486
00487
00488
00489
00490
00491
00498 int grid_bottom(FILE *file,GRID *grid)
00499 {
00500 fseek(file, 0L, 2);
00501 return(grid_skip(file, grid, -1));
00502 }
00503
00504
00505
00506
00507
00508
00509
00510
00517 int grid_count_snapshots(FILE *file, GRID *grid) {
00518 int i = 0;
00519 char tag[GRID_TAG_LENGTH];
00520 float *data = (float *)malloc(grid->header.number_of_nodes*sizeof(float));
00521
00522 grid_top(file, grid);
00523 while (grid_read(file, grid, tag, data) == 0)
00524 i++;
00525 free(data);
00526 grid_top(file, grid);
00527 return(i);
00528 }
00529
00531 char *strsed(register char *string, register char *pattern, int *range);
00532
00533
00534
00535
00536
00537
00538
00539
00540
00541
00542
00543
00544
00545
00546
00547
00548
00549
00550
00551
00552
00553
00554
00555
00556
00557
00558
00559
00560
00561
00562
00563
00564
00565
00566
00567
00568
00569
00570
00571
00572
00573
00574
00575
00576
00584 int grid_node(GRID *grid, int row, int column)
00585 {
00586 if (row > 0 && row <= grid->header.number_of_rows) {
00587 if (column >= grid->config.xstart[row - 1] && column <= grid->config.xend[row - 1])
00588 return ((grid->config.cum_node_count[row - 1] - 1) + column - grid->config.xstart[row - 1] + 1);
00589 }
00590 return -1;
00591 }
00592
00593
00594
00595
00596
00598 void setgrid_(char *title, int *nrows, int *nnodes, float *xsize, float *ysize, int *xstart, int *xend, int *cum_count, int title_len)
00599 {
00600 int i, array_size;
00601
00602 F77_to_C_string(fortran_grid.header.title, title,
00603 ((title_len < GRID_TITLE_LENGTH) ? title_len : GRID_TITLE_LENGTH));
00604
00605 fortran_grid.header.number_of_rows = *nrows;
00606 fortran_grid.header.number_of_nodes = *nnodes;
00607 fortran_grid.header.size.x = *xsize;
00608 fortran_grid.header.size.y = *ysize;
00609
00610
00611 array_size = (*nrows < MAX_GRID_ROWS) ? MAX_GRID_ROWS : *nrows;
00612 fortran_grid.config.xstart = (int *) malloc(array_size * sizeof(int));
00613 fortran_grid.config.xend = (int *) malloc(array_size * sizeof(int));
00614 fortran_grid.config.cum_node_count = (int *) malloc(array_size * sizeof(int));
00615
00616 for (i = 0; i < fortran_grid.header.number_of_rows; i++) {
00617 fortran_grid.config.xstart[i] = xstart[i];
00618 fortran_grid.config.xend[i] = xend[i];
00619 fortran_grid.config.cum_node_count[i] = cum_count[i];
00620 }
00621 }
00622
00623
00624
00625
00626
00627
00628
00629
00631 void getgrid_(char *title, int *nrows, int *nnodes, float *xsize, float *ysize,
00632 int *xstart, int *xend, int *cum_count, int title_len)
00633 {
00634 int i;
00635
00636 C_to_F77_string(title,fortran_grid.header.title,
00637 ((title_len < GRID_TITLE_LENGTH) ? title_len : GRID_TITLE_LENGTH));
00638
00639 *nrows = fortran_grid.header.number_of_rows;
00640 *nnodes = fortran_grid.header.number_of_nodes;
00641 *xsize = fortran_grid.header.size.x;
00642 *ysize = fortran_grid.header.size.y;
00643 for (i = 0; i < fortran_grid.header.number_of_rows; i++) {
00644 xstart[i] = fortran_grid.config.xstart[i];
00645 xend[i] = fortran_grid.config.xend[i];
00646 cum_count[i] =fortran_grid.config.cum_node_count[i];
00647 }
00648 }
00649
00650
00651
00652
00653
00658 void grid_io_fatal(char *name, char *message)
00659 {
00660 (void) fprintf(stderr, "ERROR in %s: ", name);
00661 (void) fprintf(stderr, message);
00662 (void) abort();
00663 }
00664
00665
00666
00667
00668
00670 void F77_to_C_string(char *dest, char *src, int length)
00671 {
00672 int i;
00673 strncpy(dest, src, length);
00674 for (i = length - 1; isspace(dest[i]); i--)
00675 dest[i] = '\0';
00676 }
00677
00678
00679
00680
00681
00682
00684 void C_to_F77_string(char *dest, char *src, int length)
00685 {
00686 int i;
00687
00688 strncpy(dest,src,length);
00689 for (i = strlen(dest); i < length; i++)
00690 dest[i] = ' ';
00691 }
00692
00693
00694
00695
00696
00697
00703 int grid_free(GRID *grid)
00704 {
00705 int errs = 0;
00706
00707 free(grid->config.xstart);
00708 free(grid->config.xend);
00709 free(grid->config.cum_node_count);
00710
00711 return(errs);
00712 }
00713
00715 int openfilef77_(int *unit, char *filename, char *access, int filename_len, int access_len)
00716 {
00717 GR_FORTRAN_FILE *iFile=gr_fortran_file_list;
00718 GR_FORTRAN_FILE *prevFile=gr_fortran_file_list;
00719 char *filename_buf = (char *) malloc(sizeof(char)*(filename_len+1));
00720 char *access_buf = (char *) malloc(sizeof(char)*(access_len+1));
00721
00722 F77_to_C_string(filename_buf, filename, filename_len);
00723 F77_to_C_string(access_buf, access, access_len);
00724
00725 while (iFile != 0) {
00726 if(iFile->unit_number == *unit) {
00727 fprintf(stderr,"Error: unit %d already open, can not open file %s as unit %d\n", *unit, filename, *unit);
00728 return 0;
00729
00730 }
00731 prevFile=iFile;
00732 iFile = iFile->next;
00733 }
00734
00735 iFile = (GR_FORTRAN_FILE *) malloc(sizeof(GR_FORTRAN_FILE));
00736 if(prevFile == 0 )
00737 gr_fortran_file_list = iFile;
00738 else
00739 prevFile->next = iFile;
00740 iFile->fptr = fopen(filename_buf, access_buf);
00741 if (iFile->fptr == 0) {
00742 fprintf(stderr,"Error: can not open file \"%s\" as unit %d\n",
00743 filename_buf, *unit);
00744 }
00745 iFile->unit_number = *unit;
00746 iFile->next = 0;
00747 return 1;
00748 }
00749
00751 int closefilef77_(int *unit)
00752 {
00753 GR_FORTRAN_FILE *iFile=gr_fortran_file_list;
00754 GR_FORTRAN_FILE *prevFile=gr_fortran_file_list;
00755 while (iFile != 0) {
00756 if(iFile->unit_number == *unit) {
00757 if(iFile == gr_fortran_file_list)
00758 gr_fortran_file_list = iFile->next;
00759 else
00760 prevFile->next = iFile->next;
00761 free(iFile);
00762 return 1;
00763 }
00764 }
00765 return 0;
00766 }
00767
00769 FILE* getfilep_(int *unit)
00770 {
00771 GR_FORTRAN_FILE *iFile;
00772 for(iFile = gr_fortran_file_list; iFile!=0; iFile =iFile->next) {
00773 if(iFile->unit_number == *unit) return iFile->fptr;
00774 }
00775 return 0;
00776 }
00777