|
6 | 6 |
|
7 | 7 | !> Implementation of saving multidimensional arrays to npy files
|
8 | 8 | submodule(stdlib_io_np) stdlib_io_np_save
|
| 9 | + use stdlib_array |
9 | 10 | use stdlib_error, only: error_stop
|
| 11 | + use stdlib_filesystem, only: run |
10 | 12 | use stdlib_strings, only: to_string
|
| 13 | + use stdlib_string_type, only: string_type, char |
| 14 | + use stdlib_io_zip, only: zip |
11 | 15 | implicit none
|
12 | 16 |
|
13 | 17 | contains
|
@@ -137,18 +141,79 @@ contains
|
137 | 141 | !> ([Specification](../page/specs/stdlib_io.html#save_npz))
|
138 | 142 | module subroutine save_npz_from_arrays(filename, arrays, compressed, iostat, iomsg)
|
139 | 143 | character(len=*), intent(in) :: filename
|
140 |
| - type(t_array_wrapper), intent(in) :: arrays(*) |
| 144 | + type(t_array_wrapper), intent(in) :: arrays(:) |
141 | 145 | !> If true, the file is saved in compressed format. The default is false.
|
142 | 146 | logical, intent(in), optional :: compressed
|
143 | 147 | integer, intent(out), optional :: iostat
|
144 | 148 | character(len=:), allocatable, intent(out), optional :: iomsg
|
145 | 149 |
|
| 150 | + integer :: i, j, stat |
146 | 151 | logical :: is_compressed
|
| 152 | + character(len=:), allocatable :: msg |
| 153 | + type(string_type), allocatable :: files(:) |
| 154 | + |
| 155 | + if (present(iostat)) iostat = 0 |
147 | 156 |
|
148 | 157 | if (present(compressed)) then
|
149 | 158 | is_compressed = compressed
|
150 | 159 | else
|
151 | 160 | is_compressed = .false.
|
152 | 161 | end if
|
| 162 | + |
| 163 | + allocate(files(size(arrays))) |
| 164 | + do i = 1, size(arrays) |
| 165 | + select type (typed_array => arrays(i)%array) |
| 166 | +#:for k1, t1 in KINDS_TYPES |
| 167 | +#:for rank in RANKS |
| 168 | + class is (t_array_${t1[0]}$${k1}$_${rank}$) |
| 169 | + do j = 1, size(files) |
| 170 | + if (char(files(j)) == typed_array%name) then |
| 171 | + if (present(iostat)) iostat = 1 |
| 172 | + if (present(iomsg)) iomsg = "Error saving array to file '"//filename// & |
| 173 | + "': Array with the same name '"//typed_array%name//"' already exists." |
| 174 | + call delete_files(files) |
| 175 | + return |
| 176 | + end if |
| 177 | + end do |
| 178 | + |
| 179 | + call save_npy(typed_array%name, typed_array%values, stat, msg) |
| 180 | + if (stat /= 0) then |
| 181 | + if (present(iostat)) iostat = stat |
| 182 | + if (present(iomsg)) iomsg = msg |
| 183 | + call delete_files(files) |
| 184 | + return |
| 185 | + end if |
| 186 | + |
| 187 | + files = [files, string_type(typed_array%name)] |
| 188 | +#:endfor |
| 189 | +#:endfor |
| 190 | + class default |
| 191 | + if (present(iostat)) iostat = 1 |
| 192 | + if (present(iomsg)) iomsg = "Error saving array to file '"//filename//"': Unsupported array type." |
| 193 | + call delete_files(files) |
| 194 | + return |
| 195 | + end select |
| 196 | + end do |
| 197 | + |
| 198 | + call zip(filename, files, stat, msg) |
| 199 | + if (stat /= 0) then |
| 200 | + if (present(iostat)) iostat = stat |
| 201 | + if (present(iomsg)) iomsg = msg |
| 202 | + call delete_files(files) |
| 203 | + return |
| 204 | + end if |
| 205 | + |
| 206 | + call delete_files(files) |
| 207 | + end |
| 208 | + |
| 209 | + subroutine delete_files(files) |
| 210 | + type(string_type), allocatable, intent(in) :: files(:) |
| 211 | + |
| 212 | + integer :: i, unit |
| 213 | + |
| 214 | + do i = 1, size(files) |
| 215 | + open(newunit=unit, file=char(files(i))) |
| 216 | + close(unit, status="delete") |
| 217 | + end do |
153 | 218 | end
|
154 | 219 | end
|
0 commit comments