@@ -18,35 +18,31 @@ def parse(chunk, &block)
1818 # Takes a String buffer to parse and returns String containing any
1919 # text remaining to parse when more data is available.
2020 def do_parse ( buffer )
21- records = buffer . split ( RS , -1 ) # -1 stops suppression of trailing null fields
22-
23- records . each_with_index do |record , i |
24- # RFC7464 2.1 Multiple consecutive RS octets do not denote empty
25- # sequence elements between them and can be ignored.
26- next if record == ''
27-
28- is_last_record = i == records . size - 1
29-
30- # Try to decode the record
31- begin
32- value = MultiJson . load ( record )
33- if truncated? ( record , value )
34- return record if is_last_record
35-
36- yield JsonSequence ::Result ::MaybeTruncated . new ( value )
37- else
38- yield JsonSequence ::Result ::Json . new ( value )
39- end
40- rescue MultiJson ::ParseError => err
41- return record if is_last_record
42-
43- yield JsonSequence ::Result ::ParseError . new ( record , err )
44- end
45- end
21+ # RFC7464 2.1 Multiple consecutive RS octets do not denote empty
22+ # sequence elements between them and can be ignored.
23+ records = buffer . split ( RS ) . reject ( &:empty? )
24+
25+ # Every record except the last is guaranteed to be completed
26+ records [ 0 ...-1 ] . each { |record | yield decode_record ( record ) }
27+
28+ last_result = decode_record ( records . last )
29+
30+ # If we have an incomplete record and run out of valid json early, return it to the buffer
31+ return records . last if !buffer . end_with? ( RS ) && partial_result? ( last_result )
32+ yield last_result
4633
4734 ''
4835 end
4936
37+ def decode_record ( record )
38+ value = MultiJson . load ( record )
39+ return JsonSequence ::Result ::MaybeTruncated . new ( value ) if truncated? ( record , value )
40+
41+ JsonSequence ::Result ::Json . new ( value )
42+ rescue MultiJson ::ParseError => e
43+ JsonSequence ::Result ::ParseError . new ( record , e )
44+ end
45+
5046 def truncated? ( record , value )
5147 case value
5248 when Numeric , TrueClass , FalseClass , NilClass
@@ -57,5 +53,9 @@ def truncated?(record, value)
5753 false
5854 end
5955 end
56+
57+ def partial_result? ( result )
58+ !result . is_a? ( JsonSequence ::Result ::Json )
59+ end
6060 end
6161end
0 commit comments