casacore
RecordDescRep.h
Go to the documentation of this file.
1 //# RecordDescRep.h: Representation of a RecordDesc
2 //# Copyright (C) 1996,1997,1998,1999,2000,2001
3 //# Associated Universities, Inc. Washington DC, USA.
4 //#
5 //# This library is free software; you can redistribute it and/or modify it
6 //# under the terms of the GNU Library General Public License as published by
7 //# the Free Software Foundation; either version 2 of the License, or (at your
8 //# option) any later version.
9 //#
10 //# This library is distributed in the hope that it will be useful, but WITHOUT
11 //# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
12 //# FITNESS FOR A PARTICULAR PURPOSE. See the GNU Library General Public
13 //# License for more details.
14 //#
15 //# You should have received a copy of the GNU Library General Public License
16 //# along with this library; if not, write to the Free Software Foundation,
17 //# Inc., 675 Massachusetts Ave, Cambridge, MA 02139, USA.
18 //#
19 //# Correspondence concerning AIPS++ should be addressed as follows:
20 //# Internet email: aips2-request@nrao.edu.
21 //# Postal address: AIPS++ Project Office
22 //# National Radio Astronomy Observatory
23 //# 520 Edgemont Road
24 //# Charlottesville, VA 22903-2475 USA
25 //#
26 //#
27 //# $Id$
28 
29 
30 #ifndef CASA_RECORDDESCREP_H
31 #define CASA_RECORDDESCREP_H
32 
33 //# Includes
34 #include <casacore/casa/aips.h>
35 #include <casacore/casa/Utilities/DataType.h>
36 #include <casacore/casa/Containers/Block.h>
37 #include <casacore/casa/Arrays/IPosition.h>
38 #include <casacore/casa/iosfwd.h>
39 #include <map>
40 
41 namespace casacore { //# NAMESPACE CASACORE - BEGIN
42 
43 //# Forward Declarations
44 class RecordDesc;
45 class AipsIO;
46 
47 
48 // <summary>
49 // Representation of a RecordDesc
50 // </summary>
51 
52 // <use visibility=local>
53 // <reviewed reviewer="Mark Wieringa" date="1996/04/15" tests="tRecordDesc">
54 // </reviewed>
55 
56 // <prerequisite>
57 // <li> <linkto group="DataType.h#DataType">DataType</linkto>
58 // <li> <linkto class="RecordDesc">RecordDesc</linkto>
59 // </prerequisite>
60 
61 // <etymology>
62 // Rep is an often used abbreviation for representation.
63 // Thus RecordDescRep is the representation of a RecordDesc.
64 // </etymology>
65 
66 // <synopsis>
67 // RecordDescRep is used by RecordDesc
68 // to implement its copy-on-write semantics. RecordDesc is the interface
69 // to the user, while RecordDescRep contains the actual implementation.
70 // See <linkto class=RecordDesc>RecordDesc</linkto> for a more detailed
71 // description of a record description.
72 // </synopsis>
73 
74 // <example>
75 // See the example in the description of the
76 // <linkto class="Record:example1">Record</linkto> class.
77 // </example>
78 
79 // <motivation>
80 // RecordDescRep is needed to make copy-on-write semantics possible in
81 // class RecordDesc.
82 // </motivation>
83 
84 // <todo asof="1995/06/01">
85 // <li> Should the strategy wrt. field names be changed (not used in
86 // field description equality, must be unique at a given level?).
87 // <li> Perhaps we should be able to more conveniently change the description
88 // of an existing field.
89 // </todo>
90 
92 {
93 public:
94  // Create a description with no fields.
95  RecordDescRep();
96 
97  // Create a description which is a copy of other.
98  RecordDescRep (const RecordDescRep& other);
99 
100  // Replace this description with other.
101  RecordDescRep& operator= (const RecordDescRep& other);
102 
103  virtual ~RecordDescRep();
104 
105  // Add scalar or array field. If of array type, the shape is set to [-1],
106  // which indicates a variable sized array. Returns the number of fields in
107  // the description.
108  uInt addField (const String& fieldName, DataType scalarOrArrayType);
109 
110  // Add an array field of the indicated type. The DataType is promoted
111  // from a scalar type to an array type if necessary, e.g.,
112  // <src>TpInt ->TpArrayInt</src>. Returns the number of fields in
113  // the description.
114  uInt addArray (const String& fieldName, DataType scalarOrArrayType,
115  const IPosition& shape);
116 
117  // Add a Record field to the description. This allows hierarchical
118  // descriptions to be developed. Returns the number of fields in the
119  // description.
120  uInt addRecord (const String& fieldName, const RecordDesc& subDesc);
121 
122  // Add a Table field to the description. The Table description has the
123  // given name. Returns the number of fields in the description.
124  uInt addTable (const String& fieldName, const String& tableDescName);
125 
126  // Get the comment for this field.
127  const String& comment (Int whichField) const;
128 
129  // Set the comment for this field.
130  void setComment (Int whichField, const String& comment);
131 
132  // Set the shape for this field.
133  // An exception will be thrown if the field is no array.
134  void setShape (Int whichField, const IPosition& shape);
135 
136  // Merge a single field from other. If allowDuplicates is True, silently
137  // throw away fields if one with the same name and type already exists,
138  // otherwise an exception is thrown. Conflicting types always cause an
139  // exception. Returns the number of fields in the description.
140  uInt mergeField (const RecordDescRep& other, Int whichFieldFromOther,
141  int duplicateAction);
142 
143  // Add all the fields from another RecordDescRep to the current objects.
144  uInt merge (const RecordDescRep& other, int duplicateAction);
145 
146  // Remove the given field from the description.
147  virtual uInt removeField (Int whichField);
148 
149  // Rename the given field.
150  virtual void renameField (const String& newName, Int whichField);
151 
152  // Returns the index of the field named fieldName. Returns -1 if fieldName
153  // does not exist.
154  Int fieldNumber (const String& fieldName) const;
155 
156  // Number of fields in the description.
157  uInt nfields() const;
158 
159  // What is the type of the given field. Returns TpRecord if the field is
160  // a sub-Record.
161  DataType type (Int whichField) const;
162 
163  // What is the name of the given field.
164  const String& name (Int whichField) const;
165 
166  // Create a name for a field defined by index as *i (similar to glish).
167  // It takes care that the resulting name is unique by adding a suffix _j
168  // when needed.
169  String makeName (Int whichField) const;
170 
171  // Make the given name unique by adding a suffix _j when needed.
172  // j is the minimal number needed to make it unique.
173  String uniqueName (const String& name) const;
174 
175  // Returns True if whichField is an array.
176  Bool isArray (Int whichField) const;
177 
178  // Returns True if whichField is a scalar.
179  Bool isScalar (Int whichField) const;
180 
181  // Returns True if whichField is a sub-record.
182  Bool isSubRecord (Int whichField) const;
183 
184  // Returns True if whichField is a table.
185  Bool isTable (Int whichField) const;
186 
187  // What is the shape of the given field. Returns [1] if the field is a
188  // scalar, table or, sub-record, [-1] if it is a variable length array,
189  // and the actual shape for a fixed length array.
190  const IPosition& shape (Int whichField) const;
191 
192  // What is the name of the table description associated with a table.
193  const String& tableDescName (Int whichField) const;
194 
195  // If whichField is a sub-record with a description,
196  // return its description. Otherwise an exception is thrown.
197  // <group>
198  const RecordDesc& subRecord (Int whichField) const;
199  RecordDesc& subRecord (Int whichField);
200  // </group>
201 
202  // <group>
203  // This and other compare equal if the field types and shapes are identical
204  // (recursively if there are described sub-records or tables).
205  // The field names are not used.
206  Bool operator== (const RecordDescRep& other) const;
207  Bool operator!= (const RecordDescRep& other) const;
208  // </group>
209 
210  // Test if this description conforms the other.
211  // It is similar to operator==. However, a subrecord in that description
212  // always conforms an arbitrary (i.e. empty) subrecord in this
213  // description.
214  // <br>This is used by Record, to see if another record can be assigned
215  // to this record.
216  Bool conform (const RecordDescRep& other) const;
217 
218  // Test if this description equals another one.
219  // It is equal if the number of fields is equal and all field names in
220  // this description occur in the other too. The order of the fields
221  // is not important.
222  // <br>The flag equalDataTypes is set to True if the data types
223  // of all fields match.
224  // <br>Use function operator== if order and types are important,
225  // but names are not.
226  Bool isEqual (const RecordDescRep& other, Bool& equalDataTypes) const;
227 
228  // Test if this description is a subset of another one.
229  // It is similar to isEqual above.
230  Bool isSubset (const RecordDescRep& other, Bool& equalDataTypes) const;
231 
232  // Test if this description is a strict subset of another one, thus
233  // if it is a subset and not equal.
234  Bool isStrictSubset (const RecordDescRep& other,
235  Bool& equalDataTypes) const;
236 
237  // Test if the set of field names in this and other record description
238  // is disjoint (i.e. if they do not share names).
239  Bool isDisjoint (const RecordDescRep& other) const;
240 
241 protected:
242  // Add a field name and its type.
243  // It checks if the name is unique and it extends the various blocks
244  // using increment_length.
245  void addFieldName (const String& fieldName, DataType type);
246 
247  // Add a field from another Record description.
248  // This is used by the merge functions.
249  virtual void addRepField (const RecordDescRep& other,
250  const String& newName, Int whichField);
251 
252  // Add the field info. These are helper functions for the add functions
253  // and can be used in derived classes too.
254  // <group>
255  void addFieldAny (DataType scalarOrArrayType);
256  void addFieldArray (DataType scalarOrArrayType, const IPosition& shape);
257  // </group>
258 
259  // Set the shape (for a derived class).
260  void setShape (const IPosition& shape, Int whichField);
261 
262  // Helper functions
263  // <group>
264  virtual void increment_length();
265  void copy_other (const RecordDescRep& other);
266  // </group>
267 
268 private:
269  // Test if all fields are part of the other description.
270  // The flag equalDataTypes is set to True if the data types of the
271  // fields in both descriptions are the same.
272  Bool allExist (const RecordDescRep&, Bool& equalDataTypes) const;
273 
274  // Number of fields in the description.
276  // The DataType of each field.
278  // The name of each field.
280  // The description of the subrecords. Null if the field is not a subrecord.
281  // This isn't the most efficient representation. If this is ever an issue
282  // we could calculate these, or store them in one Block, or implement
283  // copy-on-write semantics.
285  // The shape of the field [1] for scalars and sub-records.
287  // True if the corresponding field is an array.
289  // Table description name for table fields.
291  // Comments for each field.
293  // Mapping of field name to field number.
294  std::map<String,Int> name_map_p;
295 };
296 
298 {
299  return n_p;
300 }
301 
302 inline DataType RecordDescRep::type (Int whichField) const
303 {
304  return DataType(types_p[whichField]);
305 }
306 
307 inline const String& RecordDescRep::name (Int whichField) const
308 {
309  return names_p[whichField];
310 }
311 
312 inline const IPosition& RecordDescRep::shape (Int whichField) const
313 {
314  return shapes_p[whichField];
315 }
316 
317 inline Bool RecordDescRep::isArray (Int whichField) const
318 {
319  return is_array_p[whichField];
320 }
321 
322 inline Bool RecordDescRep::isScalar (Int whichField) const
323 {
324  return isScalarFun (DataType(types_p[whichField]));
325 }
326 
327 inline Bool RecordDescRep::isSubRecord (Int whichField) const
328 {
329  return (types_p[whichField] == TpRecord);
330 }
331 
332 inline Bool RecordDescRep::isTable (Int whichField) const
333 {
334  return (types_p[whichField] == TpTable);
335 }
336 
337 inline const RecordDesc& RecordDescRep::subRecord (Int whichField) const
338 {
339  //# The cast to non-const is completely safe.
340  return ((RecordDescRep*)this)->subRecord (whichField);
341 }
342 
343 inline const String& RecordDescRep::tableDescName (Int whichField) const
344 {
345  return tableDescNames_p[whichField];
346 }
347 
348 
349 
350 } //# NAMESPACE CASACORE - END
351 
352 #endif
casacore::RecordDescRep::RecordDescRep
RecordDescRep()
Create a description with no fields.
casacore::RecordDescRep::tableDescName
const String & tableDescName(Int whichField) const
What is the name of the table description associated with a table.
Definition: RecordDescRep.h:343
casacore::RecordDesc
Description of the fields in a record object.
Definition: RecordDesc.h:105
casacore::RecordDescRep::fieldNumber
Int fieldNumber(const String &fieldName) const
Returns the index of the field named fieldName.
casacore::IPosition
A Vector of integers, for indexing into Array<T> objects.
Definition: IPosition.h:119
casacore::RecordDescRep::renameField
virtual void renameField(const String &newName, Int whichField)
Rename the given field.
casacore::RecordDescRep::increment_length
virtual void increment_length()
Helper functions.
casacore::RecordDescRep::addField
uInt addField(const String &fieldName, DataType scalarOrArrayType)
Add scalar or array field.
casacore::RecordDesc::subRecord
const RecordDesc & subRecord(Int whichField) const
If whichField is a sub-record return its description.
Definition: RecordDesc.h:447
casacore::PtrBlock
A drop-in replacement for Block<T*>.
Definition: Block.h:814
casacore::RecordDescRep::names_p
Block< String > names_p
The name of each field.
Definition: RecordDescRep.h:279
casacore::RecordDescRep::addRecord
uInt addRecord(const String &fieldName, const RecordDesc &subDesc)
Add a Record field to the description.
casacore::RecordDescRep::setComment
void setComment(Int whichField, const String &comment)
Set the comment for this field.
casacore::RecordDescRep::comment
const String & comment(Int whichField) const
Get the comment for this field.
casacore::RecordDescRep::isArray
Bool isArray(Int whichField) const
Returns True if whichField is an array.
Definition: RecordDescRep.h:317
casacore::RecordDescRep::addFieldArray
void addFieldArray(DataType scalarOrArrayType, const IPosition &shape)
casacore::RecordDescRep::isStrictSubset
Bool isStrictSubset(const RecordDescRep &other, Bool &equalDataTypes) const
Test if this description is a strict subset of another one, thus if it is a subset and not equal.
casacore::RecordDescRep::nfields
uInt nfields() const
Number of fields in the description.
Definition: RecordDescRep.h:297
casacore::RecordDescRep::operator=
RecordDescRep & operator=(const RecordDescRep &other)
Replace this description with other.
casacore::RecordDescRep::isSubset
Bool isSubset(const RecordDescRep &other, Bool &equalDataTypes) const
Test if this description is a subset of another one.
casacore::RecordDescRep::conform
Bool conform(const RecordDescRep &other) const
Test if this description conforms the other.
casacore::RecordDescRep::operator==
Bool operator==(const RecordDescRep &other) const
This and other compare equal if the field types and shapes are identical (recursively if there are de...
casacore::RecordDescRep::types_p
Block< Int > types_p
The DataType of each field.
Definition: RecordDescRep.h:277
casacore::RecordDescRep::copy_other
void copy_other(const RecordDescRep &other)
casacore::RecordDescRep::addTable
uInt addTable(const String &fieldName, const String &tableDescName)
Add a Table field to the description.
casacore::uInt
unsigned int uInt
Definition: aipstype.h:51
casacore::RecordDescRep::addArray
uInt addArray(const String &fieldName, DataType scalarOrArrayType, const IPosition &shape)
Add an array field of the indicated type.
casacore::RecordDescRep::addFieldAny
void addFieldAny(DataType scalarOrArrayType)
Add the field info.
casacore::RecordDescRep::is_array_p
Block< Bool > is_array_p
True if the corresponding field is an array.
Definition: RecordDescRep.h:288
casacore::RecordDescRep::makeName
String makeName(Int whichField) const
Create a name for a field defined by index as *i (similar to glish).
casacore::RecordDescRep::~RecordDescRep
virtual ~RecordDescRep()
casacore::RecordDescRep::isSubRecord
Bool isSubRecord(Int whichField) const
Returns True if whichField is a sub-record.
Definition: RecordDescRep.h:327
casacore::RecordDescRep::isEqual
Bool isEqual(const RecordDescRep &other, Bool &equalDataTypes) const
Test if this description equals another one.
casacore::RecordDescRep::name_map_p
std::map< String, Int > name_map_p
Mapping of field name to field number.
Definition: RecordDescRep.h:294
casacore::RecordDescRep::shapes_p
Block< IPosition > shapes_p
The shape of the field [1] for scalars and sub-records.
Definition: RecordDescRep.h:286
casacore::RecordDescRep::tableDescNames_p
Block< String > tableDescNames_p
Table description name for table fields.
Definition: RecordDescRep.h:290
casacore::RecordDescRep::isDisjoint
Bool isDisjoint(const RecordDescRep &other) const
Test if the set of field names in this and other record description is disjoint (i....
casacore::RecordDescRep::subRecord
const RecordDesc & subRecord(Int whichField) const
If whichField is a sub-record with a description, return its description.
Definition: RecordDescRep.h:337
casacore::Int
int Int
Definition: aipstype.h:50
casacore
this file contains all the compiler specific defines
Definition: mainpage.dox:28
casacore::RecordDescRep::mergeField
uInt mergeField(const RecordDescRep &other, Int whichFieldFromOther, int duplicateAction)
Merge a single field from other.
casacore::RecordDescRep::setShape
void setShape(Int whichField, const IPosition &shape)
Set the shape for this field.
casacore::RecordDescRep::shape
const IPosition & shape(Int whichField) const
What is the shape of the given field.
Definition: RecordDescRep.h:312
casacore::RecordDescRep::isScalar
Bool isScalar(Int whichField) const
Returns True if whichField is a scalar.
Definition: RecordDescRep.h:322
casacore::RecordDescRep::name
const String & name(Int whichField) const
What is the name of the given field.
Definition: RecordDescRep.h:307
casacore::RecordDescRep::sub_records_p
PtrBlock< RecordDesc * > sub_records_p
The description of the subrecords.
Definition: RecordDescRep.h:284
casacore::RecordDescRep::isTable
Bool isTable(Int whichField) const
Returns True if whichField is a table.
Definition: RecordDescRep.h:332
casacore::RecordDescRep::removeField
virtual uInt removeField(Int whichField)
Remove the given field from the description.
casacore::String
String: the storage and methods of handling collections of characters.
Definition: String.h:223
casacore::Bool
bool Bool
Define the standard types used by Casacore.
Definition: aipstype.h:42
casacore::Block< Int >
casacore::RecordDescRep::addRepField
virtual void addRepField(const RecordDescRep &other, const String &newName, Int whichField)
Add a field from another Record description.
casacore::RecordDescRep::comments_p
Block< String > comments_p
Comments for each field.
Definition: RecordDescRep.h:292
casacore::RecordDescRep
Representation of a RecordDesc.
Definition: RecordDescRep.h:91
casacore::RecordDescRep::addFieldName
void addFieldName(const String &fieldName, DataType type)
Add a field name and its type.
casacore::RecordDescRep::n_p
uInt n_p
Number of fields in the description.
Definition: RecordDescRep.h:275
casacore::RecordDescRep::allExist
Bool allExist(const RecordDescRep &, Bool &equalDataTypes) const
Test if all fields are part of the other description.
casacore::RecordDescRep::merge
uInt merge(const RecordDescRep &other, int duplicateAction)
Add all the fields from another RecordDescRep to the current objects.
casacore::RecordDescRep::operator!=
Bool operator!=(const RecordDescRep &other) const
casacore::RecordDescRep::uniqueName
String uniqueName(const String &name) const
Make the given name unique by adding a suffix _j when needed.
casacore::RecordDescRep::type
DataType type(Int whichField) const
What is the type of the given field.
Definition: RecordDescRep.h:302