/*module documentation block */ /* . . . */ /* module: obsmod */ /* prgmmr: middlecoff org: gsd/esrl date: 2006-04-27 */ /* */ /* abstract: This module contains contains routines used to open, */ /* read from, and close data files in a manner similar */ /* to fortran direct access (DA) reads */ /* */ /* The Fortran standard does not */ /* - specify what the status return code should be for a DA */ /* when read past the EOF */ /* - provide a way to detect end-of-file for a DA file */ /* - apply the concept end-of-file to direct-access files */ /* */ /* Consequently, the standard does not specify what the contents */ /* of the buffer will be for locations past the EOF. */ /* */ /* The routines in this file provide a more portable way to */ /* read a file in a "direct access" like manner. */ /* */ /* program history log: */ /* 2006-04-27 middlecoff */ /* */ /* */ /* Subroutines Included: */ /* sub openfileread - ope */ /* sub closfile */ /* sub getbytes - */ /* */ /* Variable Definitions: */ /* */ /* */ /* */ /*end documentation block */ #include #include #define MAXLUN 1000 static int lunTableInit=0; static FILE *lunTable[MAXLUN]; static int lunUsed[MAXLUN]; void initLunTable () { int i; if (lunTableInit == 0) { for (i=0; i < MAXLUN; i++) lunUsed[i] = 0; lunTableInit = 1; } } void #if defined(funder) openfileread_ #elif defined(f2under) openfileread__ #elif defined(fcaps) OPENFILEREAD #else openfileread #endif (FortranInt *lun, FortranInt *istat, FortranByte *fname) /* Assume the name is null terminated in the Fortran code */ { int cLun; initLunTable(); cLun = (int) *lun; /* Check lun range */ if ((cLun < 0) || (cLun >= MAXLUN)) { *istat = -1; return; } /* Close if open */ if (lunUsed[cLun] != 0) fclose (lunTable[cLun]); /* Open the file */ lunTable[cLun] = fopen (fname, "r"); if (lunTable[cLun] == NULL) { *istat = -1; return; } lunUsed[cLun] = 1; *istat = 0; return; } /* This routine emulates IBM Fortran direct access read */ void #if defined(funder) getbytes_ #elif defined(f2under) getbytes__ #elif defined(fcaps) GETBYTES #else getbytes #endif (FortranInt *lun, void *buff, FortranLlong *recno, FortranLlong *recl, FortranInt *istat) { int cLun; size_t cRecl; size_t xfer; char *cbuff; int i; long offset; initLunTable(); cRecl = (size_t) *recl; cLun = (int) *lun; cbuff = (char *) buff; /* Check lun range */ if ((cLun < 0) || (cLun >= MAXLUN)) { *istat = -1; return; } /* Is it open? */ if (lunUsed[cLun] == 0) { *istat = -2; return; } /* move to the right record */ offset = ((long) *recno-1)*cRecl; if(fseek(lunTable[cLun], offset, 0) !=0) {*istat = -3;return; } /* Get the data */ xfer = fread (buff, (size_t) 1, cRecl, lunTable[cLun]); if (xfer < cRecl) { *istat = 1; /* Short read, pad with zeros */ for (i=xfer; i < cRecl; i++) cbuff[i] = '\0'; } else *istat = 0; return; } void #if defined(funder) closefile_ #elif defined(f2under) closefile__ #elif defined(fcaps) CLOSEFILE #else closefile #endif (FortranInt *lun, FortranInt *istat) { int cLun; initLunTable(); cLun = (int) *lun; /* Check lun range */ if ((cLun < 0) || (cLun >= MAXLUN)) { *istat = -1; return; } /* Is it open? */ if (lunUsed[cLun] == 0) { *istat = -1; return; } /* Close the file */ fclose (lunTable[cLun]); lunUsed[cLun] = 0; *istat = 0; return; }