unescape_string Subroutine

private subroutine unescape_string(str_in, str_out)

Arguments

Type IntentOptional AttributesName
character(kind=CK,len=*), intent(in) :: str_in

string as stored in a json_value

character(kind=CK,len=:), intent(out), allocatable:: str_out

decoded string

Description

Remove the escape characters from a JSON string and return it.

The escaped characters are denoted by the '' character:

    '\"'        quotation mark
    '\\'        reverse solidus
    '\/'        solidus
    '\b'        backspace
    '\f'        formfeed
    '\n'        newline (LF)
    '\r'        carriage return (CR)
    '\t'        horizontal tab
    '\uXXXX'    4 hexadecimal digits

Calls

proc~~unescape_string~~CallsGraph proc~unescape_string unescape_string interface~to_unicode to_unicode proc~unescape_string->interface~to_unicode interface~throw_exception throw_exception proc~unescape_string->interface~throw_exception proc~to_uni to_uni interface~to_unicode->proc~to_uni proc~to_uni_vec to_uni_vec interface~to_unicode->proc~to_uni_vec proc~json_throw_exception json_throw_exception interface~throw_exception->proc~json_throw_exception
Help

Called By

proc~~unescape_string~~CalledByGraph proc~unescape_string unescape_string proc~json_get_string json_get_string proc~json_get_string->proc~unescape_string proc~json_get_string_with_path json_get_string_with_path proc~json_get_string_with_path->proc~json_get_string proc~wrap_json_get_string_with_path wrap_json_get_string_with_path proc~wrap_json_get_string_with_path->proc~json_get_string_with_path interface~json_get json_get interface~json_get->proc~json_get_string interface~json_get->proc~json_get_string_with_path proc~json_get_logical_vec_with_path json_get_logical_vec_with_path interface~json_get->proc~json_get_logical_vec_with_path proc~json_get_string_vec_with_path json_get_string_vec_with_path interface~json_get->proc~json_get_string_vec_with_path proc~json_get_logical_vec json_get_logical_vec interface~json_get->proc~json_get_logical_vec proc~json_get_integer_vec json_get_integer_vec interface~json_get->proc~json_get_integer_vec proc~json_get_integer_vec_with_path json_get_integer_vec_with_path interface~json_get->proc~json_get_integer_vec_with_path proc~json_get_double_vec_with_path json_get_double_vec_with_path interface~json_get->proc~json_get_double_vec_with_path proc~json_get_string_vec json_get_string_vec interface~json_get->proc~json_get_string_vec proc~json_get_double_vec json_get_double_vec interface~json_get->proc~json_get_double_vec proc~json_file_get_string json_file_get_string proc~json_file_get_string->interface~json_get proc~json_file_get_string_vec json_file_get_string_vec proc~json_file_get_string_vec->interface~json_get proc~json_get_logical_vec_with_path->interface~json_get proc~test_12 test_12 proc~test_12->interface~json_get interface~json_update json_update proc~test_12->interface~json_update proc~json_value_remove_if_present json_value_remove_if_present proc~json_value_remove_if_present->interface~json_get proc~json_get_string_vec_with_path->interface~json_get proc~json_file_get_integer json_file_get_integer proc~json_file_get_integer->interface~json_get proc~rename rename proc~rename->interface~json_get proc~rename->interface~json_update proc~json_get_logical_vec->interface~json_get proc~test_2 test_2 proc~test_2->interface~json_get proc~test_2->interface~json_update proc~test_7 test_7 proc~test_7->interface~json_get proc~json_file_get_integer_vec json_file_get_integer_vec proc~json_file_get_integer_vec->interface~json_get proc~json_file_get_double json_file_get_double proc~json_file_get_double->interface~json_get proc~json_update_logical json_update_logical proc~json_update_logical->interface~json_get proc~json_get_integer_vec->interface~json_get proc~json_file_get_double_vec json_file_get_double_vec proc~json_file_get_double_vec->interface~json_get proc~json_update_double json_update_double proc~json_update_double->interface~json_get proc~json_get_integer_vec_with_path->interface~json_get proc~json_update_integer json_update_integer proc~json_update_integer->interface~json_get proc~json_file_get_logical json_file_get_logical proc~json_file_get_logical->interface~json_get proc~json_get_double_vec_with_path->interface~json_get proc~json_update_string json_update_string proc~json_update_string->interface~json_get proc~json_get_string_vec->interface~json_get proc~json_get_double_vec->interface~json_get proc~json_file_get_logical_vec json_file_get_logical_vec proc~json_file_get_logical_vec->interface~json_get proc~test_10 test_10 proc~test_10->interface~json_get interface~json_remove_if_present json_remove_if_present proc~test_10->interface~json_remove_if_present proc~test_10->interface~json_update proc~wrap_json_file_get_string wrap_json_file_get_string proc~wrap_json_file_get_string->proc~json_file_get_string proc~wrap_json_file_get_string_vec wrap_json_file_get_string_vec proc~wrap_json_file_get_string_vec->proc~json_file_get_string_vec proc~wrap_json_get_logical_vec_with_path wrap_json_get_logical_vec_with_path proc~wrap_json_get_logical_vec_with_path->proc~json_get_logical_vec_with_path program~jf_test_12 jf_test_12 program~jf_test_12->proc~test_12 proc~wrap_json_value_remove_if_present wrap_json_value_remove_if_present proc~wrap_json_value_remove_if_present->proc~json_value_remove_if_present interface~json_remove_if_present->proc~json_value_remove_if_present proc~wrap_json_get_string_vec_with_path wrap_json_get_string_vec_with_path proc~wrap_json_get_string_vec_with_path->proc~json_get_string_vec_with_path proc~wrap_json_file_get_integer wrap_json_file_get_integer proc~wrap_json_file_get_integer->proc~json_file_get_integer program~jf_test_2 jf_test_2 program~jf_test_2->proc~test_2 program~jf_test_7 jf_test_7 program~jf_test_7->proc~test_7 proc~wrap_json_file_get_integer_vec wrap_json_file_get_integer_vec proc~wrap_json_file_get_integer_vec->proc~json_file_get_integer_vec proc~wrap_json_file_get_double wrap_json_file_get_double proc~wrap_json_file_get_double->proc~json_file_get_double proc~wrap_json_update_logical wrap_json_update_logical proc~wrap_json_update_logical->proc~json_update_logical interface~json_update->proc~json_update_logical interface~json_update->proc~json_update_double interface~json_update->proc~json_update_integer interface~json_update->proc~json_update_string proc~json_file_update_integer json_file_update_integer proc~json_file_update_integer->interface~json_update proc~json_file_update_string json_file_update_string proc~json_file_update_string->interface~json_update proc~test_1 test_1 proc~test_1->interface~json_update proc~json_file_update_real json_file_update_real proc~json_file_update_real->interface~json_update proc~json_file_update_logical json_file_update_logical proc~json_file_update_logical->interface~json_update proc~wrap_json_file_update_integer wrap_json_file_update_integer proc~wrap_json_file_update_integer->proc~json_file_update_integer proc~json_file_update_string_name_ascii json_file_update_string_name_ascii proc~json_file_update_string_name_ascii->proc~json_file_update_string proc~wrap_json_file_update_string wrap_json_file_update_string proc~wrap_json_file_update_string->proc~json_file_update_string proc~json_file_update_string_val_ascii json_file_update_string_val_ascii proc~json_file_update_string_val_ascii->proc~json_file_update_string program~jf_test_1 jf_test_1 program~jf_test_1->proc~test_1 proc~wrap_json_file_update_real wrap_json_file_update_real proc~wrap_json_file_update_real->proc~json_file_update_real proc~wrap_json_file_update_logical wrap_json_file_update_logical proc~wrap_json_file_update_logical->proc~json_file_update_logical proc~wrap_json_file_get_double_vec wrap_json_file_get_double_vec proc~wrap_json_file_get_double_vec->proc~json_file_get_double_vec proc~wrap_json_update_double wrap_json_update_double proc~wrap_json_update_double->proc~json_update_double proc~wrap_json_get_integer_vec_with_path wrap_json_get_integer_vec_with_path proc~wrap_json_get_integer_vec_with_path->proc~json_get_integer_vec_with_path proc~wrap_json_update_integer wrap_json_update_integer proc~wrap_json_update_integer->proc~json_update_integer proc~wrap_json_file_get_logical wrap_json_file_get_logical proc~wrap_json_file_get_logical->proc~json_file_get_logical proc~wrap_json_get_double_vec_with_path wrap_json_get_double_vec_with_path proc~wrap_json_get_double_vec_with_path->proc~json_get_double_vec_with_path proc~json_update_string_name_ascii json_update_string_name_ascii proc~json_update_string_name_ascii->proc~json_update_string proc~wrap_json_update_string wrap_json_update_string proc~wrap_json_update_string->proc~json_update_string proc~json_update_string_val_ascii json_update_string_val_ascii proc~json_update_string_val_ascii->proc~json_update_string proc~wrap_json_file_get_logical_vec wrap_json_file_get_logical_vec proc~wrap_json_file_get_logical_vec->proc~json_file_get_logical_vec program~jf_test_10 jf_test_10 program~jf_test_10->proc~test_10
Help

Variables

TypeVisibility AttributesNameInitial
integer, public :: i

counter

integer, public :: n

length of str_in

integer, public :: m

length of str_out

character(kind=CK,len=1), public :: c

for scanning each character in string


Source Code

    subroutine unescape_string(str_in, str_out)

    implicit none

    character(kind=CK,len=*),intent(in)              :: str_in  !! string as stored in a [[json_value]]
    character(kind=CK,len=:),allocatable,intent(out) :: str_out !! decoded string

    integer :: i   !! counter
    integer :: n   !! length of str_in
    integer :: m   !! length of str_out
    character(kind=CK,len=1) :: c  !! for scanning each character in string

    if (scan(str_in,backslash)>0) then

        !there is at least one escape character, so process this string:

        n = len(str_in)
        str_out = repeat(space,n) !size the output string (will be trimmed later)
        m = 0  !counter in str_out
        i = 0  !counter in str_in

        do

            i = i + 1
            if (i>n) exit ! finished
            c = str_in(i:i) ! get next character in the string

            if (c == backslash) then

                if (i<n) then

                    i = i + 1
                    c = str_in(i:i) !character after the escape

                    if (any(c == [quotation_mark,backslash,slash, &
                         to_unicode(['b','f','n','r','t'])])) then

                        select case(c)
                        case (quotation_mark,backslash,slash)
                            !use d as is
                        case (CK_'b')
                             c = bspace
                        case (CK_'f')
                             c = formfeed
                        case (CK_'n')
                             c = newline
                        case (CK_'r')
                             c = carriage_return
                        case (CK_'t')
                             c = horizontal_tab
                        end select

                        m = m + 1
                        str_out(m:m) = c

                    else if (c == 'u') then !expecting 4 hexadecimal digits after
                                            !the escape character    [\uXXXX]

                        !for now, we are just returning them as is
                        ![not checking to see if it is a valid hex value]
                        !
                        ! Example:
                        !   123456
                        !   \uXXXX

                        if (i+4<=n) then
                            m = m + 1
                            str_out(m:m+5) = str_in(i-1:i+4)
                            i = i + 4
                            m = m + 5
                        else
                            call throw_exception('Error in json_get_string:'//&
                                                 ' Invalid hexadecimal sequence'//&
                                                 ' in string: '//str_in(i-1:))
                            str_out = ''
                            return
                        end if

                    else
                        !unknown escape character
                        call throw_exception('Error in json_get_string:'//&
                                             ' unknown escape sequence in string "'//&
                                             trim(str_in)//'" ['//backslash//c//']')
                        str_out = ''
                        return
                    end if

                else
                    !an escape character is the last character in
                    ! the string [this may not be valid syntax,
                    ! but just keep it]
                    m = m + 1
                    str_out(m:m) = c
                end if

            else
                m = m + 1
                str_out(m:m) = c
            end if

        end do

        !trim trailing space:
        str_out = str_out(1:m)

    else
        !there are no escape characters, so return as is:
        str_out = str_in
    end if

    end subroutine unescape_string