697: def patch(src, patchset, direction = nil)
698: string = src.kind_of?(String)
699:
700: res = src.class.new
701:
702:
703: patchset = __normalize_patchset(patchset)
704:
705: direction ||= Diff::LCS.__diff_direction(src, patchset)
706: direction ||= :patch
707:
708: ai = bj = 0
709:
710: patchset.each do |change|
711:
712: action = PATCH_MAP[direction][change.action]
713:
714: case change
715: when Diff::LCS::ContextChange
716: case direction
717: when :patch
718: el = change.new_element
719: op = change.old_position
720: np = change.new_position
721: when :unpatch
722: el = change.old_element
723: op = change.new_position
724: np = change.old_position
725: end
726:
727: case action
728: when '-'
729: while ai < op
730: res << (string ? src[ai, 1] : src[ai])
731: ai += 1
732: bj += 1
733: end
734: ai += 1
735: when '+'
736: while bj < np
737: res << (string ? src[ai, 1] : src[ai])
738: ai += 1
739: bj += 1
740: end
741:
742: res << el
743: bj += 1
744: when '='
745:
746:
747:
748: res << el
749:
750: ai += 1
751: bj += 1
752: when '!'
753: while ai < op
754: res << (string ? src[ai, 1] : src[ai])
755: ai += 1
756: bj += 1
757: end
758:
759: bj += 1
760: ai += 1
761:
762: res << el
763: end
764: when Diff::LCS::Change
765: case action
766: when '-'
767: while ai < change.position
768: res << (string ? src[ai, 1] : src[ai])
769: ai += 1
770: bj += 1
771: end
772: ai += 1
773: when '+'
774: while bj < change.position
775: res << (string ? src[ai, 1] : src[ai])
776: ai += 1
777: bj += 1
778: end
779:
780: bj += 1
781:
782: res << change.element
783: end
784: end
785: end
786:
787: while ai < src.size
788: res << (string ? src[ai, 1] : src[ai])
789: ai += 1
790: bj += 1
791: end
792:
793: res
794: end