Get the next character from the file (or string).
This routine ignores non-printing ASCII characters (iachar<=31) that are in strings.
Type | Intent | Optional | Attributes | Name | ||
---|---|---|---|---|---|---|
class(json_core), | intent(inout) | :: | json | |||
integer(kind=IK), | intent(in) | :: | unit | file unit number (if parsing from a file) |
||
character(kind=CK,len=*), | intent(in) | :: | str | JSON string (if parsing from a string) – only used if unit=0 |
||
logical(kind=LK), | intent(out) | :: | eof | true if the end of the file has been reached. |
||
logical(kind=LK), | intent(in), | optional | :: | skip_ws | to ignore whitespace. |
the popped character.
recursive function pop_char(json, unit, str, eof, skip_ws) result(popped)
implicit none
class(json_core),intent(inout) :: json
character(kind=CK,len=1) :: popped !! the popped character.
integer(IK),intent(in) :: unit !! file unit number (if parsing from a file)
character(kind=CK,len=*),intent(in) :: str !! JSON string (if parsing from a string) -- only used if unit=0
logical(LK),intent(out) :: eof !! true if the end of the file has been reached.
logical(LK),intent(in),optional :: skip_ws !! to ignore whitespace.
integer(IK) :: ios,str_len
character(kind=CK,len=1) :: c
logical(LK) :: ignore
if (.not. json%exception_thrown) then
eof = .false.
if (.not. present(skip_ws)) then
ignore = .false.
else
ignore = skip_ws
end if
do
if (json%pushed_index > 0) then
! there is a character pushed back on, most likely
! from the number parsing. Note: this can only occur if
! reading from a file when use_unformatted_stream=.false.
c = json%pushed_char(json%pushed_index:json%pushed_index)
json%pushed_index = json%pushed_index - 1
else
if (unit/=0) then !read from the file
!read the next character:
if (use_unformatted_stream) then
read(unit=unit,pos=json%ipos,iostat=ios) c
else
read(unit=unit,fmt='(A1)',advance='NO',iostat=ios) c
end if
json%ipos = json%ipos + 1
!....note: maybe try read the file in chunks...
!.... or use asynchronous read with double buffering
! (see Modern Fortran: Style and Usage)
else !read from the string
str_len = len(str) !length of the string
if (json%ipos<=str_len) then
c = str(json%ipos:json%ipos)
ios = 0
else
ios = IOSTAT_END !end of the string
end if
json%ipos = json%ipos + 1
end if
json%char_count = json%char_count + 1 !character count in the current line
if (IS_IOSTAT_END(ios)) then !end of file
json%char_count = 0
eof = .true.
exit
else if (IS_IOSTAT_EOR(ios) .or. c==newline) then !end of record
json%char_count = 0
json%line_count = json%line_count + 1
cycle
end if
end if
if (any(c == control_chars)) then
! non printing ascii characters
cycle
else if (ignore .and. c == space) then
cycle
else
popped = c
exit
end if
end do
end if
end function pop_char