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    */
BrotliDecoderChannel(ReadableByteChannel source, int bufferSize)30   public BrotliDecoderChannel(ReadableByteChannel source, int bufferSize) throws IOException {
31     super(source, bufferSize);
32   }
33 
BrotliDecoderChannel(ReadableByteChannel source)34   public BrotliDecoderChannel(ReadableByteChannel source) throws IOException {
35     this(source, DEFAULT_BUFFER_SIZE);
36   }
37 
38   @Override
isOpen()39   public boolean isOpen() {
40     synchronized (mutex) {
41       return !closed;
42     }
43   }
44 
45   @Override
close()46   public void close() throws IOException {
47     synchronized (mutex) {
48       super.close();
49     }
50   }
51 
52   @Override
read(ByteBuffer dst)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 <= 0) {
62           return result == 0 ? outputSize : result;
63         }
64         result += consume(dst);
65       }
66       return result;
67     }
68   }
69 }
70