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.dec; 8 9 import java.io.IOException; 10 import java.nio.ByteBuffer; 11 import java.nio.channels.ClosedChannelException; 12 import java.nio.channels.ReadableByteChannel; 13 14 /** 15 * ReadableByteChannel that wraps native brotli decoder. 16 */ 17 public class BrotliDecoderChannel extends Decoder implements ReadableByteChannel { 18 /** The default internal buffer size used by the decoder. */ 19 private static final int DEFAULT_BUFFER_SIZE = 16384; 20 21 private final Object mutex = new Object(); 22 23 /** 24 * Creates a BrotliDecoderChannel. 25 * 26 * @param source underlying source 27 * @param bufferSize intermediate buffer size 28 * @param customDictionary initial LZ77 dictionary 29 */ 30 public BrotliDecoderChannel(ReadableByteChannel source, int bufferSize) throws IOException { 31 super(source, bufferSize); 32 } 33 34 public BrotliDecoderChannel(ReadableByteChannel source) throws IOException { 35 this(source, DEFAULT_BUFFER_SIZE); 36 } 37 38 @Override 39 public boolean isOpen() { 40 synchronized (mutex) { 41 return !closed; 42 } 43 } 44 45 @Override 46 public void close() throws IOException { 47 synchronized (mutex) { 48 super.close(); 49 } 50 } 51 52 @Override 53 public int read(ByteBuffer dst) throws IOException { 54 synchronized (mutex) { 55 if (closed) { 56 throw new ClosedChannelException(); 57 } 58 int result = 0; 59 while (dst.hasRemaining()) { 60 int outputSize = decode(); 61 if (outputSize == -1) { 62 return result == 0 ? -1 : result; 63 } 64 result += consume(dst); 65 } 66 return result; 67 } 68 } 69 } 70