5 Appendix A: Programming Examples 5.1 C 5.1.1 icreate.c 5.1.2 icopy.c 5.1.3 record_copy.c 5.2 FORTRAN 5.2.1 icreate.f 5.2.2 icopy.f
This first example simply creates a new IBIS file with a number of different formats. No Reading or Writing is performed.
/** ** icreate.c: Creates one new IBIS file. ** ** Uses: Ported VICAR runtime library, ** IBIS2 subroutine library. **/ #include "vicmain_c" #include "ibisfile.h" main44() { int outunit,status; int out; int nc, nr; int count, def; char org[10]; char format_buf[20][IFMT_SIZE]; char *fmt_ptr=(char *)0; zvparm("cform", format_buf, &count, &def, 20, IFMT_SIZE); if (!def && count) fmt_ptr=format_buf; zvp("nr", &nr, &def ); /* open the output file, or abort on error */ nc=count; nr=10; zvpone( "org", org, 1, 0 ); zvunit( &outunit, "out", 1, 0); status = IBISFileOpen(outunit,&out,IMODE_WRITE, nc, nr, fmt_ptr, org); if (status!=1) IBISSignalU( outunit, status, 1); /* close up shop */ status = IBISFileClose( out ); if (status != 1) IBISSignalU( outunit, status, 1); }
This next example will create a copy of another IBIS file. This is a lot more than it seems, as the two files may have different organizations (by Row, Column, or old format), and may be from different hosts. The data is translated into the native format automatically.
/** ** icopy.c: Copies one general new IBIS file to another, ** possibly with a change in organization (row/column). ** ** Uses: Ported VICAR runtime library, ** IBIS2 subroutine library. **/ #include "vicmain_c" #include "ibisfile.h" #ifndef MIN #define MIN(x,y) (((x) < (y)) ? (x) : (y)) #endif #define DBUFSIZE 1000 #define IBUFSIZE (DBUFSIZE*sizeof(double)) main44() { int inunit,outunit,status; long in, out; int nc=1, nr=1, col,colsize=1; int row, row_inc, nrow,count; char *format, org[10]; double buffer[IBUFSIZE]; /* needs to be byte-aligned */ /* open the input IBIS file, abort on error */ zvunit( &inunit, "inp", 1, 0); status = IBISFileOpen( inunit, &in, IMODE_READ, 0,0,0,0); if (status!=1) IBISSignalU( inunit, status, 1); /* get the input row & column counts */ IBISFileGet( in, IFILE_NC, &nc, 1, 1, 0 ); IBISFileGet( in, IFILE_NR, &nr, 1, 1, 0 ); /* allocate and get the input format string */ format = (char *)malloc( IFMT_SIZE * nc ); if (!format) { zvmessage( "unable to allocate format string", 0); zabend(); } count = IBISFileGet( in, IFILE_FORMAT,format,1,nc, IFMT_SIZE ); /* open the output file, or abort on error */ zvpone( "org", org, 1, 0 ); zvunit( &outunit, "out", 1, 0); status = IBISFileOpen( outunit, &out, IMODE_WRITE, nc, nr, format,org ); if (status!=1) IBISSignalU( outunit, status, 1); /* * copy the columns -- Note that this is only efficient * for column-oriented files. In general, use of a record * may be be more efficient. */ for (col=1; col<=nc; col++) { /* get the column's translated size */ IBISColumnGet( in, ICOLUMN_U_SIZE, &colsize, col ); /* Compute # rows that will fit into buffer : */ row_inc = (IBUFSIZE + colsize - 1)/colsize ; for (row = 1; row<=nr; row += row_inc) { nrow = MIN( nr+1-row , row_inc); status=IBISColumnRead(in,buffer,col, row, nrow ); if (status != 1) IBISSignal( in, status ); status =IBISColumnWrite(out,buffer,col,row,nrow ); if (status != 1) IBISSignal( in, status ); } } /* close up shop */ IBISFileClose( in, 0 ); status = IBISFileClose( out, 0 ); if (status!=1) IBISSignalU( outunit, status, 1); }
This example shows how to use records to copy data from one place in a file to another using records. The file will be open in update mode. Note that we should really check each column format beforehand that it can handle the translation format specified by the 'format' parameter (ie, ASCII and numeric are not mixed). We should also be careful about making sure that the output buffer isn't overlapping with the input buffer (we can do this with IBISRecordSet( 'NR' )).
#include "vicmain_c.h" #include "ibisfile.h" main44() { int unit; int status,def; int ibis; int row, inrow,outrow,ncols,cols[20]; int nc, nr; int nrows,recrows; int col; int inrecord,outrecord; int fsize; int bufsize; char format[20]; char *buffer; status=zvunit( &unit, "inp", 1, 0); if (status!=1) zvsignal( unit, status, 1); /* open the output file, or abort on error */ status = IBISFileOpen(unit, &ibis, IMODE_UPDATE, 0, 0, 0, 0); if (status!=1) IBISSignalU( unit, status, 1); zvp("inrow", &inrow, &def ); /* starting row to read */ zvp("nrows", &nrows, &def ); /* number of rows to copy */ zvp("outrow", &outrow, &def ); /* where to write the rows */ zvp("format", format, &def ); /* what format to translate */ zvparm("cols",cols,&ncols,&def,0 ); /* which columns to copy */ /* * Create a record with the given rows, format translation * and also resize the buffer to "recrows" rows. */ status = IBISRecordOpen(ibis,&inrecord, 0, cols,ncols, format); if (status != 1) IBISSignal( ibis, status, 1 ); status = IBISRecordOpen(ibis,&outrecord,0,cols, ncols, format); if (status != 1) IBISSignal( ibis, status, 1 ); status = IBISRecordGet(inrecord,IRECORD_REC_SIZE,&bufsize,1,1); if (status != 1) IBISSignal( ibis, status, 1 ); status = IBISRecordGet( inrecord,IRECORD_U_SIZE, &fsize, 1, 1 ); if (status != 1) IBISSignal( ibis, status, 1 ); buffer = (char *)malloc( bufsize ); if (!buffer) zabend(); for (row=0;row<nrows;row++) { status = IBISRecordRead( inrecord, buffer, inrow+row); if (status != 1) IBISSignal( ibis, status, 1); status = IBISRecordWrite( outrecord, buffer, outrow+row); if (status != 1) IBISSignal( ibis, status, 1); } /* close up shop */ status = IBISFileClose( ibis, 0 ); if (status != 1) IBISSignalU( unit, status, 1); }
This program is the FORTRAN equivalent to the "icreate.c" program listed above, and performs the same operations.
C C icreate.f: Creates one new IBIS file. C C Uses: Ported VICAR runtime library, C IBIS2 subroutine library. C include 'VICMAIN_FOR' subroutine main44 integer outunit,status integer out integer nc, nr character*16 org character*5 format_buf(20) integer i include 'ibisfile' !definitions for IBIS-2 C Set up the format_buf as FULL format do i=1,20 format_buf(i) = IFMT_FULL enddo C Set IBIS columns 7, 8, and 9 as formats half, double and A200 format_buf(8) = IFMT_HALF format_buf(9) = IFMT_DOUB format_buf(10) = 'a200' !dont use IFMT_ASCII !!! C Determine from the user-arg if 'row' or 'column' oriented files C are wanted (default=column) call xvpone( 'org', org, 1, 0) C Get the VICAR file unit to pass into ibis_file_open call xvunit( outunit, 'out', 1, status, ' ') C Create the output file for writing with 20 columns and 10 rows. C This call returns in 'out' the IBIS file handle nc=20 !Number of columns nr=10 !Number of rows call ibis_file_open( outunit, out, IMODE_WRITE, nc, nr, + format_buf, org, status) if (status.ne.1) then !print error message using VICAR unit and abort call ibis_signal_u( outunit, status, 1) endif C If you want to initialize the columns, you would use C ibis_column_write or ibis_row_write at this point. C close the file -- important to do, as this updates the VICAR label call ibis_file_close( out, ' ', status ) return end
C C icopy.f: Copies one general new IBIS file to another, C possibly with a change in organization (row/column). C C This routine gives an example of how to use the IBIS-2 C subroutine package using the FORTRAN bridges. C C Uses: Ported VICAR runtime library, C IBIS-2 subroutine library. C include 'VICMAIN_FOR' subroutine main44 integer inunit,outunit,status integer count integer ibis_out,ibis_in,ibufsize parameter (ibufsize=250) integer nc, nr, col,colsize integer row, row_inc, nrow character*16 org character*6 format(1000) character*6 cfmt logical ascii character*64 cbuffer(ibufsize*8) real*8 buffer(ibufsize*64) ! The equivalence is just to conserve memory: equivalence (buffer,cbuffer) include 'ibisfile' C open the input IBIS file, abort on error. The four '0' arguments C in the ibis_file_open are only used for creating output files call xvunit( inunit, 'inp', 1, status, ' ') call ibis_file_open( inunit, ibis_in, IMODE_READ, 0, + 0,' ',' ', status) if (status.ne.1) call ibis_signal_u( inunit, status, 1) C get the # rows & columns and the column-format C of the input IBIS file: count = ibis_file_get( ibis_in,IFILE_NC, nc, 1,1 ) if (count.lt.0) call ibis_signal( ibis_in, count, 1) count = ibis_file_get( ibis_in,IFILE_NR, nr, 1,1 ) if (count.lt.0) call ibis_signal( ibis_in, count, 1) count = ibis_file_get( ibis_in,IFILE_FORMATS, format, 1, nc ) if (count.lt.0) call ibis_signal( ibis_in, count, 1) C open the output file with identical structure. The routine returns C in variable 'ibis_out' the handle to the IBIS file, which should be used C in all IBIS file-io operations call xvpone( 'org', org, 1, 0 ) call xvunit( outunit, 'out', 1,status, ' ') call ibis_file_open( outunit, ibis_out, IMODE_WRITE, nc, + nr, format, org, status ) if (status.ne.1) call ibis_signal_u( outunit, status, 1) C copy the column data from input to output do col=1,nc call ibis_column_get( ibis_in, ICOLUMN_FORMAT, + cfmt, col, status ) if (status .ne.1) call ibis_signal( ibis_in, status, 1) ! Determine format -- library alway returns keywords in UPPERCASE. ascii = (cfmt(1:1).eq.'A') if (ascii) then call ibis_column_set( ibis_in, + ICOLUMN_U_FORMAT,'a64',col,status) if (status .ne.1) call ibis_signal( ibis_in, + status, 1) call ibis_column_set( ibis_out, + ICOLUMN_U_FORMAT,'a64',col,status) if (status .ne.1) call ibis_signal( ibis_out, + status, 1) endif ! Get the size of a column's buffer element, in bytes call ibis_column_get( ibis_in,ICOLUMN_U_SIZE, colsize, + col, status ) if (status .ne.1) call ibis_signal( ibis_in, status, 1) ! Compute #elements that will fit into buffer row_inc = (ibufsize + colsize - 1)/colsize ! Actually do some writing. The ibis_column_read/write calls ! read/write <nrow> rows of column #<col> from buffer, ! starting at row #<row>. The data is automatically converted ! into the native host format of the given column. do row = 1,nr,row_inc nrow = MIN( nr+1-row , row_inc) ! If this is an ASCII column, need to use the A*64 buffer: ! Note that we could have used the same buffer if we ! just turned the U_FORMAT to NONE. if (ascii) then call ibis_column_read( ibis_in, cbuffer, + col, row, nrow,status ) else call ibis_column_read( ibis_in, buffer, + col, row, nrow,status ) endif ! We know that ibis_in is a valid IBIS handle here ! so in case of error, we can call ibis_signal if (status.ne.1) call ibis_signal( ibis_in, + status, 1) ! If this is an ASCII column, need to use CHAR: if (ascii) then call ibis_column_write( ibis_out, cbuffer, + col, row, nrow,status ) else call ibis_column_write( ibis_out, buffer, + col, row, nrow,status ) endif if (status.ne.1) call ibis_signal( ibis_out, + status, 1) enddo enddo C close up shop call ibis_file_close( ibis_in, ' ', status ) if (status.ne.1) call ibis_signal( ibis_in, status, 1) call ibis_file_close( ibis_out,' ', status ) if (status.ne.1) call ibis_signal( ibis_out, status, 1) return end