Class: Yajl::FFI::Parser
- Inherits:
-
Object
- Object
- Yajl::FFI::Parser
- Defined in:
- lib/yajl/ffi/parser.rb
Overview
Constant Summary collapse
- BUF_SIZE =
4096
- CONTINUE_PARSE =
1
- FLOAT =
/[\.eE]/
Class Method Summary collapse
-
.parse(json) ⇒ Object
Parses a full JSON document from a String or an IO stream and returns the parsed object graph.
Instance Method Summary collapse
-
#<<(data) ⇒ Object
Pass data into the parser to advance the state machine and generate callback events.
- #end_array(&block) ⇒ Object
- #end_document(&block) ⇒ Object
- #end_object(&block) ⇒ Object
-
#finish ⇒ Object
Drain any remaining buffered characters into the parser to complete the parsing of the document.
-
#initialize(&block) ⇒ Parser
constructor
Create a new parser with an optional initialization block where we can register event callbacks.
- #key(&block) ⇒ Object
- #start_array(&block) ⇒ Object
- #start_document(&block) ⇒ Object
- #start_object(&block) ⇒ Object
- #value(&block) ⇒ Object
Constructor Details
#initialize(&block) ⇒ Parser
Create a new parser with an optional initialization block where we can register event callbacks.
Examples
parser = Yajl::FFI::Parser.new do
start_document { puts "start document" }
end_document { puts "end document" }
start_object { puts "start object" }
end_object { puts "end object" }
start_array { puts "start array" }
end_array { puts "end array" }
key { |k| puts "key: #{k}" }
value { |v| puts "value: #{v}" }
end
62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 |
# File 'lib/yajl/ffi/parser.rb', line 62 def initialize(&block) @listeners = { start_document: [], end_document: [], start_object: [], end_object: [], start_array: [], end_array: [], key: [], value: [] } # Track parse stack. @depth = 0 @started = false # Allocate native memory. @callbacks = callbacks @handle = Yajl::FFI.alloc(@callbacks.to_ptr, nil, nil) @handle = ::FFI::AutoPointer.new(@handle, method(:release)) # Register any observers in the block. instance_eval(&block) if block_given? end |
Class Method Details
.parse(json) ⇒ Object
Parses a full JSON document from a String or an IO stream and returns the parsed object graph. For parsing small JSON documents with small memory requirements, use the json gem’s faster JSON.parse method instead.
json - The String or IO containing JSON data.
Examples
Yajl::FFI::Parser.parse('{"hello": "world"}')
# => {"hello": "world"}
Raises a Yajl::FFI::ParserError if the JSON data is malformed.
Returns a Hash.
34 35 36 37 38 39 40 41 42 43 44 45 |
# File 'lib/yajl/ffi/parser.rb', line 34 def self.parse(json) stream = json.is_a?(String) ? StringIO.new(json) : json parser = Parser.new builder = Builder.new(parser) while (buffer = stream.read(BUF_SIZE)) != nil parser << buffer end parser.finish builder.result ensure stream.close end |
Instance Method Details
#<<(data) ⇒ Object
Pass data into the parser to advance the state machine and generate callback events. This is well suited for an EventMachine receive_data loop.
data - The String of partial JSON data to parse.
Raises a Yajl::FFI::ParserError if the JSON data is malformed.
Returns nothing.
128 129 130 131 132 133 134 135 |
# File 'lib/yajl/ffi/parser.rb', line 128 def <<(data) result = Yajl::FFI.parse(@handle, data, data.bytesize) error(data) if result == :error if @started && @depth == 0 result = Yajl::FFI.complete_parse(@handle) error(data) if result == :error end end |
#end_array(&block) ⇒ Object
107 108 109 |
# File 'lib/yajl/ffi/parser.rb', line 107 def end_array(&block) @listeners[:end_array] << block end |
#end_document(&block) ⇒ Object
91 92 93 |
# File 'lib/yajl/ffi/parser.rb', line 91 def end_document(&block) @listeners[:end_document] << block end |
#end_object(&block) ⇒ Object
99 100 101 |
# File 'lib/yajl/ffi/parser.rb', line 99 def end_object(&block) @listeners[:end_object] << block end |
#finish ⇒ Object
Drain any remaining buffered characters into the parser to complete the parsing of the document.
This is only required when parsing a document containing a single numeric value, integer or float. The parser has no other way to detect when it should no longer expect additional characters with which to complete the parse, so it must be signaled by a call to this method.
If you’re parsing more typical object or array documents, there’s no need to call ‘finish` because the parse will complete when the final closing `]` or `}` character is scanned.
Raises a Yajl::FFI::ParserError if the JSON data is malformed.
Returns nothing.
153 154 155 156 |
# File 'lib/yajl/ffi/parser.rb', line 153 def finish result = Yajl::FFI.complete_parse(@handle) error('') if result == :error end |
#key(&block) ⇒ Object
111 112 113 |
# File 'lib/yajl/ffi/parser.rb', line 111 def key(&block) @listeners[:key] << block end |
#start_array(&block) ⇒ Object
103 104 105 |
# File 'lib/yajl/ffi/parser.rb', line 103 def start_array(&block) @listeners[:start_array] << block end |
#start_document(&block) ⇒ Object
87 88 89 |
# File 'lib/yajl/ffi/parser.rb', line 87 def start_document(&block) @listeners[:start_document] << block end |
#start_object(&block) ⇒ Object
95 96 97 |
# File 'lib/yajl/ffi/parser.rb', line 95 def start_object(&block) @listeners[:start_object] << block end |
#value(&block) ⇒ Object
115 116 117 |
# File 'lib/yajl/ffi/parser.rb', line 115 def value(&block) @listeners[:value] << block end |