json_value_remove Subroutine

private subroutine json_value_remove(json, p, destroy)

Remove a json_value (and all its children) from a linked-list structure, preserving the rest of the structure.

Examples

To extract an object from one JSON structure, and add it to another:

     type(json_core) :: json
     type(json_value),pointer :: json1,json2,p
     logical :: found
     !create and populate json1 and json2
     call json%get(json1,'name',p,found)  ! get pointer to name element of json1
     call json%remove(p,destroy=.false.)  ! remove it from json1 (don't destroy)
     call json%add(json2,p)               ! add it to json2

To remove an object from a JSON structure (and destroy it):

     type(json_core) :: json
     type(json_value),pointer :: json1,p
     logical :: found
     !create and populate json1
     call json%get(json1,'name',p,found)  ! get pointer to name element of json1
     call json%remove(p)                  ! remove and destroy it

History

  • Jacob Williams : 12/28/2014 : added destroy optional argument.
  • Jacob Williams : 12/04/2020 : bug fix.

Arguments

TypeIntentOptionalAttributesName
class(json_core), intent(inout) :: json
type(json_value), pointer:: p
logical(kind=LK), intent(in), optional :: destroy

Option to destroy p after it is removed:

  • If destroy is not present, it is also destroyed.
  • If destroy is present and true, it is destroyed.
  • If destroy is present and false, it is not destroyed.

Contents

Source Code


Source Code

    subroutine json_value_remove(json,p,destroy)

    implicit none

    class(json_core),intent(inout)  :: json
    type(json_value),pointer        :: p
    logical(LK),intent(in),optional :: destroy  !! Option to destroy `p` after it is removed:
                                                !!
                                                !! * If `destroy` is not present, it is also destroyed.
                                                !! * If `destroy` is present and true, it is destroyed.
                                                !! * If `destroy` is present and false, it is not destroyed.

    type(json_value),pointer :: parent     !! pointer to parent
    type(json_value),pointer :: previous   !! pointer to previous
    type(json_value),pointer :: next       !! pointer to next
    logical(LK)              :: destroy_it !! if `p` should be destroyed

    if (associated(p)) then

        !optional input argument:
        if (present(destroy)) then
            destroy_it = destroy
        else
            destroy_it = .true.
        end if

        if (associated(p%parent)) then

            parent => p%parent

            if (associated(p%next)) then

                !there are later items in the list:
                next => p%next

                if (associated(p%previous)) then
                    !there are earlier items in the list
                    previous => p%previous
                    previous%next => next
                    next%previous => previous
                else
                    !this is the first item in the list
                    parent%children => next
                    nullify(next%previous)
                end if

            else

                if (associated(p%previous)) then
                    !there are earlier items in the list:
                    previous => p%previous
                    nullify(previous%next)
                    parent%tail => previous
                else
                    !this is the only item in the list:
                    nullify(parent%children)
                    nullify(parent%tail)
                end if

            end if

            ! nullify all pointers to original structure:
            nullify(p%next)
            nullify(p%previous)
            nullify(p%parent)

            parent%n_children = parent%n_children - 1

        end if

        if (destroy_it) call json%destroy(p)

    end if

    end subroutine json_value_remove