1 /**
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
9 *
10 * http://www.apache.org/licenses/LICENSE-2.0
11 *
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.
17 */
18
19 package org.apache.hadoop.io;
20
21 import java.io;
22
23 /** A reusable {@link DataOutput} implementation that writes to an in-memory
24 * buffer.
25 *
26 * <p>This saves memory over creating a new DataOutputStream and
27 * ByteArrayOutputStream each time data is written.
28 *
29 * <p>Typical usage is something like the following:<pre>
30 *
31 * DataOutputBuffer buffer = new DataOutputBuffer();
32 * while (... loop condition ...) {
33 * buffer.reset();
34 * ... write buffer using DataOutput methods ...
35 * byte[] data = buffer.getData();
36 * int dataLength = buffer.getLength();
37 * ... write data to its ultimate destination ...
38 * }
39 * </pre>
40 *
41 */
42 public class DataOutputBuffer extends DataOutputStream {
43
44 private static class Buffer extends ByteArrayOutputStream {
45 public byte[] getData() { return buf; }
46 public int getLength() { return count; }
47 public void reset() { count = 0; }
48
49 public void write(DataInput in, int len) throws IOException {
50 int newcount = count + len;
51 if (newcount > buf.length) {
52 byte newbuf[] = new byte[Math.max(buf.length << 1, newcount)];
53 System.arraycopy(buf, 0, newbuf, 0, count);
54 buf = newbuf;
55 }
56 in.readFully(buf, count, len);
57 count = newcount;
58 }
59 }
60
61 private Buffer buffer;
62
63 /** Constructs a new empty buffer. */
64 public DataOutputBuffer() {
65 this(new Buffer());
66 }
67
68 private DataOutputBuffer(Buffer buffer) {
69 super(buffer);
70 this.buffer = buffer;
71 }
72
73 /** Returns the current contents of the buffer.
74 * Data is only valid to {@link #getLength()}.
75 */
76 public byte[] getData() { return buffer.getData(); }
77
78 /** Returns the length of the valid data currently in the buffer. */
79 public int getLength() { return buffer.getLength(); }
80
81 /** Resets the buffer to empty. */
82 public DataOutputBuffer reset() {
83 this.written = 0;
84 buffer.reset();
85 return this;
86 }
87
88 /** Writes bytes from a DataInput directly into the buffer. */
89 public void write(DataInput in, int length) throws IOException {
90 buffer.write(in, length);
91 }
92 }