lib/json/streamer/json_streamer.rb in json-streamer-1.1.1 vs lib/json/streamer/json_streamer.rb in json-streamer-1.1.2
- old
+ new
@@ -11,102 +11,129 @@
@parser = JSON::Stream::Parser.new
@file_io = file_io
@chunk_size = chunk_size
- @current_nesting_level = -1
- @current_key = nil
+ @current_level = -1
@aggregator = {}
- @temp_aggregator_keys = {}
+ @aggregator_keys = {}
@parser.start_object {start_object}
@parser.start_array {start_array}
@parser.key {|k| key(k)}
end
# Callbacks containing `yield` have to be defined in the method called via block otherwise yield won't work
def get(nesting_level:-1, key:nil, yield_values:true)
- yield_nesting_level = nesting_level
- wanted_key = key
+ @yield_level = nesting_level
+ @yield_key = key
+ @yield_values = yield_values
@parser.value do |v|
- if @aggregator[@current_nesting_level].kind_of? Array
- if yield_values and yield_value?(yield_nesting_level)
- yield v
- else
- @aggregator[@current_nesting_level] << v
- end
- else
- @aggregator[@current_nesting_level][@current_key] = v
- if yield_values and yield_value?(yield_nesting_level, wanted_key)
- yield v
- end
- end
+ value(v) { |desired_object| yield desired_object }
end
@parser.end_object do
- if yield_object?(yield_nesting_level, wanted_key)
- yield @aggregator[@current_nesting_level].clone
- @aggregator[@current_nesting_level] = {}
- else
- merge_up
- end
-
- @current_nesting_level -= 1
+ end_level(Hash.new) { |desired_object| yield desired_object }
end
@parser.end_array do
- if yield_object?(yield_nesting_level, wanted_key)
- yield @aggregator[@current_nesting_level].clone
- @aggregator[@current_nesting_level] = []
- else
- merge_up
- end
+ end_level(Array.new) { |desired_object| yield desired_object }
+ end
- @current_nesting_level -= 1
+ @file_io.each(@chunk_size) { |chunk| @parser << chunk } if @file_io
+ end
+
+ def start_object
+ new_level(Hash.new)
+ end
+
+ def start_array
+ new_level(Array.new)
+ end
+
+ def key(k)
+ @current_key = k
+ end
+
+ def value(value)
+ reset_current_key if array_level?(@current_level)
+ yield value if yield_value?
+ add_value(value)
+ end
+
+ def add_value(value)
+ if array_level?(@current_level)
+ @aggregator[@current_level] << value
+ else
+ @aggregator[@current_level][@current_key] = value
end
+ end
- if @file_io
- @file_io.each(@chunk_size) do |chunk|
- @parser << chunk
- end
+ def end_level(type)
+ if yield_object?
+ yield @aggregator[@current_level].clone
+ reset_current_level(type)
+ else
+ merge_up
end
+
+ @current_level -= 1
end
- def yield_object?(yield_nesting_level, wanted_key)
- @current_nesting_level.eql? yield_nesting_level or (not wanted_key.nil? and wanted_key == @temp_aggregator_keys[@current_nesting_level-1])
+ def yield_object?
+ @current_level.eql?(@yield_level) or (not @yield_key.nil? and @yield_key == previous_key)
end
- def yield_value?(yield_nesting_level, wanted_key = nil)
- (@current_nesting_level + 1).eql? yield_nesting_level or (not wanted_key.nil? and wanted_key == @current_key)
+ def yield_value?
+ @yield_values and ((next_level).eql?(@yield_level) or (not @yield_key.nil? and @yield_key == @current_key))
end
- def start_object
- @temp_aggregator_keys[@current_nesting_level] = @current_key
- @current_nesting_level += 1
- @aggregator[@current_nesting_level] = {}
+ def new_level(type)
+ reset_current_key if array_level?(@current_level)
+ set_aggregator_key
+ @current_level += 1
+ reset_current_level(type)
end
- def start_array
- @current_nesting_level += 1
- @aggregator[@current_nesting_level] = []
+ def reset_current_level(type)
+ @aggregator[@current_level] = type
end
- def key(k)
- @current_key = k
+ def set_aggregator_key
+ @aggregator_keys[@current_level] = @current_key
end
+ def reset_current_key
+ @current_key = nil
+ end
+
+ def array_level?(nesting_level)
+ @aggregator[nesting_level].is_a?(Array)
+ end
+
def merge_up
- return if @current_nesting_level == 0
- previous_nesting_level = @current_nesting_level - 1
- if @aggregator[previous_nesting_level].kind_of? Array
- @aggregator[previous_nesting_level] << @aggregator[@current_nesting_level]
+ return if @current_level.zero?
+
+ if array_level?(previous_level)
+ @aggregator[previous_level] << @aggregator[@current_level]
else
- @aggregator[previous_nesting_level][@temp_aggregator_keys[previous_nesting_level]] = @aggregator[@current_nesting_level]
+ @aggregator[previous_level][previous_key] = @aggregator[@current_level]
end
- @aggregator.delete(@current_nesting_level)
- @aggregator
+ @aggregator.delete(@current_level)
+ end
+
+ def previous_level
+ @current_level - 1
+ end
+
+ def next_level
+ @current_level + 1
+ end
+
+ def previous_key
+ @aggregator_keys[previous_level]
end
end
end
end