1 | /** |
---|
2 | * Licensed to the Apache Software Foundation (ASF) under one or more |
---|
3 | * contributor license agreements. See the NOTICE file distributed with this |
---|
4 | * work for additional information regarding copyright ownership. The ASF |
---|
5 | * licenses this file to you under the Apache License, Version 2.0 (the |
---|
6 | * "License"); you may not use this file except in compliance with the License. |
---|
7 | * You may obtain a copy of the License at |
---|
8 | * |
---|
9 | * http://www.apache.org/licenses/LICENSE-2.0 |
---|
10 | * |
---|
11 | * Unless required by applicable law or agreed to in writing, software |
---|
12 | * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT |
---|
13 | * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the |
---|
14 | * License for the specific language governing permissions and limitations under |
---|
15 | * the License. |
---|
16 | */ |
---|
17 | |
---|
18 | package org.apache.hadoop.io.file.tfile; |
---|
19 | |
---|
20 | import java.io.EOFException; |
---|
21 | import java.io.IOException; |
---|
22 | import java.io.OutputStream; |
---|
23 | |
---|
24 | /** |
---|
25 | * A byte array backed output stream with a limit. The limit should be smaller |
---|
26 | * than the buffer capacity. The object can be reused through <code>reset</code> |
---|
27 | * API and choose different limits in each round. |
---|
28 | */ |
---|
29 | class BoundedByteArrayOutputStream extends OutputStream { |
---|
30 | private final byte[] buffer; |
---|
31 | private int limit; |
---|
32 | private int count; |
---|
33 | |
---|
34 | public BoundedByteArrayOutputStream(int capacity) { |
---|
35 | this(capacity, capacity); |
---|
36 | } |
---|
37 | |
---|
38 | public BoundedByteArrayOutputStream(int capacity, int limit) { |
---|
39 | if ((capacity < limit) || (capacity | limit) < 0) { |
---|
40 | throw new IllegalArgumentException("Invalid capacity/limit"); |
---|
41 | } |
---|
42 | this.buffer = new byte[capacity]; |
---|
43 | this.limit = limit; |
---|
44 | this.count = 0; |
---|
45 | } |
---|
46 | |
---|
47 | @Override |
---|
48 | public void write(int b) throws IOException { |
---|
49 | if (count >= limit) { |
---|
50 | throw new EOFException("Reaching the limit of the buffer."); |
---|
51 | } |
---|
52 | buffer[count++] = (byte) b; |
---|
53 | } |
---|
54 | |
---|
55 | @Override |
---|
56 | public void write(byte b[], int off, int len) throws IOException { |
---|
57 | if ((off < 0) || (off > b.length) || (len < 0) || ((off + len) > b.length) |
---|
58 | || ((off + len) < 0)) { |
---|
59 | throw new IndexOutOfBoundsException(); |
---|
60 | } else if (len == 0) { |
---|
61 | return; |
---|
62 | } |
---|
63 | |
---|
64 | if (count + len > limit) { |
---|
65 | throw new EOFException("Reach the limit of the buffer"); |
---|
66 | } |
---|
67 | |
---|
68 | System.arraycopy(b, off, buffer, count, len); |
---|
69 | count += len; |
---|
70 | } |
---|
71 | |
---|
72 | public void reset(int newlim) { |
---|
73 | if (newlim > buffer.length) { |
---|
74 | throw new IndexOutOfBoundsException("Limit exceeds buffer size"); |
---|
75 | } |
---|
76 | this.limit = newlim; |
---|
77 | this.count = 0; |
---|
78 | } |
---|
79 | |
---|
80 | public void reset() { |
---|
81 | this.limit = buffer.length; |
---|
82 | this.count = 0; |
---|
83 | } |
---|
84 | |
---|
85 | public int getLimit() { |
---|
86 | return limit; |
---|
87 | } |
---|
88 | |
---|
89 | public byte[] getBuffer() { |
---|
90 | return buffer; |
---|
91 | } |
---|
92 | |
---|
93 | public int size() { |
---|
94 | return count; |
---|
95 | } |
---|
96 | } |
---|