• Home
  • History
  • Annotate
  • Line#
  • Navigate
  • Raw
  • Download
  • only in /netgear-WNDR4500v2-V1.0.0.60_1.0.38/ap/gpl/timemachine/db-4.7.25.NC/java/src/com/sleepycat/util/
1/*-
2 * See the file LICENSE for redistribution information.
3 *
4 * Copyright (c) 2000,2008 Oracle.  All rights reserved.
5 *
6 * $Id: FastOutputStream.java,v 12.8 2008/01/08 20:58:39 bostic Exp $
7 */
8
9package com.sleepycat.util;
10
11import java.io.IOException;
12import java.io.OutputStream;
13import java.io.UnsupportedEncodingException;
14
15/**
16 * A replacement for ByteArrayOutputStream that does not synchronize every
17 * byte read.
18 *
19 * <p>This class extends {@link OutputStream} and its <code>write()</code>
20 * methods allow it to be used as a standard output stream.  In addition, it
21 * provides <code>writeFast()</code> methods that are not declared to throw
22 * <code>IOException</code>.  <code>IOException</code> is never thrown by this
23 * class.</p>
24 *
25 * @author Mark Hayes
26 */
27public class FastOutputStream extends OutputStream {
28
29    /**
30     * The default initial size of the buffer if no initialSize parameter is
31     * specified.  This constant is 100 bytes.
32     */
33    public static final int DEFAULT_INIT_SIZE = 100;
34
35    /**
36     * The default amount that the buffer is increased when it is full.  This
37     * constant is zero, which means to double the current buffer size.
38     */
39    public static final int DEFAULT_BUMP_SIZE = 0;
40
41    private int len;
42    private int bumpLen;
43    private byte[] buf;
44
45    /*
46     * We can return the same byte[] for 0 length arrays.
47     */
48    private static byte[] ZERO_LENGTH_BYTE_ARRAY = new byte[0];
49
50    /**
51     * Creates an output stream with default sizes.
52     */
53    public FastOutputStream() {
54
55        initBuffer(DEFAULT_INIT_SIZE, DEFAULT_BUMP_SIZE);
56    }
57
58    /**
59     * Creates an output stream with a default bump size and a given initial
60     * size.
61     *
62     * @param initialSize the initial size of the buffer.
63     */
64    public FastOutputStream(int initialSize) {
65
66	initBuffer(initialSize, DEFAULT_BUMP_SIZE);
67    }
68
69    /**
70     * Creates an output stream with a given bump size and initial size.
71     *
72     * @param initialSize the initial size of the buffer.
73     *
74     * @param bumpSize the amount to increment the buffer.
75     */
76    public FastOutputStream(int initialSize, int bumpSize) {
77
78	initBuffer(initialSize, bumpSize);
79    }
80
81    /**
82     * Creates an output stream with a given initial buffer and a default
83     * bump size.
84     *
85     * @param buffer the initial buffer; will be owned by this object.
86     */
87    public FastOutputStream(byte[] buffer) {
88
89        buf = buffer;
90        bumpLen = DEFAULT_BUMP_SIZE;
91    }
92
93    /**
94     * Creates an output stream with a given initial buffer and a given
95     * bump size.
96     *
97     * @param buffer the initial buffer; will be owned by this object.
98     *
99     * @param bumpSize the amount to increment the buffer.  If zero (the
100     * default), the current buffer size will be doubled when the buffer is
101     * full.
102     */
103    public FastOutputStream(byte[] buffer, int bumpSize) {
104
105        buf = buffer;
106        bumpLen = bumpSize;
107    }
108
109    private void initBuffer(int bufferSize, int bumpLen) {
110	buf = new byte[bufferSize];
111	this.bumpLen = bumpLen;
112    }
113
114    // --- begin ByteArrayOutputStream compatible methods ---
115
116    public int size() {
117
118        return len;
119    }
120
121    public void reset() {
122
123        len = 0;
124    }
125
126    public void write(int b) throws IOException {
127
128        writeFast(b);
129    }
130
131    public void write(byte[] fromBuf) throws IOException {
132
133        writeFast(fromBuf);
134    }
135
136    public void write(byte[] fromBuf, int offset, int length)
137        throws IOException {
138
139        writeFast(fromBuf, offset, length);
140    }
141
142    public void writeTo(OutputStream out) throws IOException {
143
144        out.write(buf, 0, len);
145    }
146
147    public String toString() {
148
149        return new String(buf, 0, len);
150    }
151
152    public String toString(String encoding)
153        throws UnsupportedEncodingException {
154
155        return new String(buf, 0, len, encoding);
156    }
157
158    public byte[] toByteArray() {
159
160	if (len == 0) {
161	    return ZERO_LENGTH_BYTE_ARRAY;
162	} else {
163	    byte[] toBuf = new byte[len];
164	    System.arraycopy(buf, 0, toBuf, 0, len);
165
166	    return toBuf;
167	}
168    }
169
170    // --- end ByteArrayOutputStream compatible methods ---
171
172    /**
173     * Equivalent to <code>write(int)<code> but does not throw
174     * <code>IOException</code>.
175     * @see #write(int)
176     */
177    public final void writeFast(int b) {
178
179        if (len + 1 > buf.length)
180            bump(1);
181
182        buf[len++] = (byte) b;
183    }
184
185    /**
186     * Equivalent to <code>write(byte[])<code> but does not throw
187     * <code>IOException</code>.
188     * @see #write(byte[])
189     */
190    public final void writeFast(byte[] fromBuf) {
191
192        int needed = len + fromBuf.length - buf.length;
193        if (needed > 0)
194            bump(needed);
195
196        System.arraycopy(fromBuf, 0, buf, len, fromBuf.length);
197        len += fromBuf.length;
198    }
199
200    /**
201     * Equivalent to <code>write(byte[],int,int)<code> but does not throw
202     * <code>IOException</code>.
203     * @see #write(byte[],int,int)
204     */
205    public final void writeFast(byte[] fromBuf, int offset, int length) {
206
207        int needed = len + length - buf.length;
208        if (needed > 0)
209            bump(needed);
210
211        System.arraycopy(fromBuf, offset, buf, len, length);
212        len += length;
213    }
214
215    /**
216     * Returns the buffer owned by this object.
217     *
218     * @return the buffer.
219     */
220    public byte[] getBufferBytes() {
221
222        return buf;
223    }
224
225    /**
226     * Returns the offset of the internal buffer.
227     *
228     * @return always zero currently.
229     */
230    public int getBufferOffset() {
231
232        return 0;
233    }
234
235    /**
236     * Returns the length used in the internal buffer, i.e., the offset at
237     * which data will be written next.
238     *
239     * @return the buffer length.
240     */
241    public int getBufferLength() {
242
243        return len;
244    }
245
246    /**
247     * Ensure that at least the given number of bytes are available in the
248     * internal buffer.
249     *
250     * @param sizeNeeded the number of bytes desired.
251     */
252    public void makeSpace(int sizeNeeded) {
253
254        int needed = len + sizeNeeded - buf.length;
255        if (needed > 0)
256            bump(needed);
257    }
258
259    /**
260     * Skip the given number of bytes in the buffer.
261     *
262     * @param sizeAdded number of bytes to skip.
263     */
264    public void addSize(int sizeAdded) {
265
266        len += sizeAdded;
267    }
268
269    private void bump(int needed) {
270
271        /* Double the buffer if the bumpLen is zero. */
272        int bump = (bumpLen > 0) ? bumpLen : buf.length;
273
274        byte[] toBuf = new byte[buf.length + needed + bump];
275
276        System.arraycopy(buf, 0, toBuf, 0, len);
277
278        buf = toBuf;
279    }
280}
281