casacore
casa
IO
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>
34
#include <casacore/casa/Containers/Block.h>
35
#include <casacore/casa/BasicSL/String.h>
36
#include <casacore/casa/BasicSL/Complex.h>
37
#include <casacore/casa/IO/ByteIO.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,
180
ByteIO::OpenOption
=
ByteIO::Old
,
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.
220
ByteIO::OpenOption
fileOption
()
const
;
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,