View Javadoc

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       * (non-Javadoc)
99       * 
100      * @see java.io.OutputStream#write(int)
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      * (non-Javadoc)
114      * 
115      * @see java.io.OutputStream#write(byte[])
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      * (non-Javadoc)
129      * 
130      * @see java.io.OutputStream#write(byte[], int, int)
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         //newOutBytes.clear();
170         buffer.flip();
171         newOutBytes.put( buffer );
172         buffer = newOutBytes;
173     }
174 
175     /*
176      * (non-Javadoc)
177      * 
178      * @see java.io.OutputStream#flush()
179      */
180     public void flush()
181     {
182         if ( _closed ) throw new IllegalStateException( "This stream was already closed!" );
183     }
184 
185     /*
186      * (non-Javadoc)
187      * 
188      * @see java.io.OutputStream#close()
189      */
190     public void close() throws IOException
191     {
192         _closed = true;
193     }
194 }