casacore
Loading...
Searching...
No Matches
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: casa-feedback@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#ifndef CASA_RECORDDESCREP_H
27#define CASA_RECORDDESCREP_H
28
29// # Includes
30#include <casacore/casa/aips.h>
31#include <casacore/casa/Utilities/DataType.h>
32#include <casacore/casa/Containers/Block.h>
33#include <casacore/casa/Arrays/IPosition.h>
34#include <casacore/casa/iosfwd.h>
35#include <map>
36
37namespace casacore { // # NAMESPACE CASACORE - BEGIN
38
39// # Forward Declarations
40class RecordDesc;
41class AipsIO;
42
43// <summary>
44// Representation of a RecordDesc
45// </summary>
46
47// <use visibility=local>
48// <reviewed reviewer="Mark Wieringa" date="1996/04/15" tests="tRecordDesc">
49// </reviewed>
50
51// <prerequisite>
52// <li> <linkto group="DataType.h#DataType">DataType</linkto>
53// <li> <linkto class="RecordDesc">RecordDesc</linkto>
54// </prerequisite>
55
56// <etymology>
57// Rep is an often used abbreviation for representation.
58// Thus RecordDescRep is the representation of a RecordDesc.
59// </etymology>
60
61// <synopsis>
62// RecordDescRep is used by RecordDesc
63// to implement its copy-on-write semantics. RecordDesc is the interface
64// to the user, while RecordDescRep contains the actual implementation.
65// See <linkto class=RecordDesc>RecordDesc</linkto> for a more detailed
66// description of a record description.
67// </synopsis>
68
69// <example>
70// See the example in the description of the
71// <linkto class="Record:example1">Record</linkto> class.
72// </example>
73
74// <motivation>
75// RecordDescRep is needed to make copy-on-write semantics possible in
76// class RecordDesc.
77// </motivation>
78
79// <todo asof="1995/06/01">
80// <li> Should the strategy wrt. field names be changed (not used in
81// field description equality, must be unique at a given level?).
82// <li> Perhaps we should be able to more conveniently change the description
83// of an existing field.
84// </todo>
85
87 public:
88 // Create a description with no fields.
90
91 // Create a description which is a copy of other.
93
94 // Replace this description with other.
96
97 virtual ~RecordDescRep();
98
99 // Add scalar or array field. If of array type, the shape is set to [-1],
100 // which indicates a variable sized array. Returns the number of fields in
101 // the description.
102 uInt addField(const String& fieldName, DataType scalarOrArrayType);
103
104 // Add an array field of the indicated type. The DataType is promoted
105 // from a scalar type to an array type if necessary, e.g.,
106 // <src>TpInt ->TpArrayInt</src>. Returns the number of fields in
107 // the description.
108 uInt addArray(const String& fieldName, DataType scalarOrArrayType, const IPosition& shape);
109
110 // Add a Record field to the description. This allows hierarchical
111 // descriptions to be developed. Returns the number of fields in the
112 // description.
113 uInt addRecord(const String& fieldName, const RecordDesc& subDesc);
114
115 // Add a Table field to the description. The Table description has the
116 // given name. Returns the number of fields in the description.
117 uInt addTable(const String& fieldName, const String& tableDescName);
118
119 // Get the comment for this field.
120 const String& comment(Int whichField) const;
121
122 // Set the comment for this field.
123 void setComment(Int whichField, const String& comment);
124
125 // Set the shape for this field.
126 // An exception will be thrown if the field is no array.
127 void setShape(Int whichField, const IPosition& shape);
128
129 // Merge a single field from other. If allowDuplicates is True, silently
130 // throw away fields if one with the same name and type already exists,
131 // otherwise an exception is thrown. Conflicting types always cause an
132 // exception. Returns the number of fields in the description.
133 uInt mergeField(const RecordDescRep& other, Int whichFieldFromOther, int duplicateAction);
134
135 // Add all the fields from another RecordDescRep to the current objects.
136 uInt merge(const RecordDescRep& other, int duplicateAction);
137
138 // Remove the given field from the description.
139 virtual uInt removeField(Int whichField);
140
141 // Rename the given field.
142 virtual void renameField(const String& newName, Int whichField);
143
144 // Returns the index of the field named fieldName. Returns -1 if fieldName
145 // does not exist.
146 Int fieldNumber(const String& fieldName) const;
147
148 // Number of fields in the description.
149 uInt nfields() const;
150
151 // What is the type of the given field. Returns TpRecord if the field is
152 // a sub-Record.
153 DataType type(Int whichField) const;
154
155 // What is the name of the given field.
156 const String& name(Int whichField) const;
157
158 // Create a name for a field defined by index as *i (similar to glish).
159 // It takes care that the resulting name is unique by adding a suffix _j
160 // when needed.
161 String makeName(Int whichField) const;
162
163 // Make the given name unique by adding a suffix _j when needed.
164 // j is the minimal number needed to make it unique.
166
167 // Returns True if whichField is an array.
168 Bool isArray(Int whichField) const;
169
170 // Returns True if whichField is a scalar.
171 Bool isScalar(Int whichField) const;
172
173 // Returns True if whichField is a sub-record.
174 Bool isSubRecord(Int whichField) const;
175
176 // Returns True if whichField is a table.
177 Bool isTable(Int whichField) const;
178
179 // What is the shape of the given field. Returns [1] if the field is a
180 // scalar, table or, sub-record, [-1] if it is a variable length array,
181 // and the actual shape for a fixed length array.
182 const IPosition& shape(Int whichField) const;
183
184 // What is the name of the table description associated with a table.
185 const String& tableDescName(Int whichField) const;
186
187 // If whichField is a sub-record with a description,
188 // return its description. Otherwise an exception is thrown.
189 // <group>
190 const RecordDesc& subRecord(Int whichField) const;
192 // </group>
193
194 // <group>
195 // This and other compare equal if the field types and shapes are identical
196 // (recursively if there are described sub-records or tables).
197 // The field names are not used.
198 Bool operator==(const RecordDescRep& other) const;
199 Bool operator!=(const RecordDescRep& other) const;
200 // </group>
201
202 // Test if this description conforms the other.
203 // It is similar to operator==. However, a subrecord in that description
204 // always conforms an arbitrary (i.e. empty) subrecord in this
205 // description.
206 // <br>This is used by Record, to see if another record can be assigned
207 // to this record.
208 Bool conform(const RecordDescRep& other) const;
209
210 // Test if this description equals another one.
211 // It is equal if the number of fields is equal and all field names in
212 // this description occur in the other too. The order of the fields
213 // is not important.
214 // <br>The flag equalDataTypes is set to True if the data types
215 // of all fields match.
216 // <br>Use function operator== if order and types are important,
217 // but names are not.
218 Bool isEqual(const RecordDescRep& other, Bool& equalDataTypes) const;
219
220 // Test if this description is a subset of another one.
221 // It is similar to isEqual above.
222 Bool isSubset(const RecordDescRep& other, Bool& equalDataTypes) const;
223
224 // Test if this description is a strict subset of another one, thus
225 // if it is a subset and not equal.
226 Bool isStrictSubset(const RecordDescRep& other, Bool& equalDataTypes) const;
227
228 // Test if the set of field names in this and other record description
229 // is disjoint (i.e. if they do not share names).
230 Bool isDisjoint(const RecordDescRep& other) const;
231
232 protected:
233 // Add a field name and its type.
234 // It checks if the name is unique and it extends the various blocks
235 // using increment_length.
236 void addFieldName(const String& fieldName, DataType type);
237
238 // Add a field from another Record description.
239 // This is used by the merge functions.
240 virtual void addRepField(const RecordDescRep& other, const String& newName, Int whichField);
241
242 // Add the field info. These are helper functions for the add functions
243 // and can be used in derived classes too.
244 // <group>
245 void addFieldAny(DataType scalarOrArrayType);
246 void addFieldArray(DataType scalarOrArrayType, const IPosition& shape);
247 // </group>
248
249 // Set the shape (for a derived class).
250 void setShape(const IPosition& shape, Int whichField);
251
252 // Helper functions
253 // <group>
254 virtual void increment_length();
255 void copy_other(const RecordDescRep& other);
256 // </group>
257
258 private:
259 // Test if all fields are part of the other description.
260 // The flag equalDataTypes is set to True if the data types of the
261 // fields in both descriptions are the same.
262 Bool allExist(const RecordDescRep&, Bool& equalDataTypes) const;
263
264 // Number of fields in the description.
266 // The DataType of each field.
268 // The name of each field.
270 // The description of the subrecords. Null if the field is not a subrecord.
271 // This isn't the most efficient representation. If this is ever an issue
272 // we could calculate these, or store them in one Block, or implement
273 // copy-on-write semantics.
275 // The shape of the field [1] for scalars and sub-records.
277 // True if the corresponding field is an array.
279 // Table description name for table fields.
281 // Comments for each field.
283 // Mapping of field name to field number.
284 std::map<String, Int> name_map_p;
285};
286
287inline uInt RecordDescRep::nfields() const { return n_p; }
288
289inline DataType RecordDescRep::type(Int whichField) const { return DataType(types_p[whichField]); }
290
291inline const String& RecordDescRep::name(Int whichField) const { return names_p[whichField]; }
292
293inline const IPosition& RecordDescRep::shape(Int whichField) const { return shapes_p[whichField]; }
294
295inline Bool RecordDescRep::isArray(Int whichField) const { return is_array_p[whichField]; }
296
297inline Bool RecordDescRep::isScalar(Int whichField) const {
298 return isScalarFun(DataType(types_p[whichField]));
299}
300
301inline Bool RecordDescRep::isSubRecord(Int whichField) const {
302 return (types_p[whichField] == TpRecord);
303}
304
305inline Bool RecordDescRep::isTable(Int whichField) const {
306 return (types_p[whichField] == TpTable);
307}
308
309inline const RecordDesc& RecordDescRep::subRecord(Int whichField) const {
310 // # The cast to non-const is completely safe.
311 return ((RecordDescRep*)this)->subRecord(whichField);
312}
313
314inline const String& RecordDescRep::tableDescName(Int whichField) const {
315 return tableDescNames_p[whichField];
316}
317
318} // namespace casacore
319
320#endif
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.
RecordDesc & subRecord(Int whichField)
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.
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.
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.
Block< RecordDesc * > sub_records_p
The description of the subrecords.
uInt addField(const String &fieldName, DataType scalarOrArrayType)
Add scalar or array field.
std::map< String, Int > name_map_p
Mapping of field name to field number.
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.
RecordDescRep & operator=(const RecordDescRep &other)
Replace this description with other.
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.
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.
const String & comment(Int whichField) const
Get the comment for this field.
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:390
String: the storage and methods of handling collections of characters.
Definition String.h:355
For temporary backward namespace compatibility, use casa as alias for casacore.
Definition mainpage.dox:28
unsigned int uInt
Definition aipstype.h:49
String name() const
Return the name of the field.
int Int
Definition aipstype.h:48
bool Bool
Define the standard types used by Casacore.
Definition aipstype.h:40