All Downloads are FREE. Search and download functionalities are using the official Maven repository.

org.refcodes.serial.SequenceInputStream Maven / Gradle / Ivy

Go to download

Artifact providing generic (byte) serialization functionality including a TTY-/COM-Port implementation of the serial framework as well as a (local) loopback port.

The newest version!
// /////////////////////////////////////////////////////////////////////////////
// REFCODES.ORG
// /////////////////////////////////////////////////////////////////////////////
// This code is copyright (c) by Siegfried Steiner, Munich, Germany, distributed
// on an "AS IS" BASIS WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, and licen-
// sed under the following (see "http://en.wikipedia.org/wiki/Multi-licensing")
// licenses:
// -----------------------------------------------------------------------------
// GNU General Public License, v3.0 ("http://www.gnu.org/licenses/gpl-3.0.html")
// -----------------------------------------------------------------------------
// Apache License, v2.0 ("http://www.apache.org/licenses/TEXT-2.0")
// -----------------------------------------------------------------------------
// Please contact the copyright holding author(s) of the software artifacts in
// question for licensing issues not being covered by the above listed licenses,
// also regarding commercial licensing models or regarding the compatibility
// with other open source licenses.
// /////////////////////////////////////////////////////////////////////////////

package org.refcodes.serial;

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

import org.refcodes.mixin.OffsetAccessor;

/**
 * The {@link SequenceInputStream} constructs an {@link InputStream} from a
 * {@link Sequence}.
 */
public class SequenceInputStream extends InputStream implements OffsetAccessor, SequenceAccessor {

	// /////////////////////////////////////////////////////////////////////////
	// VARIABLES:
	// /////////////////////////////////////////////////////////////////////////

	private final Sequence _sequence;
	boolean _isClosed = false;
	private int _offset = 0;

	// /////////////////////////////////////////////////////////////////////////
	// CONSTRUCTORS:
	// /////////////////////////////////////////////////////////////////////////

	/**
	 * Uses the provided {@link Sequence} to provide {@link InputStream}
	 * functionality.
	 * 
	 * @param aSequence The {@link Sequence} to use.
	 */
	public SequenceInputStream( Sequence aSequence ) {
		_sequence = aSequence;
	}

	/**
	 * Uses the provided {@link Sequence} to provide {@link InputStream}
	 * functionality.
	 * 
	 * @param aSequence The {@link Sequence} to use.
	 * @param aOffset The offset in the {@link Sequence} from where to start.
	 */
	public SequenceInputStream( Sequence aSequence, int aOffset ) {
		_sequence = aSequence;
		_offset = aOffset;
	}

	// /////////////////////////////////////////////////////////////////////////
	// METHODS:
	// /////////////////////////////////////////////////////////////////////////

	/**
	 * {@inheritDoc}
	 */
	@Override
	public int available() throws IOException {
		if ( _isClosed ) {
			throw new IOException( "The stream has already been closed!" );
		}
		return _sequence.getLength();
	}

	/**
	 * {@inheritDoc}
	 */
	@Override
	public void close() throws IOException {
		_isClosed = true;
		super.close();
		// _sequence = null;
	}

	/**
	 * {@inheritDoc}
	 */
	@Override
	public int read() throws IOException {
		if ( _isClosed ) {
			throw new IOException( "The stream has already been closed!" );
		}
		if ( _sequence.getLength() == _offset && !_isClosed ) {
			// while ( _sequence.getLength() == 0 && !_isClosed ) {
			//	synchronized ( _sequence ) {
			//		try {
			//			wait( DaemonLoopSleepTime.MAX.getMillis() );
			//		}
			//		catch ( InterruptedException ignore ) {}
			//	}
			return -1;
		}
		synchronized ( _sequence ) {
			if ( _sequence.getLength() == _offset ) {
				if ( _isClosed ) {
					throw new IOException( "Connection is closed and only <" + _sequence.getLength() + "> bytes out of requested <" + 1 + "> bytes are available!" );
				}
				throw new IndexOutOfBoundsException( "Only <" + _sequence.getLength() + "> bytes out of requested <" + 1 + "> bytes are available!" );
			}
			final int theValue = _sequence.getByteAt( _offset );
			_offset++;
			return theValue;
		}
	}

	/**
	 * {@inheritDoc}
	 */
	@Override
	public int read( byte[] aChunk, int aOffset, int aLength ) throws IOException {
		if ( _isClosed ) {
			throw new IOException( "The stream has already been closed!" );
		}
		synchronized ( _sequence ) {
			if ( _sequence.getLength() < _offset + aLength ) {
				aLength = _sequence.getLength();
			}
			_sequence.toBytes( _offset, aLength, aChunk, aOffset );
			_offset += aLength;
			return aLength;
		}
	}

	/**
	 * {@inheritDoc}
	 */
	@Override
	public int getOffset() {
		return _offset;
	}

	/**
	 * {@inheritDoc} ATTENTION: The original {@link Sequence} including the read
	 * bytes is returned, use the {@link #getOffset()} method to access those
	 * bytes not yet being read!
	 */
	@Override
	public Sequence getSequence() {
		return _sequence;
	}
}




© 2015 - 2025 Weber Informatics LLC | Privacy Policy