casa  $Rev:20696$
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Defines
StArrayFile.h
Go to the documentation of this file.
00001 //# StArrayFile.h: Read/write array in external format for a storage manager
00002 //# Copyright (C) 1994,1995,1996,1997,1999,2001,2002
00003 //# Associated Universities, Inc. Washington DC, USA.
00004 //#
00005 //# This library is free software; you can redistribute it and/or modify it
00006 //# under the terms of the GNU Library General Public License as published by
00007 //# the Free Software Foundation; either version 2 of the License, or (at your
00008 //# option) any later version.
00009 //#
00010 //# This library is distributed in the hope that it will be useful, but WITHOUT
00011 //# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
00012 //# FITNESS FOR A PARTICULAR PURPOSE.  See the GNU Library General Public
00013 //# License for more details.
00014 //#
00015 //# You should have received a copy of the GNU Library General Public License
00016 //# along with this library; if not, write to the Free Software Foundation,
00017 //# Inc., 675 Massachusetts Ave, Cambridge, MA 02139, USA.
00018 //#
00019 //# Correspondence concerning AIPS++ should be addressed as follows:
00020 //#        Internet email: aips2-request@nrao.edu.
00021 //#        Postal address: AIPS++ Project Office
00022 //#                        National Radio Astronomy Observatory
00023 //#                        520 Edgemont Road
00024 //#                        Charlottesville, VA 22903-2475 USA
00025 //#
00026 //# $Id: StArrayFile.h 20551 2009-03-25 00:11:33Z Malte.Marquarding $
00027 
00028 #ifndef TABLES_STARRAYFILE_H
00029 #define TABLES_STARRAYFILE_H
00030 
00031 //# Includes
00032 #include <casa/aips.h>
00033 #include <casa/IO/LargeRegularFileIO.h>
00034 #include <casa/IO/TypeIO.h>
00035 #include <casa/BasicSL/String.h>
00036 #include <casa/BasicSL/Complex.h>
00037 
00038 namespace casa { //# NAMESPACE CASA - BEGIN
00039 
00040 //# Forward Declarations
00041 class IPosition;
00042 
00043 
00044 // <summary>
00045 // Read/write array in external format for a storage manager
00046 // </summary>
00047 
00048 // <use visibility=local>
00049 
00050 // <reviewed reviewer="UNKNOWN" date="before2004/08/25" tests="">
00051 // </reviewed>
00052 
00053 // <prerequisite>
00054 //# Classes you should understand before using this one.
00055 //   <li> ToLocal
00056 //   <li> FromLocal
00057 // </prerequisite>
00058 
00059 // <etymology>
00060 // StManArrayFile is a class used by table storage managers
00061 // to store indirect arrays in a file.
00062 // </etymology>
00063 
00064 // <synopsis> 
00065 // StManArrayFile is for use by the table storage manager, in particular
00066 // to read/write indirectly stored arrays.
00067 // Instead of holding the data in memory, they are written directly
00068 // into a file. It also allows to access a part of an array, which
00069 // is needed for the table system to access an array section.
00070 // It does not use a cache of its own, but it is relying on the
00071 // underlying system routines to cache and buffer adequately.
00072 //
00073 // This class could in principle also be used for other array purposes,
00074 // for example, to implement a paged array class for really huge arrays.
00075 //
00076 // An StManArrayFile object is connected to one file. It is possible
00077 // to hold multiple arrays in the file, each with its own shape.
00078 // An array is stored as its shape followed by the actual data
00079 // (all in canonical format). An array of strings is written as
00080 // an array of offsets pointing to the actual strings.
00081 // When a string gets a new value, the new value is written at the
00082 // end of the file and the file space with the old value is lost.
00083 //
00084 // Currently only the basic types are supported, but arbitrary types
00085 // could also be supported by writing/reading an element in the normal
00086 // way into the AipsIO buffer. It would only require that AipsIO
00087 // would contain a function to get its buffers and to restart them.
00088 // </synopsis> 
00089 
00090 // <example>
00091 // <srcblock>
00092 // void writeArray (const Array<Bool>& array)
00093 // {
00094 //     // Construct object and update file StArray.dat.
00095 //     StManArrayFile arrayFile("StArray.dat, ByteIO::New);
00096 //     // Reserve space for an array with the given shape and data type.
00097 //     // This writes the shape at the end of the file and reserves
00098 //     // space the hold the entire Bool array.
00099 //     // It fills in the file offset where the shape is stored
00100 //     // and returns the length of the shape in the file.
00101 //     Int64 offset;
00102 //     uInt shapeLength = arrayFile.putShape (array.shape(), offset, static_cast<Bool*>(0));
00103 //     // Now put the actual array.
00104 //     // This has to be put at the returned file offset plus the length
00105 //     // of the shape in the file.
00106 //     Bool deleteIt;
00107 //     const Bool* dataPtr = array.getStorage (deleteIt);
00108 //     arrayFile.put (offset+shapeLength, 0, array.nelements(), dataPtr);
00109 //     array.freeStorage (dataPtr, deleteIt);
00110 // }
00111 // </srcblock>
00112 // </example>
00113 
00114 // <motivation>
00115 // The AipsIO class was not suitable for indirect table arrays,
00116 // because it uses memory to hold the data. Furthermore it is
00117 // not possible to access part of the data in AipsIO.
00118 // </motivation>
00119 
00120 // <todo asof="$DATE:$">
00121 //   <li> implement long double
00122 //   <li> support arbitrary types
00123 //   <li> when rewriting a string value, use the current file
00124 //          space if it fits
00125 // </todo>
00126 
00127 
00128 class StManArrayFile
00129 {
00130 public:
00131 
00132     // Construct the object and attach it to the give file.
00133     // The OpenOption determines how the file is opened
00134     // (e.g. ByteIO::New for a new file).
00135     // The buffersize is used to allocate a buffer of a proper size
00136     // for the underlying filebuf object (see iostream package).
00137     StManArrayFile (const String& name, ByteIO::OpenOption,
00138                     uInt version=0, Bool bigEndian=True,
00139                     uInt bufferSize=65536);
00140 
00141     // Close the possibly opened file.
00142     ~StManArrayFile();
00143 
00144     // Flush and optionally fsync the data.
00145     // It returns True when any data was written since the last flush.
00146     Bool flush (Bool fsync);
00147 
00148     // Reopen the file for read/write access.
00149     void reopenRW();
00150 
00151     // Resync the file (i.e. clear possible cache information).
00152     void resync();
00153 
00154     // Return the current file length (merely a debug tool).
00155     Int64 length()
00156         { return leng_p; }
00157 
00158     // Put the array shape and store its file offset into the offset argument.
00159     // Reserve file space for the associated array.
00160     // The length of the shape part in the file is returned.
00161     // The file offset plus the shape length is the starting offset of the
00162     // actual array data (which can be used by get and put).
00163     // Space is reserved to store the reference count.
00164     // <group>
00165     uInt putShape (const IPosition& shape, Int64& fileOffset,
00166                    const Bool* dummy);
00167     uInt putShape (const IPosition& shape, Int64& fileOffset,
00168                    const Char* dummy);
00169     uInt putShape (const IPosition& shape, Int64& fileOffset,
00170                    const uChar* dummy);
00171     uInt putShape (const IPosition& shape, Int64& fileOffset,
00172                    const Short* dummy);
00173     uInt putShape (const IPosition& shape, Int64& fileOffset,
00174                    const uShort* dummy);
00175     uInt putShape (const IPosition& shape, Int64& fileOffset,
00176                    const Int* dummy);
00177     uInt putShape (const IPosition& shape, Int64& fileOffset,
00178                    const uInt* dummy);
00179     uInt putShape (const IPosition& shape, Int64& fileOffset,
00180                    const Int64* dummy);
00181     uInt putShape (const IPosition& shape, Int64& fileOffset,
00182                    const uInt64* dummy);
00183     uInt putShape (const IPosition& shape, Int64& fileOffset,
00184                    const Float* dummy);
00185     uInt putShape (const IPosition& shape, Int64& fileOffset,
00186                    const Double* dummy);
00187 //#//    uInt putShape (const IPosition& shape, Int64& fileOffset,
00188 //#//                   const long double* dummy);
00189     uInt putShape (const IPosition& shape, Int64& fileOffset,
00190                    const Complex* dummy);
00191     uInt putShape (const IPosition& shape, Int64& fileOffset,
00192                    const DComplex* dummy);
00193     uInt putShape (const IPosition& shape, Int64& fileOffset,
00194                    const String* dummy);
00195     // </group>
00196 
00197     // Get the reference count.
00198     uInt getRefCount (Int64 offset);
00199 
00200     // Put the reference count.
00201     // An exception is thrown if a value other than 1 is put for version 0.
00202     void putRefCount (uInt refCount, Int64 offset);
00203 
00204     // Put nr elements at the given file offset and array offset.
00205     // The file offset of the first array element is the file offset
00206     // of the shape plus the length of the shape in the file.
00207     // The array offset is counted in number of elements. It can be
00208     // used to put only a (contiguous) section of the array.
00209     // <group>
00210     void put (Int64 fileOffset, uInt arrayOffset, uInt nr, const Bool*);
00211     void put (Int64 fileOffset, uInt arrayOffset, uInt nr, const Char*);
00212     void put (Int64 fileOffset, uInt arrayOffset, uInt nr, const uChar*);
00213     void put (Int64 fileOffset, uInt arrayOffset, uInt nr, const Short*);
00214     void put (Int64 fileOffset, uInt arrayOffset, uInt nr, const uShort*);
00215     void put (Int64 fileOffset, uInt arrayOffset, uInt nr, const Int*);
00216     void put (Int64 fileOffset, uInt arrayOffset, uInt nr, const uInt*);
00217     void put (Int64 fileOffset, uInt arrayOffset, uInt nr, const Int64*);
00218     void put (Int64 fileOffset, uInt arrayOffset, uInt nr, const uInt64*);
00219     void put (Int64 fileOffset, uInt arrayOffset, uInt nr, const Float*);
00220     void put (Int64 fileOffset, uInt arrayOffset, uInt nr, const Double*);
00221 //#//    void put (Int64 fileOffset, uInt arrayOffset, uInt nr, const long double*);
00222     void put (Int64 fileOffset, uInt arrayOffset, uInt nr, const Complex*);
00223     void put (Int64 fileOffset, uInt arrayOffset, uInt nr, const DComplex*);
00224     void put (Int64 fileOffset, uInt arrayOffset, uInt nr, const String*);
00225     // </group>
00226 
00227     // Get the shape at the given file offset.
00228     // It will reshape the IPosition vector when needed.
00229     // It returns the length of the shape in the file.
00230     uInt getShape (Int64 fileOffset, IPosition& shape);
00231 
00232     // Get nr elements at the given file offset and array offset.
00233     // The file offset of the first array element is the file offset
00234     // of the shape plus the length of the shape in the file.
00235     // The array offset is counted in number of elements. It can be
00236     // used to get only a (contiguous) section of the array.
00237     // <group>
00238     void get (Int64 fileOffset, uInt arrayOffset, uInt nr, Bool*);
00239     void get (Int64 fileOffset, uInt arrayOffset, uInt nr, Char*);
00240     void get (Int64 fileOffset, uInt arrayOffset, uInt nr, uChar*);
00241     void get (Int64 fileOffset, uInt arrayOffset, uInt nr, Short*);
00242     void get (Int64 fileOffset, uInt arrayOffset, uInt nr, uShort*);
00243     void get (Int64 fileOffset, uInt arrayOffset, uInt nr, Int*);
00244     void get (Int64 fileOffset, uInt arrayOffset, uInt nr, uInt*);
00245     void get (Int64 fileOffset, uInt arrayOffset, uInt nr, Int64*);
00246     void get (Int64 fileOffset, uInt arrayOffset, uInt nr, uInt64*);
00247     void get (Int64 fileOffset, uInt arrayOffset, uInt nr, Float*);
00248     void get (Int64 fileOffset, uInt arrayOffset, uInt nr, Double*);
00249 //#//    void get (Int64 fileOffset, uInt arrayOffset, uInt nr, long double*);
00250     void get (Int64 fileOffset, uInt arrayOffset, uInt nr, Complex*);
00251     void get (Int64 fileOffset, uInt arrayOffset, uInt nr, DComplex*);
00252     void get (Int64 fileOffset, uInt arrayOffset, uInt nr, String*);
00253     // </group>
00254 
00255     // Copy the array with <src>nr</src> elements from one file offset
00256     // to another.
00257     // <group>
00258     void copyArrayBool     (Int64 to, Int64 from, uInt nr);
00259     void copyArrayChar     (Int64 to, Int64 from, uInt nr);
00260     void copyArrayuChar    (Int64 to, Int64 from, uInt nr);
00261     void copyArrayShort    (Int64 to, Int64 from, uInt nr);
00262     void copyArrayuShort   (Int64 to, Int64 from, uInt nr);
00263     void copyArrayInt      (Int64 to, Int64 from, uInt nr);
00264     void copyArrayuInt     (Int64 to, Int64 from, uInt nr);
00265     void copyArrayInt64    (Int64 to, Int64 from, uInt nr);
00266     void copyArrayuInt64   (Int64 to, Int64 from, uInt nr);
00267     void copyArrayFloat    (Int64 to, Int64 from, uInt nr);
00268     void copyArrayDouble   (Int64 to, Int64 from, uInt nr);
00269 //#//    void copyArrayLDouble  (Int64 to, Int64 from, uInt nr);
00270     void copyArrayComplex  (Int64 to, Int64 from, uInt nr);
00271     void copyArrayDComplex (Int64 to, Int64 from, uInt nr);
00272     void copyArrayString   (Int64 to, Int64 from, uInt nr);
00273     // </group>
00274 
00275 private:
00276     LargeRegularFileIO* file_p;            //# File object
00277     TypeIO*         iofil_p;               //# IO object
00278     Int64           leng_p;                //# File length
00279     uInt            version_p;             //# Version of StArrayFile file
00280     Bool            swput_p;               //# True = put is possible
00281     Bool            hasPut_p;              //# True = put since last flush
00282     uInt            sizeBool_p;
00283     uInt            sizeChar_p;
00284     uInt            sizeuChar_p;
00285     uInt            sizeShort_p;
00286     uInt            sizeuShort_p;
00287     uInt            sizeInt_p;
00288     uInt            sizeuInt_p;
00289     uInt            sizeInt64_p;
00290     uInt            sizeuInt64_p;
00291     uInt            sizeFloat_p;
00292     uInt            sizeDouble_p;
00293 
00294     // Put a single value at the current file offset.
00295     // It returns the length of the value in the file.
00296     // <group>
00297     uInt put (const Int&);
00298     uInt put (const uInt&);
00299     // </group>
00300 
00301     // Put the array shape at the end of the file and reserve
00302     // space for nr elements (each lenElem bytes long).
00303     // It fills the file offset of the shape.
00304     // It returns the length of the shape in the file.
00305     uInt putRes (const IPosition& shape, Int64& fileOffset, float lenElem);
00306 
00307     // Get a single value at the current file offset.
00308     // It returns the length of the value in the file.
00309     // <group>
00310     uInt get (Int&);
00311     uInt get (uInt&);
00312     // </group>
00313 
00314     // Copy data with the given length from one file offset to another.
00315     void copyData (Int64 to, Int64 from, uInt length);
00316 
00317     // Position the file on the given offset.
00318     void setpos (Int64 offset);
00319 };
00320     
00321 
00322 inline void StManArrayFile::reopenRW()
00323 {
00324     file_p->reopenRW();
00325 }
00326 inline uInt StManArrayFile::put (const Int& value)
00327 {
00328     hasPut_p = True;
00329     return iofil_p->write (1, &value);
00330 }
00331 inline uInt StManArrayFile::put (const uInt& value)
00332 {
00333     hasPut_p = True;
00334     return iofil_p->write (1, &value);
00335 }
00336 inline uInt StManArrayFile::get (Int& value)
00337 {
00338     return iofil_p->read (1, &value);
00339 }
00340 inline uInt StManArrayFile::get (uInt& value)
00341 {
00342     return iofil_p->read (1, &value);
00343 }
00344 
00345 
00346 
00347 } //# NAMESPACE CASA - END
00348 
00349 #endif