Skip to content

Commit 825693c

Browse files
committed
add %class method
1 parent 3de19cf commit 825693c

File tree

4 files changed

+76
-27
lines changed

4 files changed

+76
-27
lines changed

API.md

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -68,6 +68,15 @@ character(*), intent(in) :: dataset_name
6868
integer(HSIZE_T), intent(out), allocatable :: dims(:)
6969
```
7070

71+
Dataset "dname" data class (i.e. integer, float, string, ...)
72+
73+
```fortran
74+
integer :: class
75+
!! H5T_INTEGER_F, H5T_FLOAT_F, H5T_STRING_F
76+
class = h%class(dname)
77+
character(*), intent(in) :: dname
78+
```
79+
7180
Dataset "dname" datatype
7281

7382
```fortran

src/interface.f90

Lines changed: 8 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@ module h5fortran
66
H5S_ALL_F, H5S_SELECT_SET_F, &
77
H5D_CONTIGUOUS_F, H5D_CHUNKED_F, H5D_COMPACT_F, &
88
H5T_NATIVE_DOUBLE, H5T_NATIVE_REAL, H5T_NATIVE_INTEGER, H5T_NATIVE_CHARACTER, H5T_STD_I64LE, &
9+
H5T_INTEGER_F, H5T_FLOAT_F, H5T_STRING_F, &
910
H5F_SCOPE_GLOBAL_F, &
1011
h5open_f, h5close_f, &
1112
h5dopen_f, h5dclose_f, h5dget_space_f, &
@@ -22,6 +23,7 @@ module h5fortran
2223
public :: check, hdf_shape_check, hdf_rank_check, hdf_get_slice, hdf_wrapup
2324
!! for submodules only
2425
public :: HSIZE_T, HID_T, H5T_NATIVE_DOUBLE, H5T_NATIVE_REAL, H5T_NATIVE_INTEGER, H5T_NATIVE_CHARACTER, H5T_STD_I64LE
26+
public :: H5T_INTEGER_F, H5T_FLOAT_F, H5T_STRING_F
2527
!! HDF5 types for end users
2628

2729
!> main type
@@ -50,7 +52,7 @@ module h5fortran
5052
flush => hdf_flush, &
5153
ndims => hdf_get_ndims, &
5254
shape => hdf_get_shape, layout => hdf_get_layout, chunks => hdf_get_chunk, &
53-
dtype => get_native_dtype, &
55+
class => get_class, dtype => get_native_dtype, &
5456
exist => hdf_check_exist, exists => hdf_check_exist, &
5557
is_contig => hdf_is_contig, is_chunked => hdf_is_chunked, is_compact => hdf_is_compact, &
5658
softlink => create_softlink
@@ -304,6 +306,11 @@ end subroutine h5write_7d
304306

305307
interface !< read.f90
306308

309+
module integer function get_class(self, dname)
310+
class(hdf5_file), intent(in) :: self
311+
character(*), intent(in) :: dname
312+
end function get_class
313+
307314
module integer(hid_t) function get_native_dtype(self, dname, ds_id)
308315
class(hdf5_file), intent(in) :: self
309316
character(*), intent(in) :: dname

src/read/read.f90

Lines changed: 51 additions & 26 deletions
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@
33
use hdf5, only : h5dget_create_plist_f, &
44
h5pget_layout_f, h5pget_chunk_f, &
55
h5dget_type_f, h5tget_native_type_f, h5tget_class_f, H5Tget_order_f, h5tclose_f, h5tget_size_f, &
6-
H5T_DIR_ASCEND_F, H5T_INTEGER_F, H5T_FLOAT_F, H5T_STRING_F
6+
H5T_DIR_ASCEND_F
77

88
use H5LT, only : h5ltpath_valid_f
99

@@ -12,54 +12,79 @@
1212
contains
1313

1414

15-
module procedure get_native_dtype
16-
!! get the dataset variable type:
17-
!! {H5T_NATIVE_REAL, H5T_NATIVE_DOUBLE, H5T_NATIVE_INTEGER, H5T_NATIVE_CHARACTER, H5T_STD_I64LE}
15+
module procedure get_class
16+
17+
call get_dset_class(self, dname, get_class)
18+
19+
end procedure get_class
20+
21+
22+
subroutine get_dset_class(self, dname, class, ds_id, size_bytes)
23+
!! get the dataset class (integer, float, string, ...)
24+
!! {H5T_INTEGER_F, H5T_FLOAT_F, H5T_STRING_F}
25+
class(hdf5_file), intent(in) :: self
26+
character(*), intent(in) :: dname
27+
integer, intent(out) :: class
28+
integer(hid_t), intent(in), optional :: ds_id
29+
integer(size_t), intent(out), optional :: size_bytes
1830

19-
integer(hid_t) :: dtype_id, native_dtype_id, dset_id
20-
integer :: class
2131
integer :: ierr
22-
! integer :: order, machine_order
23-
integer(size_t) :: size_bytes
32+
integer(hid_t) :: dtype_id, native_dtype_id, dset_id
2433

2534
if(present(ds_id)) then
2635
dset_id = ds_id
2736
else
2837
call h5dopen_f(self%lid, dname, dset_id, ierr)
29-
if(ierr/=0) error stop 'h5fortran:get_native_dtype: ' // dname // ' from ' // self%filename
38+
if(ierr/=0) error stop 'h5fortran:get_class: ' // dname // ' from ' // self%filename
3039
endif
3140

3241
call h5dget_type_f(dset_id, dtype_id, ierr)
33-
if(ierr/=0) error stop 'h5fortran:get_native_dtype: dtype_id ' // dname // ' from ' // self%filename
42+
if(ierr/=0) error stop 'h5fortran:get_class: dtype_id ' // dname // ' from ' // self%filename
3443

3544
call h5tget_native_type_f(dtype_id, H5T_DIR_ASCEND_F, native_dtype_id, ierr)
36-
if(ierr/=0) error stop 'h5fortran:get_native_dtype: native_dtype_id ' // dname // ' from ' // self%filename
37-
38-
!> endianness and within type casting is handled by HDF5
39-
! call h5tget_order_f(native_dtype_id, order, ierr)
40-
! if(ierr/=0) error stop 'h5fortran:reader: get endianness ' // dname // ' from ' // self%filename
41-
! !> check dataset endianness matches machine (in future, could swap endianness if needed)
42-
! call h5tget_order_f(H5T_NATIVE_INTEGER, machine_order, ierr)
43-
! if(order /= machine_order) error stop 'h5fortran:read: endianness /= machine native: ' &
44-
! // dname // ' from ' // self%filename
45+
if(ierr/=0) error stop 'h5fortran:get_class: native_dtype_id ' // dname // ' from ' // self%filename
4546

4647
!> compose datatype inferred
4748
call h5tget_class_f(native_dtype_id, class, ierr)
48-
if(ierr/=0) error stop 'h5fortran:get_native_dtype: class ' // dname // ' from ' // self%filename
49+
if(ierr/=0) error stop 'h5fortran:get_class: class ' // dname // ' from ' // self%filename
4950

50-
call h5tget_size_f(native_dtype_id, size_bytes, ierr)
51-
if(ierr/=0) error stop 'h5fortran:get_native_dtype: byte size ' // dname // ' from ' // self%filename
51+
if(present(size_bytes)) then
52+
call h5tget_size_f(native_dtype_id, size_bytes, ierr)
53+
if(ierr/=0) error stop 'h5fortran:get_class: byte size ' // dname // ' from ' // self%filename
54+
endif
5255

5356
!> close to avoid memory leaks
54-
call h5tclose_f(dtype_id, ierr)
55-
if(ierr/=0) error stop 'h5fortran:get_native_dtype: closing dtype ' // dname // ' from ' // self%filename
5657
call h5tclose_f(native_dtype_id, ierr)
57-
if(ierr/=0) error stop 'h5fortran:get_native_dtype: closing native dtype ' // dname // ' from ' // self%filename
58+
if(ierr/=0) error stop 'h5fortran:get_class: closing native dtype ' // dname // ' from ' // self%filename
59+
60+
call h5tclose_f(dtype_id, ierr)
61+
if(ierr/=0) error stop 'h5fortran:get_class: closing dtype ' // dname // ' from ' // self%filename
62+
5863
if(.not.present(ds_id)) then
5964
call h5dclose_f(dset_id, ierr)
60-
if(ierr/=0) error stop 'h5fortran:get_native_dtype: close dataset ' // dname // ' from ' // self%filename
65+
if(ierr/=0) error stop 'h5fortran:get_class: close dataset ' // dname // ' from ' // self%filename
6166
endif
6267

68+
end subroutine get_dset_class
69+
70+
71+
module procedure get_native_dtype
72+
!! get the dataset variable type:
73+
!! {H5T_NATIVE_REAL, H5T_NATIVE_DOUBLE, H5T_NATIVE_INTEGER, H5T_NATIVE_CHARACTER, H5T_STD_I64LE}
74+
75+
integer :: class
76+
! integer :: order, machine_order
77+
integer(size_t) :: size_bytes
78+
79+
call get_dset_class(self, dname, class, ds_id, size_bytes)
80+
81+
!> endianness and within type casting is handled by HDF5
82+
! call h5tget_order_f(native_dtype_id, order, ierr)
83+
! if(ierr/=0) error stop 'h5fortran:reader: get endianness ' // dname // ' from ' // self%filename
84+
! !> check dataset endianness matches machine (in future, could swap endianness if needed)
85+
! call h5tget_order_f(H5T_NATIVE_INTEGER, machine_order, ierr)
86+
! if(order /= machine_order) error stop 'h5fortran:read: endianness /= machine native: ' &
87+
! // dname // ' from ' // self%filename
6388

6489
if(class == H5T_INTEGER_F) then
6590
if(size_bytes == 4) then

src/tests/test_cast.f90

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@ program test_cast
22
!! test HDF5 built-in casting
33

44
use h5fortran, only : hdf5_file, &
5+
H5T_INTEGER_F, H5T_FLOAT_F, H5T_STRING_F, &
56
H5T_NATIVE_REAL, H5T_NATIVE_DOUBLE, H5T_NATIVE_INTEGER, H5T_NATIVE_CHARACTER, H5T_STD_I64LE
67
use, intrinsic :: iso_fortran_env, only : real32, real64, int32, int64
78

@@ -29,6 +30,13 @@ program test_cast
2930
call h%write('/1d_int32', i1_32)
3031
call h%write('/char', "hello")
3132

33+
!> %class method
34+
if (h%class("/scalar_int32") /= H5T_INTEGER_F) error stop "int32 not integer"
35+
if (h%class("/scalar_int64") /= H5T_INTEGER_F) error stop "int64 not integer"
36+
if (h%class("/scalar_real32") /= H5T_FLOAT_F) error stop "real32 not float"
37+
if (h%class("/scalar_real64") /= H5T_FLOAT_F) error stop "real64 not float"
38+
if (h%class("/char") /= H5T_STRING_F) error stop "char not string"
39+
3240
!> %dtype method
3341
if (h%dtype('/scalar_int32') /= H5T_NATIVE_INTEGER) error stop "int32 type"
3442
if (h%dtype("/scalar_int64") /= H5T_STD_I64LE) error stop "int64 type"

0 commit comments

Comments
 (0)