@@ -258,8 +258,9 @@ module json_value_module
258
258
259
259
integer :: ichunk = 0 ! ! index in `chunk` for [[pop_char]]
260
260
! ! when `use_unformatted_stream=True`
261
- character (kind= CK,len= stream_chunk_size) :: chunk = CK_' ' ! ! a chunk read from a stream file
262
- ! ! 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`
263
264
264
265
contains
265
266
@@ -922,8 +923,11 @@ subroutine json_initialize(me,verbose,compact_reals,&
922
923
me% char_count = 0
923
924
me% line_count = 1
924
925
me% ipos = 1
925
- me% ichunk = 0
926
- me% chunk = ' '
926
+ if (use_unformatted_stream) then
927
+ me% filesize = 0
928
+ me% ichunk = 0
929
+ me% chunk = repeat (' ' , stream_chunk_size) ! default chunk size
930
+ end if
927
931
928
932
#ifdef USE_UCS4
929
933
! reopen stdout and stderr with utf-8 encoding
@@ -8761,6 +8765,11 @@ subroutine json_parse_file(json, file, p, unit)
8761
8765
8762
8766
if (istat== 0 ) then
8763
8767
8768
+ if (use_unformatted_stream) then
8769
+ ! save the file save to be read:
8770
+ inquire (unit= iunit, size= json% filesize, iostat= istat)
8771
+ end if
8772
+
8764
8773
! create the value and associate the pointer
8765
8774
call json_value_create(p)
8766
8775
@@ -9926,7 +9935,7 @@ subroutine parse_string(json, unit, str, string)
9926
9935
character (kind= CK,len= :),allocatable :: error_message ! ! for string unescaping
9927
9936
9928
9937
! at least return a blank string if there is a problem:
9929
- string = repeat (space, chunk_size)
9938
+ string = blank_chunk
9930
9939
9931
9940
if (.not. json% exception_thrown) then
9932
9941
@@ -9951,7 +9960,7 @@ subroutine parse_string(json, unit, str, string)
9951
9960
else
9952
9961
9953
9962
! if the string is not big enough, then add another chunk:
9954
- if (ip> len (string)) string = string // repeat (space, chunk_size)
9963
+ if (ip> len (string)) string = string // blank_chunk
9955
9964
9956
9965
! append to string:
9957
9966
string (ip:ip) = c
@@ -10067,7 +10076,7 @@ subroutine parse_number(json, unit, str, value)
10067
10076
10068
10077
if (.not. json% exception_thrown) then
10069
10078
10070
- tmp = repeat (space, chunk_size)
10079
+ tmp = blank_chunk
10071
10080
ip = 1
10072
10081
first = .true.
10073
10082
is_integer = .true. ! assume it may be an integer, unless otherwise determined
@@ -10091,7 +10100,7 @@ subroutine parse_number(json, unit, str, value)
10091
10100
10092
10101
! add it to the string:
10093
10102
! tmp = tmp // c !...original
10094
- if (ip> len (tmp)) tmp = tmp // repeat (space, chunk_size)
10103
+ if (ip> len (tmp)) tmp = tmp // blank_chunk
10095
10104
tmp(ip:ip) = c
10096
10105
ip = ip + 1
10097
10106
@@ -10101,15 +10110,15 @@ subroutine parse_number(json, unit, str, value)
10101
10110
10102
10111
! add it to the string:
10103
10112
! tmp = tmp // c !...original
10104
- if (ip> len (tmp)) tmp = tmp // repeat (space, chunk_size)
10113
+ if (ip> len (tmp)) tmp = tmp // blank_chunk
10105
10114
tmp(ip:ip) = c
10106
10115
ip = ip + 1
10107
10116
10108
10117
case (CK_' 0' :CK_' 9' ) ! valid characters for numbers
10109
10118
10110
10119
! add it to the string:
10111
10120
! tmp = tmp // c !...original
10112
- if (ip> len (tmp)) tmp = tmp // repeat (space, chunk_size)
10121
+ if (ip> len (tmp)) tmp = tmp // blank_chunk
10113
10122
tmp(ip:ip) = c
10114
10123
ip = ip + 1
10115
10124
@@ -10177,10 +10186,6 @@ subroutine pop_char(json,unit,str,skip_ws,skip_comments,eof,popped)
10177
10186
logical (LK) :: parsing_comment ! ! if we are in the process
10178
10187
! ! of parsing a comment line
10179
10188
10180
- logical ,parameter :: chunk_it = .true. ! ! if true, stream files are read in chunks,
10181
- ! ! rather than one character at a time.
10182
- ! ! this speeds up the parsing dramatically.
10183
-
10184
10189
if (.not. json% exception_thrown) then
10185
10190
10186
10191
eof = .false.
@@ -10213,32 +10218,36 @@ subroutine pop_char(json,unit,str,skip_ws,skip_comments,eof,popped)
10213
10218
! read the next character:
10214
10219
if (use_unformatted_stream) then
10215
10220
10216
- if (chunk_it) then
10217
- ! in this case, we read the file in chunks.
10218
- ! if we already have the character we need ,
10219
- ! then get it from the chunk. Otherwise,
10220
- ! read another chunk
10221
-
10222
- if ( json% ichunk< 1 ) then
10223
- json% ichunk = 0
10224
- read (unit = unit,pos = json % ipos,iostat = ios) json % chunk
10225
- else
10226
- ios = 0
10221
+ ! in this case, we read the file in chunks.
10222
+ ! if we already have the character we need,
10223
+ ! then get it from the chunk. Otherwise ,
10224
+ ! read in another chunk.
10225
+ if (json % ichunk < 1 ) then
10226
+ ! read in a chunk:
10227
+ json% ichunk = 0
10228
+ if ( json% filesize < json % ipos + len (json % chunk) - 1 ) then
10229
+ ! for the last chunk, we resize
10230
+ ! it to the correct size:
10231
+ json % chunk = repeat ( ' ' , json % filesize - json % ipos +1 )
10227
10232
end if
10228
- json% ichunk = json% ichunk + 1
10233
+ read (unit= unit,pos= json% ipos,iostat= ios) json% chunk
10234
+ else
10235
+ ios = 0
10236
+ end if
10237
+ json% ichunk = json% ichunk + 1
10238
+ if (json% ichunk> len (json% chunk)) then
10239
+ ! check this just in case
10240
+ ios = IOSTAT_END
10241
+ else
10242
+ ! get the next character from the chunk:
10229
10243
c = json% chunk(json% ichunk:json% ichunk)
10230
10244
if (json% ichunk== len (json% chunk)) then
10231
- json% ichunk = 0 ! reset
10232
- else
10233
- ! we have to finish getting
10234
- ! characters from this chunk:
10235
- if (IS_IOSTAT_END(ios)) ios = 0
10245
+ json% ichunk = 0 ! reset for next chunk
10236
10246
end if
10237
- else
10238
- read (unit= unit,pos= json% ipos,iostat= ios) c
10239
10247
end if
10240
10248
10241
10249
else
10250
+ ! a formatted read:
10242
10251
read (unit= unit,fmt= ' (A1)' ,advance= ' NO' ,iostat= ios) c
10243
10252
end if
10244
10253
json% ipos = json% ipos + 1
@@ -10333,7 +10342,7 @@ subroutine push_char(json,c)
10333
10342
10334
10343
! in this case, c is ignored, and we just
10335
10344
! decrement the stream position counter:
10336
- json% ipos = json% ipos - 1
10345
+ json% ipos = json% ipos - 1
10337
10346
json% ichunk = json% ichunk - 1
10338
10347
10339
10348
else
0 commit comments