// ConcurrentBufferInputStream.java -- read bytes from blocking queue // Copyright (c)2007 Christopher League <league@contrapunctus.net> // This is free software, but it comes with ABSOLUTELY NO WARRANTY. // GNU Lesser General Public License 2.1 or Common Public License 1.0 package net.contrapunctus.lzma; import java.io.BufferedInputStream; import java.io.IOException; import java.io.InputStream; import java.io.InterruptedIOException; import java.io.PrintStream; import java.util.concurrent.ArrayBlockingQueue; class ConcurrentBufferInputStream extends InputStream { protected ArrayBlockingQueue<byte[]> q; protected byte[] buf = null; protected int next = 0; protected boolean eof = false; private static final PrintStream dbg = System.err; private static final boolean DEBUG; static { String ds = null; try { ds = System.getProperty("DEBUG_ConcurrentBuffer"); } catch(SecurityException e) { } DEBUG = ds != null; } private ConcurrentBufferInputStream( ArrayBlockingQueue<byte[]> q ) { if(DEBUG) dbg.printf("%s << %s%n", this, q); this.q = q; this.eof = false; } static InputStream create( ArrayBlockingQueue<byte[]> q ) { InputStream in = new ConcurrentBufferInputStream( q ); return in; } protected byte[] guarded_take( ) throws IOException { try { return q.take( ); } catch( InterruptedException exn ) { throw new InterruptedIOException( exn.getMessage() ); } } protected boolean prepareAndCheckEOF( ) throws IOException { if( eof ) return true; if( buf == null || next >= buf.length ) { buf = guarded_take( ); next = 0; if( buf.length == 0 ) { eof = true; return true; } } return false; } public int read( ) throws IOException { if( prepareAndCheckEOF() ) { return -1; } int x = buf[next]; next++; return x & 0xff; } public int read( byte[] b, int off, int len ) throws IOException { if( prepareAndCheckEOF() ) { return -1; } int k = buf.length - next; if( len < k ) { k = len; } System.arraycopy( buf, next, b, off, k ); next += k; return k; } public String toString( ) { return String.format("cbIn@%x", hashCode()); } }