NLSL
genio.c
Go to the documentation of this file.
1 /**************************************************************************
2 
3  This module contains FORTRAN-callable routines to read and write
4  a PC-GENPLOT binary data file:
5 
6  iret = getbin( filename, xarray, yarray, npoints, comment, ncmts, maxpts )
7 
8  call putbin( filename, xarray, yarray, npoints, comment, ncmts )
9 
10 
11  filename character variable containing name of datafile
12  xarray real*8 array to receive x data (first array in file)
13  y array real*8 array to receive y data (second array in file)
14  npoints number of points found in x,y arrays (returned by getbin)
15  (note: if greater than maxpts, only maxpts points are
16  actually returned in the x,y arrays)
17  iret returns 0 for successful read, 1 for error
18  maxpts maximum number of points to be returned by getbin
19 
20  Also included are the following utility subroutines:
21 
22  getint() reads an integer from the input file
23  getreal() reads a floating point real number (converted from
24  GENPLOT format to standard floating point format)
25  getrecsize() reads a Ryan-McFarlane unformatted file record marker
26  getlinerec() reads an ASCII line from the input file
27 
28 ***************************************************************************/
29 
30 #include <errno.h>
31 #include <stdio.h>
32 #include <string.h>
33 #include "fortrancall.h"
34 
35 #define ERROR 1
36 #define OK 0
37 #define MAXCMTLNS 16
38 #define MAXLINLTH 80
39 #define MAXELEMENTS 1024 /* Max number of elements in an array record */
40 
41 extern int errno;
42 
44 double factor, offset;
45 char info[81];
46 
47 /*********************************************************************
48  getint() read an integer from the input file
49  putint( iout ) write an integer to the output file
50 **********************************************************************/
51 
52 unsigned int getint()
53 {
54  int itmp;
55  itmp = fgetc(inputfile);
56  itmp += (fgetc(inputfile) << 8);
57  return itmp;
58 }
59 
60 void putint( iout )
61 int iout;
62 {
63  fputc( (char) (iout & 0xff), outputfile );
64  fputc( (char) (iout >> 8), outputfile );
65 }
66 
67 
68 /*************************************************************************
69 getrecsize() Read a Ryan-McFarlane FORTRAN unformatted record
70  marker from the input file
71 putrecsize( size ) Write a record marker to the output file
72 
73 Note that record size includes the two four-byte record markers
74 at either end of the record
75 ***************************************************************************/
76 
77 union i4_datum {
78  long int number;
79  unsigned int word[2];
80  } reclth;
81 
82 long int getrecsize()
83 {
84  reclth.word[0] = getint();
85  reclth.word[1] = getint();
86  return reclth.number;
87  }
88 
89 void putrecsize( recsize )
90 int recsize;
91 {
92  reclth.number = (long) recsize;
93  putint( reclth.word[0] );
94  putint( reclth.word[1] );
95 }
96 
97 
98 /***************************************************************
99  getlinerec( line ) Read a R-M FORTRAN unformatted record into a
100  character array
101 
102  putlinerec( line ) Write a R-M FORTRAN unformatted record from
103  a character array
104  ***************************************************************/
105 
107 {
108  printf("Illegal line record in getlinerec\n");
109  return ERROR;
110 }
111 
112 int getlinerec( line )
113 char line[];
114 {
115 int i, linlth;
116 
117  linlth = getrecsize()-8;
118  if (linlth > MAXLINLTH) return ill_linerec();
119 
120  for ( i=0; (i<linlth) && !feof(inputfile); i++ )
121  line[i] = (char) fgetc( inputfile );
122 
123  if ( (linlth != getrecsize()-8) || feof(inputfile)) return ill_linerec();
124  else return OK;
125 }
126 
127 
128 void putlinerec( line )
129 char line[];
130 {
131 int i;
132  putrecsize( MAXLINLTH+8 );
133  i = 0;
134  while (line[i] && (i < MAXLINLTH) ) /* output string up to null */
135  fputc( line[i++], outputfile ) ;
136  while (i++ < MAXLINLTH) /* pad the line with blanks */
137  fputc( ' ', outputfile );
138  putrecsize( MAXLINLTH+8 );
139 }
140 
141 
142 /****************************************************************************
143 * getreal() Convert 8087-format real*4 number from the disk buffer
144 * to a double precision number for an IBM 370
145 * putreal( rout ) Convert an IBM370 real*8 number to IEEE real*4 and
146 * write it to disk
147 ****************************************************************************/
148 
149 union fpdatum {
150  float number;
151  char byte[4];
152  } fp;
153 
154 double getreal()
155 {
156 long int i;
157  for (i = 3; i >= 0; i--)
158  fp.byte[i] = (char) fgetc(inputfile);
159  return (double) fp.number;
160 }
161 
162 void putreal( double *rout )
163 {
164 int i;
165  fp.number = (float) *rout;
166  for (i = 3; i >= 0; i--)
167  fputc( fp.byte[i], outputfile );
168 }
169 
170 
171 /**********************************************************************
172  getarray( array, length, maxpts ) Retrieve one or more R-M FORTRAN
173  unformatted records containing a real*4
174  array from the disk file. Does not return
175  more than the specified maximum # of pts.
176  puarray( array, length ) Write one or more R-M FORTRAN unformatted
177  records containing a real number array to
178  the disk file.
179  **********************************************************************/
181 {
182  printf("Illegal array record\n");
183  return ERROR;
184 }
185 
186 int getarray( array, arrylth, maxpts )
187 double array[];
188 long int arrylth, maxpts;
189 {
190 double dummy;
191 int i, lastel, nxtarry;
192  nxtarry = 0;
193  do {
194  lastel = (getrecsize()-8) / 4;
195  for ( i=1; i<=lastel; i++ ) {
196  if (nxtarry<maxpts)
197  array[nxtarry++] = getreal();
198  else {
199  nxtarry++;
200  dummy = getreal();
201  }
202  if (feof(inputfile)) break;
203  }
204  if ( lastel != ((getrecsize()-8)/4) ) return ill_arrayrec();
205  }
206 while ( (nxtarry < arrylth) && !feof(inputfile) );
207 return arrylth != nxtarry;
208 }
209 
210 void putarray( array, arrylth )
211 double array[];
212 long int arrylth;
213 {
214 int i, elemnts, nxtel;
215  nxtel = 0;
216  do {
217  elemnts = arrylth - nxtel;
218  if (elemnts > MAXELEMENTS) elemnts = MAXELEMENTS;
219  putrecsize( (4*elemnts) + 8 );
220  for ( i=0; i < elemnts; i++ ) putreal( array+(nxtel++) );
221  putrecsize( (4*elemnts) + 8 );
222  }
223  while (nxtel < arrylth);
224 }
225 
226 
227 
228 int array_err( errstring )
229 char *errstring;
230 {
231  printf("%s\n",errstring);
232  return ERROR;
233 }
234 
235 
236 long int FORTRAN(getbin)( filename, xarry, yarry, npoints, comment, ncmts, maxpts )
237 char filename[], comment[][MAXLINLTH];
238 double xarry[], yarry[];
239 long int *npoints, *ncmts, *maxpts;
240 {
241 int cmtlns, i, iret, ncol;
242  i = 0;
243 
244  while ((filename[i++] != ' ') && (i <= MAXLINLTH)); /* trim end blanks */
245  filename[i-1] = 0;
246  inputfile = fopen( filename, "r" );
247  if (!inputfile) {
248  printf("file open error %4d for file \'%s\'\n",errno,filename);
249  return ERROR;
250  }
251 
252  iret = getlinerec( info );
253  if ( (iret) || strncmp( info, "VERSION GENPLT 4.0", 18 ) )
254  return array_err( "Not a GENPLOT binary file");
255 
256 /* Read comment strings (including any FIR file header) */
257 
258  cmtlns = 0;
259  do
260  if ( getlinerec(comment[cmtlns]) )
261  return array_err("Bad comment line record");
262  while
263  ( strncmp(comment[cmtlns++],"\001",1) && !feof(inputfile) );
264  *ncmts = (long) -- cmtlns;
265 
266 
267 /* Read number of points and number of arrays (not used) */
268 
269  i = getrecsize();
270  *npoints = getint();
271  ncol = getint();
272  if (i != getrecsize()) return array_err("Bad npoints, ncol record");
273 
274 /* Read X data (Field) */
275 
276  iret = getlinerec( info ); /* comment for x array */
277  if (iret) return array_err("Bad X comment");
278  i = getrecsize();
279  factor = getreal(); /* multiplication factor for array */
280  offset = getreal(); /* offset for array */
281  if (i != getrecsize())
282  return array_err("Bad X factor, offset record");
283  if (getarray( xarry, *npoints, *maxpts ) )
284  return array_err("Could not get X array");
285 
286 /* Read Y data (Intensity) */
287 
288  iret = getlinerec( info ); /* comment for y array */
289  if (iret) return array_err("Bad Y comment");
290  i = getrecsize();
291  factor = getreal(); /* multiplication factor for array */
292  offset = getreal(); /* offset for array */
293  if (i != getrecsize()) return array_err("Bad Y factor, offset record");
294 
295  if ( getarray( yarry, *npoints, *maxpts ) )
296  return array_err("Could not get Y array");
297  fclose( inputfile );
298  return OK;
299 }
300 
301 /* ****************************************************************** */
302 
303 long int putbin( filename, xarry, yarry, npoints, comment, ncmts )
304 char filename[], comment[][MAXLINLTH];
305 double xarry[], yarry[];
306 long int *npoints, *ncmts;
307 {
308 int i, ncol;
309  i = 0;
310  while ((filename[i++] != ' ') && (i <= MAXLINLTH)); /* trim end blanks */
311  filename[i-1] = 0;
312 
313  outputfile = fopen( filename, "w" );
314  if (!outputfile) {
315  printf("file open error %4d\n",errno);
316  return ERROR;
317  }
318 
319  putlinerec( "VERSION GENPLT 4.0" );
320  for ( i = 0; i < *ncmts; i++ ) putlinerec( comment[i] );
321  putlinerec( "\001" );
322 
323  putrecsize( 12 );
324  ncol = 2;
325  putint( (int) *npoints );
326  putint( (int) ncol );
327  putrecsize( 12 );
328 
329 /* Write X data (Field) */
330  factor=1.0;
331  offset=0.0;
332  putlinerec( "Field" );
333  putrecsize( 16 );
334  putreal( &factor );
335  putreal( &offset );
336  putrecsize( 16 );
337  putarray( xarry, *npoints );
338 
339 /* Write Y data (Intensity) */
340 
341  putlinerec( "Intensity" );
342  putrecsize( 16 );
343  putreal( &factor );
344  putreal( &offset );
345  putrecsize( 16 );
346  putarray( yarry, *npoints );
347  fclose( outputfile );
348  return OK;
349 }
void putint(int iout)
Definition: genio.c:60
char info[81]
Definition: genio.c:45
void putrecsize(int recsize)
Definition: genio.c:89
long int FORTRAN() getbin(filename, xarry, yarry, long int *npoints, comment, long int *ncmts, long int *maxpts)
Definition: genio.c:236
unsigned int getint()
Definition: genio.c:52
union fpdatum fp
FILE * inputfile
Definition: genio.c:43
long int putbin(filename, xarry, yarry, long int *npoints, comment, long int *ncmts)
Definition: genio.c:303
double getreal()
Definition: genio.c:154
FILE * outputfile
Definition: genio.c:43
#define FORTRAN(n)
Definition: fortrancall.h:8
void putlinerec(line)
Definition: genio.c:128
Definition: genio.c:149
int getlinerec(line)
Definition: genio.c:112
unsigned int word[2]
Definition: genio.c:79
void putreal(double *rout)
Definition: genio.c:162
#define MAXELEMENTS
Definition: genio.c:39
#define MAXLINLTH
Definition: genio.c:38
int array_err(char *errstring)
Definition: genio.c:228
double factor
Definition: genio.c:44
int ill_arrayrec()
Definition: genio.c:180
long int getrecsize()
Definition: genio.c:82
int getarray(array, long int arrylth, long int maxpts)
Definition: genio.c:186
union i4_datum reclth
int ill_linerec()
Definition: genio.c:106
void putarray(array, long int arrylth)
Definition: genio.c:210
Definition: pltx.c:77
long int number
Definition: genio.c:78
#define OK
Definition: genio.c:36
char byte[4]
Definition: genio.c:151
#define ERROR
Definition: genio.c:35
Definition: genio.c:77
int errno
float number
Definition: genio.c:150
double offset
Definition: genio.c:44