FV3 Bundle
ncdf_string_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: string.f95
21 ! Author: josephalevin
22 !
23 ! Created on March 7, 2012, 7:40 PM
24 !
25 
27 
28  private
29 
32 
33  integer, parameter :: block_size = 32
34 
36  character (len = BLOCK_SIZE) :: chars
37  integer :: index = 0
38  type(ncdf_string), pointer :: next => null()
39  end type ncdf_string
40 
42  module procedure ncdf_append_chars, ncdf_append_string
43  end interface ncdf_string_append
44 
45  interface ncdf_string_copy
46  module procedure ncdf_copy_chars
47  end interface ncdf_string_copy
48 
50  module procedure ncdf_equals_string
51  end interface ncdf_string_equals
52 
54  module procedure ncdf_string_length
55  end interface ncdf_ncdf_string_length
56 
57 contains
58 
59  !
60  ! FSON STRING CREATE
61  !
62  function ncdf_string_create(chars) result(new)
63  character(len=*), optional :: chars
64  type(ncdf_string), pointer :: new
65 
66  nullify(new)
67  allocate(new)
68 
69  ! append chars if available
70  if(present(chars)) then
71  call ncdf_append_chars(new, chars)
72  end if
73 
74  end function ncdf_string_create
75 
76  !
77  ! FSON STRING CREATE
78  !
79  recursive subroutine ncdf_string_destroy(this)
80 
81  implicit none
82  type(ncdf_string), pointer :: this
83 
84  if (associated(this)) then
85 
86  if(associated(this % next)) then
87  call ncdf_string_destroy(this % next)
88  end if
89 
90  deallocate(this)
91  nullify (this)
92 
93  end if
94 
95  end subroutine ncdf_string_destroy
96 
97  !
98  ! ALLOCATE BLOCK
99  !
100  subroutine ncdf_allocate_block(this)
102  implicit none
103  type(ncdf_string), pointer :: this
104  type(ncdf_string), pointer :: new
105 
106  if (.not.associated(this % next)) then
107  nullify(new)
108  allocate(new)
109  this % next => new
110  end if
111 
112  end subroutine ncdf_allocate_block
113 
114 
115  !
116  ! APPEND_STRING
117  !
118  subroutine ncdf_append_string(str1, str2)
119  type(ncdf_string), pointer :: str1, str2
120  integer length, i
121 
122  length = ncdf_string_length(str2)
123 
124  do i = 1, length
125  call ncdf_append_char(str1, ncdf_get_char_at(str2, i))
126  end do
127 
128 
129  end subroutine ncdf_append_string
130 
131  !
132  ! APPEND_CHARS
133  !
134  subroutine ncdf_append_chars(str, c)
135  type(ncdf_string), pointer :: str
136  character (len = *), intent(in) :: c
137  integer length, i
138 
139  length = len(c)
140 
141  do i = 1, length
142  call ncdf_append_char(str, c(i:i))
143  end do
144 
145 
146  end subroutine ncdf_append_chars
147 
148  !
149  ! APPEND_CHAR
150  !
151  recursive subroutine ncdf_append_char(str, c)
152  type(ncdf_string), pointer :: str
153  character, intent(in) :: c
154 
155  if (str % index .GE. block_size) then
156  !set down the chain
157  call ncdf_allocate_block(str)
158  call ncdf_append_char(str % next, c)
159 
160  else
161  ! set local
162  str % index = str % index + 1
163  str % chars(str % index:str % index) = c
164  end if
165 
166  end subroutine ncdf_append_char
167 
168  !
169  ! COPY CHARS
170  !
171  subroutine ncdf_copy_chars(this, to)
172  type(ncdf_string), pointer :: this
173  character(len = *), intent(inout) :: to
174  integer :: length
175  integer :: i
176 
177  length = min(ncdf_string_length(this), len(to))
178 
179  do i = 1, length
180  to(i:i) = ncdf_get_char_at(this, i)
181  end do
182 
183  ! pad with nothing
184  do i = length + 1, len(to)
185  to(i:i) = ""
186  end do
187 
188 
189  end subroutine ncdf_copy_chars
190 
191 
192 
193  !
194  ! CLEAR
195  !
196  recursive subroutine ncdf_string_clear(this)
197  type(ncdf_string), pointer :: this
198 
199  if (associated(this % next)) then
200  call ncdf_string_clear(this % next)
201  deallocate(this % next)
202  nullify (this % next)
203  end if
204 
205  this % index = 0
206 
207  end subroutine ncdf_string_clear
208 
209  !
210  ! SIZE
211  !
212  recursive integer function ncdf_string_length(str) result(count)
213  type(ncdf_string), pointer :: str
214 
215  count = str % index
216 
217  if (str % index == block_size .AND. associated(str % next)) then
218  count = count + ncdf_string_length(str % next)
219  end if
220 
221  end function ncdf_string_length
222 
223 
224  !
225  ! GET CHAR AT
226  !
227  recursive character function ncdf_get_char_at(this, i) result(c)
228  type(ncdf_string), pointer :: this
229  integer, intent(in) :: i
230 
231  if (i .LE. this % index) then
232  c = this % chars(i:i)
233  else
234  c = ncdf_get_char_at(this % next, i - this % index)
235  end if
236 
237  end function ncdf_get_char_at
238 
239  !
240  ! EQUALS STRING
241  !
242  logical function ncdf_equals_string(this, other) result(equals)
243  type(ncdf_string), pointer :: this, other
244  integer :: i
245  equals = .false.
246 
247  if(ncdf_ncdf_string_length(this) .ne. ncdf_ncdf_string_length(other)) then
248  equals = .false.
249  return
250  else if(ncdf_ncdf_string_length(this) == 0) then
251  equals = .true.
252  return
253  end if
254 
255  do i=1, ncdf_string_length(this)
256  if(ncdf_get_char_at(this, i) .ne. ncdf_get_char_at(other, i)) then
257  equals = .false.
258  return
259  end if
260  end do
261 
262  equals = .true.
263 
264  end function ncdf_equals_string
265 
266 end module ncdf_string_m
subroutine ncdf_copy_chars(this, to)
logical function ncdf_equals_string(this, other)
recursive subroutine ncdf_string_clear(this)
type(ncdf_string) function, pointer, public ncdf_string_create(chars)
subroutine ncdf_append_string(str1, str2)
recursive character function ncdf_get_char_at(this, i)
integer, parameter block_size
recursive integer function ncdf_string_length(str)
recursive subroutine, public ncdf_string_destroy(this)
#define min(a, b)
Definition: mosaic_util.h:32
recursive subroutine ncdf_append_char(str, c)
subroutine ncdf_append_chars(str, c)
subroutine ncdf_allocate_block(this)