casa
$Rev:20696$
|
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