~ubuntu-branches/ubuntu/oneiric/monodevelop/oneiric

« back to all changes in this revision

Viewing changes to src/addins/VersionControl/Diff/TextDiff.cs

  • Committer: Bazaar Package Importer
  • Author(s): Jo Shields
  • Date: 2010-07-05 13:00:05 UTC
  • mfrom: (1.2.8 upstream) (1.3.9 experimental)
  • Revision ID: james.westby@ubuntu.com-20100705130005-d6hp4k5gcn1xkj8c
Tags: 2.4+dfsg-1ubuntu1
* debian/patches/remove_support_for_moonlight.patch,
  debian/patches/dont_add_moonlight_to_core_addins.patch,
  debian/control:
  + Enable support for Moonlight
* debian/rules:
  + Ensure Moonlight addin isn't shipped in main MonoDevelop package by
    mistake

Show diffs side-by-side

added added

removed removed

Lines of Context:
1
 
using System;
2
 
using System.Collections;
3
 
 
4
 
namespace Algorithm.Diff {
5
 
        
6
 
        public class TextDiff : IDiff {
7
 
                Node left, right;
8
 
                ArrayList hunks = new ArrayList();
9
 
                
10
 
                public TextDiff(string left, string right) : this (left, right, null) {
11
 
                }
12
 
                
13
 
                public TextDiff(string left, string right, IComparer comparer) {
14
 
                        this.left = new Node(left, 0, left.Length, 0);
15
 
                        this.right = new Node(right, 0, right.Length, 0);
16
 
                        
17
 
 
18
 
                        TextDiffStructuredDiff diff = new TextDiffStructuredDiff(hunks, left.ToCharArray(), right.ToCharArray());
19
 
                        diff.AddInterface(typeof(Node), new TextDiffNodeInterface(comparer));
20
 
                        diff.Compare(this.left, this.right);
21
 
                }
22
 
                
23
 
                public IList Left { get { return left.ToString().ToCharArray(); } }
24
 
                public  IList Right { get { return right.ToString().ToCharArray(); } }
25
 
                
26
 
                IEnumerator IEnumerable.GetEnumerator() {
27
 
                        return hunks.GetEnumerator();
28
 
                }
29
 
 
30
 
                private class TextDiffStructuredDiff : StructuredDiff {
31
 
                        ArrayList hunks;
32
 
                        IList leftlist, rightlist;
33
 
                        
34
 
                        public TextDiffStructuredDiff(ArrayList hunks, IList leftlist, IList rightlist) {
35
 
                                this.hunks = hunks;
36
 
                                this.leftlist = leftlist;
37
 
                                this.rightlist = rightlist;
38
 
                        }
39
 
                        
40
 
                        protected override void WritePushNode(NodeInterface nodeInterface, object left, object right) {
41
 
                        }
42
 
        
43
 
                        protected override void WritePushSame() {
44
 
                        }
45
 
                        
46
 
                        private void AddHunk(int lcount, int rcount, bool same) {
47
 
                                if (hunks.Count > 0 && same == ((Diff.Hunk)hunks[hunks.Count-1]).Same) {
48
 
                                        Diff.Hunk prev = (Diff.Hunk)hunks[hunks.Count-1];
49
 
                                        hunks[hunks.Count-1] = new Diff.Hunk(
50
 
                                                leftlist,
51
 
                                                rightlist,
52
 
                                                prev.Left.Start,
53
 
                                                prev.Left.End + lcount,
54
 
                                                prev.Right.Start,
55
 
                                                prev.Right.End + rcount,
56
 
                                                same);
57
 
                                        return;
58
 
                                }
59
 
                                
60
 
                                int le = -1;
61
 
                                int re = -1;
62
 
                                if (hunks.Count > 0) {
63
 
                                        Diff.Hunk prev = (Diff.Hunk)hunks[hunks.Count-1];
64
 
                                        le = prev.Left.End;
65
 
                                        re = prev.Right.End;
66
 
                                }
67
 
                                
68
 
                                hunks.Add( new Diff.Hunk(
69
 
                                                leftlist,
70
 
                                                rightlist,
71
 
                                                le + 1,
72
 
                                                le + lcount,
73
 
                                                re + 1,
74
 
                                                re + rcount,
75
 
                                                same) );
76
 
                        }
77
 
                
78
 
                        protected override void WriteNodeSame(NodeInterface nodeInterface, object left, object right) {
79
 
                                AddHunk(((Node)left).count, ((Node)right).count, true);
80
 
                        }
81
 
 
82
 
                        protected override void WritePopSame() {
83
 
                        }
84
 
        
85
 
                        protected override void WriteNodeChange(NodeInterface leftInterface, object left, NodeInterface rightInterface, object right) {
86
 
                                AddHunk(((Node)left).count, ((Node)right).count, false);
87
 
                        }
88
 
        
89
 
                        protected override void WriteNodesRemoved(IList objects) {
90
 
                                int start = ((Node)objects[0]).start;
91
 
                                int end = ((Node)objects[objects.Count-1]).start + ((Node)objects[objects.Count-1]).count - 1;
92
 
                                
93
 
                                AddHunk(end - start + 1, 0, false);
94
 
                        }
95
 
        
96
 
                        protected override void WriteNodesAdded(IList objects) {
97
 
                                int start = ((Node)objects[0]).start;
98
 
                                int end = ((Node)objects[objects.Count-1]).start + ((Node)objects[objects.Count-1]).count - 1;
99
 
                                
100
 
                                AddHunk(0, end - start + 1, false);
101
 
                        }
102
 
        
103
 
                        protected override void WritePopNode() {
104
 
                        }
105
 
                }
106
 
                
107
 
                private class TextDiffNodeInterface : NodeInterface {
108
 
                        IComparer comparer;
109
 
                        
110
 
                        public TextDiffNodeInterface(IComparer comparer) { this.comparer = comparer; }
111
 
                        
112
 
                        public override IList GetChildren(object node) {
113
 
                                if (((Node)node).children.Count == 0) return null;
114
 
                                return ((Node)node).children;
115
 
                        }
116
 
                        
117
 
                        private bool Equal(string a, string b) {
118
 
                                if (comparer == null)
119
 
                                        return a == b;
120
 
                                return comparer.Compare(a, b) == 0;
121
 
                        }
122
 
                        
123
 
                        public override float Compare(object left, object right, StructuredDiff comparer) {
124
 
                                string l = left.ToString(), r = right.ToString();
125
 
                                if (Equal(l, r)) return 0;
126
 
                                if (l.Length == 1 || r.Length == 1) return 1;
127
 
                                float d = comparer.CompareLists(GetChildren(left), GetChildren(right));
128
 
                                if (((Node)left).level == 2 && d >= .75) d = 1.1f;
129
 
                                return d;
130
 
                        }
131
 
                        
132
 
                        public override int GetHashCode(object node) {
133
 
                                return node.ToString().GetHashCode();
134
 
                        }
135
 
                }       
136
 
                
137
 
                private class Node {
138
 
                        public string source;
139
 
                        public int start, count;
140
 
                        
141
 
                        public int level;
142
 
                        public ArrayList children = new ArrayList();
143
 
                        
144
 
                        static char[][] delims = new char[][] {
145
 
                                new char[] { '\n', '\r' },
146
 
                                new char[] { ' ', '\t', '.', ',' }
147
 
                                };
148
 
                        
149
 
                        public Node(string source, int start, int count, int level) {
150
 
                                this.source = source;
151
 
                                this.start = start;
152
 
                                this.count = count;
153
 
                                this.level = level;
154
 
                                
155
 
                                if (level <= 1) {
156
 
                                        int pos = start;
157
 
                                        foreach (string child in ToString().Split(delims[level])) {
158
 
                                                if (child.Length >= 1)
159
 
                                                        children.Add(new Node(source, pos, child.Length, level+1));
160
 
                                                if (pos + child.Length < count)
161
 
                                                        children.Add(new Node(source, pos+child.Length, 1, level+1));
162
 
                                                pos += child.Length + 1;
163
 
                                        }
164
 
                                } else if (level == 2) {
165
 
                                        for (int i = start; i < start + count; i++)
166
 
                                                children.Add(new Node(source, i, 1, level+1));
167
 
                                }
168
 
                                
169
 
                        }
170
 
                        
171
 
                        public override string ToString() {
172
 
                                return source.Substring(start, count);
173
 
                        }
174
 
                }
175
 
        }
176
 
        
177
 
}