
org.refcodes.serial.AsciizArraySegment Maven / Gradle / Ivy
Go to download
Show more of this group Show more artifacts with this name
Show all versions of refcodes-serial Show documentation
Show all versions of refcodes-serial Show documentation
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 java.io.OutputStream;
import org.refcodes.numerical.Endianess;
import org.refcodes.numerical.EndianessAccessor;
import org.refcodes.struct.SimpleTypeMap;
import org.refcodes.struct.SimpleTypeMapBuilderImpl;
import org.refcodes.textual.CaseStyleBuilder;
import org.refcodes.textual.VerboseTextBuilder;
/**
* The {@link AsciizArraySegment} is an implementation of a {@link Section}
* carrying a {@link String} array as payload. Each {@link String} is
* represented by a {@link String} decorated by an
* {@link AllocSectionDecoratorSegment}.
*/
public class AsciizArraySegment extends AbstractPayloadSegment implements LengthWidthAccessor, EndianessAccessor, EndOfStringByteAccessor {
// /////////////////////////////////////////////////////////////////////////
// STATICS:
// /////////////////////////////////////////////////////////////////////////
private static final long serialVersionUID = 1L;
// /////////////////////////////////////////////////////////////////////////
// VARIABLES:
// /////////////////////////////////////////////////////////////////////////
private NumberSegment _lengthSegment;
private int _lengthWidth;
private Endianess _endianess;
private byte _endOfStringByte;
// /////////////////////////////////////////////////////////////////////////
// CONSTRUCTORS:
// /////////////////////////////////////////////////////////////////////////
/**
* Constructs an {@link AsciizArraySegment} from the given configuration.
* The configuration attributes are taken from the
* {@link TransmissionMetrics} configuration object, though only those
* attributes are supported which are also supported by the other
* constructors!
*
* @param aTransmissionMetrics The {@link TransmissionMetrics} to be used
* for configuring this instance.
*/
public AsciizArraySegment( TransmissionMetrics aTransmissionMetrics ) {
this( aTransmissionMetrics.getEndOfStringByte(), aTransmissionMetrics.getLengthWidth(), aTransmissionMetrics.getEndianess() );
}
/**
* Constructs an {@link AsciizArraySegment} from the given configuration.
* The configuration attributes are taken from the
* {@link TransmissionMetrics} configuration object, though only those
* attributes are supported which are also supported by the other
* constructors!
*
* @param aTransmissionMetrics The {@link TransmissionMetrics} to be used
* for configuring this instance.
* @param aValue The payload to be contained by the
* {@link AsciizArraySegment}.
*/
public AsciizArraySegment( TransmissionMetrics aTransmissionMetrics, String... aValue ) {
this( aTransmissionMetrics.getEndOfStringByte(), aTransmissionMetrics.getLengthWidth(), aTransmissionMetrics.getEndianess(), aValue );
}
/**
* Constructs an {@link AsciizArraySegment} from the given configuration.
* The configuration attributes are taken from the
* {@link TransmissionMetrics} configuration object, though only those
* attributes are supported which are also supported by the other
* constructors!
*
* @param aAlias The alias which identifies the content of this instance.
* @param aTransmissionMetrics The {@link TransmissionMetrics} to be used
* for configuring this instance.
*/
public AsciizArraySegment( String aAlias, TransmissionMetrics aTransmissionMetrics ) {
this( aAlias, aTransmissionMetrics.getEndOfStringByte(), aTransmissionMetrics.getLengthWidth(), aTransmissionMetrics.getEndianess() );
}
/**
* Constructs an {@link AsciizArraySegment} from the given configuration.
* The configuration attributes are taken from the
* {@link TransmissionMetrics} configuration object, though only those
* attributes are supported which are also supported by the other
* constructors!
*
* @param aAlias The alias which identifies the content of this instance.
* @param aTransmissionMetrics The {@link TransmissionMetrics} to be used
* for configuring this instance.
* @param aValue The payload to be contained by the
* {@link AsciizArraySegment}.
*/
public AsciizArraySegment( String aAlias, TransmissionMetrics aTransmissionMetrics, String... aValue ) {
this( aAlias, aTransmissionMetrics.getEndOfStringByte(), aTransmissionMetrics.getLengthWidth(), aTransmissionMetrics.getEndianess(), aValue );
}
// -------------------------------------------------------------------------
/**
* Constructs an {@link AsciizArraySegment} containing the provided payload
* and using the {@link TransmissionMetrics#DEFAULT_LENGTH_WIDTH} as well as
* the {@link TransmissionMetrics#DEFAULT_ENDIANESS}.
*
* @param aPayload The {@link String} elements being contained in this
* instance.
*/
public AsciizArraySegment( String... aPayload ) {
this( CaseStyleBuilder.asCamelCase( AsciizArraySegment.class.getSimpleName() ), TransmissionMetrics.DEFAULT_END_OF_STRING_BYTE, TransmissionMetrics.DEFAULT_LENGTH_WIDTH, TransmissionMetrics.DEFAULT_ENDIANESS, aPayload );
}
/**
* Constructs an {@link AsciizArraySegment} using the provided
* {@link String} elements and using the provided {@link Segment} class for
* creating {@link Segment} instances.
*
* @param aLengthWidth The width (in bytes) to be used for size values
* (number of elements in the payload array). * @param aEndianess The
* {@link Endianess} to be used for size values.
* @param aEndianess the endianess
* @param aPayload The {@link String} elements being contained in this
* instance.
*/
public AsciizArraySegment( int aLengthWidth, Endianess aEndianess, String... aPayload ) {
this( CaseStyleBuilder.asCamelCase( AsciizArraySegment.class.getSimpleName() ), TransmissionMetrics.DEFAULT_END_OF_STRING_BYTE, aLengthWidth, aEndianess, aPayload );
}
// -------------------------------------------------------------------------
/**
* Constructs an {@link AsciizArraySegment} using the provided arguments.
*
* @param aAlias The alias which identifies the content of this segment.
* @param aLengthWidth The width (in bytes) to be used for size values
* (number of elements in the payload array).
* @param aEndianess The {@link Endianess} to be used for size values.
* @param aPayload The {@link String} elements being contained in this
* instance.
*/
public AsciizArraySegment( String aAlias, int aLengthWidth, Endianess aEndianess, String... aPayload ) {
this( aAlias, TransmissionMetrics.DEFAULT_END_OF_STRING_BYTE, aLengthWidth, aEndianess, aPayload );
}
/**
* Constructs an {@link AsciizArraySegment} from the given configuration.
* The configuration attributes are taken from the
* {@link TransmissionMetrics} configuration object, though only those
* attributes are supported which are also supported by the other
* constructors!
*
* @param aAlias The alias which identifies the content of this instance.
* @param aTransmissionMetrics The {@link TransmissionMetrics} to be used
* for configuring this instance.
* @param aEndOfStringByte The alternate value instead of 0 "zero"
* identifying the end of the string.
*/
public AsciizArraySegment( String aAlias, TransmissionMetrics aTransmissionMetrics, byte aEndOfStringByte ) {
this( aAlias, aTransmissionMetrics.getEndOfStringByte(), aTransmissionMetrics.getLengthWidth(), aTransmissionMetrics.getEndianess() );
}
// -------------------------------------------------------------------------
/**
* Constructs an {@link AsciizArraySegment} containing the provided payload
* and using the {@link TransmissionMetrics#DEFAULT_LENGTH_WIDTH} as well as
* the {@link TransmissionMetrics#DEFAULT_ENDIANESS}.
*
* @param aEndOfStringByte The alternate value instead of 0 "zero"
* identifying the end of the string.
* @param aPayload The {@link String} elements being contained in this
* instance.
*/
public AsciizArraySegment( byte aEndOfStringByte, String... aPayload ) {
this( CaseStyleBuilder.asCamelCase( AsciizArraySegment.class.getSimpleName() ), aEndOfStringByte, TransmissionMetrics.DEFAULT_LENGTH_WIDTH, TransmissionMetrics.DEFAULT_ENDIANESS, aPayload );
}
/**
* Constructs an {@link AsciizArraySegment} using the provided
* {@link String} elements and using the provided {@link Segment} class for
* creating {@link Segment} instances.
*
* @param aEndOfStringByte The alternate value instead of 0 "zero"
* identifying the end of the string.
* @param aLengthWidth The width (in bytes) to be used for size values
* (number of elements in the payload array). * @param aEndianess The
* {@link Endianess} to be used for size values.
* @param aEndianess the endianess
* @param aPayload The {@link String} elements being contained in this
* instance.
*/
public AsciizArraySegment( byte aEndOfStringByte, int aLengthWidth, Endianess aEndianess, String... aPayload ) {
this( CaseStyleBuilder.asCamelCase( AsciizArraySegment.class.getSimpleName() ), aEndOfStringByte, aLengthWidth, aEndianess, aPayload );
}
// -------------------------------------------------------------------------
/**
* Constructs an {@link AsciizArraySegment} using the provided arguments.
*
* @param aAlias The alias which identifies the content of this segment.
* @param aEndOfStringByte The alternate value instead of 0 "zero"
* identifying the end of the string.
* @param aLengthWidth The width (in bytes) to be used for size values
* (number of elements in the payload array).
* @param aEndianess The {@link Endianess} to be used for size values.
* @param aPayload The {@link String} elements being contained in this
* instance.
*/
public AsciizArraySegment( String aAlias, byte aEndOfStringByte, int aLengthWidth, Endianess aEndianess, String... aPayload ) {
super( aAlias, aPayload );
_alias = aAlias;
_lengthWidth = aLengthWidth;
_endianess = aEndianess;
_lengthSegment = new NumberSegment( _lengthWidth, _endianess );
_endOfStringByte = aEndOfStringByte;
}
// /////////////////////////////////////////////////////////////////////////
// METHODS:
// /////////////////////////////////////////////////////////////////////////
/**
* {@inheritDoc}
*/
@Override
public int fromTransmission( Sequence aSequence, int aOffset ) throws TransmissionException {
int eOffset = _lengthSegment.fromTransmission( aSequence, aOffset );
final int theSize = _lengthSegment.getValue().intValue();
_payload = new String[theSize];
final AsciizSegment theAsciizSegment = new AsciizSegment( _endOfStringByte );
for ( int i = 0; i < theSize; i++ ) {
eOffset = theAsciizSegment.fromTransmission( aSequence, eOffset );
_payload[i] = theAsciizSegment.getPayload();
}
return eOffset;
}
/**
* {@inheritDoc}
*/
@Override
public void receiveFrom( InputStream aInputStream, OutputStream aReturnStream ) throws IOException {
_lengthSegment.receiveFrom( aInputStream, aReturnStream );
final int theSize = _lengthSegment.getValue().intValue();
final String[] thePayload = new String[theSize];
final AsciizSegment theAsciizSegment = new AsciizSegment( _endOfStringByte );
for ( int i = 0; i < theSize; i++ ) {
theAsciizSegment.receiveFrom( aInputStream, aReturnStream );
thePayload[i] = theAsciizSegment.getPayload();
}
}
/**
* {@inheritDoc}
*/
@Override
public Sequence toSequence() {
final ByteArraySequence theSequence = new ByteArraySequence();
_lengthSegment.setValue( _payload != null ? (long) _payload.length : 0 );
theSequence.append( _lengthSegment.toSequence() );
final int theSize = _lengthSegment.getValue().intValue();
final AsciizSegment theAsciizSegment = new AsciizSegment( _endOfStringByte );
for ( int i = 0; i < theSize; i++ ) {
theAsciizSegment.setPayload( _payload[i] );
theSequence.append( theAsciizSegment.toSequence() );
}
return theSequence;
}
/**
* {@inheritDoc}
*/
@Override
public void transmitTo( OutputStream aOutputStream, InputStream aReturnStream ) throws IOException {
_lengthSegment.setValue( _payload != null ? (long) _payload.length : 0 );
_lengthSegment.transmitTo( aOutputStream, aReturnStream );
final int theSize = _lengthSegment.getValue().intValue();
final AsciizSegment theAsciizSegment = new AsciizSegment( _endOfStringByte );
for ( int i = 0; i < theSize; i++ ) {
theAsciizSegment.setPayload( _payload[i] );
theAsciizSegment.transmitTo( aOutputStream, aReturnStream );
}
}
/**
* {@inheritDoc}
*/
@Override
public void reset() {
super.reset();
_lengthSegment.reset();
}
/**
* {@inheritDoc}
*/
@Override
public SerialSchema toSchema() {
final int theSize = _payload != null ? _payload.length : 0;
final SerialSchema[] theSchemas = new SerialSchema[theSize + 1];
theSchemas[0] = _lengthSegment.toSchema();
for ( int i = 0; i < _payload.length; i++ ) {
theSchemas[i + 1] = new AsciizSegment( _payload[i], _endOfStringByte ).toSchema();
}
return new SerialSchema( getAlias(), getClass(), toSequence(), getLength(), VerboseTextBuilder.asString( getPayload() ), "A segment containing an ASCIIZ string array payload prefixed by the number of array elements.", theSchemas );
}
/**
* {@inheritDoc}
*/
@Override
public int getLength() {
int thePayloadLength = 0;
if ( _payload != null ) {
for ( String a_payload : _payload ) {
thePayloadLength += a_payload.length() + 1;
}
}
return _lengthSegment.getLength() + thePayloadLength;
}
/**
* {@inheritDoc}
*/
@Override
public AsciizArraySegment withPayload( String[] aValue ) {
setPayload( aValue );
return this;
}
/**
* {@inheritDoc}
*/
@Override
public int getLengthWidth() {
return _lengthWidth;
}
/**
* {@inheritDoc}
*/
@Override
public Endianess getEndianess() {
return _endianess;
}
/**
* {@inheritDoc}
*/
@Override
public String getAlias() {
return _alias;
}
/**
* {@inheritDoc}
*/
@Override
public SimpleTypeMap toSimpleTypeMap() {
return new SimpleTypeMapBuilderImpl().withInsertTo( _alias, getPayload() );
}
/**
* {@inheritDoc}
*/
@Override
public byte getEndOfStringByte() {
return _endOfStringByte;
}
}