ColumnDesc.h

Go to the documentation of this file.
00001 //# ColumnDesc.h: an envelope class for column descriptions in tables
00002 //# Copyright (C) 1994,1995,1996,1997,1998,1999,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 //# $Id$
00027 
00028 #ifndef TABLES_COLUMNDESC_H
00029 #define TABLES_COLUMNDESC_H
00030 
00031 
00032 //# Includes
00033 #include <casa/aips.h>
00034 #include <tables/Tables/BaseColDesc.h>
00035 #include <casa/Containers/SimOrdMap.h>
00036 #include <casa/BasicSL/String.h>
00037 #include <casa/Arrays/IPosition.h>
00038 
00039 namespace casa { //# NAMESPACE CASA - BEGIN
00040 
00041 //# Forward Declarations
00042 class PlainColumn;
00043 class RefColumn;
00044 class TableRecord;
00045 class TableAttr;
00046 class AipsIO;
00047 #include <casa/iosfwd.h>
00048 
00049 
00050 // <summary>
00051 // Envelope class for the description of a table column
00052 // </summary>
00053 
00054 // <use visibility=export>
00055 
00056 // <reviewed reviewer="Paul Shannon" date="1994/08/11" tests="none">
00057 // </reviewed>
00058 
00059 // <prerequisite>
00060 //   <li> Tables module (see especially Tables.h, the module header file)
00061 //   <li> Envelope/Letter class design (see J. Coplien, Advanced C++)
00062 // </prerequisite>
00063 
00064 // <synopsis>
00065 // Class ColumnDesc is an envelope for the letter class BaseColDesc
00066 // and its derivations like
00067 // <linkto class="ScalarColumnDesc:description">ScalarColumnDesc</linkto>,
00068 // <linkto class="ScalarRecordColumnDesc:description">
00069 //  ScalarRecordColumnDesc</linkto>.
00070 // <linkto class="ArrayColumnDesc:description">ArrayColumnDesc</linkto>, and
00071 // <linkto class="SubTableDesc:description">SubTableDesc</linkto>.
00072 // ColumnDesc is meant to examine or slightly modify already existing
00073 // column descriptions.
00074 // It allows the retrieval of attributes like name, data type, etc..
00075 // For non-const ColumnDesc objects it is possible to modify the
00076 // attributes comment and keyword set.
00077 //
00078 // Since there are several types of columns, the class ColumnDesc
00079 // cannot handle all details of those column types. Therefore,
00080 // to create a column description, an instance of the specialized
00081 // classes ArrayColumnDesc<T>, etc. has to be constructed.
00082 // In there column type dependent things like array shape and
00083 // default value can be defined.
00084 //
00085 // This class also enumerates the possible options which can be used
00086 // when defining a column via classes like ScalarColumnDesc<T>.
00087 // These options are:
00088 // <dl>
00089 //  <dt> FixedShape
00090 //  <dd>
00091 //     This is only useful for columns containing arrays and tables.
00092 //     FixedShape means that the shape of the array or table must
00093 //     be the same in each cell of the column.
00094 //     If not given, the array or table shape may vary.
00095 //     Option Direct forces FixedShape.
00096 //  <dt> Direct
00097 //  <dd>
00098 //     This is only useful for columns containing arrays and tables.
00099 //     Direct means that the data is directly stored in the table.
00100 //     Direct forces option FixedShape.
00101 //     If not given, the array or table is indirect, which implies
00102 //     that the data will be stored in a separate file.
00103 //  <dt> Undefined
00104 //  <dd>
00105 //     Undefined is only useful for scalars. If not given, all possible
00106 //     values of the scalar have a meaning. If given, a value equal to
00107 //     the default value in the column description is an undefined value.
00108 //     The function TableColumn::isDefined will return False for such
00109 //     values.
00110 // </dl>
00111 // </synopsis>
00112 
00113 // <example>
00114 // <srcblock>
00115 //  TableDesc tableDesc("theTableDesc", TableDesc::New);
00116 //  // Add a float scalar column.
00117 //  tableDesc.addColumn (ScalarColumnDesc<float> ("NAME");
00118 //  // Get the description of a column and change the comments.
00119 //  // In order to change the comments, a reference must be used
00120 //  // (because the ColumnDesc copy constructor and assign have copy
00121 //  // semantics).
00122 //  ColumnDesc& myColDesc = tableDesc.columnDesc ("aName");
00123 //  myColDesc.comment() += "some more comments";
00124 // </srcblock>
00125 // </example>
00126 
00127 // <motivation>
00128 // When getting the description of an arbitrary column, a pointer to
00129 // that description is needed to allow proper execution of virtual
00130 // functions.
00131 // An envelope class is needed to hide this from the user.
00132 // </motivation>
00133 
00134 // <todo asof="$DATE:$">
00135 //# A List of bugs, limitations, extensions or planned refinements.
00136 // </todo>
00137 
00138 
00139 class ColumnDesc
00140 {
00141 friend class ColumnDescSet;
00142 friend class ColumnSet;
00143 friend class BaseColumn;
00144 friend class RefTable;
00145 
00146 public:
00147 
00148     // Enumerate the possible column options.
00149     // They can be combined by adding (logical or-ing) them.
00150     enum Option {
00151         // direct table or array
00152         Direct=1,
00153         // undefined values are possible
00154         Undefined=2,
00155         // fixed array/table shape
00156         FixedShape=4
00157     };
00158 
00159     // Construct from a column description.
00160     // This constructor is merely for the purpose of the automatic
00161     // conversion of an object like ScalarColumnDesc<T> to
00162     // ColumnDesc when adding a column to the table description
00163     // using the function TableDesc::addColumn.
00164     ColumnDesc (const BaseColumnDesc&);
00165 
00166     // Copy constructor (copy semantics).
00167     ColumnDesc (const ColumnDesc& that);
00168 
00169     // Default constructor (needed for ColumnDescSet).
00170     ColumnDesc();
00171 
00172     ~ColumnDesc();
00173 
00174     // Assignment (copy semantics).
00175     ColumnDesc& operator= (const ColumnDesc& that);
00176 
00177     // Comparison.
00178     // Two descriptions are equal when their data types, value types
00179     // (scalar, array or table) and possible dimensionalities are equal.
00180     // <group>
00181     Bool operator== (const ColumnDesc&) const;
00182     Bool operator!= (const ColumnDesc&) const;
00183     // </group>
00184 
00185     // Get access to the set of keywords.
00186     // <group>
00187     TableRecord& rwKeywordSet()
00188         { return colPtr_p->rwKeywordSet(); }
00189     const TableRecord& keywordSet() const
00190         { return colPtr_p->keywordSet(); }
00191     // </group>
00192 
00193     // Get the name of the column.
00194     //# Maybe it can be inlined.
00195     const String& name() const;
00196 
00197     // Get the data type of the column.
00198     // This always returns the type of a scalar, even when the column
00199     // contains arrays.
00200     DataType dataType() const
00201         { return colPtr_p->dataType(); }
00202 
00203     // Get the true data type of the column.
00204     // Unlike dataType, it returns an array data type (e.g. TpArrayInt)
00205     // when the column contains arrays.
00206     DataType trueDataType() const;
00207 
00208     // Get the type id for non-standard data types (i.e. for TpOther).
00209     // For standard data types the returned string is empty.
00210     const String& dataTypeId() const
00211         { return colPtr_p->dataTypeId(); }
00212 
00213     // Get the type name of the default data manager.
00214     const String& dataManagerType() const
00215         { return colPtr_p->dataManagerType(); }
00216 
00217     // Get the type name of the default data manager
00218     // (allowing it to be changed).
00219     String& dataManagerType()
00220         { return colPtr_p->dataManagerType(); }
00221 
00222     // Get the data manager group.
00223     const String& dataManagerGroup() const
00224         { return colPtr_p->dataManagerGroup(); }
00225 
00226     // Get the data manager group.
00227     // (allowing it to be changed).
00228     String& dataManagerGroup()
00229         { return colPtr_p->dataManagerGroup(); }
00230 
00231     // If <src>always==True</src> they are always set, otherwise only if empty.
00232     void setDefaultDataManager (Bool always=True)
00233         { colPtr_p->setDefaultDataManager (always); }
00234 
00235     // Get comment string.
00236     const String& comment() const
00237         { return colPtr_p->comment(); }
00238 
00239     // Get comment string (allowing it to be changed).
00240     String& comment()
00241         { return colPtr_p->comment(); }
00242 
00243     // Get the options. The possible options are defined by the enum Option.
00244     // E.g.
00245     // <srcblock>
00246     //    const ColumnDesc& coldesc = tableDesc.getColumn ("column_name");
00247     //    if (coldesc.option() & ColumnDesc::Direct  ==  ColumnDesc::Direct) {
00248     //            // the column has the Direct flag set
00249     //    }
00250     // </srcblock>
00251     int options() const
00252         { return colPtr_p->options(); }
00253 
00254     // Check if the column is defined with a fixed shape.
00255     // This is always true for scalars. For arrays it is true when
00256     // the FixedShape flag was set when the column was defined.
00257     Bool isFixedShape() const;
00258 
00259     // Test if column is a scalar.
00260     Bool isScalar() const
00261         { return colPtr_p->isScalar(); }
00262     // Test if column is an array.
00263     Bool isArray() const
00264         { return colPtr_p->isArray(); }
00265     // Test if column is a table.
00266     Bool isTable() const
00267         { return colPtr_p->isTable(); }
00268 
00269     // Get the number of dimensions.
00270     Int ndim() const
00271         { return colPtr_p->ndim(); }
00272 
00273     // Get the predefined shape.
00274     // If not defined, a zero shape will be returned.
00275     const IPosition& shape() const
00276         { return colPtr_p->shape(); }
00277 
00278     // Set the number of dimensions.
00279     // This is only allowed for arrays.
00280     // <src>ndim</src> can be zero to clear the number of dimensions
00281     // and the shape.
00282     // Otherwise it can only be used if the dimensionality has not been
00283     // defined yet.
00284     void setNdim (uInt ndim)
00285         { colPtr_p->setNdim (ndim); }
00286 
00287     // Set the predefined shape.
00288     // This is only allowed for arrays, for which the shape
00289     // has not been defined yet.
00290     // If the dimensionality has already been defined, it must match.
00291     // It will set the option <src>FixedShape</src> if not set yet.
00292     // <br> The first version leaves the <src>Direct</src> option as is.
00293     // The second version sets the <src>Direct</src> option as given.
00294     // <group>
00295     void setShape (const IPosition& shape)
00296         { colPtr_p->setShape (shape); }
00297     void setShape (const IPosition& shape, Bool directOption)
00298         { colPtr_p->setShape (shape, directOption); }
00299     // </group>
00300 
00301     // Set the options to the given value.
00302     // Option <src>ColumnDesc::Direct</src> forces <src>FixedShape</src>.
00303     // If <src>FixedShape</src> is not given (implicitly or explicitly),
00304     // the column can have no shape, so its shape is cleared.
00305     void setOptions (int options)
00306         { colPtr_p->setOptions (options); }
00307 
00308     // Get the maximum value length.
00309     uInt maxLength() const
00310         { return colPtr_p->maxLength(); }
00311 
00312     // Set the maximum value length.
00313     // So far, this is only possible for columns containing String values.
00314     // An exception is thrown if the column data type is not TpString.
00315     // Some storage managers support fixed length strings and can store
00316     // them more efficiently than variable length strings.
00317     void setMaxLength (uInt maxLength)
00318         { colPtr_p->setMaxLength (maxLength); }
00319 
00320     // Get table description (in case column contains subtables).
00321     // <group>
00322     const TableDesc* tableDesc() const
00323         { return colPtr_p->tableDesc(); }
00324     TableDesc* tableDesc()
00325         { return colPtr_p->tableDesc(); }
00326     // </group>
00327 
00328     // Show the column on cout.
00329     void show() const;
00330 
00331     // Show the column.
00332     void show (ostream& os) const;
00333 
00334     // Write into AipsIO.
00335     friend AipsIO& operator<< (AipsIO& ios, const ColumnDesc& cd);
00336 
00337     // Read from AipsIO.
00338     friend AipsIO& operator>> (AipsIO& ios, ColumnDesc& cd);
00339 
00340     // Show on ostream.
00341     friend ostream& operator<< (ostream& ios, const ColumnDesc& cd);
00342 
00343     // Serve as default function for registerMap (see below), which catches 
00344     // all unknown xxxColumnDesc class names.
00345     // <thrown>
00346     //   <li> TableUnknownDesc
00347     // </thrown>
00348     static BaseColumnDesc* unknownColumnDesc (const String& name);
00349 
00350 protected:
00351     BaseColumnDesc* colPtr_p;
00352     Bool            allocated_p;    //# False = not allocated -> do not delete
00353 
00354     // Define a map which maps the name of the various xxxColumnDesc
00355     // classes to a static function constructing them.
00356     // This is used when reading a column description back; it in fact
00357     // determines the exact column type and is an easier thing to do
00358     // than an enormous switch statement.
00359     // The map is filled by the function registerColumnDesc upon the
00360     // first call of ColumnDesc::getFile.
00361     static Bool registrationDone_p;
00362 public:
00363     static SimpleOrderedMap<String, BaseColumnDesc* (*)(const String&)> registerMap;
00364 
00365 
00366 private:
00367     // Construct from a pointer (for class BaseColumn).
00368     ColumnDesc (BaseColumnDesc*);
00369 
00370     // Check if a column can be handled by ColumnDescSet.
00371     // It is called before the column gets actually added, etc..
00372     // <group>
00373     // Check if the column can be added to the table description.
00374     // It is implemented for a virtual column to check if the columns
00375     // it uses really exist.
00376     void checkAdd (const ColumnDescSet& cds) const
00377         { colPtr_p->checkAdd (cds); }
00378     // Check when a column gets renamed in a table description.
00379     // It is not used.
00380     void checkRename (const ColumnDescSet& cds, const String& newName) const
00381         { colPtr_p->checkRename (cds, newName); }
00382     // </group>
00383 
00384     // Take action after a column has been handled by ColumnDescSet.
00385     // It is called after the column has been actually added, etc..
00386     // This gives, for instance, the virtual column class the opportunity
00387     // to update the virtual column list.
00388     // <group>
00389     void handleAdd (ColumnDescSet& cds)
00390         { colPtr_p->handleAdd (cds); }
00391     void handleRename (ColumnDescSet& cds, const String& oldName)
00392         { colPtr_p->handleRename (cds, oldName); }
00393     void handleRemove (ColumnDescSet& cds)
00394         { colPtr_p->handleRemove (cds); }
00395     // </group>
00396 
00397     // This function allows each column to act upon a rename of another column.
00398     // If the old name is used internally, the column can update itself.
00399     // It is called after handleRename has been called.
00400     void renameAction (const String& newName, const String& oldName)
00401         { colPtr_p->renameAction (newName, oldName); }
00402 
00403     // Create a PlainColumn column object out of this column description.
00404     PlainColumn* makeColumn (ColumnSet* csp) const
00405         { return colPtr_p->makeColumn (csp); }
00406 
00407     // Create a RefColumn column object out of this column description.
00408     RefColumn* makeRefColumn (RefTable* rtp, BaseColumn* bcp) const
00409         { return colPtr_p->makeRefColumn (rtp, bcp); }
00410 
00411     // Set the name of the column.
00412     void setName (const String& name)
00413         { colPtr_p->setName(name); }
00414 
00415     // Store the object in AipsIO.
00416     void putFile (AipsIO& ios, const TableAttr&) const;
00417 
00418     // Get the object from AipsIO.
00419     void getFile (AipsIO&, const TableAttr&);
00420 
00421     // Register all column types. In this way the getFile function
00422     // can construct the correct xxxColumnDesc object.
00423     void registerColumnDesc();
00424 };
00425 
00426 inline ColumnDesc::ColumnDesc()
00427 : colPtr_p(0),
00428   allocated_p (False)
00429 {}
00430 
00431 
00432 } //# NAMESPACE CASA - END
00433 
00434 #endif

Generated on Mon Sep 1 22:36:15 2008 for NRAOCASA by  doxygen 1.5.1