Home | History | Annotate | Download | only in enc
      1 /* Copyright 2017 Google Inc. All Rights Reserved.
      2 
      3    Distributed under MIT license.
      4    See file LICENSE for detail or copy at https://opensource.org/licenses/MIT
      5 */
      6 
      7 package org.brotli.wrapper.enc;
      8 
      9 import java.io.IOException;
     10 import java.io.OutputStream;
     11 import java.nio.channels.Channels;
     12 
     13 /**
     14  * Output stream that wraps native brotli encoder.
     15  */
     16 public class BrotliOutputStream extends OutputStream {
     17   /** The default internal buffer size used by the encoder. */
     18   private static final int DEFAULT_BUFFER_SIZE = 16384;
     19 
     20   private final Encoder encoder;
     21 
     22   /**
     23    * Creates a BrotliOutputStream.
     24    *
     25    * @param destination underlying destination
     26    * @param params encoding settings
     27    * @param bufferSize intermediate buffer size
     28    */
     29   public BrotliOutputStream(OutputStream destination, Encoder.Parameters params, int bufferSize)
     30       throws IOException {
     31     this.encoder = new Encoder(Channels.newChannel(destination), params, bufferSize);
     32   }
     33 
     34   public BrotliOutputStream(OutputStream destination, Encoder.Parameters params)
     35       throws IOException {
     36     this(destination, params, DEFAULT_BUFFER_SIZE);
     37   }
     38 
     39   public BrotliOutputStream(OutputStream destination) throws IOException {
     40     this(destination, new Encoder.Parameters());
     41   }
     42 
     43   @Override
     44   public void close() throws IOException {
     45     encoder.close();
     46   }
     47 
     48   @Override
     49   public void flush() throws IOException {
     50     if (encoder.closed) {
     51       throw new IOException("write after close");
     52     }
     53     encoder.flush();
     54   }
     55 
     56   @Override
     57   public void write(int b) throws IOException {
     58     if (encoder.closed) {
     59       throw new IOException("write after close");
     60     }
     61     while (!encoder.encode(EncoderJNI.Operation.PROCESS)) {
     62       // Busy-wait loop.
     63     }
     64     encoder.inputBuffer.put((byte) b);
     65   }
     66 
     67   @Override
     68   public void write(byte[] b) throws IOException {
     69     this.write(b, 0, b.length);
     70   }
     71 
     72   @Override
     73   public void write(byte[] b, int off, int len) throws IOException {
     74     if (encoder.closed) {
     75       throw new IOException("write after close");
     76     }
     77     while (len > 0) {
     78       if (!encoder.encode(EncoderJNI.Operation.PROCESS)) {
     79         continue;
     80       }
     81       int limit = Math.min(len, encoder.inputBuffer.remaining());
     82       encoder.inputBuffer.put(b, off, limit);
     83       off += limit;
     84       len -= limit;
     85     }
     86   }
     87 }
     88