casa
$Rev:20696$
|
00001 //# RecordRep.h: The representation of a Record 00002 //# Copyright (C) 1996,1997,2000,2001,2005 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 //# 00027 //# $Id: RecordRep.h 20969 2010-09-27 12:45:04Z gervandiepen $ 00028 00029 00030 #ifndef CASA_RECORDREP_H 00031 #define CASA_RECORDREP_H 00032 00033 //# Includes 00034 #include <casa/aips.h> 00035 #include <casa/Containers/Block.h> 00036 #include <casa/Containers/RecordDesc.h> 00037 #include <casa/Containers/RecordInterface.h> 00038 00039 namespace casa { //# NAMESPACE CASA - BEGIN 00040 00041 //# Forward Declarations 00042 class AipsIO; 00043 class IPosition; 00044 class String; 00045 00046 00047 // <summary> 00048 // The representation of a Record 00049 // </summary> 00050 00051 // <use visibility=local> 00052 // <reviewed reviewer="Mark Wieringa" date="1996/04/15" tests="tRecord"> 00053 // </reviewed> 00054 00055 // <prerequisite> 00056 // <li> <linkto class="Record">Record</linkto>. 00057 // </prerequisite> 00058 // 00059 // <etymology> 00060 // RecordRep is the REPresentation of a Record. 00061 // </etymology> 00062 // 00063 // <synopsis> 00064 // RecordRep is the actual implementation of a Record object. 00065 // It contains the description and the data. The data is stored as 00066 // a collection of void* pointers to the actual data. By storing 00067 // it in this indirect way, it is easier to extend the data block. 00068 // It also means that RecordFieldPtr objects always have the correct 00069 // pointer and do not need to be adjusted when the data block is extended. 00070 // <p> 00071 // Despite the fact that the data pointers have type void*, the 00072 // functions are completely type safe. This is done by passing the 00073 // type around using the DataType enumeration. The downpart is that 00074 // only types from that enumeration are supported (but that is also 00075 // required by the RecordDesc mechanics). 00076 // <p> 00077 // Note that RecordRep does not know anything about RecordFieldPtr 00078 // objects pointing to its data. Only its mother class Record 00079 // knows about them and handles all cases where the RecordFieldPtr's 00080 // have to be notified. 00081 // </synopsis> 00082 // 00083 // <example> 00084 // RecordRep mirrors all functions in Record. 00085 // </example> 00086 // 00087 // <motivation> 00088 // Having a separate RecordRep class makes copy-on-write possible. 00089 // It also allows derivation of other RecordRep classes (like TableRecordRep), 00090 // while their mother classes are not derived from each other. 00091 // </motivation> 00092 // 00093 // <todo asof="1996/03/12"> 00094 // <li> An implementation where arrays are stored as T*'s would cut down on 00095 // instantiations (the Arrayness would come back through the creation 00096 // of the <src>RecordFieldPtr<Array<T> ></src>). 00097 // </todo> 00098 00099 00100 class RecordRep 00101 { 00102 public: 00103 // Create a record with no fields. 00104 RecordRep(); 00105 00106 // Create a record with the given description. If it is not possible to 00107 // create all fields (for example, if a field of an unsupported type is 00108 // requested), an exception is thrown. 00109 // All fields are checked by the field checking function (if defined). 00110 RecordRep (const RecordDesc& description); 00111 00112 // Create a copy of other using copy semantics. 00113 RecordRep (const RecordRep& other); 00114 00115 // Copy all the data over. 00116 RecordRep& operator= (const RecordRep& other); 00117 00118 // Delete all data. 00119 virtual ~RecordRep(); 00120 00121 // Get the comment for this field. 00122 const String& comment (Int whichField) const; 00123 00124 // Set the comment for this field. 00125 void setComment (Int whichField, const String& comment); 00126 00127 // Describes the current structure of this Record. 00128 const RecordDesc& description() const; 00129 00130 // Change the structure of this Record to contain the fields in 00131 // newDescription. After calling restructure, <src>description() == 00132 // newDescription</src>. 00133 void restructure (const RecordDesc& newDescription, Bool recursive); 00134 00135 // Returns True if this and other have the same RecordDesc, other 00136 // than different names for the fields. That is, the number, type and the 00137 // order of the fields must be identical (recursively for fixed 00138 // structured sub-Records in this). 00139 // <note role=caution> 00140 // <src>thisRecord.conform(thatRecord) == True</src> does not imply 00141 // <br><src>thatRecord.conform(thisRecord) == True</src>, because 00142 // a variable record in one conforms a fixed record in that, but 00143 // not vice-versa. 00144 // </note> 00145 Bool conform (const RecordRep& other) const; 00146 00147 // Copy all data of the Record. 00148 void copyData (const RecordRep& other); 00149 00150 // Copy a data field. 00151 // This can only handle scalars and arrays. 00152 void copyDataField (DataType type, Int whichField, const void* that) const; 00153 00154 // Remove a field from the record. 00155 void removeField (Int whichField); 00156 00157 // Rename the given field. 00158 void renameField (const String& newName, Int whichField); 00159 00160 // Add a field with the given name and value to the record. 00161 // The data type of the field is determined by the data type of the value. 00162 // For arrays it is possible to define if the shape is fixed. 00163 // <group> 00164 void addDataField (const String& name, DataType type, 00165 const IPosition& shape, Bool fixedShape, 00166 const void* data); 00167 void addField (const String& name, const Record& value, 00168 RecordInterface::RecordType type); 00169 // </group> 00170 00171 // Define a value for the given field. 00172 // Array conformance rules will not be applied for variable shaped arrays. 00173 // When the field and value data type mismatch, type promotion 00174 // of scalars will be done if possible. If not possible, an exception 00175 // is thrown. 00176 void defineDataField (Int whichField, DataType type, const void* value); 00177 00178 // Put the description and data of the Record. 00179 // It also puts the fixedFlag attribute (of the mother object). 00180 void putRecord (AipsIO& os, int recordType) const; 00181 00182 // Get the description and data of the Record. 00183 // It also gets the fixedFlag attribute (of the mother object). 00184 void getRecord (AipsIO& os, Int& recordType); 00185 00186 // Put the data of a record. 00187 // This is used to write a subrecord, whose description has 00188 // already been written. 00189 void putData (AipsIO& os) const; 00190 00191 // Read the data of a record. 00192 // This is used to read a subrecord, whose description has 00193 // already been read. 00194 void getData (AipsIO& os, uInt version); 00195 00196 // Used by the RecordFieldPtr classes to attach in a type-safe way to the 00197 // correct field. 00198 // <group> 00199 void* get_pointer (Int whichField, DataType type) const; 00200 void* get_pointer (Int whichField, DataType type, 00201 const String& recordType) const; 00202 // </group> 00203 00204 // Merge a field from another record into this record. 00205 void mergeField (const RecordRep& other, Int whichFieldFromOther, 00206 RecordInterface::DuplicatesFlag); 00207 00208 // Merge all fields from the other record into this record. 00209 void merge (const RecordRep& other, RecordInterface::DuplicatesFlag); 00210 00211 // Print a record. 00212 // Print the contents of the record. 00213 // Only the first <src>maxNrValues</src> of an array will be printed. 00214 // A value < 0 means the entire array. 00215 void print (std::ostream&, 00216 Int maxNrValues = 25, 00217 const String& indent="") const; 00218 00219 protected: 00220 // Utility functions to avoid code duplication in the public member 00221 // functions. 00222 // <group> 00223 void delete_myself (uInt nfields); 00224 void copy_other (const RecordRep& other); 00225 // </group> 00226 00227 // Get the field number for a given name. 00228 virtual Int fieldNumber (const String& name) const; 00229 00230 // Add the data pointer to the data block. 00231 // The block is extended when needed. 00232 void addDataPtr (void* ptr); 00233 00234 // Remove a data pointer add the given index. 00235 void removeDataPtr (Int index); 00236 00237 // Check if the shape of the data array matches the shape of a 00238 // fixed-shaped array in the description. 00239 void checkShape (DataType type, const IPosition& shape, 00240 const void* value, const String& fieldName); 00241 00242 // Add a field to the description. 00243 virtual void addFieldToDesc (const String& name, DataType type, 00244 const IPosition& shape, Bool fixedShape); 00245 00246 // Remove a data field. 00247 virtual void removeData (Int whichField, void* ptr, void* vecptr); 00248 00249 // Remove a field from the description. 00250 virtual void removeFieldFromDesc (Int whichField); 00251 00252 // Create a data field for the given type and shape. 00253 // This can only handle scalars and arrays. 00254 void* createDataField (DataType type, const IPosition& shape); 00255 00256 // Delete a data field. 00257 // This can only handle scalars and arrays. 00258 void deleteDataField (DataType type, void* ptr, void* vecptr); 00259 00260 // Copy a data field. 00261 // This can only handle scalars and arrays. 00262 void copyDataField (DataType type, void* ptr, const void* that) const; 00263 00264 // Print a data field. 00265 // This can only handle scalars and arrays. 00266 void printDataField (std::ostream& os, DataType type, 00267 const String& indent, Int maxNrValues, 00268 const void* ptr) const; 00269 00270 // Put a data field. 00271 // This can only handle scalars and arrays. 00272 void putDataField (AipsIO& os, DataType type, const void* ptr) const; 00273 00274 // Get a data field. 00275 // This can only handle scalars and arrays. 00276 void getDataField (AipsIO& os, DataType type, void* ptr); 00277 00278 // Make an array for a scalar data field. 00279 // It shares the data, so a change in the data is reflected in the array. 00280 // It is used to be able to access a scalar as an 1D array. 00281 void makeDataVec (Int whichField, DataType type); 00282 00283 // Get a Scalar/ArrayKeywordSet object as a Record. 00284 // (type 0 = ScalarKeywordSet; type 1 = ArrayKeywordSet). 00285 void getKeySet (AipsIO& os, uInt version, uInt type); 00286 00287 // Get the description of a keyword set as a RecordDesc. 00288 void getKeyDesc (AipsIO& os, RecordDesc& desc); 00289 00290 // Get the scalar values of a keyword set. 00291 void getScalarKeys (AipsIO& os); 00292 00293 // Get the array values of a keyword set. 00294 void getArrayKeys (AipsIO& os); 00295 00296 00297 // Holds the structure of this Record. 00298 RecordDesc desc_p; 00299 // Pointers to data values. 00300 Block<void*> data_p; 00301 // Pointers to a vector of a scalar (to access a scalar as an array). 00302 Block<void*> datavec_p; 00303 // #Entries used in data_p. 00304 uInt nused_p; 00305 }; 00306 00307 00308 inline const RecordDesc& RecordRep::description() const 00309 { 00310 return desc_p; 00311 } 00312 00313 inline const String& RecordRep::comment (Int whichField) const 00314 { 00315 return desc_p.comment (whichField); 00316 } 00317 00318 inline void RecordRep::setComment (Int whichField, const String& comment) 00319 { 00320 desc_p.setComment (whichField, comment); 00321 } 00322 00323 inline void RecordRep::renameField (const String& newName, Int whichField) 00324 { 00325 desc_p.renameField (newName, whichField); 00326 } 00327 00328 00329 00330 } //# NAMESPACE CASA - END 00331 00332 #endif