|
8 | 8 | h5fget_obj_count_f, h5fget_obj_ids_f, h5fget_name_f, &
|
9 | 9 | h5sselect_hyperslab_f, h5screate_simple_f, &
|
10 | 10 | H5Sget_simple_extent_ndims_f, H5Sget_simple_extent_dims_f, H5Sget_simple_extent_npoints_f, &
|
11 |
| -H5F_ACC_RDONLY_F, H5F_ACC_RDWR_F, H5F_ACC_TRUNC_F, & |
| 11 | +H5F_ACC_RDONLY_F, H5F_ACC_RDWR_F, H5F_ACC_TRUNC_F, H5F_ACC_EXCL_F, & |
12 | 12 | H5F_OBJ_FILE_F, H5F_OBJ_GROUP_F, H5F_OBJ_DATASET_F, H5F_OBJ_DATATYPE_F, H5F_OBJ_ALL_F, &
|
13 | 13 | H5D_CONTIGUOUS_F, H5D_CHUNKED_F, H5D_COMPACT_F, &
|
14 | 14 | H5I_FILE_F, &
|
|
35 | 35 |
|
36 | 36 | module procedure h5open
|
37 | 37 |
|
38 |
| -character(2) :: laction |
39 | 38 | integer :: ier
|
40 | 39 | integer(HID_T) :: fapl !< file access property list
|
41 |
| -integer :: file_mode |
42 | 40 |
|
43 | 41 | if(present(ok)) ok = .true.
|
44 | 42 |
|
| 43 | +if(present(debug)) self%debug = debug |
| 44 | + |
45 | 45 | if(self%is_open()) then
|
46 |
| - write(stderr, '(a)') 'NOTICE:h5fortran:open: file handle already open: '//self%filename |
| 46 | + write(stderr, '(a)') 'NOTICE:h5fortran:open: file handle already open: '//filename |
47 | 47 | return
|
48 | 48 | endif
|
49 | 49 |
|
50 |
| -laction = 'r' |
51 |
| -if (present(action)) laction = action |
| 50 | +!> Initialize FORTRAN interface |
| 51 | +!! HDF5 1.14.0 introduced bug that if H5open_f is called more than once, |
| 52 | +!! it will error. |
| 53 | +if (.not. hdf5_is_initialized()) then |
| 54 | + if(self%debug) print '(a)', 'TRACE:h5fortran:h5open: initializing HDF5 library' |
| 55 | + call H5open_f(ier) |
| 56 | + call estop(ier, 'h5open:H5open HDF5 library initialize', filename, ok=ok) |
| 57 | + if (present(ok)) then |
| 58 | + if (.not. ok) return |
| 59 | + endif |
| 60 | +endif |
52 | 61 |
|
53 |
| -self%filename = filename |
| 62 | +!! these enums will all be 0 if h5open_f isn't called first |
| 63 | +! print *, "TRACE: H5F_ACC_RDONLY_F = ", H5F_ACC_RDONLY_F |
| 64 | +! print *, "TRACE: H5F_ACC_RDWR_F = ", H5F_ACC_RDWR_F |
| 65 | +! print *, "TRACE: H5F_ACC_TRUNC_F = ", H5F_ACC_TRUNC_F |
54 | 66 |
|
55 |
| -if(present(debug)) self%debug = debug |
| 67 | +if (present(action)) then |
| 68 | + select case(action) |
| 69 | + case('r') |
| 70 | + self%file_mode = H5F_ACC_RDONLY_F |
| 71 | + case('r+') |
| 72 | + self%file_mode = H5F_ACC_RDWR_F |
| 73 | + case('rw', 'a') |
| 74 | + if(is_hdf5(filename)) then |
| 75 | + self%file_mode = H5F_ACC_RDWR_F |
| 76 | + else |
| 77 | + self%file_mode = H5F_ACC_TRUNC_F |
| 78 | + endif |
| 79 | + case ('w') |
| 80 | + self%file_mode = H5F_ACC_TRUNC_F |
| 81 | + case default |
| 82 | + call estop(ier, 'ERROR:h5fortran:open Unsupported action=' // action, filename, ok=ok) |
| 83 | + if (present(ok)) then |
| 84 | + if(.not. ok) return |
| 85 | + endif |
| 86 | + end select |
| 87 | +elseif (allocated(self%filename)) then |
| 88 | + if(self%filename == filename .and. any(self%file_mode == [H5F_ACC_RDONLY_F, H5F_ACC_RDWR_F])) then |
| 89 | + if(self%debug) print '(3a,i0)', 'NOTICE:h5fortran:open: ', filename, ' reusing file mode ', self%file_mode |
| 90 | + else |
| 91 | + if (self%debug) print '(a)', 'TRACE:h5fortran:open: opening file: '//filename // & |
| 92 | + ' read only as this is a different filename than previously used with this file handle' |
| 93 | + self%file_mode = H5F_ACC_RDONLY_F |
| 94 | + endif |
| 95 | +else |
| 96 | + if (self%debug) print '(a)', 'TRACE:h5fortran:open: opening file: '//filename // & |
| 97 | + ' read only as no file mode is specified and no previous file handle exists' |
| 98 | + self%file_mode = H5F_ACC_RDONLY_F |
| 99 | +endif |
| 100 | + |
| 101 | + |
| 102 | + |
| 103 | +self%filename = filename |
| 104 | +!! do this AFTER the action= switch |
56 | 105 |
|
57 | 106 | !> compression parameter
|
58 |
| -if(present(comp_lvl) .and. laction /= "r") self%comp_lvl = comp_lvl |
| 107 | +if(present(comp_lvl) .and. self%file_mode /= H5F_ACC_RDONLY_F) self%comp_lvl = comp_lvl |
| 108 | + |
59 | 109 | if(self%comp_lvl > 0) then
|
60 | 110 | self%shuffle = .true.
|
61 | 111 | self%fletcher32 = .true.
|
|
72 | 122 | self%comp_lvl = 9
|
73 | 123 | endif
|
74 | 124 |
|
75 |
| -!> Initialize FORTRAN interface |
76 |
| -!! HDF5 1.14.0 introduced bug that if H5open_f is called more than once, |
77 |
| -!! it will error. |
78 |
| -if (.not. hdf5_is_initialized()) then |
79 |
| - if(self%debug) print '(a)', 'TRACE:h5fortran:h5open: initializing HDF5 library' |
80 |
| - call H5open_f(ier) |
81 |
| - call estop(ier, 'h5open:H5open HDF5 library initialize', filename, ok=ok) |
82 |
| - if (present(ok)) then |
83 |
| - if (.not. ok) return |
84 |
| - endif |
85 |
| -endif |
86 |
| - |
87 | 125 | if(self%debug) then
|
88 | 126 | call H5Eset_auto_f(1, ier)
|
89 | 127 | else
|
90 | 128 | call H5Eset_auto_f(0, ier)
|
91 | 129 | endif
|
92 |
| -call estop(ier, 'h5open:H5Eset_auto: HDF5 library set traceback', filename, ok=ok) |
| 130 | +call estop(ier, 'h5open:H5Eset_auto: HDF5 library set traceback', self%filename, ok=ok) |
93 | 131 | if (present(ok)) then
|
94 | 132 | if(.not. ok) return
|
95 | 133 | endif
|
96 | 134 |
|
97 |
| -select case(laction) |
98 |
| -case('r') |
99 |
| - file_mode = H5F_ACC_RDONLY_F |
100 |
| -case('r+') |
101 |
| - file_mode = H5F_ACC_RDWR_F |
102 |
| -case('rw', 'a') |
103 |
| - if(is_hdf5(filename)) then |
104 |
| - file_mode = H5F_ACC_RDWR_F |
105 |
| - else |
106 |
| - file_mode = H5F_ACC_TRUNC_F |
107 |
| - endif |
108 |
| -case ('w') |
109 |
| - file_mode = H5F_ACC_TRUNC_F |
110 |
| -case default |
111 |
| - call estop(ier, 'ERROR:h5fortran:open Unsupported action ' // laction, filename, ok=ok) |
112 |
| - if (present(ok)) then |
113 |
| - if(.not. ok) return |
114 |
| - endif |
115 |
| - |
116 |
| -end select |
117 |
| - |
118 | 135 | fapl = H5P_DEFAULT_F
|
119 | 136 |
|
120 |
| -!! these enums will all be 0 if h5open_f isn't called first |
121 |
| -! print *, "TRACE: file_mode = ", file_mode, " filename = ", filename |
122 |
| -! print *, "TRACE: H5F_ACC_RDONLY_F = ", H5F_ACC_RDONLY_F |
123 |
| -! print *, "TRACE: H5F_ACC_RDWR_F = ", H5F_ACC_RDWR_F |
124 |
| -! print *, "TRACE: H5F_ACC_TRUNC_F = ", H5F_ACC_TRUNC_F |
125 |
| - |
126 |
| - |
127 |
| -if (file_mode == H5F_ACC_RDONLY_F .or. file_mode == H5F_ACC_RDWR_F) then |
| 137 | +if (any(self%file_mode == [H5F_ACC_RDONLY_F, H5F_ACC_RDWR_F])) then |
128 | 138 | if(.not. is_hdf5(filename)) then
|
129 |
| - error stop "ERROR:h5fortran:open: action=" // laction // " not an HDF5 file: " // filename |
| 139 | + write(stderr, '(a,i0)') "ERROR:h5fortran:open: is not an HDF5 file: " // self%filename // " file mode ", self%file_mode |
| 140 | + if (present(ok)) then |
| 141 | + ok = .false. |
| 142 | + return |
| 143 | + else |
| 144 | + error stop |
| 145 | + endif |
130 | 146 | endif
|
131 |
| - call H5Fopen_f(filename, file_mode, self%file_id, ier, access_prp=fapl) |
132 |
| - call estop(ier, "h5open:H5Fopen", filename, ok=ok) |
| 147 | + call H5Fopen_f(self%filename, self%file_mode, self%file_id, ier, access_prp=fapl) |
| 148 | + call estop(ier, "h5open:H5Fopen", self%filename, ok=ok) |
133 | 149 | if (present(ok)) then
|
134 | 150 | if(.not. ok) return
|
135 | 151 | endif
|
136 |
| -elseif(file_mode == H5F_ACC_TRUNC_F) then |
137 |
| - call H5Fcreate_f(filename, file_mode, self%file_id, ier, access_prp=fapl) |
138 |
| - call estop(ier, "h5open:H5Fcreate", filename, ok=ok) |
| 152 | +elseif(self%file_mode == H5F_ACC_TRUNC_F) then |
| 153 | + call H5Fcreate_f(self%filename, self%file_mode, self%file_id, ier, access_prp=fapl) |
| 154 | + call estop(ier, "h5open:H5Fcreate", self%filename, ok=ok) |
139 | 155 | if (present(ok)) then
|
140 | 156 | if(.not. ok) return
|
141 | 157 | endif
|
142 | 158 | else
|
143 |
| - error stop "ERROR:h5fortran:open: Unsupported file mode: " // filename |
| 159 | + error stop "ERROR:h5fortran:open: Unsupported file mode: " // self%filename |
144 | 160 | endif
|
145 | 161 |
|
146 | 162 | end procedure h5open
|
|
200 | 216 | call H5Fclose_f(self%file_id, ierr)
|
201 | 217 | call estop(ierr, "h5close:H5Fclose: HDF5 file close", self%filename)
|
202 | 218 |
|
203 |
| -deallocate(self%filename) |
204 |
| - |
205 | 219 | if (present(close_hdf5_interface)) then
|
206 | 220 | if (close_hdf5_interface) then
|
207 | 221 | call H5close_f(ierr)
|
|
0 commit comments