1 /**********************************************************************
2 * ChannelOutputStream.java
3 * created on 16.08.2004 by netseeker
4 * $Source: /cvsroot/ejoe/EJOE/src/de/netseeker/ejoe/io/ByteBufferOutputStream.java,v $
5 * $Date: 2007/11/17 10:57:03 $
6 * $Revision: 1.19 $
7 *
8 * ====================================================================
9 *
10 * Copyright 2005-2006 netseeker aka Michael Manske
11 *
12 * Licensed under the Apache License, Version 2.0 (the "License");
13 * you may not use this file except in compliance with the License.
14 * You may obtain a copy of the License at
15 *
16 * http://www.apache.org/licenses/LICENSE-2.0
17 *
18 * Unless required by applicable law or agreed to in writing, software
19 * distributed under the License is distributed on an "AS IS" BASIS,
20 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
21 * See the License for the specific language governing permissions and
22 * limitations under the License.
23 * ====================================================================
24 *
25 * This file is part of the ejoe framework.
26 * For more information on the author, please see
27 * <http://www.manskes.de/>.
28 *
29 *********************************************************************/
30
31 package de.netseeker.ejoe.io;
32
33 import java.io.IOException;
34 import java.io.OutputStream;
35 import java.nio.ByteBuffer;
36
37 import de.netseeker.ejoe.EJConstants;
38 import de.netseeker.ejoe.cache.ByteBufferAllocator;
39
40 /***
41 * Implements an input stream for a NIO ByteBuffer. This class is based on an article found at the homepage of Michael
42 * W. Spille.
43 *
44 * @author Michael W. Spille
45 * @author netseeker aka Michael Manske
46 * @link http://www.krisnmike.com/mike/nio.html
47 * @since 0.3.0
48 */
49 public class ByteBufferOutputStream extends OutputStream
50 {
51 private ByteBuffer buffer;
52
53 private boolean _closed = false;
54
55 /***
56 *
57 */
58 public ByteBufferOutputStream()
59 {
60 this( EJConstants.NIO_BYTEBUFFER_STREAM_SIZE );
61 }
62
63 /***
64 * @param startingSize
65 */
66 public ByteBufferOutputStream(int startingSize)
67 {
68 buffer = ByteBufferAllocator.allocate( startingSize, true );
69 }
70
71 /***
72 * @param buffer
73 */
74 public ByteBufferOutputStream(ByteBuffer buffer)
75 {
76 this.buffer = buffer;
77 }
78
79 /***
80 * Reset the underlying byte buffer back to the starting state
81 */
82 public void reset()
83 {
84 if ( _closed ) throw new IllegalStateException( "This stream was already closed!" );
85 buffer.clear();
86 }
87
88 /***
89 * @return
90 */
91 public ByteBuffer getBackingBuffer()
92 {
93 if ( _closed ) throw new IllegalStateException( "This stream was already closed!" );
94 return (buffer);
95 }
96
97
98
99
100
101
102 public void write( int b ) throws IOException
103 {
104 if ( _closed ) throw new IllegalStateException( "This stream was already closed!" );
105 if ( !buffer.hasRemaining() )
106 {
107 realloc( buffer.limit() + EJConstants.NIO_BYTEBUFFER_STREAM_SIZE );
108 }
109 buffer.put( (byte) b );
110 }
111
112
113
114
115
116
117 public void write( byte[] b ) throws IOException
118 {
119 if ( _closed ) throw new IllegalStateException( "This stream was already closed!" );
120 if ( buffer.remaining() < b.length )
121 {
122 realloc( buffer.limit() + (b.length - buffer.remaining()) + EJConstants.NIO_BYTEBUFFER_STREAM_SIZE );
123 }
124 buffer.put( b );
125 }
126
127
128
129
130
131
132 public void write( byte[] b, int off, int len )
133 {
134 if ( _closed ) throw new IllegalStateException( "This stream was already closed!" );
135 if ( buffer.remaining() < len )
136 {
137 realloc( buffer.limit() + (len - buffer.remaining()) + EJConstants.NIO_BYTEBUFFER_STREAM_SIZE );
138 }
139 buffer.put( b, off, len );
140 }
141
142 /***
143 * @param b
144 */
145 public void write( ByteBuffer b )
146 {
147 if ( _closed ) throw new IllegalStateException( "This stream was already closed!" );
148 if ( buffer.remaining() < b.remaining() )
149 {
150 realloc( buffer.limit() + (b.remaining() - buffer.remaining()) + EJConstants.NIO_BYTEBUFFER_STREAM_SIZE );
151 }
152 buffer.put( b );
153 }
154
155 public void putInt( int i )
156 {
157 if ( _closed ) throw new IllegalStateException( "This stream was already closed!" );
158 if ( buffer.remaining() < 4 )
159 {
160 realloc( buffer.limit() + (4 - buffer.remaining()) + EJConstants.NIO_BYTEBUFFER_STREAM_SIZE );
161 }
162
163 buffer.putInt( i );
164 }
165
166 private void realloc( int newSize )
167 {
168 ByteBuffer newOutBytes = ByteBufferAllocator.allocate( newSize, true );
169
170 buffer.flip();
171 newOutBytes.put( buffer );
172 buffer = newOutBytes;
173 }
174
175
176
177
178
179
180 public void flush()
181 {
182 if ( _closed ) throw new IllegalStateException( "This stream was already closed!" );
183 }
184
185
186
187
188
189
190 public void close() throws IOException
191 {
192 _closed = true;
193 }
194 }