2 *******************************************************************************
\r
3 * Copyright (C) 1996-2009, International Business Machines Corporation and *
\r
4 * others. All Rights Reserved. *
\r
5 *******************************************************************************
\r
8 package com.ibm.icu.impl;
\r
10 /** VERY Basic Diff program. Compares two sequences of objects fed into it, and
\r
11 * lets you know where they are different.
\r
12 * @author Mark Davis
\r
16 final public class Differ {
\r
17 // public static final String copyright =
\r
18 // "Copyright (C) 2000, International Business Machines Corporation and others. All Rights Reserved.";
\r
21 * @param stackSize The size of the largest difference you expect.
\r
22 * @param matchCount The number of items that have to be the same to count as a match
\r
24 public Differ(int stackSize, int matchCount) {
\r
25 this.STACKSIZE = stackSize;
\r
26 this.EQUALSIZE = matchCount;
\r
27 a = new Object[stackSize+matchCount];
\r
28 b = new Object[stackSize+matchCount];
\r
31 public void add (Object aStr, Object bStr) {
\r
36 public void addA (Object aStr) {
\r
41 public void addB (Object bStr) {
\r
46 public int getALine(int offset) {
\r
47 return aLine + maxSame + offset;
\r
50 public Object getA(int offset) {
\r
51 if (offset < 0) return last;
\r
52 if (offset > aTop-maxSame) return next;
\r
56 public int getACount() {
\r
57 return aTop-maxSame;
\r
60 public int getBCount() {
\r
61 return bTop-maxSame;
\r
64 public int getBLine(int offset) {
\r
65 return bLine + maxSame + offset;
\r
68 public Object getB(int offset) {
\r
69 if (offset < 0) return last;
\r
70 if (offset > bTop-maxSame) return next;
\r
74 public void checkMatch(boolean finalPass) {
\r
75 // find the initial strings that are the same
\r
77 if (max > bCount) max = bCount;
\r
79 for (i = 0; i < max; ++i) {
\r
80 if (!a[i].equals(b[i])) break;
\r
82 // at this point, all items up to i are equal
\r
84 aTop = bTop = maxSame;
\r
85 if (maxSame > 0) last = a[maxSame-1];
\r
95 if (aCount - maxSame < EQUALSIZE || bCount - maxSame < EQUALSIZE) return;
\r
97 // now see if the last few a's occur anywhere in the b's, or vice versa
\r
98 int match = find (a, aCount-EQUALSIZE, aCount, b, maxSame, bCount);
\r
100 aTop = aCount-EQUALSIZE;
\r
105 match = find (b, bCount-EQUALSIZE, bCount, a, maxSame, aCount);
\r
107 bTop = bCount-EQUALSIZE;
\r
112 if (aCount >= STACKSIZE || bCount >= STACKSIZE) {
\r
113 // flush some of them
\r
114 aCount = (aCount + maxSame) / 2;
\r
115 bCount = (bCount + maxSame) / 2;
\r
120 /** Convenient utility
\r
121 * finds a segment of the first array in the second array.
\r
122 * @return -1 if not found, otherwise start position in b
\r
125 public int find (Object[] aArr, int aStart, int aEnd, Object[] bArr, int bStart, int bEnd) {
\r
126 int len = aEnd - aStart;
\r
127 int bEndMinus = bEnd - len;
\r
129 for (int i = bStart; i <= bEndMinus; ++i) {
\r
130 for (int j = 0; j < len; ++j) {
\r
131 if (!bArr[i + j].equals(aArr[aStart + j])) continue tryA;
\r
133 return i; // we have a match!
\r
138 // ====================== PRIVATES ======================
\r
140 private void flush() {
\r
142 int newCount = aCount-aTop;
\r
143 System.arraycopy(a, aTop, a, 0, newCount);
\r
150 int newCount = bCount-bTop;
\r
151 System.arraycopy(b, bTop, b, 0, newCount);
\r
158 private int STACKSIZE;
\r
159 private int EQUALSIZE;
\r
161 private Object [] a;
\r
162 private Object [] b;
\r
163 private Object last = "";
\r
164 private Object next = "";
\r
165 private int aCount = 0;
\r
166 private int bCount = 0;
\r
167 private int aLine = 1;
\r
168 private int bLine = 1;
\r
169 private int maxSame = 0, aTop = 0, bTop = 0;
\r