1 /* 2 * DeltaOutputStream 3 * 4 * Author: Lasse Collin <lasse.collin@tukaani.org> 5 * 6 * This file has been put into the public domain. 7 * You can do whatever you want with this file. 8 */ 9 10 package org.tukaani.xz; 11 12 import java.io.IOException; 13 import org.tukaani.xz.delta.DeltaEncoder; 14 15 class DeltaOutputStream extends FinishableOutputStream { 16 private static final int FILTER_BUF_SIZE = 4096; 17 18 private FinishableOutputStream out; 19 private final DeltaEncoder delta; 20 private final byte[] filterBuf = new byte[FILTER_BUF_SIZE]; 21 22 private boolean finished = false; 23 private IOException exception = null; 24 25 private final byte[] tempBuf = new byte[1]; 26 getMemoryUsage()27 static int getMemoryUsage() { 28 return 1 + FILTER_BUF_SIZE / 1024; 29 } 30 DeltaOutputStream(FinishableOutputStream out, DeltaOptions options)31 DeltaOutputStream(FinishableOutputStream out, DeltaOptions options) { 32 this.out = out; 33 delta = new DeltaEncoder(options.getDistance()); 34 } 35 write(int b)36 public void write(int b) throws IOException { 37 tempBuf[0] = (byte)b; 38 write(tempBuf, 0, 1); 39 } 40 write(byte[] buf, int off, int len)41 public void write(byte[] buf, int off, int len) throws IOException { 42 if (off < 0 || len < 0 || off + len < 0 || off + len > buf.length) 43 throw new IndexOutOfBoundsException(); 44 45 if (exception != null) 46 throw exception; 47 48 if (finished) 49 throw new XZIOException("Stream finished"); 50 51 try { 52 while (len > FILTER_BUF_SIZE) { 53 delta.encode(buf, off, FILTER_BUF_SIZE, filterBuf); 54 out.write(filterBuf); 55 off += FILTER_BUF_SIZE; 56 len -= FILTER_BUF_SIZE; 57 } 58 59 delta.encode(buf, off, len, filterBuf); 60 out.write(filterBuf, 0, len); 61 } catch (IOException e) { 62 exception = e; 63 throw e; 64 } 65 } 66 flush()67 public void flush() throws IOException { 68 if (exception != null) 69 throw exception; 70 71 if (finished) 72 throw new XZIOException("Stream finished or closed"); 73 74 try { 75 out.flush(); 76 } catch (IOException e) { 77 exception = e; 78 throw e; 79 } 80 } 81 finish()82 public void finish() throws IOException { 83 if (!finished) { 84 if (exception != null) 85 throw exception; 86 87 try { 88 out.finish(); 89 } catch (IOException e) { 90 exception = e; 91 throw e; 92 } 93 94 finished = true; 95 } 96 } 97 close()98 public void close() throws IOException { 99 if (out != null) { 100 try { 101 out.close(); 102 } catch (IOException e) { 103 if (exception == null) 104 exception = e; 105 } 106 107 out = null; 108 } 109 110 if (exception != null) 111 throw exception; 112 } 113 } 114