Skip to content

Commit f417499

Browse files
committed
update for compress_vectors
now, a mixed array of ints and reals will now also be compressed if this option is enabled. Fixes #470
1 parent 17856ed commit f417499

File tree

2 files changed

+67
-34
lines changed

2 files changed

+67
-34
lines changed

src/json_value_module.F90

+65-33
Original file line numberDiff line numberDiff line change
@@ -901,6 +901,7 @@ module json_value_module
901901
procedure :: to_object
902902
procedure :: to_array
903903
procedure,nopass :: json_value_clone_func
904+
procedure :: is_vector => json_is_vector
904905

905906
end type json_core
906907
!*********************************************************
@@ -6036,8 +6037,6 @@ recursive subroutine json_value_print(json,p,iunit,str,indent,&
60366037
logical(LK) :: write_file !! if we are writing to a file
60376038
logical(LK) :: write_string !! if we are writing to a string
60386039
logical(LK) :: is_array !! if this is an element in an array
6039-
integer(IK) :: var_type !! for getting the variable type of children
6040-
integer(IK) :: var_type_prev !! for getting the variable type of children
60416040
logical(LK) :: is_vector !! if all elements of a vector
60426041
!! are scalars of the same type
60436042
character(kind=CK,len=:),allocatable :: str_escaped !! escaped version of
@@ -6173,43 +6172,17 @@ recursive subroutine json_value_print(json,p,iunit,str,indent,&
61736172

61746173
count = json%count(p)
61756174

6176-
if (json%compress_vectors) then
6177-
! check to see if every child is the same type,
6178-
! and a scalar:
6179-
is_vector = .true.
6180-
var_type_prev = -1 ! an invalid value
6181-
nullify(element)
6182-
element => p%children
6183-
do i = 1, count
6184-
if (.not. associated(element)) then
6185-
call json%throw_exception('Error in json_value_print: '//&
6186-
'Malformed JSON linked list')
6187-
return
6188-
end if
6189-
! check variable type of all the children.
6190-
! They must all be the same, and a scalar.
6191-
call json%info(element,var_type=var_type)
6192-
if (var_type==json_object .or. &
6193-
var_type==json_array .or. &
6194-
(i>1 .and. var_type/=var_type_prev)) then
6195-
is_vector = .false.
6196-
exit
6197-
end if
6198-
var_type_prev = var_type
6199-
! get the next child the list:
6200-
element => element%next
6201-
end do
6202-
else
6203-
is_vector = .false.
6204-
end if
6205-
6206-
if (count==0) then !special case for empty array
6175+
if (count==0) then ! special case for empty array
62076176

62086177
s = s_indent//start_array//end_array
62096178
call write_it( comma=print_comma )
62106179

62116180
else
62126181

6182+
! if every child is the same type & a scalar:
6183+
is_vector = json%is_vector(p)
6184+
if (json%failed()) return
6185+
62136186
s = s_indent//start_array
62146187
call write_it( advance=(.not. is_vector) )
62156188

@@ -6412,6 +6385,65 @@ end subroutine write_it
64126385
end subroutine json_value_print
64136386
!*****************************************************************************************
64146387

6388+
!*****************************************************************************************
6389+
!>
6390+
! Returns true if all the children are the same type (and a scalar).
6391+
! Note that integers and reals are considered the same type for this purpose.
6392+
! This routine is used for the `compress_vectors` option.
6393+
6394+
function json_is_vector(json, p) result(is_vector)
6395+
6396+
implicit none
6397+
6398+
class(json_core),intent(inout) :: json
6399+
type(json_value),pointer :: p
6400+
logical(LK) :: is_vector !! if all elements of a vector
6401+
!! are scalars of the same type
6402+
6403+
integer(IK) :: var_type_prev !! for getting the variable type of children
6404+
integer(IK) :: var_type !! for getting the variable type of children
6405+
type(json_value),pointer :: element !! for getting children
6406+
integer(IK) :: i !! counter
6407+
integer(IK) :: count !! number of children
6408+
6409+
integer(IK),parameter :: json_invalid = -1_IK !! to initialize the flag. an invalid value
6410+
integer(IK),parameter :: json_numeric = -2_IK !! indicates `json_integer` or `json_real`
6411+
6412+
if (json%compress_vectors) then
6413+
! check to see if every child is the same type,
6414+
! and a scalar:
6415+
is_vector = .true.
6416+
var_type_prev = json_invalid
6417+
count = json%count(p)
6418+
element => p%children
6419+
do i = 1_IK, count
6420+
if (.not. associated(element)) then
6421+
call json%throw_exception('Error in json_is_vector: '//&
6422+
'Malformed JSON linked list')
6423+
return
6424+
end if
6425+
! check variable type of all the children.
6426+
! They must all be the same, and a scalar.
6427+
call json%info(element,var_type=var_type)
6428+
! special check for numeric values:
6429+
if (var_type==json_integer .or. var_type==json_real) var_type = json_numeric
6430+
if (var_type==json_object .or. &
6431+
var_type==json_array .or. &
6432+
(i>1_IK .and. var_type/=var_type_prev)) then
6433+
is_vector = .false.
6434+
exit
6435+
end if
6436+
var_type_prev = var_type
6437+
! get the next child the list:
6438+
element => element%next
6439+
end do
6440+
else
6441+
is_vector = .false.
6442+
end if
6443+
6444+
end function json_is_vector
6445+
!*****************************************************************************************
6446+
64156447
!*****************************************************************************************
64166448
!>
64176449
! Returns true if the `path` is present in the `p` JSON structure.

src/tests/jf_test_27.F90

+2-1
Original file line numberDiff line numberDiff line change
@@ -27,7 +27,8 @@ subroutine test_27(error_cnt)
2727
type(json_file) :: f
2828

2929
character(kind=CK,len=*),parameter :: json_str = &
30-
'{"int_vec": [1,2,3], "int": 1, "object": {"int_vec": [1,2,3]},'//&
30+
'{"int_vec": [1,2,3], "int": 1, "numeric_vec": [1, 2.0, 3, 4.0e1], '//&
31+
'"object": {"int_vec": [1,2,3]},'//&
3132
'"vec": [[1,2],[3,4]], "vec_of_objects": [{"a":1},{"bvec":[1,2,3]}]}'
3233

3334
error_cnt = 0

0 commit comments

Comments
 (0)