00001 namespace JLibDiff
00002 {
00003 using System;
00004 using System.Collections.Specialized;
00005
00006
00082 public class diff : define, HunkVisitable
00083 {
00084
00085 internal System.Collections.ArrayList v = new System.Collections.ArrayList();
00086
00087
00088
00089
00090 public diff()
00091 {
00092 }
00093
00094
00095
00096
00097
00098
00099
00100
00101 public diff(System.String s1, System.String s2)
00102 {
00103 diffFile(s1, s2);
00104 }
00105
00106
00107
00108
00109 public virtual System.Collections.ArrayList getHunk()
00110 {
00111 return v;
00112 }
00113
00114
00115
00116
00117 public virtual int numberOfHunk()
00118 {
00119 return v.Count;
00120 }
00121
00122
00123
00124
00125
00126
00127 public virtual Hunk hunkAt(int i)
00128 {
00129 return (Hunk) v[i];
00130 }
00131
00132
00133
00134
00135
00136
00137 public virtual void accept(HunkVisitor visitor)
00138 {
00139 for (System.Collections.IEnumerator e = v.GetEnumerator(); e.MoveNext(); )
00140 {
00141 Hunk h = (Hunk) e.Current;
00142 h.accept(visitor);
00143 }
00144 }
00145
00146
00147
00148
00149
00150
00151
00152 public virtual void diffFile(System.String s1, System.String s2)
00153 {
00154
00155 System.IO.StreamReader in_Renamed = new System.IO.StreamReader(new System.IO.StreamReader(s1).BaseStream);
00156 System.IO.StreamReader inn = new System.IO.StreamReader(new System.IO.StreamReader(s2).BaseStream);
00157 diffBuffer(in_Renamed, inn);
00158 in_Renamed.Close();
00159 inn.Close();
00160 }
00161
00162
00163
00164
00165
00166
00167
00168 public virtual void diffBuffer(System.IO.StreamReader in_Renamed, System.IO.StreamReader inn)
00169 {
00170
00171 System.String s;
00172 StringCollection listA = new StringCollection();
00173 StringCollection listB = new StringCollection();
00174
00175 while ((s = in_Renamed.ReadLine()) != null)
00176 {
00177 listA.Add(s);
00178 }
00179 while ((s = inn.ReadLine()) != null)
00180 {
00181 listB.Add(s);
00182 }
00183
00184 System.String[] A = new string[listA.Count];
00185 listA.CopyTo(A, 0);
00186 System.String[] B = new string[listB.Count];
00187 listB.CopyTo(B, 0);
00188
00189 int m = (int) (A.Length);
00190 int n = (int) (B.Length);
00191 int maxlines = ((m > n)?m:n);
00192 int origin = maxlines;
00193 int max_d = 2 * maxlines;
00194 int d = 1;
00195 int k, lower, upper, row, col;
00196
00197 int[] last_d = new int[2 * maxlines + 1];
00198
00199 edit[] script = new edit[2 * maxlines + 1];
00200
00201
00202 for (row = 0; row < m && row < n && A[row].Equals(B[row]); row++)
00203 ;
00204 last_d[origin] = row;
00205 script[origin] = null;
00206 if (row == m)
00207 lower = origin + 1;
00208 else
00209 lower = origin - 1;
00210 if (row == n)
00211 upper = origin - 1;
00212 else
00213 upper = origin + 1;
00214 if (lower > upper)
00215 return ;
00216 else
00217 {
00218
00219 for (d = 1; d <= max_d; d++)
00220 {
00221
00222 for (k = lower; k <= upper; k += 2)
00223 {
00224 edit e = new edit();
00225 if (e == null)
00226 {
00227 System.Console.Out.WriteLine(";;;;exceed" + d);
00228 System.Environment.Exit(0);
00229 }
00230 if (k == origin - d || k != origin + d && last_d[k + 1] >= last_d[k - 1])
00231 {
00232 row = last_d[k + 1] + 1;
00233 e.setnext(script[k + 1]);
00234 e.setop(JLibDiff.define_Fields.DELETE);
00235 }
00236 else
00237 {
00238 row = last_d[k - 1];
00239 e.setnext(script[k - 1]);
00240 e.setop(JLibDiff.define_Fields.INSERT);
00241 }
00242 e.setline1(row);
00243 col = row + k - origin;
00244 e.setline2(col);
00245 script[k] = e;
00246 while (row < m && col < n && A[row].Equals(B[col]))
00247 {
00248 row++;
00249 col++;
00250 }
00251 last_d[k] = row;
00252 if (row == m && col == n)
00253 {
00254 v = getHunk(script[k], A, B);
00255 return ;
00256 }
00257 if (row == m)
00258 lower = k + 2;
00259 if (col == n)
00260 upper = k - 2;
00261 }
00262
00263 lower--;
00264 upper++;
00265
00266 }
00267 }
00268 }
00269
00270
00271
00272
00273
00274
00275
00276 public virtual void diffString(System.String s1, System.String s2)
00277 {
00278
00279 int max_d = 2 * JLibDiff.define_Fields.MAXLINES, m = 0, n = 0, lower, upper, d = 1, k, row, col;
00280
00281
00282 int[] last_d = new int[2 * JLibDiff.define_Fields.MAXLINES + 1];
00283
00284 edit[] script = new edit[2 * JLibDiff.define_Fields.MAXLINES + 1];
00285
00286
00287
00288 char[] A = new char[JLibDiff.define_Fields.MAXLINES], B = new char[JLibDiff.define_Fields.MAXLINES];
00289
00290
00291 int i2;
00292 int j2;
00293 i2 = 0;
00294 j2 = 0;
00295 while (i2 < s1.Length)
00296 {
00297 A[j2] = s1[i2];
00298 i2++;
00299 j2++;
00300 }
00301
00302 int i3;
00303 int j3;
00304 i3 = 0;
00305 j3 = 0;
00306 while (i3 < s2.Length)
00307 {
00308 B[j3] = s2[i3];
00309 i3++;
00310 j3++;
00311 }
00312
00313 m = s1.Length;
00314 n = s2.Length;
00315
00316 for (row = 0; row < m && row < n && A[row] == B[row]; row++)
00317 ;
00318 last_d[JLibDiff.define_Fields.ORIGIN] = row;
00319 script[JLibDiff.define_Fields.ORIGIN] = null;
00320 if (row == m)
00321 lower = JLibDiff.define_Fields.ORIGIN + 1;
00322 else
00323 lower = JLibDiff.define_Fields.ORIGIN - 1;
00324 if (row == n)
00325 upper = JLibDiff.define_Fields.ORIGIN - 1;
00326 else
00327 upper = JLibDiff.define_Fields.ORIGIN + 1;
00328 if (lower > upper)
00329 return ;
00330 else
00331 {
00332
00333 for (d = 1; d <= max_d; d++)
00334 {
00335 for (k = lower; k <= upper; k += 2)
00336 {
00337 edit e = new edit();
00338 if (e == null)
00339 {
00340 System.Console.Out.WriteLine(";;;;exceed" + d);
00341 System.Environment.Exit(0);
00342 }
00343 if (k == JLibDiff.define_Fields.ORIGIN - d || k != JLibDiff.define_Fields.ORIGIN + d && last_d[k + 1] >= last_d[k - 1])
00344 {
00345 row = last_d[k + 1] + 1;
00346 e.setnext(script[k + 1]);
00347 e.setop(JLibDiff.define_Fields.DELETE);
00348 }
00349 else
00350 {
00351 row = last_d[k - 1];
00352 e.setnext(script[k - 1]);
00353 e.setop(JLibDiff.define_Fields.INSERT);
00354 }
00355 e.setline1(row);
00356 col = row + k - JLibDiff.define_Fields.ORIGIN;
00357 e.setline2(col);
00358 script[k] = e;
00359 while (row < m && col < n && A[row] == B[col])
00360 {
00361 row++;
00362 col++;
00363 }
00364 last_d[k] = row;
00365 if (row == m && col == n)
00366 {
00367 v = getHunk(script[k], A, B);
00368 return ;
00369 }
00370 if (row == m)
00371 lower = k + 2;
00372 if (col == n)
00373 upper = k - 2;
00374 }
00375
00376 lower--;
00377 upper++;
00378
00379 }
00380 System.Console.Out.WriteLine(";;;;exceed" + d);
00381 }
00382 }
00383
00384
00385
00386
00387 private static System.Collections.ArrayList getHunk(edit start, System.String[] A, System.String[] B)
00388 {
00389 System.Collections.ArrayList v = new System.Collections.ArrayList();
00390 bool change;
00391 int i;
00392 edit ep = new edit();
00393 edit behind = new edit();
00394 edit ahead = new edit();
00395 edit a = new edit();
00396 edit b = new edit();
00397 ahead = start;
00398 ahead = start;
00399 ep = null;
00400 while (ahead != null)
00401 {
00402 behind = ep;
00403 ep = ahead;
00404 ahead = ahead.next;
00405 ep.next = behind;
00406 }
00407
00408 while (ep != null)
00409 {
00410 b = ep;
00411 if (ep.op == JLibDiff.define_Fields.INSERT)
00412 {
00413 a = ep;
00414 behind = ep.next;
00415 while (behind != null && behind.op == JLibDiff.define_Fields.INSERT && ep.line1 == behind.line1)
00416 {
00417 a = behind;
00418 behind = behind.next;
00419 }
00420 HunkAdd add = new HunkAdd();
00421 add.ld1 = ep.line1;
00422 add.ld2 = ep.line2;
00423 add.lf2 = a.line2;
00424 do
00425 {
00426 add.b.Add(B[ep.line2 - 1] + "\n");
00427 ep = ep.next;
00428 }
00429 while (ep != null && ep.op == JLibDiff.define_Fields.INSERT && ep.line1 == b.line1);
00430 add.next = null;
00431 if (v.Count != 0)
00432 {
00433 System.Collections.ArrayList temp_arraylist;
00434 temp_arraylist = v;
00435 ((Hunk) temp_arraylist[temp_arraylist.Count - 1]).next = add;
00436 }
00437 v.Add(add);
00438 }
00439 else
00440 {
00441 do
00442 {
00443 a = b;
00444 b = b.next;
00445 }
00446 while (b != null && b.op == JLibDiff.define_Fields.DELETE && b.line1 == a.line1 + 1);
00447 change = (b != null && b.op == JLibDiff.define_Fields.INSERT && b.line1 == a.line1);
00448 if (change)
00449 {
00450 HunkChange cha = new HunkChange();
00451 cha.ld1 = ep.line1;
00452 cha.lf1 = a.line1;
00453 i = 0;
00454 behind = b;
00455 while (behind != null && behind.op == JLibDiff.define_Fields.INSERT && behind.line1 == b.line1)
00456 {
00457 i++;
00458 behind = behind.next;
00459 }
00460 cha.ld2 = b.line2;
00461 cha.lf2 = i - 1 + b.line2;
00462 do
00463 {
00464 cha.a.Add(A[ep.line1 - 1] + "\n");
00465 ep = ep.next;
00466 }
00467 while (ep != b);
00468 if (!change)
00469 continue;
00470 do
00471 {
00472 cha.b.Add(B[ep.line2 - 1] + "\n");
00473 ep = ep.next;
00474 }
00475 while (ep != null && ep.op == JLibDiff.define_Fields.INSERT && ep.line1 == b.line1);
00476 cha.next = null;
00477 if (v.Count != 0)
00478 {
00479 System.Collections.ArrayList temp_arraylist2;
00480 temp_arraylist2 = v;
00481 ((Hunk) temp_arraylist2[temp_arraylist2.Count - 1]).next = cha;
00482 }
00483 v.Add(cha);
00484 }
00485 else
00486 {
00487
00488 HunkDel del = new HunkDel();
00489 del.ld1 = ep.line1;
00490 del.lf1 = a.line1;
00491 del.ld2 = ep.line2;
00492
00493 do
00494 {
00495 del.a.Add(A[ep.line1 - 1] + "\n");
00496 ep = ep.next;
00497 }
00498 while (ep != b);
00499 del.next = null;
00500 if (v.Count != 0)
00501 {
00502 System.Collections.ArrayList temp_arraylist3;
00503 temp_arraylist3 = v;
00504 ((Hunk) temp_arraylist3[temp_arraylist3.Count - 1]).next = del;
00505 }
00506 v.Add(del);
00507
00508 }
00509 }
00510 }
00511 return v;
00512 }
00513
00514
00515
00516
00517 private static System.Collections.ArrayList getHunk(edit start, char[] A, char[] B)
00518 {
00519 System.Collections.ArrayList v = new System.Collections.ArrayList();
00520
00521 bool change;
00522 int i;
00523 edit ep = new edit();
00524 edit behind = new edit();
00525 edit ahead = new edit();
00526 edit a = new edit();
00527 edit b = new edit();
00528 ahead = start;
00529 ep = null;
00530 while (ahead != null)
00531 {
00532 behind = ep;
00533 ep = ahead;
00534 ahead = ahead.next;
00535 ep.next = behind;
00536 }
00537 while (ep != null)
00538 {
00539 b = ep;
00540 if (ep.op == JLibDiff.define_Fields.INSERT)
00541 {
00542 a = ep;
00543 behind = ep.next;
00544 while (behind != null && behind.op == JLibDiff.define_Fields.INSERT && ep.line1 == behind.line1)
00545 {
00546 a = behind;
00547 behind = behind.next;
00548 }
00549 HunkAdd add = new HunkAdd();
00550 add.ld1 = ep.line1;
00551 add.ld2 = ep.line2;
00552 add.lf2 = a.line2;
00553 System.String s = new System.String("".ToCharArray());
00554 do
00555 {
00556 s = s + B[ep.line2 - 1];
00557 ep = ep.next;
00558 }
00559 while (ep != null && ep.op == JLibDiff.define_Fields.INSERT && ep.line1 == b.line1);
00560 add.b.Add(s + "\n");
00561 v.Add(add);
00562 }
00563 else
00564 {
00565 do
00566 {
00567 a = b;
00568 b = b.next;
00569 }
00570 while (b != null && b.op == JLibDiff.define_Fields.DELETE && b.line1 == a.line1 + 1);
00571 change = (b != null && b.op == JLibDiff.define_Fields.INSERT && b.line1 == a.line1);
00572 if (change)
00573 {
00574 HunkChange cha = new HunkChange();
00575 cha.ld1 = ep.line1;
00576 cha.lf1 = a.line1;
00577 i = 0;
00578 behind = b;
00579 while (behind != null && behind.op == JLibDiff.define_Fields.INSERT && behind.line1 == b.line1)
00580 {
00581 i++;
00582 behind = behind.next;
00583 }
00584 cha.ld2 = b.line2;
00585 cha.lf2 = i - 1 + b.line2;
00586 System.String s = new System.String("".ToCharArray());
00587 do
00588 {
00589 s = s + A[ep.line1 - 1];
00590 ep = ep.next;
00591 }
00592 while (ep != b);
00593 cha.a.Add(s + "\n");
00594 s = new System.String("".ToCharArray());
00595 do
00596 {
00597 s = s + B[ep.line2 - 1];
00598 ep = ep.next;
00599 }
00600 while (ep != null && ep.op == JLibDiff.define_Fields.INSERT && ep.line1 == b.line1);
00601 cha.b.Add(s + "\n");
00602 v.Add(cha);
00603 }
00604 else
00605 {
00606 HunkDel del = new HunkDel();
00607 del.ld1 = ep.line1;
00608 del.lf1 = a.line1;
00609 del.ld2 = ep.line2;
00610 System.String s = new System.String("".ToCharArray());
00611 do
00612 {
00613 s = s + A[ep.line1 - 1];
00614 ep = ep.next;
00615 }
00616 while (ep != b);
00617 del.a.Add(s + "\n");
00618 v.Add(del);
00619 }
00620
00621 }
00622 }
00623 return v;
00624 }
00625
00626
00627
00628
00629
00630 public virtual void print()
00631 {
00632 for (System.Collections.IEnumerator e = v.GetEnumerator(); e.MoveNext(); )
00633 {
00634 System.Console.Out.Write(((Hunk) e.Current).convert());
00635 }
00636 }
00637
00638
00639
00640
00641
00642
00643
00644
00645
00646
00647
00648
00649
00650
00651
00652
00653
00654
00655
00656
00657
00658
00659
00660
00661
00662
00663
00664
00665
00666
00667
00668
00669
00670
00671
00672
00673
00674
00675
00676
00677
00678
00679
00680
00681
00682
00683
00684
00685
00686
00687
00688
00689
00690
00691
00692
00693
00694
00695 }
00696 }