source: trunk/WRF.COMMON/WRFV2/external/io_grib2/bacio-1.3/bacio.v1.3.c @ 3567

Last change on this file since 3567 was 11, checked in by aslmd, 14 years ago

spiga@svn-planeto:ajoute le modele meso-echelle martien

File size: 16.7 KB
Line 
1/* Fortran-callable routines to read and write characther (bacio) and */
2/*   numeric (banio) data byte addressably                            */
3/* Robert Grumbine  16 March 1998 */
4/*  v1.1: Put diagnostic output under control of define VERBOSE or QUIET */
5/*        Add option of non-seeking read/write                           */
6/*        Return code for fewer data read/written than requested */
7/*  v1.2: Add cray compatibility  20 April 1998                  */
8
9#include <stdio.h>
10#include <sys/types.h>
11#include <sys/stat.h>
12#include <fcntl.h>
13#include <unistd.h>
14#include <malloc.h>
15#include <ctype.h>
16#include <string.h>
17
18/* Include the C library file for definition/control */
19/* Things that might be changed for new systems are there. */
20/* This source file should not (need to) be edited, merely recompiled */
21#include "clib.h"
22
23
24/* Return Codes:  */
25/*  0    All was well                                   */
26/* -1    Tried to open read only _and_ write only       */
27/* -2    Tried to read and write in the same call       */
28/* -3    Internal failure in name processing            */
29/* -4    Failure in opening file                        */
30/* -5    Tried to read on a write-only file             */ 
31/* -6    Failed in read to find the 'start' location    */
32/* -7    Tried to write to a read only file             */
33/* -8    Failed in write to find the 'start' location   */
34/* -9    Error in close                                 */
35/* -10   Read or wrote fewer data than requested        */
36
37/* Note: In your Fortran code, call bacio, not bacio_.  */
38/*int bacio_(int * mode, int * start, int * size, int * no, int * nactual,   */ 
39/*          int * fdes, const char *fname, char *data, int  namelen,         */ 
40/*          int  datanamelen)                                                */
41/* Arguments: */
42/* Mode is the integer specifying operations to be performed                 */
43/*    see the clib.inc file for the values.  Mode is obtained                */
44/*    by adding together the values corresponding to the operations          */
45/*    The best method is to include the clib.inc file and refer to the       */
46/*    names for the operations rather than rely on hard-coded values         */
47/* Start is the byte number to start your operation from.  0 is the first    */
48/*    byte in the file, not 1.                                               */
49/* Newpos is the position in the file after a read or write has been         */
50/*    performed.  You'll need this if you're doing 'seeking' read/write      */
51/* Size is the size of the objects you are trying to read.  Rely on the      */
52/*    values in the locale.inc file.  Types are CHARACTER, INTEGER, REAL,    */
53/*    COMPLEX.  Specify the correct value by using SIZEOF_type, where type   */
54/*    is one of these.  (After having included the locale.inc file)          */
55/* no is the number of things to read or write (characters, integers,        */
56/*                                                              whatever)    */
57/* nactual is the number of things actually read or written.  Check that     */
58/*    you got what you wanted.                                               */
59/* fdes is an integer 'file descriptor'.  This is not a Fortran Unit Number  */
60/*    You can use it, however, to refer to files you've previously opened.   */
61/* fname is the name of the file.  This only needs to be defined when you    */
62/*    are opening a file.  It must be (on the Fortran side) declared as      */
63/*    CHARACTER*N, where N is a length greater than or equal to the length   */
64/*    of the file name.  CHARACTER*1 fname[80] (for example) will fail.      */
65/* data is the name of the entity (variable, vector, array) that you want    */
66/*    to write data out from or read it in to.  The fact that C is declaring */
67/*    it to be a char * does not affect your fortran.                        */
68/* namelen - Do NOT specify this.  It is created automagically by the        */
69/*    Fortran compiler                                                       */
70/* datanamelen - Ditto                                                       */ 
71
72
73int BACIO
74(int * mode, int * start, int *newpos, int * size, int * no, 
75 int * nactual, int * fdes, const char *fname, char *datary, 
76 int  namelen, int  datanamelen) 
77{
78  int i, j, jret, seekret;
79  char *realname, *tempchar;
80  int tcharval;
81  size_t count;
82
83/* Initialization(s) */
84  *nactual = 0;
85
86/* Check for illegal combinations of options */
87  if (( BAOPEN_RONLY & *mode) &&
88     ( (BAOPEN_WONLY & *mode) || (BAOPEN_WONLY_TRUNC & *mode) || (BAOPEN_WONLY_APPEND & *mode) ) ) {
89     #ifdef VERBOSE
90       printf("illegal -- trying to open both read only and write only\n");
91     #endif
92     return -1;
93  }
94  if ( (BAREAD & *mode ) && (BAWRITE & *mode) ) {
95     #ifdef VERBOSE
96       printf("illegal -- trying to both read and write in the same call\n");
97     #endif
98     return -2;
99  }
100
101/* This section handles Fortran to C translation of strings so as to */
102/*   be able to open the files Fortran is expecting to be opened.    */
103  #ifdef CRAY90
104    namelen = _fcdlen(fcd_fname);
105    fname   = _fcdtocp(fcd_fname);
106  #endif
107
108  realname = (char *) malloc( (namelen+1) * sizeof(char) ) ;
109  if (realname == NULL) { 
110    #ifdef VERBOSE
111      printf("failed to mallocate realname %d = namelen\n", namelen);
112      fflush(stdout);
113    #endif
114    return -3;
115  }
116
117  if ( (BAOPEN_RONLY & *mode) || (BAOPEN_WONLY & *mode) || 
118       (BAOPEN_WONLY_TRUNC & *mode) || (BAOPEN_WONLY_APPEND & *mode) ||
119       (BAOPEN_RW & *mode) ) {
120    #ifdef VERBOSE
121      printf("Will be opening a file %s %d\n", fname, namelen); fflush(stdout);
122      printf("Strlen %d namelen %d\n", strlen(fname), namelen); fflush(stdout);
123    #endif
124    tempchar = (char *) malloc(sizeof(char) * 1 ) ;
125    i = 0;
126    j = 0;
127    *tempchar = fname[i];
128    tcharval = *tempchar;
129    while (i == j && i < namelen ) {
130       fflush(stdout); 
131       if ( isgraph(tcharval) ) {
132         realname[j] = fname[i];
133         j += 1;
134       }
135       i += 1;
136       *tempchar = fname[i];
137       tcharval = *tempchar;
138    }
139    #ifdef VERBOSE
140      printf("i,j = %d %d\n",i,j); fflush(stdout);
141    #endif
142    realname[j] = '\0';
143    free(tempchar);
144  } 
145   
146/* Open files with correct read/write and file permission. */
147  if (BAOPEN_RONLY & *mode) {
148    #ifdef VERBOSE
149      printf("open read only %s\n", realname);
150    #endif
151     *fdes = open(realname, O_RDONLY , S_IRWXU | S_IRWXG | S_IRWXO );
152  }
153  else if (BAOPEN_WONLY & *mode ) {
154    #ifdef VERBOSE
155      printf("open write only %s\n", realname);
156    #endif
157     *fdes = open(realname, O_WRONLY | O_CREAT , S_IRWXU | S_IRWXG | S_IRWXO );
158  }
159  else if (BAOPEN_WONLY_TRUNC & *mode ) {
160    #ifdef VERBOSE
161      printf("open write only with truncation %s\n", realname);
162    #endif
163     *fdes = open(realname, O_WRONLY | O_CREAT | O_TRUNC , S_IRWXU | S_IRWXG | S_IRWXO );
164  }
165  else if (BAOPEN_WONLY_APPEND & *mode ) {
166    #ifdef VERBOSE
167      printf("open write only with append %s\n", realname);
168    #endif
169     *fdes = open(realname, O_WRONLY | O_CREAT | O_APPEND , S_IRWXU | S_IRWXG | S_IRWXO );
170  }
171  else if (BAOPEN_RW & *mode) {
172    #ifdef VERBOSE
173      printf("open read-write %s\n", realname);
174    #endif
175     *fdes = open(realname, O_RDWR | O_CREAT , S_IRWXU | S_IRWXG | S_IRWXO );
176  }
177  else {
178    #ifdef VERBOSE
179      printf("no openings\n");
180    #endif
181  }
182  if (*fdes < 0) {
183    #ifdef VERBOSE
184      printf("error in file descriptor! *fdes %d\n", *fdes);
185    #endif
186    return -4;
187  }
188  else {
189    #ifdef VERBOSE
190      printf("file descriptor = %d\n",*fdes );
191    #endif
192  }
193
194
195/* Read data as requested */
196  if (BAREAD & *mode &&
197   ( (BAOPEN_WONLY & *mode) || (BAOPEN_WONLY_TRUNC & *mode) || (BAOPEN_WONLY_APPEND & *mode) ) ) {
198    #ifdef VERBOSE
199      printf("Error, trying to read while in write only mode!\n");
200    #endif
201    return -5;
202  }
203  else if (BAREAD & *mode ) {
204  /* Read in some data */
205    if (! (*mode & NOSEEK) ) {
206      seekret = lseek(*fdes, *start, SEEK_SET);
207      if (seekret == -1) {
208        #ifdef VERBOSE
209          printf("error in seeking to %d\n",*start);
210        #endif
211        return -6;
212      }
213      #ifdef VERBOSE
214      else {
215         printf("Seek successful, seek ret %d, start %d\n", seekret, *start);
216      }
217      #endif
218    }
219    #ifdef CRAY90
220      datary = _fcdtocp(fcd_datary);
221    #endif
222    if (datary == NULL) {
223      printf("Massive catastrophe -- datary pointer is NULL\n");
224      return -666;
225    }
226    #ifdef VERBOSE
227      printf("file descriptor, datary = %d %d\n", *fdes, (int) datary);
228    #endif
229    count = (size_t) *no;
230    jret = read(*fdes, (void *) datary, count);
231    if (jret != *no) {
232      #ifdef VERBOSE
233        printf("did not read in the requested number of bytes\n");
234        printf("read in %d bytes instead of %d \n",jret, *no);
235      #endif
236    } 
237    else {
238    #ifdef VERBOSE
239      printf("read in %d bytes requested \n", *no);
240    #endif
241    }
242    *nactual = jret;
243    *newpos = *start + jret;
244  }
245/* Done with reading */
246 
247/* See if we should be writing */
248  if ( BAWRITE & *mode && BAOPEN_RONLY & *mode ) {
249    #ifdef VERBOSE
250      printf("Trying to write on a read only file \n");
251    #endif
252     return -7;
253  }
254  else if ( BAWRITE & *mode ) {
255    if (! (*mode & NOSEEK) ) {
256      seekret = lseek(*fdes, *start, SEEK_SET);
257      if (seekret == -1) {
258      #ifdef VERBOSE
259        printf("error in seeking to %d\n",*start);
260      #endif
261        return -8;
262      }
263    }
264    #ifdef CRAY90
265      datary = _fcdtocp(fcd_datary);
266    #endif
267    if (datary == NULL) {
268      printf("Massive catastrophe -- datary pointer is NULL\n");
269      return -666;
270    }
271    #ifdef VERBOSE
272      printf("write file descriptor, datary = %d %d\n", *fdes, (int) datary);
273    #endif
274    count = (size_t) *no;
275    jret = write(*fdes, (void *) datary, count);
276    if (jret != *no) {
277    #ifdef VERBOSE
278      printf("did not write out the requested number of bytes\n");
279      printf("wrote %d bytes instead\n", jret);
280    #endif
281      *nactual = jret;
282      *newpos = *start + jret;
283    }
284    else {
285    #ifdef VERBOSE
286       printf("wrote %d bytes \n", jret);
287    #endif
288       *nactual = jret;
289       *newpos = *start + jret;
290    }
291  }
292/* Done with writing */
293   
294
295/* Close file if requested */
296  if (BACLOSE & *mode ) {
297    jret = close(*fdes);
298    if (jret != 0) { 
299    #ifdef VERBOSE
300      printf("close failed! jret = %d\n",jret);
301    #endif
302      return -9;
303    }
304  }
305/* Done closing */
306
307  free(realname);
308
309/* Check that if we were reading or writing, that we actually got what */
310/*  we expected, else return a -10.  Return 0 (success) if we're here  */
311/*  and weren't reading or writing */
312  if ( (*mode & BAREAD || *mode & BAWRITE) && (*nactual != *no) ) {
313    return -10;
314  }
315  else {
316    return 0;
317  }
318} 
319int BANIO
320(int * mode, int * start, int *newpos, int * size, int * no, 
321 int * nactual, int * fdes, const char *fname, char *datary, 
322 int  namelen ) 
323{
324  int i, j, jret, seekret;
325  char *realname, *tempchar;
326  int tcharval;
327
328/* Initialization(s) */
329  *nactual = 0;
330
331/* Check for illegal combinations of options */
332  if (( BAOPEN_RONLY & *mode) &&
333     ( (BAOPEN_WONLY & *mode) || (BAOPEN_WONLY_TRUNC & *mode) || (BAOPEN_WONLY_APPEND & *mode) ) ) {
334     #ifdef VERBOSE
335       printf("illegal -- trying to open both read only and write only\n");
336     #endif
337     return -1;
338  }
339  if ( (BAREAD & *mode ) && (BAWRITE & *mode) ) {
340     #ifdef VERBOSE
341       printf("illegal -- trying to both read and write in the same call\n");
342     #endif
343     return -2;
344  }
345
346/* This section handles Fortran to C translation of strings so as to */
347/*   be able to open the files Fortran is expecting to be opened.    */
348  #ifdef CRAY90
349    namelen = _fcdlen(fcd_fname);
350    fname   = _fcdtocp(fcd_fname);
351  #endif
352  if ( (BAOPEN_RONLY & *mode) || (BAOPEN_WONLY & *mode) || 
353       (BAOPEN_WONLY_TRUNC & *mode) || (BAOPEN_WONLY_APPEND & *mode) ||
354       (BAOPEN_RW & *mode) ) {
355    #ifdef VERBOSE
356      printf("Will be opening a file %s %d\n", fname, namelen); fflush(stdout);
357      printf("Strlen %d namelen %d\n", strlen(fname), namelen); fflush(stdout);
358    #endif
359    realname = (char *) malloc( (namelen+1) * sizeof(char) ) ;
360    if (realname == NULL) { 
361      #ifdef VERBOSE
362        printf("failed to mallocate realname %d = namelen\n", namelen);
363        fflush(stdout);
364      #endif
365      return -3;
366    }
367    tempchar = (char *) malloc(sizeof(char) * 1 ) ;
368    i = 0;
369    j = 0;
370    *tempchar = fname[i];
371    tcharval = *tempchar;
372    while (i == j && i < namelen ) {
373       fflush(stdout); 
374       if ( isgraph(tcharval) ) {
375         realname[j] = fname[i];
376         j += 1;
377       }
378       i += 1;
379       *tempchar = fname[i];
380       tcharval = *tempchar;
381    }
382    #ifdef VERBOSE
383      printf("i,j = %d %d\n",i,j); fflush(stdout);
384    #endif
385    realname[j] = '\0';
386  } 
387   
388/* Open files with correct read/write and file permission. */
389  if (BAOPEN_RONLY & *mode) {
390    #ifdef VERBOSE
391      printf("open read only %s\n", realname);
392    #endif
393     *fdes = open(realname, O_RDONLY , S_IRWXU | S_IRWXG | S_IRWXO );
394  }
395  else if (BAOPEN_WONLY & *mode ) {
396    #ifdef VERBOSE
397      printf("open write only %s\n", realname);
398    #endif
399     *fdes = open(realname, O_WRONLY | O_CREAT , S_IRWXU | S_IRWXG | S_IRWXO );
400  }
401  else if (BAOPEN_WONLY_TRUNC & *mode ) {
402    #ifdef VERBOSE
403      printf("open write only with truncation %s\n", realname);
404    #endif
405     *fdes = open(realname, O_WRONLY | O_CREAT | O_TRUNC , S_IRWXU | S_IRWXG | S_IRWXO );
406  }
407  else if (BAOPEN_WONLY_APPEND & *mode ) {
408    #ifdef VERBOSE
409      printf("open write only with append %s\n", realname);
410    #endif
411     *fdes = open(realname, O_WRONLY | O_CREAT | O_APPEND , S_IRWXU | S_IRWXG | S_IRWXO );
412  }
413  else if (BAOPEN_RW & *mode) {
414    #ifdef VERBOSE
415      printf("open read-write %s\n", realname);
416    #endif
417     *fdes = open(realname, O_RDWR | O_CREAT , S_IRWXU | S_IRWXG | S_IRWXO );
418  }
419  else {
420    #ifdef VERBOSE
421      printf("no openings\n");
422    #endif
423  }
424  if (*fdes < 0) {
425    #ifdef VERBOSE
426      printf("error in file descriptor! *fdes %d\n", *fdes);
427    #endif
428    return -4;
429  }
430  else {
431    #ifdef VERBOSE
432      printf("file descriptor = %d\n",*fdes );
433    #endif
434  }
435
436
437/* Read data as requested */
438  if (BAREAD & *mode &&
439   ( (BAOPEN_WONLY & *mode) || (BAOPEN_WONLY_TRUNC & *mode) || (BAOPEN_WONLY_APPEND & *mode) ) ) {
440    #ifdef VERBOSE
441      printf("Error, trying to read while in write only mode!\n");
442    #endif
443    return -5;
444  }
445  else if (BAREAD & *mode ) {
446  /* Read in some data */
447    if (! (*mode & NOSEEK) ) {
448      seekret = lseek(*fdes, *start, SEEK_SET);
449      if (seekret == -1) {
450        #ifdef VERBOSE
451          printf("error in seeking to %d\n",*start);
452        #endif
453        return -6;
454      }
455      #ifdef VERBOSE
456      else {
457         printf("Seek successful, seek ret %d, start %d\n", seekret, *start);
458      }
459      #endif
460    }
461    jret = read(*fdes, datary, *no*(*size) );
462    if (jret != *no*(*size) ) {
463      #ifdef VERBOSE
464        printf("did not read in the requested number of items\n");
465        printf("read in %d items of %d \n",jret/(*size), *no);
466      #endif
467      *nactual = jret/(*size);
468      *newpos = *start + jret;
469    } 
470    #ifdef VERBOSE
471      printf("read in %d items \n", jret/(*size));
472    #endif
473    *nactual = jret/(*size);
474    *newpos = *start + jret;
475  }
476/* Done with reading */
477 
478/* See if we should be writing */
479  if ( BAWRITE & *mode && BAOPEN_RONLY & *mode ) {
480    #ifdef VERBOSE
481      printf("Trying to write on a read only file \n");
482    #endif
483     return -7;
484  }
485  else if ( BAWRITE & *mode ) {
486    if (! (*mode & NOSEEK) ) {
487      seekret = lseek(*fdes, *start, SEEK_SET);
488      if (seekret == -1) {
489      #ifdef VERBOSE
490        printf("error in seeking to %d\n",*start);
491      #endif
492        return -8;
493      }
494      #ifdef VERBOSE
495      else {
496        printf("Seek successful, seek ret %d, start %d\n", seekret, *start);
497      }
498      #endif
499    }
500    jret = write(*fdes, datary, *no*(*size));
501    if (jret != *no*(*size)) {
502    #ifdef VERBOSE
503      printf("did not write out the requested number of items\n");
504      printf("wrote %d items instead\n", jret/(*size) );
505    #endif
506      *nactual = jret/(*size) ;
507      *newpos = *start + jret;
508    }
509    else {
510    #ifdef VERBOSE
511       printf("wrote %d items \n", jret/(*size) );
512    #endif
513       *nactual = jret/(*size) ;
514       *newpos = *start + jret;
515    }
516  }
517/* Done with writing */
518   
519
520/* Close file if requested */
521  if (BACLOSE & *mode ) {
522    jret = close(*fdes);
523    if (jret != 0) { 
524    #ifdef VERBOSE
525      printf("close failed! jret = %d\n",jret);
526    #endif
527      return -9;
528    }
529  }
530/* Done closing */
531
532/* Check that if we were reading or writing, that we actually got what */
533/*  we expected, else return a -10.  Return 0 (success) if we're here  */
534/*  and weren't reading or writing */
535  if ( (*mode & BAREAD || *mode & BAWRITE) && (*nactual != *no) ) {
536    return -10;
537  }
538  else {
539    return 0;
540  }
541} 
Note: See TracBrowser for help on using the repository browser.