2 * Licensed to the Apache Software Foundation (ASF) under one
3 * or more contributor license agreements. See the NOTICE file
4 * distributed with this work for additional information
5 * regarding copyright ownership. The ASF licenses this file
6 * to you under the Apache License, Version 2.0 (the
7 * "License"); you may not use this file except in compliance
8 * with the License. You may obtain a copy of the License at
10 * http://www.apache.org/licenses/LICENSE-2.0
12 * Unless required by applicable law or agreed to in writing, software
13 * distributed under the License is distributed on an "AS IS" BASIS,
14 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
15 * See the License for the specific language governing permissions and
16 * limitations under the License.
18 package org
.apache
.hadoop
.hbase
.io
;
20 import java
.io
.OutputStream
;
21 import java
.nio
.BufferOverflowException
;
22 import java
.nio
.ByteBuffer
;
23 import java
.util
.Arrays
;
25 import org
.apache
.hadoop
.hbase
.nio
.ByteBuff
;
26 import org
.apache
.hadoop
.hbase
.util
.ByteBufferUtils
;
27 import org
.apache
.hadoop
.hbase
.util
.Bytes
;
28 import org
.apache
.yetus
.audience
.InterfaceAudience
;
31 * Our own implementation of ByteArrayOutputStream where all methods are NOT synchronized and
32 * supports writing ByteBuffer directly to it.
34 @InterfaceAudience.Private
35 public class ByteArrayOutputStream
extends OutputStream
implements ByteBufferWriter
{
37 // Borrowed from openJDK:
38 // http://grepcode.com/file/repository.grepcode.com/java/root/jdk/openjdk/8-b132/java/util/ArrayList.java#221
39 private static final int MAX_ARRAY_SIZE
= Integer
.MAX_VALUE
- 8;
44 public ByteArrayOutputStream() {
48 public ByteArrayOutputStream(int capacity
) {
49 this.buf
= new byte[capacity
];
53 public void write(ByteBuffer b
, int off
, int len
) {
54 checkSizeAndGrow(len
);
55 ByteBufferUtils
.copyFromBufferToArray(this.buf
, b
, off
, this.pos
, len
);
60 public void writeInt(int i
) {
61 checkSizeAndGrow(Bytes
.SIZEOF_INT
);
62 Bytes
.putInt(this.buf
, this.pos
, i
);
63 this.pos
+= Bytes
.SIZEOF_INT
;
67 public void write(int b
) {
68 checkSizeAndGrow(Bytes
.SIZEOF_BYTE
);
69 buf
[this.pos
] = (byte) b
;
74 public void write(byte[] b
, int off
, int len
) {
75 checkSizeAndGrow(len
);
76 System
.arraycopy(b
, off
, this.buf
, this.pos
, len
);
80 private void checkSizeAndGrow(int extra
) {
81 long capacityNeeded
= this.pos
+ (long) extra
;
82 if (capacityNeeded
> this.buf
.length
) {
83 // guarantee it's possible to fit
84 if (capacityNeeded
> MAX_ARRAY_SIZE
) {
85 throw new BufferOverflowException();
87 // double until hit the cap
88 long nextCapacity
= Math
.min(this.buf
.length
<< 1, MAX_ARRAY_SIZE
);
89 // but make sure there is enough if twice the existing capacity is still too small
90 nextCapacity
= Math
.max(nextCapacity
, capacityNeeded
);
91 if (nextCapacity
> MAX_ARRAY_SIZE
) {
92 throw new BufferOverflowException();
94 byte[] newBuf
= new byte[(int) nextCapacity
];
95 System
.arraycopy(buf
, 0, newBuf
, 0, buf
.length
);
101 * Resets the <code>pos</code> field of this byte array output stream to zero. The output stream
104 public void reset() {
109 * Copies the content of this Stream into a new byte array.
110 * @return the contents of this output stream, as new byte array.
112 public byte[] toByteArray() {
113 return Arrays
.copyOf(buf
, pos
);
116 public void toByteBuff(ByteBuff buff
) {
117 buff
.put(buf
, 0, pos
);
121 * @return the underlying array where the data gets accumulated
123 public byte[] getBuffer() {
128 * @return The current size of the buffer.