|
| 1 | +submodule (h5fortran:hdf5_read) h5f_datatype |
| 2 | + |
| 3 | +implicit none |
| 4 | + |
| 5 | +contains |
| 6 | + |
| 7 | + |
| 8 | +module procedure get_class |
| 9 | + |
| 10 | +integer(HID_T) :: dset_id |
| 11 | +integer :: ier |
| 12 | + |
| 13 | +call H5Dopen_f(self%file_id, dname, dset_id, ier) |
| 14 | +call estop(ier, "get_class:H5Dopen", self%filename, dname) |
| 15 | + |
| 16 | +call get_obj_class(self, dname, dset_id, get_class) |
| 17 | + |
| 18 | +call H5Dclose_f(dset_id, ier) |
| 19 | +call estop(ier, "get_class:H5Dclose", self%filename, dname) |
| 20 | + |
| 21 | +end procedure get_class |
| 22 | + |
| 23 | + |
| 24 | +module procedure get_obj_class |
| 25 | + |
| 26 | +integer :: ier, obj_type |
| 27 | +integer(HID_T) :: obj_dtype, native_dtype |
| 28 | + |
| 29 | +call H5Iget_type_f(obj_id, obj_type, ier) |
| 30 | +call estop(ier, "get_obj_class:H5Iget_type", self%filename, obj_name) |
| 31 | + |
| 32 | +if(obj_type == H5I_DATASET_F) then |
| 33 | + call H5Dget_type_f(obj_id, obj_dtype, ier) |
| 34 | +elseif(obj_type == H5I_ATTR_F) then |
| 35 | + call H5Aget_type_f(obj_id, obj_dtype, ier) |
| 36 | +else |
| 37 | + error stop "ERROR:h5fortran:get_obj_class: only datasets and attributes have datatype " // obj_name // " " // self%filename |
| 38 | +endif |
| 39 | +call estop(ier, "get_obj_class:H5[A,D]get_type", self%filename, obj_name) |
| 40 | + |
| 41 | +call H5Tget_native_type_f(obj_dtype, H5T_DIR_ASCEND_F, native_dtype, ier) |
| 42 | +call estop(ier, "get_obj_class:H5Tget_native_type", self%filename, obj_name) |
| 43 | + |
| 44 | +!> compose datatype inferred |
| 45 | +call H5Tget_class_f(native_dtype, class, ier) |
| 46 | +call estop(ier, "get_obj_class:H5Tget_class", self%filename, obj_name) |
| 47 | + |
| 48 | +if(present(size_bytes)) then |
| 49 | + call H5Tget_size_f(native_dtype, size_bytes, ier) |
| 50 | + call estop(ier, "get_obj_class:H5Tget_size", self%filename, obj_name) |
| 51 | +endif |
| 52 | + |
| 53 | +call H5Tclose_f(native_dtype, ier) |
| 54 | +call estop(ier, "get_obj_class:H5Tclose", self%filename, obj_name) |
| 55 | + |
| 56 | +if(present(pad_type)) then |
| 57 | + if(class /= H5T_STRING_F) error stop "ERROR:h5fortran:get_class: pad_type only for string" |
| 58 | + |
| 59 | + call H5Tget_strpad_f(obj_dtype, pad_type, ier) |
| 60 | + call estop(ier, "get_obj_class:H5Tget_strpad", self%filename, obj_name) |
| 61 | +endif |
| 62 | + |
| 63 | +call H5Tclose_f(obj_dtype, ier) |
| 64 | +call estop(ier, "get_obj_class:H5Tclose", self%filename, obj_name) |
| 65 | + |
| 66 | +end procedure get_obj_class |
| 67 | + |
| 68 | + |
| 69 | +module procedure get_native_dtype |
| 70 | +!! get the dataset variable type: |
| 71 | +!! {H5T_NATIVE_REAL, H5T_NATIVE_DOUBLE, H5T_NATIVE_INTEGER, H5T_NATIVE_CHARACTER, H5T_STD_I64LE} |
| 72 | + |
| 73 | +integer :: class, ier |
| 74 | +! integer :: order, machine_order |
| 75 | +integer(size_t) :: size_bytes |
| 76 | +integer(HID_T) :: o_id |
| 77 | + |
| 78 | +if(present(obj_id)) then |
| 79 | + o_id = obj_id |
| 80 | +else |
| 81 | + !! assume dataset |
| 82 | + call H5Dopen_f(self%file_id, dname, o_id, ier) |
| 83 | + call estop(ier, "get_native_dtype:H5Dopen", self%filename, dname) |
| 84 | +endif |
| 85 | + |
| 86 | +call get_obj_class(self, dname, o_id, class, size_bytes=size_bytes) |
| 87 | + |
| 88 | +if(.not.present(obj_id)) then |
| 89 | + call H5Dclose_f(o_id, ier) |
| 90 | + call estop(ier, "get_native_dtype:H5Dclose", self%filename, dname) |
| 91 | +endif |
| 92 | + |
| 93 | +!> endianness and within type casting is handled by HDF5 |
| 94 | +! call h5tget_order_f(native_dtype, order, ier) |
| 95 | +! if(ier/=0) error stop 'ERROR:h5fortran:reader: get endianness ' // dname // ' from ' // self%filename |
| 96 | +! !> check dataset endianness matches machine (in future, could swap endianness if needed) |
| 97 | +! call h5tget_order_f(H5T_NATIVE_INTEGER, machine_order, ier) |
| 98 | +! if(order /= machine_order) error stop 'ERROR:h5fortran:read: endianness /= machine native: ' & |
| 99 | +! // dname // ' from ' // self%filename |
| 100 | + |
| 101 | +if(class == H5T_INTEGER_F) then |
| 102 | + if(size_bytes == 4) then |
| 103 | + get_native_dtype = H5T_NATIVE_INTEGER |
| 104 | + elseif(size_bytes == 8) then |
| 105 | + get_native_dtype = H5T_STD_I64LE |
| 106 | + else |
| 107 | + error stop "ERROR:h5fortran:get_native_dtype: expected 32-bit or 64-bit integer:" // dname // ' from ' // self%filename |
| 108 | + endif |
| 109 | +elseif(class == H5T_FLOAT_F) then |
| 110 | + if(size_bytes == 4) then |
| 111 | + get_native_dtype = H5T_NATIVE_REAL |
| 112 | + elseif(size_bytes == 8) then |
| 113 | + get_native_dtype = H5T_NATIVE_DOUBLE |
| 114 | + else |
| 115 | + error stop "ERROR:h5fortran:get_native_dtype: expected 32-bit or 64-bit real:" // dname // ' from ' // self%filename |
| 116 | + endif |
| 117 | +elseif(class == H5T_STRING_F) then |
| 118 | + get_native_dtype = H5T_NATIVE_CHARACTER |
| 119 | +else |
| 120 | + error stop "ERROR:h5fortran:get_native_dtype: non-handled datatype: " // dname // " from " // self%filename |
| 121 | +endif |
| 122 | + |
| 123 | +end procedure get_native_dtype |
| 124 | + |
| 125 | +end submodule h5f_datatype |
0 commit comments