def patch(src, patchset, direction = nil)
string = src.kind_of?(String)
res = src.class.new
patchset = __normalize_patchset(patchset)
direction ||= Diff::LCS.__diff_direction(src, patchset)
direction ||= :patch
ai = bj = 0
patchset.each do |change|
action = PATCH_MAP[direction][change.action]
case change
when Diff::LCS::ContextChange
case direction
when :patch
el = change.new_element
op = change.old_position
np = change.new_position
when :unpatch
el = change.old_element
op = change.new_position
np = change.old_position
end
case action
when '-'
while ai < op
res << (string ? src[ai, 1] : src[ai])
ai += 1
bj += 1
end
ai += 1
when '+'
while bj < np
res << (string ? src[ai, 1] : src[ai])
ai += 1
bj += 1
end
res << el
bj += 1
when '='
res << el
ai += 1
bj += 1
when '!'
while ai < op
res << (string ? src[ai, 1] : src[ai])
ai += 1
bj += 1
end
bj += 1
ai += 1
res << el
end
when Diff::LCS::Change
case action
when '-'
while ai < change.position
res << (string ? src[ai, 1] : src[ai])
ai += 1
bj += 1
end
ai += 1
when '+'
while bj < change.position
res << (string ? src[ai, 1] : src[ai])
ai += 1
bj += 1
end
bj += 1
res << change.element
end
end
end
while ai < src.size
res << (string ? src[ai, 1] : src[ai])
ai += 1
bj += 1
end
res
end