I'm now using the Unix diff built in to Apache Jakarta Commons JRCS

(which I found on suigeneris.org, not apache.org) in order to bulletproof the
Tibetan Converter tests.  They used to fail due to nondeterminism in the
Java RTF writer; they should no longer fail.

I've also changed it so that the Tibetan Converter tests run in headless
mode, which means that they'll run on the nightly builds server.
This commit is contained in:
dchandler 2003-07-14 12:26:26 +00:00
parent 06fb77a82b
commit 1c29566aee
10 changed files with 41 additions and 1032 deletions

View file

@ -181,7 +181,12 @@
<target name="check"
description="Compiles and runs all JUnit tests (that can be run given the present extension JARs) for the entire project. Our coverage is currently quite low."
depends="compile-junit-tests">
<ant antfile="junitbuild.xml" target="run-all-junit-tests"
<ant antfile="junitbuild.xml" target="run-headed-junit-tests"
inheritAll="false" inheritRefs="false">
<reference refid="entire.class.path"/>
<property name="junitbin" value="${junitbin}"/>
</ant>
<ant antfile="junitbuild.xml" target="run-headless-junit-tests"
inheritAll="false" inheritRefs="false">
<reference refid="entire.class.path"/>
<property name="junitbin" value="${junitbin}"/>

View file

@ -32,17 +32,31 @@
<!-- This creates output files TEST* in the Jskad/ directory. -->
<target name="run-all-junit-tests"
<target name="run-headed-junit-tests"
description="Assuming that compilation of appropriate classes has been done, this target runs all the JUnit tests in the project.">
<junit fork="no" printsummary="yes" haltonfailure="no" haltonerror="no">
<junit fork="no" printsummary="yes" haltonfailure="yes" haltonerror="no">
<!-- we don't halt on error because you get an error when you run
on a headless display -->
<classpath>
<pathelement location="${junitbin}"/>
<path refid="entire.class.path"/>
</classpath>
<formatter type="xml"/><!-- If not XML, then 'ant -buildfile
build.xml check-report' will fail. -->
<test name="org.thdl.util.RTFFixerInputStreamTest"/>
<test name="org.thdl.tib.input.DuffPaneTest"/>
</junit>
</target>
<target name="run-headless-junit-tests"
description="Assuming that compilation of appropriate classes has been done, this target runs all the JUnit tests in the project.">
<junit fork="no" printsummary="yes" haltonfailure="yes" haltonerror="yes">
<classpath>
<pathelement location="${junitbin}"/>
<path refid="entire.class.path"/>
</classpath>
<formatter type="xml"/><!-- If not XML, then 'ant -buildfile
build.xml check-report' will fail. -->
<sysproperty key="java.awt.headless" value="true"/>
<test name="org.thdl.util.RTFFixerInputStreamTest"/>
<test name="org.thdl.util.ThdlLazyExceptionTest"/>
<test name="org.thdl.util.TrieTest"/>
<test name="org.thdl.tib.input.TMW_RTF_TO_THDL_WYLIETest"/>
@ -55,7 +69,7 @@
<!-- Note the odd dependencies. -->
<target name="make-nightly-report"
description="Creates an HTML report about the status of the tests; is dependent (via build.xml) on target `run-all-junit-tests'.">
description="Creates an HTML report about the status of the tests; is dependent (via build.xml) on targets that execute JUnit Ant tasks.">
<junitreport todir="${dist}">
<fileset dir=".">
<include name="TEST-*.xml"/>

View file

@ -26,7 +26,8 @@ import java.io.FileOutputStream;
import java.io.FileNotFoundException;
import org.thdl.util.ThdlOptions;
import org.thdl.util.javaxdelta.Delta;
import org.apache.commons.jrcs.tools.JDiff;
import org.apache.commons.jrcs.diff.Revision;
/**
* @author David Chandler
@ -78,9 +79,21 @@ public class TMW_RTF_TO_THDL_WYLIETest extends TestCase {
+ "TMW_RTF_TO_THDL_WYLIE" + testName + ".expected";
assertTrue(new File(actualFile).exists());
assertTrue(new File(expectedFile).exists());
rc = Delta.areFilesDifferent(actualFile, expectedFile);
if (0 != rc) System.out.println("0: rc is " + rc);
assertTrue(0 == rc);
Revision rev = JDiff.getDiff(expectedFile, actualFile);
assertTrue(null != rev);
String lineSep = System.getProperty("line.separator");
boolean foundExpectedDiff = false;
String expectedDiff
= ("3c3" + lineSep
+ "< {\\stylesheet{\\s1\\li0\\ri0\\fi0\\ql\\sbasedon2\\snext1 Body Text;}{\\s2 default;}}\n"
+ "---" + lineSep
+ "> {\\stylesheet{\\s2 default;}{\\s1\\li0\\ri0\\fi0\\ql\\sbasedon2\\snext1 Body Text;}}\n");
if (0 != rev.size()
&& !(foundExpectedDiff = expectedDiff.equals(rev.toString()))) {
System.out.println("Oops! the diff is this:");
System.out.print(rev.toString());
assertTrue(false);
}
}

View file

@ -1,203 +0,0 @@
/* Taken from the javaxdelta project.
http://cvs.sourceforge.net/cgi-bin/viewcvs.cgi/javaxdelta/javaxdelta/com/nothome/delta/Checksum.java?rev=1.1.1.1&content-type=text/vnd.viewcvs-markup */
/*
*
* Copyright (c) 2001 Torgeir Veimo
* Copyright (c) 2002 Nicolas PERIDONT
*
* Permission is hereby granted, free of charge, to any person obtaining a
* copy of this software and associated documentation files (the "Software"),
* to deal in the Software without restriction, including without limitation
* the rights to use, copy, modify, merge, publish, distribute, sublicense,
* and/or sell copies of the Software, and to permit persons to whom the
* Software is furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
* THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
* IN THE SOFTWARE.
*
*/
package org.thdl.util.javaxdelta;
import java.io.*;
import java.util.*;
// DC: import cmp.Primes.*; // Please note that this package has a slightly different copyright style.
public class Checksum {
public static final int BASE = 65521;
public static final int S = (1 << 4); // 16
public static boolean debug = false;
protected int hashtable[];
protected long checksums[];
protected int prime;
public Checksum() { }
protected static final char single_hash[] = {
/* Random numbers generated using SLIB's pseudo-random number generator. */
0xbcd1, 0xbb65, 0x42c2, 0xdffe, 0x9666, 0x431b, 0x8504, 0xeb46,
0x6379, 0xd460, 0xcf14, 0x53cf, 0xdb51, 0xdb08, 0x12c8, 0xf602,
0xe766, 0x2394, 0x250d, 0xdcbb, 0xa678, 0x02af, 0xa5c6, 0x7ea6,
0xb645, 0xcb4d, 0xc44b, 0xe5dc, 0x9fe6, 0x5b5c, 0x35f5, 0x701a,
0x220f, 0x6c38, 0x1a56, 0x4ca3, 0xffc6, 0xb152, 0x8d61, 0x7a58,
0x9025, 0x8b3d, 0xbf0f, 0x95a3, 0xe5f4, 0xc127, 0x3bed, 0x320b,
0xb7f3, 0x6054, 0x333c, 0xd383, 0x8154, 0x5242, 0x4e0d, 0x0a94,
0x7028, 0x8689, 0x3a22, 0x0980, 0x1847, 0xb0f1, 0x9b5c, 0x4176,
0xb858, 0xd542, 0x1f6c, 0x2497, 0x6a5a, 0x9fa9, 0x8c5a, 0x7743,
0xa8a9, 0x9a02, 0x4918, 0x438c, 0xc388, 0x9e2b, 0x4cad, 0x01b6,
0xab19, 0xf777, 0x365f, 0x1eb2, 0x091e, 0x7bf8, 0x7a8e, 0x5227,
0xeab1, 0x2074, 0x4523, 0xe781, 0x01a3, 0x163d, 0x3b2e, 0x287d,
0x5e7f, 0xa063, 0xb134, 0x8fae, 0x5e8e, 0xb7b7, 0x4548, 0x1f5a,
0xfa56, 0x7a24, 0x900f, 0x42dc, 0xcc69, 0x02a0, 0x0b22, 0xdb31,
0x71fe, 0x0c7d, 0x1732, 0x1159, 0xcb09, 0xe1d2, 0x1351, 0x52e9,
0xf536, 0x5a4f, 0xc316, 0x6bf9, 0x8994, 0xb774, 0x5f3e, 0xf6d6,
0x3a61, 0xf82c, 0xcc22, 0x9d06, 0x299c, 0x09e5, 0x1eec, 0x514f,
0x8d53, 0xa650, 0x5c6e, 0xc577, 0x7958, 0x71ac, 0x8916, 0x9b4f,
0x2c09, 0x5211, 0xf6d8, 0xcaaa, 0xf7ef, 0x287f, 0x7a94, 0xab49,
0xfa2c, 0x7222, 0xe457, 0xd71a, 0x00c3, 0x1a76, 0xe98c, 0xc037,
0x8208, 0x5c2d, 0xdfda, 0xe5f5, 0x0b45, 0x15ce, 0x8a7e, 0xfcad,
0xaa2d, 0x4b5c, 0xd42e, 0xb251, 0x907e, 0x9a47, 0xc9a6, 0xd93f,
0x085e, 0x35ce, 0xa153, 0x7e7b, 0x9f0b, 0x25aa, 0x5d9f, 0xc04d,
0x8a0e, 0x2875, 0x4a1c, 0x295f, 0x1393, 0xf760, 0x9178, 0x0f5b,
0xfa7d, 0x83b4, 0x2082, 0x721d, 0x6462, 0x0368, 0x67e2, 0x8624,
0x194d, 0x22f6, 0x78fb, 0x6791, 0xb238, 0xb332, 0x7276, 0xf272,
0x47ec, 0x4504, 0xa961, 0x9fc8, 0x3fdc, 0xb413, 0x007a, 0x0806,
0x7458, 0x95c6, 0xccaa, 0x18d6, 0xe2ae, 0x1b06, 0xf3f6, 0x5050,
0xc8e8, 0xf4ac, 0xc04c, 0xf41c, 0x992f, 0xae44, 0x5f1b, 0x1113,
0x1738, 0xd9a8, 0x19ea, 0x2d33, 0x9698, 0x2fe9, 0x323f, 0xcde2,
0x6d71, 0xe37d, 0xb697, 0x2c4f, 0x4373, 0x9102, 0x075d, 0x8e25,
0x1672, 0xec28, 0x6acb, 0x86cc, 0x186e, 0x9414, 0xd674, 0xd1a5
};
/**
* assumes the buffer is of length S
*/
public static long queryChecksum(byte buf[], int len) {
int high = 0; int low = 0;
for (int i = 0; i < len; i++) {
low += single_hash[buf[i]+128];
high += low;
}
return ((high & 0xffff) << 16) | (low & 0xffff);
}
public static long incrementChecksum(long checksum, byte out, byte in) {
char old_c = single_hash[out+128];
char new_c = single_hash[in+128];
int low = ((int)((checksum) & 0xffff) - old_c + new_c) & 0xffff;
int high = ((int)((checksum) >> 16) - (old_c * S) + low) & 0xffff;
return (high << 16) | (low & 0xffff);
}
public static int generateHash(long checksum) {
long high = (checksum >> 16) & 0xffff;
long low = checksum & 0xffff;
long it = (high >> 2) + (low << 3) + (high << 16);
int hash = (int) (it ^ high ^ low);
return hash > 0 ? hash : -hash;
}
/**
* Initialize checksums for source. The checksum for the S bytes at offset
* S * i is inserted into an array at index i.
*
* This is not good enough, we also need a hashtable into these indexes.
*
*/
public void generateChecksums(File sourceFile, int length) throws IOException {
InputStream is = new BufferedInputStream(new FileInputStream(sourceFile));
int checksumcount = (int)sourceFile.length() / S;
// DC: System.out.println("generating checksum array of size " + checksumcount);
// DC: added this:
if (checksumcount == 0) checksumcount = 16;
checksums = new long[checksumcount];
hashtable = new int[checksumcount];
prime = findClosestPrime(checksumcount);
// DC: added this but I think it isn't needed thanks to the above addition:
if (0 == prime) throw new Error("Checksum failed 304ffe");
// DC: System.out.println("using prime " + prime);
// generate cheksums at each interval
for (int i = 0; i < checksumcount; i++) {
byte buf[] = new byte[S];
is.read(buf, 0, S);
checksums[i] = queryChecksum(buf, S);
}
is.close();
// generate hashtable entries for all checksums
for (int i = 0; i < checksumcount; i++) hashtable[i] = -1;
for (int i = 0; i < checksumcount; i++) {
int hash = generateHash(checksums[i]) % prime;
if (debug)
System.out.println("checking with hash: " + hash);
if (hashtable[hash] != -1) {
if (debug)
System.out.println("hash table collision for index " + i);
} else {
hashtable[hash] = i;
}
}
//System.out.println("checksums : " + printLongArray(checksums));
//System.out.println("hashtable : " + printIntArray(hashtable));
}
public int findChecksumIndex(long checksum) {
return hashtable[generateHash(checksum) % prime];
}
public static int findClosestPrime(int size) {
// since it is used only one, we initialize the prime number generator here
Primes primes = new Primes(size);
return primes.below(size);
}
private String printIntArray(int[] a) {
String result = "";
result += "[";
for (int i = 0; i < a.length; i++) {
result += a[i];
if (i != (a.length - 1))
result += ",";
else
result += "]";
}
return result;
}
private String printLongArray(long[] a) {
String result = "";
result += "[";
for (int i = 0; i < a.length; i++) {
result += a[i];
if (i != (a.length - 1))
result += ",";
else
result += "]";
}
return result;
}
}

View file

@ -1,79 +0,0 @@
/* Taken from the javaxdelta project.
http://cvs.sourceforge.net/cgi-bin/viewcvs.cgi/javaxdelta/javaxdelta/com/nothome/delta/DebugDiffWriter.java?rev=1.1.1.1&content-type=text/vnd.viewcvs-markup */
/*
*
* Copyright (c) 2001 Torgeir Veimo
*
* Permission is hereby granted, free of charge, to any person obtaining a
* copy of this software and associated documentation files (the "Software"),
* to deal in the Software without restriction, including without limitation
* the rights to use, copy, modify, merge, publish, distribute, sublicense,
* and/or sell copies of the Software, and to permit persons to whom the
* Software is furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
* THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
* IN THE SOFTWARE.
*
*/
package org.thdl.util.javaxdelta;
/**
* This class implements a GDIFF output queue, that will contatenate
* subsequent copy statements when necessary, and write both
* copy statement and insert statement to the specified OutputStream.
*
* The output follows the GDIFF file specification available at
* http://www.w3.org/TR/NOTE-gdiff-19970901.html.
*/
import java.util.*;
import java.io.*;
public class DebugDiffWriter implements DiffWriter {
byte buf[] = new byte[256]; int buflen = 0;
public DebugDiffWriter() {}
public void addCopy(int offset, int length) throws IOException {
if (buflen > 0)
writeBuf();
System.err.println("COPY off: " + offset + ", len: " + length);
}
public void addData(byte b) throws IOException {
if (buflen < 256)
buf[buflen++] = b;
else
writeBuf();
}
private void writeBuf() {
if (buflen > 0) { // DC: added this
System.err.print("DATA: ");
for (int ix = 0; ix < buflen; ix++) {
if (buf[ix] == '\n')
System.err.print("\\n");
else
System.err.print(String.valueOf((char)((char) buf[ix])));
//System.err.print("0x" + Integer.toHexString(buf[ix]) + " "); // hex output
}
System.err.println("");
buflen = 0;
}
}
public void flush() throws IOException { writeBuf(); } // DC: these did nothing, but that's not correct.
public void close() throws IOException { flush(); } // DC: these did nothing, but that's not correct.
}

View file

@ -1,269 +0,0 @@
/* Taken from the javaxdelta project.
http://cvs.sourceforge.net/cgi-bin/viewcvs.cgi/javaxdelta/javaxdelta/com/nothome/delta/Delta.java?rev=1.1.1.1&content-type=text/vnd.viewcvs-markup */
/*
*
* Copyright (c) 2001 Torgeir Veimo
* Copyright (c) 2002 Nicolas PERIDONT
*
* Permission is hereby granted, free of charge, to any person obtaining a
* copy of this software and associated documentation files (the "Software"),
* to deal in the Software without restriction, including without limitation
* the rights to use, copy, modify, merge, publish, distribute, sublicense,
* and/or sell copies of the Software, and to permit persons to whom the
* Software is furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
* THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
* IN THE SOFTWARE.
*
*/
package org.thdl.util.javaxdelta;
import java.io.*;
import java.util.*;
public class Delta {
public final static int S = Checksum.S;
public final static boolean debug = false;
public final static int buff_size = 64*S;
public Delta() { }
public void computeDelta(File sourceFile, File targetFile, DiffWriter output) throws IOException {
int targetLength = (int) targetFile.length();
int sourceLength = (int) sourceFile.length();
int targetidx = 0;
Checksum checksum = new Checksum();
if (debug) {
System.out.println("source len: " + sourceLength);
System.out.println("target len: " + targetLength);
System.out.println("using match length S = " + S);
}
checksum.generateChecksums(sourceFile, sourceLength);
PushbackInputStream target = new PushbackInputStream(new BufferedInputStream(new FileInputStream(targetFile)),buff_size);
RandomAccessFile source = new RandomAccessFile(sourceFile, "r");
boolean done = false;
byte buf[] = new byte[S];
long hashf = 0; byte b[] = new byte[1]; byte sourcebyte[] = new byte[S];
if (targetLength-targetidx <= S) {
System.err.println("too short input file");
return;
}
// initialize first complete checksum.
target.read(buf, 0, S);
targetidx += S;
hashf = checksum.queryChecksum(buf, S);
// The check for alternative hashf is only because I wanted to verify that the
// update method really is correct. I will remove it shortly.
long alternativehashf = hashf;
if (debug)
System.out.println("my hashf: " + hashf + ", adler32: " + alternativehashf);
while (!done) {
int index = checksum.findChecksumIndex(hashf);
if (index != -1) {
// possible match, need to check byte for byte
boolean match = true;
int offset = index * S;
int length = S - 1;
source.seek(offset);
source.read(sourcebyte, 0, S);
for (int ix = 0; ix < S; ix++) {
if (sourcebyte[ix] != buf[ix]) {
match = false;
}
}
if (match) {
//System.out.println("before targetidx : " + targetidx );
// The length of the match is determined by comparing bytes.
long start = System.currentTimeMillis();
boolean ok = true;
byte[] sourceBuff = new byte[buff_size];
byte[] targetBuff = new byte[buff_size];
int source_idx = 0;
int target_idx = 0;
do{
source_idx = source.read(sourceBuff, 0, buff_size);
target_idx = target.read(targetBuff, 0, buff_size);
int read_idx = Math.max(source_idx,target_idx);
int i = 0;
do {
targetidx++;
++length;
ok = sourceBuff[i] == targetBuff[i];
i++;
if(!ok) {
b[0] = targetBuff[i-1];
target.unread(targetBuff,i,target_idx-i);
}
} while(i < read_idx && ok);
} while(ok && targetLength-targetidx > 0);
// this is a insert instruction
//System.out.println("output.addCopy("+offset+","+length+")");
output.addCopy(offset, length);
if (targetLength-targetidx <= S) { // eof reached, special case for last bytes
if (debug)
System.out.println("last part of file");
buf[0] = b[0]; // don't loose this byte
int remaining = targetLength-targetidx;
target.read(buf, 1 , remaining);
targetidx += remaining;
for (int ix = 0; ix < (remaining + 1); ix++)
output.addData(buf[ix]);
done = true;
} else {
buf[0] = b[0];
target.read(buf, 1, S - 1);
targetidx += S-1;
alternativehashf = hashf = checksum.queryChecksum(buf, S);
}
continue; //continue loop
}
}
if (targetLength-targetidx > 0) {
// update the adler fingerpring with a single byte
target.read(b, 0, 1);
targetidx += 1;
// insert instruction with the old byte we no longer use...
output.addData(buf[0]);
alternativehashf = checksum.incrementChecksum(alternativehashf, buf[0], b[0]);
for (int j = 0; j < 15; j++)
buf[j] = buf[j+1];
buf[15] = b[0];
hashf = checksum.queryChecksum(buf, S);
if (debug)
System.out.println("raw: " + Integer.toHexString((int)hashf) + ", incremental: " + Integer.toHexString((int)alternativehashf));
} else {
for (int ix = 0; ix < S; ix++)
output.addData(buf[ix]);
done = true;
}
}
output.close();
}
// sample program to compute the difference between two input files.
public static void main(String argv[]) {
// DC: javaxdeltamain(argv);
thdltoolsmain(argv);
}
public static void javaxdeltamain(String argv[]) {
Delta delta = new Delta();
if (argv.length != 3) {
System.err.println("usage Delta [-d] source target [output]");
System.err.println("either -d or an output filename must be specified.");
System.err.println("aborting..");
return;
}
try {
DiffWriter output = null;
File sourceFile = null;
File targetFile = null;
if (argv[0].equals("-d")) {
sourceFile = new File(argv[1]);
targetFile = new File(argv[2]);
output = new DebugDiffWriter();
} else {
sourceFile = new File(argv[0]);
targetFile = new File(argv[1]);
output = new GDiffWriter(new DataOutputStream(new BufferedOutputStream(new FileOutputStream(new File(argv[2])))));
}
if (sourceFile.length() > Integer.MAX_VALUE || targetFile.length() > Integer.MAX_VALUE) {
System.err.println("source or target is too large, max length is " + Integer.MAX_VALUE);
System.err.println("aborting..");
return;
}
//output.close();
delta.computeDelta(sourceFile, targetFile, output);
output.flush();
output.close();
// DC: System.out.println("finished generating delta");
} catch (IOException ioe) {
System.err.println("error while generating delta; " + ioe);
}
}
public static void thdltoolsmain(String argv[]) {
Delta delta = new Delta();
if (argv.length != 2) {
System.err.println("usage Delta source target");
System.err.println("aborting..");
System.exit(-2);
}
int rc = Delta.areFilesDifferent(argv[0], argv[1]);
if (rc == 1)
System.out.println("files differ");
else if (rc == 0)
System.out.println("files are the same");
else
System.out.println("error comparing files");
System.exit(rc);
}
/** Returns 1 if source and target differ, 0 if they don't, -1 on
error. David Chandler wrote this based on main(). */
public static int areFilesDifferent(String source, String target) {
Delta delta = new Delta();
try {
YesOrNoDiffWriter output = new YesOrNoDiffWriter();
File sourceFile = new File(source);
File targetFile = new File(target);
if (sourceFile.length() > Integer.MAX_VALUE || targetFile.length() > Integer.MAX_VALUE) {
return -1;
}
delta.computeDelta(sourceFile, targetFile, output);
return (output.areFilesDifferent()) ? 1 : 0;
} catch (IOException ioe) {
return -1;
}
}
}

View file

@ -1,43 +0,0 @@
/* Taken from the javaxdelta project.
http://cvs.sourceforge.net/cgi-bin/viewcvs.cgi/javaxdelta/javaxdelta/com/nothome/delta/DiffWriter.java?rev=1.1.1.1&content-type=text/vnd.viewcvs-markup */
/*
*
* Copyright (c) 2001 Torgeir Veimo
*
* Permission is hereby granted, free of charge, to any person obtaining a
* copy of this software and associated documentation files (the "Software"),
* to deal in the Software without restriction, including without limitation
* the rights to use, copy, modify, merge, publish, distribute, sublicense,
* and/or sell copies of the Software, and to permit persons to whom the
* Software is furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
* THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
* IN THE SOFTWARE.
*
*/
package org.thdl.util.javaxdelta;
import java.io.IOException;
/**
*
* @author torgeir
*/
public interface DiffWriter {
public void addCopy(int offset, int length) throws IOException;
//public void addInsert(String insertString) throws IOException;
public void addData(byte b) throws IOException;
public void flush() throws IOException;
public void close() throws IOException;
}

View file

@ -1,141 +0,0 @@
/* Taken from the javaxdelta project.
http://cvs.sourceforge.net/cgi-bin/viewcvs.cgi/javaxdelta/javaxdelta/com/nothome/delta/GDiffWriter.java?rev=1.1.1.1&content-type=text/vnd.viewcvs-markup */
/*
*
* Copyright (c) 2001 Torgeir Veimo
*
* Permission is hereby granted, free of charge, to any person obtaining a
* copy of this software and associated documentation files (the "Software"),
* to deal in the Software without restriction, including without limitation
* the rights to use, copy, modify, merge, publish, distribute, sublicense,
* and/or sell copies of the Software, and to permit persons to whom the
* Software is furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
* THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
* IN THE SOFTWARE.
*
*/
package org.thdl.util.javaxdelta;
/**
* The output follows the GDIFF file specification available at
* http://www.w3.org/TR/NOTE-gdiff-19970901.html.
*/
import java.util.*;
import java.io.*;
public class GDiffWriter implements DiffWriter {
byte buf[] = new byte[256]; int buflen = 0;
protected boolean debug = false;
//Vector writeQueue = new Vector();
DataOutputStream output = null;
public GDiffWriter(DataOutputStream os) throws IOException {
this.output = os;
// write magic string "d1 ff d1 ff 04"
output.writeByte(0xd1);
output.writeByte(0xff);
output.writeByte(0xd1);
output.writeByte(0xff);
output.writeByte(0x04);
}
public void setDebug(boolean flag) { debug = flag; }
public void addCopy(int offset, int length) throws IOException {
if (buflen > 0)
writeBuf();
//output debug data
if (debug)
System.err.println("COPY off: " + offset + ", len: " + length);
// output real data
byte command;
if (offset > Integer.MAX_VALUE) {
// use long, int format
output.writeByte(255);
// Actually, we don't support longer files than int.MAX_VALUE at the moment..
} else if (offset < 65536) {
if (length < 256) {
// use ushort, ubyte
output.writeByte(249);
output.writeShort(offset);
output.writeByte(length);
} else if (length > 65535) {
// use ushort, int
output.writeByte(251);
output.writeShort(offset);
output.writeInt(length);
} else {
// use ushort, ushort
output.writeByte(250);
output.writeShort(offset);
output.writeShort(length);
}
} else {
if (length < 256) {
// use int, ubyte
output.writeByte(252);
output.writeInt(offset);
output.writeByte(length);
} else if (length > 65535) {
// use int, int
output.writeByte(254);
output.writeInt(offset);
output.writeInt(length);
} else {
// use int, ushort
output.writeByte(253);
output.writeInt(offset);
output.writeShort(length);
}
}
}
public void addData(byte b) throws IOException {
if (buflen >= 246)
writeBuf();
buf[buflen] = b; buflen++;
}
private void writeBuf() throws IOException {
// output debug data
if (debug) {
System.err.print("DATA:");
for (int ix = 0; ix < buflen; ix++) {
if (buf[ix] == '\n')
System.err.print("\\n");
else
System.err.print(String.valueOf((char)((char) buf[ix])));
}
System.err.println("");
}
if (buflen > 0) {
// output real data
output.writeByte(buflen);
output.write(buf, 0, buflen);
}
buflen = 0;
}
public void flush() throws IOException { if (buflen > 0) writeBuf(); output.flush(); }
public void close() throws IOException { this.flush(); }
}

View file

@ -1,228 +0,0 @@
/* Taken from the javaxdelta project. */
/*
Primes 1.1 calculates the primes 1..N, tells you if N is prime,
computes the prime just below or above N. It is useful in computing
optimal HashTable sizes. Java source included. Copyright 1998 by
Roedy Green of Canadian Mind Products. May be freely distbributed
for any purpose but military.
*/
// Primes.java
package org.thdl.util.javaxdelta;
/** Copyright 1998
* Roedy Green
* Canadian Mind Products
* #208 - 525 Ninth Street
* New Westminster, BC Canada V3M 5T9
* tel: (604) 777-1804
* mailto:roedy@mindprod.com
* http://mindprod.com
*/
// May be freely distributed for any purpose but military
import java.util.BitSet;
/**
* @author Roedy Green
* @version 1.10 1998 November 10
* Calculate primes using Eratostheses Sieve.
* Tell if a given number is prime.
* Find a prime just below a given number.
* Find a prime just above a given number.
*/
/*
* version 1.1 1998 November 10 - new address and phone.
*/
public class Primes
{
private static final String EmbeddedCopyright =
"Copyright 1997-2000 Roedy Green, Canadian Mind Products, http://mindprod.com";
/**
* constructors
*/
public Primes()
{
ensureCapacity(1000);
}
/**
* @param capacity - largest number you will be asking if prime.
* If give too small a number, it will automatically grow by
* recomputing the sieve array.
*/
public Primes (int capacity)
{
ensureCapacity(capacity);
}
/**
* @param candidate - is this a prime?
*/
public boolean isPrime(int candidate)
{
ensureCapacity(candidate);
if (candidate < 3) return candidate != 0;
if (candidate % 2 == 0 ) return false;
return !b.get(candidate/2);
}
/**
* @return first prime higher than candidate
*/
public int above(int candidate)
{
do
{
// see what we can find in the existing sieve
for (int i=candidate+1; i<= sieveCapacity; i++)
{
if (isPrime(i)) return i;
}
// Keep building ever bigger sieves till we succeed.
// The next prime P' is between P+2 and P^2 - 2.
// However that is a rather pessimistic upper bound.
// Ideally some theorem would tell us how big we need to build
// to find one.
ensureCapacity(Math.max(candidate*2, sieveCapacity*2));
} // end do
while (true);
} // end above
/**
* @return first prime less than candidate
*/
public int below (int candidate)
{
for (candidate--; candidate > 0; candidate--)
{
if (isPrime(candidate)) return candidate;
}
// candidate was 1 or 0 or -ve
return 0;
}
/**
* calc all primes in the range 1..n,
* not the first n primes.
* @param n highest candidate, not necessarily prime.
* @return list of primes 1..n in an array
*/
public final int[] getPrimes(int n)
{
// calculate the primes
ensureCapacity(n);
// pass 1: count primes
int countPrimes = 0;
for (int i = 0; i <= n; i++)
{
if (isPrime(i)) countPrimes++;
}
// pass 2: construct array of primes
int [] primes = new int[countPrimes];
countPrimes = 0;
for (int i = 0; i <= n; i++)
{
if (isPrime(i)) primes[countPrimes++] = i;
}
return primes;
} // end getPrimes
/**
* calculate the sieve, bit map of all primes 0..n
* @param n highest number evalutated by the sieve, not necessarily prime.
*/
private final void sieve ( int n )
{
// Presume BitSet b set is big enough for our purposes.
// Presume all even numbers are already marked composite, effectively.
// Presume all odd numbers are already marked prime (0 in bit map).
int last = (int)(Math.sqrt(n))+1;
for (int candidate = 3; candidate <= last; candidate += 2)
{
// only look at odd numbers
if (!b.get(candidate/2) /* if candidate is prime */)
{
// Our candidate is prime.
// Only bother to mark multiples of primes. Others already done.
// no need to mark even multiples, already done
int incr = candidate*2;
for ( int multiple = candidate + incr; multiple < n; multiple += incr)
{
b.set(multiple/2); // mark multiple as composite
} // end for multiple
} // end if
} // end for candidate
// at this point our sieve b is correct, except for 0..2
} // end sieve
/**
* Ensure have a sieve to tackle primes as big as n.
* If we don't allocate a sieve big enough and calculate it.
* @param n - ensure sieve big enough to evaluate n for primality.
*/
private void ensureCapacity (int n)
{
if ( n > sieveCapacity )
{
b = new BitSet((n+1)/2);
// starts out all 0, presume all numbers prime
sieveCapacity = n;
sieve(n);
}
// otherwise existing sieve is fine
} // end ensureCapacity
private int sieveCapacity;
// biggest number we have computed in our sieve.
// our BitSet array is indexed 0..N (odd only)
private BitSet b; /* true for each odd number if is composite */
/**
* Demonstrate and test the methods
*/
public static void main (String[] args)
{
// print primes 1..101
Primes calc = new Primes(106);
int[] primes = calc.getPrimes(101);
for (int i=0; i<primes.length; i++)
{
System.out.println(primes[i]);
}
// demonstrate isPrime, above, below
System.out.println(calc.isPrime(149));
System.out.println(calc.below(149));
System.out.println(calc.above(149));
// print all the primes just greater than powers of 2
calc = new Primes(10000000);
for (int pow=8; pow < 10000000; pow*=2)
System.out.println(calc.above(pow));
// Validate that isPrime works by comparing it with brute force
for (int i=3; i<=151; i++)
{
boolean prime = true;
for (int j=2; j<i; j++)
{
if (i % j == 0 )
{
prime = false;
break;
}
} // end for j
if ( calc.isPrime(i) != prime ) System.out.println(i + " oops");
} // end for i
} // end main
} // end Primes

View file

@ -1,60 +0,0 @@
/* Added by David Chandler, based on stuff in this package. */
/*
*
* Copyright (c) 2001 Torgeir Veimo
*
* Permission is hereby granted, free of charge, to any person obtaining a
* copy of this software and associated documentation files (the "Software"),
* to deal in the Software without restriction, including without limitation
* the rights to use, copy, modify, merge, publish, distribute, sublicense,
* and/or sell copies of the Software, and to permit persons to whom the
* Software is furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
* THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
* IN THE SOFTWARE.
*
*/
package org.thdl.util.javaxdelta;
import java.util.*;
import java.io.*;
/** We look to see that one special DATA statement and only one COPY statment
are generated. If so, there's no difference between the input and
the output. Otherwise there is.
@author David Chandler */
public class YesOrNoDiffWriter implements DiffWriter {
public YesOrNoDiffWriter() {}
private int numCopies = 0;
private int numDatas = 0;
public void addCopy(int offset, int length) throws IOException {
if (numCopies == 1) numCopies = 2;
if (numCopies == 0) numCopies = 1;
}
public void addData(byte b) throws IOException {
if (numDatas == 1) numDatas = 2;
if (numDatas == 0) numDatas = 1;
}
public boolean areFilesDifferent() {
return numCopies != 1 || numDatas != 1;
}
private void writeBuf() { }
public void flush() throws IOException { }
public void close() throws IOException { }
}