/* @(#)tct.c 17.1.1.1 (ESO-DMD) 01/25/02 17:36:45 */ /*=========================================================================== 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 ===========================================================================*/ /*++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ .TYPE Module .NAME tct.c .LANGUAGE C .AUTHOR IPG-ESO Garching .CATEGORY table interface .VERSION 1.0 25-Mar-1987 Definition J.D. Ponz .VERSION 3.0 01-Jul-1990 New Version with Arrays / Elementary IO .COMMENTS \begin{TeX} This module contains the routines to handle tables as a whole. Table initialization and open table functions return the table identification tid, used by other table routines. Tables are physically stored on disk in two different formats: by records, corresponding to the natural way of storing sequentially the rows, and transposed, where all the values of a single variable -- column -- are stored together. It is the responsibility of the user to decide the physical format when initializing the table file. The functions provided by this module are: \begin{itemize} \item Create or Initialize a table (TCTINI) \item Open an existing table (TCTOPN) \item Map an opened table to virtual memory (TCTMAP) \item Unmap a mapped table (TCTUNM): write modified parts, unmap mapped pieces \item Close a table (TCTCLO). \end{itemize} Main arguments used by the routines are: \begin{description} \item[allcol] number of words per record allocated physically in the table file. \item[allrow] number of records (rows) allocated physically in the table file. \item[mode] file opening mode. There are several modes to open a table: F\_I\_MODE input (TBTOPN), F\_O\_MODE output (TBTINI), F\_IO\_MODE input/output (TBTOPN), F\_X\_MODE scratch (TBTINI), F\_D\_MODE descriptors only (TBTOPN). These symbols are provided in the file 'midas\_def.h' in the directory 'MID\_INCLUDE'. The access mode may be forced to mapping with the F\_MAP\_FORCE option, or to elementary i/o mode with the F\_EIO\_FORCE option. The default is EIO mode for tables larger than TBL\_EIO\_LIMIT bytes, a configuration parameter which may be changed with TCOSET \item[name] table file name. It is a character string defining the file name of the table as follows: '[path\_name]table\_name[.ext]', where 'path\_name' is the directory path name, defaulted to the working directory, 'table\_name' is the name of the file and 'ext' is the file extension, defaulted to 'tbl'. \item[storage] physical file format. Defined as F\_RECORD if the table is stored by records, or F\_TRANS for transposed format. These symbols are provided in the file 'midas\_def.h' in the directory 'MID\_INCLUDE'. \item[tid] table identifier. It is an integer number provided by the system when the table is created or opened. \end{description} \end{TeX} 011025 last modif ------------------------------------------------------------*/ #include /* General MIDAS Symbols */ #include #include /* Table System parameters */ #include /* Symbols used for Tables */ #include /* List of Table Errors */ #include /* Classical macros */ #include /* for malloc, free */ static int one = 1; static int zero = 0; static int dunit; /* For future use */ static int eio_limit = TBL_EIO_LIMIT; char *osmmget(), *osmmexp(); /* Memory Allocation Functions */ /* Mnemonics for some operations */ /*======================================================================= * Conversion of NULL values from old to New *=======================================================================*/ #ifdef __STDC__ static int convert_nulls(TABLE *tp) #else static int convert_nulls(tp) /*++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ .PURPOSE Change NULL values to -Infinity .METHOD Assume that table is MAPPED. .RETURNS Number of Modified Columns ------------------------------------------------------------------*/ TABLE *tp; /* MOD: Table concerned */ #endif { int i, j, di, o, cols; char *first, *pv; float fnull; double dnull; TBL_toNULL((TBL_D_R4<cols; j++) { if (tp->swise == F_TRANS) o = tp->offset[j] * tp->arows, di = tp->bytes[j]; else o = tp->offset[j], di = tp->reclen; switch(tp->dtypes[j] >> TBL_D_BITS) { default: continue; case TBL_D_R4: cols++; for (pv = tp->addres + o, i = tp->arows; --i >= 0; pv += di) { if (*((float *)pv) > 1.e38) *(float *)pv = fnull; } break; case TBL_D_R8: cols++; for (pv = tp->addres + o, i = tp->arows; --i >= 0; pv += di) { if (*((double *)pv) > 1.e38) *(double *)pv = dnull; } break; } } return(cols); } /*======================================================================= * Private Routines *=======================================================================*/ #ifdef __STDC__ static int TBL_setcols(TABLE *tp) #else static int TBL_setcols(tp) /*++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ .PURPOSE Set up configuration of the arrays with physical columns .ALGORITHM Allocate memory, and compute offset + length, set formats .RETURNS length of 1 record ------------------------------------------------------------------*/ TABLE *tp; /* MOD: Table concerned */ #endif { int n, len1, icode, ncur, i; /* Compute derived quantities */ tp->reclen = (tp->acols + 1) * 4; tp->wsize = (tp->acols + 1) * tp->arows; /* Store correct locations of arrays */ n = tp->colitems; tp->bytes = (int *)osmmget(n*2*sizeof(int)); tp->abytes = tp->bytes + n; tp->label = osmmget(n*(2+TBL_FORLEN+TBL_LABLEN)); tp->format = tp->label + n*(1+TBL_LABLEN); /* Compute length + offset of each column */ ncur = 4; for (i = 0; i < tp->cols; i++) { icode = tp->dtypes[i]; if (icode < 0) { /* Convert OLD definitions to new ones */ switch (icode) { default: case -4: icode = TBL_D_R4; break; case -8: icode = TBL_D_R8; break; case -11: icode = TBL_D_I1; break; case -12: icode = TBL_D_I2; break; case -14: icode = TBL_D_I4; break; } icode = (icode << TBL_D_BITS) | 1; tp->dtypes[i] = icode; } len1 = TBL_ElementSize(icode); n = TBL_Items(icode); if (tp->version == 0) { /* BEWARE ! (MP) Old to New implies true len of CHAR is multiple of 4 */ n = ((3+len1*n)>>2)<<2; /* n is now Multiple of 4 */ n /= len1; tp->offset[i] = ncur; if (!(icode>>TBL_D_BITS)) tp->dtypes[i] = n; /* MP 070291 */ } tp->bytes[i] = len1*n; ncur += tp->bytes[i]; } /* Zero unused values */ for (; i < tp->colitems; i++) tp->dtypes[i] = tp->offset[i] = tp->bytes[i] = 0; /* Formats not loaded */ for (i=0; i < tp->colitems; i++) tp->format[i*(1+TBL_FORLEN)] = '\0'; /* Labels not loaded */ for (i=0; i < tp->colitems; i++) tp->label[i*(1+TBL_LABLEN)] = '\0'; return (ncur); } #ifdef __STDC__ static int do_map(TABLE *tp, int mode) #else static int do_map(tp, mode) /*++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ .PURPOSE Choose the mode for file access (EIO / Mapping / Simulated Mapping) .RETURNS status ------------------------------------------------------------------*/ TABLE *tp; /* IN: Table to map */ int mode; /* IN: Mode for Mapping */ #endif { int status; int dummy, i; float null_float; status = ERR_NORMAL; tp->cbuf = tp->nbuf = 0; tp->tbuf = (TABLE_BUF *)0; tp->sbuf = 0; tp->addres = (char *)0; tp->loaded_map = (unsigned char *)0; tp->vsel = (unsigned char *)0; tp->vsize = 0; /* Check, for old versions, of possible bad NULL values. Changing NULL values also implies loding the table, and therefore the F_MAP_FORCE is set. Note that this test is only temporarly required, until no table with old format exists any more... */ if (tp->version == 0) { TBL_toNULL((TBL_D_R4<tflags |= TBL__BADNULLS; */ tp->tflags |= TBL__BADNULLS; mode = F_MAP_FORCE|F_IO_MODE; } /* Choose the mode: TBL__MAPPED, or TBL__EIO. If no option, use TBL_EIO if size > TBL_EIO_LIMIT */ if (mode & F_MAP_FORCE) tp->tflags |= TBL__MAPPED; else if (mode & F_EIO_FORCE) tp->tflags |= TBL__EIO; if ((tp->tflags& (TBL__MAPPED|TBL__EIO)) == 0) { if (sizeof(int)*tp->acols*tp->arows > eio_limit) tp->tflags |= TBL__EIO; } if (tp->tflags & TBL__MAPPED) { status = SCFMAP(tp->imno, mode&0xf, 1,0,&dummy,&tp->addres); if_not(tp->tflags & TBL__READONLY) tp->tflags |= TBL__MODIFIED; } else if (tp->tflags & TBL__EIO) { /* Elementary Mode. Define Buffers */ /* Let's assume at least one buffer per column (in case the table is stored columnwise and accessed recordwise) + Selection + another */ tp->nbuf = tp->acols + 2; if (tp->nbuf < TBL_TBUFS) tp->nbuf = TBL_TBUFS; i = tp->nbuf * sizeof(TABLE_BUF); tp->tbuf = (TABLE_BUF *)osmmget(i); oscfill ((char *)tp->tbuf, i, 0); } else { /* BitMap contains size/64k bytes */ i = sizeof(float)*(tp->acols + 1) * tp->arows; tp->addres = osmmget(i); i = (1 + (i|0xffff)) >> 16; tp->loaded_map = (unsigned char *)osmmget(2*i); tp->modified_map = tp->loaded_map + i; oscfill ((char *)tp->loaded_map, 2*i, 0); } if (status) TBL_errf(status, "can't map table: %s", tp->phname); return(status); } /*======================================================================= * Public Routines *=======================================================================*/ int TCTCLO(tid) /*++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ .PURPOSE Closes table file . .ALGORITHM First Unmap, then release used memory. .RETURNS status ------------------------------------------------------------------*/ int tid; /* IN : table id */ { TABLE *tp; int status, i, m; char save_name[100]; tp = TBL_ptr(tid); if (status = CheckTable(tp)) return(TBL_errs(tid, status,0)); if (tp->intlFITS == 'F') { /* SCFCLO may still need FITS data */ if (status = TCTUNMF(tid,0)) return(status); status = SCFCLO(tp->imno); (void) TCTUNMF(tid,1); /* now, also free table data memory */ goto free_memory; } if (status = TCTUNM(tid)) return(status); status = SCFCLO(tp->imno); if (status == -99) /* we have to convert to FITS */ (void) strcpy(save_name,tp->phname); /* Free allocated memory of table */ free_memory: if (tp->phname != (char *) 0) { osmmfree(tp->phname); osmmfree((char *)tp->loaded_map); } /* tp->usname is NOT used currently */ if (!(tp->tflags&TBL__MAPPED)) { if (tp->addres != (char *) 0) osmmfree(tp->addres); } if (tp->label != (char *) 0) osmmfree(tp->label); if (tp->dtypes != (int *) 0) osmmfree((char *)tp->dtypes); if (tp->bytes != (int *) 0) osmmfree((char *)tp->bytes); if (tp->tbuf != (TABLE_BUF *) 0) osmmfree((char *)tp->tbuf); if (tp->vsel != (unsigned char *) 0) osmmfree((char *)tp->vsel); TBL_kill(tid); if (status == -99) /* we have to convert to FITS */ { char temp[12], delname[80]; delname[0] = '\0'; status = TCTOPN(save_name,F_I_MODE,&i); if (status == 0) { tid = i; status = SCFSAV(tid,2); /* convert table to FITS */ if (status != ERR_NORMAL) return (status); status = SCFCLO(tid); if (status == ERR_NORMAL) { status = osfrename("midFITS.mt",save_name); if (status != 0) { status = ERR_INPINV; (void) sprintf(temp,"TCTCLO/osfrename: %s ",save_name); MID_ERROR("MID",temp,status,0); return (status); } tp = TBL_ptr(tid); goto free_memory; } } } return (status); } int TCTCRV(name, refer_name, mode) /*++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ .PURPOSE Create a view (a table with only a Selection Column) taking columns from another (existing!) table. .ALGORITHM The view is ONLY CREATED. It must later be opened ... .RETURNS Status ------------------------------------------------------------------*/ char *name; /* IN : Name of view to create */ char *refer_name; /* IN : Name of related table */ int mode; /* IN : creation mode (future) */ { int status; int vid; TABLE *vp; /* Operations: 1- TCTOPN refer_table in read-only mode; check. 2- Create file. Set all bits to 1. 3- Copy column definitions 4- Copy selections ? */ if (status = TCTOPN (refer_name, F_I_MODE | F_EIO_FORCE, &vid)) return (status); vp = TBL_ptr (vid); if (vp->swise & F_B_VIEW) { TCTCLO (vid); return (TBL_errf(ERR_TBLENT, "can't create view of the view: %s", refer_name)); } vp->swise |= F_B_VIEW; vp->vsize = 4 + (vp->rows>>3) ; vp->vsel = (unsigned char *)osmmget( vp->vsize ); oscfill ((char *)vp->vsel, vp->vsize, ~0); if (status = SCFCRE (name, D_R4_FORMAT, F_O_MODE, F_TBL_TYPE, vp->vsize>>2, &vp->vno)) goto error; status = SCFPUT(vp->vno,1,vp->vsize,(char *)vp->vsel); /* Add refer_table as descriptor */ status = SCDWRC(vp->vno, TBL_Dview, 1, refer_name, 1, strlen(refer_name), &dunit); if (status) goto error; /* copy descriptors */ if (status = SCDCOP(vp->imno, vp->vno, 1, " ")) goto error; /* Rewrite Main Descriptor */ if (status = SCDWRI(vp->vno, TBL_Dmain, &vp->acols, 1,TBL_Dmain_SIZE,&dunit)) goto error; SCFCLO(vp->vno); error: /* error in SC routines */ TCTCLO (vid); if (status) TBL_errs(vid, status, 0); return ( status ); } /* */ int TCTUNMF(tid,flag) /*++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ .PURPOSE Unmap (Flush) FITS table file in 2 calls .ALGORITHM 1st call: write back modified parts 2nd call: release used memory .RETURNS status ------------------------------------------------------------------*/ int tid; /* IN : table id */ int flag; /* IN : 0 = do 1st part of TCTUNM 1 = do 2nd part of TCTUNM */ { TABLE *tp; TABLE_BUF *bp; int status, i, newtid; int *tmpntr, *base, *tbptr; int maxval, inull; register int nr; tp = TBL_ptr(tid); status = ERR_NORMAL; if (flag == 0) { if (tp->phname == (char *) 0) return ERR_NORMAL; /* nothing to do */ /* tp->usname is currently NOT ised... if (tp->vsize != 0 && tp->usname) { if (tp->tflags & TBL__VREADONLY) ; else { status = SCFOPN(tp->usname,D_R4_FORMAT,F_O_MODE,F_TBL_TYPE, &newtid); status = SCFPUT (newtid, 1, tp->vsize, (char *)tp->vsel); status = SCFCLO(newtid); } } */ if ((tp->tflags & (TBL__READONLY|TBL__MODIFIED)) == TBL__MODIFIED) { if_not (tp->tflags & TBL__KEEPVERS) tp->version = TBL_VERSION; /* If ALL is selected, correct number of selected rows */ if ((tp->selected < 0) && (tp->select == '\1')) tp->selected = tp->rows; } if (tp->tflags != TBL__READONLY) /* if_not (tp->tflags & TBL__MAPPED) */ status = TBL_WR (tp); } else { if (tp->addres != (char *) 0) { osmmfree(tp->addres); tp->addres = (char *) 0; /* MP 920909 */ } for (i=0; inbuf; i++) { bp = tp->tbuf+i; if (bp && bp->buf) osmmfree(bp->buf); } } return (status); } /* */ int TCTFIX(tid) /*++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ .PURPOSE write control descriptors of table .RETURNS status added by KB 980428 990624 ------------------------------------------------------------------*/ int tid; /* IN : table id */ { TABLE *tp; int status; int i; tp = TBL_ptr(tid); if (status = TCTUNM(tid)) return(status); /* Free allocated memory */ osmmfree(tp->phname); tp->phname = (char *) 0; /* tp->usname is NOT used currently */ osmmfree((char *)tp->dtypes); tp->dtypes = (int *) 0; osmmfree((char *)tp->bytes); tp->bytes = (int *) 0; osmmfree(tp->label); tp->label = (char *) 0; if (!(tp->tflags&TBL__MAPPED)) { if (tp->addres != (char *) 0) { osmmfree(tp->addres); tp->addres = (char *) 0; } } osmmfree((char *)tp->tbuf); tp->tbuf = (TABLE_BUF *) 0; osmmfree((char *)tp->loaded_map); tp->loaded_map = (unsigned char *) 0; osmmfree((char *)tp->vsel); tp->vsel = (unsigned char *) 0; return (status); } int TCTUNM(tid) /*++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ .PURPOSE Unmap (Flush) table file .ALGORITHM Writes back modified parts and releases used memory. .RETURNS status ------------------------------------------------------------------*/ int tid; /* IN : table id */ { TABLE *tp; TABLE_BUF *bp; int status; int i,newtid; tp = TBL_ptr(tid); if (status = CheckTable(tp)) return(TBL_errs(tid, status,0)); if (tp->vsize != 0 && tp->usname) { if (tp->tflags & TBL__VREADONLY) ; else { status = SCFOPN(tp->usname,D_R4_FORMAT,F_O_MODE,F_TBL_TYPE, &newtid); status = SCFPUT (newtid, 1, tp->vsize, (char *)tp->vsel); status = SCFCLO(newtid); } } if ((tp->tflags & (TBL__READONLY|TBL__MODIFIED)) == TBL__MODIFIED) { if_not (tp->tflags & TBL__KEEPVERS) tp->version = TBL_VERSION; /* If ALL is selected, correct number of selected rows */ if ((tp->selected < 0) && (tp->select == '\1')) tp->selected = tp->rows; /* write descriptors */ status = SCDWRI(tp->imno, TBL_Ddtypes, tp->dtypes, 1,tp->colitems, &dunit); if (status == ERR_NORMAL) status = SCDWRI(tp->imno, TBL_Doffset, tp->offset,1,tp->colitems, &dunit); if (status == ERR_NORMAL) status = SCDWRI(tp->imno, TBL_Dmain, &tp->acols,1,TBL_Dmain_SIZE,&dunit); if (status != ERR_NORMAL) goto error; } if_not (tp->tflags & TBL__MAPPED) { /* Must write everything */ if (status = TBL_WR (tp)) return(status); osmmfree(tp->addres); tp->addres = '\0'; /* MP 920909 */ } for (i=0; inbuf; i++) { bp = tp->tbuf+i; if (bp && bp->buf) osmmfree(bp->buf); } error: /* error in SC routines */ if (status) { TBL_enter("TCTUNM problems"); TBL_errs(tid, status, 0); } return (status); } int TCTID(name) /*++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ .PURPOSE Find number from Name .RETURNS Corresponding tid / -1 if not found --------------------------------------------------------------------*/ char *name; /* IN: Name to look for */ { return (TBL_tid(name)); } int TCTINI(name, storage, mode, allcol, allrow, tid) /*++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ .PURPOSE Initializes table file on disk and in memory .ALGORITHM Creates output file and opens it according to the desired storage option and mode. The storage option can be by records (F_RECORD) or transposed (F_TRANS). The openning mode can be F_O_MODE for output or F_X_MODE for scratch. The mode may include modifiers F_MAP_FORCE to force the mapping, F_EIO_FORCE to force an elementary i/o mode, F_ALL_FORCE to force exact numbers of lines / cols. In this last case (F_ALL_FORCE), the number of physical columns to allocate may be given in the 2 leftmost bytes of mode, i.e. mode = (physical_columns*2**16 + F_ALL_FORCE + mode) .RETURNS Status ------------------------------------------------------------------*/ char *name; /* IN : table name */ int storage; /* IN : physical structure on disk */ int mode; /* IN : opening mode */ int allcol; /* IN : number of words per record alloc.*/ int allrow; /* IN : number of rows allocated */ int *tid; /* MOD: table identifier (try to keep it) */ { TABLE *tp; int status; int imno, len, acol, arow, colitems; int dummy; tp = (TABLE *)0; acol = (allcol <= 0) ? TBL_DALCOL : allcol ; arow = (allrow <= 0) ? TBL_DALROW : allrow ; /* Restrictions: Rows multiple of 8, columns odd. * This ensures alignments on 8-byte boundaries */ colitems = 0; if (mode & F_ALL_FORCE) { colitems = mode >> 16; } else { arow = ((arow+7)>>3)<<3; if (!(acol&1)) acol++; } if (colitems == 0) colitems = MIN (acol, COLS_MAX); len = arow * (acol + 1); imno = 0; if (mode == F_FO_MODE) { dummy = 1; mode = F_O_MODE; status = SCFCRE(name,D_R4_FORMAT,mode&0xf,F_FTBL_TYPE,len,&imno); } else { dummy = 0; status = SCFCRE(name,D_R4_FORMAT,mode&0xf,F_TBL_TYPE,len,&imno); } if (status != ERR_NORMAL) goto error; /* initialize control variables */ if (TBL_new(imno) < 0) return(TBL_errf(ERR_TBLFUL, "too many tables, can't create %s", name)); *tid = imno; tp = TBL_ptr(imno); tp->phname = TBL_ssave(name); tp->usname = (char *)0; tp->imno = imno; tp->acols = acol; tp->arows = arow; tp->cols = 0; tp->rows = 0; tp->kcol = 0; tp->scol = 0; tp->swise = storage; tp->version= TBL_VERSION; tp->colitems = colitems; tp->selected = -1; /* Unknown */ tp->tflags = 0; tp->select = 0; if (dummy == 1) tp->intlFITS = 'F'; /* internal FITS table */ else tp->intlFITS = 0; /* Initialize columns for dtype */ tp->dtypes = (int *)osmmget(2*sizeof(int)*tp->colitems); tp->offset = tp->dtypes + tp->colitems; TBL_setcols (tp); /* Write Basic Descriptors */ status = SCDWRI(tp->imno, TBL_Ddtypes, tp->dtypes, 1,tp->colitems, &dunit); if (status != ERR_NORMAL) goto error; status = SCDWRI(tp->imno, TBL_Doffset, tp->offset, 1,tp->colitems, &dunit); if (status != ERR_NORMAL) goto error; status = SCDWRI(tp->imno, TBL_Dmain, &tp->acols,1,TBL_Dmain_SIZE,&dunit); if (status != ERR_NORMAL) goto error; /* map file */ status = do_map(tp, mode); if (status != ERR_NORMAL) goto error; if (tp->intlFITS == 'F') /* we have to write data */ { /* because TCSINI uses SCFGET ... */ status = dummyPUT(imno,len); if (status != ERR_NORMAL) goto error; } /* Initialize S */ TCSINI (*tid); error: if (status) { if (tp) osmmfree (tp->phname), TBL_kill (tp->imno); if (status < ERR_TBLFUL) /* SC error */ MID_ERROR("MIDAS","TCTINI: ",status,1); } return ( status ); } /* */ int dummyPUT(imno,size) int imno, size; { int status, savtyp; char *fpt; struct FCT_STRUCT *fctpntr; fctpntr = FCT.ENTRIES + imno; fpt = osmmget((unsigned int) (size * sizeof(float))); /* already set to 0 */ fctpntr->FILTYP = 22; status = SCFPUT(imno,1,size,fpt); fctpntr->FILTYP = 2; osmmfree(fpt); return (status); } /* */ int TCTMAP(tid, addr) /*++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ .PURPOSE Maps complete Table .RETURNS status ------------------------------------------------------------------*/ int tid; /* IN : table id */ char **addr; /* OUT: Where table Mapped */ { TABLE_BUF *bp; /* MOD: The buffer concerned */ TABLE *tp; unsigned char *pmap; int status; int i; tp = TBL_ptr(tid); if (status = CheckTable(tp)) return(TBL_errs(tid, status,0)); if (tp->tflags & TBL__MAPPED) { /* Already Done */ *addr = tp->addres; return(status); } if (tp->tflags & TBL__EIO) { /* Verify all empty */ for (i = tp->nbuf, bp = tp->tbuf; (--i >= 0) && (bp->size == 0); bp++); } else { /* Just check bitmap */ i = sizeof(float)*(tp->acols + 1) * tp->arows; i = (1 + (i|0xffff)) >> 16; for (pmap = tp->loaded_map; (--i >= 0) && (*pmap == 0); pmap++) ; } if (i >= 0) status = ERR_TBLMAP; if (status) { TBL_errf(status, "Table partly mapped. First Unmap table %s", tp->phname); return(status); } /* Free allocated memory for Buffers */ osmmfree((char *)tp->tbuf); osmmfree((char *)tp->loaded_map); osmmfree((char *)tp->vsel); i = F_MAP_FORCE | (tp->tflags & TBL__READONLY ? F_I_MODE : F_IO_MODE); status = do_map (tp, i); return (status); } int TCTOPN(name,mode,tid) /*++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ .PURPOSE Reads table file from disk. .ALGORITHM Opens table file according to the desired mode. The openning mode can be F_I_MODE for input, F_D_MODE for descriptors only, F_IO_MODE for update. The mode may include modifiers F_MAP_FORCE to force the mapping, or F_EIO_FORCE to force an elementary i/o mode. .RETURNS Status ------------------------------------------------------------------*/ char *name; /* IN : table name */ int mode; /* IN : openning mode */ int *tid; /* MOD: table identifier (try to keep it) */ { TABLE *tp; int dnull, imno, maxval; int flags[3]; int status; /* opens file */ SCECNT("GET", flags, flags+1, flags+2); SCECNT("PUT", &one, flags+1, &zero); imno = *tid; /* in case a specific `index' is wanted... */ if (status = SCFOPN(name, D_R4_FORMAT, 0, F_TBL_TYPE, &imno)) { SCECNT("PUT", flags, flags+1, flags+2); return(TBL_errf(status,"Error opening Table %s",name)); } if (TBL_new(imno) < 0) /* Not too many opened tables? */ { TBL_errf(ERR_TBLFUL, "too many tables, can't open %s", name); return (ERR_TBLFUL); } *tid = imno; tp = TBL_ptr(imno); tp->phname = TBL_ssave(name); tp->usname = (char *)0; tp->tflags = ((mode&0xf) == F_I_MODE ? TBL__READONLY : 0); tp->imno = imno; tp->addres = (char *)0; tp->select = 0; /* get control variables */ status = SCDRDI(tp->imno, TBL_Dmain,1,TBL_Dmain_SIZE, &maxval,&tp->acols,&dunit,&dnull); if (status != ERR_NORMAL) goto error; if (maxval < 8) tp->version = 0; if (maxval < 9) tp->colitems = MAX (tp->acols, tp->cols); if (maxval <10) tp->selected = -1; /* Unknown */ if (tp->selected == -1) tp->selected = tp->rows; /* Is it a View ? */ if (tp->swise & F_B_VIEW) { int vid; TABLE *vp; char view[1+TBL_Dview_SIZE]; status = SCDRDC(tp->imno, TBL_Dview, 1,1,TBL_Dview_SIZE, &maxval, view, &dunit, &dnull); if (status != ERR_NORMAL) { TBL_errf (status, "Bad View: %s", name); goto error; } view[maxval] = '\0'; if (osfdate(view) > osfdate(name)) TBL_errf (-1, "table '%s' refered by view '%s' was modified ?", view, name); status = TCTOPN (view, F_I_MODE, &vid); if (status != ERR_NORMAL) goto error; vp = TBL_ptr(vid); vp->vno = tp->imno; /* vp->swise = tp->swise; */ if (tp->tflags & TBL__READONLY) vp->tflags |= TBL__VREADONLY; /* Read Selection Table */ vp->vsize = 1 + (vp->rows>>3); vp->vsel = (unsigned char *)osmmget( vp->vsize ); vp->usname = TBL_ssave(name); status = SCFGET (vp->vno, 1, tp->vsize>>2, &maxval, (char *)vp->vsel); TCTCLO(*tid); TBL_kill(*tid); *tid = vid; goto error; } /* Map File */ status = do_map(tp, mode); if (status != ERR_NORMAL) goto error; /* Get Column datatypes */ tp->dtypes = (int *)osmmget(2*sizeof(int)*tp->colitems); tp->offset = tp->dtypes + tp->colitems; status = SCDRDI(tp->imno, TBL_Ddtypes,1,tp->colitems,&maxval, tp->dtypes,&dunit,&dnull); if (status != ERR_NORMAL) goto error; if (tp->version) status = SCDRDI(tp->imno, TBL_Doffset,1,tp->colitems, &maxval,tp->offset,&dunit,&dnull); /* layout of physical columns */ TBL_setcols (tp); /* Convert NULL values if required */ if (tp->tflags & TBL__BADNULLS) { convert_nulls(tp); tp->tflags &= ~TBL__BADNULLS; } error: SCECNT("PUT", flags, flags+1, flags+2); if ((status) && (status < ERR_TBLFUL)) /* SC error */ TBL_errs(imno, status, 0); return ( status ); } int TCTVIS(tid,name) /*++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ .PURPOSE Reads table file from disk. .ALGORITHM Opens table file according to the desired mode. The openning mode can be F_I_MODE for input, F_D_MODE for descriptors only, F_IO_MODE for update. The mode may include modifiers F_MAP_FORCE to force the mapping, or F_EIO_FORCE to force an elementary i/o mode. .RETURNS Status ------------------------------------------------------------------*/ int tid; /* MOD: table identifier (try to keep it) */ char *name; /* IN : table name */ { TABLE *tp; tp = TBL_ptr(tid); if (tp->usname) { strncpy(name,tp->usname,60); return(1); } else return(0); }