/* @(#)dataio.c 17.1.1.1 (ESO-DMD) 01/25/02 17:39:07 */ /*=========================================================================== Copyright (C) 1995 European Southern Observatory (ESO) This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 675 Massachusetts Ave, Cambridge, MA 02139, USA. Correspondence concerning ESO-MIDAS should be addressed as follows: Internet e-mail: midas@eso.org Postal address: European Southern Observatory Data Management Division Karl-Schwarzschild-Strasse 2 D 85748 Garching bei Muenchen GERMANY ===========================================================================*/ /*++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ .COPYRIGHT (c) 1995 European Southern Observatory .IDENT dataio.c .LAUGUAGE C .AUTHOR P.Grosbol ESO/IPG .KEYWORDS data I/O routines, tape, stream .COMMENT buffered I/O for data format IHAP/FITS routiens .VERSION 1.0 1988-Dec-10 : Creation, PJG .VERSION 1.1 1989-Jan-17 : Add count of output blocks, PJG .VERSION 1.2 1989-May-24 : Specify blocksize for disk/tape, PJG .VERSION 1.4 1989-Nov-06 : Upgrade for fixed-block devices , PJG .VERSION 1.5 1990-Feb-04 : Intiate cvb and change call-seq., PJG .VERSION 1.6 1990-Mar-30 : Insert error messages for OS-calls, PJG .VERSION 1.8 1991-Jan-25 : Change include files. FO .VERSION 1.9 1991-Nov-19 : Correct error in write with fix-block, PJG .VERSION 2.0 1993-Oct-28 : Update to new SC and prototypes, PJG .VERSION 2.1 1994-Jun-29 : Check error only in first read, PJG .VERSION 2.2 1995-Jan-23 : Skip 'osmsg' for osdopen, PJG .VERSION 2.3 1996-Jan-09 : Check read status for disk files, PJG 980528 ---------------------------------------------------------------------*/ #include #include #include #include #include #define MXBUF 30720 /* size of internal buffer */ char *osmsg(); /* OS error message */ static int fdi = -1; /* file descriptor of input file */ static int fdo = -1; /* file descriptor of output file */ static int fd = -1; /* file descriptor of tape */ static int apos; /* absolute position of tape */ static int fmt; /* format of data file FITS/IHAP */ static int widx; /* current write index in buffer */ static int ridx; /* current read index in buffer */ static int rlvb; /* last of valid byte in read buffer */ static int wlvb; /* last of valid byte in write buffer */ static int rbsize; /* block size of reads */ static int wbsize; /* block size of writes */ static int devbs; /* device block size */ static int mxbuf; /* actual size of buffer */ static int nopb; /* no. of output bytes */ static int lrs; /* last read status */ static char dev; /* type of input device */ static char *rbptr = (char *) 0; /* pointer to read buffer */ static char *wbptr = (char *) 0; /* pointer to write buffer */ /* */ #ifdef __STDC__ int dopen(char * name , int iomode , char type , int den) #else int dopen(name,iomode,type,den) /*+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ .PURPOSE open device .RETURN file descriptor - if error status of open call ---------------------------------------------------------------------*/ char *name; /* IN: name of device to open */ int iomode; /* IN: I/O open mode 0:read, 1:write */ char type; /* IN: device type - Block, Stream */ int den; /* IN: tape density for tapes (B) */ #endif { int myfd; dev = type; apos = 0; devbs = 1; if (dev == 'S') { /* open disk file */ osfop('F',FITSLR); /* force 2880 byte fix records */ myfd = osdopen(name,iomode); if (myfd == -1) return (-1); if (iomode == 0) fdi = myfd; else fdo = myfd; } else { /* open block dev/tape */ myfd = osuopen(name,iomode,den); if (myfd == -1) { SCTPUT(osmsg()); return (-1); } devbs = osubsize(myfd); fd = myfd; } mxbuf = (MAXIO1 < MXBUF) ? MAXIO1 : MXBUF; /* allocate buffer */ if (iomode == 0) { if (rbptr == (char *) 0) rbptr = (char *)osmmget(mxbuf); } else { if (wbptr == (char *) 0) wbptr = (char *)osmmget(mxbuf); } mxbuf = (mxbuf/devbs) * devbs; return myfd; } int drinit() /*+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ .PURPOSE initiate read buffer and check data format IHAP/FITS .RETURN data format - 1:FITS, 2:IHAP, 0:Unknown, -1: NO data ---------------------------------------------------------------------*/ { char *pc,*str; int i,n; union { char c[10]; short s[5]; } tmp; ridx = 0; rlvb = 0; lrs = 1; if (dev == 'S') { rlvb = osdread(fdi,rbptr,mxbuf); if (rlvb0) { n = dread(&pcin,FITSLR); if (n > 0) { pcout = pcin; dwrite(pcout,n); } } (void) dweof(); return 0; } int dclose(fid) /*+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ .PURPOSE spool buffer to device and close it .RETURN status 0: OK, -1: error ---------------------------------------------------------------------*/ int fid; /* IN: file id returned from `dopen' */ { if (dev != 'S') /* for tape ignore fid */ { osuclose(fd, 0); if (rbptr != (char *) 0) { (void) osmmfree(rbptr); rbptr = (char *) 0; } if (wbptr != (char *) 0) { (void) osmmfree(wbptr); wbptr = (char *) 0; } } else { osdclose(fid); if (fid == fdi) { fdi = -1; if (rbptr != (char *) 0) /* clear read buffer */ { (void) osmmfree(rbptr); rbptr = (char *) 0; } } else if (fid == fdo) { fdo = -1; if (wbptr != (char *) 0) /* clear write buffer */ { (void) osmmfree(wbptr); wbptr = (char *) 0; } } else { char tmp[80]; (void) sprintf(tmp,"(FITS) dclose: bad file id (%d) passed...",fid); SCTPUT(tmp); if (rbptr != (char *) 0) { (void) osmmfree(rbptr); rbptr = (char *) 0; } if (wbptr != (char *) 0) { (void) osmmfree(wbptr); wbptr = (char *) 0; } return (-1); } } return 0; } int dapos(no) /*+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ .PURPOSE position on an absolute file no. on a magnetic tape .RETURN status 0: OK, -1: error ---------------------------------------------------------------------*/ int no; /* absolute file no. on tape */ { int n; if (dev == 'S') return -1; /* cannot position Stream */ apos = (no<0) ? osufseek(fd,0,FILE_END) : osufseek(fd,no,FILE_START); if (apos<0) { SCTPUT(osmsg()); return -1; } return 0; } int dskip(no) /*+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ .PURPOSE skip files on a magnetic tape .RETURN status 0: OK, -1: error ---------------------------------------------------------------------*/ int no; /* no. of files to be skipped */ { if (dev == 'S') return -1; /* cannot position stream */ if (no) apos = osufseek(fd,no,FILE_CURRENT); if (apos<0) { SCTPUT(osmsg()); return -1; } return 0; } #ifdef __STDC__ int dbfill(char val) #else int dbfill(val) /*+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ .PURPOSE fill remaining part of FITS record with 'val' .RETURN status always 0: OK ---------------------------------------------------------------------*/ char val; /* IN: value to fill block with */ #endif { char *pc; int nx; nx = ((nopb-1)/FITSLR+1)*FITSLR - nopb; nopb += nx; pc = &wbptr[widx]; while (nx--) { *pc++ = val; widx++; } return 0; } int dweof() /*+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ .PURPOSE flush data in internal buffer and close current file .RETURN no. of records written, -1: error ---------------------------------------------------------------------*/ { int n,i; n = (0