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 digitsType | Intent | Optional | Attributes | Name | ||
---|---|---|---|---|---|---|
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 |
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