casa  5.7.0-16
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Groups Pages
VLATapeInput.h
Go to the documentation of this file.
1 //# VLATapeInput.h: This class reads VLA archive records from a Tape
2 //# Copyright (C) 1995,1999,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 NRAO_VLATAPEINPUT_H
29 #define NRAO_VLATAPEINPUT_H
30 
31 #include <casa/aips.h>
32 #include <casa/IO/TapeIO.h>
33 #include <casa/Containers/Block.h>
35 
36 #include <casa/namespace.h>
37 namespace casacore{
38 
39 class Path;
40 class ByteSource;
41 }
42 
43 namespace casa { //# NAMESPACE CASA - BEGIN
44 } //# NAMESPACE CASA - END
45 
46 
47 // <summary>This class reads VLA archive records from a Tape</summary>
48 
49 // <reviewed reviewer="" date="" tests="" demos="">
50 
51 // <prerequisite>
52 // <ol>
53 // <li> The IO Module
54 // </ol>
55 // </prerequisite>
56 //
57 // <etymology>
58 // This class is designed to reads VLA archive records from a Tape
59 // </etymology>
60 //
61 // <synopsis>
62 
63 // This class is designed to read VLA archive data. The data may be read from
64 // a disk, tape drive or any other data source supported by the IO module. A
65 // call to the operator++() function assembles the next reconstructed VLA
66 // archive data record from the input. A reference to this data can be
67 // obtained using the logicalRecord function.
68 //
69 // Refer to the "VLA Archive casacore::Data casacore::Format", VLA Computer Memorandum 186
70 // by G.C. Hunt, K.P. Sowinski, and T.J. Bottomly; June 1993.
71 // (This is also available as AIPS++ note 159)
72 //
73 // The VLA archive records are always a multiple of 2048 bytes. The
74 // record sizes were designed for use with magnetic tapes, so there is
75 // a maximum physical record size of 13*2048=26624 bytes.
76 //
77 // The low level class (blockio), that actually does the I/O, allows
78 // for a record (hereinafter chunk) size and for a input block size of
79 // a multiple of the chunk size. The low level read operation tests
80 // for the number of bytes actually read from the device.
81 //
82 // The helper classes VlaDiskInput, VlaTapeInput, and VlaStdInput are
83 // designed to deal with the low level input from the devices in an
84 // analogous fashion to the ones used for casacore::FITS input.
85 //
86 // Since a read may be issued for an arbitrary number of bytes from a
87 // disk, the chunk multiple is arbitrary and may be used to tune the
88 // speed of operation. There is an obvious trade-off between the
89 // block size created in the blockio class and the number of read
90 // operations.
91 //
92 // The story is quite different for tape input. A read request for at
93 // least the maximum physical record size must be made to avoid loss of
94 // data. Since a single tape record will be read with a single read
95 // operation, there is no point is having it any larger. The chunk
96 // multiple must be exactly 13 so that the block size is 26624.
97 //
98 // The reconstitution algorithm is as follows:
99 //
100 // 1. Read a 2048 chunk from the input.
101 //
102 // The first two 16-bit integers should contain the values 1 and n,
103 // where n is the number of "physical records" in the current "logical
104 // record." (If the first value is not 1, then the chunk is rejected
105 // and a new one read until the first 16-bit value is 1.) These two
106 // values are not part of the reconstituted "logical record."
107 //
108 // 2. The next 32-bit integer contains the length of the "logical
109 // record" in 16-bit words. The buffer is resized so that it can
110 // contain the whole reconstituted "logical record."
111 //
112 // 3. The remainder of the chunk is copied to the buffer.
113 //
114 // 4. Successive chunks are read from the input.
115 //
116 // The chunks are copied into the buffer until the "logical record"
117 // is complete. For "logical records" longer than 26620 byte, this is
118 // not the whole story. Each "physical record" contains maximum of 13
119 // chunks. When the first "physical record" of 13 chunks has been read,
120 // the next chunk will be the first of the next "physical record." The
121 // first two 16-bit integers will now be 2 and n, to indicate that this
122 // is the second "physical record" of the sequence. These 4 bytes are
123 // decoded and the rest of this chunk is copied to the buffer. And so
124 // on...
125 //
126 // An end-of-file condition on the input will cause record processing
127 // to be declared complete.
128 // </synopsis>
129 //
130 // <example>
131 // To open and read a VLA archive data file
132 // <code>
133 // VLAArchiveInput *in;
134 // casacore::Block <casacore::Char> *buff;
135 // casacore::String fileName = " ";
136 // casacore::String fileType = "tape";
137 //
138 // if (fileType == casacore::String("tape")) {
139 // in = new VLAArchiveInput(fileName.chars(), VLAArchiveInput::Tape);
140 // } else {
141 // in = new VLAArchiveInput(fileName.chars(), VLAArchiveInput::Disk);
142 // }
143 //
144 // casacore::uInt record = 0;
145 // for (buff=&(in->next()); in->atEnd()==false; buff=&(in->next()), record++) {
146 // cout << "casacore::Record" << record << endl;
147 // // process record pointed to by buff
148 // }
149 // </code>
150 //
151 // </example>
152 //
153 // <motivation>
154 // </motivation>
155 //
156 // <todo asof="">
157 // <ol>
158 // <li> Bulletproofing - check for realistic buffer size (<1e6)
159 // <li> Bulletproofing - check newn and newm on each read
160 // <li> What happens after a single end-of-file on a tape drive?
161 // <li> Add record skipping
162 // <li> Should it work with stdin? This is in place but not debugged.
163 // </ol>
164 // </todo>
165 
167 {
168 public:
169  // Create an object that reads its data from the specified file on the
170  // specified tape device. The whichFile argument indicates which tape to read
171  // from the tape with zero meaning "read the next file". The first file
172  // containing data (ie ignoring the tape header file) is file 1. An exception
173  // is thrown if there is any problem opening (readonly) the tape device or if
174  // the tape cannot be positioned to the start of the specified file.
175  VLATapeInput(const casacore::Path& device, casacore::uInt whichFile=0);
176 
177  // Create an object that reads its data from the specified files on the
178  // specified tape device. The tape is rewound and only the specified file is
179  // read. The first file containing data (ie ignoring the tape header file) is
180  // file 1 and zero means "read the next file". An exception is thrown if
181  // there is any problem opening (readonly) the tape device or if the tape
182  // cannot be positioned to the start of the first specified file. The file
183  // numbers should be in increasing order as only one pass through the tape is
184  // made.
185  VLATapeInput(const casacore::Path& device, const casacore::Block<casacore::uInt>& whichFiles);
186 
187  // The destructor closes the tape device.
188  ~VLATapeInput();
189 
190  // Reads the next logical record from specified tape. Returns false if
191  // there was a problem assembling the next record ie., it returns the value
192  // of the hasData() member function.
193  virtual casacore::Bool read();
194 
195 private:
196  //# This is the amount data that is read with every system call. It needs to
197  //# be at least as big as the biggest record on tape. However it can bigger
198  //# as this code will not complain if less data was read (although all data
199  //# read must be in multiples of the BlockSize)
200  static const casacore::uInt ReadSize;
201 
202  //# The default constructor is private and undefined
203  VLATapeInput();
204 
205  //# The copy constructor is private and undefined
206  VLATapeInput(const VLATapeInput& other);
207 
208  //# The assignment operator is private and undefined
209  VLATapeInput& operator=(const VLATapeInput& other);
210 
211  //# Reads through a VLA archive looking for the first physical record in a
212  //# logical record. Returns false if the first record could not be found. If
213  //# It was found then this function also returns the number of physical
214  //# records in this logical record.
216 
217  //# Positions the tape to the beginning of the next file. Uses and
218  //# manipulates the itsFiles and itsCurFile data members. Returns false if
219  //# the tape could not be positioned.
221 
222  //# Reads the next record from the tape. Skips over bad data but not
223  //# filemarks. Throws an exception if no valid records could be read.
225 
226  //# Read the specified number of bytes from the current ByteIO. Returns false
227  //# if no data was written, a read error was detected or the data read was
228  //# not a multiple of the BlockSize. Sets the appropriate Flags when
229  //# returning false. Writes the data into an internal buffer.
231 
232  //# This object that provides the data input. Usually a Tape, casacore::File, Socket
233  //# etc.
235 
236  //# This object indicates which files we are to read on the tape;
238 
239  //# An index into the itsFiles block indicating which file, in tape, we
240  //# are currently reading. A negative number indicates that the tape has not
241  //# been positioned yet.
243 
244  //# A temporary buffer that is used to store the data prior to copying it
245  //# into the casacore::MemoryIO object. This is necessary because the casacore::MemoryIO object
246  //# does not allow you low level access to its data.
248 };
249 #endif
This class reads VLA archive records from a Tape.
int Int
Definition: aipstype.h:50
casacore::Block< casacore::uChar > itsBuffer
Definition: VLATapeInput.h:247
casacore::TapeIO itsTape
Definition: VLATapeInput.h:234
Class for read-only access to data in a given format.
Definition: ByteSource.h:91
VLATapeInput & operator=(const VLATapeInput &other)
static const casacore::uInt ReadSize
Definition: VLATapeInput.h:200
casacore::Bool findFirstRecord(casacore::Short &m)
virtual casacore::Bool read()
Reads the next logical record from specified tape.
Path name of a file.
Definition: Path.h:126
short Short
Definition: aipstype.h:48
casacore::Int itsCurFile
Definition: VLATapeInput.h:242
This class reads VLA archive records from a Tape.
Definition: VLATapeInput.h:166
~VLATapeInput()
The destructor closes the tape device.
bool Bool
Define the standard types used by Casacore.
Definition: aipstype.h:42
casacore::Bool nextFile()
casacore::Bool fillBuffer(casacore::uInt &bytesToRead)
Class for IO on a tape device.
Definition: TapeIO.h:87
casacore::Block< casacore::uInt > itsFiles
Definition: VLATapeInput.h:237
casacore::Bool nextRecord()
unsigned int uInt
Definition: aipstype.h:51
#define casacore
&lt;X11/Intrinsic.h&gt; #defines true, false, casacore::Bool, and String.
Definition: X11Intrinsic.h:42