Type | Intent | Optional | Attributes | Name | ||
---|---|---|---|---|---|---|
type(json_value), | intent(in), | pointer | :: | me | ||
integer(kind=IK), | intent(in) | :: | iunit | file unit to write to (6=console) |
||
character(kind=CK,len=:), | intent(inout), | allocatable | :: | str | if iunit==unit2str (-1) then the structure is printed to this string rather than a file. This mode is used by json_value_to_string. |
|
integer(kind=IK), | intent(in), | optional | :: | indent | indention level |
|
logical(kind=LK), | intent(in), | optional | :: | need_comma | if it needs a comma after it |
|
logical(kind=LK), | intent(in), | optional | :: | colon | if the colon was just written |
|
logical(kind=LK), | intent(in), | optional | :: | is_array_element | if this is an array element |
Print the JSON structure to a string or a file.
Type | Visibility | Attributes | Name | Initial | |||
---|---|---|---|---|---|---|---|
character(kind=CK,len=max_numeric_str_len), | public | :: | tmp | ||||
character(kind=CK,len=:), | public, | allocatable | :: | s | |||
type(json_value), | public, | pointer | :: | element | |||
integer(kind=IK), | public | :: | tab | ||||
integer(kind=IK), | public | :: | i | ||||
integer(kind=IK), | public | :: | count | ||||
integer(kind=IK), | public | :: | spaces | ||||
logical(kind=LK), | public | :: | print_comma | ||||
logical(kind=LK), | public | :: | write_file | ||||
logical(kind=LK), | public | :: | write_string | ||||
logical(kind=LK), | public | :: | is_array |
Type | Intent | Optional | Attributes | Name | ||
---|---|---|---|---|---|---|
character(kind=CK,len=*), | intent(in) | :: | s | |||
logical(kind=LK), | intent(in), | optional | :: | advance | ||
logical(kind=LK), | intent(in), | optional | :: | comma |
recursive subroutine json_value_print(me,iunit,str,indent,need_comma,colon,is_array_element)
implicit none
type(json_value),pointer,intent(in) :: me
integer(IK),intent(in) :: iunit !! file unit to write to (6=console)
integer(IK),intent(in),optional :: indent !! indention level
logical(LK),intent(in),optional :: is_array_element !! if this is an array element
logical(LK),intent(in),optional :: need_comma !! if it needs a comma after it
logical(LK),intent(in),optional :: colon !! if the colon was just written
character(kind=CK,len=:),intent(inout),allocatable :: str
!! if iunit==unit2str (-1) then the structure is
!! printed to this string rather than
!! a file. This mode is used by
!! [[json_value_to_string]].
character(kind=CK,len=max_numeric_str_len) :: tmp !for val to string conversions
character(kind=CK,len=:),allocatable :: s
type(json_value),pointer :: element
integer(IK) :: tab, i, count, spaces
logical(LK) :: print_comma
logical(LK) :: write_file, write_string
logical(LK) :: is_array
if (.not. exception_thrown) then
!whether to write a string or a file (one or the other):
write_string = (iunit==unit2str)
write_file = .not. write_string
!if the comma will be printed after the value
! [comma not printed for the last elements]
if (present(need_comma)) then
print_comma = need_comma
else
print_comma = .false.
end if
!number of "tabs" to indent:
if (present(indent)) then
tab = indent
else
tab = 0
end if
!convert to number of spaces:
spaces = tab*spaces_per_tab
!if this is an element in an array:
if (present(is_array_element)) then
is_array = is_array_element
else
is_array = .false.
end if
!if the colon was the last thing written
if (present(colon)) then
s = ''
else
s = repeat(space, spaces)
end if
select case (me%var_type)
case (json_object)
count = json_count(me)
if (count==0) then !special case for empty object
call write_it( s//start_object//end_object, comma=print_comma )
else
call write_it( s//start_object )
!if an object is in an array, there is an extra tab:
if (is_array) then
tab = tab+1
spaces = tab*spaces_per_tab
end if
nullify(element)
element => me%children
do i = 1, count
! print the name
if (allocated(element%name)) then
call write_it(repeat(space, spaces)//quotation_mark//&
element%name//quotation_mark//colon_char//space,&
advance=.false.)
else
call throw_exception('Error in json_value_print:'//&
' element%name not allocated')
nullify(element)
return
end if
! recursive print of the element
call json_value_print(element, iunit=iunit, indent=tab + 1, &
need_comma=i<count, colon=.true., str=str)
! get the next child the list:
element => element%next
end do
! [one fewer tab if it isn't an array element]
if (.not. is_array) s = repeat(space, max(0,spaces-spaces_per_tab))
call write_it( s//end_object, comma=print_comma )
nullify(element)
end if
case (json_array)
count = json_count(me)
if (count==0) then !special case for empty array
call write_it( s//start_array//end_array, comma=print_comma )
else
call write_it( start_array )
nullify(element)
element => me%children
do i = 1, count
! recursive print of the element
call json_value_print(element, iunit=iunit, indent=tab,&
need_comma=i<count, is_array_element=.true., str=str)
! get the next child the list:
element => element%next
end do
!indent the closing array character:
call write_it( repeat(space, max(0,spaces-spaces_per_tab))//end_array,&
comma=print_comma )
nullify(element)
end if
case (json_null)
call write_it( s//null_str, comma=print_comma )
case (json_string)
if (allocated(me%str_value)) then
call write_it( s//quotation_mark// &
trim(me%str_value)//quotation_mark, comma=print_comma )
else
call throw_exception('Error in json_value_print:'//&
' me%value_string not allocated')
return
end if
case (json_logical)
if (me%log_value) then
call write_it( s//true_str, comma=print_comma )
else
call write_it( s//false_str, comma=print_comma )
end if
case (json_integer)
call integer_to_string(me%int_value,tmp)
call write_it( s//trim(tmp), comma=print_comma )
case (json_double)
call real_to_string(me%dbl_value,tmp)
call write_it( s//trim(tmp), comma=print_comma )
case default
call throw_exception('Error in json_value_print: unknown data type')
end select
!cleanup:
if (allocated(s)) deallocate(s)
end if
contains
!
! write the string to the file (or the output string)
!
subroutine write_it(s,advance,comma)
implicit none
character(kind=CK,len=*),intent(in) :: s !string to print
logical(LK),intent(in),optional :: advance !to add line break or not
logical(LK),intent(in),optional :: comma !print comma after the string
logical(LK) :: add_line_break, add_comma
character(kind=CK,len=:),allocatable :: s2
if (present(comma)) then
add_comma = comma
else
add_comma = .false. !default is not to add comma
end if
if (present(advance)) then
add_line_break = advance
else
add_line_break = .true. !default is to advance
end if
!string to print:
s2 = s
if (add_comma) s2 = s2 // delimiter
if (write_file) then
if (add_line_break) then
write(iunit,fmt='(A)') s2
else
write(iunit,fmt='(A)',advance='NO') s2
end if
else !write string
str = str // s2
if (add_line_break) str = str // newline
end if
!cleanup:
if (allocated(s2)) deallocate(s2)
end subroutine write_it
end subroutine json_value_print