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
1.5.1