FV3 Bundle
ncdf_value_m.f90
Go to the documentation of this file.
1 ! Copyright (c) 2012 Joseph A. Levin
2 !
3 ! Permission is hereby granted, free of charge, to any person obtaining a copy of this
4 ! software and associated documentation files (the "Software"), to deal in the Software
5 ! without restriction, including without limitation the rights to use, copy, modify, merge,
6 ! publish, distribute, sublicense, and/or sell copies of the Software, and to permit
7 ! persons to whom the Software is furnished to do so, subject to the following conditions:
8 !
9 ! The above copyright notice and this permission notice shall be included in all copies or
10 ! substantial portions of the Software.
11 !
12 ! THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED,
13 ! INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR
14 ! PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
15 ! LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT
16 ! OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
17 ! DEALINGS IN THE SOFTWARE.
18 
19 !
20 ! File: value_m.f95
21 ! Author: josephalevin
22 !
23 ! Created on March 7, 2012, 10:14 PM
24 !
25 
27 
28  use ncdf_string_m
29 
30  implicit none
31 
32  private
33 
34  public :: ncdf_value, ncdf_value_create, &
38 
39  !constants for the value types
40  integer, public, parameter :: type_unknown = -1
41  integer, public, parameter :: type_null = 0
42  integer, public, parameter :: type_object = 1
43  integer, public, parameter :: type_array = 2
44  integer, public, parameter :: type_string = 3
45  integer, public, parameter :: type_integer = 4
46  integer, public, parameter :: type_real = 5
47  integer, public, parameter :: type_logical = 6
48 
49 
50  !
51  ! FSON VALUE
52  !
54  type(ncdf_string), pointer :: name => null()
55  integer :: value_type = type_unknown
56  logical :: value_logical
57  integer :: value_integer
58  real :: value_real
59  double precision :: value_double
60  integer, private :: count = 0
61  type(ncdf_string), pointer :: value_string => null()
62  type(ncdf_value), pointer :: next => null()
63  type(ncdf_value), pointer :: parent => null()
64  type(ncdf_value), pointer :: children => null()
65  type(ncdf_value), pointer :: tail => null()
66  end type ncdf_value
67 
68  !
69  ! FSON VALUE GET
70  !
71  ! Use either a 1 based index or member name to get the value.
72  interface ncdf_value_get
73  module procedure ncdf_get_by_index
74  module procedure ncdf_get_by_name_chars
75  module procedure ncdf_get_by_name_string
76  end interface ncdf_value_get
77 
78 contains
79 
80  !
81  ! FSON VALUE CREATE
82  !
83  function ncdf_value_create() result(new)
84  type(ncdf_value), pointer :: new
85 
86  nullify(new)
87  allocate(new)
88 
89  end function ncdf_value_create
90 
91  !
92  ! FSON VALUE DESTROY
93  !
94  recursive subroutine ncdf_value_destroy(this, destroy_next)
95 
96  implicit none
97  type(ncdf_value), pointer :: this
98  logical, intent(in), optional :: destroy_next
99 
100  type(ncdf_value), pointer :: p
101  integer :: count
102  logical :: donext
103 
104  if (present(destroy_next)) then
105  donext = destroy_next
106  else
107  donext = .true.
108  end if
109 
110  if (associated(this)) then
111 
112  if(associated(this % name)) then
113  call ncdf_string_destroy(this % name)
114  nullify (this % name)
115  end if
116 
117  if(associated(this % value_string)) then
118  call ncdf_string_destroy(this % value_string)
119  nullify (this % value_string)
120  end if
121 
122  if(associated(this % children)) then
123  do while (this % count > 0)
124  p => this % children
125  this % children => this % children % next
126  this % count = this % count - 1
127  call ncdf_value_destroy(p, .false.)
128  end do
129  nullify(this % children)
130  end if
131 
132  if ((associated(this % next)) .and. (donext)) then
133  call ncdf_value_destroy(this % next)
134  nullify (this % next)
135  end if
136 
137  if(associated(this % tail)) then
138  nullify (this % tail)
139  end if
140 
141  deallocate(this)
142  nullify(this)
143 
144  end if
145 
146  end subroutine ncdf_value_destroy
147 
148  !
149  ! FSON VALUE ADD
150  !
151  ! Adds the member to the linked list
152 
153  subroutine ncdf_value_add(this, member)
155  implicit none
156  type(ncdf_value), pointer :: this, member
157 
158  ! associate the parent
159  member % parent => this
160 
161  ! add to linked list
162  if (associated(this % children)) then
163  this % tail % next => member
164  else
165  this % children => member
166  end if
167 
168  this % tail => member
169  this % count = this % count + 1
170 
171  end subroutine ncdf_value_add
172 
173  !
174  ! FSON_VALUE_COUNT
175  !
176  integer function ncdf_value_count(this) result(count)
177  type(ncdf_value), pointer :: this, p
178 
179  count = this % count
180 
181  end function
182 
183  !
184  ! GET BY INDEX
185  !
186  function ncdf_get_by_index(this, index) result(p)
187  type(ncdf_value), pointer :: this, p
188  integer, intent(in) :: index
189  integer :: i
190 
191  p => this % children
192 
193  do i = 1, index - 1
194  p => p % next
195  end do
196 
197  end function ncdf_get_by_index
198 
199  !
200  ! GET BY NAME CHARS
201  !
202  function ncdf_get_by_name_chars(this, name) result(p)
203  type(ncdf_value), pointer :: this, p
204  character(len=*), intent(in) :: name
205 
206  type(ncdf_string), pointer :: string
207 
208  ! convert the char array into a string
209  string => ncdf_string_create(name)
210 
211  p => ncdf_get_by_name_string(this, string)
212 
214 
215  end function ncdf_get_by_name_chars
216 
217  !
218  ! GET BY NAME STRING
219  !
220  function ncdf_get_by_name_string(this, name) result(p)
221  type(ncdf_value), pointer :: this, p
222  type(ncdf_string), pointer :: name
223  integer :: i
224 
225  if(this % value_type .ne. type_object) then
226  nullify(p)
227  return
228  end if
229 
230  do i=1, ncdf_value_count(this)
231  p => ncdf_value_get(this, i)
232  if (ncdf_string_equals(p%name, name)) then
233  return
234  end if
235  end do
236 
237  ! didn't find anything
238  nullify(p)
239 
240 
241  end function ncdf_get_by_name_string
242 
243  !
244  ! FSON VALUE PRINT
245  !
246  recursive subroutine ncdf_value_print(this, indent)
247  type(ncdf_value), pointer :: this, element
248  integer, optional, intent(in) :: indent
249  character (len = 1024) :: tmp_chars
250  integer :: tab, i, count, spaces
251 
252  if (present(indent)) then
253  tab = indent
254  else
255  tab = 0
256  end if
257 
258  spaces = tab * 2
259 
260  select case (this % value_type)
261  case(type_object)
262  print *, repeat(" ", spaces), "{"
263  count = ncdf_value_count(this)
264  do i = 1, count
265  ! get the element
266  element => ncdf_value_get(this, i)
267  ! get the name
268  call ncdf_string_copy(element % name, tmp_chars)
269  ! print the name
270  print *, repeat(" ", spaces), '"', trim(tmp_chars), '":'
271  ! recursive print of the element
272  call ncdf_value_print(element, tab + 1)
273  ! print the separator if required
274  if (i < count) then
275  print *, repeat(" ", spaces), ","
276  end if
277  end do
278 
279  print *, repeat(" ", spaces), "}"
280  case (type_array)
281  print *, repeat(" ", spaces), "["
282  count = ncdf_value_count(this)
283  do i = 1, count
284  ! get the element
285  element => ncdf_value_get(this, i)
286  ! recursive print of the element
287  call ncdf_value_print(element, tab + 1)
288  ! print the separator if required
289  if (i < count) then
290  print *, ","
291  end if
292  end do
293  print *, repeat(" ", spaces), "]"
294  case (type_null)
295  print *, repeat(" ", spaces), "null"
296  case (type_string)
297  call ncdf_string_copy(this % value_string, tmp_chars)
298  print *, repeat(" ", spaces), '"', trim(tmp_chars), '"'
299  case (type_logical)
300  if (this % value_logical) then
301  print *, repeat(" ", spaces), "true"
302  else
303  print *, repeat(" ", spaces), "false"
304  end if
305  case (type_integer)
306  print *, repeat(" ", spaces), this % value_integer
307  case (type_real)
308  print *, repeat(" ", spaces), this % value_double
309  end select
310  end subroutine ncdf_value_print
311 
312 
313 end module ncdf_value_m
type(ncdf_value) function, pointer ncdf_get_by_index(this, index)
integer, parameter, public type_real
type(ncdf_string) function, pointer, public ncdf_string_create(chars)
type(ncdf_value) function, pointer ncdf_get_by_name_chars(this, name)
integer, parameter, public type_logical
type(ncdf_value) function, pointer, public ncdf_value_create()
type(ncdf_value) function, pointer ncdf_get_by_name_string(this, name)
integer, parameter, public type_integer
integer, parameter, public type_array
integer, parameter, public type_string
recursive subroutine, public ncdf_value_print(this, indent)
recursive subroutine, public ncdf_value_destroy(this, destroy_next)
integer, parameter, public type_unknown
recursive subroutine, public ncdf_string_destroy(this)
integer, parameter, public type_object
integer, parameter, public type_null
subroutine, public ncdf_value_add(this, member)
integer function, public ncdf_value_count(this)