KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > com > vladium > util > ByteArrayOStream


1 /* Copyright (C) 2003 Vladimir Roubtsov. All rights reserved.
2  *
3  * This program and the accompanying materials are made available under
4  * the terms of the Common Public License v1.0 which accompanies this distribution,
5  * and is available at http://www.eclipse.org/legal/cpl-v10.html
6  *
7  * $Id: ByteArrayOStream.java,v 1.1.1.1 2004/05/09 16:57:52 vlad_r Exp $
8  */

9 package com.vladium.util;
10
11 import java.io.IOException JavaDoc;
12 import java.io.OutputStream JavaDoc;
13
14 import com.vladium.util.asserts.$assert;
15
16 // ----------------------------------------------------------------------------
17
/**
18  * An unsynchronized version of java.io.ByteArrayOutputStream that can expose
19  * the underlying byte array without a defensive clone and can also be converted
20  * to a {@link ByteArrayIStream} without intermediate array copies.<p>
21  *
22  * All argument validation is disabled in release mode.<p>
23  *
24  * NOTE: copy-on-write not supported
25  *
26  * @author (C) 2001, Vlad Roubtsov
27  */

28 public
29 final class ByteArrayOStream extends OutputStream JavaDoc
30 {
31     // public: ................................................................
32

33     /**
34      * Callee takes ownership of 'buf'.
35      */

36     public ByteArrayOStream (final int initialCapacity)
37     {
38         if ($assert.ENABLED)
39             $assert.ASSERT (initialCapacity >= 0, "negative initial capacity: " + initialCapacity);
40         
41         m_buf = new byte [initialCapacity];
42     }
43     
44     public final ByteArrayIStream toByteIStream ()
45     {
46         return new ByteArrayIStream (m_buf, m_pos);
47     }
48     
49     public final void write2 (final int b1, final int b2)
50     {
51         final int pos = m_pos;
52         final int capacity = pos + 2;
53         byte [] mbuf = m_buf;
54         final int mbuflen = mbuf.length;
55         
56         if (mbuflen < capacity)
57         {
58             final byte [] newbuf = new byte [Math.max (mbuflen << 1, capacity)];
59         
60             if (pos < NATIVE_COPY_THRESHOLD)
61                 for (int i = 0; i < pos; ++ i) newbuf [i] = mbuf [i];
62             else
63                 System.arraycopy (mbuf, 0, newbuf, 0, pos);
64             
65             m_buf = mbuf = newbuf;
66         }
67         
68         mbuf [pos] = (byte) b1;
69         mbuf [pos + 1] = (byte) b2;
70         m_pos = capacity;
71     }
72     
73     public final void write3 (final int b1, final int b2, final int b3)
74     {
75         final int pos = m_pos;
76         final int capacity = pos + 3;
77         byte [] mbuf = m_buf;
78         final int mbuflen = mbuf.length;
79         
80         if (mbuflen < capacity)
81         {
82             final byte [] newbuf = new byte [Math.max (mbuflen << 1, capacity)];
83         
84             if (pos < NATIVE_COPY_THRESHOLD)
85                 for (int i = 0; i < pos; ++ i) newbuf [i] = mbuf [i];
86             else
87                 System.arraycopy (mbuf, 0, newbuf, 0, pos);
88             
89             m_buf = mbuf = newbuf;
90         }
91         
92         mbuf [pos] = (byte) b1;
93         mbuf [pos + 1] = (byte) b2;
94         mbuf [pos + 2] = (byte) b3;
95         m_pos = capacity;
96     }
97     
98     public final void write4 (final int b1, final int b2, final int b3, final int b4)
99     {
100         final int pos = m_pos;
101         final int capacity = pos + 4;
102         byte [] mbuf = m_buf;
103         final int mbuflen = mbuf.length;
104         
105         if (mbuflen < capacity)
106         {
107             final byte [] newbuf = new byte [Math.max (mbuflen << 1, capacity)];
108         
109             if (pos < NATIVE_COPY_THRESHOLD)
110                 for (int i = 0; i < pos; ++ i) newbuf [i] = mbuf [i];
111             else
112                 System.arraycopy (mbuf, 0, newbuf, 0, pos);
113             
114             m_buf = mbuf = newbuf;
115         }
116         
117         mbuf [pos] = (byte) b1;
118         mbuf [pos + 1] = (byte) b2;
119         mbuf [pos + 2] = (byte) b3;
120         mbuf [pos + 3] = (byte) b4;
121         m_pos = capacity;
122     }
123     
124     public final void writeTo (final OutputStream JavaDoc out)
125         throws IOException JavaDoc
126     {
127         out.write (m_buf, 0, m_pos);
128     }
129     
130 // public final void readFully (final InputStream in)
131
// throws IOException
132
// {
133
// while (true)
134
// {
135
// int chunk = in.available ();
136
//
137
// System.out.println ("available = " + chunk);
138
//
139
// // TODO: this case is handled poorly (on EOF)
140
// if (chunk == 0) chunk = READ_CHUNK_SIZE;
141
//
142
// // read at least 'available' bytes: extend the capacity as needed
143
//
144
// int free = m_buf.length - m_pos;
145
//
146
// final int read;
147
// if (free > chunk)
148
// {
149
// // try reading more than 'chunk' anyway:
150
// read = in.read (m_buf, m_pos, free);
151
// }
152
// else
153
// {
154
// // extend the capacity to match 'chunk':
155
// {
156
// System.out.println ("reallocation");
157
// final byte [] newbuf = new byte [m_pos + chunk];
158
//
159
// if (m_pos < NATIVE_COPY_THRESHOLD)
160
// for (int i = 0; i < m_pos; ++ i) newbuf [i] = m_buf [i];
161
// else
162
// System.arraycopy (m_buf, 0, newbuf, 0, m_pos);
163
//
164
// m_buf = newbuf;
165
// }
166
//
167
// read = in.read (m_buf, m_pos, chunk);
168
// }
169
//
170
// if (read < 0)
171
// break;
172
// else
173
// m_pos += read;
174
// }
175
// }
176

177 // public final void addCapacity (final int extraCapacity)
178
// {
179
// final int pos = m_pos;
180
// final int capacity = pos + extraCapacity;
181
// byte [] mbuf = m_buf;
182
// final int mbuflen = mbuf.length;
183
//
184
// if (mbuflen < capacity)
185
// {
186
// final byte [] newbuf = new byte [Math.max (mbuflen << 1, capacity)];
187
//
188
// if (pos < NATIVE_COPY_THRESHOLD)
189
// for (int i = 0; i < pos; ++ i) newbuf [i] = mbuf [i];
190
// else
191
// System.arraycopy (mbuf, 0, newbuf, 0, pos);
192
//
193
// m_buf = newbuf;
194
// }
195
// }
196

197     public final byte [] getByteArray ()
198     {
199         return m_buf;
200     }
201
202     /**
203      *
204      * @return [result.length = size()]
205      */

206     public final byte [] copyByteArray ()
207     {
208         final int pos = m_pos;
209         
210         final byte [] result = new byte [pos];
211         final byte [] mbuf = m_buf;
212         
213         if (pos < NATIVE_COPY_THRESHOLD)
214             for (int i = 0; i < pos; ++ i) result [i] = mbuf [i];
215         else
216             System.arraycopy (mbuf, 0, result, 0, pos);
217         
218         return result;
219     }
220     
221     public final int size ()
222     {
223         return m_pos;
224     }
225     
226     public final int capacity ()
227     {
228         return m_buf.length;
229     }
230     
231     /**
232      * Does not reduce the current capacity.
233      */

234     public final void reset ()
235     {
236         m_pos = 0;
237     }
238     
239     // OutputStream:
240

241     public final void write (final int b)
242     {
243         final int pos = m_pos;
244         final int capacity = pos + 1;
245         byte [] mbuf = m_buf;
246         final int mbuflen = mbuf.length;
247         
248         if (mbuflen < capacity)
249         {
250             final byte [] newbuf = new byte [Math.max (mbuflen << 1, capacity)];
251             
252             if (pos < NATIVE_COPY_THRESHOLD)
253                 for (int i = 0; i < pos; ++ i) newbuf [i] = mbuf [i];
254             else
255                 System.arraycopy (mbuf, 0, newbuf, 0, pos);
256             
257             m_buf = mbuf = newbuf;
258         }
259         
260         mbuf [pos] = (byte) b;
261         m_pos = capacity;
262     }
263
264
265     public final void write (final byte [] buf, final int offset, final int length)
266     {
267         if ($assert.ENABLED)
268             $assert.ASSERT ((offset >= 0) && (offset <= buf.length) &&
269                 (length >= 0) && ((offset + length) <= buf.length),
270                 "invalid input (" + buf.length + ", " + offset + ", " + length + ")");
271         
272         final int pos = m_pos;
273         final int capacity = pos + length;
274         byte [] mbuf = m_buf;
275         final int mbuflen = mbuf.length;
276         
277         if (mbuflen < capacity)
278         {
279             final byte [] newbuf = new byte [Math.max (mbuflen << 1, capacity)];
280             
281             if (pos < NATIVE_COPY_THRESHOLD)
282                 for (int i = 0; i < pos; ++ i) newbuf [i] = mbuf [i];
283             else
284                 System.arraycopy (mbuf, 0, newbuf, 0, pos);
285             
286             m_buf = mbuf = newbuf;
287         }
288         
289         if (length < NATIVE_COPY_THRESHOLD)
290             for (int i = 0; i < length; ++ i) mbuf [pos + i] = buf [offset + i];
291         else
292             System.arraycopy (buf, offset, mbuf, pos, length);
293             
294         m_pos = capacity;
295     }
296
297     
298     /**
299      * Equivalent to {@link #reset()}.
300      */

301     public final void close ()
302     {
303         reset ();
304     }
305     
306     // protected: .............................................................
307

308     // package: ...............................................................
309

310     // private: ...............................................................
311

312     
313     private byte [] m_buf;
314     private int m_pos;
315     
316 // private static final int READ_CHUNK_SIZE = 16 * 1024;
317
private static final int NATIVE_COPY_THRESHOLD = 9;
318
319 } // end of class
320
// ----------------------------------------------------------------------------
Popular Tags