@@ -148,7 +148,6 @@ module json_value_module
148
148
! call json%print(p,'test.json') !write it to a file
149
149
! call json%destroy(p) !cleanup
150
150
! end program test
151
- ! type,public :: json_core
152
151
! ````
153
152
type,public :: json_core
154
153
@@ -503,6 +502,14 @@ module json_value_module
503
502
procedure :: json_matrix_info
504
503
procedure :: MAYBEWRAP(json_matrix_info_by_path)
505
504
505
+ ! >
506
+ ! insert a new element after an existing one,
507
+ ! updating the JSON structure accordingly
508
+ generic,public :: insert_after = > json_value_insert_after, &
509
+ json_value_insert_after_child_by_index
510
+ procedure :: json_value_insert_after
511
+ procedure :: json_value_insert_after_child_by_index
512
+
506
513
procedure ,public :: remove = > json_value_remove ! ! Remove a [[json_value]] from a linked-list structure.
507
514
procedure ,public :: check_for_errors = > json_check_for_errors ! ! check for error and get error message
508
515
procedure ,public :: clear_exceptions = > json_clear_exceptions ! ! clear exceptions
@@ -518,7 +525,7 @@ module json_value_module
518
525
procedure ,public :: print_error_message = > json_print_error_message ! ! simply routine to print error messages
519
526
procedure ,public :: swap = > json_value_swap ! ! Swap two [[json_value]] pointers
520
527
! ! 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.
528
+ procedure ,public :: is_child_of = > json_value_is_child_of ! ! Check if a [[json_value]] is a descendant of another.
522
529
procedure ,public :: validate = > json_value_validate ! ! Check that a [[json_value]] linked list is valid
523
530
! ! (i.e., is properly constructed). This may be
524
531
! ! useful if it has been constructed externally.
@@ -2375,7 +2382,7 @@ subroutine json_update_string(json,p,name,val,found)
2375
2382
case default
2376
2383
found = .false.
2377
2384
call json% throw_exception(' Error in json_update_string: ' // &
2378
- ' the variable is not a scalar value' )
2385
+ ' the variable is not a scalar value' )
2379
2386
end select
2380
2387
2381
2388
else
@@ -2481,6 +2488,158 @@ subroutine json_value_add_member(json,p,member)
2481
2488
end subroutine json_value_add_member
2482
2489
! *****************************************************************************************
2483
2490
2491
+ ! *****************************************************************************************
2492
+ ! >
2493
+ ! Inserts `element` after `p`, and updates the JSON structure accordingly.
2494
+ !
2495
+ ! ### Example
2496
+ !
2497
+ ! ````fortran
2498
+ ! program test
2499
+ ! use json_module
2500
+ ! implicit none
2501
+ ! logical(json_LK) :: found
2502
+ ! type(json_core) :: json
2503
+ ! type(json_value),pointer :: p,new,element
2504
+ ! call json%parse(file='myfile.json', p=p)
2505
+ ! call json%get(p,'x(3)',element,found) ! get pointer to an array element in the file
2506
+ ! call json%create_integer(new,1,'') ! create a new element
2507
+ ! call json%insert_after(element,new) ! insert new element after x(3)
2508
+ ! call json%print(p,'myfile2.json') ! write it to a file
2509
+ ! call json%destroy(p) ! cleanup
2510
+ ! end program test
2511
+ ! ````
2512
+ !
2513
+ ! ### Details
2514
+ !
2515
+ ! * This routine can be used to insert a new element (or set of elements)
2516
+ ! into an array or object at a specific index.
2517
+ ! See [[json_value_insert_after_child_by_index]]
2518
+ ! * Children and subsequent elements of `element` are carried along.
2519
+ ! * If the inserted elements are part of an existing list, then
2520
+ ! they are removed from that list.
2521
+ !
2522
+ ! ````
2523
+ ! p
2524
+ ! [1] - [2] - [3] - [4]
2525
+ ! |
2526
+ ! [5] - [6] - [7] n=3 elements inserted
2527
+ ! element last
2528
+ !
2529
+ ! Result is:
2530
+ !
2531
+ ! [1] - [2] - [5] - [6] - [7] - [3] - [4]
2532
+ !
2533
+ ! ````
2534
+
2535
+ subroutine json_value_insert_after (json ,p ,element )
2536
+
2537
+ implicit none
2538
+
2539
+ class(json_core),intent (inout ) :: json
2540
+ type (json_value),pointer :: p ! ! a value from a JSON structure
2541
+ ! ! (presumably, this is a child of
2542
+ ! ! an object or array).
2543
+ type (json_value),pointer :: element ! ! the element to insert after `p`
2544
+
2545
+ type (json_value),pointer :: parent ! ! the parent of `p`
2546
+ type (json_value),pointer :: next ! ! temp pointer for traversing structure
2547
+ type (json_value),pointer :: last ! ! the last of the items being inserted
2548
+ integer :: n ! ! number of items being inserted
2549
+
2550
+ if (.not. json% exception_thrown) then
2551
+
2552
+ parent = > p% parent
2553
+
2554
+ ! set first parent of inserted list:
2555
+ element% parent = > parent
2556
+
2557
+ ! Count the number of inserted elements.
2558
+ ! and set their parents.
2559
+ n = 1 ! initialize counter
2560
+ next = > element% next
2561
+ last = > element
2562
+ do
2563
+ if (.not. associated (next)) exit
2564
+ n = n + 1
2565
+ next% parent = > parent
2566
+ last = > next
2567
+ next = > next% next
2568
+ end do
2569
+
2570
+ if (associated (parent)) then
2571
+ ! update parent's child counter:
2572
+ parent% n_children = parent% n_children + n
2573
+ ! if p is last of parents children then
2574
+ ! also have to update parent tail pointer:
2575
+ if (associated (parent% tail,p)) then
2576
+ parent% tail = > last
2577
+ end if
2578
+ end if
2579
+
2580
+ if (associated (element% previous)) then
2581
+ ! element is apparently part of an existing list,
2582
+ ! so have to update that as well.
2583
+ if (associated (element% previous% parent)) then
2584
+ element% previous% parent% n_children = &
2585
+ element% previous% parent% n_children - n
2586
+ element% previous% parent% tail = > &
2587
+ element% previous ! now the last one in the list
2588
+ else
2589
+ ! this would be a memory leak if the previous entries
2590
+ ! are not otherwise being pointed too
2591
+ ! [throw an error in this case???]
2592
+ end if
2593
+ ! remove element from the other list:
2594
+ element% previous% next = > null ()
2595
+ end if
2596
+ element% previous = > p
2597
+
2598
+ if (associated (p% next)) then
2599
+ ! if there are any in the list after p:
2600
+ last% next = > p% next
2601
+ last% next% previous = > element
2602
+ else
2603
+ last% next = > null ()
2604
+ end if
2605
+ p% next = > element
2606
+
2607
+ end if
2608
+
2609
+ end subroutine json_value_insert_after
2610
+ ! *****************************************************************************************
2611
+
2612
+ ! *****************************************************************************************
2613
+ ! >
2614
+ ! Inserts `element` after the `idx`-th child of `p`,
2615
+ ! and updates the JSON structure accordingly. This is just
2616
+ ! a wrapper for [[json_value_insert_after]].
2617
+
2618
+ subroutine json_value_insert_after_child_by_index (json ,p ,idx ,element )
2619
+
2620
+ implicit none
2621
+
2622
+ class(json_core),intent (inout ) :: json
2623
+ type (json_value),pointer :: p ! ! a JSON object or array.
2624
+ integer (IK),intent (in ) :: idx ! ! the index of the child of `p` to
2625
+ ! ! insert the new element after
2626
+ type (json_value),pointer :: element ! ! the element to insert
2627
+
2628
+ type (json_value),pointer :: tmp ! ! for getting the `idx`-th child of `p`
2629
+
2630
+ if (.not. json% exception_thrown) then
2631
+
2632
+ ! get the idx-th child of p:
2633
+ call json% get_child(p,idx,tmp)
2634
+
2635
+ ! call json_value_insert_after:
2636
+ if (.not. json% failed()) call json% insert_after(tmp,element)
2637
+
2638
+ end if
2639
+
2640
+ end subroutine json_value_insert_after_child_by_index
2641
+ ! *****************************************************************************************
2642
+
2484
2643
! *****************************************************************************************
2485
2644
! > author: Jacob Williams
2486
2645
! date: 1/19/2014
0 commit comments