casa  $Rev:20696$
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Defines
TableRecordRep.h
Go to the documentation of this file.
00001 //# TableRecordRep.h: The representation of a TableRecord
00002 //# Copyright (C) 1996,1997,2000,2001
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: TableRecordRep.h 20969 2010-09-27 12:45:04Z gervandiepen $
00028 
00029 
00030 #ifndef TABLES_TABLERECORDREP_H
00031 #define TABLES_TABLERECORDREP_H
00032 
00033 #include <casa/aips.h>
00034 #include <casa/Containers/RecordRep.h>
00035 
00036 namespace casa { //# NAMESPACE CASA - BEGIN
00037 
00038 //# Forward Declarations
00039 class TableRecord;
00040 class TableAttr;
00041 
00042 
00043 // <summary>
00044 // The representation of a TableRecord
00045 // </summary>
00046 
00047 // <use visibility=local>
00048 // <reviewed reviewer="Mark Wieringa" date="1996/04/15" tests="tTableRecord">
00049 // </reviewed>
00050 
00051 // <prerequisite>
00052 //   <li> <linkto class="TableRecord">TableRecord</linkto>.
00053 //   <li> <linkto class="RecordRep">RecordRep</linkto>.
00054 // </prerequisite>
00055 //
00056 // <etymology>
00057 // TableRecordRep is the REPresentation of a TableRecord.
00058 // </etymology>
00059 //
00060 // <synopsis>
00061 // TableRecordRep is the actual implementation of a TableRecord object.
00062 // It contains the description and the data. The data is stored as
00063 // a collection of void* pointers to the actual data. By storing
00064 // it in this indirect way, it is easier to extend the data block.
00065 // It also means that RecordFieldPtr objects always have the correct
00066 // pointer and do not need to be adjusted when the data block is extended.
00067 // <p>
00068 // Despite the fact that the data pointers have type void*, the
00069 // functions are completely type safe. This is done by passing the
00070 // type around using the DataType enumeration. The downpart is that
00071 // only types from that enumeration are supported (but that is also
00072 // required by the RecordDesc mechanics).
00073 // <p>
00074 // Note that TableRecordRep does not know anything about RecordFieldPtr
00075 // objects pointing to its data. Only its mother class TableRecord
00076 // knows about them and handles all cases where the RecordFieldPtr's
00077 // have to be notified.
00078 // <p>
00079 // Fields containing tables are not directly handled using class Table.
00080 // Instead the class <linkto class=TableKeyword>TableKeyword</linkto>
00081 // is used to map a table name to a table and to take care of
00082 // opening a table on demand.
00083 // </synopsis>
00084 //
00085 // <example>
00086 // TableRecordRep mirrors all functions in TableRecord.
00087 // </example>
00088 //
00089 // <motivation>
00090 // Having a separate TableRecordRep class makes copy-on-write possible.
00091 // It also allows derivation from RecordRep.
00092 // </motivation>
00093 //
00094 //# <todo asof="1995/08/22">
00095 //# </todo>
00096 
00097 
00098 class TableRecordRep : public RecordRep
00099 {
00100 public:
00101     // Create a record with no fields.
00102     TableRecordRep();
00103 
00104     // Create a record with the given description. If it is not possible to 
00105     // create all fields (for example, if a field of an unsupported type is
00106     // requested), an exception is thrown.
00107     // All fields are checked by the field checking function (if defined).
00108     TableRecordRep (const RecordDesc& description);
00109 
00110     // Create a copy of other using copy semantics.
00111     TableRecordRep (const TableRecordRep& other);
00112 
00113     // Copy all the data over.
00114     TableRecordRep& operator= (const TableRecordRep& other);
00115     
00116     // Delete all data.
00117     ~TableRecordRep();
00118 
00119     // Get the comment for this field.
00120     const String& comment (Int whichField) const;
00121 
00122     // Set the comment for this field.
00123     void setComment (Int whichField, const String& comment);
00124 
00125     // Describes the current structure of this Record.
00126     const RecordDesc& description() const;
00127 
00128     // Change the structure of this Record to contain the fields in
00129     // newDescription. After calling restructure, <src>description() ==
00130     // newDescription</src>.
00131     void restructure (const RecordDesc& newDescription, Bool recursive);
00132 
00133     // Returns True if this and other have the same RecordDesc, other
00134     // than different names for the fields. That is, the number, type and the
00135     // order of the fields must be identical (recursively for fixed
00136     // structured sub-Records in this).
00137     // <note role=caution>
00138     // <src>thisRecord.conform(thatRecord) == True</src> does not imply
00139     // <br><src>thatRecord.conform(thisRecord) == True</src>, because
00140     // a variable record in one conforms a fixed record in that, but
00141     // not vice-versa.
00142     // </note>
00143     Bool conform (const TableRecordRep& other) const;
00144 
00145     // Rename the given field.
00146     void renameField (const String& newName, Int whichField);
00147 
00148     // Copy all data of the TableRecord.
00149     void copyData (const TableRecordRep& other);
00150 
00151     // Add a field with the given name and value to the record.
00152     // The data type of the field is determined by the data type of the value.
00153     // <group>
00154     void addField (const String& name, const TableRecord& value,
00155                    RecordInterface::RecordType type);
00156     void addField (const String& name, const Table& value,
00157                    RecordInterface::RecordType type);
00158     // </group>
00159 
00160     // Define a value for the given field.
00161     // Array conformance rules will not be applied for variable shaped arrays.
00162     // When the field and value data type mismatch, type promotion
00163     // of scalars will be done if possible. If not possible, an exception
00164     // is thrown.
00165     void defineDataField (Int whichField, DataType type, const void* value);
00166 
00167     // Close the table in the given field.
00168     // When accessed again, it will be opened automatically.
00169     // This can be useful to save memory usage.
00170     void closeTable (Int whichField) const;
00171 
00172     // Close all open tables.
00173     // When accessed again, it will be opened automatically.
00174     // This can be useful to save memory usage.
00175     void closeTables() const;
00176 
00177     // Flush all open subtables.
00178     void flushTables (Bool fsync) const;
00179 
00180     // Rename the subtables with a path containing the old parent table name.
00181     void renameTables (const String& newParentName,
00182                        const String& oldParentName);
00183 
00184     // Are subtables used in other processes.
00185     Bool areTablesMultiUsed() const;
00186 
00187     // Put the description and data of the Record.
00188     // It also puts the fixedFlag attribute (of the mother object).
00189     void putRecord (AipsIO& os, Int recordType, const TableAttr&) const;
00190 
00191     // Get the description and data of the Record.
00192     // It also gets the fixedFlag attribute (of the mother object).
00193     void getRecord (AipsIO& os, Int& recordType, const TableAttr&);
00194 
00195     // Put the data of a record.
00196     // This is used to write a subrecord, whose description has
00197     // already been written.
00198     void putData (AipsIO& os, const TableAttr&) const;
00199 
00200     // Read the data of a record.
00201     // This is used to read a subrecord, whose description has
00202     // already been read.
00203     void getData (AipsIO& os, uInt version, const TableAttr&);
00204 
00205     // Reopen possible tables in keywords as read/write.
00206     // Tables are not reopened if they are not writable.
00207     void reopenRW();
00208 
00209     // Used by the RecordFieldPtr classes to attach in a type-safe way to the
00210     // correct field.
00211     // <group>
00212     void* get_pointer (Int whichField, DataType type) const;
00213     void* get_pointer (Int whichField, DataType type,
00214                        const String& recordType) const;
00215     // </group>
00216 
00217     // Merge a field from another record into this record.
00218     void mergeField (const TableRecordRep& other, Int whichFieldFromOther,
00219                      RecordInterface::DuplicatesFlag);
00220 
00221     // Merge all fields from the other record into this record.
00222     void merge (const TableRecordRep& other,
00223                 RecordInterface::DuplicatesFlag);
00224     
00225     // Print a record.
00226     // Print the contents of the record.
00227     // Only the first <src>maxNrValues</src> of an array will be printed.
00228     // A value < 0 means the entire array.
00229     void print (std::ostream&,
00230                 Int maxNrValues = 25,
00231                 const String& indent="") const;
00232 
00233 
00234 protected:
00235     // Utility function to avoid code duplication in the public member 
00236     // functions.
00237     void copy_other (const TableRecordRep& other);
00238 
00239     // Get the field number for a given name.
00240     virtual Int fieldNumber (const String& name) const;
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     // Get a KeywordSet object as a TableRecord.
00253     // (type: 0=ScalarKeywordSet, 1=ArrayKeywordSet, 2=TableKeywordSet)
00254     void getTableKeySet (AipsIO& os, uInt version, const TableAttr&,
00255                          uInt type);
00256 
00257 
00258     // Holds the description.
00259     //# Although we could use the RecordDesc object from RecordRep,
00260     //# it is better to use an own RecordDesc object in case a dedicated
00261     //# TableRecordDesc is needed in the future. In this way it
00262     //# is sure that inherited functions do not use the RecordDesc object
00263     //# in RecordRep.
00264     RecordDesc desc_p;
00265 };
00266 
00267 
00268 inline const String& TableRecordRep::comment (Int whichField) const
00269 {
00270     return desc_p.comment (whichField);
00271 }
00272 
00273 inline void TableRecordRep::setComment (Int whichField, const String& comment)
00274 {
00275     desc_p.setComment (whichField, comment);
00276 }
00277 
00278 inline const RecordDesc& TableRecordRep::description() const
00279 {
00280     return desc_p;
00281 }
00282 
00283 inline void TableRecordRep::renameField (const String& newName, Int whichField)
00284 {
00285     desc_p.renameField (newName, whichField);
00286 }
00287 
00288 
00289 
00290 
00291 } //# NAMESPACE CASA - END
00292 
00293 #endif