Class: JsonProjection::Parser
- Inherits:
-
Object
- Object
- JsonProjection::Parser
- Defined in:
- lib/json-projection/parser.rb
Overview
A streaming JSON parser that generates SAX-like events for state changes. Use the json gem for small documents. Use this for huge documents that won’t fit in memory.
Constant Summary collapse
- CONTROL =
/[\x00-\x1F]/
- WS =
/[ \n\t\r]/
- HEX =
/[0-9a-fA-F]/
- DIGIT =
/[0-9]/
- DIGIT_1_9 =
/[1-9]/
- DIGIT_END =
/\d$/
- TRUE_RE =
/[rue]/
- FALSE_RE =
/[alse]/
- NULL_RE =
/[ul]/
- TRUE_KEYWORD =
'true'
- FALSE_KEYWORD =
'false'
- NULL_KEYWORD =
'null'
- LEFT_BRACE =
'{'
- RIGHT_BRACE =
'}'
- LEFT_BRACKET =
'['
- RIGHT_BRACKET =
']'
- BACKSLASH =
'\\'
- SLASH =
'/'
- QUOTE =
'"'
- COMMA =
','
- COLON =
':'
- ZERO =
'0'
- MINUS =
'-'
- PLUS =
'+'
- POINT =
'.'
- EXPONENT =
/[eE]/
Instance Method Summary collapse
-
#initialize(stream, chunk_size = 4096) ⇒ Parser
constructor
Initialize a new parser with a stream.
-
#next_event ⇒ Object
Draw bytes from the stream until an event can be constructed.
Constructor Details
#initialize(stream, chunk_size = 4096) ⇒ Parser
Initialize a new parser with a stream. The stream cursor is advanced as events are drawn from the parser. The parser maintains a small data cache of bytes read from the stream.
- stream
-
IO IO stream to read data from.
- chunk_size
-
Integer Number of bytes to read from the stream at a time.
Returns nothing.
76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 |
# File 'lib/json-projection/parser.rb', line 76 def initialize(stream, chunk_size = 4096) @stream = stream @chunk_size = chunk_size @event_buffer = Fifo.new @character_buffer = Buffer.new @characters_cursor = -1 @characters = nil @stream_position = -1 @state = :start_document @stack = [] @value_buffer = "" @unicode = "" end |
Instance Method Details
#next_event ⇒ Object
Draw bytes from the stream until an event can be constructed. May raise IO errors.
Returns a JsonProject::StreamEvent subclass or raises StandardError.
99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 |
# File 'lib/json-projection/parser.rb', line 99 def next_event() # Are there any already read events, return the oldest event = @event_buffer.pop! return event unless event.nil? if @state == :end_document error("already EOF, no more events") end while true do if @characters.nil? || @characters_cursor == @characters.size data = stream.read(@chunk_size) if data == nil # hit EOF error("unexpected EOF") end @characters = @character_buffer.<<(data).each_char.to_a @characters_cursor = 0 end character = @characters[@characters_cursor] @characters_cursor += 1 @stream_position += 1 new_state, new_events = handle_character(@state, character) @state = new_state @event_buffer.prepend!(new_events) event = @event_buffer.pop! return event unless event.nil? end end |