casacore
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Groups Pages
AipsIO.h
Go to the documentation of this file.
1 //# AipsIO.h: AipsIO is the object persistency mechanism of Casacore
2 //# Copyright (C) 1993,1994,1995,1996,1998,2000,2001
3 //# Associated Universities, Inc. Washington DC, USA.
4 //#
5 //# This library is free software; you can redistribute it and/or modify it
6 //# under the terms of the GNU Library General Public License as published by
7 //# the Free Software Foundation; either version 2 of the License, or (at your
8 //# option) any later version.
9 //#
10 //# This library is distributed in the hope that it will be useful, but WITHOUT
11 //# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
12 //# FITNESS FOR A PARTICULAR PURPOSE. See the GNU Library General Public
13 //# License for more details.
14 //#
15 //# You should have received a copy of the GNU Library General Public License
16 //# along with this library; if not, write to the Free Software Foundation,
17 //# Inc., 675 Massachusetts Ave, Cambridge, MA 02139, USA.
18 //#
19 //# Correspondence concerning AIPS++ should be addressed as follows:
20 //# Internet email: aips2-request@nrao.edu.
21 //# Postal address: AIPS++ Project Office
22 //# National Radio Astronomy Observatory
23 //# 520 Edgemont Road
24 //# Charlottesville, VA 22903-2475 USA
25 //#
26 //# $Id$
27 
28 #ifndef CASA_AIPSIO_H
29 #define CASA_AIPSIO_H
30 
31 
32 //# Includes
33 #include <casacore/casa/aips.h>
38 #include <casacore/casa/vector.h>
39 
40 namespace casacore { //# NAMESPACE CASACORE - BEGIN
41 
42 //# Forward Declarations
43 class TypeIO;
44 class ByteIO;
45 class RegularFileIO;
46 class MultiFileBase;
47 
48 
49 // <summary>
50 // AipsIO is the object persistency mechanism of Casacore
51 // </summary>
52 
53 // <use visibility=export>
54 
55 // <reviewed reviewer="ghunt" date="95Feb21" tests="" demos="">
56 
57 // <etymology>
58 // AipsIO is simply the conventional shorthand for "AIPS++ input/output".
59 // Note that Casacore is the successor of the old AIPS++ project.
60 // </etymology>
61 
62 // <synopsis>
63 // AipsIO is a class designed to do I/O for objects.
64 // It reads/writes the data using a class derived from
65 // <linkto class=TypeIO>TypeIO</linkto>. For instance, class
66 // <linkto class=CanonicalIO>CanonicalIO</linkto> can be used
67 // to read/write the data in canonical format.
68 // <p>
69 // The TypeIO class in its turn uses a class derived from
70 // <linkto class=ByteIO>ByteIO</linkto> to determine where the data
71 // has to be written.
72 // <p>
73 // An object is written by writing all its data members. It will be
74 // preceeded by a header containing type and version.
75 // The I/O can be done via de overloaded << and >> operators to write or
76 // read a single item (e.g., an int or an object). These operators are
77 // already defined for all built-in data types and for Complex, DComplex,
78 // String, and Bool.
79 // Since each enumeration is a specific type, it is hard to handle them.
80 // Casting to Bool (which is also an enumerated type) is a possibility,
81 // but that assumes that each enumerated type has the same size (which
82 // is probably true for all compilers).
83 // Another possibility is to store it in an int when writing. Reading
84 // can be done the opposite way, although the ARM says that an int
85 // cannot be assigned to an enumerated type.
86 // <p>
87 // There are also functions put, get and getnew to write or read an
88 // array of values. These functions are defined for the same data types
89 // as << and >> (so one can write, for example, an array of Strings).
90 // AipsIO.put (nr, arr) writes nr values from the given array.
91 // AipsIO.get (nr, arr) reads nr values into the given user-supplied array.
92 // AipsIO.getnew (&nr, &arr) reads the number of values written into
93 // a new array allocated on the heap. It returns the nr of values read
94 // and a pointer to the array.
95 // The data must be read back in the same order as it was written.
96 // <p>
97 // The functions <src>putstart(type,version)</src>
98 // and <src>putend()</src> must be called
99 // before resp. after writing all values of the object.
100 // It stores the given type and version of the object.
101 // Similarly <src>getstart(type)</src> and <src>getend()</src> must be called.
102 // getstart checks the type and returns the version. By using the version
103 // the read function of the object can convert older versions of the
104 // object (which may still reside on disk) to the latest version.
105 // The function getNextType is available to get the type of the next
106 // object stored. This can be used to check the type or to open (i.e.
107 // issue a getstart) in the correct way.
108 // <p>
109 // When implementing a class, one should also define the operators << and >>
110 // for the class to allow users to write or read an object in this
111 // simple way (e.g., as io >> obj; to read an object).
112 // One has to define the friend functions:
113 // <srcblock>
114 // friend AipsIO& operator<< (AipsIO&, const YourClass&);
115 // friend AipsIO& operator>> (AipsIO&, YourClass&);
116 // </srcblock>
117 // since they cannot be stored in the class itself.
118 // The type of an object is usually passed as the class name.
119 // <srcblock>
120 // AipsIO& operator<< (AipsIO& ios, const YourClass& object) {
121 // ios.putstart ("YourClass", version);
122 // ios << ....;
123 // ios.putend ();
124 // }
125 // </srcblock>
126 //
127 // The functions getpos() and setpos(offset) can be used to get and set
128 // the offset in the file to a given point. They can be used to point
129 // to a position in the file where an object must be written or read.
130 // Obviously these functions are to be used by a storage manager and
131 // are not for public use. Someday they should be made private with
132 // a friend defined.
133 // </synopsis>
134 
135 // <example>
136 // <srcblock>
137 // MyClass myObject(...); // some object
138 // AipsIO ios("file.name", ByteIO::New); // create new file
139 // ios << myObject; // write object
140 // MyClass myObject2;
141 // ios >> myObject2; // read it back
142 // </srcblock>
143 // This example creates an object, writes it to AipsIO and reads it
144 // back into another object.
145 // The shift functions for MyClass could be defined as follows:
146 // <srcblock>
147 // AipsIO& operator<< (AipsIO& ios, const MyClass& myObject)
148 // {
149 // ios.putstart ("MyClass", 1); // MyClass version 1
150 // ios << ...; // write all data members
151 // ios.putend();
152 // }
153 // AipsIO& operator>> (AipsIO& ios, const MyClass& myObject)
154 // {
155 // // If needed, delete current data members first.
156 // // Now read in the object.
157 // uInt version = ios.getstart ("MyClass");
158 // ios >> ...; // read all data members
159 // ios.getend();
160 // }
161 // </srcblock>
162 // In this example the version is not used. In more complex objects
163 // it will probably be used when data members get added or changed
164 // in future versions of a software system.
165 // </example>
166 
167 
168 class AipsIO
169 {
170 public:
171  // No file attached yet
172  AipsIO();
173 
174  // Construct and open/create a file with the given name.
175  // The actual IO is done via a CanonicalIO object on a regular file
176  // using buffered IO with a buffer of the given size.
177  // <br>If the MultiFileBase pointer is not null, a virtual file in the
178  // MultiFileBase will be used instead of a regular file.
179  explicit AipsIO (const String& fileName,
181  uInt filebufSize=65536,
183  MultiFileBase* mfile=0);
184 
185  // Construct from a stream object derived from ByteIO.
186  // This can for instance by used to use AipsIO on a file descriptor
187  // for which a <linkto class=FilebufIO>FilebufIO</linkto>
188  // object has been created.
189  // The actual IO is done via a CanonicalIO object on top of it.
190  explicit AipsIO (ByteIO*);
191 
192  // Construct from a stream object derived from TypeIO, thus from
193  // a stream on top of ByteIOn doing the possible conversions.
194  explicit AipsIO (TypeIO*);
195 
196  // Close if not done yet
197  ~AipsIO();
198 
199  // Open/create file (either a regular file or a MultiFileBase virtual file).
200  // An exception is thrown if the object contains an already open file.
201  void open (const String& fileName, ByteIO::OpenOption = ByteIO::Old,
202  uInt filebufSize=65536, MultiFileBase* mfile=0);
203 
204  // Open by connecting to the given byte stream.
205  // This can for instance by used to use AipsIO on a file descriptor
206  // for which a <linkto class=FilebufIO>FilebufIO</linkto>
207  // object has been created.
208  // The actual IO is done via a CanonicalIO object on top of it.
209  // An exception is thrown if the object contains an already open file.
210  void open (ByteIO*);
211 
212  // Open by connecting to the given typed byte stream.
213  // An exception is thrown if the object contains an already open file.
214  void open (TypeIO*);
215 
216  // Close file opened
217  void close();
218 
219  // Return the file option.
221 
222  // Start putting an object.
223  // This writes the object type and version. When reading back getstart
224  // calls have to be done in the same way. Getstart
225  // checks the type and returns the version. The user can use that to
226  // correctly read back objects with different versions.
227  // <br>
228  // Data in the outermost object cannot be put before a putstart is done.
229  // Data in nested objects can be put without an intermediate putstart.
230  // However, for complex objects it is recommended to do a putstart
231  // to have a better checking.
232  // <br>
233  // After all values (inclusing nested objects) of the object have
234  // been put, a call to putend has to be done.
235  // <group>
236  uInt putstart (const String& objectType, uInt objectVersion);
237  uInt putstart (const Char* objectType, uInt objectVersion);
238  // </group>
239 
240  // Put a single value.
241  // <group>
242  AipsIO& operator<< (const Bool& value);
243  AipsIO& operator<< (const Char& value);
244  AipsIO& operator<< (const uChar& value);
245  AipsIO& operator<< (const short& value);
246  AipsIO& operator<< (const unsigned short& value);
247  AipsIO& operator<< (const int& value);
248  AipsIO& operator<< (const unsigned int& value);
249  AipsIO& operator<< (const Int64& value);
250  AipsIO& operator<< (const uInt64& value);
251  AipsIO& operator<< (const float& value);
252  AipsIO& operator<< (const double& value);
253  AipsIO& operator<< (const Complex& value);
254  AipsIO& operator<< (const DComplex& value);
255  AipsIO& operator<< (const String& value);
256  AipsIO& operator<< (const Char* value);
257  // </group>
258 
259  // Put an array of values with the given number of values.
260  // If the flag putNr is set, the number of values is put first.
261  // <group>
262  AipsIO& put (uInt nrval, const Bool* values, Bool putNR = True);
263  AipsIO& put (uInt nrval, const Char* values, Bool putNR = True);
264  AipsIO& put (uInt nrval, const uChar* values, Bool putNR = True);
265  AipsIO& put (uInt nrval, const short* values, Bool putNR = True);
266  AipsIO& put (uInt nrval, const unsigned short* values, Bool putNR = True);
267  AipsIO& put (uInt nrval, const int* values, Bool putNR = True);
268  AipsIO& put (uInt nrval, const unsigned int* values, Bool putNR = True);
269  AipsIO& put (uInt nrval, const Int64* values, Bool putNR = True);
270  AipsIO& put (uInt nrval, const uInt64* values, Bool putNR = True);
271  AipsIO& put (uInt nrval, const float* values, Bool putNR = True);
272  AipsIO& put (uInt nrval, const double* values, Bool putNR = True);
273  AipsIO& put (uInt nrval, const Complex* values, Bool putNR = True);
274  AipsIO& put (uInt nrval, const DComplex* values, Bool putNR = True);
275  AipsIO& put (uInt nrval, const String* values, Bool putNR = True);
276  // </group>
277 
278  // Put a vector as an array of values
279  // For standard types it has the same result as put with putNR=True.
280  template<typename T>
281  AipsIO& put (const vector<T>& vec)
282  { *this << uInt(vec.size());
283  for (typename vector<T>::const_iterator iter=vec.begin();
284  iter!=vec.end(); ++iter) {
285  *this << *iter;
286  }
287  return *this;
288  }
289  //# Possibly specialize for standard types to make it faster.
290  //# Specialize for a bool vector.
291  AipsIO& put (const vector<Bool>& vec);
292 
293 
294  // End putting an object. It returns the object length (including
295  // possible nested objects).
296  uInt putend();
297 
298  // Get and set file-offset.
299  // <group>
300  Int64 getpos ();
301  Int64 setpos (Int64 offset);
302  // </group>
303 
304  // Get the type of the next object stored.
305  // This is not possible if a put is in progress.
306  const String& getNextType();
307 
308  // Start reading an object. It will check if the given type matches
309  // the one stored by putstart. It returns the object version which
310  // can be used to read in older version of the object correctly.
311  // <br>
312  // After all values (inclusing nested objects) of the object have
313  // been read, a call to getend has to be done.
314  // <group>
315  uInt getstart (const String& objectType);
316  uInt getstart (const Char* objectType);
317  // </group>
318 
319  // Get a single value.
320  // <group>
321  AipsIO& operator>> (Bool& value);
322  AipsIO& operator>> (Char& value);
323  AipsIO& operator>> (uChar& value);
324  AipsIO& operator>> (short& value);
325  AipsIO& operator>> (unsigned short& value);
326  AipsIO& operator>> (int& value);
327  AipsIO& operator>> (unsigned int& value);
328  AipsIO& operator>> (Int64& value);
329  AipsIO& operator>> (uInt64& value);
330  AipsIO& operator>> (float& value);
331  AipsIO& operator>> (double& value);
332  AipsIO& operator>> (Complex& value);
333  AipsIO& operator>> (DComplex& value);
334  AipsIO& operator>> (String& value);
335  // </group>
336 
337  // Read in nrval values into the user-supplied values buffer.
338  // The buffer must be long enough.
339  // <group>
340  AipsIO& get (uInt nrval, Bool* values);
341  AipsIO& get (uInt nrval, Char* values);
342  AipsIO& get (uInt nrval, uChar* values);
343  AipsIO& get (uInt nrval, short* values);
344  AipsIO& get (uInt nrval, unsigned short* values);
345  AipsIO& get (uInt nrval, int* values);
346  AipsIO& get (uInt nrval, unsigned int* values);
347  AipsIO& get (uInt nrval, Int64* values);
348  AipsIO& get (uInt nrval, uInt64* values);
349  AipsIO& get (uInt nrval, float* values);
350  AipsIO& get (uInt nrval, double* values);
351  AipsIO& get (uInt nrval, Complex* values);
352  AipsIO& get (uInt nrval, DComplex* values);
353  AipsIO& get (uInt nrval, String* values);
354  // </group>
355 
356  // Get a vector as an array of values (similar to getnew).
357  // It resizes the vector as needed.
358  template<typename T>
359  AipsIO& get (vector<T>& vec)
360  { uInt sz;
361  *this >> sz;
362  vec.resize(sz);
363  for (typename vector<T>::iterator iter=vec.begin();
364  iter!=vec.end(); ++iter) {
365  *this >> *iter;
366  }
367  return *this;
368  }
369  //# Specialize for a bool vector.
370  AipsIO& get (vector<Bool>& vec);
371 
372 
373  // Read in values as written by the function put.
374  // It will read the number of values (into nrval), allocate a
375  // values buffer of that length and read the values into that buffer.
376  // A pointer to the buffer is returned into values.
377  // <warn=caution> Although the buffer is allocated by this function,
378  // the user has to delete it (using <src>delete [] values;</src>).
379  // <group>
380  AipsIO& getnew (uInt& nrval, Bool*& values);
381  AipsIO& getnew (uInt& nrval, Char*& values);
382  AipsIO& getnew (uInt& nrval, uChar*& values);
383  AipsIO& getnew (uInt& nrval, short*& values);
384  AipsIO& getnew (uInt& nrval, unsigned short*& values);
385  AipsIO& getnew (uInt& nrval, int*& values);
386  AipsIO& getnew (uInt& nrval, unsigned int*& values);
387  AipsIO& getnew (uInt& nrval, Int64*& values);
388  AipsIO& getnew (uInt& nrval, uInt64*& values);
389  AipsIO& getnew (uInt& nrval, float*& values);
390  AipsIO& getnew (uInt& nrval, double*& values);
391  AipsIO& getnew (uInt& nrval, Complex*& values);
392  AipsIO& getnew (uInt& nrval, DComplex*& values);
393  AipsIO& getnew (uInt& nrval, String*& values);
394  // </group>
395 
396  // End reading an object. It returns the object length (including
397  // possible nested objects).
398  // It checks if the entire object has been read (to keep the data
399  // stream in sync). If not, an exception is thrown.
400  uInt getend();
401 
402 private:
403  // Initialize everything for the open.
404  // It checks if there is no outstanding open file.
406 
407  // Test if put is possible (throw exception if not).
408  void testput();
409 
410  // Test if get is possible (throw exception if not).
411  void testget();
412 
413  // Test if get did not exceed object.
414  void testgetLength();
415 
416  // Throw exception for testput
417  void testputerr();
418 
419  // Throw exception for testget
420  void testgeterr();
421 
422  // Throw exception for testgetLength
423  void testgeterrLength();
424 
425 
426  // 1 = file was opened by AipsIO
427  // 0 = file not opened
428  // -1 = file opened by user (=fd passed)
430  // File open option
432  // <0 = not opened for put
433  // 0 = no putstart done
434  // >0 = put is possible
435  int swput_p;
436  // <0 = not opened for get
437  // 0 = no getstart done
438  // >0 = get is possible
439  int swget_p;
440  // Nested object level
442  // Current size of objlen and objptr
444  // Object length at each level
446  // Object length to be read at each level
448  // Offset of length at each level
450  // True = the object type has already been read
452  // The cached object type.
454  // The file object.
456  // The actual IO object.
458  // Is the file is seekable?
460  // magic value to check sync.
461  static const uInt magicval_p;
462 };
463 
464 
465 
466 // Return the file option.
468 { return fopt_p; }
469 
470 
471 // testput tests if a put can be done; ie. if putstart has been done.
472 // It throws an exception if not.
473 // testget is similar to test if a get can be done.
474 inline void AipsIO::testput()
475 {
476  if (swput_p <= 0) {
477  testputerr();
478  }
479 }
480 inline void AipsIO::testget()
481 {
482  if (swget_p <= 0) {
483  testgeterr();
484  }
485 }
487 {
488  if (objlen_p[level_p] > objtln_p[level_p]) {
490  }
491 }
492 
493 
494 
495 } //# NAMESPACE CASACORE - END
496 
497 #endif
void testput()
Test if put is possible (throw exception if not).
Definition: AipsIO.h:474
uInt putstart(const String &objectType, uInt objectVersion)
Start putting an object.
long long Int64
Define the extra non-standard types used by Casacore (like proposed uSize, Size)
Definition: aipsxtype.h:38
int Int
Definition: aipstype.h:50
AipsIO & operator<<(const Bool &value)
Put a single value.
const String & getNextType()
Get the type of the next object stored.
AipsIO()
No file attached yet.
ByteIO * file_p
The file object.
Definition: AipsIO.h:455
Abstract base class to combine multiple files in a single one.
AipsIO is the object persistency mechanism of Casacore.
Definition: AipsIO.h:168
int swget_p
&lt;0 = not opened for get 0 = no getstart done &gt;0 = get is possible
Definition: AipsIO.h:439
uInt level_p
Nested object level.
Definition: AipsIO.h:441
unsigned long long uInt64
Definition: aipsxtype.h:39
unsigned char uChar
Definition: aipstype.h:47
static const uInt magicval_p
magic value to check sync.
Definition: AipsIO.h:461
void testputerr()
Throw exception for testput.
char Char
Definition: aipstype.h:46
Bool hasCachedType_p
True = the object type has already been read.
Definition: AipsIO.h:451
void testgeterrLength()
Throw exception for testgetLength.
Int64 getpos()
Get and set file-offset.
AipsIO & put(uInt nrval, const Bool *values, Bool putNR=True)
Put an array of values with the given number of values.
TypeIO * io_p
The actual IO object.
Definition: AipsIO.h:457
int swput_p
&lt;0 = not opened for put 0 = no putstart done &gt;0 = put is possible
Definition: AipsIO.h:435
void openInit(ByteIO::OpenOption)
Initialize everything for the open.
String objectType_p
The cached object type.
Definition: AipsIO.h:453
Int64 setpos(Int64 offset)
uInt maxlev_p
Current size of objlen and objptr.
Definition: AipsIO.h:443
uInt putend()
End putting an object.
Abstract base class for IO on a byte stream.
Definition: ByteIO.h:61
Abstract base class for IO of data in a type-dependent format.
Definition: TypeIO.h:79
uInt getstart(const String &objectType)
Start reading an object.
Block< Int64 > objptr_p
Offset of length at each level.
Definition: AipsIO.h:449
bool Bool
Define the standard types used by Casacore.
Definition: aipstype.h:42
Block< uInt > objlen_p
Object length at each level.
Definition: AipsIO.h:445
~AipsIO()
Close if not done yet.
void close()
Close file opened.
AipsIO & operator>>(Bool &value)
Get a single value.
void open(const String &fileName, ByteIO::OpenOption=ByteIO::Old, uInt filebufSize=65536, MultiFileBase *mfile=0)
Open/create file (either a regular file or a MultiFileBase virtual file).
void testgetLength()
Test if get did not exceed object.
Definition: AipsIO.h:486
OpenOption
Define the possible ByteIO open options.
Definition: ByteIO.h:65
uInt getend()
End reading an object.
ByteIO::OpenOption fopt_p
File open option.
Definition: AipsIO.h:431
Bool seekable_p
Is the file is seekable?
Definition: AipsIO.h:459
void testget()
Test if get is possible (throw exception if not).
Definition: AipsIO.h:480
String: the storage and methods of handling collections of characters.
Definition: String.h:225
Int opened_p
1 = file was opened by AipsIO 0 = file not opened -1 = file opened by user (=fd passed) ...
Definition: AipsIO.h:429
AipsIO & getnew(uInt &nrval, Bool *&values)
Read in values as written by the function put.
const Bool True
Definition: aipstype.h:43
Block< uInt > objtln_p
Object length to be read at each level.
Definition: AipsIO.h:447
ByteIO::OpenOption fileOption() const
Return the file option.
Definition: AipsIO.h:467
LatticeExprNode value(const LatticeExprNode &expr)
This function returns the value of the expression without a mask.
unsigned int uInt
Definition: aipstype.h:51
void testgeterr()
Throw exception for testget.
AipsIO & put(const vector< T > &vec)
Put a vector as an array of values For standard types it has the same result as put with putNR=True...
Definition: AipsIO.h:281