ritsuko
Helper utilities for ArtifactDB C++ code
Loading...
Searching...
No Matches
validate_string.hpp
Go to the documentation of this file.
1#ifndef RITSUKO_HDF5_VALIDATE_STRING_HPP
2#define RITSUKO_HDF5_VALIDATE_STRING_HPP
3
4#include <string>
5#include <vector>
6#include <stdexcept>
7
8#include "H5Cpp.h"
9
10#include "get_name.hpp"
11#include "get_1d_length.hpp"
12#include "get_dimensions.hpp"
15#include "IterateNdDataset.hpp"
16#include "_strings.hpp"
17
23namespace ritsuko {
24
25namespace hdf5 {
26
34inline void validate_scalar_string_dataset(const H5::DataSet& handle) {
35 auto dtype = handle.getDataType();
36 if (!dtype.isVariableStr()) {
37 return;
38 }
39
40 char* vptr;
41 handle.read(&vptr, dtype);
42 auto dspace = handle.getSpace(); // don't set as temporary in constructor below, otherwise it gets destroyed and the ID invalidated.
43 [[maybe_unused]] VariableStringCleaner deletor(dtype.getId(), dspace.getId(), &vptr);
44 if (vptr == NULL) {
45 throw std::runtime_error("detected a NULL pointer for a variable length string in '" + get_name(handle) + "'");
46 }
47}
48
58inline void validate_1d_string_dataset(const H5::DataSet& handle, hsize_t full_length, hsize_t buffer_size) {
59 auto dtype = handle.getDataType();
60 if (!dtype.isVariableStr()) {
61 return;
62 }
63
64 hsize_t block_size = pick_1d_block_size(handle.getCreatePlist(), full_length, buffer_size);
65 H5::DataSpace mspace(1, &block_size), dspace(1, &full_length);
66 std::vector<char*> buffer(block_size);
67
68 for (hsize_t i = 0; i < full_length; i += block_size) {
69 auto available = std::min(full_length - i, block_size);
70 constexpr hsize_t zero = 0;
71 mspace.selectHyperslab(H5S_SELECT_SET, &available, &zero);
72 dspace.selectHyperslab(H5S_SELECT_SET, &available, &i);
73
74 handle.read(buffer.data(), dtype, mspace, dspace);
75 [[maybe_unused]] VariableStringCleaner deletor(dtype.getId(), mspace.getId(), buffer.data());
76 for (hsize_t j = 0; j < available; ++j) {
77 if (buffer[j] == NULL) {
78 throw std::runtime_error("detected a NULL pointer for a variable length string in '" + get_name(handle) + "'");
79 }
80 }
81 }
82}
83
89inline void validate_1d_string_dataset(const H5::DataSet& handle, hsize_t buffer_size) {
90 validate_1d_string_dataset(handle, get_1d_length(handle, false), buffer_size);
91}
92
102inline void validate_nd_string_dataset(const H5::DataSet& handle, const std::vector<hsize_t>& dimensions, hsize_t buffer_size) {
103 auto stype = handle.getDataType();
104 if (!stype.isVariableStr()) {
105 return;
106 }
107
108 auto blocks = pick_nd_block_dimensions(handle.getCreatePlist(), dimensions, buffer_size);
109 IterateNdDataset iter(dimensions, blocks);
110 std::vector<char*> buffer;
111
112 while (!iter.finished()) {
113 buffer.resize(iter.current_block_size());
114
115 // Scope this to ensure that 'mspace' doesn't get changed by
116 // 'iter.next()' before the destructor is called.
117 {
118 const auto& mspace = iter.memory_space();
119 [[maybe_unused]] VariableStringCleaner stream(stype.getId(), mspace.getId(), buffer.data());
120 handle.read(buffer.data(), stype, mspace, iter.file_space());
121 for (auto x : buffer) {
122 if (x == NULL) {
123 throw std::runtime_error("detected NULL pointer in a variable-length string dataset");
124 }
125 }
126 }
127
128 iter.next();
129 }
130}
131
137inline void validate_nd_string_dataset(const H5::DataSet& handle, hsize_t buffer_size) {
138 auto dimensions = get_dimensions(handle, false);
139 validate_nd_string_dataset(handle, dimensions, buffer_size);
140}
141
149inline void validate_scalar_string_attribute(const H5::Attribute& attr) {
150 auto dtype = attr.getDataType();
151 if (!dtype.isVariableStr()) {
152 return;
153 }
154
155 auto mspace = attr.getSpace();
156 char* buffer;
157 attr.read(dtype, &buffer);
158 [[maybe_unused]] VariableStringCleaner deletor(dtype.getId(), mspace.getId(), &buffer);
159 if (buffer == NULL) {
160 throw std::runtime_error("detected a NULL pointer for a variable length string attribute");
161 }
162}
163
172inline void validate_1d_string_attribute(const H5::Attribute& attr, hsize_t full_length) {
173 auto dtype = attr.getDataType();
174 if (!dtype.isVariableStr()) {
175 return;
176 }
177
178 auto mspace = attr.getSpace();
179 std::vector<char*> buffer(full_length);
180 attr.read(dtype, buffer.data());
181 [[maybe_unused]] VariableStringCleaner deletor(dtype.getId(), mspace.getId(), buffer.data());
182 for (hsize_t i = 0; i < full_length; ++i) {
183 if (buffer[i] == NULL) {
184 throw std::runtime_error("detected a NULL pointer for a variable length string attribute");
185 }
186 }
187}
188
193inline void validate_1d_string_attribute(const H5::Attribute& attr) {
195}
196
197}
198
199}
200
201#endif
Iterate through an N-dimensional dataset by block.
Get the length of a 1-dimensional HDF5 dataset.
Get the dimensions of a HDF5 dataset.
Get the name of a HDF5 object.
std::string get_name(const Handle_ &handle)
Definition get_name.hpp:24
hsize_t pick_1d_block_size(const H5::DSetCreatPropList &cplist, hsize_t full_length, hsize_t buffer_size=10000)
Definition pick_1d_block_size.hpp:26
void validate_1d_string_dataset(const H5::DataSet &handle, hsize_t full_length, hsize_t buffer_size)
Definition validate_string.hpp:58
void validate_scalar_string_attribute(const H5::Attribute &attr)
Definition validate_string.hpp:149
void validate_1d_string_attribute(const H5::Attribute &attr, hsize_t full_length)
Definition validate_string.hpp:172
void validate_nd_string_dataset(const H5::DataSet &handle, const std::vector< hsize_t > &dimensions, hsize_t buffer_size)
Definition validate_string.hpp:102
void validate_scalar_string_dataset(const H5::DataSet &handle)
Definition validate_string.hpp:34
hsize_t get_1d_length(const H5::DataSpace &space, bool allow_scalar)
Definition get_1d_length.hpp:25
std::vector< hsize_t > pick_nd_block_dimensions(const H5::DSetCreatPropList &cplist, const std::vector< hsize_t > &dimensions, hsize_t buffer_size=10000)
Definition pick_nd_block_dimensions.hpp:26
std::vector< hsize_t > get_dimensions(const H5::DataSpace &space, bool allow_scalar)
Definition get_dimensions.hpp:25
Assorted helper functions for parsing and validation.
Definition choose_missing_placeholder.hpp:15
Pick a block size for a 1-dimensional HDF5 dataset.
Pick block dimensions for an N-dimensional HDF5 dataset.
Iterate through an N-dimensional dataset by block.
Definition IterateNdDataset.hpp:25
const H5::DataSpace & memory_space() const
Definition IterateNdDataset.hpp:132
bool finished() const
Definition IterateNdDataset.hpp:92
const H5::DataSpace & file_space() const
Definition IterateNdDataset.hpp:124
size_t current_block_size() const
Definition IterateNdDataset.hpp:101
void next()
Definition IterateNdDataset.hpp:55