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