json_value_get_child_by_index Subroutine

private subroutine json_value_get_child_by_index(json, p, idx, child, found)

Returns a child in the object or array given the index.

Arguments

Type IntentOptional AttributesName
class(json_core), intent(inout) :: json
type(json_value), intent(in), pointer:: p

object or array JSON data

integer(kind=IK), intent(in) :: idx

index of the child (this is a 1-based Fortran style array index).

type(json_value), pointer:: child

pointer to the child

logical(kind=LK), intent(out), optional :: found

true if the value was found (if not present, an exception will be thrown if it was not found. If present and not found, no exception will be thrown).


Contents


Source Code

    subroutine json_value_get_child_by_index(json, p, idx, child, found)

    implicit none

    class(json_core),intent(inout)      :: json
    type(json_value),pointer,intent(in) :: p      !! object or array JSON data
    integer(IK),intent(in)              :: idx    !! index of the child
                                                  !! (this is a 1-based Fortran
                                                  !! style array index).
    type(json_value),pointer            :: child  !! pointer to the child
    logical(LK),intent(out),optional    :: found  !! true if the value was found
                                                  !! (if not present, an exception
                                                  !! will be thrown if it was not
                                                  !! found.  If present and not
                                                  !! found, no exception will be
                                                  !! thrown).

    integer(IK) :: i  !! counter

    nullify(child)

    if (.not. json%exception_thrown) then

        if (associated(p%children)) then

            ! If getting first or last child, we can do this quickly.
            ! Otherwise, traverse the list.
            if (idx==1) then

                child => p%children  ! first one

            elseif (idx==p%n_children) then

                if (associated(p%tail)) then
                    child => p%tail  ! last one
                else
                    call json%throw_exception('Error in json_value_get_child_by_index:'//&
                                              ' child%tail is not associated.',found)
                end if

            elseif (idx<1 .or. idx>p%n_children) then

                call json%throw_exception('Error in json_value_get_child_by_index:'//&
                                          ' idx is out of range.',found)

            else

                ! if idx is closer to the end, we traverse the list backward from tail,
                ! otherwise we traverse it forward from children:

                if (p%n_children-idx < idx) then  ! traverse backward

                    child => p%tail

                    do i = 1, p%n_children - idx

                        if (associated(child%previous)) then
                            child => child%previous
                        else
                            call json%throw_exception('Error in json_value_get_child_by_index:'//&
                                                      ' child%previous is not associated.',found)
                            nullify(child)
                            exit
                        end if

                    end do

                else  ! traverse forward

                    child => p%children

                    do i = 1, idx - 1

                        if (associated(child%next)) then
                            child => child%next
                        else
                            call json%throw_exception('Error in json_value_get_child_by_index:'//&
                                                      ' child%next is not associated.',found)
                            nullify(child)
                            exit
                        end if

                    end do

                end if

            end if

        else

            call json%throw_exception('Error in json_value_get_child_by_index:'//&
                                      ' p%children is not associated.',found)

        end if

        ! found output:
        if (json%exception_thrown) then
            if (present(found)) then
                call json%clear_exceptions()
                found = .false.
            end if
        else
            if (present(found)) found = .true.
        end if

    else
        if (present(found)) found = .false.
    end if

    end subroutine json_value_get_child_by_index