unescape_string Subroutine

public subroutine unescape_string(str, error_message)

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

Arguments

Type IntentOptional AttributesName
character(kind=CK,len=:), intent(inout), allocatable:: str

in a json_value. out: decoded string.

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

will be allocated if there was an error


Calls

proc~~unescape_string~~CallsGraph proc~unescape_string unescape_string proc~valid_json_hex valid_json_hex proc~unescape_string->proc~valid_json_hex

Called by

proc~~unescape_string~~CalledByGraph proc~unescape_string unescape_string proc~parse_string parse_string proc~parse_string->proc~unescape_string

Contents

Source Code


Source Code

    subroutine unescape_string(str, error_message)

    implicit none

    character(kind=CK,len=:),allocatable,intent(inout) :: str           !! in: string as stored
                                                                        !! in a [[json_value]].
                                                                        !! out: decoded string.
    character(kind=CK,len=:),allocatable,intent(out)   :: error_message !! will be allocated if
                                                                        !! there was an error

    integer :: i   !! counter
    integer :: n   !! length of `str`
    integer :: m   !! length of `str_tmp`
    character(kind=CK,len=1) :: c  !! for scanning each character in string
    character(kind=CK,len=:),allocatable :: str_tmp !! temp decoded string (if the input
                                                    !! string contains an escape character
                                                    !! and needs to be decoded).

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

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

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

        do

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

            if (c == backslash) then

                if (i<n) then

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

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

                    case (CK_'u') ! 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

                            ! validate the hex string:
                            if (valid_json_hex(str(i+1:i+4))) then
                                m = m + 1
                                str_tmp(m:m+5) = str(i-1:i+4)
                                i = i + 4
                                m = m + 5
                            else
                                error_message = 'Error in unescape_string:'//&
                                                ' Invalid hexadecimal sequence in string "'//&
                                                trim(str)//'" ['//str(i-1:i+4)//']'
                                if (allocated(str_tmp)) deallocate(str_tmp)
                                return
                            end if
                        else
                            error_message = 'Error in unescape_string:'//&
                                            ' Invalid hexadecimal sequence in string "'//&
                                            trim(str)//'" ['//str(i-1:)//']'
                            if (allocated(str_tmp)) deallocate(str_tmp)
                            return
                        end if

                    case default

                        !unknown escape character
                        error_message = 'Error in unescape_string:'//&
                                        ' unknown escape sequence in string "'//&
                                        trim(str)//'" ['//backslash//c//']'
                        if (allocated(str_tmp)) deallocate(str_tmp)
                        return

                    end select

                else
                    ! an escape character is the last character in
                    ! the string. This is an error.
                    error_message = 'Error in unescape_string:'//&
                                    ' invalid escape character in string "'//&
                                    trim(str)//'"'
                    if (allocated(str_tmp)) deallocate(str_tmp)
                    return
                end if

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

        end do

        !trim trailing space:
        str = str_tmp(1:m)

    end if

    end subroutine unescape_string