30#include "NDimensionalArray.h"
31#include <libdap/util.h>
33#include <libdap/Byte.h>
34#include <libdap/Int16.h>
35#include <libdap/UInt16.h>
36#include <libdap/Int32.h>
37#include <libdap/UInt32.h>
38#include <libdap/Float32.h>
39#include <libdap/Float64.h>
45#define BESDEBUG( x, y )
50string NDimensionalArray::vectorToIndices(vector<unsigned int> *v)
53 for (
unsigned int i = 0; i < v->size(); i++) {
54 s <<
"[" << (*v)[i] <<
"]";
60NDimensionalArray::NDimensionalArray()
61:_dapType(dods_null_c),_shape(0),_currentLastDimensionSlabIndex(0),_totalValueCount(0),_sizeOfValue(0),_storage(0) {
63 string msg =
"NDimArray::NDimArray() - INTERNAL_ERROR: This is the private constructor and should never be used";
64 BESDEBUG(NDimensionalArray_debug_key, msg << endl);
65 throw libdap::InternalErr(__FILE__, __LINE__, msg);
69NDimensionalArray::NDimensionalArray(libdap::Array *a) :
70 _dapType(dods_null_c), _shape(0), _currentLastDimensionSlabIndex(0), _totalValueCount(0), _sizeOfValue(0), _storage(
73 BESDEBUG(NDimensionalArray_debug_key,
"NDimensionalArray::NDimensionalArray(libdap::Array *) - BEGIN"<< endl);
76 _totalValueCount = computeConstrainedShape(a, _shape);
77 BESDEBUG(NDimensionalArray_debug_key,
78 "NDimensionalArray::NDimensionalArray() - _shape" <<vectorToIndices(_shape) << endl);
79 _dapType = a->var()->type();
80 BESDEBUG(NDimensionalArray_debug_key,
81 "NDimensionalArray::NDimensionalArray() - Total Value Count: " << _totalValueCount <<
" element(s) of type '"<< libdap::type_name(_dapType) <<
"'" << endl);
83 allocateStorage(_totalValueCount, _dapType);
84 BESDEBUG(NDimensionalArray_debug_key,
"NDimensionalArray::NDimensionalArray(libdap::Array *) - END"<< endl);
87NDimensionalArray::NDimensionalArray(std::vector<unsigned int> *shape, libdap::Type dapType) :
88 _dapType(dods_null_c), _shape(0), _currentLastDimensionSlabIndex(0), _totalValueCount(0), _sizeOfValue(0), _storage(
91 BESDEBUG(NDimensionalArray_debug_key,
92 "NDimensionalArray::NDimensionalArray(std::vector<unsigned int> *, libdap::Type) - BEGIN"<< endl);
95 _totalValueCount = computeArraySizeFromShapeVector(_shape);
97 BESDEBUG(NDimensionalArray_debug_key,
98 "NDimensionalArray::NDimensionalArray() - _shape" <<vectorToIndices(_shape) << endl);
99 BESDEBUG(NDimensionalArray_debug_key,
100 "NDimensionalArray::NDimensionalArray() - Total Value Count: " << _totalValueCount <<
" element(s) of type '"<< libdap::type_name(_dapType) <<
"'" << endl);
101 allocateStorage(_totalValueCount, _dapType);
102 BESDEBUG(NDimensionalArray_debug_key,
103 "NDimensionalArray::NDimensionalArray(std::vector<unsigned int> *, libdap::Type) - END"<< endl);
107NDimensionalArray::~NDimensionalArray()
109 delete[] (
char *) _storage;
133 BESDEBUG(NDimensionalArray_debug_key,
"NDimensionalArray::computeConstrainedShape() - BEGIN." << endl);
135 libdap::Array::Dim_iter dIt;
140 unsigned int dimSize = 1;
144 BESDEBUG(NDimensionalArray_debug_key,
145 "NDimensionalArray::computeConstrainedShape() - Array has " << a->dimensions(
true) <<
" dimensions."<< endl);
149 for (dIt = a->dim_begin(); dIt != a->dim_end(); dIt++) {
150 BESDEBUG(NDimensionalArray_debug_key,
151 "NDimensionalArray::computeConstrainedShape() - Processing dimension '" << a->dimension_name(dIt)<<
"'. (dim# "<< dimNum <<
")"<< endl);
152 start = a->dimension_start(dIt,
true);
153 stride = a->dimension_stride(dIt,
true);
154 stop = a->dimension_stop(dIt,
true);
155 BESDEBUG(NDimensionalArray_debug_key,
156 "NDimensionalArray::computeConstrainedShape() - start: " << start <<
" stride: " << stride <<
" stop: "<<stop<< endl);
158 dimSize = 1 + ((stop - start) / stride);
159 BESDEBUG(NDimensionalArray_debug_key,
160 "NDimensionalArray::computeConstrainedShape() - dimSize: " << dimSize << endl);
162 (*shape)[dimNum++] = dimSize;
163 totalSize *= dimSize;
165 BESDEBUG(NDimensionalArray_debug_key,
166 "NDimensionalArray::computeConstrainedShape() - totalSize: " << totalSize << endl);
167 BESDEBUG(NDimensionalArray_debug_key,
"NDimensionalArray::computeConstrainedShape() - END." << endl);
172void NDimensionalArray::retrieveLastDimHyperSlabLocationFromConstrainedArrray(libdap::Array *a,
175 BESDEBUG(NDimensionalArray_debug_key,
176 "NDimensionalArray::retrieveLastDimHyperSlabLocationFromConstrainedArrray() - BEGIN." << endl);
178 libdap::Array::Dim_iter dIt;
179 libdap::Array::Dim_iter next_dIt;
186 BESDEBUG(NDimensionalArray_debug_key,
187 "NDimensionalArray::retrieveLastDimHyperSlabLocationFromConstrainedArrray() - Array has " << a->dimensions(
true) <<
" dimensions."<< endl);
191 for (dIt = a->dim_begin(); dIt != a->dim_end(); dIt++) {
195 BESDEBUG(NDimensionalArray_debug_key,
196 "NDimensionalArray::retrieveLastDimHyperSlabLocationFromConstrainedArrray() - Processing dimension '" << a->dimension_name(dIt)<<
"'. (dim# "<< dimNum <<
")"<< endl);
197 start = a->dimension_start(dIt,
true);
198 stride = a->dimension_stride(dIt,
true);
199 stop = a->dimension_stop(dIt,
true);
200 BESDEBUG(NDimensionalArray_debug_key,
201 "NDimensionalArray::retrieveLastDimHyperSlabLocationFromConstrainedArrray() - start: " << start <<
" stride: " << stride <<
" stop: "<<stop<< endl);
203 if (next_dIt != a->dim_end() && start != stop && stride != 1) {
204 msg <<
"retrieveLastDimHyperSlabLocationFromConstrainedArrray() - The array '" << a->name()
205 <<
"' has not been constrained to a last dimension hyperslab.";
206 BESDEBUG(NDimensionalArray_debug_key, msg.str() << endl);
207 throw Error(msg.str());
210 if (next_dIt == a->dim_end()) {
211 if (start != 0 || stride != 1 || stop != ((
unsigned int) a->dimension_size(dIt) - 1)) {
212 msg <<
"retrieveLastDimHyperSlabLocationFromConstrainedArrray() - The array '" << a->name()
213 <<
"' has not been constrained to a last dimension hyperslab.";
214 BESDEBUG(NDimensionalArray_debug_key, msg.str() << endl);
215 throw Error(msg.str());
219 BESDEBUG(NDimensionalArray_debug_key,
220 "NDimensionalArray::retrieveLastDimHyperSlabLocationFromConstrainedArrray() - location"<< vectorToIndices(location) << endl);
221 BESDEBUG(NDimensionalArray_debug_key,
222 "NDimensionalArray::retrieveLastDimHyperSlabLocationFromConstrainedArrray() - END." << endl);
226 BESDEBUG(NDimensionalArray_debug_key,
227 "NDimensionalArray::retrieveLastDimHyperSlabLocationFromConstrainedArrray() - Adding location "<< start <<
" to dimension " << location->size() << endl);
229 location->push_back(start);
233 <<
"retrieveLastDimHyperSlabLocationFromConstrainedArrray() - Method Failure - this line should never be reached.";
234 BESDEBUG(NDimensionalArray_debug_key, msg.str() << endl);
235 throw Error(msg.str());
246 for (
unsigned int i = 0; i < shape->size(); i++) {
247 totalSize *= (*shape)[i];
256void NDimensionalArray::allocateStorage(
long numValues,
Type dapType)
259 BESDEBUG(NDimensionalArray_debug_key,
260 "NDimensionalArray::allocateStorage() - Allocating memory for " << numValues <<
" element(s) of type '"<< libdap::type_name(dapType) <<
"'" << endl);
264 _sizeOfValue =
sizeof(dods_byte);
267 _sizeOfValue =
sizeof(dods_int16);
270 _sizeOfValue =
sizeof(dods_uint16);
273 _sizeOfValue =
sizeof(dods_int32);
276 _sizeOfValue =
sizeof(dods_uint32);
279 _sizeOfValue =
sizeof(dods_float32);
282 _sizeOfValue =
sizeof(dods_float64);
285 throw InternalErr(__FILE__, __LINE__,
"Unknown DAP type encountered when constructing NDimensionalArray");
288 _storage =
new char[numValues * _sizeOfValue];
295void NDimensionalArray::confirmStorage()
299 "ERROR - NDimensionalArray storage has been relinquished. Instance is no longer viable for set/get operations.";
300 BESDEBUG(NDimensionalArray_debug_key, msg << endl);
301 throw InternalErr(__FILE__, __LINE__, msg);
308void NDimensionalArray::confirmType(
Type dapType)
310 if (_dapType != dapType) {
311 string msg =
"NDimensionalArray::setValue() - Passed value does not match template array type. Expected "
312 + libdap::type_name(_dapType) +
" received " + libdap::type_name(dapType);
313 BESDEBUG(NDimensionalArray_debug_key, msg << endl);
314 throw InternalErr(__FILE__, __LINE__, msg);
321void NDimensionalArray::confirmLastDimSize(
unsigned int n)
323 unsigned long elementCount = getLastDimensionElementCount();
324 if (elementCount != n) {
326 "NDimensionalArray::setLastDimensionHyperSlab() - Passed valueCount does not match size of last dimension hyper-slab. ";
327 msg +=
"Last dimension hyper-slab has " + libdap::long_to_string(elementCount) +
" elements. ";
328 msg +=
"Received a valueCount of " + libdap::long_to_string(n);
329 BESDEBUG(NDimensionalArray_debug_key, msg << endl);
330 throw InternalErr(__FILE__, __LINE__, msg);
344 confirmType(dods_byte_c);
347 dods_byte *_store =
static_cast<dods_byte*
>(_storage);
348 dods_byte oldValue = _store[storageIndex];
349 _store[storageIndex] = value;
362 confirmType(dods_int16_c);
365 dods_int16 *_store =
static_cast<dods_int16 *
>(_storage);
366 dods_int16 oldValue = _store[storageIndex];
367 _store[storageIndex] = value;
379 confirmType(dods_uint16_c);
382 dods_uint16 *_store =
static_cast<dods_uint16 *
>(_storage);
383 dods_uint16 oldValue = _store[storageIndex];
384 _store[storageIndex] = value;
396 confirmType(dods_int32_c);
399 dods_int32 *_store =
static_cast<dods_int32 *
>(_storage);
400 dods_int32 oldValue = _store[storageIndex];
401 _store[storageIndex] = value;
413 confirmType(dods_uint32_c);
416 dods_uint32 *_store =
static_cast<dods_uint32 *
>(_storage);
417 dods_uint32 oldValue = _store[storageIndex];
418 _store[storageIndex] = value;
430 confirmType(dods_float32_c);
433 dods_float32 *_store =
static_cast<dods_float32 *
>(_storage);
434 dods_float32 oldValue = _store[storageIndex];
435 _store[storageIndex] = value;
447 confirmType(dods_float64_c);
450 dods_float64 *_store =
static_cast<dods_float64 *
>(_storage);
451 dods_float64 oldValue = _store[storageIndex];
452 _store[storageIndex] = value;
462 unsigned int *elementCount)
464 BESDEBUG(NDimensionalArray_debug_key, endl<< endl <<
"NDimensionalArray::getLastDimensionHyperSlab() - BEGIN"<<endl);
466 if (location->size() != _shape->size() - 1) {
468 "NDimensionalArray::getLastDimensionHyperSlab() - Passed location vector doesn't match array shape.";
469 BESDEBUG(NDimensionalArray_debug_key, msg << endl);
470 throw InternalErr(__FILE__, __LINE__, msg);
473 BESDEBUG(NDimensionalArray_debug_key,
474 "NDimensionalArray::getLastDimensionHyperSlab() - location" <<vectorToIndices(location) << endl);
478 slabLocation.push_back(0);
479 BESDEBUG(NDimensionalArray_debug_key,
480 "NDimensionalArray::getLastDimensionHyperSlab() - slabLocation" <<vectorToIndices(&slabLocation) << endl);
484 *slab = &((
char *) _storage)[storageIndex * _sizeOfValue];
485 *elementCount = *(_shape->rbegin());
486 BESDEBUG(NDimensionalArray_debug_key,
"NDimensionalArray::getLastDimensionHyperSlab() - END"<<endl<<endl);
490void NDimensionalArray::getNextLastDimensionHyperSlab(
void **slab)
493 unsigned int storageIndex = _shape->back() * _currentLastDimensionSlabIndex++;
494 BESDEBUG(NDimensionalArray_debug_key,
495 "NDimensionalArray::getNextLastDimensionHyperSlab() - Storage Index:"<< libdap::long_to_string(storageIndex) << endl);
496 *slab = &((
char *) _storage)[storageIndex * _sizeOfValue];
506 BESDEBUG(NDimensionalArray_debug_key,
"NDimensionalArray::getStorageIndex() - BEGIN." << endl);
507 long storageIndex = 0;
509 if (location->size() != shape->size()) {
510 string msg =
"getStorageIndex() - The supplied location vector does not match array shape.";
511 BESDEBUG(NDimensionalArray_debug_key, msg << endl);
515 BESDEBUG(NDimensionalArray_debug_key,
516 "NDimensionalArray::getStorageIndex() - Shape and location have the same number of elements." << endl);
521 for (dimIndex = shape->size() - 1; dimIndex >= 0; dimIndex--) {
522 BESDEBUG(NDimensionalArray_debug_key,
523 "NDimensionalArray::getStorageIndex() - dimIndex=" << libdap::long_to_string(dimIndex) << endl);
525 if ((*location)[dimIndex] >= (*shape)[dimIndex]) {
527 "NDimensionalArray::getStorageIndex() - The location vector references a value that does not match the array shape. ";
528 msg +=
"location[" + libdap::long_to_string(dimIndex) +
"]=";
529 msg += libdap::long_to_string((*location)[dimIndex]) +
" ";
530 msg +=
"shape[" + libdap::long_to_string(dimIndex) +
"]=";
531 msg += libdap::long_to_string((*shape)[dimIndex]) +
" ";
532 BESDEBUG(NDimensionalArray_debug_key, msg << endl);
535 storageIndex += chunkSize * ((*location)[dimIndex]);
536 chunkSize *= ((*shape)[dimIndex]);
539 BESDEBUG(NDimensionalArray_debug_key,
"NDimensionalArray::getStorageIndex() - END." << endl);
548void NDimensionalArray::setLastDimensionHyperSlab(std::vector<unsigned int> *location, dods_byte *values,
549 unsigned int valueCount)
551 confirmType(dods_byte_c);
552 confirmLastDimSize(valueCount);
553 setLastDimensionHyperSlab(location, (
void *) values, valueCount *
sizeof(dods_byte));
561void NDimensionalArray::setLastDimensionHyperSlab(std::vector<unsigned int> *location, dods_int16 *values,
562 unsigned int valueCount)
564 confirmType(dods_int16_c);
565 confirmLastDimSize(valueCount);
566 setLastDimensionHyperSlab(location, (
void *) values, valueCount *
sizeof(dods_int16));
574void NDimensionalArray::setLastDimensionHyperSlab(std::vector<unsigned int> *location, dods_uint16 *values,
575 unsigned int valueCount)
577 confirmType(dods_uint16_c);
578 confirmLastDimSize(valueCount);
579 setLastDimensionHyperSlab(location, (
void *) values, valueCount *
sizeof(dods_uint16));
587void NDimensionalArray::setLastDimensionHyperSlab(std::vector<unsigned int> *location, dods_int32 *values,
588 unsigned int valueCount)
590 confirmType(dods_int32_c);
591 confirmLastDimSize(valueCount);
592 setLastDimensionHyperSlab(location, (
void *) values, valueCount *
sizeof(dods_int32));
600void NDimensionalArray::setLastDimensionHyperSlab(std::vector<unsigned int> *location, dods_uint32 *values,
601 unsigned int valueCount)
603 confirmType(dods_uint32_c);
604 confirmLastDimSize(valueCount);
605 setLastDimensionHyperSlab(location, (
void *) values, valueCount *
sizeof(dods_uint32));
613void NDimensionalArray::setLastDimensionHyperSlab(std::vector<unsigned int> *location, dods_float32 *values,
614 unsigned int valueCount)
616 confirmType(dods_float32_c);
617 confirmLastDimSize(valueCount);
618 setLastDimensionHyperSlab(location, (
void *) values, valueCount *
sizeof(dods_float32));
626void NDimensionalArray::setLastDimensionHyperSlab(std::vector<unsigned int> *location, dods_float64 *values,
627 unsigned int valueCount)
629 confirmType(dods_float64_c);
630 confirmLastDimSize(valueCount);
631 setLastDimensionHyperSlab(location, (
void *) values, valueCount *
sizeof(dods_float64));
638void NDimensionalArray::setLastDimensionHyperSlab(std::vector<unsigned int> *location,
void *values,
639 unsigned int byteCount)
643 unsigned int slabElementCount;
645 getLastDimensionHyperSlab(location, &slab, &slabElementCount);
646 memcpy(slab, values, byteCount);
656 memset(_storage, val, _totalValueCount * _sizeOfValue);
665 return *(_shape->rbegin());
668libdap::Array *NDimensionalArray::getArray(libdap::Array *templateArray)
671 if (_shape->size() != templateArray->dimensions(
true))
672 throw Error(
"Template Array has different number of dimensions than NDimensional Array!!");
674 libdap::Array *resultDapArray;
678 libdap::Byte tt(templateArray->name());
679 resultDapArray =
new libdap::Array(templateArray->name(), &tt);
682 case dods_uint16_c: {
683 libdap::Int16 tt(templateArray->name());
684 resultDapArray =
new libdap::Array(templateArray->name(), &tt);
688 libdap::UInt16 tt(templateArray->name());
689 resultDapArray =
new libdap::Array(templateArray->name(), &tt);
693 libdap::Int32 tt(templateArray->name());
694 resultDapArray =
new libdap::Array(templateArray->name(), &tt);
697 case dods_uint32_c: {
698 libdap::UInt32 tt(templateArray->name());
699 resultDapArray =
new libdap::Array(templateArray->name(), &tt);
702 case dods_float32_c: {
703 libdap::Float32 tt(templateArray->name());
704 resultDapArray =
new libdap::Array(templateArray->name(), &tt);
707 case dods_float64_c: {
708 libdap::Float64 tt(templateArray->name());
709 resultDapArray =
new libdap::Array(templateArray->name(), &tt);
713 throw InternalErr(__FILE__, __LINE__,
714 "Unknown DAP type encountered when converting to gridfields internal type.");
717 libdap::Array::Dim_iter dimIt;
719 for (dimIt = templateArray->dim_begin(); dimIt != templateArray->dim_end(); dimIt++, s++) {
720 resultDapArray->append_dim((*_shape)[s], (*dimIt).name);
724 BESDEBUG(NDimensionalArray_debug_key,
725 "TwoDMeshTopology::getGFAttributeAsDapArray() - Copying libdap::Attribute's from template array " << templateArray->name() << endl);
726 resultDapArray->set_attr_table(templateArray->get_attr_table());
730 resultDapArray->set_value((dods_byte *) _storage, _totalValueCount);
733 case dods_uint16_c: {
734 resultDapArray->set_value((dods_uint16 *) _storage, _totalValueCount);
738 resultDapArray->set_value((dods_int16 *) _storage, _totalValueCount);
741 case dods_uint32_c: {
742 resultDapArray->set_value((dods_uint32 *) _storage, _totalValueCount);
746 resultDapArray->set_value((dods_int32 *) _storage, _totalValueCount);
749 case dods_float32_c: {
750 resultDapArray->set_value((dods_float32 *) _storage, _totalValueCount);
753 case dods_float64_c: {
754 resultDapArray->set_value((dods_float64 *) _storage, _totalValueCount);
758 throw InternalErr(__FILE__, __LINE__,
759 "Unknown DAP type encountered when converting to gridfields internal type.");
762 return resultDapArray;
769 if (location->size() == _shape->size()) {
771 s << vectorToIndices(location);
774 long storageIndex = getStorageIndex(_shape, location);
777 s << ((dods_byte *) _storage)[storageIndex];
780 case dods_uint16_c: {
781 s << ((dods_uint16 *) _storage)[storageIndex];
785 s << ((dods_int16 *) _storage)[storageIndex];
788 case dods_uint32_c: {
789 s << ((dods_uint32 *) _storage)[storageIndex];
793 s << ((dods_int32 *) _storage)[storageIndex];
796 case dods_float32_c: {
797 s << ((dods_float32 *) _storage)[storageIndex];
800 case dods_float64_c: {
801 s << ((dods_float64 *) _storage)[storageIndex];
805 throw InternalErr(__FILE__, __LINE__,
806 "Unknown DAP type encountered when converting to gridfields internal type.");
812 int nextDimSize = (*_shape)[location->size()];
813 for (
int i = 0; i < nextDimSize; i++) {
814 location->push_back(i);
815 s << toString_worker(location);
816 location->pop_back();
824string NDimensionalArray::toString()
830 s << endl <<
"NDimensionalArray: " << endl;
831 s << toString_worker(&location);
void getLastDimensionHyperSlab(std::vector< unsigned int > *location, void **slab, unsigned int *elementCount)
static long getStorageIndex(vector< unsigned int > *shape, vector< unsigned int > *location)
void * relinquishStorage()
static long computeConstrainedShape(libdap::Array *a, vector< unsigned int > *shape)
long getLastDimensionElementCount()
static long computeArraySizeFromShapeVector(vector< unsigned int > *shape)
dods_byte setValue(std::vector< unsigned int > *location, dods_byte value)