21 static constexpr bool value =
22 std::is_same<typename inspector<T>::base_type, std::string>::value;
25template <
class T,
class V =
void>
26struct enable_shallow_copy
27 :
public std::enable_if<!is_std_string<T>::value && inspector<T>::is_trivially_copyable, V> {};
29template <
class T,
class V =
void>
30struct enable_deep_copy
31 :
public std::enable_if<!is_std_string<T>::value && !inspector<T>::is_trivially_copyable, V> {};
33template <
class T,
class V =
void>
34struct enable_string_copy:
public std::enable_if<is_std_string<T>::value, V> {};
37template <
typename T,
bool IsReadOnly>
38struct ShallowCopyBuffer {
39 using type = unqualified_t<T>;
41 typename std::conditional<IsReadOnly,
42 typename std::add_const<typename inspector<T>::hdf5_type>::type,
43 typename inspector<T>::hdf5_type>::type;
45 ShallowCopyBuffer() =
delete;
47 explicit ShallowCopyBuffer(
typename std::conditional<IsReadOnly, const T&, T&>::type val)
48 : ptr(inspector<T>::data(val)){};
50 hdf5_type* getPointer()
const {
54 hdf5_type* begin()
const {
58 void unserialize(T& )
const {
67struct DeepCopyBuffer {
68 using type = unqualified_t<T>;
69 using hdf5_type =
typename inspector<type>::hdf5_type;
71 explicit DeepCopyBuffer(
const std::vector<size_t>& _dims)
72 : buffer(inspector<T>::
getSize(_dims))
75 hdf5_type* getPointer() {
79 hdf5_type
const* getPointer()
const {
87 hdf5_type
const* begin()
const {
91 void unserialize(T& val)
const {
92 inspector<type>::unserialize(buffer.data(), dims, val);
96 std::vector<hdf5_type> buffer;
97 std::vector<size_t> dims;
100enum class BufferMode { Read, Write };
106inline size_t char_buffer_length(
char const*
const str,
size_t max_string_size) {
107 for (
size_t i = 0; i < max_string_size; ++i) {
108 if (str[i] ==
'\0') {
113 return max_string_size;
164template <
typename T, BufferMode buffer_mode>
166 using type = unqualified_t<T>;
167 using hdf5_type =
typename inspector<type>::hdf5_type;
171 StringView(StringBuffer<T, buffer_mode>& _buffer,
size_t _i)
182 void assign(
char const* data,
size_t length,
StringPadding pad) {
183 if (buffer.isVariableLengthString()) {
185 buffer.variable_length_pointers[i] = data;
187 buffer.variable_length_buffer[i] = std::string(data, length);
188 buffer.variable_length_pointers[i] = buffer.variable_length_buffer[i].data();
190 }
else if (buffer.isFixedLengthString()) {
193 if (length > buffer.string_max_length) {
194 throw std::invalid_argument(
"String length too big.");
197 memcpy(&buffer.fixed_length_buffer[i * buffer.string_size], data, length);
202 StringBuffer<T, buffer_mode>& buffer;
207 class StringConstView {
209 StringConstView(
const StringBuffer<T, buffer_mode>& _buffer,
size_t _i)
216 char const* data()
const {
217 if (buffer.isVariableLengthString()) {
218 return buffer.variable_length_pointers[i];
220 return &buffer.fixed_length_buffer[i * buffer.string_size];
230 size_t length()
const {
231 if (buffer.isNullTerminated()) {
232 return char_buffer_length(data(), buffer.string_size);
234 return buffer.string_max_length;
239 const StringBuffer<T, buffer_mode>& buffer;
246 Iterator(StringBuffer<T, buffer_mode>& _buffer,
size_t _pos)
250 Iterator operator+(
size_t n_strings)
const {
251 return Iterator(buffer, pos + n_strings);
254 void operator+=(
size_t n_strings) {
258 StringView operator*() {
259 return StringView(buffer, pos);
262 StringConstView operator*()
const {
263 return StringConstView(buffer, pos);
267 StringBuffer<T, buffer_mode>& buffer;
271 StringBuffer(std::vector<size_t> _dims,
const DataType& _file_datatype)
272 : file_datatype(_file_datatype.asStringType())
273 , padding(file_datatype.getPadding())
274 , string_size(file_datatype.isVariableStr() ? size_t(-1) : file_datatype.
getSize())
275 , string_max_length(string_size - size_t(isNullTerminated()))
277 if (string_size == 0 && isNullTerminated()) {
278 throw DataTypeException(
279 "Fixed-length, null-terminated need at least one byte to store the "
284 if (isVariableLengthString()) {
285 variable_length_buffer.resize(n_strings);
286 variable_length_pointers.resize(n_strings);
289 fixed_length_buffer.assign(n_strings * string_size, pad);
293 bool isVariableLengthString()
const {
294 return file_datatype.isVariableStr();
297 bool isFixedLengthString()
const {
298 return file_datatype.isFixedLenStr();
301 bool isNullTerminated()
const {
307 if (file_datatype.isVariableStr()) {
308 return variable_length_pointers.data();
310 return fixed_length_buffer.data();
315 return Iterator(*
this, 0ul);
318 void unserialize(T& val) {
319 inspector<type>::unserialize(begin(), dims, val);
323 StringType file_datatype;
329 size_t string_max_length;
330 std::vector<size_t> dims;
332 std::vector<char> fixed_length_buffer;
333 std::vector<std::string> variable_length_buffer;
335 typename std::conditional<buffer_mode == BufferMode::Write, const char, char>::type*>
336 variable_length_pointers;
340template <
typename T,
typename Enable =
void>
344struct Writer<T, typename enable_shallow_copy<T>::type>:
public ShallowCopyBuffer<T, true> {
346 using super = ShallowCopyBuffer<T, true>;
349 explicit Writer(
const T& val,
const DataType& )
354struct Writer<T, typename enable_deep_copy<T>::type>:
public DeepCopyBuffer<T> {
355 explicit Writer(
const T& val,
const DataType& )
356 : DeepCopyBuffer<T>(inspector<T>::getDimensions(val)) {
357 inspector<T>::serialize(val, this->begin());
362struct Writer<T, typename enable_string_copy<T>::type>:
public StringBuffer<T, BufferMode::Write> {
363 explicit Writer(
const T& val,
const DataType& _file_datatype)
364 : StringBuffer<T, BufferMode::Write>(inspector<T>::getDimensions(val), _file_datatype) {
365 inspector<T>::serialize(val, this->begin());
369template <
typename T,
typename Enable =
void>
373struct Reader<T, typename enable_shallow_copy<T>::type>:
public ShallowCopyBuffer<T, false> {
375 using super = ShallowCopyBuffer<T, false>;
376 using type =
typename super::type;
379 Reader(
const std::vector<size_t>&, type& val,
const DataType& )
384struct Reader<T, typename enable_deep_copy<T>::type>:
public DeepCopyBuffer<T> {
386 using super = DeepCopyBuffer<T>;
387 using type =
typename super::type;
390 Reader(
const std::vector<size_t>& _dims, type&,
const DataType& )
396struct Reader<T, typename enable_string_copy<T>::type>:
public StringBuffer<T, BufferMode::Write> {
398 explicit Reader(
const std::vector<size_t>& _dims,
400 const DataType& _file_datatype)
401 : StringBuffer<T, BufferMode::Write>(_dims, _file_datatype) {}
404struct data_converter {
405 template <
typename T>
406 static Writer<T> serialize(
const typename inspector<T>::type& val,
407 const DataType& file_datatype) {
408 return Writer<T>(val, file_datatype);
411 template <
typename T>
412 static Reader<T> get_reader(
const std::vector<size_t>& dims,
414 const DataType& file_datatype) {
416 auto effective_dims = details::squeezeDimensions(dims, inspector<T>::recursive_ndim);
417 inspector<T>::prepare(val, effective_dims);
418 return Reader<T>(effective_dims, val, file_datatype);
size_t getSize(const File &file, const std::string &path)
Definition H5Easy_public.hpp:82
Definition H5_definitions.hpp:22
StringPadding
Definition string_padding.hpp:7
size_t compute_total_size(const std::vector< size_t > &dims)
Definition H5Inspector_decl.hpp:10