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

org.refcodes.serial.ext.handshake.AcknowledgeMessage Maven / Gradle / Ivy

Go to download

The refcodes-serial-ext-handshake artifact extends the refcodes-serial artifact with handshake functionality.

The newest version!
/*
 * 
 */
package org.refcodes.serial.ext.handshake;

import static org.refcodes.serial.SerialSugar.*;

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

import org.refcodes.serial.AssertMagicBytesSegment;
import org.refcodes.serial.Segment;
import org.refcodes.serial.Sequence;
import org.refcodes.serial.SequenceNumberSegment;
import org.refcodes.serial.SerialSchema;
import org.refcodes.serial.TransmissionException;
import org.refcodes.struct.SimpleTypeMap;
import org.refcodes.struct.SimpleTypeMapImpl;

/**
 * A {@link AcknowledgeMessage} represents a {@link Segment} consisting of magic
 * bytes and providing a sequence number covered by a CRC checksum acknowledging
 * transmission receival.
 */
class AcknowledgeMessage implements HandshakeMessage, AcknowledgeTypeAccessor {

	// /////////////////////////////////////////////////////////////////////////
	// STATICS:
	// /////////////////////////////////////////////////////////////////////////

	private static final long serialVersionUID = 1L;

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

	protected Segment _delegatee = null;
	private SequenceNumberSegment _sequenceNumberSegment;
	private AssertMagicBytesSegment _assertMagicBytesSegment;
	private HandshakeTransmissionMetrics _transmissionMetrics;

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

	/**
	 * Instantiates a new {@link AcknowledgeMessage} for the given sequence
	 * number.
	 * 
	 * @param aAcknowledgeType The {@link AcknowledgeType} identifying the
	 *        message.
	 * @param aSequenceNumber The sequence number to be assigned to the
	 *        {@link AcknowledgeMessage}.
	 */
	public AcknowledgeMessage( AcknowledgeType aAcknowledgeType, int aSequenceNumber ) {
		this( aAcknowledgeType, aSequenceNumber, new HandshakeTransmissionMetrics() );
	}

	/**
	 * Instantiates a new {@link AcknowledgeMessage} for the given sequence
	 * number.
	 * 
	 * @param aAcknowledgeType The {@link AcknowledgeType} identifying the
	 *        message.
	 * @param aSequenceNumber The sequence number to be assigned to the
	 *        {@link AcknowledgeMessage}.
	 * @param aTransmissionMetrics The {@link HandshakeTransmissionMetrics} to
	 *        use.
	 */
	public AcknowledgeMessage( AcknowledgeType aAcknowledgeType, int aSequenceNumber, HandshakeTransmissionMetrics aTransmissionMetrics ) {
		aTransmissionMetrics = aTransmissionMetrics != null ? aTransmissionMetrics : new HandshakeTransmissionMetrics();
		// @formatter:off
		_delegatee = segmentComposite(  
			crcSegment(
				segmentComposite(
					_assertMagicBytesSegment = assertMagicBytesSegment(  aTransmissionMetrics.toMagicBytes( aAcknowledgeType ), aTransmissionMetrics ), _sequenceNumberSegment = sequenceNumberSegment( aSequenceNumber, aTransmissionMetrics ) 
				), 
				aTransmissionMetrics
			)
		);
		// @formatter:on
		_transmissionMetrics = aTransmissionMetrics;
	}

	/**
	 * Instantiates a new {@link AcknowledgeMessage}.
	 *
	 * @param aAcknowledgeType the magic bytes
	 */
	public AcknowledgeMessage( AcknowledgeType aAcknowledgeType ) {
		this( aAcknowledgeType, -1, new HandshakeTransmissionMetrics() );
	}

	/**
	 * Instantiates a new {@link AcknowledgeMessage}.
	 * 
	 * @param aAcknowledgeType The magic bytes identifying the acknowledge
	 *        message.
	 * @param aTransmissionMetrics The {@link HandshakeTransmissionMetrics} to
	 *        use.
	 */
	public AcknowledgeMessage( AcknowledgeType aAcknowledgeType, HandshakeTransmissionMetrics aTransmissionMetrics ) {
		this( aAcknowledgeType, -1, aTransmissionMetrics );
	}

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

	/**
	 * {@inheritDoc}
	 */
	@Override
	public int getLength() {
		return _delegatee.getLength();
	}

	/**
	 * {@inheritDoc}
	 */
	@Override
	public void reset() {
		_assertMagicBytesSegment.reset();
		_delegatee.reset();
		_sequenceNumberSegment.reset();
	}

	/**
	 * {@inheritDoc}
	 */
	@Override
	public Sequence toSequence() {
		return _delegatee.toSequence();
	}

	/**
	 * {@inheritDoc}
	 */
	@Override
	public String toString() {
		return getClass().getSimpleName() + " [segment=" + _delegatee + "]";
	}

	/**
	 * {@inheritDoc}
	 */
	@Override
	public SimpleTypeMap toSimpleTypeMap() {
		return _delegatee != null ? _delegatee.toSimpleTypeMap() : new SimpleTypeMapImpl();
	}

	/**
	 * {@inheritDoc}
	 */
	@Override
	public void transmitTo( OutputStream aOutputStream, InputStream aReturnStream ) throws IOException {
		_delegatee.transmitTo( aOutputStream, aReturnStream );
	}

	/**
	 * {@inheritDoc}
	 */
	@Override
	public SerialSchema toSchema() {
		return _delegatee.toSchema();
	}

	/**
	 * {@inheritDoc}
	 */
	@Override
	public int fromTransmission( Sequence aSequence, int aOffset ) throws TransmissionException {
		return _delegatee.fromTransmission( aSequence, aOffset );
	}

	/**
	 * {@inheritDoc}
	 */
	@Override
	public void receiveFrom( InputStream aInputStream, OutputStream aReturnStream ) throws IOException {
		_delegatee.receiveFrom( aInputStream, aReturnStream );

	}

	/**
	 * {@inheritDoc}
	 */
	@Override
	public int getSequenceNumber() {
		return _sequenceNumberSegment != null ? ( _sequenceNumberSegment.getValue() != null ? _sequenceNumberSegment.getValue().intValue() : -1 ) : -1;
	}

	/**
	 * {@inheritDoc}
	 */
	@Override
	public byte[] getMagicBytes() {
		return _assertMagicBytesSegment.getMagicBytes();
	}

	/**
	 * {@inheritDoc}
	 */
	@Override
	public int hashCode() {
		final int prime = 31;
		int result = 1;
		result = prime * result + ( ( _delegatee == null ) ? 0 : _delegatee.hashCode() );
		return result;
	}

	/**
	 * {@inheritDoc}
	 */
	@Override
	public boolean equals( Object obj ) {
		if ( this == obj ) {
			return true;
		}
		if ( obj == null ) {
			return false;
		}
		if ( getClass() != obj.getClass() ) {
			return false;
		}
		final AcknowledgeMessage other = (AcknowledgeMessage) obj;
		if ( _delegatee == null ) {
			if ( other._delegatee != null ) {
				return false;
			}
		}
		else if ( !_delegatee.equals( other._delegatee ) ) {
			return false;
		}
		return true;
	}

	/**
	 * {@inheritDoc}
	 */
	@Override
	public AcknowledgeType getAcknowledgeType() {
		return _transmissionMetrics.toAcknowledgeType( _assertMagicBytesSegment.getMagicBytes() );
	}

	// /////////////////////////////////////////////////////////////////////////
	// HELPER:
	// /////////////////////////////////////////////////////////////////////////
}




© 2015 - 2025 Weber Informatics LLC | Privacy Policy