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.io;
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.hbase.classification.InterfaceAudience;
29 import org.apache.hadoop.hbase.classification.InterfaceStability;
30 import org.apache.hadoop.hbase.util.Bytes;
31
32
33
34
35 @InterfaceAudience.Public
36 @InterfaceStability.Evolving
37 public class ByteBufferOutputStream extends OutputStream {
38
39 protected ByteBuffer buf;
40
41 public ByteBufferOutputStream(int capacity) {
42 this(capacity, false);
43 }
44
45 public ByteBufferOutputStream(int capacity, boolean useDirectByteBuffer) {
46 this(allocate(capacity, useDirectByteBuffer));
47 }
48
49
50
51
52
53
54
55
56
57
58
59 public ByteBufferOutputStream(final ByteBuffer bb) {
60 this.buf = bb;
61 this.buf.clear();
62 }
63
64 public int size() {
65 return buf.position();
66 }
67
68 private static ByteBuffer allocate(final int capacity, final boolean useDirectByteBuffer) {
69 return useDirectByteBuffer? ByteBuffer.allocateDirect(capacity): ByteBuffer.allocate(capacity);
70 }
71
72
73
74
75
76 public ByteBuffer getByteBuffer() {
77 buf.flip();
78 return buf;
79 }
80
81 private void checkSizeAndGrow(int extra) {
82 if ( (buf.position() + extra) > buf.limit()) {
83
84
85 int newSize = (int)Math.min((((long)buf.capacity()) * 2),
86 (long)(Integer.MAX_VALUE));
87 newSize = Math.max(newSize, buf.position() + extra);
88 ByteBuffer newBuf = allocate(newSize, buf.isDirect());
89 buf.flip();
90 newBuf.put(buf);
91 buf = newBuf;
92 }
93 }
94
95
96 @Override
97 public void write(int b) throws IOException {
98 checkSizeAndGrow(Bytes.SIZEOF_BYTE);
99
100 buf.put((byte)b);
101 }
102
103
104
105
106
107
108
109
110 public synchronized void writeTo(OutputStream out) throws IOException {
111 WritableByteChannel channel = Channels.newChannel(out);
112 ByteBuffer bb = buf.duplicate();
113 bb.flip();
114 channel.write(bb);
115 }
116
117 @Override
118 public void write(byte[] b) throws IOException {
119 checkSizeAndGrow(b.length);
120
121 buf.put(b);
122 }
123
124 @Override
125 public void write(byte[] b, int off, int len) throws IOException {
126 checkSizeAndGrow(len);
127
128 buf.put(b, off, len);
129 }
130
131 @Override
132 public void flush() throws IOException {
133
134 }
135
136 @Override
137 public void close() throws IOException {
138
139 }
140
141 public byte[] toByteArray(int offset, int length) {
142 ByteBuffer bb = buf.duplicate();
143 bb.flip();
144
145 byte[] chunk = new byte[length];
146
147 bb.position(offset);
148 bb.get(chunk, 0, length);
149 return chunk;
150 }
151 }