Skip to content

Commit 9b66eda

Browse files
committed
added new json_value_insert_after routine.
added unit test.
1 parent 0570381 commit 9b66eda

File tree

2 files changed

+195
-2
lines changed

2 files changed

+195
-2
lines changed

src/json_value_module.F90

Lines changed: 70 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -518,10 +518,12 @@ module json_value_module
518518
procedure,public :: print_error_message => json_print_error_message !! simply routine to print error messages
519519
procedure,public :: swap => json_value_swap !! Swap two [[json_value]] pointers
520520
!! in a structure (or two different structures).
521-
procedure,public :: is_child_of => json_value_is_child_of !! Check if a [[json_value]] is a child of another.
521+
procedure,public :: is_child_of => json_value_is_child_of !! Check if a [[json_value]] is a descendant of another.
522522
procedure,public :: validate => json_value_validate !! Check that a [[json_value]] linked list is valid
523523
!! (i.e., is properly constructed). This may be
524524
!! useful if it has been constructed externally.
525+
procedure,public :: insert_after => json_value_insert_after !! insert a new element after an existing one,
526+
!! updating the JSON structure accordingly
525527

526528
!other private routines:
527529
procedure :: name_equal
@@ -2375,7 +2377,7 @@ subroutine json_update_string(json,p,name,val,found)
23752377
case default
23762378
found = .false.
23772379
call json%throw_exception('Error in json_update_string: '//&
2378-
'the variable is not a scalar value')
2380+
'the variable is not a scalar value')
23792381
end select
23802382

23812383
else
@@ -2481,6 +2483,72 @@ subroutine json_value_add_member(json,p,member)
24812483
end subroutine json_value_add_member
24822484
!*****************************************************************************************
24832485

2486+
!*****************************************************************************************
2487+
!>
2488+
! Inserts `new` after `p`, and updates the JSON structure accordingly.
2489+
!
2490+
!### Example
2491+
!
2492+
!````fortran
2493+
! program test
2494+
! use json_module
2495+
! implicit none
2496+
! logical(json_LK) :: found
2497+
! type(json_core) :: json
2498+
! type(json_value),pointer :: p,new,element
2499+
! call json%parse(file='myfile.json', p=p)
2500+
! call json%get(p,'x(3)',element,found) ! get pointer to an array element in the file
2501+
! call json%create_integer(new,1,'') ! create a new element
2502+
! call json%insert_after(element,new) ! insert new element after x(3)
2503+
! call json%print(p,'myfile2.json') ! write it to a file
2504+
! call json%destroy(p) ! cleanup
2505+
! end program test
2506+
!````
2507+
!
2508+
!@note This routine can be used to insert a new element
2509+
! into an array or object at a specific index.
2510+
2511+
subroutine json_value_insert_after(json,p,element)
2512+
2513+
implicit none
2514+
2515+
class(json_core),intent(inout) :: json
2516+
type(json_value),pointer :: p !! a value from a JSON structure
2517+
!! (presumably, this is a child of
2518+
!! an object or array).
2519+
type(json_value),pointer :: element !! the element to insert after `p`
2520+
2521+
type(json_value),pointer :: parent !! the parent of `p`
2522+
2523+
if (.not. json%exception_thrown) then
2524+
2525+
parent => p%parent
2526+
2527+
if (associated(parent)) then
2528+
element%parent => parent
2529+
parent%n_children = parent%n_children + 1
2530+
! if p is last in list have to update parent tail:
2531+
if (associated(parent%tail,p)) parent%tail => element
2532+
else
2533+
element%parent => null()
2534+
end if
2535+
2536+
!if are there any in the list after p:
2537+
if (associated(p%next)) then
2538+
element%next => p%next
2539+
element%next%previous => element
2540+
else
2541+
element%next => null()
2542+
end if
2543+
2544+
p%next => element
2545+
element%previous => p
2546+
2547+
end if
2548+
2549+
end subroutine json_value_insert_after
2550+
!*****************************************************************************************
2551+
24842552
!*****************************************************************************************
24852553
!> author: Jacob Williams
24862554
! date: 1/19/2014

src/tests/jf_test_20.f90

Lines changed: 125 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,125 @@
1+
!*****************************************************************************************
2+
!> author: Jacob Williams
3+
! date: 7/17/2016
4+
!
5+
! Test the `insert` routine.
6+
7+
module jf_test_20_mod
8+
9+
use json_module, lk => json_lk, rk => json_rk, ik => json_ik,&
10+
ck => json_ck, cdk => json_cdk
11+
use, intrinsic :: iso_fortran_env , only: error_unit,output_unit
12+
13+
implicit none
14+
15+
contains
16+
17+
subroutine test_20(error_cnt)
18+
19+
implicit none
20+
21+
integer,intent(out) :: error_cnt !! report number of errors to caller
22+
23+
type(json_core) :: json
24+
type(json_value),pointer :: p,new,element
25+
logical(lk) :: found,is_valid
26+
integer(IK),dimension(:),allocatable :: iarray
27+
character(kind=CK,len=:),allocatable :: error_msg
28+
29+
character(kind=CK,len=*),parameter :: json_example = '{"x":[1,2,3,4]}'
30+
31+
write(error_unit,'(A)') ''
32+
write(error_unit,'(A)') '================================='
33+
write(error_unit,'(A)') ' TEST 20'
34+
write(error_unit,'(A)') '================================='
35+
write(error_unit,'(A)') ''
36+
37+
error_cnt = 0
38+
39+
call json%parse(p,json_example)
40+
if (json%failed()) then
41+
call json%print_error_message(error_unit)
42+
error_cnt = error_cnt + 1
43+
else
44+
45+
!insert one in the middle:
46+
nullify(element)
47+
call json%get(p,'x(3)',element) ! get pointer to an array element in the file
48+
if (json%failed()) then
49+
call json%print_error_message(error_unit)
50+
error_cnt = error_cnt + 1
51+
else
52+
call json%create_integer(new,33,'') ! create a new element
53+
call json%insert_after(element,new) ! insert new element after x(3)
54+
if (json%failed()) then
55+
call json%print_error_message(error_unit)
56+
error_cnt = error_cnt + 1
57+
else
58+
call json%get(p,'x',iarray)
59+
if (.not. all(iarray==[1,2,3,33,4])) then
60+
write(error_unit,'(A,1x,*(I2,1X))') 'Error: unexpected output:',iarray
61+
error_cnt = error_cnt + 1
62+
else
63+
write(error_unit,'(A,1x,*(I2,1X))') 'Success:',iarray
64+
end if
65+
end if
66+
end if
67+
68+
!insert one at the end:
69+
nullify(element)
70+
call json%get(p,'x(5)',element) ! get pointer to an array element in the file
71+
if (json%failed()) then
72+
call json%print_error_message(error_unit)
73+
error_cnt = error_cnt + 1
74+
else
75+
call json%create_integer(new,44,'') ! create a new element
76+
call json%insert_after(element,new) ! insert new element after x(3)
77+
if (json%failed()) then
78+
call json%print_error_message(error_unit)
79+
error_cnt = error_cnt + 1
80+
else
81+
call json%get(p,'x',iarray)
82+
if (.not. all(iarray==[1,2,3,33,4,44])) then
83+
write(error_unit,'(A,1x,*(I2,1X))') 'Error: unexpected output:',iarray
84+
error_cnt = error_cnt + 1
85+
else
86+
write(error_unit,'(A,1x,*(I2,1X))') 'Success:',iarray
87+
end if
88+
end if
89+
end if
90+
91+
call json%validate(p,is_valid,error_msg)
92+
if (.not. is_valid) then
93+
write(error_unit,'(A)') trim(error_msg)
94+
error_cnt = error_cnt + 1
95+
end if
96+
97+
end if
98+
99+
! cleanup:
100+
call json%destroy(p)
101+
102+
write(error_unit,'(A)') ''
103+
write(error_unit,'(A)') '================================='
104+
write(error_unit,'(A)') ''
105+
106+
end subroutine test_20
107+
108+
end module jf_test_20_mod
109+
!*****************************************************************************************
110+
111+
!*****************************************************************************************
112+
program jf_test_20
113+
114+
!! 20th unit test.
115+
116+
use jf_test_20_mod, only: test_20
117+
118+
implicit none
119+
120+
integer :: n_errors
121+
call test_20(n_errors)
122+
if ( n_errors /= 0) stop 1
123+
124+
end program jf_test_20
125+
!*****************************************************************************************

0 commit comments

Comments
 (0)