aboutsummaryrefslogtreecommitdiff
path: root/doc/html/UsingC.html
diff options
context:
space:
mode:
Diffstat (limited to 'doc/html/UsingC.html')
-rw-r--r--doc/html/UsingC.html505
1 files changed, 505 insertions, 0 deletions
diff --git a/doc/html/UsingC.html b/doc/html/UsingC.html
new file mode 100644
index 0000000..3acab85
--- /dev/null
+++ b/doc/html/UsingC.html
@@ -0,0 +1,505 @@
+<html>
+ <head>
+ <title>IEEEIO C Interface</title>
+ </head>
+ <body bgcolor="#F0F0F0">
+ <table><tr>
+ <td><img src="Images/info.gif"></td>
+ <td><h1>ANSI and K&R C</h1></td>
+ </tr></table>
+ <hr>
+ <h1>Using the C Interface</h1>
+ To use the C interface, you must include the
+ headers <b>IO.h</b> and <b>IEEEIO.h</b>. By default the headers
+ are treated as K&R C (eg. no prototypes) because that is the
+ default of for many workstation C compilers. To enable the ANSI
+ C prototypes compile with -DANSI or use <b>#define ANSI</b> in
+ your source files before you include the <b>IO.h</b> and
+ <b>IEEEIO.h</b> headers. If you only require
+ the IEEEIO interface, you link only with <b>libieeeio.a</b> using
+ <code>-L$IEEE_DIRECTORY/lib -lieeeio</code><p>
+
+ If you also want HDF support you must also include the header
+ <b>HDFIO.hh</b> and link with <b>libhdfio.a</b> and
+ the usual complement of HDF libraries using
+ <code>-L$HDF_DIRECTORY/lib -L$IEEE_DIRECTORY/lib -lhdfio -lieeeio -lmfhdf -ldf -ljpeg -lz</code><p>
+
+ <hr>
+ <h1>C Subroutines</h1>
+ <UL>
+ <LI><a href="#Opening">Opening and Closing Datafiles</a>
+ <LI><a href="#Writing">Writing Datasets</a>
+ <LI><a href="#Reading">Reading Datasets</a>
+ <LI><a href="#Seeking">Random Access to Datasets
+ <i>(Seeking)</i></a>
+ <LI><a href="#WriteAttribs">Writing Attributes</a>
+ <LI><a href="#ReadAttribs">Reading Attributes</a>
+ <LI><a href="#WriteAnn">Writing Annotations</a>
+ <LI><a href="#ReadAnn">Reading Annotations</a>
+ <LI><a href="#ReadWriteChunk">Writing and Reading in Chunks</a>
+ </UL>
+
+ <hr>
+ <a name="Opening"><h2>Opening</h2></a>
+ Just like the familiar <b>FILE*</b> type for C stdio operations, all
+ IEEEIO operations require a file handle. The type of this handle is
+ IOFile (and 8-byte integer number). The <b>IEEEopen()</b> and
+ <b>HDFIOopen()</b>
+ routines are used to create this handle and the IOclose() subroutine can
+ be used to close file handles of either type.<p>
+ <b>ANSI C Prototype</b><br>
+ <code>IOFile IEEEopen(char *filename,char *accessmode);</code><br>
+ <DL>
+ <DT><i>filename</i>:
+ <DD>The name of the IEEEIO data file to
+ open. The typical extension for these files is <i>.raw</i>
+ <DT><i>accessmode</i>:
+ <DD>The accessmode for the file. This is
+ one of 3 different access modes
+ <UL>
+ <LI><b>"read"</b>:<i>Opens a file in read-only mode. This
+ can also be selected using any of the standard fopen()
+ modes; "r" and "rb"</i>
+ <LI><b>"write"</b>:<i>Opens a file in write-only mode. If the
+ file does not exist, it will be created. If it does exist, it will be
+ truncated. This
+ can also be selected using any of the standard fopen()
+ modes; "w","wb","w+","w+b", and "wb+"</i>
+ <LI><b>"append"</b>: <i>Opens a file in read/write mode. The file
+ pointer is automatically placed at the end of the file for appending,
+ but random-access read operations are allowed as well.This
+ can also be selected using any of the standard fopen()
+ modes; "a","ab","a+","a+b", and "ab+"</i>
+ </UL>
+ </DL>
+
+ After you open the file handle you can use the same set of
+ subroutines for operations on the file regardless of whether the
+ file is HDF or IEEEIO. The libraries manage all of this internally. So
+ the open step is the only thing that is important to differentiating
+ between your HDF and IEEEIO files.
+ There are plans, for example, to have a SocketIO system
+ that allows the data to be written out to a TCP socket instead of to a
+ file for real-time simulation-visualization systems. There are also
+ plans to use this interface to drive an existing Parallel IO
+ system.<p><br>
+ <pre>
+ /* write an IEEEIO file */
+ IOFile writer = IEEEopen("datafileout.raw","write");
+ /* write an HDF file */
+ IOFile writer = HDFIOopen("datafileout.raw","w"); /* "w" is also valid */
+ /* another way to open for writing */
+ IOFile writer = IEEEopenWrite("datafileout.raw");
+ /* open HDF file for reading */
+ IOFile reader = HDFIOopen("datafilein.raw","read");
+ /* another way to open an HDF file for reading */
+ IOFile reader = HDFIOopenRead("datafileout.raw");
+ /* another way to open an IEEEIO file for reading */
+ IOFile reader = IEEEopenRead("datafileout.raw");
+ </pre><p>
+
+ You can test if the file was opened successfully using the
+ IOisValid() function.<br>
+ <pre>
+ IOFile fileID = IEEEopen("datafileout.raw","write");
+ if(!IOisValid(fileID))
+ puts("The file you specified does not exist or is not in a
+readable format");
+ </pre><br>
+
+ To close the file, you simply use IOclose.
+ <pre>
+ IOclose(IOFile filehandle);
+ </pre>
+
+
+ <hr>
+ <a name="Writing"><h2>Writing</h2></a>
+ To write data you simply use the method write().
+ <p><b>ANSI C Prototype</b><br>
+ <code>int IOwrite(IOFile filehandle,int numbertype,int rank,int
+ *dimensions,void *data);</code>
+ <DL>
+ <DT><i>filehandle</i>
+ <DD>An open filehandle for the datafile.
+ <DT><i>numbertype</i>:
+ <DD>The type of the data being stored
+ <i>(<a href="DataTypes.html">datatype definition</a>)</i>.
+ It can be one of
+ <UL>
+ <LI><b>FLOAT32</b><br><i>32-bit single-precision IEEE
+ float</i>
+ <LI><b>FLOAT64</b><br><i>64-bit double-precision IEEE
+ float</i>
+ <LI><b>STRING</b><br><i>Character string. This is
+ null-terminated automatically by the API. This is
+ interpreted differently from the <b>byte</b> datatype
+ which is raw data.</i>
+ <LI><b>INT8</b><br><i>byte</i>
+ <LI><b>INT16</b><br><i>16-bit short integer</i>
+ <LI><b>INT32</b><br><i>32-bit standard integer</i>
+ <LI><b>INT64</b><br><i>64-bit long integer. (note: this is not
+ availible on the Intel/Windows platform because it
+ does not allow 64-bit integers)</i>
+ <LI><b>UINT8</b><br><i>unsigned character</i>
+ <LI><b>UINT16</b><br><i>unsigned 16-bit short integer</i>
+ <LI><b>UINT32</b><br><i>unsigned 32-bit standard integer</i>
+ <LI><b>UINT64</b><br><i>unsigned 64-bit long
+ integer. (note: this is not availible on the
+ Intel/Windows platform)</i>
+ </UL>
+ <DT><i>rank</i>
+ <DD>Number of dimensions of the dataset
+ <DT><i>dimensions</i>:
+ <DD>An array of <i>rank</i> integers that give the dimensions of
+ the dataset
+ <DT><i>data</i>:
+ <DD>Your data array.
+ </DL>
+
+ So to write a sample array of data.
+ <pre>
+ float myarray[40][50][60]; /* our bogus data array */
+ int i,rank=3;
+ int dims[3]={60,50,40}; /* notice these are reversed. */
+ /* this is because ieeeio assumes f77 order for data
+ and c/c++ use exactly the opposite ordering for data in */
+memory.
+ IOFile writer=IEEEopen("datafile.raw","write"); /* create a outfile */
+ for(i=0;i&ltndatasets;i++){
+ . . . . computation . . .
+ IOwrite(writer,FLOAT32,rank,dims,myarray); /* write a dataset */
+ . . . . you can write as many datasets as you want
+ }
+ IOclose(writer); /* then close the file */
+ </pre>
+
+ <hr>
+ <a name="Reading"><h2>Reading Data</h2></a>
+ Reading is a two step process. First you get information on
+ the size and type of the data you intend to read. This allows
+ you to allocate an array of the proper size and type for the
+ reading. Then you actually read the data into a pre-allocated
+ array. The methods for this are <b>IOreadInfo()</b> and
+ <b>IOread()</b>.<p>
+ <b>ANSI C Prototype</b><br>
+ <code>int IOreadInfo(IOFile filehandle,int *numbertype,int *rank,int
+ *dims,int maxdims);</code><p>
+ <DL>
+ <DT><i>filehandle</i>
+ <DD>A filehandle open for reading or appending.
+ <DT><i>numbertype</i>:
+ <DD>The type of the data being stored
+ <i>(<a href="DataTypes.html">datatype definition</a>)</i>.
+ It can be one of
+ <UL>
+ <LI><b>FLOAT32</b><br><i>32-bit single-precision IEEE float</i>
+ <LI><b>FLOAT64</b><br><i>64-bit double-precision IEEE float</i>
+ <LI><b>INT8</b><br><i>byte</i>
+ <LI><b>INT16</b><br><i>16-bit short integer</i>
+ <LI><b>INT32</b><br><i>32-bit standard integer</i>
+ <LI><b>INT64</b><br><i>64-bit long integer. (note: this is not
+ availible on the Intel/Windows platform)</i>
+ <LI><b>UINT8</b><br><i>unsigned character</i>
+ <LI><b>UINT16</b><br><i>unsigned 16-bit short integer</i>
+ <LI><b>UINT32</b><br><i>unsigned 32-bit standard integer</i>
+ <LI><b>UINT64</b><br><i>unsigned 64-bit long integer. (note: this is not availible on the Intel/Windows platform)</i>
+ </UL>
+ <DT><i>rank</i>
+ <DD>Number of dimensions of the dataset
+ <DT><i>dimensions</i>:
+ <DD>An array of <i>rank</i> integers that give the dimensions
+ of the dataset
+ <DT><i>maxdims</i>:
+ <DD>The maximum size of the dimensions array you given it.
+ This prevents array overruns if the dataset has more
+ dimensions than you were anticipating. It can be any positive
+ integer.
+ </DL>
+ This retrieves information about the datatype, rank,
+ and dimensions of the dataset to be retrieved.
+ By default the maximum size of the dimensions array is 3,
+ but you can set it to be larger.<p>
+ <b>ANSI C Prototype</b><br>
+ <code>
+ int IOread(IOFile filehandle,void *data);
+ </code><p>
+ This actually reads the dataset into the preallocated array
+ <i>data</i>.<p>
+
+ Another useful utility function is IOsizeOf() which returns the
+ number of bytes in a give IO datatype in manner analogous to the
+ standard C sizeof() operator.
+
+ So for instance, to read a simple dataset, you would do
+ <pre>
+ int rank;
+ int numbertype;
+ int dims[3];
+ float *data; /* assumes float data */
+ IOFile infile = IEEEopen("dataset.raw","read");
+ IOreadInfo(infile,&numbertype,&rank,dims);
+ /* OK, we are assuming a 3D IO::Float32 array,
+ but you can be more sophisticated... */
+ data = (float*)malloc(IOnBytes(numbertype,rank,dims));
+ /* nBytes() is a convenience function... you could also use
+ data = (float*)malloc(dims[0] * dims[1] * dims[2] * IOsizeOf(numbertype)); */
+ IOread(infile,data); /* read in the data */
+ </pre><p>
+
+ Since multiple datasets can be stored in a file, you can
+ retrieve them in the order they were written <i>(there is a <a
+ href="#Seeking">seek()</a> function that allows random access as
+ well)</i>. The method <b>readInfo()</b> implies reading the next
+ dataset stored in the file. The method <b>nDatasets()</b> tells how
+ many datasets are in a file. So typically if you want to read all
+ datasets in a file in order, you would use code similar to;
+ <pre>
+ IOFile infile = IEEEopen("dataset.raw","r");
+ for(int i=0;i&lt IOnDatasets(infile);i++){
+ .....lots of code....
+ IOreadInfo(infile,&numbertype,&rank,dims); /* increments to next dataset */
+ .....more code....
+ }
+ </pre>
+
+ <hr>
+ <a name="Seeking"><h2>Random Access to Datasets
+ <i>(Seeking)</i></h2></a>
+ You can select specific datasets in a file using the seek()
+ method.<p>
+ <b>ANSI C Prototype</b>
+ <code>int IOseek(IOFile filehandle,int index)</code>
+ <DL>
+ <DT><i>filehandle</i>:
+ <DD>Handle to a file open for reading.
+ <DT><i>index</i>:
+ <DD>The index of the dataset you want to read from. This can
+ be any number from 0 to (number_of_datasets - 1).
+ </DL>
+
+ <hr>
+ <a name="WriteAttribs"><h2>Writing Attributes</h2></a>
+ Attributes allow you to attach extra information to each
+ dataset stored in the file. Each attribute has a name and an
+ array of data (of any of the standard IO datatypes) stored with
+ it. These attributes can be retrieved by name or by integer
+ index in the order in which they were stored. A typical
+ attribute would typically be parameters that describe the grid
+ or the data like, "origin" which would be the 3-vector of floats
+ which locates of the origin of a grid in 3-space. The method
+ used to write these attributes is <b>IOwriteAttribute()</b>.<p>
+ <b>ANSI C Prototype</b><br>
+ <code>
+ int IOwriteAttribute(IOFile filehandle,char *name,int numbertype,int
+ length,void *data)
+ </code><p>
+ <DL>
+ <DT><i>filehandle</i>
+ <DD>An open filehandle for the datafile.
+ <DT><i>name</i>:
+ <DD>Name of the attribute (like "origin" or "coordinates")
+ <DT><i>numbertype</i>:
+ <DD>The type of the data array associated with the attribute
+ <i>(<a href="DataTypes.html">datatype definition</a>)</i>
+ <DT><i>length</i>:
+ <DD>The number of elements in the data array.
+ <DT><i>data</i>:
+ <DD>The attribute data.
+ </DL><p>
+ So to write an attribute named <i>origin</i> along with a
+ 3-vector float for the coordinates of the origin, you would use;
+ <pre>
+ float origin[3]={5.1,0.3,0.5};
+ /* and assuming the file is already open for writing
+ the following attribute will be attached to the last
+ written dataset. (you must have write data before adding
+ attribs) */
+ IOwriteAttribute(writer,"origin",FLOAT32,3,origin);
+ </pre>
+
+ <hr>
+ <a name="ReadAttribs"><h2>Reading Attributes</h2></a>
+ The attributes can be retrieved in the order they were written
+ or they can be retrieved by their name. To retrieve the
+ attributes in order, you would utilize the <b>IOnAttributes()</b>
+ method to determine how many attributes are attached,
+ <b>IOreadIndexedAttributeInfo()</b> to get the size and type of the
+ attribute based on its index (<i>use IOreadAttributeInfo() to get size
+ and type for the attribute based on its name</i>),
+ and <b>IOreadAttribute()</b> to read the attribute
+ data.<p>
+ <b>ANSI C Prototype</b><br>
+ <code>int IOnAttributes()</code><p>
+ <DL>
+ <DT><i>filehandle</i>
+ <DD>An open filehandle for the datafile.
+ <DT><i>returnvalue</i>:
+ <DD>Number of attributes in the file
+ </DL><p>
+ <b>ANSI C Prototype</b><br>
+ <code>int IOreadIndexedAttributeInfo(IOFile filehandle,int index,char *name,int *numbertype,int *length,int maxnamelength);
+ </code>
+ <DL>
+ <DT><i>filehandle</i>
+ <DD>An open filehandle for the datafile.
+ <DT><i>index</i>:
+ <DD>The index of the attribute which can be 0 to (nattributes-1)
+ <DT><i>name</i>:
+ <DD>A buffer in which the name of the attribute will be placed.
+ <DT><i>numbertype</i>:
+ <DD>The type of the attribute data
+ <i>(<a href="DataTypes.html">datatype definition</a>)</i>
+ <DT><i>length</i>:
+ <DD>The number of elements in the attribute data.
+ <DT><i>maxnamelength</i>:<DD>The maximum size of a name that can be
+ stored in the <b>name</b> buffer. It can be any positive integer.
+ </DL>
+ <p>
+ <b>ANSI C Prototype</b><br>
+ <code>int IOreadAttribute(IOFile filehandle,int index,void
+ *data);</code>
+ <DL>
+ <DT><i>filehandle</i>
+ <DD>An open filehandle for the datafile.
+ <DT><i>index</i>:
+ <DD>The index of the attribute data to read
+ <DT><i>data</i>:
+ <DD>The array into which the attribute data is copied.
+ </DL>
+ So for example, to read the attributes in order, you can use
+ <pre>
+ for(int i=0;i&ltIOnAttributes(infile);i++){
+ char name[128];
+ int length,datatype;
+ ...
+ IOreadIndexedAttributeInfo(infile,i,name,&datatype,&length,128);
+ ... allocate some data for storage
+ IOreadAttribute(infile,i,data);
+ }
+ </pre><p>
+
+ The attributes can also be retrieve by name. In fact, the is
+ the most likely way you will use the attributes interface. The
+ <b>IOreadAttributeInfo()</b> method is overloaded to allow retrieval by
+ name as
+ well. It returns the index of the attribute if one is found with a
+ matching name: it returns -1 if one is not found.
+ <p><b>ANSI C Prototype</b><br>
+ <code>
+ int IOreadAttributeInfo(char *name,int *numbertype,int *length);
+ </code>
+ <DL>
+ <DT><i>filehandle</i>
+ <DD>An open filehandle for the datafile.
+ <DT><i>returnvalue</i>:
+ <DD>The index of the attribute if found or -1 if no attribute with
+ matching name is found.
+ <DT><i>name</i>:
+ <DD>The name of the attribute to find.
+ <DT><i>numbertype</i>:
+ <DD>Returns the numbertype of the stored attribute data
+ <i>(<a href="DataTypes.html">datatype definition</a>)</i>
+ <DT><i>length</i>:
+ <DD>he length of the stored attribute data.
+ </DL>
+ So a typical use of this interface would be to find an attribute
+ named "origin" and retrieve its data if it exists.
+ <pre>
+ int index = IOreadAttributeInfo(infile,"origin",&datatype,&length);
+ if(index>=0) /* the attribute exists */
+ IOreadAttribute(infile,index,data);
+ else
+ puts("The attribute origin could not be found");
+ </pre>
+
+ </pre>
+
+ <hr>
+ <a name="WriteAnn"><h2>Writing Annotations</h2></a>
+ An annotation is a text string which can be used to
+ describe a dataset. To write an annotation, you use the
+ writeAnnotation() method.<p>
+ <b>ANSI C Prototype</b><br>
+ <code>
+ int IOwriteAnnotation(IOFile filehandle,char *annotationtext)
+ </code>
+ <DL>
+ <DT><i>filehandle</i>
+ <DD>An open filehandle for the datafile.
+ <DT><i>annotationtext</i>:
+ <DD>A null terminated string of the annotation text
+ </DL>
+ The annotation will be attached to the last written dataset.
+ You can store more than one annotation per dataset and the
+ annotations can be of arbitrary length.<p>
+
+ <hr>
+ <a name="ReadAnn"><h2>Reading Annotations</h2></a>
+ The annotations are stored in the order they are written. The
+ method <b>nAnnotations()</b> is used to find out how many
+ attributes are attached to a dataset. The method
+ <b>readAnnotationInfo()</b> is used to find the length of the
+ annotation and <b>readAnnotatin()</b> reads the actual
+ annotation text.<p>
+ <b>ANSI C Prototype</b><br>
+ <code>
+ int IOnAnnotations(IOFile filehandle);
+ </code>
+ <DL>
+ <DT><i>filehandle</i>
+ <DD>An open filehandle for the datafile.
+ <DT><i>returnvalue</i>:
+ <DD>Number of annotations attached to current dataset.
+ </DL><p>
+ <b>ANSI C Prototype</b><br><code>
+ IOreadAnnotationInfo(IOFile filehandle,int index,int *length)
+ </code>
+ <DL>
+ <DT><i>filehandle</i>
+ <DD>An open filehandle for the datafile.
+ <DT><i>index</i>:
+ <DD>Index of the annotations which can be 0 to (nannotations-1)
+ <DT><i>length</i>:
+ <DD>Length in characters of the annotation. This includes the
+ null-terminating character.
+ </DL>
+ <hr>
+ <a name="ReadWriteChunk"><h2>Writing and Reading in Chunks</h2></a>
+ For distributed-memory programming paradigms like HPF, MPI, or
+ PVM, it is often not unfeasible to write data to disk in a
+ single operation. For this reason, a <i>chunking</i> interface
+ is provided which allows you to write data in blocks to the
+ disk.<p>
+ To begin a chunk writing operation, you must first reserve a
+ data chunk in the file. This is accomplished using <b>IOreserveChunk()</b>
+ <b>ANSI C Prototype</b><br>
+ <code>
+ int IOreserveChunk(IOFile filehandle,int datatype,int rank,int *dims);
+ </code><p>
+ Once space has been allocated in the datafile, you can write
+ blocks of data specified by their dimensions and origin using
+ <b>IOwriteChunk()</b>
+ <b>ANSI C Prototype</b><br>
+ <code>
+ int IOwriteChunk(IOFile filehandle,int *dims,int *origin,void *data);
+ </code><p>
+ Likewise, it is possible to read chunks from the disk as
+ well. No special procedure is required to select a record to
+ read in chunks. Simply use <a href="#Reading">IOreadInfo()</a>
+ to get the dimensions and
+ type of the dataset and then use <b>IOreadChunk()</b> in place
+ of <b>IOread()</b> in order to read-in the data.
+ <b>ANSI C Prototype</b><br>
+ <code>
+ int IOreadChunk(IOFile filehandle,int *dims,int *origin,void *data);
+ </code><p>
+ <hr>
+ <address><a href="mailto:jshalf@suttung.aei-potsdam.mpg.de">John
+ Shalf</a></address>
+ <!-- Created: Mon Apr 7 12:52:52 MDT 1997 -->
+ <!-- hhmts start -->
+Last modified: Thu Feb 4 21:58:57 CST 1999
+<!-- hhmts end -->
+ </body>
+</html>