2 // Microsoft.TeamFoundation.VersionControl.Client.DifferenceUtil
5 // Joel Reed (joelwreed@gmail.com)
7 // Copyright (C) 2007 Joel Reed
9 // Permission is hereby granted, free of charge, to any person obtaining
10 // a copy of this software and associated documentation files (the
11 // "Software"), to deal in the Software without restriction, including
12 // without limitation the rights to use, copy, modify, merge, publish,
13 // distribute, sublicense, and/or sell copies of the Software, and to
14 // permit persons to whom the Software is furnished to do so, subject to
15 // the following conditions:
17 // The above copyright notice and this permission notice shall be
18 // included in all copies or substantial portions of the Software.
20 // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
21 // EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
22 // MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
23 // NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
24 // LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
25 // OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
26 // WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
30 using System
.Collections
;
31 using System
.Collections
.Generic
;
35 using Microsoft
.TeamFoundation
.VersionControl
.Common
;
37 namespace Microsoft
.TeamFoundation
.VersionControl
.Client
39 internal class DiffItemUtil
41 public string[] Lines
= new string[0];
52 public DiffItemUtil(char prefix
, string name
, IDiffItem file
)
54 string fileContents
= file
.GetFile();
55 Length
= fileContents
.Length
;
57 string path
= PrefixedHeaderPath(prefix
, name
);
60 this.name
= "/dev/null";
64 // gnu patch doesn't want to see backslashes in filenames
65 this.name
= path
.Replace('\\', '/');
67 // don't bother trying to parse lines for binary files
68 if (file
.GetEncoding() == RepositoryConstants
.EncodingBinary
) return;
70 // if file ends with /n the split below generates one extra row we dont want
71 int len
= fileContents
.Length
;
72 if (fileContents
.EndsWith("\n")) len
-= 1;
74 string x
= fileContents
.Substring(0, len
);
75 Lines
= x
.Split('\n');
78 private string PrefixedHeaderPath(char c
, string path
)
80 StringBuilder sb
= new StringBuilder();
83 if (path
[0] != Path
.DirectorySeparatorChar
) sb
.Append(Path
.DirectorySeparatorChar
);
89 static public bool IsBinary(string s
)
91 int size
= Math
.Min(8000, s
.Length
);
92 for (int i
=0; i
<size
; i
++)
104 static readonly int CONTEXT
= 3;
106 private DiffItem item
;
107 private int ctx1Start
= 0;
108 private int ctx2Start
= 0;
109 private int ctx1End
= 0;
110 private int ctx2End
= 0;
111 public int ctxLineCnt
;
113 public DiffItem Item { get { return item; }
}
115 public Hunk(DiffItem item
, int prevDist
, int nextDist
,
120 ctx1Start
= Math
.Max(item
.StartA
- prevDist
, 0);
121 int proposedEnd
= Math
.Min(item
.StartA
, ctx1Start
+ prevDist
);
122 ctx1End
= Math
.Min(proposedEnd
, maxA
);
124 if (nextDist
>= CONTEXT
)
126 ctx2End
= Math
.Min(item
.StartB
+ item
.insertedB
+ nextDist
, maxB
);
127 int proposedStart
= Math
.Max(item
.StartB
+ item
.insertedB
, ctx2End
- nextDist
);
128 //Console.WriteLine("proposedStart {0}, nextDist {1}", proposedStart, nextDist);
129 ctx2Start
= Math
.Min(proposedStart
, ctx2End
);
132 ctxLineCnt
= (ctx1End
- ctx1Start
) + (ctx2End
- ctx2Start
);
133 //Console.WriteLine(String.Format("ctx1Start={0} ctx1End={1} ctx2Start={2} ctx2End={3} ctxLineCnt={4}\nmaxB={5} prevDist={6} nextDist={7}",
134 // ctx1Start, ctx1End, ctx2Start, ctx2End, ctxLineCnt, maxB, prevDist, nextDist));
137 public int LinesA { get { return ctxLineCnt + item.deletedA; }
}
138 public int LinesB { get { return ctxLineCnt + item.insertedB; }
}
140 public string ToString(string[] a
, string[] b
)
142 StringBuilder sb
= new StringBuilder();
143 for (int i
= ctx1Start
; i
< ctx1End
; i
++)
144 sb
.Append(" " + a
[i
] + "\n");
146 for (int i
= item
.StartA
; i
< item
.StartA
+ item
.deletedA
; i
++)
147 sb
.Append("-" + a
[i
] + "\n");
149 for (int i
= item
.StartB
; i
< item
.StartB
+ item
.insertedB
; i
++)
150 sb
.Append("+" + b
[i
] + "\n");
152 for (int i
= ctx2Start
; i
< ctx2End
; i
++)
153 sb
.Append(" " + b
[i
] + "\n");
155 return sb
.ToString();