1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20 package org.apache.hadoop.hbase.util;
21
22 import java.io.IOException;
23 import java.io.OutputStream;
24 import java.nio.ByteBuffer;
25 import java.nio.channels.Channels;
26 import java.nio.channels.WritableByteChannel;
27
28 import org.apache.hadoop.classification.InterfaceAudience;
29 import org.apache.hadoop.classification.InterfaceStability;
30
31
32
33
34 @InterfaceAudience.Public
35 @InterfaceStability.Evolving
36 public class ByteBufferOutputStream extends OutputStream {
37
38 protected ByteBuffer buf;
39
40 public ByteBufferOutputStream(int capacity) {
41 this(capacity, false);
42 }
43
44 public ByteBufferOutputStream(int capacity, boolean useDirectByteBuffer) {
45 if (useDirectByteBuffer) {
46 buf = ByteBuffer.allocateDirect(capacity);
47 } else {
48 buf = ByteBuffer.allocate(capacity);
49 }
50 }
51
52 public int size() {
53 return buf.position();
54 }
55
56
57
58
59
60 public ByteBuffer getByteBuffer() {
61 buf.flip();
62 return buf;
63 }
64
65 private void checkSizeAndGrow(int extra) {
66 if ( (buf.position() + extra) > buf.limit()) {
67
68
69 int newSize = (int)Math.min((((long)buf.capacity()) * 2),
70 (long)(Integer.MAX_VALUE));
71 newSize = Math.max(newSize, buf.position() + extra);
72
73 ByteBuffer newBuf = ByteBuffer.allocate(newSize);
74 buf.flip();
75 newBuf.put(buf);
76 buf = newBuf;
77 }
78 }
79
80
81 @Override
82 public void write(int b) throws IOException {
83 checkSizeAndGrow(Bytes.SIZEOF_BYTE);
84
85 buf.put((byte)b);
86 }
87
88
89
90
91
92
93
94
95 public synchronized void writeTo(OutputStream out) throws IOException {
96 WritableByteChannel channel = Channels.newChannel(out);
97 ByteBuffer bb = buf.duplicate();
98 bb.flip();
99 channel.write(bb);
100 }
101
102 @Override
103 public void write(byte[] b) throws IOException {
104 checkSizeAndGrow(b.length);
105
106 buf.put(b);
107 }
108
109 @Override
110 public void write(byte[] b, int off, int len) throws IOException {
111 checkSizeAndGrow(len);
112
113 buf.put(b, off, len);
114 }
115
116 @Override
117 public void flush() throws IOException {
118
119 }
120
121 @Override
122 public void close() throws IOException {
123
124 }
125
126 public byte[] toByteArray(int offset, int length) {
127 ByteBuffer bb = buf.duplicate();
128 bb.flip();
129
130 byte[] chunk = new byte[length];
131
132 bb.position(offset);
133 bb.get(chunk, 0, length);
134 return chunk;
135 }
136 }