//# RecordInterface.cc: Abstract base class for a hierarchical collection of named fields of various types //# Copyright (C) 1996,1998,1999,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 #include #include #include #include #include namespace casacore { //# NAMESPACE CASACORE - BEGIN RecordInterface::RecordInterface () : checkFunction_p (0), checkArgument_p (0), type_p (Variable) {} RecordInterface::RecordInterface (RecordType type, CheckFieldFunction* funcPtr, const void* checkArgument) : checkFunction_p (funcPtr), checkArgument_p (checkArgument), type_p (type) {} RecordInterface::RecordInterface (const RecordInterface& other) : NoticeSource (), checkFunction_p (other.checkFunction_p), checkArgument_p (other.checkArgument_p), type_p (other.type_p) {} RecordInterface& RecordInterface::operator= (const RecordInterface& other) { checkFunction_p = other.checkFunction_p; checkArgument_p = other.checkArgument_p; type_p = other.type_p; return *this; } RecordInterface::~RecordInterface() { notify (RecordNotice (RecordNotice::DETACH, 0)); } void RecordInterface::throwIfFixed() const { if (isFixed()) { throw (AipsError ("Record cannot be changed (fixed structure)")); } } void RecordInterface::checkName (const String& fieldName, DataType type) const { if (checkFunction_p != 0) { String message; if (! checkFunction_p (fieldName, type, checkArgument_p, message)) { throw (AipsError ("Record field " + fieldName + " cannot be added: " + message)); } } } RecordDesc RecordInterface::description() const { return getDescription(); } Int RecordInterface::newIdToNumber (const RecordFieldId& id) const { if (id.byName()) { return fieldNumber (id.fieldName()); } Int nfield = nfields(); if (id.fieldNumber() > nfield) { throw (AipsError ("RecordInterface::define - " "new fieldNumber exceeds #fields")); } if (id.fieldNumber() == nfield) { return -1; } return id.fieldNumber(); } Int RecordInterface::idToNumber (const RecordFieldId& id) const { if (! id.byName()) { return id.fieldNumber(); } Int whichField = fieldNumber (id.fieldName()); if (whichField < 0) { throw (AipsError ("RecordInterface: field " + id.fieldName() + " is unknown")); } return whichField; } String RecordInterface::name (const RecordFieldId& id) const { return description().name (idToNumber (id)); } IPosition RecordInterface::shape (const RecordFieldId& id) const { Int whichField = idToNumber (id); switch (type (whichField)) { case TpArrayBool: return asArrayBool(whichField).shape(); case TpArrayUChar: return asArrayuChar(whichField).shape(); case TpArrayShort: return asArrayShort(whichField).shape(); case TpArrayInt: return asArrayInt(whichField).shape(); case TpArrayUInt: return asArrayuInt(whichField).shape(); case TpArrayInt64: return asArrayInt64(whichField).shape(); case TpArrayFloat: return asArrayFloat(whichField).shape(); case TpArrayDouble: return asArrayDouble(whichField).shape(); case TpArrayComplex: return asArrayComplex(whichField).shape(); case TpArrayDComplex: return asArrayDComplex(whichField).shape(); case TpArrayString: return asArrayString(whichField).shape(); default: break; } return IPosition (1,1); } void RecordInterface::defineField (const RecordFieldId& id, DataType type, const void* value) { defineField (id, type, IPosition(), False, value); } void RecordInterface::defineField (const RecordFieldId& id, DataType type, const IPosition& shape, Bool fixedShape, const void* value) { Int whichField = newIdToNumber (id); if (whichField < 0) { throwIfFixed(); String name; if (id.byName()) { name = id.fieldName(); }else{ name = description().makeName (id.fieldNumber()); } checkName (name, type); addDataField (name, type, shape, fixedShape, value); }else{ defineDataField (whichField, type, value); } } void RecordInterface::define (const RecordFieldId& id, Bool value) { defineField (id, TpBool, &value); } void RecordInterface::define (const RecordFieldId& id, uChar value) { defineField (id, TpUChar, &value); } void RecordInterface::define (const RecordFieldId& id, Short value) { defineField (id, TpShort, &value); } void RecordInterface::define (const RecordFieldId& id, Int value) { defineField (id, TpInt, &value); } void RecordInterface::define (const RecordFieldId& id, uInt value) { defineField (id, TpUInt, &value); } void RecordInterface::define (const RecordFieldId& id, Int64 value) { defineField (id, TpInt64, &value); } void RecordInterface::define (const RecordFieldId& id, float value) { defineField (id, TpFloat, &value); } void RecordInterface::define (const RecordFieldId& id, double value) { defineField (id, TpDouble, &value); } void RecordInterface::define (const RecordFieldId& id, const Complex& value) { defineField (id, TpComplex, &value); } void RecordInterface::define (const RecordFieldId& id, const DComplex& value) { defineField (id, TpDComplex, &value); } void RecordInterface::define (const RecordFieldId& id, const String& value) { defineField (id, TpString, &value); } void RecordInterface::define (const RecordFieldId& id, const Array& value, Bool fixedShape) { defineField (id, TpArrayBool, value.shape(), fixedShape, &value); } void RecordInterface::define (const RecordFieldId& id, const Array& value, Bool fixedShape) { defineField (id, TpArrayUChar, value.shape(), fixedShape, &value); } void RecordInterface::define (const RecordFieldId& id, const Array& value, Bool fixedShape) { defineField (id, TpArrayShort, value.shape(), fixedShape, &value); } void RecordInterface::define (const RecordFieldId& id, const Array& value, Bool fixedShape) { defineField (id, TpArrayInt, value.shape(), fixedShape, &value); } void RecordInterface::define (const RecordFieldId& id, const Array& value, Bool fixedShape) { defineField (id, TpArrayUInt, value.shape(), fixedShape, &value); } void RecordInterface::define (const RecordFieldId& id, const Array& value, Bool fixedShape) { defineField (id, TpArrayInt64, value.shape(), fixedShape, &value); } void RecordInterface::define (const RecordFieldId& id, const Array& value, Bool fixedShape) { defineField (id, TpArrayFloat, value.shape(), fixedShape, &value); } void RecordInterface::define (const RecordFieldId& id, const Array& value, Bool fixedShape) { defineField (id, TpArrayDouble, value.shape(), fixedShape, &value); } void RecordInterface::define (const RecordFieldId& id, const Array& value, Bool fixedShape) { defineField (id, TpArrayComplex, value.shape(), fixedShape, &value); } void RecordInterface::define (const RecordFieldId& id, const Array& value, Bool fixedShape) { defineField (id, TpArrayDComplex, value.shape(), fixedShape, &value); } void RecordInterface::define (const RecordFieldId& id, const Array& value, Bool fixedShape) { defineField (id, TpArrayString, value.shape(), fixedShape, &value); } void RecordInterface::get (const RecordFieldId& id, Bool& value) const { value = asBool (id); } void RecordInterface::get (const RecordFieldId& id, uChar& value) const { value = asuChar (id); } void RecordInterface::get (const RecordFieldId& id, Short& value) const { value = asShort (id); } void RecordInterface::get (const RecordFieldId& id, Int& value) const { value = asInt (id); } void RecordInterface::get (const RecordFieldId& id, uInt& value) const { value = asuInt (id); } void RecordInterface::get (const RecordFieldId& id, Int64& value) const { value = asInt64 (id); } void RecordInterface::get (const RecordFieldId& id, float& value) const { value = asFloat (id); } void RecordInterface::get (const RecordFieldId& id, double& value) const { value = asDouble (id); } void RecordInterface::get (const RecordFieldId& id, Complex& value) const { value = asComplex (id); } void RecordInterface::get (const RecordFieldId& id, DComplex& value) const { value = asDComplex (id); } void RecordInterface::get (const RecordFieldId& id, String& value) const { value = asString (id); } void RecordInterface::get (const RecordFieldId& id, Array& value) const { Array array = toArrayBool (id); value.resize (array.shape()); value = array; } void RecordInterface::get (const RecordFieldId& id, Array& value) const { Array array = toArrayuChar (id); value.resize (array.shape()); value = array; } void RecordInterface::get (const RecordFieldId& id, Array& value) const { Array array = toArrayShort (id); value.resize (array.shape()); value = array; } void RecordInterface::get (const RecordFieldId& id, Array& value) const { Array array = toArrayInt (id); value.resize (array.shape()); value = array; } void RecordInterface::get (const RecordFieldId& id, Array& value) const { Array array = toArrayuInt (id); value.resize (array.shape()); value = array; } void RecordInterface::get (const RecordFieldId& id, Array& value) const { Array array = toArrayInt64 (id); value.resize (array.shape()); value = array; } void RecordInterface::get (const RecordFieldId& id, Array& value) const { Array array = toArrayFloat (id); value.resize (array.shape()); value = array; } void RecordInterface::get (const RecordFieldId& id, Array& value) const { Array array = toArrayDouble (id); value.resize (array.shape()); value = array; } void RecordInterface::get (const RecordFieldId& id, Array& value) const { Array array = toArrayComplex (id); value.resize (array.shape()); value = array; } void RecordInterface::get (const RecordFieldId& id, Array& value) const { Array array = toArrayDComplex (id); value.resize (array.shape()); value = array; } void RecordInterface::get (const RecordFieldId& id, Array& value) const { Array array = toArrayString (id); value.resize (array.shape()); value = array; } Bool RecordInterface::asBool (const RecordFieldId& id) const { Int whichField = idToNumber (id); DataType dataType = type (whichField); switch (dataType) { case TpBool: break; case TpInt: return *(const Int*)get_pointer (whichField, TpInt); default: throw (AipsError ("RecordInterface::asBool - invalid data type")); } return *(const Bool*)get_pointer (whichField, TpBool); } uChar RecordInterface::asuChar (const RecordFieldId& id) const { Int whichField = idToNumber (id); DataType dataType = type (whichField); switch (dataType) { case TpUChar: break; case TpShort: return *(const Short*)get_pointer (whichField, TpShort); case TpInt: return *(const Int*)get_pointer (whichField, TpInt); case TpUInt: return *(const uInt*)get_pointer (whichField, TpUInt); default: throw (AipsError ("RecordInterface::asuChar - invalid data type")); } return *(const uChar*)get_pointer (whichField, TpUChar); } Short RecordInterface::asShort (const RecordFieldId& id) const { Int whichField = idToNumber (id); DataType dataType = type (whichField); switch (dataType) { case TpUChar: return *(const uChar*)get_pointer (whichField, TpUChar); case TpShort: break; case TpInt: return *(const Int*)get_pointer (whichField, TpInt); case TpUInt: return *(const uInt*)get_pointer (whichField, TpUInt); default: throw (AipsError ("RecordInterface::asShort - invalid data type")); } return *(const Short*)get_pointer (whichField, TpShort); } Int RecordInterface::asInt (const RecordFieldId& id) const { Int whichField = idToNumber (id); DataType dataType = type (whichField); switch (dataType) { case TpUChar: return *(const uChar*)get_pointer (whichField, TpUChar); case TpShort: return *(const Short*)get_pointer (whichField, TpShort); case TpInt: break; case TpUInt: return *(const uInt*)get_pointer (whichField, TpUInt); case TpInt64: return *(const Int64*)get_pointer (whichField, TpInt64); default: throw (AipsError ("RecordInterface::asInt - invalid data type")); } return *(const Int*)get_pointer (whichField, TpInt); } uInt RecordInterface::asuInt (const RecordFieldId& id) const { Int whichField = idToNumber (id); DataType dataType = type (whichField); switch (dataType) { case TpUChar: return *(const uChar*)get_pointer (whichField, TpUChar); case TpShort: return *(const Short*)get_pointer (whichField, TpShort); case TpInt: return *(const Int*)get_pointer (whichField, TpInt); case TpUInt: break; case TpInt64: return *(const Int64*)get_pointer (whichField, TpInt64); default: throw (AipsError ("RecordInterface::asuInt - invalid data type")); } return *(const uInt*)get_pointer (whichField, TpUInt); } Int64 RecordInterface::asInt64 (const RecordFieldId& id) const { Int whichField = idToNumber (id); DataType dataType = type (whichField); switch (dataType) { case TpUChar: return *(const uChar*)get_pointer (whichField, TpUChar); case TpShort: return *(const Short*)get_pointer (whichField, TpShort); case TpInt: return *(const Int*)get_pointer (whichField, TpInt); case TpUInt: return *(const uInt*)get_pointer (whichField, TpUInt); case TpInt64: break; default: throw (AipsError ("RecordInterface::asInt64 - invalid data type")); } return *(const Int64*)get_pointer (whichField, TpInt64); } float RecordInterface::asFloat (const RecordFieldId& id) const { Int whichField = idToNumber (id); DataType dataType = type (whichField); switch (dataType) { case TpUChar: return *(const uChar*)get_pointer (whichField, TpUChar); case TpShort: return *(const Short*)get_pointer (whichField, TpShort); case TpInt: return *(const Int*)get_pointer (whichField, TpInt); case TpUInt: return *(const uInt*)get_pointer (whichField, TpUInt); case TpInt64: return *(const Int64*)get_pointer (whichField, TpInt64); case TpFloat: break; case TpDouble: return *(const double*)get_pointer (whichField, TpDouble); default: throw (AipsError ("RecordInterface::asFloat - invalid data type")); } return *(const float*)get_pointer (whichField, TpFloat); } double RecordInterface::asDouble (const RecordFieldId& id) const { Int whichField = idToNumber (id); DataType dataType = type (whichField); switch (dataType) { case TpUChar: return *(const uChar*)get_pointer (whichField, TpUChar); case TpShort: return *(const Short*)get_pointer (whichField, TpShort); case TpInt: return *(const Int*)get_pointer (whichField, TpInt); case TpUInt: return *(const uInt*)get_pointer (whichField, TpUInt); case TpInt64: return *(const Int64*)get_pointer (whichField, TpInt64); case TpFloat: return *(const float*)get_pointer (whichField, TpFloat); case TpDouble: break; default: throw (AipsError ("RecordInterface::asDouble - invalid data type")); } return *(const double*)get_pointer (whichField, TpDouble); } Complex RecordInterface::asComplex (const RecordFieldId& id) const { Int whichField = idToNumber (id); DataType dataType = type (whichField); switch (dataType) { case TpUChar: return *(const uChar*)get_pointer (whichField, TpUChar); case TpShort: return *(const Short*)get_pointer (whichField, TpShort); case TpInt: return *(const Int*)get_pointer (whichField, TpInt); case TpUInt: return *(const uInt*)get_pointer (whichField, TpUInt); case TpInt64: return *(const Int64*)get_pointer (whichField, TpInt64); case TpFloat: return *(const float*)get_pointer (whichField, TpFloat); case TpDouble: return *(const double*)get_pointer (whichField, TpDouble); case TpComplex: break; case TpDComplex: { DComplex dc = *(const DComplex*)get_pointer (whichField, TpDComplex); return Complex(dc.real(), dc.imag()); } default: throw (AipsError ("RecordInterface::asComplex - invalid data type")); } return *(const Complex*)get_pointer (whichField, TpComplex); } DComplex RecordInterface::asDComplex (const RecordFieldId& id) const { Int whichField = idToNumber (id); DataType dataType = type (whichField); switch (dataType) { case TpUChar: return *(const uChar*)get_pointer (whichField, TpUChar); case TpShort: return *(const Short*)get_pointer (whichField, TpShort); case TpInt: return *(const Int*)get_pointer (whichField, TpInt); case TpUInt: return *(const uInt*)get_pointer (whichField, TpUInt); case TpInt64: return *(const Int64*)get_pointer (whichField, TpInt64); case TpFloat: return *(const float*)get_pointer (whichField, TpFloat); case TpDouble: return *(const double*)get_pointer (whichField, TpDouble); case TpComplex: { const Complex* val = (const Complex*)get_pointer (whichField, TpComplex); return DComplex (val->real(), val->imag()); } case TpDComplex: break; default: throw (AipsError ("RecordInterface::asDComplex - invalid data type")); } return *(const DComplex*)get_pointer (whichField, TpDComplex); } const String& RecordInterface::asString (const RecordFieldId& id) const { Int whichField = idToNumber (id); return *(const String*)get_pointer (whichField, TpString); } const Array& RecordInterface::asArrayBool (const RecordFieldId& id) const { Int whichField = idToNumber (id); return *(const Array*)get_pointer (whichField, TpArrayBool); } const Array& RecordInterface::asArrayuChar (const RecordFieldId& id) const { Int whichField = idToNumber (id); return *(const Array*)get_pointer (whichField, TpArrayUChar); } const Array& RecordInterface::asArrayShort (const RecordFieldId& id) const { Int whichField = idToNumber (id); return *(const Array*)get_pointer (whichField, TpArrayShort); } const Array& RecordInterface::asArrayInt (const RecordFieldId& id) const { Int whichField = idToNumber (id); return *(const Array*)get_pointer (whichField, TpArrayInt); } const Array& RecordInterface::asArrayuInt (const RecordFieldId& id) const { Int whichField = idToNumber (id); return *(const Array*)get_pointer (whichField, TpArrayUInt); } const Array& RecordInterface::asArrayInt64 (const RecordFieldId& id) const { Int whichField = idToNumber (id); return *(const Array*)get_pointer (whichField, TpArrayInt64); } const Array& RecordInterface::asArrayFloat (const RecordFieldId& id) const { Int whichField = idToNumber (id); return *(const Array*)get_pointer (whichField, TpArrayFloat); } const Array& RecordInterface::asArrayDouble (const RecordFieldId& id) const { Int whichField = idToNumber (id); return *(const Array*)get_pointer (whichField, TpArrayDouble); } const Array& RecordInterface::asArrayComplex (const RecordFieldId& id) const { Int whichField = idToNumber (id); return *(const Array*)get_pointer (whichField, TpArrayComplex); } const Array& RecordInterface::asArrayDComplex (const RecordFieldId& id) const { Int whichField = idToNumber (id); return *(const Array*)get_pointer (whichField, TpArrayDComplex); } const Array& RecordInterface::asArrayString (const RecordFieldId& id) const { Int whichField = idToNumber (id); return *(const Array*)get_pointer (whichField, TpArrayString); } RecordNotice::RecordNotice (NoticeType changeType, uInt fieldNumber) : changeType_p (changeType), fieldNumber_p (fieldNumber) {} bool RecordNotice::operator== (const Notice& that) const { if (typeid(*this) != typeid(that)) { return false; } return (changeType_p == ((const RecordNotice&)that).changeType_p) && (fieldNumber_p == ((const RecordNotice&)that).fieldNumber_p); } } //# NAMESPACE CASACORE - END