SheafSystem  0.0.0.0
sheaf_file.cc
1 
2 //
3 // Copyright (c) 2014 Limit Point Systems, Inc.
4 //
5 // Licensed under the Apache License, Version 2.0 (the "License");
6 // you may not use this file except in compliance with the License.
7 // You may obtain a copy of the License at
8 //
9 // http://www.apache.org/licenses/LICENSE-2.0
10 //
11 // Unless required by applicable law or agreed to in writing, software
12 // distributed under the License is distributed on an "AS IS" BASIS,
13 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14 // See the License for the specific language governing permissions and
15 // limitations under the License.
16 //
17 
18 // Implementation for class sheaf_file
19 
20 #include "SheafSystem/sheaf_file.h"
21 
22 #include "SheafSystem/assert_contract.h"
23 #include "SheafSystem/file_data_type_map.h"
24 #include "SheafSystem/error_message.h"
25 
26 namespace
27 {
28  //
29  // Value representing failure for HDF routine.
30  // Most HDF routines return "a negative value" for failure.
31  //
32  const int HDF_FAIL = -1;
33 }
34 
35 
36 // PUBLIC MEMBER FUNCTIONS
37 
38 // CANONICAL MEMBERS
39 
40 // Default constructor
44 {
45 
46  // Preconditions:
47 
48 
49  // Body:
50 
51  // _name empty by default
52 
53  _hdf_id = HDF_FAIL;
54  _mode = NONE;
55  _type_map = 0;
56 
57  // Postconditions:
58 
59  ensure(invariant());
60 
61  // Exit:
62 
63  return;
64 }
65 
66 
67 // Copy constructor
70 sheaf_file(const sheaf_file& xother)
71 {
72  // Preconditions:
73 
74  // Body:
75 
76  _name = xother._name;
77  _hdf_id = xother._hdf_id;
78  _mode = xother._mode;
79  _type_map = xother._type_map;
80 
81  // Postconditions:
82 
83  ensure(invariant());
84 }
85 
86 
87 
88 // Virtual constructor
92 clone() const
93 {
94  sheaf_file* result;
95 
96  // Preconditions:
97 
98  // Body:
99 
100  result = new sheaf_file();
101 
102  // Postconditions:
103 
104  ensure(result != 0);
105  ensure(is_same_type(result));
106 
107  // Exit:
108 
109  return result;
110 }
111 
112 
113 // Destructor
117 {
118 
119  // Preconditions:
120 
121  // Body:
122 
123 
124  // Postconditions:
125 
126  // Exit:
127 
128  return;
129 }
130 
131 
132 // Class invariant
134 bool
136 invariant() const
137 {
138  bool result = true;
139 
140  // Preconditions:
141 
142  // Body:
143 
144  // Must satisfy base class invariant
145 
146  result = result && any::invariant();
147 
148  if(invariant_check())
149  {
150  // Prevent recursive calls to invariant
151 
153 
154  // is_open implies type_map_defined
155 
156  result = result && (is_open() == type_map_defined());
157 
158  // Finished, turn invariant checking back on.
159 
161  }
162 
163  // Postconditions:
164 
165  // Exit
166 
167  return result;
168 }
169 
170 // Conformance test
172 bool
174 is_ancestor_of(const any* other) const
175 {
176 
177  // Preconditions:
178 
179  require(other != 0);
180 
181  // Body:
182 
183  // True if other conforms to this
184 
185  bool result = dynamic_cast<const sheaf_file*>(other) != 0;
186 
187  // Postconditions:
188 
189  return result;
190 
191 }
192 
193 
194 
195 // SHEAF_FILE INTERFACE
196 
197 
199 void
201 open(const std::string &xname, access_mode xmode, bool xclobber)
202 {
203  // Preconditions:
204 
205  require(!is_open());
206  require(!xname.empty());
207 
208  // Body:
209 
210  // Save the name
211 
212  _name = xname;
213 
214  switch(xmode)
215  {
216  case READ_ONLY:
217 
218  // Open the file with read-only access.
219 
220  _hdf_id = H5Fopen(_name.c_str(), H5F_ACC_RDONLY, H5P_DEFAULT);
221  if(_hdf_id >= 0)
222  {
223  // File creation succeeded.
224  // Store the mode.
225 
226  _mode = READ_ONLY;
227 
228  // Create the type map.
229  // Since the file already exists,
230  // do not create external types.
231 
232  _type_map = new file_data_type_map(_hdf_id, false);
233  }
234  else
235  {
236  // File creation failed.
237 
238  // H5Eprint(stderr);
239  H5Eprint1(stderr);
240  post_fatal_error_message("unable to open file in READ_ONLY mode");
241  }
242  break;
243 
244  case READ_WRITE:
245 
246  // Open the file with read-write access.
247 
248  if(xclobber)
249  {
250  // Delete ("truncate") the file if it already exists.
251 
252  _hdf_id = H5Fcreate(_name.c_str(), H5F_ACC_TRUNC, H5P_DEFAULT, H5P_DEFAULT);
253  if(_hdf_id >= 0)
254  {
255  // File creation succeeded.
256  // Store the mode.
257 
258  _mode = READ_WRITE;
259 
260  // Create the type map.
261  // Since the file is new,
262  // force creation of the external types.
263 
264  _type_map = new file_data_type_map(_hdf_id, true);
265  }
266  else
267  {
268  // File creation failed.
269 
270  H5Eprint1(stderr);
271  post_fatal_error_message("unable to open file in READ_WRITE mode");
272  }
273  }
274  else
275  {
276  post_fatal_error_message("no clobber not yet implemented");
277  }
278  break;
279 
280  default:
281 
282  // Unrecognized access mode.
283  // Should be unreachable.
284 
285  post_fatal_error_message("unrecognized access mode");
286  break;
287  }
288 
289  // Postconditions:
290 
291  ensure(invariant());
292  ensure(name() == xname);
293  ensure(mode() == xmode);
294  ensure(is_open());
295 
296  // Exit
297 
298  return;
299 }
300 
301 
302 
304 bool
306 is_open() const
307 {
308  bool result = false;
309 
310  // Preconditions:
311 
312  // Body:
313 
314  result = (_mode != NONE);
315 
316  // Postconditions:
317 
318  ensure(result == (mode() != NONE));
319 
320  // Exit
321 
322  return result;
323 }
324 
325 
326 
330 mode() const
331 {
332  access_mode result;
333 
334  // Preconditions:
335 
336  // Body:
337 
338  result = _mode;
339 
340  // Postconditions:
341 
342  // Exit
343 
344  return result;
345 }
346 
347 
349 void
352 {
353  // Preconditions:
354 
355  require(is_open());
356 
357  // Body:
358 
359  // Delete the type map that was created when we opened the file.
360  // Closes various HDF objects which must be closed for the file
361  // to be closed.
362 
363  delete _type_map;
364 
365  // Close the file.
366  // If any HDF objects that reference the file are still open,
367  // HDF will close access to the file but silently leave the file open.
368 
369  herr_t lstatus = H5Fclose(_hdf_id);
370 
371  if(lstatus < 0)
372  {
373  post_fatal_error_message("failed to close file");
374  }
375 
376  _mode = NONE;
377 
378  // Postconditions:
379 
380  ensure(!is_open());
381 
382  // Exit
383 
384  return;
385 }
386 
387 
388 
389 
394 {
395  // Preconditions:
396 
397  require(is_open());
398 
399  // Body:
400 
401  data_type_map& result = *_type_map;
402 
403  // Postconditions:
404 
405  // Exit
406 
407  return result;
408 }
409 
413 type_map() const
414 {
415  // Preconditions:
416 
417  require(is_open());
418 
419  // Body:
420 
421  data_type_map& result = *_type_map;
422 
423  // Postconditions:
424 
425  // Exit
426 
427  return result;
428 }
429 
430 
431 
432 
434 bool
437 {
438  bool result;
439 
440  // Preconditions:
441 
442  // Body:
443 
444  result = _type_map != 0;
445 
446  // Postconditions:
447 
448  // Exit
449 
450  return result;
451 }
452 
453 
454 
455 
456 
457 hid_t
458 sheaf::sheaf_file::
459 hdf_id() const
460 {
461  hid_t result;
462 
463  // Preconditions:
464 
465  require(is_open());
466 
467  // Body:
468 
469  result = _hdf_id;
470 
471  // Postconditions:
472 
473  // Exit
474 
475  return result;
476 }
virtual bool invariant() const
Class invariant.
Definition: sheaf_file.cc:136
virtual bool invariant() const
Class invariant, intended to be redefined in each descendant. See below for template for invariant in...
Definition: any.cc:153
An encapsulation of an HDF file containing sheaf data.
Definition: sheaf_file.h:49
A collection of data converters that map data types between internal and external representations ass...
virtual sheaf_file * clone() const
Virtual constructor; makes a new instance of the same type as this.
Definition: sheaf_file.cc:92
access_mode
File access modes.
Definition: sheaf_file.h:111
data_type_map & type_map()
Data type map for primitive types in this file (mutable version)
Definition: sheaf_file.cc:393
Abstract base class with useful features for all objects.
Definition: any.h:39
bool is_open() const
True if this file is open.
Definition: sheaf_file.cc:306
access_mode mode() const
The current access mode.
Definition: sheaf_file.cc:330
std::string name() const
The name of this file.
Definition: sheaf_file.h:103
void disable_invariant_check() const
Disable invariant check. Intended for preventing recursive calls to invariant and for suppressing inv...
Definition: any.h:97
void close()
Closes the file.
Definition: sheaf_file.cc:351
sheaf_file()
Default constructor.
Definition: sheaf_file.cc:43
bool type_map_defined() const
True if type map previously defined.
Definition: sheaf_file.cc:436
virtual ~sheaf_file()
Destructor.
Definition: sheaf_file.cc:116
bool invariant_check() const
True if invariant checking is enabled.
Definition: any.h:79
virtual bool is_ancestor_of(const any *other) const
Conformance test; true if other conforms to this.
Definition: sheaf_file.cc:174
void open(const std::string &xname, access_mode xmode=READ_WRITE, bool xclobber=true)
Opens a file with name xname, with access mode xmode. If xclobber and the file already exists...
Definition: sheaf_file.cc:201
A collection of data converters that map data types between internal and external representations...
Definition: data_type_map.h:49
bool is_same_type(const any *other) const
True if other is the same type as this.
Definition: any.cc:79
void enable_invariant_check() const
Enable invariant checking.
Definition: any.h:87