View Javadoc

1   /***
2    * Redistribution  and use  in source  and binary  forms, with  or without
3    * modification, are permitted provided  that the following conditions are
4    * met :
5    *
6    * . Redistributions  of  source  code  must  retain  the  above copyright
7    *   notice, this list of conditions and the following disclaimer.
8    *
9    * . Redistributions in  binary form  must reproduce  the above  copyright
10   *   notice, this list of conditions  and the following disclaimer in  the
11   *   documentation and/or other materials provided with the distribution.
12   *
13   * . The name of the author may not be used to endorse or promote products
14   *   derived from this software without specific prior written permission.
15   *
16   * THIS SOFTWARE IS  PROVIDED BY THE  AUTHOR ``AS IS''  AND ANY EXPRESS  OR
17   * IMPLIED  WARRANTIES,  INCLUDING,  BUT   NOT  LIMITED  TO,  THE   IMPLIED
18   * WARRANTIES OF MERCHANTABILITY AND  FITNESS FOR A PARTICULAR  PURPOSE ARE
19   * DISCLAIMED.  IN NO  EVENT SHALL  THE AUTHOR  BE LIABLE  FOR ANY  DIRECT,
20   * INDIRECT,  INCIDENTAL,  SPECIAL,  EXEMPLARY,  OR  CONSEQUENTIAL  DAMAGES
21   * (INCLUDING,  BUT  NOT LIMITED  TO,  PROCUREMENT OF  SUBSTITUTE  GOODS OR
22   * SERVICES;  LOSS  OF USE,  DATA,  OR PROFITS;  OR  BUSINESS INTERRUPTION)
23   * HOWEVER CAUSED  AND ON  ANY THEORY  OF LIABILITY,  WHETHER IN  CONTRACT,
24   * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
25   * ANY  WAY  OUT OF  THE  USE OF  THIS  SOFTWARE, EVEN  IF  ADVISED OF  THE
26   * POSSIBILITY OF SUCH DAMAGE.
27   *
28   * $Id$
29   */
30  
31  package palmed.edit.text;
32  
33  import java.io.IOException;
34  import java.io.InputStream;
35  
36  /***
37   * This class provides a means to split a stream into chunks.
38   *
39   * @author Mathieu Champlon
40   * @version $Revision$ $Date$
41   */
42  public final class MultiInputStream extends InputStream
43  {
44      /***
45       * The underlying stream.
46       */
47      private final InputStream stream_;
48      /***
49       * The size of each chunk.
50       */
51      private final int size_;
52      /***
53       * The remaining number of bytes in the current chunk.
54       */
55      private int remaining_;
56  
57      /***
58       * Create a multi input stream.
59       *
60       * @param stream the stream
61       * @param size the size of each chunk
62       */
63      public MultiInputStream( final InputStream stream, final int size )
64      {
65          if( stream == null )
66              throw new IllegalArgumentException( "parameter 'stream' is null" );
67          if( size <= 0 )
68              throw new IllegalArgumentException( "parameter 'size' must be > 0" );
69          stream_ = stream;
70          size_ = size;
71          remaining_ = size;
72      }
73  
74      /***
75       * {@inheritDoc}
76       */
77      public int read() throws IOException
78      {
79          if( remaining_ == 0 )
80              return -1;
81          final int b = stream_.read();
82          if( b == -1 )
83              return -1;
84          --remaining_;
85          return b;
86      }
87  
88      /***
89       * {@inheritDoc}
90       */
91      public int read( final byte[] b ) throws IOException
92      {
93          return read( b, 0, b.length );
94      }
95  
96      /***
97       * {@inheritDoc}
98       */
99      public int read( final byte[] b, final int off, final int len ) throws IOException
100     {
101         if( remaining_ == 0 )
102             return -1;
103         final int read = stream_.read( b, off, Math.min( remaining_, len ) );
104         if( read == -1 )
105             return -1;
106         remaining_ -= read;
107         return read;
108     }
109 
110     /***
111      * {@inheritDoc}
112      */
113     public int available() throws IOException
114     {
115         return Math.min( remaining_, stream_.available() );
116     }
117 
118     /***
119      * {@inheritDoc}
120      */
121     public void close() throws IOException
122     {
123         stream_.close();
124     }
125 
126     /***
127      * {@inheritDoc}
128      */
129     public boolean markSupported()
130     {
131         return false;
132     }
133 
134     /***
135      * Move to next chunk.
136      */
137     public void next()
138     {
139         remaining_ = size_;
140     }
141 }