1
/*===========================================================================
2
Copyright (C) 1995-2005 European Southern Observatory (ESO)
4
This program is free software; you can redistribute it and/or
5
modify it under the terms of the GNU General Public License as
6
published by the Free Software Foundation; either version 2 of
7
the License, or (at your option) any later version.
9
This program is distributed in the hope that it will be useful,
10
but WITHOUT ANY WARRANTY; without even the implied warranty of
11
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12
GNU General Public License for more details.
14
You should have received a copy of the GNU General Public
15
License along with this program; if not, write to the Free
16
Software Foundation, Inc., 675 Massachusetts Ave, Cambridge,
19
Correspondence concerning ESO-MIDAS should be addressed as follows:
20
Internet e-mail: midas@eso.org
21
Postal address: European Southern Observatory
22
Data Management Division
23
Karl-Schwarzschild-Strasse 2
24
D 85748 Garching bei Muenchen
26
===========================================================================*/
28
/*++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
29
.COPYRIGHT (c) 1995-2005 European Southern Observatory
32
.AUTHOR P.Grosbol ESO/IPG
33
.KEYWORDS data I/O routines, tape, stream
34
.COMMENT buffered I/O for data format IHAP/FITS routiens
35
.VERSION 1.0 1988-Dec-10 : Creation, PJG
36
.VERSION 1.1 1989-Jan-17 : Add count of output blocks, PJG
37
.VERSION 1.2 1989-May-24 : Specify blocksize for disk/tape, PJG
38
.VERSION 1.4 1989-Nov-06 : Upgrade for fixed-block devices , PJG
39
.VERSION 1.5 1990-Feb-04 : Intiate cvb and change call-seq., PJG
40
.VERSION 1.6 1990-Mar-30 : Insert error messages for OS-calls, PJG
41
.VERSION 1.8 1991-Jan-25 : Change include files. FO
42
.VERSION 1.9 1991-Nov-19 : Correct error in write with fix-block, PJG
43
.VERSION 2.0 1993-Oct-28 : Update to new SC and prototypes, PJG
44
.VERSION 2.1 1994-Jun-29 : Check error only in first read, PJG
45
.VERSION 2.2 1995-Jan-23 : Skip 'osmsg' for osdopen, PJG
46
.VERSION 2.3 1996-Jan-09 : Check read status for disk files, PJG
49
---------------------------------------------------------------------*/
57
#include <midas_def.h>
59
#define MXBUF 30720 /* size of internal buffer */
61
char *osmsg(); /* OS error message */
63
static int fdi = -1; /* file descriptor of input file */
64
static int gdi; /* backup of fdi */
65
static int fdo = -1; /* file descriptor of output file */
66
static int gdo; /* backup of fdo */
67
static int fd = -1; /* file descriptor of tape */
68
static int apos; /* absolute position of tape */
69
static int fmt; /* format of data file FITS/IHAP */
70
static int widx; /* current write index in buffer */
71
static int ridx; /* current read index in buffer */
72
static int rlvb; /* last of valid byte in read buffer */
73
static int wlvb; /* last of valid byte in write buffer */
74
static int rbsize; /* block size of reads */
75
static int wbsize; /* block size of writes */
76
static int devbs; /* device block size */
77
static int mxbuf; /* actual size of buffer */
78
static int nopb; /* no. of output bytes */
79
static int lrs; /* last read status */
80
static char dev; /* type of input device */
81
static char *rbptr = (char *) 0; /* pointer to read buffer */
82
static char *wbptr = (char *) 0; /* pointer to write buffer */
89
int dopen(char * name , int iomode , char type , int den)
91
int dopen(name,iomode,type,den)
92
/*+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
94
.RETURN file descriptor - if error status of open call
95
---------------------------------------------------------------------*/
96
char *name; /* IN: name of device to open */
97
int iomode; /* IN: I/O open mode 0:read, 1:write */
98
char type; /* IN: device type - Block, Stream */
99
int den; /* IN: tape density for tapes (B) */
107
dev = type; apos = 0; devbs = 1;
108
mxbuf = (MAXIO1 < MXBUF) ? MAXIO1 : MXBUF; /* determine buffer size */
111
{ /* open disk file */
112
osfop('F',FITSLR); /* force 2880 byte fix records */
113
myfd = osdopen(name,iomode);
114
if (myfd == -1) return (-1);
126
{ /* open block dev/tape */
127
myfd = osuopen(name,iomode,den);
130
SCTPUT(osmsg()); return (-1);
132
devbs = osubsize(myfd);
133
mxbuf = (mxbuf/devbs) * devbs;
137
/* allocate data buffer */
141
if (rbptr == (char *) 0) rbptr = (char *)osmmget(mxbuf);
145
if (wbptr == (char *) 0) wbptr = (char *)osmmget(mxbuf);
152
/*+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
153
.PURPOSE initiate read buffer and check data format
154
.RETURN data format = 1:FITS, 0:Unknown, -1: NO data
155
---------------------------------------------------------------------*/
161
ridx = 0; rlvb = 0; lrs = 1;
164
rlvb = osdread(fdi,rbptr,mxbuf);
165
if (rlvb<mxbuf) lrs = 0;
168
rlvb = osuread(fd,rbptr,mxbuf);
176
pc = rbptr; str = "SIMPLE =";
177
while ((*pc) == (*str)) pc++, str++;
179
if (*pc==' ' && !(*str))
180
{ /* check if FITS format */
181
rbsize = (mxbuf/FITSLR) * FITSLR; /* define best read size */
184
rbsize = (devbs==1) ? rbsize+4 : ((mxbuf-FITSLR)/devbs)*devbs;
186
cvinit(); fmt = FITS;
194
/*+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
195
.PURPOSE read 'no' bytes from device
196
.RETURN no. of bytes read, -1: EOF, -2:error
197
---------------------------------------------------------------------*/
198
char **ppbuf; /* pointer to buffer pointer */
199
int no; /* no. of bytes to read */
201
register char *pbs,*pbe;
207
{ /* too few data - read next block */
208
n = rlvb - ridx; rlvb = n;
209
pbs = rbptr; pbe = &rbptr[ridx];
210
while (n--) *pbs++ = *pbe++; /* move bytes to start of buffer */
212
while (lrs && rlvb<no)
213
{ /* read enough data for request */
216
nb = rbsize - rlvb; /* devbs = 1 */
217
n = osdread(fdi,pbs,nb);
222
nb = ((rbsize-rlvb-1)/devbs + 1) * devbs;
223
n = osuread(fd,pbs,nb);
233
if (rlvb < no) no = rlvb;
236
*ppbuf = &rbptr[ridx];
243
/*+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
244
.PURPOSE initiate write buffer and define blocking factor
246
---------------------------------------------------------------------*/
247
int bf; /* FITS blocking factor */
249
widx = 0; wlvb = 0; nopb = 0;
254
wbsize = (10<bf) ? 10*FITSLR : bf*FITSLR;
256
if (mxbuf<wbsize) wbsize = (mxbuf/FITSLR) * FITSLR;
257
if (dev!='S' && devbs!=1) wbsize = (mxbuf/devbs)*devbs;
264
/*+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
265
.PURPOSE write 'no' bytes to device
266
.RETURN no. of bytes transfered or <0 error
267
---------------------------------------------------------------------*/
268
char *pbuf; /* pointer to data to be written */
269
int no; /* no. of bytes to write */
279
widx += no; nn = no; nopb += no;
281
{ /* space in buffer - transfer */
282
while (no--) *pc++ = *pbuf++;
287
n = wbsize - widx + no; no -= n;
288
while (n--) *pc++ = *pbuf++;
291
n = osdwrite(fdo,wbptr,wbsize);
293
n = osuwrite(fd,wbptr,wbsize);
296
if (n<0) SCTPUT(osmsg());
297
SCTPUT("Error: I/O-error in writting block");
298
widx -= no; return -1;
304
n = osdwrite(fdo,pbuf,wbsize);
306
n = osuwrite(fd,pbuf,wbsize);
309
if (n<0) SCTPUT(osmsg());
310
SCTPUT("Error: I/O-error in writting block");
311
widx -= no; return -1;
316
widx = no; pc = wbptr;
317
while (no--) *pc++ = *pbuf++;
325
/*+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
326
.PURPOSE write 'no' bytes to device
327
.RETURN no. of bytes transfered or <0 error
328
---------------------------------------------------------------------*/
336
/* we need read + write buffer */
338
if (rbptr == (char *) 0) rbptr = (char *)osmmget(mxbuf);
339
if (wbptr == (char *) 0) wbptr = (char *)osmmget(mxbuf);
341
n = 1; /* kick off the loop */
344
n = dread(&pcin,FITSLR);
359
/*+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
360
.PURPOSE spool buffer to device and close it
361
.RETURN status 0: OK, -1: error
362
---------------------------------------------------------------------*/
363
int fid; /* IN: file id returned from `dopen' */
366
if (dev != 'S') /* for tape ignore fid */
370
if (rbptr != (char *) 0)
372
(void) osmmfree(rbptr);
375
if (wbptr != (char *) 0)
377
(void) osmmfree(wbptr);
384
/* for FITS files on disk */
386
if ((fid == fdi) || (fid == gdi))
388
if (fdi != -1) osdclose(fdi);
390
if (rbptr != (char *) 0) /* clear read buffer */
392
(void) osmmfree(rbptr);
396
else if ((fid == fdo) || (fid == gdo))
398
if (fdo != -1) osdclose(fdo);
400
if (wbptr != (char *) 0) /* clear write buffer */
402
(void) osmmfree(wbptr);
410
(void) sprintf(tmp,"(FITS) dclose: bad file id (%d) passed...",fid);
412
if (rbptr != (char *) 0)
414
(void) osmmfree(rbptr);
417
if (wbptr != (char *) 0)
419
(void) osmmfree(wbptr);
430
/*+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
431
.PURPOSE position on an absolute file no. on a magnetic tape
432
.RETURN status 0: OK, -1: error
433
---------------------------------------------------------------------*/
434
int no; /* absolute file no. on tape */
438
if (dev == 'S') return -1; /* cannot position Stream */
440
apos = (no<0) ? osufseek(fd,0,FILE_END) : osufseek(fd,no,FILE_START);
441
if (apos<0) { SCTPUT(osmsg()); return -1; }
446
/*+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
447
.PURPOSE skip files on a magnetic tape
448
.RETURN status 0: OK, -1: error
449
---------------------------------------------------------------------*/
450
int no; /* no. of files to be skipped */
452
if (dev == 'S') return -1; /* cannot position stream */
453
if (no) apos = osufseek(fd,no,FILE_CURRENT);
454
if (apos<0) { SCTPUT(osmsg()); return -1; }
462
/*+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
463
.PURPOSE fill remaining part of FITS record with 'val'
464
.RETURN status always 0: OK
465
---------------------------------------------------------------------*/
466
char val; /* IN: value to fill block with */
472
nx = ((nopb-1)/FITSLR+1)*FITSLR - nopb;
475
while (nx--) { *pc++ = val; widx++; }
481
/*+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
482
.PURPOSE flush data in internal buffer and close current file
483
.RETURN no. of records written, -1: error
484
---------------------------------------------------------------------*/
488
n = (0<widx) ? (((widx-1)/devbs)+1)*devbs : 0;
489
for (i=widx; i<n; i++) wbptr[i] = '\0';
495
n = osdwrite(fdo,wbptr,n);
504
n = osuwrite(fd,wbptr,n);
505
if (n<0) { SCTPUT(osmsg()); osufclose(fd); return -1; }