85 std::vector<std::size_t> dims;
89 auto shandle = group.openDataSet(
"shape");
90 auto sspace = shandle.getSpace();
91 if (sspace.getSimpleExtentNdims() != 1) {
92 throw std::runtime_error(
"'shape' dataset should be 1-dimensional");
95 sspace.getSimpleExtentDims(&len);
97 throw std::runtime_error(
"'shape' dataset should have length 2");
100 if (version.lt(1, 1, 0)) {
101 dims = load_non_negative_integer_vector_0_99<std::size_t>(shandle, 2);
103 if (ritsuko::hdf5::exceeds_integer_limit(shandle, 64,
false)) {
104 throw std::runtime_error(
"'shape' should have a datatype that can fit into a 64-bit unsigned integer");
106 dims = load_dimensions_from_uint64_contents<std::size_t>(shandle, 2);
112 auto dhandle = group.openDataSet(
"data");
113 auto dspace = dhandle.getSpace();
114 if (dspace.getSimpleExtentNdims() != 1) {
115 throw std::runtime_error(
"'data' dataset should be 1-dimensional");
117 dspace.getSimpleExtentDims(&nnz);
119 if (version.lt(1, 1, 0)) {
120 array_type = translate_type_0_99(dhandle.getTypeClass());
121 if (is_boolean_0_99(dhandle)) {
122 array_type = BOOLEAN;
125 auto type = load_scalar_string_attribute(dhandle,
"type");
126 array_type = translate_type_1_1(type);
128 check_type_1_1(dhandle, array_type);
133 if (array_type != INTEGER && array_type != BOOLEAN && array_type != FLOAT) {
134 throw std::runtime_error(
"dataset should be integer, float or boolean");
136 validate_missing_placeholder(dhandle, version);
142 if (!version.lt(1, 1, 0)) {
143 auto bhandle = group.openDataSet(
"by_column");
144 if (bhandle.getSpace().getSimpleExtentNdims() != 0) {
145 throw std::runtime_error(
"'by_column' dataset should be scalar");
147 if (ritsuko::hdf5::exceeds_integer_limit(bhandle, 8,
true)) {
148 throw std::runtime_error(
"datatype of the 'by_column' dataset should fit into an 8-bit signed integer");
151 bhandle.read(&val, H5::PredType::NATIVE_INT8);
155 const auto primary = (csc ? dims[1] : dims[0]);
156 const auto secondary = (csc ? dims[0] : dims[1]);
158 std::vector<std::uint64_t> indptrs;
160 auto iphandle = group.openDataSet(
"indptr");
161 auto ipspace = iphandle.getSpace();
162 if (ipspace.getSimpleExtentNdims() != 1) {
163 throw std::runtime_error(
"'indptr' dataset should be 1-dimensional");
166 ipspace.getSimpleExtentDims(&iplen);
168 if (iplen == 0 || !sanisizer::is_equal(iplen - 1, primary)) {
169 throw std::runtime_error(
"'indptr' should have length equal to the number of " + (csc ? std::string(
"columns") : std::string(
"rows")) +
" plus 1");
172 if (version.lt(1, 1, 0)) {
173 if (iphandle.getTypeClass() != H5T_INTEGER) {
174 throw std::runtime_error(
"'indptr' should be integer");
176 indptrs = load_non_negative_integer_vector_0_99<std::uint64_t>(iphandle, iplen);
178 if (ritsuko::hdf5::exceeds_integer_limit(iphandle, 64,
false)) {
179 throw std::runtime_error(
"datatype of 'indptr' should fit into a 64-bit unsigned integer");
181 sanisizer::resize(indptrs, iplen);
182 iphandle.read(indptrs.data(), H5::PredType::NATIVE_UINT64);
185 iphandle.read(indptrs.data(), H5::PredType::NATIVE_UINT64);
186 if (indptrs[0] != 0) {
187 throw std::runtime_error(
"first entry of 'indptr' should be 0");
189 if (!sanisizer::is_equal(indptrs.back(), nnz)) {
190 throw std::runtime_error(
"last entry of 'indptr' should be equal to the length of 'data'");
195 auto ihandle = group.openDataSet(
"indices");
196 auto ispace = ihandle.getSpace();
197 if (ispace.getSimpleExtentNdims() != 1) {
198 throw std::runtime_error(
"'indices' dataset should be 1-dimensional");
201 ispace.getSimpleExtentDims(&inum);
203 throw std::runtime_error(
"'indices' and 'data' should have the same length");
206 if (version.lt(1, 1, 0)) {
207 if (!ritsuko::hdf5::exceeds_integer_limit(ihandle, 64,
true)) {
208 validate_sparse_indices<std::int64_t>(ihandle, indptrs, primary, secondary, csc);
209 }
else if (!ritsuko::hdf5::exceeds_integer_limit(ihandle, 64,
false)) {
210 validate_sparse_indices<std::uint64_t>(ihandle, indptrs, primary, secondary, csc);
212 throw std::runtime_error(
"'indices' should be integer");
216 if (ritsuko::hdf5::exceeds_integer_limit(ihandle, 64,
false)) {
217 throw std::runtime_error(
"datatype of 'indices' should fit into a 64-bit unsigned integer");
219 validate_sparse_indices<std::uint64_t>(ihandle, indptrs, primary, secondary, csc);
224 if (group.exists(
"dimnames")) {
225 validate_dimnames_internal(group, dims, version);