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
- BUF_SIZE =
4096
- 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) ⇒ 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) ⇒ 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.
Returns nothing.
74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 |
# File 'lib/json-projection/parser.rb', line 74 def initialize(stream) @stream = stream @event_buffer = Fifo.new @bytes_buffer = Buffer.new @bytes = nil @pos = -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.
94 95 96 97 98 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 |
# File 'lib/json-projection/parser.rb', line 94 def next_event() # Are there any already read events, return the oldest @event_buffer, event = @event_buffer.pop return event unless event.nil? if @state == :end_document error("already EOF, no more events") end while true do if @bytes.nil? || @bytes.empty? data = stream.read(BUF_SIZE) if data == nil # hit EOF error("unexpected EOF") end @bytes = @bytes_buffer.<<(data).each_char.to_a end head = @bytes.first tail = @bytes.slice!(1, @bytes.size - 1) @bytes = tail @pos += 1 new_state, events = handle_character(@state, head) @state = new_state @event_buffer = events.append(@event_buffer) unless @event_buffer.empty? @event_buffer, event = @event_buffer.pop return event end end end |