Package org.spoutcraft.diff

Source Code of org.spoutcraft.diff.JBPatch

package org.spoutcraft.diff;

/*
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2 of the License, or
(at your option) any later version.

This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
GNU General Public License for more details.

You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
*/
import java.io.DataInputStream;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import java.util.zip.GZIPInputStream;

/**
* Java Binary patcher (based on bspatch by Colin Percival)
*
* @author Joe Desbonnet, joe@galway.net
*/
public class JBPatch {

  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);
  }

  public static void bspatch(File oldFile, File newFile, File diffFile) throws IOException {

    int oldpos, newpos;

    DataInputStream diffIn = new DataInputStream(new FileInputStream(diffFile));

    // headerMagic at header offset 0 (length 8 bytes)
    long headerMagic = diffIn.readLong();

    // ctrlBlockLen after gzip compression at heater offset 8 (length 8 bytes)
    long ctrlBlockLen = diffIn.readLong();

    // diffBlockLen after gzip 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);
     */

    FileInputStream in;
    in = new FileInputStream(diffFile);
    in.skip(ctrlBlockLen + 32);
    GZIPInputStream diffBlockIn = new GZIPInputStream(in);

    in = new FileInputStream(diffFile);
    in.skip(diffBlockLen + ctrlBlockLen + 32);
    GZIPInputStream extraBlockIn = new GZIPInputStream(in);

    /*
     * Read in old file (file to be patched) to oldBuf
     */
    int oldsize = (int) oldFile.length();
    byte[] oldBuf = new byte[oldsize + 1];
    FileInputStream oldIn = new FileInputStream(oldFile);
    Util.readFromStream(oldIn, oldBuf, 0, oldsize);
    oldIn.close();

    byte[] newBuf = new byte[newsize + 1];

    oldpos = 0;
    newpos = 0;
    int[] ctrl = new int[3];
    int nbytes;
    while (newpos < newsize) {

      for (int i = 0; i <= 2; i++) {
        ctrl[i] = diffIn.readInt();
        // System.err.println ("  ctrl[" + i + "]=" + ctrl[i]);
      }

      if (newpos + ctrl[0] > newsize) {
        System.err.println("Corrupt patch\n");
        return;
      }

      /*
       * Read ctrl[0] bytes from diffBlock stream
       */

      if (!Util.readFromStream(diffBlockIn, newBuf, newpos, ctrl[0])) {
        System.err.println("error reading from extraIn");
        return;
      }

      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) {
        System.err.println("Corrupt patch");
        return;
      }

      if (!Util.readFromStream(extraBlockIn, newBuf, newpos, ctrl[1])) {
        System.err.println("error reading from extraIn");
        return;
      }

      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

    diffBlockIn.close();
    extraBlockIn.close();
    diffIn.close();

    FileOutputStream out = new FileOutputStream(newFile);
    out.write(newBuf, 0, newBuf.length - 1);
    out.close();
  }
}
TOP

Related Classes of org.spoutcraft.diff.JBPatch

TOP
Copyright © 2018 www.massapi.com. All rights reserved.
All source code are property of their respective owners. Java is a trademark of Sun Microsystems, Inc and owned by ORACLE Inc. Contact coftware#gmail.com.