Reading and Writing Data

Three sets of get and put routines are provided for accessing table data. The "tbe..." routines get or put single elements; that is, values at a specified row and column. The "tbr..." routines get or put one or more elements in a single row. The "tbc..." routines get or put values in a single column over a range of rows. The last (sixth) letter of each routine name specifies the buffer data type: "t" for a text string, "b" for boolean, "i" for integer, "r" for real, and "d" for double precision. The data type of the buffer does not need to be the same as the data type of the table column; the table I/O routines convert data type when the column and buffer do not match.

The tbrgtT and tbcgtT routines return a boolean array that indicates whether the table elements gotten are undefined. A true value means the table element is undefined. The tbegtT routine returns the data type-specific INDEF value when the table element is undefined. When writing values into a table, values may be set to undefined by calling tbrudf. If a row exists, but no value has ever been written to a particular column in that row, the element at that row and column will automatically be undefined; that is, it is not necessary to call tbrudf. A row exists if a value has been put into any column in that row or into a subsequent row (larger row number).

Table E.5: Table Get and Put Procedures.

Example E.2 gets two values from each row of a table and copies them to another table if neither value is undefined. A double-precision buffer is used so that data of any numerical type will be copied without loss of precision.

include <tbset.h> 
define  NCOLS           2       # number of columns to get 
procedure test() 
pointer sp                      # stack pointer 
pointer intable, outtable       # scratch for table names 
pointer ira, idec               # scratch for arrays of input values 
pointer ora, odec               # scratch for arrays of output values 
pointer ra_flag                 # scratch for array of null flags 
pointer dec_flag                # scratch for array of null flags 
char    cname[SZ_COLNAME,NCOLS] # column names 
pointer itp, otp                # pointers to table descriptors 
pointer icp[NCOLS]              # pointers to column descriptors in input 
pointer ocp[NCOLS]              # pointers to column descriptors in output 
int     inrows, onrows          # number of rows in input, output tables 
int     irow                    # loop index for row number in input table 
int     orow                    # row number in output table 
int     i                       # loop index 
bool    nullflag[NCOLS]         # null flags for getting info from a row 
bool    bad                     # true if any element of nullflag is true 
double  value[NCOLS]            # values gotten from a table 
pointer tbtopn() 
int     tbpsta() 
        # Allocate scratch space for table names.  We'll allocate space 
        # for column values later, after we know the size of the table. 
        call smark (sp) 
        call salloc (intable, SZ_FNAME, TY_CHAR) 
        call salloc (outtable, SZ_FNAME, TY_CHAR) 

        # Get table names. 
        call clgstr ("intable", Memc[intable], SZ_FNAME) 
        call clgstr ("outtable", Memc[outtable], SZ_FNAME) 

        # Get column names. 
        call clgstr ("ra_col", cname[1,1], SZ_COLNAME) 
        call clgstr ("dec_col", cname[1,2], SZ_COLNAME) 

        # Open input table. 
        itp = tbtopn (Memc[intable], READ_ONLY, NULL) 

        # Find columns in input table.  Check if they were found. 
        call tbcfnd (itp, cname, icp, NCOLS) 
        if (icp[1] == NULL || icp[2] == NULL) { 
            call tbtclo (itp) 
            call error (1, "column not found") 

        # Create an output table with the same columns as the input table. 
        otp = tbtopn (Memc[outtable], NEW_COPY, itp) 
        call tbtcre (otp) 

        # Copy header parameters from input to output. 
        call tbhcal (itp, otp) 

        # Find columns in output table.  They will be there since they were 
        # in the input table. 
        call tbcfnd (otp, cname, ocp, NCOLS) 

        # There will be fewer rows in the output table if the columns 
        # we're interested in contain undefined elements. 
        inrows = tbpsta (itp, TBL_NROWS) 

        # Here are three different ways of copying the values. 
        # 1.  Copy element by element. 
        orow = 0 
        do irow = 1, inrows { 
            call tbegtd (itp, icp[1], irow, value[1]) 
            call tbegtd (itp, icp[2], irow, value[2]) 
            if (!IS_INDEFD(value[1]) && !IS_INDEFD(value[2])) { 
                orow = orow + 1 
                call tbeptd (otp, ocp[1], orow, value[1]) 
                call tbeptd (otp, ocp[2], orow, value[2]) 

        # 2.  Use the get-row and put-row routines.  This will copy 
        # any number of columns, one row at a time. 
        orow = 0 
        do irow = 1, inrows { 
            call tbrgtd (itp, icp, value, nullflag, NCOLS, irow) 
            bad = false 
            do i = 1, NCOLS 
                if (nullflag[i]) 
                    bad = true 
            if (!bad) { 
                orow = orow + 1 
                call tbrptd (otp, ocp, value, NCOLS, orow) 

        # 3.  Use the get-column and put-column routines. 
        call salloc (ira, inrows, TY_DOUBLE) 
        call salloc (idec, inrows, TY_DOUBLE) 
        call salloc (ra_flag, inrows, TY_BOOL) 
        call salloc (dec_flag, inrows, TY_BOOL) 
        call salloc (ora, inrows, TY_DOUBLE)    # possibly more than we need 
        call salloc (odec, inrows, TY_DOUBLE) 
        call tbcgtd (itp, icp[1], Memd[ira], Memb[ra_flag], 1, inrows) 
        call tbcgtd (itp, icp[2], Memd[idec], Memb[dec_flag], 1, inrows) 

        # Note that irow and orow are zero indexed in this loop. 
        orow = -1 
        do irow = 0, inrows-1 { 
            if (!Memb[ra_flag+irow] && !Memb[dec_flag+irow]) { 
                orow = orow + 1 
                Memd[ora+orow] = Memd[ira+irow] 
                Memd[odec+orow] = Memd[idec+irow] 
        onrows = orow + 1               # number of rows in output table 
        if (orow > 0) { 
            call tbcptd (otp, ocp[1], Memd[ora], 1, onrows) 
            call tbcptd (otp, ocp[2], Memd[odec], 1, onrows) 

        # Done.  Three times, even. 
        call tbtclo (itp) 
        call tbtclo (otp) 
        call sfree (sp) 

Table E.5: - Table Get and Put Procedures.

Generated with CERN WebMaker