1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16 package io.netty.handler.codec.compression;
17
18 import io.netty.buffer.ByteBuf;
19 import io.netty.buffer.ByteBufAllocator;
20 import io.netty.buffer.Unpooled;
21 import io.netty.handler.codec.ByteToMessageDecoder;
22
23
24
25
26
27 abstract class InputBufferingDecompressor implements Decompressor {
28 protected final ByteBufAllocator allocator;
29 private ByteBuf cumulation;
30
31 InputBufferingDecompressor(ByteBufAllocator allocator) {
32 this.allocator = allocator;
33 }
34
35 @Override
36 public final void addInput(ByteBuf buf) throws DecompressionException {
37 if (!buf.isReadable()) {
38 buf.release();
39 return;
40 }
41 if (this.cumulation != null) {
42 buf = ByteToMessageDecoder.MERGE_CUMULATOR.cumulate(allocator, this.cumulation, buf);
43 this.cumulation = null;
44 }
45 try {
46 processInput(buf);
47 } catch (Throwable t) {
48 buf.release();
49 throw t;
50 }
51 if (buf.isReadable()) {
52 this.cumulation = buf;
53 } else {
54 buf.release();
55 }
56 }
57
58 @Override
59 public final ByteBuf takeOutput() throws DecompressionException {
60 ByteBuf buf = cumulation == null ? Unpooled.EMPTY_BUFFER : cumulation;
61 ByteBuf output = processOutput(buf);
62 try {
63 if (status() == Status.NEED_INPUT && buf.isReadable()) {
64 processInput(buf);
65 }
66 } catch (Throwable t) {
67 output.release();
68 throw t;
69 }
70 if (this.cumulation != null && !this.cumulation.isReadable()) {
71 this.cumulation.release();
72 this.cumulation = null;
73 }
74 return output;
75 }
76
77
78
79
80
81
82
83 abstract void processInput(ByteBuf buf) throws DecompressionException;
84
85
86
87
88
89
90
91 abstract ByteBuf processOutput(ByteBuf buf) throws DecompressionException;
92
93
94
95
96
97
98 final int available() {
99 return cumulation == null ? 0 : cumulation.readableBytes();
100 }
101
102 @Override
103 public void close() {
104 if (this.cumulation != null) {
105 this.cumulation.release();
106 this.cumulation = null;
107 }
108 }
109 }