gdncfileopen.f90 File Reference

Go to the source code of this file.

Functions/Subroutines

subroutine gdncfileopen (fileid, filename, writable, overwrite, stat, err)
 

Function/Subroutine Documentation

◆ gdncfileopen()

subroutine gdncfileopen ( integer, intent(out)  fileid,
character(len = *), intent(in)  filename,
logical, intent(in), optional  writable,
logical, intent(in), optional  overwrite,
integer, intent(out), optional  stat,
logical, intent(out), optional  err 
)

Definition at line 2 of file gdncfileopen.f90.

References dc_trace::beginsub(), dc_trace::endsub(), gtdata_netcdf_file_internal::id_head, gtdata_netcdf_file_internal::id_used, dc_error::storeerror(), and dc_types::string.

Referenced by gdncvarcreate(), gdncvarcreated(), gdncvaropen(), and gdncvarsearchinit().

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