1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28 package org.apache.hc.core5.http2.impl.io;
29
30 import java.io.IOException;
31 import java.io.OutputStream;
32 import java.nio.ByteBuffer;
33
34 import org.apache.hc.core5.util.Args;
35
36
37
38
39 abstract class FrameOutputStream extends OutputStream {
40
41 private final OutputStream outputStream;
42
43 private final byte[] cache;
44 private int cachePosition;
45
46 public FrameOutputStream(final int minChunkSize, final OutputStream outputStream) {
47 super();
48 this.outputStream = Args.notNull(outputStream, "Output stream");
49 this.cache = new byte[minChunkSize];
50 }
51
52 protected abstract void write(final ByteBuffer src, final boolean endStream, final OutputStream outputStream) throws IOException;
53
54 private void flushCache(final boolean endStream) throws IOException {
55 if (this.cachePosition > 0) {
56 write(ByteBuffer.wrap(this.cache, 0, this.cachePosition), endStream, this.outputStream);
57 this.cachePosition = 0;
58 }
59 }
60
61 @Override
62 public void write(final int b) throws IOException {
63 this.cache[this.cachePosition] = (byte) b;
64 this.cachePosition++;
65 if (this.cachePosition == this.cache.length) {
66 flushCache(false);
67 }
68 }
69
70 @Override
71 public void write(final byte[] b) throws IOException {
72 write(b, 0, b.length);
73 }
74
75 @Override
76 public void write(final byte[] src, final int off, final int len) throws IOException {
77 if (len >= this.cache.length - this.cachePosition) {
78 flushCache(false);
79 write(ByteBuffer.wrap(src, off, len), false, this.outputStream);
80 } else {
81 System.arraycopy(src, off, cache, this.cachePosition, len);
82 this.cachePosition += len;
83 }
84 }
85
86 @Override
87 public void flush() throws IOException {
88 flushCache(false);
89 this.outputStream.flush();
90 }
91
92 @Override
93 public void close() throws IOException {
94 if (this.cachePosition > 0) {
95 flushCache(true);
96 } else {
97 write(null, true, this.outputStream);
98 }
99 flushCache(true);
100 this.outputStream.flush();
101 }
102
103 }