31 class FETPAPI_DLL_IMPORT_OR_EXPORT
FesapiHdfProxy :
public EML2_NS::AbstractHdfProxy
38 FesapiHdfProxy(
AbstractSession* session, COMMON_NS::DataObjectRepository * repo,
const std::string & guid,
const std::string & title,
const std::string & packageDirAbsolutePath,
const std::string & externalFilePath, COMMON_NS::DataObjectRepository::openingMode hdfPermissionAccess) :
39 EML2_NS::AbstractHdfProxy(packageDirAbsolutePath, externalFilePath, hdfPermissionAccess), session_(session), compressionLevel(0) {
40 xmlNs_ = repo->getDefaultEmlVersion() == COMMON_NS::DataObjectRepository::EnergisticsStandard::EML2_3 ?
"eml23" :
"eml20";
41 initGsoapProxy(repo, guid, title, 20);
48 EML2_NS::AbstractHdfProxy(fromGsoap), session_(session), compressionLevel(0), xmlNs_(
"eml20") {}
54 EML2_NS::AbstractHdfProxy(dor), session_(session), compressionLevel(0) {
55 std::string ct = dor.getContentType();
56 if (ct.find(
"2.0") != std::string::npos) {
59 else if (ct.find(
"2.3") != std::string::npos) {
63 throw std::invalid_argument(
"The HDF Proxy DataObjectReference does not look to be eml20 or eml23 neither : " + ct);
85 bool isOpened() const final {
return session_ !=
nullptr && !session_->isWebSocketSessionClosed(); }
95 COMMON_NS::AbstractObject::numericalDatatypeEnum getNumericalDatatype(
const std::string & groupName)
final;
116 const std::string & name,
117 COMMON_NS::AbstractObject::numericalDatatypeEnum cumulativeLengthDatatype,
118 const void * cumulativeLength,
119 uint64_t cumulativeLengthSize,
120 COMMON_NS::AbstractObject::numericalDatatypeEnum elementsDatatype,
121 const void * elements,
122 uint64_t elementsSize)
final;
134 void setCompressionLevel(
unsigned int newCompressionLevel)
final {
if (newCompressionLevel > 9) compressionLevel = 9;
else compressionLevel = newCompressionLevel; }
147 const std::string & name,
148 COMMON_NS::AbstractObject::numericalDatatypeEnum datatype,
150 const uint64_t * numValuesInEachDimension,
151 unsigned int numDimensions)
final;
163 const std::string& groupName,
164 const std::string& name,
165 COMMON_NS::AbstractObject::numericalDatatypeEnum datatype,
166 const uint64_t* numValuesInEachDimension,
167 unsigned int numDimensions)
final;
180 const std::string& groupName,
181 const std::string& name,
182 COMMON_NS::AbstractObject::numericalDatatypeEnum datatype,
184 const uint64_t* numValuesInEachDimension,
185 const uint64_t* offsetValuesInEachDimension,
186 unsigned int numDimensions)
final;
200 const std::string& groupName,
201 const std::string& name,
202 COMMON_NS::AbstractObject::numericalDatatypeEnum datatype,
204 const uint64_t* numValuesInEachDimension,
205 const uint64_t* offsetValuesInEachDimension,
206 unsigned int numDimensions);
212 const std::vector<std::string>&,
213 const std::vector<std::string>&)
final {
214 throw std::logic_error(
"Group attributes are not supported in ETP1.2");
222 const std::vector<std::string>&)
final {
223 throw std::logic_error(
"Group attributes are not supported in ETP1.2");
230 const std::vector<std::string>&,
231 const std::vector<double>&) {
232 throw std::logic_error(
"Group attributes are not supported in ETP1.2");
239 const std::vector<std::string>&,
240 const std::vector<int>&)
final {
241 throw std::logic_error(
"Group attributes are not supported in ETP1.2");
248 const std::vector<std::string>&,
249 const std::vector<std::string>&)
final {
250 throw std::logic_error(
"Dataset attributes are not supported in ETP1.2");
258 const std::vector<std::string>&)
final {
259 throw std::logic_error(
"Dataset attributes are not supported in ETP1.2");
266 const std::vector<std::string>&,
267 const std::vector<double>&)
final {
268 throw std::logic_error(
"Dataset attributes are not supported in ETP1.2");
275 const std::vector<std::string>&,
276 const std::vector<int>&)
final {
277 throw std::logic_error(
"Dataset attributes are not supported in ETP1.2");
280 std::string readStringAttribute(
const std::string&,
281 const std::string&)
const final {
282 throw std::logic_error(
"Attributes are not supported in ETP1.2");
285 std::vector<std::string> readStringArrayAttribute(
const std::string&,
286 const std::string&)
const final {
287 throw std::logic_error(
"Attributes are not supported in ETP1.2");
290 double readDoubleAttribute(
const std::string&,
291 const std::string&)
const final {
292 throw std::logic_error(
"Attributes are not supported in ETP1.2");
295 int64_t readInt64Attribute(
const std::string&,
296 const std::string&)
const final {
297 throw std::logic_error(
"Attributes are not supported in ETP1.2");
316 const std::string & datasetName,
318 uint64_t
const * numValuesInEachDimension,
319 uint64_t
const * offsetInEachDimension,
320 unsigned int numDimensions)
final;
333 const std::string & datasetName,
double* values,
334 uint64_t
const * blockCountPerDimension,
335 uint64_t
const * offsetInEachDimension,
336 uint64_t
const * strideInEachDimension,
337 uint64_t
const * blockSizeInEachDimension,
338 unsigned int numDimensions)
final;
340 void selectArrayNdOfValues(
341 const std::string & datasetName,
342 uint64_t
const * blockCountPerDimension,
343 uint64_t
const * offsetInEachDimension,
344 uint64_t
const * strideInEachDimension,
345 uint64_t
const * blockSizeInEachDimension,
346 unsigned int numDimensions,
348 hdf5_hid_t & dataset,
349 hdf5_hid_t & filespace)
final;
360 hdf5_hid_t filespace,
362 uint64_t slabSize)
final;
380 const std::string & datasetName,
382 uint64_t
const * numValuesInEachDimension,
383 uint64_t
const * offsetInEachDimension,
384 unsigned int numDimensions)
final;
391 void readArrayNdOfInt64Values(
const std::string & datasetName, int64_t* values)
final { readArrayNdOfValues(datasetName, values); }
402 const std::string & datasetName,
404 uint64_t
const * numValuesInEachDimension,
405 uint64_t
const * offsetInEachDimension,
406 unsigned int numDimensions)
final;
420 void readArrayNdOfIntValues(
const std::string & datasetName,
int* values)
final { readArrayNdOfValues(datasetName, values); }
431 const std::string & datasetName,
433 uint64_t
const * numValuesInEachDimension,
434 uint64_t
const * offsetInEachDimension,
435 unsigned int numDimensions
443 void readArrayNdOfUIntValues(
const std::string & datasetName,
unsigned int* values)
final { readArrayNdOfValues(datasetName, values); }
458 void readArrayNdOfUShortValues(
const std::string & datasetName,
unsigned short* values)
final { readArrayNdOfValues(datasetName, values); }
465 void readArrayNdOfInt8Values(
const std::string & datasetName, int8_t* values)
final { readArrayNdOfValues(datasetName, values); }
471 void readArrayNdOfUInt8Values(
const std::string & datasetName, uint8_t* values)
final { readArrayNdOfValues(datasetName, values); }
476 bool exist(
const std::string & absolutePathInHdfFile)
const final;
498 unsigned int compressionLevel;
500 size_t maxArraySize_{ 12000000 };
503 std::shared_ptr<Energistics::Etp::v12::Protocol::DataArray::GetDataArrays> buildGetDataArraysMessage(
const std::string & datasetName)
const;
504 std::shared_ptr<Energistics::Etp::v12::Protocol::DataArray::GetDataArrayMetadata> buildGetDataArrayMetadataMessage(
const std::string & datasetName)
const;
508 template<
typename T>
void readArrayNdOfValues(
const std::string & datasetName, T* values)
512 const size_t valueCount = std::accumulate(daMetadata.dimensions.begin(), daMetadata.dimensions.end(), 1, std::multiplies<int64_t>());
514 size_t valueSize = 1;
515 switch (daMetadata.transportArrayType) {
516 case Energistics::Etp::v12::Datatypes::AnyArrayType::bytes:
517 case Energistics::Etp::v12::Datatypes::AnyArrayType::arrayOfBoolean:
break;
518 case Energistics::Etp::v12::Datatypes::AnyArrayType::arrayOfInt: valueSize = 6;
break;
519 case Energistics::Etp::v12::Datatypes::AnyArrayType::arrayOfFloat: valueSize = 4;
break;
520 case Energistics::Etp::v12::Datatypes::AnyArrayType::arrayOfLong: valueSize = 10;
break;
521 case Energistics::Etp::v12::Datatypes::AnyArrayType::arrayOfDouble: valueSize = 8;
break;
522 default:
throw std::logic_error(
"Array of strings are not implemented yet");
524 const size_t wholeSize = valueCount * valueSize;
527 const size_t maxAllowedDataArraySize = session_->getMaxWebSocketMessagePayloadSize()
528 -
sizeof(Energistics::Etp::v12::Datatypes::MessageHeader)
529 - (daMetadata.dimensions.size() * 2 + 1) * 8;
532 auto specializedHandler = std::make_shared<GetFullDataArrayHandlers<T>>(session_, values);
533 if (wholeSize + (valueCount + 1) * 8 <= maxAllowedDataArraySize) {
535 session_->sendWithSpecificHandlerAndBlock(
536 buildGetDataArraysMessage(datasetName),
542 std::vector<int64_t> counts(daMetadata.dimensions.size(), 1);
545 size_t subArrayValueCount = 1;
546 for (int64_t dimIndex = daMetadata.dimensions.size() - 1; dimIndex >= 0; --dimIndex) {
547 int64_t maxCountOnDim = daMetadata.preferredSubarrayDimensions.empty()
548 ? daMetadata.dimensions[dimIndex]
549 : daMetadata.preferredSubarrayDimensions[dimIndex];
550 subArrayValueCount *= maxCountOnDim;
551 int64_t allowedCountOnDim = maxCountOnDim;
552 while (subArrayValueCount * valueSize + (subArrayValueCount + 1) * 8 > maxAllowedDataArraySize) {
553 subArrayValueCount /= allowedCountOnDim;
554 allowedCountOnDim /= 2;
555 subArrayValueCount *= allowedCountOnDim;
557 counts[dimIndex] = allowedCountOnDim;
558 if (allowedCountOnDim != maxCountOnDim) {
564 auto msg = std::make_shared<Energistics::Etp::v12::Protocol::DataArray::GetDataSubarrays>();
565 size_t subArrayIndex = 0;
566 std::vector<int64_t> starts(daMetadata.dimensions.size(), 0);
567 std::vector<int64_t> currentCounts = counts;
568 bool hasParsedAllArray =
false;
569 while (!hasParsedAllArray) {
570 std::string subArrayIndexStr = std::to_string(subArrayIndex);
571 msg->dataSubarrays[subArrayIndexStr].uid = buildDataArrayIdentifier(datasetName);
572 msg->dataSubarrays[subArrayIndexStr].counts = currentCounts;
573 msg->dataSubarrays[subArrayIndexStr].starts = starts;
577 hasParsedAllArray =
true;
578 for (int64_t dimIndex = daMetadata.dimensions.size() - 1; dimIndex >= 0; --dimIndex) {
579 if (starts[dimIndex] + currentCounts[dimIndex] < daMetadata.dimensions[dimIndex]) {
580 starts[dimIndex] += currentCounts[dimIndex];
581 if (starts[dimIndex] + currentCounts[dimIndex] > daMetadata.dimensions[dimIndex]) {
582 currentCounts[dimIndex] = daMetadata.dimensions[dimIndex] - starts[dimIndex];
585 for (
size_t dimIndex2 = dimIndex + 1; dimIndex2 < daMetadata.dimensions.size(); ++dimIndex2) {
586 starts[dimIndex2] = 0;
587 currentCounts[dimIndex2] = counts[dimIndex2];
589 hasParsedAllArray =
false;
594 specializedHandler->setDataSubarrays(subArrayIndexStr, msg->dataSubarrays[subArrayIndexStr]);
598 session_->sendWithSpecificHandlerAndBlock(