casa
$Rev:20696$
|
00001 //# HDF5Record.h: A class to write/read a record into HDF5 00002 //# Copyright (C) 2008 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: HDF5Record.h 20615 2009-06-09 02:16:01Z Malte.Marquarding $ 00027 00028 #ifndef CASA_HDF5RECORD_H 00029 #define CASA_HDF5RECORD_H 00030 00031 //# Includes 00032 #include <casa/HDF5/HDF5Object.h> 00033 #include <casa/HDF5/HDF5DataType.h> 00034 #include <casa/Containers/Record.h> 00035 00036 namespace casa { //# NAMESPACE CASA - BEGIN 00037 00038 // <summary> 00039 // A class to write/read a record into HDF5. 00040 // </summary> 00041 00042 // <use visibility=export> 00043 00044 // <reviewed reviewer="" date="" tests="tHDF5Record.cc"> 00045 // </reviewed> 00046 00047 // <prerequisite> 00048 // <li> <a href="http://hdf.ncsa.uiuc.edu">HDF5 system</a> 00049 // <li> <linkto class=Record>class Record</linkto> 00050 // </prerequisite> 00051 00052 // <synopsis> 00053 // This class has a static function to write a Record (or TableRecord) 00054 // into an HDF5 file by storing it as attributes for the given group. 00055 // Another static function can read back the Record. 00056 // It can handle all types of fields in a record. 00057 // <br> 00058 // A few remarks: 00059 // <ul> 00060 // <li> When writing the record, it first deletes all attributes of the group 00061 // to be sure that the group's attributes only contain the record. 00062 // <li> An AIPS++ Record is a recursive structure, so it is written as nested 00063 // groups. The name of a subgroup is the name of the subrecord. 00064 // <li> HDF5 cannot deal with empty arrays. Therefore they are written as 00065 // a special compound type holding the rank and type of the empty array. 00066 // <li> HDF5 cannot hold empty fixed length strings. This is solved by 00067 // storing an empty string with the special value <tt>__empty__</tt>. 00068 // </ul> 00069 // </synopsis> 00070 00071 // <motivation> 00072 // Record is a very important class in AIPS++ images, so it has to be 00073 // possible to read and write them from/to HDF5. 00074 // </motivation> 00075 00076 class HDF5Record 00077 { 00078 public: 00079 // Read a record from the attributes of the given group. 00080 // Nested records are read back correctly. 00081 // An empty record is returned if the group does not exist. 00082 static Record readRecord (const HDF5Object& parentHid, 00083 const String& groupName); 00084 00085 // Write the record as attributes of a group of the given parent. 00086 // Nested records are written as nested groups. 00087 // The group is deleted first if it already exists. 00088 static void writeRecord (const HDF5Object& parentHid, 00089 const String& recordName, 00090 const RecordInterface& rec); 00091 00092 // Remove the record (i.e. group) from the given parent. 00093 // Nothing is done if the record does not exist. 00094 static void remove (const HDF5Object& parentHid, 00095 const String& recordName); 00096 00097 // Read back a (nested) record. 00098 static Record doReadRecord (hid_t parentHid); 00099 00100 private: 00101 // Read a scalar value and add it to the record. 00102 static void readScalar (hid_t attrId, hid_t dtid, 00103 const String& name, RecordInterface& rec); 00104 00105 // Read an array value and add it to the record. 00106 static void readArray (hid_t attrId, hid_t dtid, const IPosition&, 00107 const String& name, RecordInterface& rec); 00108 00109 // Read a scalar string from an attribute and add it to the record. 00110 static void readScaString (hid_t attrId, Int sz, 00111 const String& name, RecordInterface& rec); 00112 00113 // Read a array of strings from an atrribute and add it to the record. 00114 static void readArrString (hid_t attrId, const IPosition&, 00115 const String& name, RecordInterface& rec); 00116 00117 // Read a field containing an empty array. 00118 static void readEmptyArray (hid_t attrId, 00119 const String& name, RecordInterface& rec); 00120 00121 // Read a field containing a scalar of fixed length. 00122 template<typename T> 00123 static void readSca (hid_t attrId, const String& name, 00124 RecordInterface& rec) 00125 { 00126 T value; 00127 HDF5DataType dtype((T*)0); 00128 read (attrId, &value, dtype); 00129 rec.define (name, value); 00130 } 00131 00132 // Read a field containing an array of fixed length elements. 00133 template<typename T> 00134 static void readArr (hid_t attrId, const IPosition& shape, 00135 const String& name, 00136 RecordInterface& rec) 00137 { 00138 Array<T> value(shape); 00139 HDF5DataType dtype((T*)0); 00140 read (attrId, value.data(), dtype); 00141 rec.define (name, value); 00142 } 00143 00144 // Read fixed length values from an attribute (scalar and array). 00145 static void read (hid_t attrId, void* value, 00146 const HDF5DataType& dtype); 00147 00148 // Write a (nested) record. 00149 static void doWriteRecord (const HDF5Object& groupHid, 00150 const RecordInterface& rec); 00151 00152 // Write a fixed length scalar value as attribute. 00153 static void writeScalar (hid_t parentHid, const String& name, 00154 const void* value, 00155 const HDF5DataType& dtype); 00156 00157 // Write an array of fixed length values as attribute. 00158 static void writeArray (hid_t parentHid, const String& name, 00159 const void* value, const IPosition& shape, 00160 const HDF5DataType& dtype); 00161 00162 // Write a scalar string as attribute. 00163 // HDF5 cannot handle empty strings, so for empty strings a special 00164 // value is written. 00165 static void writeScaString (hid_t parentHid, const String& name, 00166 const String& value); 00167 00168 // Write an array of strings as attribute. 00169 // HDF5 cannot handle empty strings, so for empty strings a special 00170 // value is written. 00171 static void writeArrString (hid_t parentHid, const String& name, 00172 const Array<String>& value); 00173 00174 // Write a field containing an empty array. 00175 static void writeEmptyArray (hid_t groupHid, const String& name, 00176 Int rank, DataType dtype); 00177 00178 // Write a field containing a fixed length scalar value. 00179 template<typename T> 00180 static void writeSca (hid_t parentHid, const String& name, 00181 const RecordInterface& rec, Int i) 00182 { 00183 T value; 00184 rec.get (i, value); 00185 HDF5DataType dtype((T*)0); 00186 writeScalar (parentHid, name, &value, dtype); 00187 } 00188 00189 // Write a field containing an array of fixed length elements. 00190 template<typename T> 00191 static void writeArr (hid_t parentHid, const String& name, 00192 const RecordInterface& rec, Int i) 00193 { 00194 Array<T> value; 00195 rec.get (i, value); 00196 HDF5DataType dtype((T*)0); 00197 writeArray (parentHid, name, value.data(), value.shape(), dtype); 00198 } 00199 00200 }; 00201 00202 } 00203 00204 #endif