1
2
3
4
5
6
7
8
9
10
11
12 package org.eclipse.jgit.diff;
13
14 import static org.eclipse.jgit.util.RawCharUtil.isWhitespace;
15 import static org.eclipse.jgit.util.RawCharUtil.trimLeadingWhitespace;
16 import static org.eclipse.jgit.util.RawCharUtil.trimTrailingWhitespace;
17
18 import org.eclipse.jgit.util.IntList;
19
20
21
22
23 public abstract class RawTextComparator extends SequenceComparator<RawText> {
24
25 public static final RawTextComparatorhtml#RawTextComparator">RawTextComparator DEFAULT = new RawTextComparator() {
26 @Override
27 public boolean equals(RawTextxt.html#RawText">RawText a, int ai, RawText b, int bi) {
28 ai++;
29 bi++;
30
31 int as = a.lines.get(ai);
32 int bs = b.lines.get(bi);
33 final int ae = a.lines.get(ai + 1);
34 final int be = b.lines.get(bi + 1);
35
36 if (ae - as != be - bs)
37 return false;
38
39 while (as < ae) {
40 if (a.content[as++] != b.content[bs++])
41 return false;
42 }
43 return true;
44 }
45
46 @Override
47 protected int hashRegion(byte[] raw, int ptr, int end) {
48 int hash = 5381;
49 for (; ptr < end; ptr++)
50 hash = ((hash << 5) + hash) + (raw[ptr] & 0xff);
51 return hash;
52 }
53 };
54
55
56 public static final RawTextComparatorawTextComparator">RawTextComparator WS_IGNORE_ALL = new RawTextComparator() {
57 @Override
58 public boolean equals(RawTextxt.html#RawText">RawText a, int ai, RawText b, int bi) {
59 ai++;
60 bi++;
61
62 int as = a.lines.get(ai);
63 int bs = b.lines.get(bi);
64 int ae = a.lines.get(ai + 1);
65 int be = b.lines.get(bi + 1);
66
67 ae = trimTrailingWhitespace(a.content, as, ae);
68 be = trimTrailingWhitespace(b.content, bs, be);
69
70 while (as < ae && bs < be) {
71 byte ac = a.content[as];
72 byte bc = b.content[bs];
73
74 while (as < ae - 1 && isWhitespace(ac)) {
75 as++;
76 ac = a.content[as];
77 }
78
79 while (bs < be - 1 && isWhitespace(bc)) {
80 bs++;
81 bc = b.content[bs];
82 }
83
84 if (ac != bc)
85 return false;
86
87 as++;
88 bs++;
89 }
90
91 return as == ae && bs == be;
92 }
93
94 @Override
95 protected int hashRegion(byte[] raw, int ptr, int end) {
96 int hash = 5381;
97 for (; ptr < end; ptr++) {
98 byte c = raw[ptr];
99 if (!isWhitespace(c))
100 hash = ((hash << 5) + hash) + (c & 0xff);
101 }
102 return hash;
103 }
104 };
105
106
107
108
109 public static final RawTextComparatorxtComparator">RawTextComparator WS_IGNORE_LEADING = new RawTextComparator() {
110 @Override
111 public boolean equals(RawTextxt.html#RawText">RawText a, int ai, RawText b, int bi) {
112 ai++;
113 bi++;
114
115 int as = a.lines.get(ai);
116 int bs = b.lines.get(bi);
117 int ae = a.lines.get(ai + 1);
118 int be = b.lines.get(bi + 1);
119
120 as = trimLeadingWhitespace(a.content, as, ae);
121 bs = trimLeadingWhitespace(b.content, bs, be);
122
123 if (ae - as != be - bs)
124 return false;
125
126 while (as < ae) {
127 if (a.content[as++] != b.content[bs++])
128 return false;
129 }
130 return true;
131 }
132
133 @Override
134 protected int hashRegion(byte[] raw, int ptr, int end) {
135 int hash = 5381;
136 ptr = trimLeadingWhitespace(raw, ptr, end);
137 for (; ptr < end; ptr++)
138 hash = ((hash << 5) + hash) + (raw[ptr] & 0xff);
139 return hash;
140 }
141 };
142
143
144 public static final RawTextComparatortComparator">RawTextComparator WS_IGNORE_TRAILING = new RawTextComparator() {
145 @Override
146 public boolean equals(RawTextxt.html#RawText">RawText a, int ai, RawText b, int bi) {
147 ai++;
148 bi++;
149
150 int as = a.lines.get(ai);
151 int bs = b.lines.get(bi);
152 int ae = a.lines.get(ai + 1);
153 int be = b.lines.get(bi + 1);
154
155 ae = trimTrailingWhitespace(a.content, as, ae);
156 be = trimTrailingWhitespace(b.content, bs, be);
157
158 if (ae - as != be - bs)
159 return false;
160
161 while (as < ae) {
162 if (a.content[as++] != b.content[bs++])
163 return false;
164 }
165 return true;
166 }
167
168 @Override
169 protected int hashRegion(byte[] raw, int ptr, int end) {
170 int hash = 5381;
171 end = trimTrailingWhitespace(raw, ptr, end);
172 for (; ptr < end; ptr++)
173 hash = ((hash << 5) + hash) + (raw[ptr] & 0xff);
174 return hash;
175 }
176 };
177
178
179 public static final RawTextComparatorextComparator">RawTextComparator WS_IGNORE_CHANGE = new RawTextComparator() {
180 @Override
181 public boolean equals(RawTextxt.html#RawText">RawText a, int ai, RawText b, int bi) {
182 ai++;
183 bi++;
184
185 int as = a.lines.get(ai);
186 int bs = b.lines.get(bi);
187 int ae = a.lines.get(ai + 1);
188 int be = b.lines.get(bi + 1);
189
190 ae = trimTrailingWhitespace(a.content, as, ae);
191 be = trimTrailingWhitespace(b.content, bs, be);
192
193 while (as < ae && bs < be) {
194 byte ac = a.content[as];
195 byte bc = b.content[bs];
196
197 if (ac != bc)
198 return false;
199
200 if (isWhitespace(ac))
201 as = trimLeadingWhitespace(a.content, as, ae);
202 else
203 as++;
204
205 if (isWhitespace(bc))
206 bs = trimLeadingWhitespace(b.content, bs, be);
207 else
208 bs++;
209 }
210 return as == ae && bs == be;
211 }
212
213 @Override
214 protected int hashRegion(byte[] raw, int ptr, int end) {
215 int hash = 5381;
216 end = trimTrailingWhitespace(raw, ptr, end);
217 while (ptr < end) {
218 byte c = raw[ptr];
219 hash = ((hash << 5) + hash) + (c & 0xff);
220 if (isWhitespace(c))
221 ptr = trimLeadingWhitespace(raw, ptr, end);
222 else
223 ptr++;
224 }
225 return hash;
226 }
227 };
228
229 @Override
230 public int hash(RawText seq, int lno) {
231 final int begin = seq.lines.get(lno + 1);
232 final int end = seq.lines.get(lno + 2);
233 return hashRegion(seq.content, begin, end);
234 }
235
236
237 @Override
238 public Editff/Edit.html#Edit">Edit reduceCommonStartEnd(RawTexthref="../../../../org/eclipse/jgit/diff/RawText.html#RawText">RawText a, RawText b, Edit e) {
239
240
241
242
243
244
245 if (e.beginA == e.endA || e.beginB == e.endB)
246 return e;
247
248 byte[] aRaw = a.content;
249 byte[] bRaw = b.content;
250
251 int aPtr = a.lines.get(e.beginA + 1);
252 int bPtr = a.lines.get(e.beginB + 1);
253
254 int aEnd = a.lines.get(e.endA + 1);
255 int bEnd = b.lines.get(e.endB + 1);
256
257
258
259
260
261 if (aPtr < 0 || bPtr < 0 || aEnd > aRaw.length || bEnd > bRaw.length)
262 throw new ArrayIndexOutOfBoundsException();
263
264 while (aPtr < aEnd && bPtr < bEnd && aRaw[aPtr] == bRaw[bPtr]) {
265 aPtr++;
266 bPtr++;
267 }
268
269 while (aPtr < aEnd && bPtr < bEnd && aRaw[aEnd - 1] == bRaw[bEnd - 1]) {
270 aEnd--;
271 bEnd--;
272 }
273
274 e.beginA = findForwardLine(a.lines, e.beginA, aPtr);
275 e.beginB = findForwardLine(b.lines, e.beginB, bPtr);
276
277 e.endA = findReverseLine(a.lines, e.endA, aEnd);
278
279 final boolean partialA = aEnd < a.lines.get(e.endA + 1);
280 if (partialA)
281 bEnd += a.lines.get(e.endA + 1) - aEnd;
282
283 e.endB = findReverseLine(b.lines, e.endB, bEnd);
284
285 if (!partialA && bEnd < b.lines.get(e.endB + 1))
286 e.endA++;
287
288 return super.reduceCommonStartEnd(a, b, e);
289 }
290
291 private static int findForwardLine(IntList lines, int idx, int ptr) {
292 final int end = lines.size() - 2;
293 while (idx < end && lines.get(idx + 2) < ptr)
294 idx++;
295 return idx;
296 }
297
298 private static int findReverseLine(IntList lines, int idx, int ptr) {
299 while (0 < idx && ptr <= lines.get(idx))
300 idx--;
301 return idx;
302 }
303
304
305
306
307
308
309
310
311
312
313
314
315 protected abstract int hashRegion(byte[] raw, int ptr, int end);
316 }