File: ColDescSet.cc

package info (click to toggle)
casacore 3.5.0-2
  • links: PTS, VCS
  • area: main
  • in suites: bookworm
  • size: 51,680 kB
  • sloc: cpp: 462,815; fortran: 16,372; ansic: 7,403; yacc: 4,626; lex: 2,340; sh: 1,786; python: 629; perl: 531; sed: 499; csh: 34; makefile: 31
file content (298 lines) | stat: -rw-r--r-- 8,678 bytes parent folder | download | duplicates (2)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
//# ColDescSet.cc: This class defines a set of column descriptions
//# Copyright (C) 1994,1995,1996,1997,2000,2001
//# Associated Universities, Inc. Washington DC, USA.
//#
//# This library is free software; you can redistribute it and/or modify it
//# under the terms of the GNU Library General Public License as published by
//# the Free Software Foundation; either version 2 of the License, or (at your
//# option) any later version.
//#
//# This library is distributed in the hope that it will be useful, but WITHOUT
//# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
//# FITNESS FOR A PARTICULAR PURPOSE.  See the GNU Library General Public
//# License for more details.
//#
//# You should have received a copy of the GNU Library General Public License
//# along with this library; if not, write to the Free Software Foundation,
//# Inc., 675 Massachusetts Ave, Cambridge, MA 02139, USA.
//#
//# Correspondence concerning AIPS++ should be addressed as follows:
//#        Internet email: aips2-request@nrao.edu.
//#        Postal address: AIPS++ Project Office
//#                        National Radio Astronomy Observatory
//#                        520 Edgemont Road
//#                        Charlottesville, VA 22903-2475 USA
//#
//# $Id$

#include <casacore/tables/Tables/ColDescSet.h>
#include <casacore/tables/Tables/TableDesc.h>
#include <casacore/tables/DataMan/DataManager.h>
#include <casacore/tables/Tables/TableError.h>
#include <casacore/casa/iostream.h>


namespace casacore { //# NAMESPACE CASACORE - BEGIN


ColumnDescSet::ColumnDescSet()
  : colSeq_p (0)
{
}

ColumnDescSet::ColumnDescSet (const ColumnDescSet& that)
  : colSeq_p (0)
    { operator= (that); }


ColumnDescSet::~ColumnDescSet()
{}


ColumnDescSet& ColumnDescSet::operator= (const ColumnDescSet& that)
{
    if (this != &that) {
	uInt nrcol = that.cols_p.size();
	colSeq_p.resize (nrcol);
        cols_p.clear();
	//# Now we have to fill in the column order, which is the
	//# same as the order in the source.
	//# Make a copy of the ColumnDesc object and keep a pointer to it.
        for (uInt i=0; i<nrcol; ++i) {
	    const String& colName = that[i].name();
            CountedPtr<ColumnDesc> col = that.cols_p.at(colName);
            cols_p.insert (std::make_pair (colName,
                                           CountedPtr<ColumnDesc>(new ColumnDesc(*col))));
	    colSeq_p[i] = cols_p.at(colName).get();
	}
    }
    return *this;
}


ColumnDesc& ColumnDescSet::operator[] (const String& name)
{
    // Throw an exception if the column is undefined.
    std::map<String,CountedPtr<ColumnDesc>>::iterator iter = cols_p.find (name);
    if (iter == cols_p.end()) {
	throw (TableError ("Table column " + name + " is unknown"));
    }
    return *(iter->second);
}


//# Add a column to the set with another name.
ColumnDesc& ColumnDescSet::addColumn (const ColumnDesc& cd,
				      const String& newname)
{
    //# First make a copy to be able to change the name.
    ColumnDesc coldes (cd);
    coldes.setName (newname);
    return addColumn (coldes);
}

//# Add a column to the set.
ColumnDesc& ColumnDescSet::addColumn (const ColumnDesc& cd)
{
    //# First check if the column name already exists.
    if (isDefined (cd.name())) {
	throw (TableInvColumnDesc (cd.name(), "column already exists"));
    }
    cd.checkAdd (*this);
    cols_p.insert (std::make_pair(cd.name(), CountedPtr<ColumnDesc>(new ColumnDesc(cd))));
    //# Get actual column description object.
    ColumnDesc& coldes = *(cols_p.at(cd.name()));
    //# Add the new column to the sequence block.
    uInt nrcol = ncolumn();
    if (nrcol > colSeq_p.nelements()) {
	colSeq_p.resize (nrcol + 63);
    }
    colSeq_p[nrcol-1] = &coldes;
    coldes.handleAdd (*this);
    return coldes;
}


//# Remove a column.
//# Let the column first act upon its removal.
void ColumnDescSet::remove (const String& name)
{
    ColumnDesc& cd = (*this)[name];
    cd.handleRemove (*this);
    //# Remove it first from the sequence block.
    uInt nrcol = ncolumn();
    for (uInt i=0; i<nrcol; i++) {
	if (colSeq_p[i] == &cd) {
	    for (; i<nrcol-1; i++) {
		colSeq_p[i] = colSeq_p[i+1];
	    }
            break;
	}
    }
    //# Now really remove the column.
    cols_p.erase (name);
}

//# Rename a column in the set.
//# Let all columns act upon the rename (in case they refer to the old name).
void ColumnDescSet::rename (const String& newname, const String& oldname)
{
    if (! isDefined(oldname)) {
        throw (AipsError ("TableDesc::renameColumn - old name " + oldname +
			  " does not exist"));
    }
    if (isDefined(newname)) {
        throw (AipsError ("TableDesc::renameColumn - new name " + newname +
			  " already exists"));
    }
    // Find the entry in the colSeq_p list, so it can be updated.
    uInt inx;
    for (inx=0; inx<colSeq_p.size(); ++inx) {
      if (static_cast<ColumnDesc*>(colSeq_p[inx])->name() == oldname) {
        break;
      }
    }
    AlwaysAssert (inx < colSeq_p.size(), AipsError);
    CountedPtr<ColumnDesc> cdesc = cols_p.at(oldname);
    cdesc->checkRename (*this, newname);
    cols_p.erase (oldname);
    cols_p.insert (std::make_pair(newname, cdesc));
    ColumnDesc& cd = *(cols_p.at(newname));
    colSeq_p[inx] = &cd;
    //# Actually rename in BaseColDesc object.
    cd.setName (newname);
    //# Handle rename for other things.
    cd.handleRename (*this, oldname);
    for (auto& x : cols_p) {
	x.second->renameAction (newname, oldname);
    }
}


//# Check recursevily if the descriptions of all subtables are known.
void ColumnDescSet::checkSubTableDesc() const
{
    uInt nrcol = ncolumn();
    for (uInt i=0; i<nrcol; i++) {
	const ColumnDesc& cd = (*this)[i];
	if (cd.dataType() == TpTable) {
	    const TableDesc* tdp = cd.tableDesc();  // throws if unknown desc.
	    tdp->checkSubTableDesc();               // check recursively
	}
    }
}


Bool ColumnDescSet::isEqual (const ColumnDescSet& other,
			     Bool& equalDataTypes) const
{
    equalDataTypes = False;
    if (ncolumn() != other.ncolumn()) {
	return False;
    }
    return allExist (other, equalDataTypes);
}

Bool ColumnDescSet::isSubset (const ColumnDescSet& other,
			      Bool& equalDataTypes) const
{
    equalDataTypes = False;
    if (ncolumn() > other.ncolumn()) {
	return False;
    }
    return allExist (other, equalDataTypes);
}

Bool ColumnDescSet::isStrictSubset (const ColumnDescSet& other,
				    Bool& equalDataTypes) const
{
    equalDataTypes = False;
    if (ncolumn() >= other.ncolumn()) {
	return False;
    }
    return allExist (other, equalDataTypes);
}

Bool ColumnDescSet::allExist (const ColumnDescSet& other,
			      Bool& equalDataTypes) const
{
    equalDataTypes = True;
    uInt nrcol = ncolumn();
    for (uInt i=0; i<nrcol; i++) {
	const ColumnDesc& thisCol = (*this)[i];
	if (! other.isDefined (thisCol.name())) {
	    return False;                     // name does not exist in other
	}
	if (thisCol.dataType() != other[thisCol.name()].dataType()) {
	    equalDataTypes = False;           // unequal data type
	}
    }
    return True;                              // names are equal
}

Bool ColumnDescSet::isDisjoint (const ColumnDescSet& other) const
{
    uInt nrcol = other.ncolumn();
    for (uInt i=0; i<nrcol; i++) {
	if (isDefined (other[i].name())) {
	    return False;                     //# name exists in other
	}
    }
    return True;
}


//# Add another column set.
//# Duplicates are not allowed, because renaming or skipping them
//# may disturb the virtual columns referencing others.
//# Add each column in its turn.
void ColumnDescSet::add (const ColumnDescSet& set)
{
    //# First check if duplicates exist, otherwise we may end
    //# up with adding only part of the other set.
    if (! isDisjoint (set)) {
	throw (TableError ("ColumnDescSet::add; column sets not disjoint"));
    }
    uInt nrcol = set.ncolumn();
    for (uInt i=0; i<nrcol; i++) {
	addColumn (set[i]);
    }
}


//# Put the object.
void ColumnDescSet::putFile (AipsIO& ios, const TableAttr& parentAttr) const
{
    uInt nrcol = ncolumn();
    ios << nrcol;
    for (uInt i=0; i<nrcol; i++) {
	(*this)[i].putFile (ios, parentAttr);
    }
}

//# Get the object.
void ColumnDescSet::getFile (AipsIO& ios, const TableAttr& parentAttr)
{
    //# Clear the entire set.
    *this = ColumnDescSet();
    uInt nrcol;
    ios >> nrcol;
    for (uInt i=0; i<nrcol; i++) {
	ColumnDesc coldes;
	coldes.getFile (ios, parentAttr);
	addColumn (coldes);
    }
}


void ColumnDescSet::show (ostream& os) const
{
    uInt nrcol = ncolumn();
    for (uInt i=0; i<nrcol; i++) {
	os << (*this)[i];
	os << endl;
    }
}

} //# NAMESPACE CASACORE - END