Logo
Distributed Genetic Programming Framework
print print

File org.sfc.io.block.BlockInputStream.java

Here you can find all the information about the file org.sfc.io.block.BlockInputStream.java. You may explore it here or download it onto your local disk.
/*
 * Copyright (c) 2006 Thomas Weise
 * 
 * E-Mail           : tweise@gmx.de
 * Creation Date    : 2006-06-27 18:18:01
 * Original Filename: org.sfc.io.block.BlockInputStream.java
 * Version          : 1.0.0
 * Last modification: 2006-06-27
 *                by: Thomas Weise
 * 
 * License          : GNU LESSER GENERAL PUBLIC LICENSE
 *                    Version 2.1, February 1999
 *                    You should have received a copy of this license along
 *                    with this library; if not, write to the Free Software
 *                    Foundation, Inc., 59 Temple Place, Suite 330, Boston,
 *                    MA 02111-1307, USA or download the license under
 *                    http://www.gnu.org/copyleft/lesser.html.
 *                    
 * Warranty         : This software is provided "as is" without any
 *                    warranty; without even the implied warranty of
 *                    merchantability or fitness for a particular purpose.
 *                    See the Gnu Lesser General Public License for more
 *                    details.
 */

 
package org.sfc.io.block;

import java.io.IOException;
import java.io.InputStream;

import org.sfc.io.ReferenceCountedInputStream;

/**
 * A block data input stream degroups blocks read from a source into stream
 * data that can be read sequentially.
 *
 * @author Thomas Weise
 */

public   class BlockInputStream  extends ReferenceCountedInputStream
  {
/**
 * The source input stream.
 */

  private final InputStream   m_in     ;
/**
 * The input buffer.
 */

  private final byte[]        m_buffer  ;
/**
 * The current position in the output data.
 */

  private       int           m_pos    ;
/**
 * The count of bytes available.
 */

  private       int           m_available ;
/**
 * The next byte.
 */

  private       int           m_next;
  
/**
 * 0 = first read, 1 = open, 2 = closed 
 */

  private       byte          m_state ;
  
/**
 * The block handler interface to delegate to.
 */

  private final IBlockHandler m_handler ;
  
/**
 * Create a new block data input stream.
 * @param p_in          The input stream to read from.
 * @param p_block_size  The block size to use for reading.
 * @param p_handler     The block handler interface to delegate to.
 */

  public  BlockInputStream  (final InputStream   p_in,
                             final int           p_block_size,
                             final IBlockHandler p_handler)
    {
    super();
    this.m_buffer  = new byte[(p_block_size > 0) ? p_block_size : 1];
    this.m_handler = p_handler;
    this.m_in      = p_in;
    }
  
/**
 * Fill the internal buffer.
 * @param p_b The buffer to fill.
 * @return  <code>true</code> if data became available, <code>false</code>
 *          otherwise.
 * @throws  IOException if something fails.
 */

  private final boolean fill_buffer (final byte[] p_b) throws IOException
    {
    int  l_l, l_b;
    byte l_s;    
    
    if((l_s = this.m_state) > 1) return false;
    
    this.m_pos = 0;
    
    l_l = p_b.length;
    l_b = this.m_next;
        
    if(l_s > 0)
      {
      p_b[0] = ((byte)l_b);
      l_b    = (this.m_in.read(p_b, 1, l_l-1)+1);
      }
    else
      {
      l_b          = this.m_in.read(p_b, 0, l_l);
      this.m_state = 1;
      }
    
    if(l_b < l_l)
      {
      this.m_available = 0;
      return false;
      }
    
    this.m_handler.on_block(p_b);
        
    l_b = this.m_in.read();
    if(l_b < 0)
      {
      for(--l_l; l_l >= 0; l_l--)
        {
        if(p_b[l_l] == BlockOutputStream.END_MARK) break;
        }
      
      this.m_available = l_l;
      this.m_state     = 2;
      
      return (l_l > 0);
      }
    
    this.m_available = l_l;
    this.m_next      = l_b;
    return true;
    }
  
  
/**
 * Reads up to <code>len</code> bytes of data from the input stream into
 * an array of bytes.  An attempt is made to read as many as
 * <code>len</code> bytes, but a smaller number may be read.
 * The number of bytes actually read is returned as an integer.
 *
 * <p> This method blocks until input data is available, end of file is
 * detected, or an exception is thrown.
 *
 * <p> If <code>b</code> is <code>null</code>, a
 * <code>NullPointerException</code> is thrown.
 *
 * <p> If <code>off</code> is negative, or <code>len</code> is negative, or
 * <code>off+len</code> is greater than the length of the array
 * <code>b</code>, then an <code>IndexOutOfBoundsException</code> is
 * thrown.
 *
 * <p> If <code>len</code> is zero, then no bytes are read and
 * <code>0</code> is returned; otherwise, there is an attempt to read at
 * least one byte. If no byte is available because the stream is at end of
 * file, the value <code>-1</code> is returned; otherwise, at least one
 * byte is read and stored into <code>b</code>.
 *
 * <p> The first byte read is stored into element <code>b[off]</code>, the
 * next one into <code>b[off+1]</code>, and so on. The number of bytes read
 * is, at most, equal to <code>len</code>. Let <i>k</i> be the number of
 * bytes actually read; these bytes will be stored in elements
 * <code>b[off]</code> through <code>b[off+</code><i>k</i><code>-1]</code>,
 * leaving elements <code>b[off+</code><i>k</i><code>]</code> through
 * <code>b[off+len-1]</code> unaffected.
 *
 * <p> In every case, elements <code>b[0]</code> through
 * <code>b[off]</code> and elements <code>b[off+len]</code> through
 * <code>b[b.length-1]</code> are unaffected.
 *
 * <p> If the first byte cannot be read for any reason other than end of
 * file, then an <code>IOException</code> is thrown. In particular, an
 * <code>IOException</code> is thrown if the input stream has been closed.
 *
 * <p> The <code>read(b,</code> <code>off,</code> <code>len)</code> method
 * for class <code>InputStream</code> simply calls the method
 * <code>read()</code> repeatedly. If the first such call results in an
 * <code>IOException</code>, that exception is returned from the call to
 * the <code>read(b,</code> <code>off,</code> <code>len)</code> method.  If
 * any subsequent call to <code>read()</code> results in a
 * <code>IOException</code>, the exception is caught and treated as if it
 * were end of file; the bytes read up to that point are stored into
 * <code>b</code> and the number of bytes read before the exception
 * occurred is returned.  Subclasses are encouraged to provide a more
 * efficient implementation of this method.
 *
 * @param      p_b     the buffer into which the data is read.
 * @param      p_off   the start offset in array <code>b</code>
 *                   at which the data is written.
 * @param      p_len   the maximum number of bytes to read.
 * @return     the total number of bytes read into the buffer, or
 *             <code>-1</code> if there is no more data because the end of
 *             the stream has been reached.
 * @exception  IOException  if an I/O error occurs.
 * @exception  NullPointerException  if <code>b</code> is <code>null</code>.
 * @see        java.io.InputStream#read()
 */

  @Override
  public final  int read(final  byte[] p_b,
                                int    p_off,
                                int    p_len) throws IOException
    { 
    int     l_r, l_s;
    byte[]  l_b;
    
    if(p_len <= 0) return 0;
    
    l_b = this.m_buffer;
    l_s = 0;
    while(p_len > 0)
      {
      l_r = this.m_available;
      if(l_r > p_len) l_r = p_len;
      System.arraycopy(l_b, this.m_pos, p_b, p_off, l_r);
      
      l_s   += l_r;
            
      if((this.m_available -= l_r) <= 0)
        {
        if(!(this.fill_buffer(l_b))) break;
        }
      else
        {
        this.m_pos += l_r;
        break;
        }
      
      p_off += l_r;
      p_len -= l_r;      
      }
    
    return ((l_s > 0) ? l_s : -1);
    }
  
/**
 * Reads the next byte of data from the input stream. The value byte is
 * returned as an <code>int</code> in the range <code>0</code> to
 * <code>255</code>. If no byte is available because the end of the stream
 * has been reached, the value <code>-1</code> is returned. This method
 * blocks until input data is available, the end of the stream is detected,
 * or an exception is thrown.
 *
 * <p> A subclass must provide an implementation of this method.
 *
 * @return     the next byte of data, or <code>-1</code> if the end of the
 *             stream is reached.
 * @exception  IOException  if an I/O error occurs.
 */

  @Override
  public final int read() throws IOException
    {
    byte[]  l_b;
    byte    l_r;
    
    l_b = this.m_buffer;
    if( (this.m_available > 0) || this.fill_buffer(l_b) )
      {
      l_r = l_b[this.m_pos++];
      if( (--this.m_available) <= 0 ) this.fill_buffer(l_b);
      return l_r;
      }
    
    return -1;
    }
  }

File Information:

file name:BlockInputStream.java
package:org.sfc.io.block
qualified name:org.sfc.io.block.BlockInputStream.java
file type:Java Source File
download location:download http://dgpf.sourceforge.net/source/org/sfc/io/block/BlockInputStream.java
size:8.826 KB (9038 B)
uploaded: 2015-07-22 04:11:12 GMT+0000
last update: 2006-06-30 04:38:57 GMT+0000
last access: 2018-01-23 19:23:04 GMT+0000

statistics online since 2006-01-02.   RSS Feed
Contact us by sending an email to tweise@gmx.de to receive further information, to report errors, or to join our project.
All content on this site (http://dgpf.sourceforge.net/) is LGPL-licensed.
http://dgpf.sourceforge.net/scripts/source/source.php last modified at 2015-07-22 04:10:53 GMT+0000 served at 2018-01-23 19:23:04 GMT+0000.
Valid CSS Valid XHTML 1.1
Valid RSS SourceForge.net Logo