summaryrefslogtreecommitdiff
path: root/Ganlib/src/OPNMOD.f90
blob: 6c73a15ebf7c26566656f6d246a121a28b08988f (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
!
!-----------------------------------------------------------------------
!
!Purpose:
! Fortran-2003 bindings for fortran direct access in WIMS-AECL. Open,
! read or close indexed random file using fortran direct access files
! Subroutines:
!  OPNIND: open file and read master index
!  REDIND: read data on indexed file
!  CLSIND: close file
!
!Copyright:
! Copyright (C) 2020 Ecole Polytechnique de Montreal
! This library is free software; you can redistribute it and/or
! modify it under the terms of the GNU Lesser General Public
! License as published by the Free Software Foundation; either
! version 2.1 of the License, or (at your option) any later version.
!
!Author(s): J. Donnelly
!
!Parameters: input/output
! IUNIT   read unit
! INDEX   index table (master index for OPNIND)
! LINDEX  length of index table (LINDEX >=(# of entries) + 1)
! DATA    data array to retreive from file
! NWORDS  lenght of data array to retreive from file
! KEY     location of data array in index
!
!Internal parameter description
! IOUT    output unit = 6
! NBLOCKS number of blocks per record = 256
! IOFSET  offset for index length = 65536
!
!-----------------------------------------------------------------------
!
module OPNMOD
   private
   integer iunitr
   public :: OPNIND, REDIND, CLSIND
   interface REDIND
      ! read data on indexed file
      module procedure REDIND_I1, REDIND_R1
   end interface
contains
   subroutine OPNIND(iunit,index,lindex)
   parameter (iout=6,nblock=256,iofset=65536)
   integer    iunit,index(lindex),lindex
   logical    exst, opnd
   character  dirst*7
   !----
   ! unit number must be > zero
   !----
   if(iunit.le.0) then
     write(iout,6000) iunit
     call XABORT('OPNIND: (readonly) illegal unit number')
   endif
   !----
   ! find out file status, and if unit already associated with
   ! an open file
   !----
   inquire(unit=iunit,exist=exst,opened=opnd,direct=dirst)
   if(.not.opnd) then
     !----
     ! file closed
     !----
     write(iout,6010) iunit
     call XABORT('OPNIND: (readonly) file not opened')
   endif
   if( exst .and. dirst .eq. 'no' ) then
     !----
     ! file already exists, but is not direct access
     !----
     write(iout,6020) iunit
     call XABORT('OPNIND: (readonly) file is nor direct access')
   endif
   if(.not.exst) then
     !----
     ! file does not exists
     !----
     write(iout,6030) iunit
     call XABORT('OPNIND: (readonly) file does not exists ')
   endif
   !----
   ! process the file master index
   !----
   iunitr=iunit
   irec = 1
   minw = 1
   40 continue
   maxw = min0( minw + nblock - 1 , lindex )
   ierr=0
   read(iunit,rec=irec,iostat=ierr) (index(i),i=minw,maxw)
   if(ierr.ne.0) then
      write(iout,6040) iunit,ierr
      call XABORT('OPNIND: read master record error')
   endif
   irec = irec + 1
   if( maxw .ne. lindex ) then
     minw = maxw + 1
     go to 40
   endif
   return
   !----
   !  format
   !----
   6000 format(' //// OPNIND: file, ',i5,' invalid')
   6010 format(' //// OPNIND: file, ',i5,' has not been opened with KDROPN')
   6020 format(' //// OPNIND: unit ',i5,' is not a direct access file')
   6030 format(' //// OPNIND: unit ',i5,' does not exists (readonly version)')
   6040 format(' //// OPNIND: error during reading of master index ', &
               'of unit ',i5,' status = ',i5)
   end subroutine OPNIND
   !----
   subroutine CLSIND(iunit)
   parameter (iout=6)
   integer    iunit
   if(iunitr.ne.iunit) then
     write(iout,6100) iunit
     call XABORT('CLSIND: file not opened by OPNIND')
   endif
   iunitr=kdrcls(iunit,1)
   if(iunitr.ne.0) then
     write(iout,6110) iunitr
     call XABORT('CLSIND: error in file closing')
   endif
   return
   !----
   ! format
   !----
   6100 format(' //// CLSIND: unit ',i5,' not found')
   6110 format(' //// CLSIND: error status =',i5,' from kdrcls')
   end subroutine CLSIND
   !----
   subroutine REDIND_I1(iunit,index,lindex,data,nwords,key)
   parameter (iout=6,nblock=256,iofset=65536)
   integer    iunit,index(lindex),lindex,nwords,key
   integer    data(nwords)
   !
   if(iunitr.ne.iunit) then
     write(iout,6200) iunit
     call XABORT('REDIND_I1: file not opened by OPNIND')
   endif
   !----
   ! validate key number
   !----
   if(key.le.0.or.key.ge.lindex) then
     write(iout,6210) iunit, key
     call XABORT('REDIND_I1: invalid key')
   endif
   !----
   ! key number valid, validate record number
   !----
   indr=index(key+1)
   if(indr.eq.0) then
     write(iout,6220) iunit, key
     call XABORT('REDIND_I1: invalid record number for key')
   endif
   !----
   ! validate record length
   !----
   lrecrd = (nwords-1)/nblock + 1
   loldrc = indr/iofset
   if(loldrc.lt.lrecrd) then
     write(iout,6230) iunit, key
     call XABORT('REDIND_I1: invalid record length')
   endif
   !----
   ! record found, read the data
   !----
   nrec = mod( indr, iofset )
   minw = 1
   50 continue
   maxw = min0( minw + nblock - 1 , nwords )
   ierr=0
   read(iunit,rec=nrec,iostat=ierr) (data(i),i=minw,maxw)
   if(ierr.ne.0) then
     write(iout,6240) iunit,ierr
     call XABORT('REDIND_I1: read record error')
   endif
   nrec = nrec + 1
   if( maxw .ne. nwords ) then
     minw = maxw + 1
     go to 50
   endif
   return
   !----
   ! format
   !----
   6200 format(' //// REDIND_I1: unit ',i5,' not found')
   6210 format(' //// REDIND_I1: invalid record number, unit ',i5,' key= ',i10)
   6220 format(' //// REDIND_I1: non-existant record, unit ',i5, &
               ' record key =',i10)
   6230 format(' //// REDIND_I1: data count exceeds record, unit ',i5, &
               ' record key =',i10)
   6240 format(' //// REDIND_I1: error during reading of record ', &
               'of unit ',i5,' status = ',i5)
   end subroutine REDIND_I1
   !----
   subroutine REDIND_R1(iunit,index,lindex,data,nwords,key)
   parameter (iout=6,nblock=256,iofset=65536)
   integer    iunit,index(lindex),lindex,nwords,key
   real       data(nwords)
   !
   if(iunitr.ne.iunit) then
     write(iout,6200) iunit
     call XABORT('REDIND_R1: file not opened by OPNIND')
   endif
   !----
   ! validate key number
   !----
   if(key.le.0.or.key.ge.lindex) then
     write(iout,6210) iunit, key
     call XABORT('REDIND_R1: invalid key')
   endif
   !----
   ! key number valid, validate record number
   !----
   indr=index(key+1)
   if(indr.eq.0) then
     write(iout,6220) iunit, key
     call XABORT('REDIND_R1: invalid record number for key')
   endif
   !----
   ! validate record length
   !----
   lrecrd = (nwords-1)/nblock + 1
   loldrc = indr/iofset
   if(loldrc.lt.lrecrd) then
     write(iout,6230) iunit, key
     call XABORT('REDIND_R1: invalid record length')
   endif
   !----
   ! record found, read the data
   !----
   nrec = mod( indr, iofset )
   minw = 1
   50 continue
   maxw = min0( minw + nblock - 1 , nwords )
   ierr=0
   read(iunit,rec=nrec,iostat=ierr) (data(i),i=minw,maxw)
   if(ierr.ne.0) then
     write(iout,6240) iunit,ierr
     call XABORT('REDIND_R1: read record error')
   endif
   nrec = nrec + 1
   if( maxw .ne. nwords ) then
     minw = maxw + 1
     go to 50
   endif
   return
   !----
   ! format
   !----
   6200 format(' //// REDIND_R1: unit ',i5,' not found')
   6210 format(' //// REDIND_R1: invalid record number, unit ',i5,' key= ',i10)
   6220 format(' //// REDIND_R1: non-existant record, unit ',i5, &
               ' record key =',i10)
   6230 format(' //// REDIND_R1: data count exceeds record, unit ',i5, &
               ' record key =',i10)
   6240 format(' //// REDIND_R1: error during reading of record ', &
               'of unit ',i5,' status = ',i5)
   end subroutine REDIND_R1
end module OPNMOD