ritsuko
Helper utilities for ArtifactDB C++ code
Loading...
Searching...
No Matches
Pointer.hpp
Go to the documentation of this file.
1#ifndef RITSUKO_CVLS_POINTER_HPP
2#define RITSUKO_CVLS_POINTER_HPP
3
4#include <stdexcept>
5#include <string>
6#include <cstddef>
7#include <limits>
8
9#include "H5Cpp.h"
10#include "sanisizer/sanisizer.hpp"
11
14#include "../hdf5/get_name.hpp"
15
21namespace ritsuko {
22
23namespace cvls {
24
34template<typename Offset_, typename Length_>
35struct Pointer {
40 Offset_ offset;
41
46 Length_ length;
47
51 static_assert(std::is_integral<Offset_>::value);
52 static_assert(std::is_unsigned<Offset_>::value);
53 static_assert(std::is_integral<Length_>::value);
54 static_assert(std::is_unsigned<Length_>::value);
58};
59
68template<typename Offset_, typename Length_>
70 typedef Pointer<Offset_, Length_> tmp;
71 H5::CompType pointer_type(sizeof(tmp));
72 pointer_type.insertMember("offset", HOFFSET(tmp, offset), hdf5::as_numeric_datatype<Offset_>());
73 pointer_type.insertMember("length", HOFFSET(tmp, length), hdf5::as_numeric_datatype<Length_>());
74 return pointer_type;
75}
76
88inline void validate_pointer_datatype(const H5::CompType& type, const std::size_t offset_precision, const std::size_t length_precision) {
89 if (type.getNmembers() != 2) {
90 throw std::runtime_error("expected compressed VLS compound datatype to have two members");
91 }
92
93 if (type.getMemberName(0) != "offset") {
94 throw std::runtime_error("first member of a compressed VLS compound datatype should be named 'offset'");
95 }
96 if (type.getMemberClass(0) != H5T_INTEGER) {
97 throw std::runtime_error("first member of a compressed VLS compound datatype should have integer type");
98 }
99 auto offset_type = type.getMemberIntType(0);
100 if (hdf5::exceeds_integer_limit(offset_type, offset_precision, false)) {
101 throw std::runtime_error("first member of a compressed VLS compound datatype should not exceed a " + std::to_string(offset_precision) + "-bit unsigned integer");
102 }
103
104 if (type.getMemberName(1) != "length") {
105 throw std::runtime_error("second member of a compressed VLS compound datatype should be named 'length'");
106 }
107 if (type.getMemberClass(1) != H5T_INTEGER) {
108 throw std::runtime_error("second member of a compressed VLS compound datatype should have integer type");
109 }
110 auto length_type = type.getMemberIntType(1);
111 if (hdf5::exceeds_integer_limit(length_type, length_precision, false)) {
112 throw std::runtime_error("second member of a VLS compound datatype should not exceed a " + std::to_string(length_precision) + "-bit unsigned integer");
113 }
114}
115
125inline void validate_pointer_datatype(const H5::DataSet& data, const std::size_t offset_precision, const std::size_t length_precision) {
126 if (data.getTypeClass() != H5T_COMPOUND) {
127 throw std::runtime_error("expected a compound datatype for a compressed VLS pointer dataset at '" + hdf5::get_name(data) + "'");
128 }
129
130 try {
131 validate_pointer_datatype(data.getCompType(), offset_precision, length_precision);
132 } catch (std::exception& e) {
133 std::string msg = e.what();
134 msg += " in '" + hdf5::get_name(data) + "'";
135 throw std::runtime_error(msg.c_str());
136 }
137}
138
147template<typename Offset_, typename Length_>
148bool is_Pointer_out_of_range(const Pointer<Offset_, Length_>& ptr, const hsize_t heap_length) {
149 // Some finesse is required here to avoid computing offset + length, as that might overflow.
150 return sanisizer::is_greater_than(ptr.offset, heap_length) || sanisizer::is_greater_than(ptr.length, heap_length - ptr.offset);
151}
152
153}
154
155}
156
157#endif
Choose a HDF5 datatype.
Check for larger-than-expected types in HDF5 datasets.
Get the name of a HDF5 object.
void validate_pointer_datatype(const H5::CompType &type, const std::size_t offset_precision, const std::size_t length_precision)
Definition Pointer.hpp:88
H5::CompType define_pointer_datatype()
Definition Pointer.hpp:69
bool is_Pointer_out_of_range(const Pointer< Offset_, Length_ > &ptr, const hsize_t heap_length)
Definition Pointer.hpp:148
std::string get_name(const Object_ &obj)
Definition get_name.hpp:29
const H5::PredType & as_numeric_datatype()
Definition as_numeric_datatype.hpp:27
bool exceeds_integer_limit(const H5::IntType &itype, std::size_t precision, bool is_signed)
Definition exceeds_limit.hpp:28
Helper functions for ArtifactDB parsing and validation.
Definition Pointer.hpp:21
Pointer into the compressed VLS heap.
Definition Pointer.hpp:35
Length_ length
Definition Pointer.hpp:46
Offset_ offset
Definition Pointer.hpp:40