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 if (useDirectByteBuffer) {
47 buf = ByteBuffer.allocateDirect(capacity);
48 } else {
49 buf = ByteBuffer.allocate(capacity);
50 }
51 }
52
53 public int size() {
54 return buf.position();
55 }
56
57
58
59
60
61 public ByteBuffer getByteBuffer() {
62 buf.flip();
63 return buf;
64 }
65
66 private void checkSizeAndGrow(int extra) {
67 if ( (buf.position() + extra) > buf.limit()) {
68
69
70 int newSize = (int)Math.min((((long)buf.capacity()) * 2),
71 (long)(Integer.MAX_VALUE));
72 newSize = Math.max(newSize, buf.position() + extra);
73 ByteBuffer newBuf = null;
74 if (buf.isDirect()) {
75 newBuf = ByteBuffer.allocateDirect(newSize);
76 } else {
77 newBuf = ByteBuffer.allocate(newSize);
78 }
79 buf.flip();
80 newBuf.put(buf);
81 buf = newBuf;
82 }
83 }
84
85
86 @Override
87 public void write(int b) throws IOException {
88 checkSizeAndGrow(Bytes.SIZEOF_BYTE);
89
90 buf.put((byte)b);
91 }
92
93
94
95
96
97
98
99
100 public synchronized void writeTo(OutputStream out) throws IOException {
101 WritableByteChannel channel = Channels.newChannel(out);
102 ByteBuffer bb = buf.duplicate();
103 bb.flip();
104 channel.write(bb);
105 }
106
107 @Override
108 public void write(byte[] b) throws IOException {
109 checkSizeAndGrow(b.length);
110
111 buf.put(b);
112 }
113
114 @Override
115 public void write(byte[] b, int off, int len) throws IOException {
116 checkSizeAndGrow(len);
117
118 buf.put(b, off, len);
119 }
120
121 @Override
122 public void flush() throws IOException {
123
124 }
125
126 @Override
127 public void close() throws IOException {
128
129 }
130
131 public byte[] toByteArray(int offset, int length) {
132 ByteBuffer bb = buf.duplicate();
133 bb.flip();
134
135 byte[] chunk = new byte[length];
136
137 bb.position(offset);
138 bb.get(chunk, 0, length);
139 return chunk;
140 }
141 }