Program Listing for File h5ppInfo.h¶
↰ Return to documentation for file (/home/david/GitProjects/h5pp/h5pp/include/h5pp/details/h5ppInfo.h
)
#pragma once
#include "h5ppEnums.h"
#include "h5ppHid.h"
#include "h5ppLogger.h"
#include "h5ppOptional.h"
#include <hdf5.h>
#include <hdf5_hl.h>
#include <string>
#include <typeindex>
#include <variant>
#include <vector>
namespace h5pp {
namespace debug {
enum class DimSizeComparison { ENFORCE, PERMISSIVE };
inline auto reportCompatibility(std::optional<std::vector<hsize_t>> smallDims,
std::optional<std::vector<hsize_t>> largeDims,
DimSizeComparison dimComp = DimSizeComparison::ENFORCE) {
std::string msg;
if(not smallDims) return msg;
if(not largeDims) return msg;
if(smallDims->size() != largeDims->size()) msg.append("rank mismatch | ");
bool ok = false;
switch(dimComp) {
case DimSizeComparison::ENFORCE:
ok = std::equal(std::begin(smallDims.value()),
std::end(smallDims.value()),
std::begin(largeDims.value()),
std::end(largeDims.value()),
[](const hsize_t &s, const hsize_t &l) -> bool { return s <= l; });
break;
case DimSizeComparison::PERMISSIVE: ok = true; break;
default: break;
}
if(not ok) msg.append("dimensions incompatible | ");
return msg;
}
inline auto reportCompatibility(std::optional<H5D_layout_t> h5Layout,
std::optional<std::vector<hsize_t>> dims,
std::optional<std::vector<hsize_t>> dimsChunk,
std::optional<std::vector<hsize_t>> dimsMax) {
std::string error_msg;
if(h5Layout) {
if(h5Layout.value() == H5D_CHUNKED) {}
if(h5Layout.value() == H5D_COMPACT) {
if(dimsChunk)
error_msg.append(h5pp::format("Chunk dims {} | Layout is H5D_COMPACT | chunk dimensions are only meant for H5D_CHUNKED layouts\n", dimsChunk.value()));
if(dimsMax and dims and dimsMax.value() != dims.value())
error_msg.append(h5pp::format(
"dims {} | max dims {} | layout is H5D_COMPACT | dims and max dims must be equal unless the layout is H5D_CHUNKED\n", dims.value(), dimsMax.value()));
}
if(h5Layout.value() == H5D_CONTIGUOUS) {
if(dimsChunk)
error_msg.append(
h5pp::format("Chunk dims {} | Layout is H5D_CONTIGUOUS | chunk dimensions are only meant for datasets with H5D_CHUNKED layout \n", dimsChunk.value()));
if(dimsMax)
error_msg.append(
h5pp::format("Max dims {} | Layout is H5D_CONTIGUOUS | max dimensions are only meant for datasets with H5D_CHUNKED layout \n", dimsMax.value()));
}
}
std::string res1 = reportCompatibility(dims, dimsMax);
std::string res2 = reportCompatibility(dims, dimsChunk, DimSizeComparison::PERMISSIVE);
std::string res3 = reportCompatibility(dimsChunk, dimsMax);
if(not res1.empty()) error_msg.append(h5pp::format("\t{}: dims {} | max dims {}\n", res1, dims.value(), dimsMax.value()));
if(not res2.empty()) error_msg.append(h5pp::format("\t{}: dims {} | chunk dims {}\n", res2, dims.value(), dimsChunk.value()));
if(not res3.empty()) error_msg.append(h5pp::format("\t{}: chunk dims {} | max dims {}\n", res3, dimsChunk.value(), dimsMax.value()));
return error_msg;
}
}
struct Options {
std::optional<std::string> linkPath = std::nullopt;
std::optional<std::string> attrName = std::nullopt;
OptDimsType dataDims = std::nullopt;
OptDimsType dsetDimsChunk = std::nullopt;
OptDimsType dsetDimsMax = std::nullopt;
std::optional<Hyperslab> dsetSlab = std::nullopt;
std::optional<Hyperslab> attrSlab = std::nullopt;
std::optional<Hyperslab> dataSlab = std::nullopt;
std::optional<hid::h5t> h5Type = std::nullopt;
std::optional<H5D_layout_t> h5Layout = std::nullopt;
std::optional<unsigned int> compression = std::nullopt;
std::optional<h5pp::ResizeMode> resizeMode = std::nullopt;
[[nodiscard]] std::string string() const {
std::string msg;
/* clang-format off */
if(dataDims) msg.append(h5pp::format(" | data dims {}", dataDims.value()));
if(dsetDimsMax) msg.append(h5pp::format(" | max dims {}", dsetDimsMax.value()));
if(h5Layout){
switch(h5Layout.value()){
case H5D_CHUNKED: msg.append(h5pp::format(" | H5D_CHUNKED")); break;
case H5D_CONTIGUOUS: msg.append(h5pp::format(" | H5D_CONTIGUOUS")); break;
case H5D_COMPACT: msg.append(h5pp::format(" | H5D_COMPACT")); break;
default: break;
}
}
if(dsetDimsChunk) msg.append(h5pp::format(" | chunk dims {}", dsetDimsChunk.value()));
if (dataSlab) msg.append(h5pp::format(" | memory hyperslab {}", dataSlab->string()));
if (dsetSlab) msg.append(h5pp::format(" | file hyperslab {}", dsetSlab->string()));
return msg;
/* clang-format on */
}
void assertWellDefined() const {
std::string error_msg;
if(not linkPath) error_msg.append("\tMissing field: linkPath\n");
error_msg.append(debug::reportCompatibility(h5Layout, dataDims, dsetDimsChunk, dsetDimsMax));
if(not error_msg.empty()) throw std::runtime_error(h5pp::format("Options are not well defined: \n{}", error_msg));
}
};
struct DataInfo {
std::optional<hsize_t> dataSize = std::nullopt;
std::optional<size_t> dataByte = std::nullopt;
OptDimsType dataDims = std::nullopt;
std::optional<int> dataRank = std::nullopt;
std::optional<Hyperslab> dataSlab = std::nullopt;
std::optional<hid::h5s> h5Space = std::nullopt;
std::optional<std::string> cppTypeName = std::nullopt;
std::optional<size_t> cppTypeSize = std::nullopt;
std::optional<std::type_index> cppTypeIndex = std::nullopt;
void setFromSpace() {
if(not h5Space) return;
dataRank = H5Sget_simple_extent_ndims(h5Space.value());
dataDims = std::vector<hsize_t>(static_cast<size_t>(dataRank.value()), 0);
H5Sget_simple_extent_dims(h5Space.value(), dataDims->data(), nullptr);
}
void assertWriteReady() const {
std::string error_msg;
/* clang-format off */
if(not dataSize) error_msg.append(" | dataSize");
if(not dataByte) error_msg.append(" | dataByte");
if(not dataDims) error_msg.append(" | dataDims");
if(not dataRank) error_msg.append(" | dataRank");
if(not h5Space) error_msg.append(" | h5Space");
if(not error_msg.empty())
throw std::runtime_error(h5pp::format("Cannot write from memory. The following fields are undefined:\n{}", error_msg));
if(not h5Space->valid() ) error_msg.append(" | h5Space");
if(not error_msg.empty())
throw std::runtime_error(h5pp::format("Cannot write from memory. The following fields are not valid:\n{}", error_msg));
/* clang-format on */
hsize_t size_check = std::accumulate(dataDims->begin(), dataDims->end(), static_cast<hsize_t>(1), std::multiplies<>());
if(size_check != dataSize.value())
throw std::runtime_error(h5pp::format("Data size mismatch: dataSize [{}] | dataDims {} = size [{}]", dataSize.value(), dataDims.value(), size_check));
}
void assertReadReady() const {
std::string error_msg;
/* clang-format off */
if(not dataSize) error_msg.append(" | dataSize");
if(not dataByte) error_msg.append(" | dataByte");
if(not dataRank) error_msg.append(" | dataRank");
if(not dataDims) error_msg.append(" | dataDims");
if(not h5Space) error_msg.append(" | h5Space");
if(not error_msg.empty())
throw std::runtime_error(h5pp::format("Cannot read into memory. The following fields are undefined:\n{}", error_msg));
if(not h5Space->valid() ) error_msg.append(" | h5Space");
if(not error_msg.empty())
throw std::runtime_error(h5pp::format("Cannot read into memory. The following fields are not valid:\n{}", error_msg));
/* clang-format on */
hsize_t size_check = std::accumulate(dataDims->begin(), dataDims->end(), static_cast<hsize_t>(1), std::multiplies<>());
if(size_check != dataSize.value()) throw std::runtime_error(h5pp::format("Data size mismatch: dataSize [{}] | size check [{}]", dataSize.value(), size_check));
}
[[nodiscard]] std::string string() const {
// std::string msg;
std::string msg;
/* clang-format off */
if(dataSize) msg.append(h5pp::format(" | size {}", dataSize.value()));
if(dataByte) msg.append(h5pp::format(" | bytes {}", dataByte.value()));
if(dataRank) msg.append(h5pp::format(" | rank {}", dataRank.value()));
if(dataDims) msg.append(h5pp::format(" | dims {}", dataDims.value()));
if (h5Space and H5Sget_select_type(h5Space.value()) == H5S_sel_type::H5S_SEL_HYPERSLABS){
Hyperslab slab(h5Space.value());
msg.append(h5pp::format(" | [ Hyperslab {} ]", slab.string()));
}
if(cppTypeName) msg.append(h5pp::format(" | type [{}]", cppTypeName.value()));
return msg;
/* clang-format on */
}
};
struct DsetInfo {
std::optional<hid::h5f> h5File = std::nullopt;
std::optional<hid::h5f> h5Group = std::nullopt;
std::optional<hid::h5f> h5ObjLoc = std::nullopt;
std::optional<hid::h5d> h5Dset = std::nullopt;
std::optional<hid::h5t> h5Type = std::nullopt;
std::optional<H5D_layout_t> h5Layout = std::nullopt;
std::optional<hid::h5s> h5Space = std::nullopt;
std::optional<hid::h5p> h5PlistDsetCreate = std::nullopt;
std::optional<hid::h5p> h5PlistDsetAccess = std::nullopt;
std::optional<std::string> dsetPath = std::nullopt;
std::optional<bool> dsetExists = std::nullopt;
std::optional<hsize_t> dsetSize = std::nullopt;
std::optional<size_t> dsetByte = std::nullopt;
std::optional<int> dsetRank = std::nullopt;
OptDimsType dsetDims = std::nullopt;
OptDimsType dsetDimsMax = std::nullopt;
OptDimsType dsetChunk = std::nullopt;
std::optional<Hyperslab> dsetSlab = std::nullopt;
std::optional<h5pp::ResizeMode> resizeMode = std::nullopt;
std::optional<unsigned int> compression = std::nullopt;
std::optional<std::string> cppTypeName = std::nullopt;
std::optional<size_t> cppTypeSize = std::nullopt;
std::optional<std::type_index> cppTypeIndex = std::nullopt;
[[nodiscard]] hid_t getLocId() const {
if(h5File) return h5File.value();
if(h5Group) return h5Group.value();
if(h5ObjLoc) return h5ObjLoc.value();
h5pp::logger::log->debug("Dataset location id is not defined");
return -1;
}
void assertCreateReady() const {
std::string error_msg;
/* clang-format off */
if(not dsetPath ) error_msg.append("\t dsetPath\n");
if(not dsetExists ) error_msg.append("\t dsetExists\n");
if(not h5Type ) error_msg.append("\t h5Type\n");
if(not h5Space ) error_msg.append("\t h5Space\n");
if(not h5PlistDsetCreate ) error_msg.append("\t h5PlistDsetCreate\n");
if(not h5PlistDsetAccess ) error_msg.append("\t h5PlistDsetAccess\n");
if(not error_msg.empty())
throw std::runtime_error(h5pp::format("Cannot create dataset. The following fields are undefined:\n{}",error_msg));
if(not h5Type->valid() ) error_msg.append("\t h5Type\n");
if(not h5Space->valid() ) error_msg.append("\t h5Space\n");
if(not h5PlistDsetCreate->valid() ) error_msg.append("\t h5PlistDsetCreate\n");
if(not h5PlistDsetAccess->valid() ) error_msg.append("\t h5PlistDsetAccess\n");
if(not error_msg.empty())
throw std::runtime_error("Cannot create dataset. The following fields are not valid\n\t" + error_msg);
if(getLocId() < 0) throw std::runtime_error(h5pp::format("Cannot create dataset [{}]: The location ID is not set", dsetPath.value()));
error_msg.append(debug::reportCompatibility(h5Layout,dsetDims,dsetChunk,dsetDimsMax));
if(not error_msg.empty()) throw std::runtime_error(h5pp::format("Dataset dimensions are not well defined:\n{}", error_msg));
/* clang-format on */
}
void assertResizeReady() const {
std::string error_msg;
/* clang-format off */
if(dsetExists and dsetPath and not dsetExists.value()) error_msg.append(h5pp::format("\t Dataset does not exist [{}]", dsetPath.value()));
else if(dsetExists and not dsetExists.value()) error_msg.append("\t Dataset does not exist");
if(resizeMode and resizeMode == h5pp::ResizeMode::DO_NOT_RESIZE) error_msg.append("\t Resize mode is set to DO_NOT_RESIZE");
if(not error_msg.empty())
throw std::runtime_error(h5pp::format("Cannot resize dataset.\n{}", error_msg));
if(not dsetPath ) error_msg.append("\t dsetPath\n");
if(not dsetExists ) error_msg.append("\t dsetExists\n");
if(not dsetDimsMax ) error_msg.append("\t dsetDimsMax\n");
if(not h5Dset ) error_msg.append("\t h5Dset\n");
if(not h5Type ) error_msg.append("\t h5Type\n");
if(not h5Space ) error_msg.append("\t h5Space\n");
if(not h5Layout ) error_msg.append("\t h5Layout\n");
if(not error_msg.empty())
throw std::runtime_error(h5pp::format("Cannot resize dataset. The following fields are undefined:\n{}", error_msg));
if(not dsetExists.value() ) error_msg.append("\t dsetExists == false\n");
if(not h5Dset->valid() ) error_msg.append("\t h5Dset\n");
if(not h5Type->valid() ) error_msg.append("\t h5Type\n");
if(not h5Space->valid() ) error_msg.append("\t h5Space\n");
if(not error_msg.empty())
throw std::runtime_error(h5pp::format("Cannot resize dataset [{}]. The following fields are not valid:\n{}",dsetPath.value(), error_msg));
/* clang-format on */
}
void assertWriteReady() const {
std::string error_msg;
/* clang-format off */
if(not dsetPath ) error_msg.append("\t linkPath\n");
if(not dsetExists ) error_msg.append("\t dsetExists\n");
if(not h5Dset ) error_msg.append("\t h5Dset\n");
if(not h5Type ) error_msg.append("\t h5Type\n");
if(not h5Space ) error_msg.append("\t h5Space\n");
if(not error_msg.empty())
throw std::runtime_error(h5pp::format("Cannot write into dataset. The following fields are undefined:\n{}", error_msg));
if(not h5Dset->valid() ) error_msg.append("\t h5Dset\n");
if(not h5Type->valid() ) error_msg.append("\t h5Type\n");
if(not h5Space->valid() ) error_msg.append("\t h5Space\n");
if(not error_msg.empty())
throw std::runtime_error(h5pp::format("Cannot write into dataset [{}]. The following fields are not valid:\n",dsetPath.value(), error_msg));
/* clang-format on */
}
void assertReadReady() const {
std::string error_msg;
/* clang-format off */
if(not dsetPath ) error_msg.append("\t linkPath\n");
if(not dsetExists ) error_msg.append("\t dsetExists\n");
if(not h5Dset ) error_msg.append("\t h5Dset\n");
if(not h5Type ) error_msg.append("\t h5Type\n");
if(not h5Space ) error_msg.append("\t h5Space\n");
if(not error_msg.empty())
throw std::runtime_error(h5pp::format("Cannot read from dataset. The following fields are undefined:\n{}",error_msg));
if(not h5Type->valid() ) error_msg.append("\t h5Type\n");
if(not h5Space->valid() ) error_msg.append("\t h5Space\n");
if(not error_msg.empty())
throw std::runtime_error(h5pp::format("Cannot read from dataset [{}]. The following fields are not valid:\n{}",dsetPath.value(), error_msg));
if(not dsetExists.value())
throw std::runtime_error(h5pp::format("Cannot read from dataset [{}]: It does not exist", dsetPath.value()));
/* clang-format on */
}
[[nodiscard]] std::string string() const {
// std::string msg;
std::string msg;
/* clang-format off */
if(dsetSize) msg.append(h5pp::format(" | size {}", dsetSize.value()));
if(dsetByte) msg.append(h5pp::format(" | bytes {}", dsetByte.value()));
if(dsetRank) msg.append(h5pp::format(" | rank {}", dsetRank.value()));
if(dsetDims) msg.append(h5pp::format(" | dims {}", dsetDims.value()));
if(h5Layout){
msg.append(" | layout ");
switch(h5Layout.value()){
case H5D_CHUNKED: msg.append(h5pp::format("H5D_CHUNKED")); break;
case H5D_CONTIGUOUS: msg.append(h5pp::format("H5D_CONTIGUOUS")); break;
case H5D_COMPACT: msg.append(h5pp::format("H5D_COMPACT")); break;
default: break;
}
}
if(dsetChunk) msg.append(h5pp::format(" | chunk dims {}", dsetChunk.value()));
if(dsetDimsMax){
std::vector<long> maxDimsLong;
for(auto &dim : dsetDimsMax.value()) {
if(dim == H5S_UNLIMITED)
maxDimsLong.emplace_back(-1);
else
maxDimsLong.emplace_back(static_cast<long>(dim));
}
msg.append(h5pp::format(" | max dims {}", maxDimsLong));
}
if (h5Space and H5Sget_select_type(h5Space.value()) == H5S_sel_type::H5S_SEL_HYPERSLABS){
Hyperslab slab(h5Space.value());
msg.append(h5pp::format(" | [ Hyperslab {} ]", slab.string()));
}
if(resizeMode){
msg.append(" | resize mode ");
switch(resizeMode.value()){
case ResizeMode::RESIZE_TO_FIT: msg.append(h5pp::format("RESIZE_TO_FIT")); break;
case ResizeMode::INCREASE_ONLY: msg.append(h5pp::format("INCREASE_ONLY")); break;
case ResizeMode::DO_NOT_RESIZE: msg.append(h5pp::format("DO_NOT_RESIZE")); break;
default: break;
}
}
if(compression) msg.append(h5pp::format(" | compression {}", compression.value()));
if(dsetPath) msg.append(h5pp::format(" | dset path [{}]",dsetPath.value()));
if(cppTypeName) msg.append(h5pp::format(" | c++ type [{}]",cppTypeName.value()));
if(cppTypeSize) msg.append(h5pp::format(" | c++ size [{}] bytes",cppTypeSize.value()));
return msg;
/* clang-format on */
}
};
struct AttrInfo {
std::optional<hid::h5a> h5Attr = std::nullopt;
std::optional<hid::h5o> h5Link = std::nullopt;
std::optional<hid::h5t> h5Type = std::nullopt;
std::optional<hid::h5s> h5Space = std::nullopt;
std::optional<hid::h5p> h5PlistAttrCreate = std::nullopt;
std::optional<hid::h5p> h5PlistAttrAccess = std::nullopt;
std::optional<std::string> attrName = std::nullopt;
std::optional<std::string> linkPath = std::nullopt;
std::optional<bool> attrExists = std::nullopt;
std::optional<bool> linkExists = std::nullopt;
std::optional<hsize_t> attrSize = std::nullopt;
std::optional<size_t> attrByte = std::nullopt;
std::optional<int> attrRank = std::nullopt;
std::optional<std::vector<hsize_t>> attrDims = std::nullopt;
std::optional<Hyperslab> attrSlab = std::nullopt;
std::optional<std::string> cppTypeName = std::nullopt;
std::optional<size_t> cppTypeSize = std::nullopt;
std::optional<std::type_index> cppTypeIndex = std::nullopt;
void assertCreateReady() const {
std::string error_msg;
/* clang-format off */
if(not attrName ) error_msg.append("\t attrName\n");
if(not linkPath ) error_msg.append("\t linkPath\n");
if(not attrExists ) error_msg.append("\t attrExists\n");
if(not linkExists ) error_msg.append("\t linkExists\n");
if(not h5Link ) error_msg.append("\t h5Link\n");
if(not h5Type ) error_msg.append("\t h5Type\n");
if(not h5Space ) error_msg.append("\t h5Space\n");
if(not h5PlistAttrCreate) error_msg.append("\t h5PlistAttrCreate\n");
if(not h5PlistAttrAccess) error_msg.append("\t h5PlistAttrAccess\n");
if(not error_msg.empty())
throw std::runtime_error(h5pp::format("Cannot create attribute. The following fields are undefined:\n{}", error_msg));
if(not linkExists.value())
throw std::runtime_error(h5pp::format("Cannot create attribute [{}] for link [{}]. The link does not exist",attrName.value(),linkPath.value()));
if(not h5Link->valid() ) error_msg.append("\t h5Link\n");
if(not h5Type->valid() ) error_msg.append("\t h5Type\n");
if(not h5Space->valid() ) error_msg.append("\t h5Space\n");
if(not h5PlistAttrCreate->valid()) error_msg.append("\t h5PlistAttrCreate\n");
if(not h5PlistAttrAccess->valid()) error_msg.append("\t h5PlistAttrAccess\n");
if(not error_msg.empty())
throw std::runtime_error(h5pp::format("Cannot create attribute [{}] for link [{}]. The following fields are not valid: {}",attrName.value(),linkPath.value(),error_msg));
/* clang-format on */
}
void assertWriteReady() const {
std::string error_msg;
/* clang-format off */
if(not h5Attr ) error_msg.append("\t h5Attr\n");
if(not h5Type ) error_msg.append("\t h5Type\n");
if(not error_msg.empty())
throw std::runtime_error(h5pp::format("Cannot create attribute. The following fields are undefined:\n{}", error_msg));
if(not h5Attr->valid() ) error_msg.append("\t h5Attr\n");
if(not h5Type->valid() ) error_msg.append("\t h5Type\n");
if(not error_msg.empty())
throw std::runtime_error(h5pp::format("Cannot create attribute [{}] for link [{}]. The following fields are not valid: {}",attrName.value(),linkPath.value(),error_msg));
/* clang-format on */
}
void assertReadReady() const {
std::string error_msg;
/* clang-format off */
if(not h5Attr ) error_msg.append("\t h5Attr\n");
if(not h5Type ) error_msg.append("\t h5Type\n");
if(not h5Space ) error_msg.append("\t h5Space\n");
if(not error_msg.empty())
throw std::runtime_error(h5pp::format("Cannot create attribute. The following fields are undefined:\n{}",error_msg));
if(not h5Attr->valid() ) error_msg.append("\t h5Attr\n");
if(not h5Type->valid() ) error_msg.append("\t h5Type\n");
if(not error_msg.empty())
throw std::runtime_error(h5pp::format("Cannot create attribute [{}] for link [{}]. The following fields are not valid: {}",attrName.value(),linkPath.value(),error_msg));
/* clang-format on */
}
[[nodiscard]] std::string string() const {
std::string msg;
/* clang-format off */
if(attrSize) msg.append(h5pp::format(" | size {}", attrSize.value()));
if(attrByte) msg.append(h5pp::format(" | bytes {}", attrByte.value()));
if(attrRank) msg.append(h5pp::format(" | rank {}", attrRank.value()));
if(attrDims and not attrDims->empty())
msg.append(h5pp::format(" | dims {}", attrDims.value()));
if(attrName) msg.append(h5pp::format(" | name [{}]",attrName.value()));
if(linkPath) msg.append(h5pp::format(" | link [{}]",linkPath.value()));
return msg;
/* clang-format on */
}
};
struct TableInfo {
std::optional<size_t> numFields = std::nullopt;
std::optional<size_t> numRecords = std::nullopt;
std::optional<size_t> recordBytes = std::nullopt;
std::optional<std::vector<std::string>> fieldNames = std::nullopt;
std::optional<std::vector<size_t>> fieldSizes = std::nullopt;
std::optional<std::vector<size_t>> fieldOffsets = std::nullopt;
std::optional<std::vector<hid::h5t>> fieldTypes = std::nullopt;
std::optional<bool> tableExists = std::nullopt;
std::optional<std::string> tableTitle = std::nullopt;
std::optional<std::string> tablePath = std::nullopt;
std::optional<std::string> tableGroupName = std::nullopt;
std::optional<hid::h5f> tableFile = std::nullopt;
std::optional<hid::h5g> tableGroup = std::nullopt;
std::optional<hid::h5o> tableObjLoc = std::nullopt;
std::optional<hid::h5d> tableDset = std::nullopt;
std::optional<hid::h5t> tableType = std::nullopt;
std::optional<size_t> compressionLevel = std::nullopt;
std::optional<hsize_t> chunkSize = std::nullopt;
std::optional<std::vector<std::string>> cppTypeName = std::nullopt;
std::optional<std::vector<size_t>> cppTypeSize = std::nullopt;
std::optional<std::vector<std::type_index>> cppTypeIndex = std::nullopt;
[[nodiscard]] hid_t getTableLocId() const {
if(tableFile) return tableFile.value();
if(tableGroup) return tableGroup.value();
if(tableObjLoc) return tableObjLoc.value();
h5pp::logger::log->debug("Table location is not defined");
return -1;
}
/* clang-format off */
void assertCreateReady() const {
std::string error_msg;
if(not numFields) error_msg.append("\t numFields\n");
if(not numRecords) error_msg.append("\t numRecords\n");
if(not recordBytes) error_msg.append("\t recordBytes\n");
if(not fieldNames) error_msg.append("\t fieldNames\n");
if(not fieldSizes) error_msg.append("\t fieldSizes\n");
if(not fieldOffsets) error_msg.append("\t fieldOffsets\n");
if(not fieldTypes) error_msg.append("\t fieldTypes\n");
if(not tablePath) error_msg.append("\t tablePath\n");
if(not tableGroupName) error_msg.append("\t tableGroupName\n");
if(not tableTitle) error_msg.append("\t tableTitle\n");
if(not compressionLevel) error_msg.append("\t compressionLevel\n");
if(not chunkSize) error_msg.append("\t chunkSize\n");
if(not error_msg.empty()) throw std::runtime_error(h5pp::format("Cannot create new table: The following fields are not set:\n{}", error_msg));
}
void assertReadReady() const {
std::string error_msg;
if(not recordBytes) error_msg.append("\t recordBytes\n");
if(not fieldSizes) error_msg.append("\t fieldSizes\n");
if(not fieldOffsets) error_msg.append("\t fieldOffsets\n");
if(not tablePath) error_msg.append("\t tablePath\n");
if(not error_msg.empty()) throw std::runtime_error(h5pp::format("Cannot read from table: The following fields are not set:\n{}", error_msg));
if(getTableLocId() < 0) throw std::runtime_error(h5pp::format("Cannot read from table [{}]: The location ID is not set", tablePath.value()));
}
void assertWriteReady() const {
std::string error_msg;
if(not recordBytes) error_msg.append("\t recordBytes\n");
if(not fieldSizes) error_msg.append("\t fieldSizes\n");
if(not fieldOffsets) error_msg.append("\t fieldOffsets\n");
if(not tablePath) error_msg.append("\t tablePath\n");
if(not error_msg.empty()) throw std::runtime_error(h5pp::format("Cannot write to table: The following fields are not set:\n{}", error_msg));
if(getTableLocId() < 0) throw std::runtime_error(h5pp::format("Cannot write to table [{}]: The location ID is not set", tablePath.value()));
}
[[nodiscard]] std::string string() const {
std::string msg;
if(tableTitle) msg.append(h5pp::format("Table title [{}]", tableTitle.value()));
if(numFields) msg.append(h5pp::format(" | num fields [{}]", numFields.value()));
if(numRecords) msg.append(h5pp::format(" | num records [{}]", numRecords.value()));
if(chunkSize) msg.append(h5pp::format(" | chunk size [{}]", chunkSize.value()));
if(tablePath) msg.append(h5pp::format(" | path [{}]",tablePath.value()));
return msg;
}
/* clang-format on */
};
struct TypeInfo {
std::optional<std::string> cppTypeName;
std::optional<size_t> cppTypeBytes;
std::optional<std::type_index> cppTypeIndex;
std::optional<std::string> h5Path;
std::optional<std::string> h5Name;
std::optional<hsize_t> h5Size;
std::optional<int> h5Rank;
std::optional<std::vector<hsize_t>> h5Dims;
std::optional<hid::h5t> h5Type;
std::optional<hid::h5o> h5Link;
[[nodiscard]] std::string string() {
std::string msg;
if(cppTypeName) msg.append(h5pp::format("C++: type [{}]", cppTypeName.value()));
if(cppTypeBytes) msg.append(h5pp::format(" bytes [{}]", cppTypeBytes.value()));
if(not msg.empty()) msg.append(" | HDF5:");
if(h5Path) msg.append(h5pp::format(" path [{}]", h5Path.value()));
if(h5Name) msg.append(h5pp::format(" name [{}]", h5Name.value()));
if(h5Size) msg.append(h5pp::format(" size [{}]", h5Size.value()));
if(h5Rank) msg.append(h5pp::format(" rank [{}]", h5Rank.value()));
if(h5Dims) msg.append(h5pp::format(" dims {}", h5Dims.value()));
return msg;
}
};
}