|
What this is
Other links
The source code/* * Copyright (c) 2005, Joe Desbonnet, (jdesbonnet@gmail.com) * All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions are met: * * Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * * Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in the * documentation and/or other materials provided with the distribution. * * Neither the name of the <organization> nor the * names of its contributors may be used to endorse or promote products * derived from this software without specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY <copyright holder> ``AS IS'' AND ANY * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE * DISCLAIMED. IN NO EVENT SHALL <copyright holder> BE LIABLE FOR ANY * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */package ie.wombat.jbdiff; import java.io.BufferedInputStream; import java.io.ByteArrayInputStream; import java.io.DataInputStream; import java.io.File; import java.io.FileInputStream; import java.io.FileOutputStream; import java.io.IOException; import java.io.InputStream; import java.io.OutputStream; import java.util.zip.GZIPInputStream; /** * Java Binary patcher (based on bspatch by Colin Percival) * * @author Joe Desbonnet, joe@galway.net */ public class JBPatch { // JBPatch extensions by Stefan.Liebig@compeople.de: // // - uses GZIP compressor to compress ALL of the blocks (ctrl,diff,extra). // - added an interface that allows using of JBPatch with streams and byte // arrays private static final String VERSION = "jbdiff-0.1.0"; /** * Run JBPatch from the command line. Params: oldfile newfile patchfile. * newfile will be created. * * @param arg * @throws IOException */ public static void main(String[] arg) throws IOException { if (arg.length != 3) { System.err .println("usage example: java -Xmx200m ie.wombat.jbdiff.JBPatch oldfile newfile patchfile"); } File oldFile = new File(arg[0]); File newFile = new File(arg[1]); File diffFile = new File(arg[2]); bspatch(oldFile, newFile, diffFile); } /** * @param oldFile * @param newFile * @param diffFile * @throws IOException */ public static void bspatch(File oldFile, File newFile, File diffFile) throws IOException { InputStream oldInputStream = new BufferedInputStream( new FileInputStream(oldFile)); byte[] diffBytes = new byte[(int) diffFile.length()]; InputStream diffInputStream = new FileInputStream(diffFile); Util.readFromStream(diffInputStream, diffBytes, 0, diffBytes.length); byte[] newBytes = bspatch(oldInputStream, (int) oldFile.length(), diffBytes); OutputStream newOutputStream = new FileOutputStream(newFile); newOutputStream.write(newBytes); newOutputStream.close(); } /** * @param oldInputStream * @param diffInputStream * @return */ public static byte[] bspatch(InputStream oldInputStream, int oldsize, byte[] diffBytes) throws IOException { /* * Read in old file (file to be patched) to oldBuf */ // int oldsize = (int) oldFile.length(); // byte[] oldBuf = new byte[oldsize + 1]; byte[] oldBuf = new byte[oldsize]; // InputStream oldIn = new FileInputStream( oldFile ); Util.readFromStream(oldInputStream, oldBuf, 0, oldsize); oldInputStream.close(); // oldIn.close(); return JBPatch.bspatch(oldBuf, oldsize, diffBytes); } /** * @param oldBuf * @param oldsize * @param diffBytes * @return * @throws IOException */ public static byte[] bspatch(byte[] oldBuf, int oldsize, byte[] diffBytes) throws IOException { return bspatch(oldBuf, oldsize, diffBytes, diffBytes.length); } /** * @param oldBuf * @param oldsize * @param diffBuf * @param diffSize * @return * @throws IOException */ public static byte[] bspatch(byte[] oldBuf, int oldsize, byte[] diffBuf, int diffSize) throws IOException { DataInputStream diffIn = new DataInputStream(new ByteArrayInputStream( diffBuf, 0, diffSize)); // skip headerMagic at header offset 0 (length 8 bytes) diffIn.skip(8); // ctrlBlockLen after bzip2 compression at heater offset 8 (length 8 // bytes) long ctrlBlockLen = diffIn.readLong(); // diffBlockLen after bzip2 compression at header offset 16 (length 8 // bytes) long diffBlockLen = diffIn.readLong(); // size of new file at header offset 24 (length 8 bytes) int newsize = (int) diffIn.readLong(); // System.err.println( "newsize=" + newsize ); // System.err.println( "ctrlBlockLen=" + ctrlBlockLen ); // System.err.println( "diffBlockLen=" + diffBlockLen ); // System.err.println( "newsize=" + newsize ); InputStream in; in = new ByteArrayInputStream(diffBuf, 0, diffSize); in.skip(Util.HEADER_SIZE); DataInputStream ctrlBlockIn = new DataInputStream(new GZIPInputStream( in)); in = new ByteArrayInputStream(diffBuf, 0, diffSize); in.skip(ctrlBlockLen + Util.HEADER_SIZE); InputStream diffBlockIn = new GZIPInputStream(in); in = new ByteArrayInputStream(diffBuf, 0, diffSize); in.skip(diffBlockLen + ctrlBlockLen + Util.HEADER_SIZE); InputStream extraBlockIn = new GZIPInputStream(in); // byte[] newBuf = new byte[newsize + 1]; byte[] newBuf = new byte[newsize]; int oldpos = 0; int newpos = 0; int[] ctrl = new int[3]; // int nbytes; while (newpos < newsize) { for (int i = 0; i <= 2; i++) { // ctrl[i] = diffIn.readInt(); ctrl[i] = ctrlBlockIn.readInt(); // System.err.println (" ctrl[" + i + "]=" + ctrl[i]); } if (newpos + ctrl[0] > newsize) { throw new IOException("Corrupt patch."); } /* * Read ctrl[0] bytes from diffBlock stream */ Util.readFromStream(diffBlockIn, newBuf, newpos, ctrl[0]); for (int i = 0; i < ctrl[0]; i++) { if ((oldpos + i >= 0) && (oldpos + i < oldsize)) { newBuf[newpos + i] += oldBuf[oldpos + i]; } } newpos += ctrl[0]; oldpos += ctrl[0]; if (newpos + ctrl[1] > newsize) { throw new IOException("Corrupt patch."); } Util.readFromStream(extraBlockIn, newBuf, newpos, ctrl[1]); newpos += ctrl[1]; oldpos += ctrl[2]; } // TODO: Check if at end of ctrlIn // TODO: Check if at the end of diffIn // TODO: Check if at the end of extraIn // This check is not needed since the byte array has been allocated with // this constraint! // if ( newBuf.length - 1 != newsize ) { // throw new IOException( "Corrupt patch." ); // } ctrlBlockIn.close(); diffBlockIn.close(); extraBlockIn.close(); diffIn.close(); return newBuf; // OutputStream out = new FileOutputStream( newFile ); // out.write( newBuf, 0, newBuf.length - 1 ); // out.close(); } } |
... this post is sponsored by my books ... | |
#1 New Release! |
FP Best Seller |
Copyright 1998-2024 Alvin Alexander, alvinalexander.com
All Rights Reserved.
A percentage of advertising revenue from
pages under the /java/jwarehouse
URI on this website is
paid back to open source projects.