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.nio.Buffer; 11 import java.nio.ByteBuffer; 12 import java.nio.channels.ClosedChannelException; 13 import java.nio.channels.WritableByteChannel; 14 15 /** 16 * WritableByteChannel that wraps native brotli encoder. 17 */ 18 public class BrotliEncoderChannel extends Encoder implements WritableByteChannel { 19 /** The default internal buffer size used by the decoder. */ 20 private static final int DEFAULT_BUFFER_SIZE = 16384; 21 22 private final Object mutex = new Object(); 23 24 /** 25 * Creates a BrotliEncoderChannel. 26 * 27 * @param destination underlying destination 28 * @param params encoding settings 29 * @param bufferSize intermediate buffer size 30 */ BrotliEncoderChannel(WritableByteChannel destination, Encoder.Parameters params, int bufferSize)31 public BrotliEncoderChannel(WritableByteChannel destination, Encoder.Parameters params, 32 int bufferSize) throws IOException { 33 super(destination, params, bufferSize); 34 } 35 BrotliEncoderChannel(WritableByteChannel destination, Encoder.Parameters params)36 public BrotliEncoderChannel(WritableByteChannel destination, Encoder.Parameters params) 37 throws IOException { 38 this(destination, params, DEFAULT_BUFFER_SIZE); 39 } 40 BrotliEncoderChannel(WritableByteChannel destination)41 public BrotliEncoderChannel(WritableByteChannel destination) throws IOException { 42 this(destination, new Encoder.Parameters()); 43 } 44 45 @Override isOpen()46 public boolean isOpen() { 47 synchronized (mutex) { 48 return !closed; 49 } 50 } 51 52 @Override close()53 public void close() throws IOException { 54 synchronized (mutex) { 55 super.close(); 56 } 57 } 58 59 @Override write(ByteBuffer src)60 public int write(ByteBuffer src) throws IOException { 61 synchronized (mutex) { 62 if (closed) { 63 throw new ClosedChannelException(); 64 } 65 int result = 0; 66 while (src.hasRemaining() && encode(EncoderJNI.Operation.PROCESS)) { 67 int limit = Math.min(src.remaining(), inputBuffer.remaining()); 68 ByteBuffer slice = src.slice(); 69 ((Buffer) slice).limit(limit); 70 inputBuffer.put(slice); 71 result += limit; 72 ((Buffer) src).position(src.position() + limit); 73 } 74 return result; 75 } 76 } 77 } 78