/* dtkComposerNodeArrayDataExtractor.cpp --- * * Author: tkloczko * Copyright (C) 2011 - Thibaud Kloczko, Inria. * Created: Wed Jul 4 12:07:20 2012 (+0200) * Version: $Id: f5c0d7fee42f4401a86dd10e6c916c1ff19aba36 $ * Last-Updated: mar. févr. 4 17:07:39 2014 (+0100) * By: Nicolas Niclausse * Update #: 64 */ /* Commentary: * */ /* Change log: * */ #include "dtkComposerNodeArrayDataExtractor.h" #include "dtkComposerTransmitterEmitter.h" #include "dtkComposerTransmitterReceiver.h" #include "dtkComposerTransmitterVariant.h" #include #include // ///////////////////////////////////////////////////////////////// // dtkComposerNodeArrayDataExtractorPrivate interface // ///////////////////////////////////////////////////////////////// class dtkComposerNodeArrayDataExtractorPrivate { public: dtkComposerTransmitterVariant receiver_array; dtkComposerTransmitterReceiver receiver_index; public: dtkComposerTransmitterVariant emitter_item; }; // ///////////////////////////////////////////////////////////////// // dtkComposerNodeArrayDataExtractor implementation // ///////////////////////////////////////////////////////////////// dtkComposerNodeArrayDataExtractor::dtkComposerNodeArrayDataExtractor(void) : dtkComposerNodeLeaf(), d(new dtkComposerNodeArrayDataExtractorPrivate) { this->appendReceiver(&d->receiver_array); this->appendReceiver(&d->receiver_index); this->appendEmitter(&d->emitter_item); } dtkComposerNodeArrayDataExtractor::~dtkComposerNodeArrayDataExtractor(void) { delete d; d = NULL; } QString dtkComposerNodeArrayDataExtractor::inputLabelHint(int port) { switch (port) { case 0: return "array"; break; case 1: return "index"; break; default: break; } return "port"; } QString dtkComposerNodeArrayDataExtractor::outputLabelHint(int port) { switch (port) { case 0: return "item"; break; default: break; } return "port"; } void dtkComposerNodeArrayDataExtractor::run(void) { if (!d->receiver_array.isEmpty() && !d->receiver_index.isEmpty()) { dtkAbstractContainerWrapper *array = d->receiver_array.container(); qlonglong index = *d->receiver_index.data(); if (!array) { dtkError() << "Input array is not defined."; return; } if (index >= array->count()) { dtkWarn() << "index " << index << " > size of the input array " << array->count() << ". Invalid QVariant is returned."; d->emitter_item.setData(QVariant()); } else { d->emitter_item.setData(array->at(index)); } } else { dtkWarn() << "Inputs not specified. Invalid QVariant is returned."; d->emitter_item.setData(QVariant()); } } // ///////////////////////////////////////////////////////////////// // dtkComposerNodeArrayDataExtractorSubArrayPrivate interface // ///////////////////////////////////////////////////////////////// class dtkComposerNodeArrayDataExtractorSubArrayPrivate { public: dtkComposerTransmitterVariant receiver_array; dtkComposerTransmitterVariant receiver_indices; public: dtkComposerTransmitterVariant emitter_subarray; public: dtkAbstractContainerWrapper *subarray; }; // ///////////////////////////////////////////////////////////////// // dtkComposerNodeArrayDataExtractorSubArray implementation // ///////////////////////////////////////////////////////////////// dtkComposerNodeArrayDataExtractorSubArray::dtkComposerNodeArrayDataExtractorSubArray(void) : dtkComposerNodeLeaf(), d(new dtkComposerNodeArrayDataExtractorSubArrayPrivate) { d->subarray = NULL; this->appendReceiver(&d->receiver_array); QList variant_list; variant_list << QMetaType::Int << QMetaType::UInt << QMetaType::LongLong << QMetaType::ULongLong; d->receiver_indices.setDataTypes(variant_list); this->appendReceiver(&d->receiver_indices); this->appendEmitter(&d->emitter_subarray); } dtkComposerNodeArrayDataExtractorSubArray::~dtkComposerNodeArrayDataExtractorSubArray(void) { if (d->subarray) delete d->subarray; d->subarray = NULL; delete d; d = NULL; } QString dtkComposerNodeArrayDataExtractorSubArray::inputLabelHint(int port) { switch (port) { case 0: return "array"; break; case 1: return "index array"; break; default: break; } return "port"; } QString dtkComposerNodeArrayDataExtractorSubArray::outputLabelHint(int port) { switch (port) { case 0: return "subarray"; break; default: break; } return "port"; } void dtkComposerNodeArrayDataExtractorSubArray::run(void) { if (!d->receiver_array.isEmpty() && !d->receiver_indices.isEmpty()) { dtkAbstractContainerWrapper *array = d->receiver_array.container(); dtkAbstractContainerWrapper *indices = d->receiver_indices.container(); if (!array || !indices) { dtkError() << "Inputs are not defined."; d->emitter_subarray.clearData(); return; } if (!d->subarray) d->subarray = array->voidClone(); else d->subarray->clear(); qlonglong index; for (qlonglong i = 0; i < indices->count(); ++i) { index = indices->at(i).value(); if (index >= array->count()) { dtkWarn() << "index " << i << " of indices array is greater than the size of the array. Zero is inserted."; d->subarray->append(QVariant()); } else { d->subarray->append(array->at(index)); } } d->emitter_subarray.setData(d->subarray); } else { dtkWarn() << "Inputs not specified. Nothing is done"; d->emitter_subarray.clearData(); } } // ///////////////////////////////////////////////////////////////// // dtkComposerNodeArrayDataExtractorArrayPartPrivate interface // ///////////////////////////////////////////////////////////////// class dtkComposerNodeArrayDataExtractorArrayPartPrivate { public: dtkComposerTransmitterVariant receiver_array; dtkComposerTransmitterReceiver receiver_from; dtkComposerTransmitterReceiver receiver_length; public: dtkComposerTransmitterVariant emitter_subarray; public: dtkAbstractContainerWrapper *subarray; }; // ///////////////////////////////////////////////////////////////// // dtkComposerNodeArrayDataExtractorArrayPart implementation // ///////////////////////////////////////////////////////////////// dtkComposerNodeArrayDataExtractorArrayPart::dtkComposerNodeArrayDataExtractorArrayPart(void) : dtkComposerNodeLeaf(), d(new dtkComposerNodeArrayDataExtractorArrayPartPrivate) { d->subarray = NULL; this->appendReceiver(&d->receiver_array); this->appendReceiver(&d->receiver_from); this->appendReceiver(&d->receiver_length); this->appendEmitter(&d->emitter_subarray); } dtkComposerNodeArrayDataExtractorArrayPart::~dtkComposerNodeArrayDataExtractorArrayPart(void) { if (d->subarray) delete d->subarray; d->subarray = NULL; delete d; d = NULL; } QString dtkComposerNodeArrayDataExtractorArrayPart::inputLabelHint(int port) { switch (port) { case 0: return "array"; break; case 1: return "from"; break; case 2: return "length"; break; default: break; } return "port"; } QString dtkComposerNodeArrayDataExtractorArrayPart::outputLabelHint(int port) { switch (port) { case 0: return "subarray"; break; default: break; } return "port"; } void dtkComposerNodeArrayDataExtractorArrayPart::run(void) { if (!d->receiver_array.isEmpty() && !d->receiver_from.isEmpty()) { dtkAbstractContainerWrapper *array = d->receiver_array.container(); if (!array) { dtkError() << "Inputs are not defined."; d->emitter_subarray.clearData(); return; } if (array->isReset()) { dtkWarn() << "Input array is not valid. Nothing is done."; d->emitter_subarray.clearData(); return; } qlonglong from = *d->receiver_from.data(); if (from >= array->count()) { dtkWarn() << "Starting value from is greater than array size:" << from << ">=" << array->count(); d->emitter_subarray.clearData(); return; } qlonglong length = 0; if (!d->receiver_length.isEmpty()) length = *d->receiver_length.data(); if (length < 0) { dtkWarn() << "Length value is negative:" << length << "<" << 0; d->emitter_subarray.clearData(); return; } qlonglong to = qMin((from + length), array->count()); if (!d->subarray) d->subarray = array->voidClone(); else d->subarray->clear(); for (qlonglong i = from; i < to; ++i) { d->subarray->append(array->at(i)); } d->emitter_subarray.setData(d->subarray); } else { dtkWarn() << "Inputs not specified. Nothing is done"; d->emitter_subarray.clearData(); } }