Home | History | Annotate | Download | only in xz
      1 /*
      2  * DeltaOutputStream
      3  *
      4  * Author: Lasse Collin <lasse.collin (at) 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 
     27     static int getMemoryUsage() {
     28         return 1 + FILTER_BUF_SIZE / 1024;
     29     }
     30 
     31     DeltaOutputStream(FinishableOutputStream out, DeltaOptions options) {
     32         this.out = out;
     33         delta = new DeltaEncoder(options.getDistance());
     34     }
     35 
     36     public void write(int b) throws IOException {
     37         tempBuf[0] = (byte)b;
     38         write(tempBuf, 0, 1);
     39     }
     40 
     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 
     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 
     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 
     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