/* @(#)middsca.c 17.1.1.1 (ESO-DMD) 01/25/02 17:36:22 */ /*=========================================================================== 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 ===========================================================================*/ /*+++++++++++++++++++++ Module MIDDSCA +++++++++++++++++++++++++++++++++++++++ .LANGUAGE C .IDENTIFICATION MIDDSCA.C .AUTHOR Klaus Banse ESO - Garching .COMMENTS holds INITDS, WDSCRI, WDSCRR, WDSCRC, RDSCRI, RDSCRR, RDSCRC .KEYWORDS MIDAs Descriptors .ENVIRONMENT VMS and UNIX .VERSION [1.30] 861110: creation from FORTRAN version .VERSION [2.50] 910718: initialize some variables in the next_descr branch .VERSION [2.60] 930907: long int -> int !!! 010906 last modif ------------------------------------------------------------------------*/ #include #define BIT_0 0x1 #define READ 0 #define WRITE 1 #define READ_WRITE 2 #define APPEND 3 #define DISK_REC 512 /* size of single block (in bytes) */ /* */ int MID_INITDS(fcbp,iochan) /*++++++++++++++++++++++++++++++++++++++++++++++++++ .PURPOSE initialize the descr. directory + update the FCB accordingly .ALGORITHM set up the descr. directory exactly like any other descriptor reserve already LDB's (= 12 blocks) for directory + standard descriptors .RETURNS status: I*4 return status --------------------------------------------------*/ struct FCB_STRUCT *fcbp; /* IN: pointer to FCB of frame */ int iochan; /* IN: channel of frame */ { int kldb, nn, dscdsiz; int n, mm, status; register int nr; char *cpntrb, *dscpntr; struct LDB_STRUCT *ldbp; status = cacheLDB(22,iochan,fcbp->PTRLDB,&ldbp); /* create cache */ dscdsiz = fcbp->DBEGIN; kldb = fcbp->INLDB[0]; /* no. of LDBs needed for dscdir */ mm = (kldb * LDB_NDSCRB); /* size in bytes */ n = mm - dscdsiz; /* space left in `kldb' LDBs */ nn = (kldb << 2) - 2; /* (*4 - 2), so blockno.s like 2, 6, 10, 14 */ /* set up endpointers to include already 1. entry of descr. directory */ if (n > 0) { fcbp->ENDLDB[0] = nn; /* dscdir fits with extra space */ mm -= LDB_NDSCRB; /* no_bytes in full first blocks */ n = (dscdsiz - mm) / II_SIZE; /* move to 4-byte words */ fcbp->ENDLDB[1] = n + 1; /* offset is in 4-byte words ... */ } else { fcbp->ENDLDB[0] = nn + 4; /* dscdir fits with no extra space */ fcbp->ENDLDB[1] = 1; } fcbp->DIRBYTELEM = 1; /* use "flat" character */ fcbp->DSIZE = dscdsiz - 12; /* just drop the 12 byte header stuff */ /* calculate initial no. of LDBs and initialize them */ ldbp->LDBWORDS.IWORD[0] = fcbp->DSIZE; ldbp->LDBWORDS.IWORD[1] = -1; /* indicate that it's contiguous */ ldbp->LDBWORDS.IWORD[2] = 0; /* no index into extension block, yet */ /* handle very old, old and new decriptor directory entries */ if (fcbp->DSCFLAG == 'Y') /* new version */ { fcbp->DIRENTRY = YENTRY_SIZE; /* entry in descr. direc. = 100 chars */ fcbp->DIREXT = 2500; /* one extension = 25 entries (2500 chars) */ YDSC_PNTR->NAMELEN = (short int) CGN_COPY(YDSC_PNTR->NAMESTR,"DESCRIPTOR.DIRECTORY"); YDSC_PNTR->TYPE = 'C'; /* type of descr. */ YDSC_PNTR->HELPLEN = (short int) 0; /* no help text */ YDSC_PNTR->UNIT = (short int) 0; YDSC_PNTR->BYTELEM = (short int) fcbp->DIRBYTELEM; YDSC_PNTR->NOELEM = fcbp->DSIZE; YDSC_PNTR->START = fcbp->PTRLDB; /* start in 1. LDB (block 2) */ YDSC_PNTR->INDEX = 1; /* in first data word */ dscpntr = (char *) &YDSCDIR_ENTRY; nn = fcbp->DIRENTRY; } else { fcbp->DIRENTRY = ENTRY_SIZE; /* entry in descr. direc. = 1/2/3 * 30 chars */ fcbp->DIREXT = 1500; /* one extension = 1500 chars */ if (fcbp->DSCFLAG == 'Z') /* old version */ { ZDSC_PNTR->NOBLK[0] = '2'; /* indicate how many basic blocks */ ZDSC_PNTR->NOBLK[1] = ' '; ZDSC_PNTR->UNIT = 0; ZDSC_PNTR->BYTELEM = (unsigned short int) fcbp->DIRBYTELEM; ZDSC_PNTR->NOELEM = fcbp->DSIZE; ZDSC_PNTR->START = fcbp->PTRLDB; /* start in 1. LDB (block 2) */ ZDSC_PNTR->INDEX = 1; /* in first data word */ ZDSC_PNTR->HNOELEM = 0; /* no help */ ZDSC_PNTR->HSTART = 0; ZDSC_PNTR->HINDEX = 0; ZDSC_PNTR->TYPE = 'C'; (void) strcpy(ZDSC_PNTR->NAME,"DESCRIPTOR.DIRECTORY"); dscpntr = (char *) &ZDSCDIR_ENTRY; nn = 2*ENTRY_SIZE; } else /* very old version ... */ { dscpntr = (char *) &DSCDIR_ENTRY; (void) strncpy(dscpntr,"DIRECTORY.MIDASC ",20); DSC_PNTR->BYTELEM = fcbp->DIRBYTELEM; DSC_PNTR->NOELEM = (unsigned short int) fcbp->DSIZE; DSC_PNTR->START = fcbp->PTRLDB; /* start in 1. LDB (block 2) */ DSC_PNTR->INDEX = 1; /* in first data word */ nn = ENTRY_SIZE; } } fcbp->DFILLED = nn; /* first entry used for direc. itself */ cpntrb = (char *) &ldbp->LDBWORDS; cpntrb += (3*II_SIZE); /* skip 3 integers (= LDB.LDBWORDS.CWORD[12]) */ CGN_COPYALL(cpntrb,dscpntr,nn); /* put chardata into word 4,5,6,... */ /* already reserve + link the first LDBs together from no. 2 on remember, 4 blocks form an LDB and block 1 = FCB the descr directory is included */ nn = fcbp->INLDB[0] + fcbp->INLDB[1]; /* total no. of inital LDBs */ ldbp->BLKNUM = fcbp->PTRLDB; for (nr=1; nrNEXT = ldbp->BLKNUM + 4; status = cacheLDB(3,iochan,ldbp->BLKNUM,&ldbp); /* write to disk */ if (status != ERR_NORMAL) goto end_of_it; ldbp->BLKNUM = ldbp->NEXT; /* chain LDBs */ } ldbp->NEXT = 0; /* mark end of LDB list */ status = cacheLDB(3,iochan,ldbp->BLKNUM,&ldbp); /* write last LDB to disk */ if (status == ERR_NORMAL) return (status); /* that's it folks... */ /* store error codes */ end_of_it: status = ERR_FRMNAC; MID_ERROR("MIDAS","MID_INITDS:",status,0); return (status); } /* */ int MID_RDSCRC(iochan,start_block,start_indx,first,total,cvals,nullo) /*++++++++++++++++++++++++++++++++++++++++++++++++++ .PURPOSE read the contents of a descriptor and its extensions as integer/real/character data .ALGORITHM The values of a descriptor are returned as integer/real/char. data. No more than MAXVAL values will be returned, but ACTVAL will be set to the actual no. of values associated with the descriptor, starting from the position which is specified as 1. element .RETURNS nothing --------------------------------------------------*/ int iochan /* IN : channel of frame */; int start_block /* IN : start block no. of descriptor */; int start_indx /* IN : start index in that block */; int first /* IN : position of 1. element to be accessed */; int total /* IN : no. of values to return */; char *cvals /* OUT: array to hold descriptor data */; int *nullo /* IO : no. of null values in data */; { int nulflag, bldb, ildb, extens[2]; int off, begin, end, tval, rval; int status, idummy; char *cpntra; float rdummy; struct LDB_STRUCT *ldbp; /* set up pointers: begin, end point to begin + end of descr. data off points to offset within descr. data */ end = 0; bldb = start_block; ildb = start_indx; nulflag = *nullo; /* save null flag, -1 means do not check... */ status = cacheLDB(1,iochan,bldb,&ldbp); /* get starting LDB in */ /* 1. loop - look for start descriptor element */ loop_1: (void) LDBinfo(iochan,ldbp,ildb,&rval,extens); begin = end + 1; /* keep start index */ end += rval; /* update end */ if (first > end) { bldb = extens[0]; ildb = extens[1] - 1; /* indices are counted in FORTRAN */ if (bldb != ldbp->BLKNUM) status = cacheLDB(1,iochan,bldb,&ldbp); goto loop_1; } /* 2. loop - fill data with descriptor data */ tval = 0; off = first - begin + 1; *nullo = 0; cpntra = cvals; if (nulflag >= 0) { register char *kpntr; register int nr; while (tval < total) { if (bldb != ldbp->BLKNUM) status = cacheLDB(1,iochan,bldb,&ldbp); rval = total - tval; (void) MID_RDLDB(iochan,ldbp,ildb,3,&idummy,&rdummy,cpntra, off,&rval,extens); kpntr = cpntra; /* handle NULL checks */ for (nr=0; nrBLKNUM) status = cacheLDB(1,iochan,bldb,&ldbp); rval = total - tval; (void) MID_RDLDB(iochan,ldbp,ildb,3,&idummy,&rdummy,cpntra, off,&rval,extens); tval += rval; if (tval < total) { cpntra += rval; /* update pointers */ bldb = extens[0]; ildb = extens[1] - 1; off = 1; goto loop2; } } return 0; } /* */ int MID_RDSCRI(iochan,start_block,start_indx,first,total,ivals,nullo) /*++++++++++++++++++++++++++++++++++++++++++++++++++ .PURPOSE read the contents of a descriptor and its extensions as integer/real/character data .ALGORITHM The values of a descriptor are returned as integer/real/char. data. No more than MAXVAL values will be returned, but ACTVAL will be set to the actual no. of values associated with the descriptor, starting from the position which is specified as 1. element .RETURNS nothing --------------------------------------------------*/ int iochan /* IN : channel of frame */; int start_block /* IN : start bldb no. of descriptor */; int start_indx /* IN : start index in that bldb */; int first /* IN : position of 1. element to be accessed */; int total /* IN : no. of values to return */; int *ivals /* OUT: array to hold descriptor data */; int *nullo /* IO : no. of null values in data */; { int nulflag, bldb, ildb, extens[2]; int off, begin, end, tval, rval; int status; int *ipntr; char cdummy[4]; float rdummy; struct LDB_STRUCT *ldbp; /* set up pointers: begin, end point to begin + end of descr. data off points to offset within descr. data */ end = 0; bldb = start_block; ildb = start_indx; nulflag = *nullo; /* save null flag, -1 means do not check... */ status = cacheLDB(1,iochan,bldb,&ldbp); /* 1. loop - look for start descriptor element */ loop_1: (void) LDBinfo(iochan,ldbp,ildb,&rval,extens); begin = end + 1; /* keep start index */ end += rval; /* update end */ if (first > end) { bldb = extens[0]; ildb = extens[1] - 1; /* indices are counted in FORTRAN */ if (bldb != ldbp->BLKNUM) status = cacheLDB(1,iochan,bldb,&ldbp); goto loop_1; } /* 2. loop - fill data with descriptor data */ tval = 0; off = first - begin + 1; *nullo = 0; ipntr = ivals; if (nulflag >= 0) { register int nr; register int *hpntr; while (tval < total) { if (bldb != ldbp->BLKNUM) status = cacheLDB(1,iochan,bldb,&ldbp); rval = total - tval; (void) MID_RDLDB(iochan,ldbp,ildb,1,ipntr,&rdummy,cdummy,off, &rval,extens); hpntr = ipntr; for (nr=0; nrBLKNUM) status = cacheLDB(1,iochan,bldb,&ldbp); rval = total - tval; (void) MID_RDLDB(iochan,ldbp,ildb,1,ipntr,&rdummy,cdummy,off, &rval,extens); tval += rval; if (tval < total) { ipntr += rval; /* update pointers */ bldb = extens[0]; ildb = extens[1] - 1; off = 1; goto loop2; } } return 0; } /* */ int MID_RDSCRR(iochan,start_block,start_indx,first,total,rvals,nullo) /*++++++++++++++++++++++++++++++++++++++++++++++++++ .PURPOSE read the contents of a descriptor and its extensions as integer/real/character data .ALGORITHM The values of a descriptor are returned as integer/real/char. data. No more than MAXVAL values will be returned, but ACTVAL will be set to the actual no. of values associated with the descriptor, starting from the position which is specified as 1. element .RETURNS nothing --------------------------------------------------*/ int iochan /* IN : channel of frame */; int start_block /* IN : start bldb no. of descriptor */; int start_indx /* IN : start index in that bldb */; int first /* IN : position of 1. element to be accessed */; int total /* IN : no. of values to return */; float *rvals /* OUT: array to hold descriptor data */; int *nullo /* IO : no. of null values in data */; { int nulflag, bldb, ildb, extens[2]; int off, begin, end, tval, rval; int status, idummy; char cdummy[4]; float *rpntr; struct LDB_STRUCT *ldbp; /* set up pointers: begin, end point to begin + end of descr. data off points to offset within descr. data */ end = 0; bldb = start_block; ildb = start_indx; nulflag = *nullo; /* save null flag, -1 means do not check... */ status = cacheLDB(1,iochan,bldb,&ldbp); /* 1. loop - look for start descriptor element */ loop_1: (void) LDBinfo(iochan,ldbp,ildb,&rval,extens); begin = end + 1; /* keep start index */ end += rval; /* update end */ if (first > end) { bldb = extens[0]; ildb = extens[1] - 1; /* indices are counted in FORTRAN */ if (bldb != ldbp->BLKNUM) status = cacheLDB(1,iochan,bldb,&ldbp); goto loop_1; } /* 2. loop - fill data with descriptor data */ tval = 0; off = first - begin + 1; *nullo = 0; rpntr = rvals; if (nulflag >= 0) { register int nr; register float *fpntr; while (tval < total) { if (bldb != ldbp->BLKNUM) status = cacheLDB(1,iochan,bldb,&ldbp); rval = total - tval; (void) MID_RDLDB(iochan,ldbp,ildb,2,&idummy,rpntr,cdummy, off,&rval,extens); fpntr = rpntr; for (nr=0; nrBLKNUM) status = cacheLDB(1,iochan,bldb,&ldbp); rval = total - tval; (void) MID_RDLDB(iochan,ldbp,ildb,2,&idummy,rpntr,cdummy,off, &rval,extens); tval += rval; if (tval < total) { rpntr += rval; /* update pointers */ bldb = extens[0]; ildb = extens[1] - 1; off = 1; goto loop2; } } return 0; } /* */ int MID_WDSCRI(iochan,start_block,start_indx,ivals,conflg,first,nval) /*++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ .PURPOSE Write a descriptor + its values as integer/real/character data to the LDB. .ALGORITHM Descriptor data is written into atoms which are already created - so no checks for overflow are necessary. .RETURNS nothing ------------------------------------------------------------------*/ int iochan /* IN : channel no of frame */; int start_block /* IN : start LDB no */; int start_indx /* IN : starting index in bldb */; int *ivals /* IN : integer descriptor data */; int conflg /* IN : constant flag = 1/0 (Yes/No) */; int first /* IN : pos. of 1st desc. value to be accessed \ if 1st = -1, desc. values are appended \ to existing ones */; int nval /* IN : no. of data values */; { int *ipntr; int bldb, ildb, extens[2]; int off, begin, end, tval, rval; int status; char cdummy[4]; float rdummy; struct LDB_STRUCT *ldbp; /* get starting LDB */ bldb = start_block; ildb = start_indx; end = 0; status = cacheLDB(1,iochan,bldb,&ldbp); /* 1. loop - look for start descriptor element */ loop_1: (void) LDBinfo(iochan,ldbp,ildb,&rval,extens); begin = end + 1; /* keep start index */ end += rval; /* update end */ if (first > end) { bldb = extens[0]; ildb = extens[1] - 1; /* indices are counted in FORTRAN */ if (bldb != ldbp->BLKNUM) status = cacheLDB(1,iochan,bldb,&ldbp); goto loop_1; } /* 2. loop - fill descriptor data */ tval = 0; off = first - begin + 1; ipntr = ivals; loop2: if (bldb != ldbp->BLKNUM) status = cacheLDB(1,iochan,bldb,&ldbp); rval = nval - tval; (void) MID_WRLDB(iochan,ldbp,ildb,1,ipntr,&rdummy,cdummy, conflg,off,&rval,extens); tval += rval; if (tval < nval) { if (conflg == 0) ipntr += rval; /* update pointer */ bldb = extens[0]; ildb = extens[1] - 1; off = 1; goto loop2; } return 0; } /* */ int MID_WDSCRR(iochan,start_block,start_indx,rvals,conflg,first,nval) /*+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ .PURPOSE Write a descriptor + its values as integer/real/character data to the LDB. .ALGORITHM Descriptor data is written into atoms which are already created - so no checks for overflow are necessary. .RETURNS nothing --------------------------------------------------------------------------*/ int iochan /* IN : channel no of frame */; int start_block /* IN : start LDB no */; int start_indx /* IN : starting index in bldb */; float *rvals /* IN : real descriptor data */; int conflg /* IN : constant flag = 1/0 (Yes/No) */; int first /* IN : pos. of 1st desc. value to be accessed \ if 1st = -1, desc. values are appended \ to existing ones */; int nval /* IN : no. of data values */; { int bldb, ildb, extens[2]; int off, begin, end, tval, rval; int status, idummy; char cdummy[4]; float *rpntr; struct LDB_STRUCT *ldbp; bldb = start_block; /* get starting LDB */ ildb = start_indx; end = 0; status = cacheLDB(1,iochan,bldb,&ldbp); /* 1. loop - look for start descriptor element */ loop_1: (void) LDBinfo(iochan,ldbp,ildb,&rval,extens); begin = end + 1; /* keep start index */ end += rval; /* update end */ if (first > end) { bldb = extens[0]; ildb = extens[1] - 1; /* indices are counted in FORTRAN */ if (bldb != ldbp->BLKNUM) status = cacheLDB(1,iochan,bldb,&ldbp); goto loop_1; } /* 2. loop - fill descriptor data */ tval = 0; off = first - begin + 1; rpntr = rvals; loop2: if (bldb != ldbp->BLKNUM) status = cacheLDB(1,iochan,bldb,&ldbp); rval = nval - tval; (void) MID_WRLDB(iochan,ldbp,ildb,2,&idummy,rpntr,cdummy, conflg,off,&rval,extens); tval += rval; if (tval < nval) { if (conflg == 0) rpntr += rval; /* update pointer */ bldb = extens[0]; ildb = extens[1] - 1; off = 1; goto loop2; } return 0; } /* */ int MID_WDSCRC(iochan,start_block,start_indx,cvals,conflg,first,nval) /*+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ .PURPOSE Write a descriptor + its values as integer/real/character data to the LDB. .ALGORITHM Descriptor data is written into atoms which are already created - so no checks for overflow are necessary. .RETURNS nothing -------------------------------------------------------------------*/ int iochan /* IN : channel no of frame */; int start_block /* IN : start LDB no */; int start_indx /* IN : starting index in bldb */; char *cvals /* IN : character descriptor data */; int conflg /* IN : constant flag = 1/0 (Yes/No) */; int first /* IN : pos. of 1st desc. value to be accessed \ if 1st = -1, desc. values are appended \ to existing ones */; int nval /* IN : no. of data values */; { int bldb, ildb, extens[2]; int off, begin, end, tval, rval; int status, idummy; char *cpntra; float rdummy; struct LDB_STRUCT *ldbp; /* get starting LDB */ bldb = start_block; ildb = start_indx; end = 0; status = cacheLDB(1,iochan,bldb,&ldbp); /* 1. loop - look for start descriptor element */ loop_1: (void) LDBinfo(iochan,ldbp,ildb,&rval,extens); begin = end + 1; /* keep start index */ end += rval; /* update end */ if (first > end) { bldb = extens[0]; ildb = extens[1] - 1; /* indices are counted in FORTRAN */ if (bldb != ldbp->BLKNUM) status = cacheLDB(1,iochan,bldb,&ldbp); goto loop_1; } /* 2. loop - fill descriptor data */ tval = 0; off = first - begin + 1; cpntra = cvals; loop2: if (bldb != ldbp->BLKNUM) status = cacheLDB(1,iochan,bldb,&ldbp); rval = nval - tval; (void) MID_WRLDB(iochan,ldbp,ildb,3,&idummy,&rdummy,cpntra, conflg,off,&rval,extens); tval += rval; if (tval < nval) { if (conflg == 0) cpntra += rval; /* update pointer */ bldb = extens[0]; ildb = extens[1] - 1; off = 1; goto loop2; } return 0; }