public static int patchLessMemory(RandomAccessFile oldFile,int oldsize,byte[] diffBuf,int diffSize,File newFile,int extLen) throws IOException {
  if (oldFile == null || oldsize <= 0) {
    return RETURN_OLD_FILE_ERR;
  }
  if (newFile == null) {
    return RETURN_NEW_FILE_ERR;
  }
  if (diffBuf == null || diffSize <= 0) {
    return RETURN_DIFF_FILE_ERR;
  }
  int commentLenPos=oldsize - extLen - 2;
  if (commentLenPos <= 2) {
    return RETURN_OLD_FILE_ERR;
  }
  DataInputStream diffIn=new DataInputStream(new ByteArrayInputStream(diffBuf,0,diffSize));
  diffIn.skip(8);
  long ctrlBlockLen=diffIn.readLong();
  long diffBlockLen=diffIn.readLong();
  int newsize=(int)diffIn.readLong();
  diffIn.close();
  InputStream in=new ByteArrayInputStream(diffBuf,0,diffSize);
  in.skip(BSUtil.HEADER_SIZE);
  DataInputStream ctrlBlockIn=new DataInputStream(new GZIPInputStream(in));
  in=new ByteArrayInputStream(diffBuf,0,diffSize);
  in.skip(ctrlBlockLen + BSUtil.HEADER_SIZE);
  InputStream diffBlockIn=new GZIPInputStream(in);
  in=new ByteArrayInputStream(diffBuf,0,diffSize);
  in.skip(diffBlockLen + ctrlBlockLen + BSUtil.HEADER_SIZE);
  InputStream extraBlockIn=new GZIPInputStream(in);
  OutputStream outStream=new FileOutputStream(newFile);
  try {
    int oldpos=0;
    int newpos=0;
    int[] ctrl=new int[3];
    while (newpos < newsize) {
      for (int i=0; i <= 2; i++) {
        ctrl[i]=ctrlBlockIn.readInt();
      }
      if (newpos + ctrl[0] > newsize) {
        outStream.close();
        return RETURN_DIFF_FILE_ERR;
      }
      byte[] buffer=new byte[ctrl[0]];
      if (!BSUtil.readFromStream(diffBlockIn,buffer,0,ctrl[0])) {
        outStream.close();
        return RETURN_DIFF_FILE_ERR;
      }
      byte[] oldBuffer=new byte[ctrl[0]];
      if (oldFile.read(oldBuffer,0,ctrl[0]) < ctrl[0]) {
        outStream.close();
        return RETURN_DIFF_FILE_ERR;
      }
      for (int i=0; i < ctrl[0]; i++) {
        if (oldpos + i == commentLenPos) {
          oldBuffer[i]=0;
          oldBuffer[i + 1]=0;
        }
        if ((oldpos + i >= 0) && (oldpos + i < oldsize)) {
          buffer[i]+=oldBuffer[i];
        }
      }
      outStream.write(buffer);
      newpos+=ctrl[0];
      oldpos+=ctrl[0];
      if (newpos + ctrl[1] > newsize) {
        outStream.close();
        return RETURN_DIFF_FILE_ERR;
      }
      buffer=new byte[ctrl[1]];
      if (!BSUtil.readFromStream(extraBlockIn,buffer,0,ctrl[1])) {
        outStream.close();
        return RETURN_DIFF_FILE_ERR;
      }
      outStream.write(buffer);
      outStream.flush();
      newpos+=ctrl[1];
      oldpos+=ctrl[2];
      oldFile.seek(oldpos);
    }
    ctrlBlockIn.close();
    diffBlockIn.close();
    extraBlockIn.close();
  }
  finally {
    oldFile.close();
    outStream.close();
  }
  return RETURN_SUCCESS;
}

public static int patchLessMemory ( RandomAccessFile oldFile , int oldsize , byte [ ] diffBuf , int diffSize , File newFile , int extLen ) throws IOException { if ( oldFile == null || oldsize <= 0 ) { return RETURN_OLD_FILE_ERR ; } if ( newFile == null ) { return RETURN_NEW_FILE_ERR ; } if ( diffBuf == null || diffSize <= 0 ) { return RETURN_DIFF_FILE_ERR ; } int commentLenPos = oldsize - extLen - 2 ; if ( commentLenPos <= 2 ) { return RETURN_OLD_FILE_ERR ; } DataInputStream diffIn = new DataInputStream ( new ByteArrayInputStream ( diffBuf , 0 , diffSize ) ) ; diffIn . skip ( 8 ) ; long ctrlBlockLen = diffIn . readLong ( ) ; long diffBlockLen = diffIn . readLong ( ) ; int newsize = ( int ) diffIn . readLong ( ) ; diffIn . close ( ) ; InputStream in = new ByteArrayInputStream ( diffBuf , 0 , diffSize ) ; in . skip ( BSUtil . HEADER_SIZE ) ; DataInputStream ctrlBlockIn = new DataInputStream ( new GZIPInputStream ( in ) ) ; in = new ByteArrayInputStream ( diffBuf , 0 , diffSize ) ; in . skip ( ctrlBlockLen + BSUtil . HEADER_SIZE ) ; InputStream diffBlockIn = new GZIPInputStream ( in ) ; in = new ByteArrayInputStream ( diffBuf , 0 , diffSize ) ; in . skip ( diffBlockLen + ctrlBlockLen + BSUtil . HEADER_SIZE ) ; InputStream extraBlockIn = new GZIPInputStream ( in ) ; OutputStream outStream = new FileOutputStream ( newFile ) ; try { int oldpos = 0 ; int newpos = 0 ; int [ ] ctrl = new int [ 3 ] ; while ( newpos < newsize ) { for ( int i = 0 ; i <= 2 ; i ++ ) { ctrl [ i ] = ctrlBlockIn . readInt ( ) ; } if ( newpos + ctrl [ 0 ] > newsize ) { outStream . close ( ) ; return RETURN_DIFF_FILE_ERR ; } byte [ ] buffer = new byte [ ctrl [ 0 ] ] ; if ( ! BSUtil . readFromStream ( diffBlockIn , buffer , 0 , ctrl [ 0 ] ) ) { outStream . close ( ) ; return RETURN_DIFF_FILE_ERR ; } byte [ ] oldBuffer = new byte [ ctrl [ 0 ] ] ; if ( oldFile . read ( oldBuffer , 0 , ctrl [ 0 ] ) < ctrl [ 0 ] ) { outStream . close ( ) ; return RETURN_DIFF_FILE_ERR ; } for ( int i = 0 ; i < ctrl [ 0 ] ; i ++ ) { if ( oldpos + i == commentLenPos ) { oldBuffer [ i ] = 0 ; oldBuffer [ i + 1 ] = 0 ; } if ( ( oldpos + i >= 0 ) && ( oldpos + i < oldsize ) ) { buffer [ i ] += oldBuffer [ i ] ; } } outStream . write ( buffer ) ; newpos += ctrl [ 0 ] ; oldpos += ctrl [ 0 ] ; if ( newpos + ctrl [ 1 ] > newsize ) { outStream . close ( ) ; return RETURN_DIFF_FILE_ERR ; } buffer = new byte [ ctrl [ 1 ] ] ; if ( ! BSUtil . readFromStream ( extraBlockIn , buffer , 0 , ctrl [ 1 ] ) ) { outStream . close ( ) ; return RETURN_DIFF_FILE_ERR ; } outStream . write ( buffer ) ; outStream . flush ( ) ; newpos += ctrl [ 1 ] ; oldpos += ctrl [ 2 ] ; oldFile . seek ( oldpos ) ; } ctrlBlockIn . close ( ) ; diffBlockIn . close ( ) ; extraBlockIn . close ( ) ; } finally { oldFile . close ( ) ; outStream . close ( ) ; } return RETURN_SUCCESS ; }
bspatch using less memory size . memory size = difffile size + max block size extlen the length of the apk external info . set 0 if has no external info .
