@@ -256,6 +256,12 @@ module json_value_module
256256 ! ! (both escaped and unescaped versions are still
257257 ! ! valid in all cases).
258258
259+ integer :: ichunk = 0 ! ! index in `chunk` for [[pop_char]]
260+ ! ! when `use_unformatted_stream=True`
261+ integer :: filesize = 0 ! ! the file size when when `use_unformatted_stream=True`
262+ character (kind= CK,len= :),allocatable :: chunk ! ! a chunk read from a stream file
263+ ! ! when `use_unformatted_stream=True`
264+
259265 contains
260266
261267 private
@@ -918,6 +924,11 @@ subroutine json_initialize(me,verbose,compact_reals,&
918924 me% char_count = 0
919925 me% line_count = 1
920926 me% ipos = 1
927+ if (use_unformatted_stream) then
928+ me% filesize = 0
929+ me% ichunk = 0
930+ me% chunk = repeat (' ' , stream_chunk_size) ! default chunk size
931+ end if
921932
922933#ifdef USE_UCS4
923934 ! reopen stdout and stderr with utf-8 encoding
@@ -8755,6 +8766,11 @@ subroutine json_parse_file(json, file, p, unit)
87558766
87568767 if (istat== 0 ) then
87578768
8769+ if (use_unformatted_stream) then
8770+ ! save the file save to be read:
8771+ inquire (unit= iunit, size= json% filesize, iostat= istat)
8772+ end if
8773+
87588774 ! create the value and associate the pointer
87598775 call json_value_create(p)
87608776
@@ -9110,6 +9126,7 @@ recursive subroutine parse_value(json, unit, str, value)
91109126 ! the routine is being called incorrectly.
91119127 if (.not. associated (value)) then
91129128 call json% throw_exception(' Error in parse_value: value pointer not associated.' )
9129+ return
91139130 end if
91149131
91159132 ! pop the next non whitespace character off the file
@@ -9957,7 +9974,7 @@ subroutine parse_string(json, unit, str, string)
99579974 character (kind= CK,len= :),allocatable :: error_message ! ! for string unescaping
99589975
99599976 ! at least return a blank string if there is a problem:
9960- string = repeat (space, chunk_size)
9977+ string = blank_chunk
99619978
99629979 if (.not. json% exception_thrown) then
99639980
@@ -9982,7 +9999,7 @@ subroutine parse_string(json, unit, str, string)
99829999 else
998310000
998410001 ! if the string is not big enough, then add another chunk:
9985- if (ip> len (string)) string = string // repeat (space, chunk_size)
10002+ if (ip> len (string)) string = string // blank_chunk
998610003
998710004 ! append to string:
998810005 string (ip:ip) = c
@@ -10098,7 +10115,7 @@ subroutine parse_number(json, unit, str, value)
1009810115
1009910116 if (.not. json% exception_thrown) then
1010010117
10101- tmp = repeat (space, chunk_size)
10118+ tmp = blank_chunk
1010210119 ip = 1
1010310120 first = .true.
1010410121 is_integer = .true. ! assume it may be an integer, unless otherwise determined
@@ -10122,7 +10139,7 @@ subroutine parse_number(json, unit, str, value)
1012210139
1012310140 ! add it to the string:
1012410141 ! tmp = tmp // c !...original
10125- if (ip> len (tmp)) tmp = tmp // repeat (space, chunk_size)
10142+ if (ip> len (tmp)) tmp = tmp // blank_chunk
1012610143 tmp(ip:ip) = c
1012710144 ip = ip + 1
1012810145
@@ -10132,15 +10149,15 @@ subroutine parse_number(json, unit, str, value)
1013210149
1013310150 ! add it to the string:
1013410151 ! tmp = tmp // c !...original
10135- if (ip> len (tmp)) tmp = tmp // repeat (space, chunk_size)
10152+ if (ip> len (tmp)) tmp = tmp // blank_chunk
1013610153 tmp(ip:ip) = c
1013710154 ip = ip + 1
1013810155
1013910156 case (CK_' 0' :CK_' 9' ) ! valid characters for numbers
1014010157
1014110158 ! add it to the string:
1014210159 ! tmp = tmp // c !...original
10143- if (ip> len (tmp)) tmp = tmp // repeat (space, chunk_size)
10160+ if (ip> len (tmp)) tmp = tmp // blank_chunk
1014410161 tmp(ip:ip) = c
1014510162 ip = ip + 1
1014610163
@@ -10185,7 +10202,7 @@ end subroutine parse_number
1018510202! @note This routine ignores non-printing ASCII characters
1018610203! (`iachar<=31`) that are in strings.
1018710204
10188- recursive subroutine pop_char (json ,unit ,str ,skip_ws ,skip_comments ,eof ,popped )
10205+ subroutine pop_char (json ,unit ,str ,skip_ws ,skip_comments ,eof ,popped )
1018910206
1019010207 implicit none
1019110208
@@ -10239,16 +10256,41 @@ recursive subroutine pop_char(json,unit,str,skip_ws,skip_comments,eof,popped)
1023910256
1024010257 ! read the next character:
1024110258 if (use_unformatted_stream) then
10242- read (unit= unit,pos= json% ipos,iostat= ios) c
10259+
10260+ ! in this case, we read the file in chunks.
10261+ ! if we already have the character we need,
10262+ ! then get it from the chunk. Otherwise,
10263+ ! read in another chunk.
10264+ if (json% ichunk< 1 ) then
10265+ ! read in a chunk:
10266+ json% ichunk = 0
10267+ if (json% filesize< json% ipos+ len (json% chunk)- 1 ) then
10268+ ! for the last chunk, we resize
10269+ ! it to the correct size:
10270+ json% chunk = repeat (' ' , json% filesize- json% ipos+1 )
10271+ end if
10272+ read (unit= unit,pos= json% ipos,iostat= ios) json% chunk
10273+ else
10274+ ios = 0
10275+ end if
10276+ json% ichunk = json% ichunk + 1
10277+ if (json% ichunk> len (json% chunk)) then
10278+ ! check this just in case
10279+ ios = IOSTAT_END
10280+ else
10281+ ! get the next character from the chunk:
10282+ c = json% chunk(json% ichunk:json% ichunk)
10283+ if (json% ichunk== len (json% chunk)) then
10284+ json% ichunk = 0 ! reset for next chunk
10285+ end if
10286+ end if
10287+
1024310288 else
10289+ ! a formatted read:
1024410290 read (unit= unit,fmt= ' (A1)' ,advance= ' NO' ,iostat= ios) c
1024510291 end if
1024610292 json% ipos = json% ipos + 1
1024710293
10248- ! ....note: maybe try read the file in chunks...
10249- ! .... or use asynchronous read with double buffering
10250- ! (see Modern Fortran: Style and Usage)
10251-
1025210294 else ! read from the string
1025310295
1025410296 str_len = len (str) ! length of the string
@@ -10339,7 +10381,8 @@ subroutine push_char(json,c)
1033910381
1034010382 ! in this case, c is ignored, and we just
1034110383 ! decrement the stream position counter:
10342- json% ipos = json% ipos - 1
10384+ json% ipos = json% ipos - 1
10385+ json% ichunk = json% ichunk - 1
1034310386
1034410387 else
1034510388
0 commit comments