def traverse_balanced(seq1, seq2, callbacks = Diff::LCS::BalancedCallbacks)
matches = Diff::LCS.__lcs(seq1, seq2)
a_size = seq1.size
b_size = seq2.size
ai = bj = mb = 0
ma = -1
string = seq1.kind_of?(String)
loop do
loop do
ma += 1
break unless ma < matches.size and matches[ma].nil?
end
break if ma >= matches.size
mb = matches[ma]
while (ai < ma) or (bj < mb)
ax = string ? seq1[ai, 1] : seq1[ai]
bx = string ? seq2[bj, 1] : seq2[bj]
case [(ai < ma), (bj < mb)]
when [true, true]
if callbacks.respond_to?(:change)
event = Diff::LCS::ContextChange.new('!', ai, ax, bj, bx)
event = yield event if block_given?
callbacks.change(event)
ai += 1
bj += 1
else
event = Diff::LCS::ContextChange.new('-', ai, ax, bj, bx)
event = yield event if block_given?
callbacks.discard_a(event)
ai += 1
ax = string ? seq1[ai, 1] : seq1[ai]
event = Diff::LCS::ContextChange.new('+', ai, ax, bj, bx)
event = yield event if block_given?
callbacks.discard_b(event)
bj += 1
end
when [true, false]
event = Diff::LCS::ContextChange.new('-', ai, ax, bj, bx)
event = yield event if block_given?
callbacks.discard_a(event)
ai += 1
when [false, true]
event = Diff::LCS::ContextChange.new('+', ai, ax, bj, bx)
event = yield event if block_given?
callbacks.discard_b(event)
bj += 1
end
end
ax = string ? seq1[ai, 1] : seq1[ai]
bx = string ? seq2[bj, 1] : seq2[bj]
event = Diff::LCS::ContextChange.new('=', ai, ax, bj, bx)
event = yield event if block_given?
callbacks.match(event)
ai += 1
bj += 1
end
while (ai < a_size) or (bj < b_size)
ax = string ? seq1[ai, 1] : seq1[ai]
bx = string ? seq2[bj, 1] : seq2[bj]
case [(ai < a_size), (bj < b_size)]
when [true, true]
if callbacks.respond_to?(:change)
event = Diff::LCS::ContextChange.new('!', ai, ax, bj, bx)
event = yield event if block_given?
callbacks.change(event)
ai += 1
bj += 1
else
event = Diff::LCS::ContextChange.new('-', ai, ax, bj, bx)
event = yield event if block_given?
callbacks.discard_a(event)
ai += 1
ax = string ? seq1[ai, 1] : seq1[ai]
event = Diff::LCS::ContextChange.new('+', ai, ax, bj, bx)
event = yield event if block_given?
callbacks.discard_b(event)
bj += 1
end
when [true, false]
event = Diff::LCS::ContextChange.new('-', ai, ax, bj, bx)
event = yield event if block_given?
callbacks.discard_a(event)
ai += 1
when [false, true]
event = Diff::LCS::ContextChange.new('+', ai, ax, bj, bx)
event = yield event if block_given?
callbacks.discard_b(event)
bj += 1
end
end
end