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.
96 
97  // Create a description which is a copy of other.
98  RecordDescRep (const RecordDescRep& other);
99 
100  // Replace this description with 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.
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
A drop-in replacement for Block<T*>.
Definition: Block.h:814
String uniqueName(const String &name) const
Make the given name unique by adding a suffix _j when needed.
Bool isDisjoint(const RecordDescRep &other) const
Test if the set of field names in this and other record description is disjoint (i....
const RecordDesc & subRecord(Int whichField) const
If whichField is a sub-record with a description, return its description.
uInt addArray(const String &fieldName, DataType scalarOrArrayType, const IPosition &shape)
Add an array field of the indicated type.
Bool isArray(Int whichField) const
Returns True if whichField is an array.
uInt addRecord(const String &fieldName, const RecordDesc &subDesc)
Add a Record field to the description.
RecordDescRep & operator=(const RecordDescRep &other)
Replace this description with other.
virtual uInt removeField(Int whichField)
Remove the given field from the description.
void setComment(Int whichField, const String &comment)
Set the comment for this field.
void addFieldArray(DataType scalarOrArrayType, const IPosition &shape)
Block< String > tableDescNames_p
Table description name for table fields.
uInt mergeField(const RecordDescRep &other, Int whichFieldFromOther, int duplicateAction)
Merge a single field from other.
Bool isEqual(const RecordDescRep &other, Bool &equalDataTypes) const
Test if this description equals another one.
RecordDescRep(const RecordDescRep &other)
Create a description which is a copy of other.
uInt n_p
Number of fields in the description.
Bool operator==(const RecordDescRep &other) const
This and other compare equal if the field types and shapes are identical (recursively if there are de...
Bool isSubset(const RecordDescRep &other, Bool &equalDataTypes) const
Test if this description is a subset of another one.
Bool allExist(const RecordDescRep &, Bool &equalDataTypes) const
Test if all fields are part of the other description.
const IPosition & shape(Int whichField) const
What is the shape of the given field.
Block< String > names_p
The name of each field.
void setShape(Int whichField, const IPosition &shape)
Set the shape for this field.
std::map< String, Int > name_map_p
Mapping of field name to field number.
void addFieldName(const String &fieldName, DataType type)
Add a field name and its type.
void setShape(const IPosition &shape, Int whichField)
Set the shape (for a derived class).
Block< String > comments_p
Comments for each field.
uInt addField(const String &fieldName, DataType scalarOrArrayType)
Add scalar or array field.
const String & name(Int whichField) const
What is the name of the given field.
Int fieldNumber(const String &fieldName) const
Returns the index of the field named fieldName.
virtual void addRepField(const RecordDescRep &other, const String &newName, Int whichField)
Add a field from another Record description.
String makeName(Int whichField) const
Create a name for a field defined by index as *i (similar to glish).
Bool operator!=(const RecordDescRep &other) const
virtual void renameField(const String &newName, Int whichField)
Rename the given field.
Bool isScalar(Int whichField) const
Returns True if whichField is a scalar.
const String & tableDescName(Int whichField) const
What is the name of the table description associated with a table.
uInt merge(const RecordDescRep &other, int duplicateAction)
Add all the fields from another RecordDescRep to the current objects.
uInt nfields() const
Number of fields in the description.
Bool isTable(Int whichField) const
Returns True if whichField is a table.
Block< Int > types_p
The DataType of each field.
Bool isSubRecord(Int whichField) const
Returns True if whichField is a sub-record.
RecordDesc & subRecord(Int whichField)
const String & comment(Int whichField) const
Get the comment for this field.
RecordDescRep()
Create a description with no fields.
uInt addTable(const String &fieldName, const String &tableDescName)
Add a Table field to the description.
void copy_other(const RecordDescRep &other)
Bool conform(const RecordDescRep &other) const
Test if this description conforms the other.
virtual void increment_length()
Helper functions.
void addFieldAny(DataType scalarOrArrayType)
Add the field info.
Block< IPosition > shapes_p
The shape of the field [1] for scalars and sub-records.
PtrBlock< RecordDesc * > sub_records_p
The description of the subrecords.
Block< Bool > is_array_p
True if the corresponding field is an array.
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.
DataType type(Int whichField) const
What is the type of the given field.
const RecordDesc & subRecord(Int whichField) const
If whichField is a sub-record return its description.
Definition: RecordDesc.h:447
String: the storage and methods of handling collections of characters.
Definition: String.h:225
this file contains all the compiler specific defines
Definition: mainpage.dox:28
unsigned int uInt
Definition: aipstype.h:51
int Int
Definition: aipstype.h:50
bool Bool
Define the standard types used by Casacore.
Definition: aipstype.h:42