Loading...
Searching...
No Matches
gdncfileopen.f90
Go to the documentation of this file.
1subroutine gdncfileopen(fileid, filename, writable, overwrite, stat, err)
4 use netcdf, only: &
5 & nf90_write, &
6 & nf90_nowrite, &
7 & nf90_noerr, &
8 & nf90_noclobber, &
9 & nf90_clobber, &
10 & nf90_64bit_offset, &
11 & nf90_open, &
12 & nf90_create
13 use dc_message, only: messagenotify
14 use dc_error, only: storeerror
15 use dc_types, only: string
16 use dc_trace, only: beginsub, endsub
17 implicit none
18 integer, intent(out):: fileid
19 character(len = *), intent(in):: filename
20 logical, intent(in), optional:: writable
21 ! .TRUE. は書き込みモード、
22 ! .FALSE. は読込モード。
23 ! 読込モードの際にファイルが
24 ! ファイルが存在しないと
25 ! エラーになる。
26 ! デフォルトは読み込みモード
27 logical, intent(in), optional:: overwrite
28 ! writable が .TRUE. の
29 ! 場合のみ有効。
30 ! .TRUE. ならば上書きモード
31 ! .FALSE. の場合、既存の
32 ! ファイルが存在すると
33 ! エラーになる
34 logical, intent(out), optional:: err
35 integer, intent(out), optional:: stat
36 logical:: writable_required
37 logical:: overwrite_required
38 type(gd_nc_file_id_entry), pointer:: identptr, prev
39 integer:: mystat, mode
40 character(len = 256):: real_filename
41 character(len = STRING):: cause_c
42 character(*), parameter:: subname = "GDNcFileOpen"
43continue
44 fileid = -1
45 !
46 ! オプションの解釈
47 !
48 writable_required = .false.
49 overwrite_required = .false.
50 if (present(writable)) writable_required = writable
51 if (present(overwrite)) overwrite_required = overwrite
52 call beginsub(subname, 'writable=%y overwrite=%y file=%c', &
53 & l=(/writable_required, overwrite_required/), c1=trim(filename))
54 !
55 ! 同じ名前で書込み可能性も適合していれば nf90_open しないで済ませる
56 !
57 if (id_used) then
58 identptr => id_head
59 nullify(prev)
60 do
61 if ((identptr % filename == filename) &
62 & .and. (identptr % writable .or. .not. writable_required)) then
63 fileid = identptr % id
64 identptr % count = identptr % count + 1
65 if (present(err)) err = .false.
66 if (present(stat)) stat = nf90_noerr
67 mystat = nf90_noerr
68 goto 999
69 endif
70 prev => identptr
71 identptr => identptr % next
72 if (.not. associated(identptr)) exit
73 enddo
74 allocate(identptr)
75 prev%next => identptr
76 else
77 nullify(prev)
78 allocate(id_head)
79 identptr => id_head
80 id_used = .true.
81 endif
82 nullify(identptr % next)
83 identptr % filename = filename
84 identptr % writable = writable_required
85 identptr % count = 1
86 !
87 ! URL の部分的サポート
88 !
89 real_filename = filename
90 if (real_filename(1:8) == 'file:///') then
91 real_filename = real_filename(8: )
92 else if (real_filename(1:5) == 'file:' .AND. real_filename(6:6) /= '/') then
93 real_filename = real_filename(6: )
94 endif
95 !
96 ! いざ nf90_open
97 !
98 mode = nf90_nowrite
99 if (writable_required) mode = ior(mode, nf90_write)
100 ! 既に nc ファイルがあると思って開けてみる
101 mystat = nf90_open(real_filename, mode, identptr % id)
102 !
103 ! ファイルが既に存在する場合
104 !
105 if (mystat == nf90_noerr) then
106 ! 書き込みモードの場合
107 if (writable_required) then
108 if (overwrite_required) then
109 ! 上書きモードの場合
110 mode = nf90_clobber
111 call messagenotify('M', subname, &
112 & '"%c" is overwritten.', c1=trim(filename), rank_mpi = -1)
113 else
114 ! 上書き禁止モードの場合
115 mode = nf90_noclobber
116 call messagenotify('W', subname, &
117 & '"%c" is opened in write-protect mode.', c1=trim(filename), rank_mpi = -1)
118 end if
119 mode = ior(mode,nf90_64bit_offset)
120 mystat = nf90_create(real_filename, mode, identptr % id)
121 if (mystat /= nf90_noerr) then
122 cause_c=filename
123 if (present(stat)) stat = mystat
124 goto 999
125 end if
126 endif
127 ! 読み込みモードの場合は何もしない
128 else
129 !
130 ! ファイルが無かった場合
131 !
132 if (.not. writable_required) then
133 ! 読み込みモードの場合
134 !
135 ! 「無いよ」とエラーを吐いて終了
136 if (mystat /= nf90_noerr) then
137 cause_c=filename
138 if (present(stat)) stat = mystat
139 goto 999
140 end if
141 else
142 ! 書き込みモードの場合
143 mode = nf90_clobber
144 ! ファイルを作成する
145 mode = ior(mode,nf90_64bit_offset)
146 mystat = nf90_create(real_filename, mode, identptr % id)
147 if (mystat /= nf90_noerr) then
148 cause_c=filename
149 if (present(stat)) stat = mystat
150 goto 999
151 end if
152 endif
153 endif
154
155 fileid = identptr % id
156
157 ! 失敗したら消しておく
158 if (mystat /= nf90_noerr) then
159 if (associated(prev)) then
160 prev%next => identptr % next
161 else
162 id_head => identptr % next
163 if (.not. associated(id_head)) id_used = .false.
164 endif
165 deallocate(identptr)
166 fileid = -1
167 endif
168
169 if (present(stat)) then
170 stat = mystat
171 if (present(err)) err = (stat /= nf90_noerr)
172 else
173 cause_c=filename
174 goto 999
175 endif
176999 continue
177 call storeerror(mystat, subname, err, cause_c)
178 call endsub(subname, 'id=%d stat=%d', i=(/fileid, mystat/))
179end subroutine gdncfileopen
subroutine gdncfileopen(fileid, filename, writable, overwrite, stat, err)
subroutine, public storeerror(number, where, err, cause_c, cause_i)
Definition dc_error.f90:830
種別型パラメタを提供します。
Definition dc_types.f90:49
integer, parameter, public string
文字列を保持する 文字型変数の種別型パラメタ
Definition dc_types.f90:118
type(gd_nc_file_id_entry), pointer, save id_head