//# MSMIndColumn.cc: Memory storage manager for variable shaped table arrays //# Copyright (C) 2003 //# 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: MSMIndColumn.cc 20551 2009-03-25 00:11:33Z Malte.Marquarding $ #include #include #include #include #include #include #include #include // for memcpy namespace casacore { //# NAMESPACE CASACORE - BEGIN //# Define a macro which gets the pointer for the given row //# and casts it to the block. #define MSMINDCOLUMN_GETDATA(rownr) \ (static_cast(getArrayPtr(rownr))) MSMIndColumn::MSMIndColumn (MSMBase* smptr, int dataType) : MSMColumn (smptr, dataType, True) {} //# Delete all objects created. MSMIndColumn::~MSMIndColumn() { rownr_t nr = stmanPtr_p->nrow(); for (rownr_t i=0; ishape().isEqual (shape)) { return; } ptr->clear(dataType()); delete ptr; } // Create the array. ptr = new Data (shape, dataType(), elemSize()); putArrayPtr (rownr, ptr); } //# Get the shape for the array (if any) in the given row. //# Read shape if not read yet. MSMIndColumn::Data* MSMIndColumn::getShape (rownr_t rownr) { void* ptr = getArrayPtr(rownr); if (ptr == 0) { throw (DataManInvOper ("MSM: no array in row " + String::toString(rownr) + " in column " + columnName() + " of " + stmanPtr_p->fileName())); } return static_cast(ptr); } Bool MSMIndColumn::isShapeDefined (rownr_t rownr) { return (getArrayPtr(rownr) == 0 ? False : True); } uInt MSMIndColumn::ndim (rownr_t rownr) { return getShape(rownr)->shape().nelements(); } IPosition MSMIndColumn::shape (rownr_t rownr) { return getShape(rownr)->shape(); } Bool MSMIndColumn::canChangeShape() const { return True; } void MSMIndColumn::getArrayV (rownr_t rownr, ArrayBase& arr) { Data* data = getShape(rownr); //# also checks if row contains data DebugAssert (data->shape().isEqual (arr.shape()), AipsError); Bool deleteIt; void* arrData = arr.getVStorage (deleteIt); if (dtype() == TpString) { objcopy (static_cast(arrData), static_cast(data->data()), arr.size()); } else { memcpy (static_cast(arrData), static_cast(data->data()), elemSize() * arr.size()); } arr.putVStorage (arrData, deleteIt); } void MSMIndColumn::putArrayV (rownr_t rownr, const ArrayBase& arr) { Data* data = getShape(rownr); //# also checks if row contains data DebugAssert (shape(rownr).isEqual (arr.shape()), AipsError); Bool deleteIt; const void* arrData = arr.getVStorage (deleteIt); if (dtype() == TpString) { objcopy (static_cast(data->data()), static_cast(arrData), arr.size()); } else { memcpy (static_cast(data->data()), static_cast(arrData), elemSize() * arr.size()); } arr.freeVStorage (arrData, deleteIt); stmanPtr_p->setHasPut(); } void MSMIndColumn::getSliceV (rownr_t rownr, const Slicer& ns, ArrayBase& arr) { Data* data = getShape(rownr); //# also checks if row contains data const IPosition& shp = data->shape(); IPosition blc, trc, inc; ns.inferShapeFromSource (shp, blc, trc, inc); switch (dtype()) { case TpBool: arr.assignBase (Array(shp, static_cast(data->data()), SHARE) (blc, trc, inc), False); break; case TpUChar: arr.assignBase (Array(shp, static_cast(data->data()), SHARE) (blc, trc, inc), False); break; case TpShort: arr.assignBase (Array(shp, static_cast(data->data()), SHARE) (blc, trc, inc), False); break; case TpUShort: arr.assignBase (Array(shp, static_cast(data->data()), SHARE) (blc, trc, inc), False); break; case TpInt: arr.assignBase (Array(shp, static_cast(data->data()), SHARE) (blc, trc, inc), False); break; case TpUInt: arr.assignBase (Array(shp, static_cast(data->data()), SHARE) (blc, trc, inc), False); break; case TpInt64: arr.assignBase (Array(shp, static_cast(data->data()), SHARE) (blc, trc, inc), False); break; case TpFloat: arr.assignBase (Array(shp, static_cast(data->data()), SHARE) (blc, trc, inc), False); break; case TpDouble: arr.assignBase (Array(shp, static_cast(data->data()), SHARE) (blc, trc, inc), False); break; case TpComplex: arr.assignBase (Array(shp, static_cast(data->data()), SHARE) (blc, trc, inc), False); break; case TpDComplex: arr.assignBase (Array(shp, static_cast(data->data()), SHARE) (blc, trc, inc), False); break; case TpString: arr.assignBase (Array(shp, static_cast(data->data()), SHARE) (blc, trc, inc), False); break; default: throw DataManInvDT ("MSMIndColumn::getSliceV"); } } void MSMIndColumn::putSliceV (rownr_t rownr, const Slicer& ns, const ArrayBase& arr) { Data* data = MSMINDCOLUMN_GETDATA(rownr); const IPosition& shp = data->shape(); IPosition blc, trc, inc; ns.inferShapeFromSource (shp, blc, trc, inc); switch (dtype()) { case TpBool: Array(shp, static_cast(data->data()), SHARE) (blc, trc, inc).assignBase (arr, False); break; case TpUChar: Array(shp, static_cast(data->data()), SHARE) (blc, trc, inc).assignBase (arr, False); break; case TpShort: Array(shp, static_cast(data->data()), SHARE) (blc, trc, inc).assignBase (arr, False); break; case TpUShort: Array(shp, static_cast(data->data()), SHARE) (blc, trc, inc).assignBase (arr, False); break; case TpInt: Array(shp, static_cast(data->data()), SHARE) (blc, trc, inc).assignBase (arr, False); break; case TpUInt: Array(shp, static_cast(data->data()), SHARE) (blc, trc, inc).assignBase (arr, False); break; case TpInt64: Array(shp, static_cast(data->data()), SHARE) (blc, trc, inc).assignBase (arr, False); break; case TpFloat: Array(shp, static_cast(data->data()), SHARE) (blc, trc, inc).assignBase (arr, False); break; case TpDouble: Array(shp, static_cast(data->data()), SHARE) (blc, trc, inc).assignBase (arr, False); break; case TpComplex: Array(shp, static_cast(data->data()), SHARE) (blc, trc, inc).assignBase (arr, False); break; case TpDComplex: Array(shp, static_cast(data->data()), SHARE) (blc, trc, inc).assignBase (arr, False); break; case TpString: Array(shp, static_cast(data->data()), SHARE) (blc, trc, inc).assignBase (arr, False); break; default: throw DataManInvDT ("MSMIndColumn::putSliceV"); } stmanPtr_p->setHasPut(); } void MSMIndColumn::remove (rownr_t rownr) { deleteArray (rownr); MSMColumn::remove (rownr); } void MSMIndColumn::deleteArray (rownr_t rownr) { Data* ptr = MSMINDCOLUMN_GETDATA(rownr); // Remove the array for this row (if there). if (ptr != 0) { ptr->clear(dataType()); delete ptr; } } MSMIndColumn::Data::Data (const IPosition& shape, int dtype, int elemSize) : shape_p (shape), data_p (0) { Int64 nelem = shape.product(); if (dtype == TpString) { data_p = new String[nelem]; } else { data_p = new char[nelem * elemSize]; } } MSMIndColumn::Data::~Data() noexcept(false) { if (data_p != 0) { throw DataManInternalError("MSMIndColumn::dtor: data array not deleted"); } } void MSMIndColumn::Data::clear (int dtype) { if (dtype == TpString) { delete [] static_cast(data_p); } else { delete [] static_cast(data_p); } data_p = 0; } } //# NAMESPACE CASACORE - END