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