00001 //# VSCEngine.h: Base virtual column for a scalar column with any type 00002 //# Copyright (C) 1994,1995,1996,1999,2000 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_VSCENGINE_H 00029 #define TABLES_VSCENGINE_H 00030 00031 //# Includes 00032 #include <casacore/casa/aips.h> 00033 #include <casacore/tables/DataMan/VirtColEng.h> 00034 #include <casacore/tables/DataMan/VirtScaCol.h> 00035 00036 00037 namespace casacore { //# NAMESPACE CASACORE - BEGIN 00038 00039 // <summary> 00040 // Base virtual column for a scalar column with any type 00041 // </summary> 00042 00043 // <reviewed reviewer="UNKNOWN" date="before2004/08/25" tests=""> 00044 // </reviewed> 00045 00046 // <use visibility=export> 00047 00048 // <prerequisite> 00049 //# Classes you should understand before using this one. 00050 // <li> VirtualColumnEngine 00051 // <li> VirtualScalarColumn 00052 // </prerequisite> 00053 00054 // <etymology> 00055 // VSCEngine stands for Virtual Scalar Column Engine, i.e. a class 00056 // handling a virtual table column containing scalar values. 00057 // </etymology> 00058 00059 // <synopsis> 00060 // VSCEngine is a base virtual column engine to handle a column 00061 // with an arbitrary type. 00062 // Data of columns with standard data types can directly be stored 00063 // in a Table using a storage manager, but data of column with non-standard 00064 // types have to be stored in another way. 00065 // The way to do this is to split the object with the non-standard 00066 // type into its individual elements, which are subsequently put into the 00067 // appropriate columns. 00068 // 00069 // A virtual column engine has to be implemented for each non-standard 00070 // data type, which has to be stored in a table. This engine has to get 00071 // and put the individual parts the object. 00072 // VSCEngine is the base class for such engines, so the actual 00073 // engine quite simple to implement. The example shows the implementation 00074 // of an engine AVSCEngine handling a data type A. 00075 // 00076 // In principle the name of the engine class is free, but it is strongly 00077 // recommended to use the name <src><dataTypeId>VSCEngine</src>, where VSC 00078 // stands for Virtual Scalar Column (e.g. <src>AVSCEngine</src> for class A). 00079 // In this way the default data manager name supplied by the class and by 00080 // class ScalarColumnDesc can be used. 00081 // </synopsis> 00082 00083 // <example> 00084 // This example shows the implementation of an engine class AVSCEngine, 00085 // which stores the data of a class A. 00086 // The data objects A are stored in a column called the source column. 00087 // The user has to associate two target columns with it. The engine stores 00088 // the data parts x and y in the target columns. 00089 // The names of the target columns are stored as keywords in the source 00090 // column. In this way the engine can reconstruct itself when the table 00091 // is read back. 00092 // 00093 // In the example all AVSCEngine functions are shown inline, but they 00094 // should be implemented out-of-line in a separate .cc file. 00095 // <srcblock> 00096 // //# AVSCEngine.h: Example virtual column engine to handle data type A 00097 // 00098 // #if !defined(AIPS_AVSCENGINE_H) 00099 // #define AIPS_AVSCENGINE_H 00100 // 00101 // //# Includes 00102 // #include <casacore/tables/DataMan/VSCEngine.h> 00103 // #include <casacore/tables/Tables/ScalarColumn.h> 00104 // 00105 // // Define the class A. 00106 // class A 00107 // { 00108 // public: 00109 // A(): x_p(0), y_p(0) {} 00110 // A(Int x, float y) : x_p(x), y_p(y) {} 00111 // A(const A& that): x_p(that.x_p), y_p(that.y_p) {} 00112 // static String dataTypeId() 00113 // { return "A"; } 00114 // Int x() const 00115 // { return x_p; } 00116 // float y() const 00117 // { return y_p; } 00118 // Int& x() 00119 // { return x_p; } 00120 // float& y() 00121 // { return y_p; } 00122 // int operator== (const A& that) const 00123 // { return x_p==that.x_p && y_p==that.y_p; } 00124 // int operator< (const A& that) const 00125 // { return x_p<that.x_p || (x_p==that.x_p && y_p<that.y_p); } 00126 // private: 00127 // Int x_p; 00128 // float y_p; 00129 // }; 00130 // 00131 // // Now define the engine to handle objects of type A. 00132 // class AVSCEngine : public VSCEngine<A> 00133 // { 00134 // public: 00135 // 00136 // // The default constructor is required for reconstruction of the 00137 // // engine when a table is read back. 00138 // AVSCEngine() 00139 // {} 00140 // 00141 // // Construct the engine for the given source column and storing 00142 // // the result in the given target columns for the data members 00143 // // x and y of class A. 00144 // AVSCEngine (const String& sourceColumnName, 00145 // const String& xTargetColumnName, 00146 // const String& yTargetColumnname) 00147 // : VSCEngine<A> (sourceColumnName), 00148 // xTargetName_p (xTargetColumnName), 00149 // yTargetName_p (yTargetColumnName) 00150 // {} 00151 // 00152 // // Destructor is mandatory. 00153 // virtual ~AVSCEngine() 00154 // {} 00155 // 00156 // // Clone the object. 00157 // virtual DataManager* clone() const 00158 // { 00159 // DataManager* dmPtr = new AVSCEngine (sourceColumnName(), 00160 // xTargetName_p, yTargetName_p); 00161 // return dmPtr; 00162 // } 00163 // 00164 // // Store the target column names in the source column keywords. 00165 // virtual void create (uInt) 00166 // { 00167 // TableColumn src (table(), sourceColumnName()); 00168 // src.keywordSet().keysString()("_xTargetName") = xTargetName_p; 00169 // src.keywordSet().keysString()("_yTargetName") = yTargetName_p; 00170 // } 00171 // 00172 // // Prepare the engine by allocating column objects 00173 // // for the target columns. 00174 // virtual void prepare() 00175 // { 00176 // TableColumn src (table(), sourceColumnName()); 00177 // xTargetName_p = src.keywordSet().asString ("_xTargetName"); 00178 // yTargetName_p = src.keywordSet().asString ("_yTargetName"); 00179 // rocolx.attach (table(), xTargetName_p); 00180 // rocoly.attach (table(), yTargetName_p); 00181 // if (table().isWritable()) { 00182 // colx.attach (table(), xTargetName_p); 00183 // coly.attach (table(), yTargetName_p); 00184 // } 00185 // } 00186 // 00187 // // Get the data from a row. 00188 // virtual void get (uInt rownr, A& value) 00189 // { 00190 // rocolx.get (rownr, value.x()); 00191 // rocoly.get (rownr, value.y()); 00192 // } 00193 // 00194 // // Put the data in a row. 00195 // virtual void put (uInt rownr, const A& value) 00196 // { 00197 // colx.put (rownr, value.x()); 00198 // coly.put (rownr, value.y()); 00199 // } 00200 // 00201 // // Register the class name and the static makeObject "constructor". 00202 // // This will make the engine known to the table system. 00203 // static void registerClass() 00204 // { 00205 // DataManager::registerCtor ("AVSCEngine", makeObject); 00206 // } 00207 // 00208 // private: 00209 // // Copy constructor is only used by clone(). 00210 // // (so it is made private). 00211 // AVSCEngine (const AVSCEngine&) 00212 // : VSCEngine<A> (that), 00213 // xTargetName_p (that.xTargetName_p), 00214 // yTargetName_p (that.yTargetName_p) 00215 // {} 00216 // 00217 // // Assignment is not needed and therefore forbidden 00218 // // (so it is made private and is not implemented). 00219 // AVSCEngine& operator= (const AVSCEngine&); 00220 // 00221 // 00222 // // The target column names. 00223 // String xTargetName_p; 00224 // String yTargetName_p; 00225 // // Objects for the target columns. 00226 // ScalarColumn<Int> colx; // used by put 00227 // ScalarColumn<Int> rocolx; // used by get 00228 // ScalarColumn<float> coly; // used by put 00229 // ScalarColumn<float> rocoly; // used by get 00230 // 00231 // public: 00232 // // Define the "constructor" to construct this engine when a 00233 // // table is read back. 00234 // // This "constructor" has to be registered by the user of the engine. 00235 // // Function registerClass() is doing that. 00236 // static DataManager* makeObject (const String& dataManagerType) 00237 // { 00238 // DataManager* dmPtr = new AVSCEngine(); 00239 // return dmPtr; 00240 // } 00241 // }; 00242 // 00243 // #endif 00244 // </srcblock> 00245 // 00246 // User code using this engine to create a new table could look like: 00247 // <srcblock> 00248 // // Register the engine. 00249 // // This is not needed if the engine is registered as part 00250 // // of the general DataManager::registerAllCtor function. 00251 // AVSCEngine::registerClass(); 00252 // // Create the table description. 00253 // TableDesc td; 00254 // td.addColumn (ScalarColumnDesc<A>("source")); 00255 // td.addColumn (ScalarColumnDesc<Int>("xTarget")); 00256 // td.addColumn (ScalarColumnDesc<Int>("yTarget")); 00257 // SetupNewTable setup ("table.name", td, Table::New); 00258 // // Define the engine for column "source". 00259 // AVSCEngine engine ("source", "xTarget", "yTarget"); 00260 // Table tab (setup, 10); 00261 // // Put data into column "source". 00262 // ScalarColumn<A> col (tab, "source"); 00263 // for (uInt i=0; i<10; i++) { 00264 // col.put (i, someA); // writes indirectly xTarget and yTarget 00265 // } 00266 // </srcblock> 00267 // </example> 00268 // 00269 // <motivation> 00270 // This class makes it easier for the user to implement the engine. 00271 // It supplies several default functions. 00272 // </motivation> 00273 00274 // <templating arg=T> 00275 // <li> Default constructor T(); 00276 // <li> Copy constructor T(const T&); 00277 // <li> Assignment operator T& operator= (const T&); 00278 // <li> comparison operator int operator== (const T&) const; 00279 // <li> comparison operator int operator< (const T&) const; 00280 // <li> identification <src>static String dataTypeId();</src> 00281 // This should return the (unique) name of the class, thus 00282 // when T is templated in its turn, the name should contain the 00283 // template argument name. 00284 // </templating> 00285 00286 00287 template<class T> 00288 class VSCEngine : public VirtualColumnEngine, 00289 public VirtualScalarColumn<T> 00290 { 00291 //# Make members of parent class known. 00292 public: 00293 using VirtualScalarColumn<T>::dataTypeId; 00294 00295 public: 00296 // The default constructor is required for reconstruction of the 00297 // engine when a table is read back. 00298 // It is also used to construct an engine, which does not check 00299 // the source column name. 00300 VSCEngine(); 00301 00302 // Construct an engine to handle a column with an arbitrary data type. 00303 // Later it will check if the source column name is correct. 00304 VSCEngine (const String& sourceColumnName); 00305 00306 // Destructor is mandatory. 00307 ~VSCEngine(); 00308 00309 // Return the data manager type name. 00310 // This defaults to the data type ID followed by VSCEngine 00311 // (meaning Virtual Scalar Column Engine). 00312 String dataManagerType() const; 00313 00314 // Get the name of the source column. 00315 const String& sourceColumnName() const 00316 { return sourceName_p; } 00317 00318 protected: 00319 00320 // Copy constructor is only used by clone(). 00321 // (so it is made protected). 00322 VSCEngine (const VSCEngine<T>&); 00323 00324 private: 00325 // Assignment is not needed and therefore forbidden 00326 // (so it is made private). 00327 VSCEngine<T>& operator= (const VSCEngine<T>&); 00328 00329 // The column is in principle writable. 00330 // This does not mean it is actually writable, because that 00331 // depends on the fact if the table is writable. 00332 Bool isWritable() const; 00333 00334 // Create the column object for the scalar column in this engine. 00335 // It will check if the given column name matches the source 00336 // column name. This assures that the engine is bound to the 00337 // correct column. 00338 DataManagerColumn* makeScalarColumn (const String& columnName, 00339 int dataType, 00340 const String& dataTypeID); 00341 00342 00343 //# Now define the data members. 00344 String sourceName_p; //# source column name 00345 }; 00346 00347 00348 00349 } //# NAMESPACE CASACORE - END 00350 00351 #ifndef CASACORE_NO_AUTO_TEMPLATES 00352 #include <casacore/tables/DataMan/VSCEngine.tcc> 00353 #endif //# CASACORE_NO_AUTO_TEMPLATES 00354 #endif