public interface DataMessage extends Message
Empty messages may be created using various factory methods on API interfaces.
Data may be written to messages using the various 'put..' methods. A new record has its data pointer positioned at the start and each put method will move the pointer to the end of the written data.
Message data is essentially 'byte' data and bytes can be written using
put(byte)
or put(byte[])
. However, there are a number of
other methods that make it easier to write String data to messages.
put(String...)
can be used to write one or more String values to the
message. Strings are converted to bytes using the character set that is in
use for the message (see getCharset()
).
Further convenience methods exist for writing 'fields' and 'records' to the message.
Fields are simply String items separated by field delimiters
allowing data to be written and read in convenient variable
length chunks. The putFields(String...)
method is the same as
putString except the strings will be separated by field delimiters.
Records are groups of fields and so a message may comprise one or more
records each containing one or more fields. Records are separated by
record delimiters
. A Record
may be
created and populated before being written to a message using
putRecords(Record...)
. For convenience there is also a
putRecord(String...)
method which allows a list of Strings to be
written to the message as a record.
Empty records may be written to a message but it should be noted that a
message that has had only one empty record written to it is essentially the
same as an empty message. Only when a second record (empty or not) is put
into the message is the delimiter written to the message and then there are
two records. A single Message.RECORD_MU
delimiter may be used to
represent a message containing a single empty record.
Also when there is no content between record delimiters (or before the first
record delimiter or after the last) it is interpreted as an empty record. To
represent a record with a single empty field a single
Message.FIELD_MU
may be written within the record. This is done
automatically by the various putRecord methods.
When a data message is sent it the data portion may also optionally have a
byte Encoding
applied to it. The encoding may be set explicitly for a
message using setEncoding(Encoding)
. Incoming messages would retain
the encoding they arrived with.
It should be noted that once a message has been sent it becomes 'locked' and can no longer be changed in any way.
Reading data from messages can either be done in an 'absolute' or 'relative'
manner. 'Absolute' means that all of the message data is read, whereas
'relative' means that a segment of data is read from the message's current
pointer position. asString()
and asBytes()
are 'absolute'
read methods, whereas the 'relative' read methods are those that begin with
'next'.
Before performing relative reads the message pointer should be reset using
rewind()
. As long as hasRemaining()
returns true it means
there is some data to read (except in the case of record/field based reads).
When reading bytes the number of remaining bytes to read may be obtained
using remaining()
. Each read operation will move the message pointer
is preparation for reading the next segment of data.
Because a message has a single pointer used in both 'put' and relative read
operations, care must be taken to consider the pointer position at any point
in time. It must also be borne in mind that such operations are therefore not
thread safe. In order to read a message without affecting its message
pointers a MessageReader
may be obtained using getReader()
.
When reading Strings the bytes are converted to characters using the message character set in the same way as when writing Strings.
EMPTY_FIELD, EMPTY_FIELD_CHAR, EMPTY_FIELD_STRING, FIELD_DELIMITER, FIELD_DELIMITER_CHAR, FIELD_DELIMITER_STRING, FIELD_MU, LIST_DELIMITER, LIST_DELIMITER_CHAR, LIST_DELIMITER_STRING, MESSAGE_SEPARATOR, MESSAGE_SEPARATOR_CHAR, RECORD_DELIMITER, RECORD_DELIMITER_CHAR, RECORD_DELIMITER_STRING, RECORD_MU
Modifier and Type | Method and Description |
---|---|
ByteBuffer |
asByteBuffer()
Returns the whole message data content as a newly allocated ByteBuffer.
|
byte[] |
asBytes()
Returns the whole message as a new byte array.
|
List<String> |
asFields()
Returns the whole message body as fields.
|
List<Record> |
asRecords()
Returns the whole message body as records.
|
List<Record> |
asRecords(MRecord metadata)
Returns the whole message body as
records . |
String |
asString()
Returns the whole message body as a String.
|
int |
available()
Indicates the free space available for writing to in bytes.
|
String |
getCharset()
Returns the character set used for character to byte conversions and vice
versa.
|
Encoding |
getEncoding()
Returns the message encoding.
|
InputStream |
getInputStream()
Returns an
InputStream which may be used for reading bytes from
the message. |
OutputStream |
getOutputStream()
Returns an
OutputStream which may be used for writing bytes to
the message. |
MessageReader |
getReader()
This returns a reader which may be used to perform relative read
operations on a message without affecting the pointers of the original
message.
|
boolean |
hasRemaining()
Indicates whether the message has any remaining data to read.
|
int |
length()
Returns the length of the data within the message in bytes.
|
byte |
nextByte()
Returns the next byte of data from the message.
|
void |
nextBytes(byte[] destination)
Returns data from the message as bytes from the current position.
|
String |
nextField()
Returns a field of string data from the current message position.
|
Object |
nextObject()
Uses Java object serialization to read the content of the message into an
object.
|
Record |
nextRecord()
Returns a record of string data from the current message position.
|
Record |
nextRecord(MRecord metadata)
Returns a record of string data from the current message position using a
metadata definition.
|
void |
put(byte data)
Relative put of a single byte of data.
|
void |
put(byte[] data)
Relative put of a byte array of data.
|
void |
put(ByteBuffer buffer)
Relative put of data from a ByteBuffer.
|
void |
put(DataMessage message)
Puts the entire content of another message into this message.
|
void |
put(String... data)
Relative put of String data.
|
void |
putFields(byte[]... fields)
Relative put of one or more byte array fields.
|
void |
putFields(Collection<?> fields)
Relative put of one or more fields.
|
void |
putFields(String... fields)
Relative put of one or more String fields.
|
void |
putObject(Object object)
Writes an object to the message using Java object serialization.
|
void |
putRecord(byte[]... fields)
Relative put of a set of byte array fields as a record.
|
void |
putRecord(Collection<?> fields)
Relative put of a collection of fields as a record.
|
void |
putRecord(String... fields)
Relative put of a set of String fields as a record.
|
void |
putRecords(Collection<Record> records)
Relative put of one or more Records from a
Collection . |
void |
putRecords(Record... records)
Relative put of one or more records.
|
int |
remaining()
Indicates the number of unread data bytes remaining within the message.
|
void |
rewind()
Resets the data pointer to the start of the data in preparation for
relative read ('next...') operations.
|
void |
setCharset(String charset)
Sets the character set to be used by the message for byte/character
conversions.
|
void |
setEncoding(Encoding encoding)
Sets the byte encoding for the message.
|
getHeader, getHeaders, isTopicMessage, setHeaders, setHeaders, size, toMessage, toString
String getCharset()
void setCharset(String charset) throws MessageException
If no character set is explicitly specified for a message then the
default as determined by RootConfig.getCharset()
is assumed.
charset
- character set nameMessageException
- is an invalid character set is suppliedEncoding getEncoding()
The encoding value represents the byte encoding that will be applied to the message when it is sent.
void setEncoding(Encoding encoding) throws MessageException
This will cause the message data to be encoded in the manner specified before it is sent.
encoding
- the encoding valueMessageException
- if unable to set or change the message encodingvoid put(byte data) throws MessageException
This appends a single byte of data to the end of the current message data.
data
- a single byte of dataMessageException
- if unable to put the byte of data into the
messagevoid put(byte[] data) throws MessageException
This appends the bytes from the specified array to the end of the current message data.
data
- a byte arrayMessageException
- if unable to put the data into the messagevoid put(ByteBuffer buffer) throws MessageException
This method appends the bytes remaining in the given source buffer to the end of the current message data.
buffer
- the source bufferMessageException
- if unable to put data, possibly because message
size limits have been exceededvoid put(String... data) throws MessageException
Converts supplied string(s) to bytes using the message's character set encoding and appends the bytes to the end of the message. Multiple strings are concatenated.
data
- one or more strings to add to the messageMessageException
- if unable to add strings to the messagevoid put(DataMessage message) throws MessageException
All data bytes from the source message are appended to the end of this message.
message
- the message to copy data fromMessageException
- is unable to copy data from the supplied messagevoid putRecord(String... fields) throws MessageException
The specified fields are appended to the message delimited by field delimiters. Strings are converted to bytes using the character set of the message.
If there is already data in the buffer that is not terminated by a record delimiter then a record delimiter will first be written to the message.
fields
- one or more string fieldsMessageException
- if unable to put record into messagevoid putRecord(Collection<?> fields) throws MessageException
Fields are appended to the message delimited by field delimiters. The toString() value of each object in the collection is converted to bytes using the character set of the message.
If there is already data in the buffer that is not terminated by a record delimiter then a record delimiter will first be written to the message.
If any field value is null it will be written as an empty field (i.e. a zero length string).
fields
- a collection of objects from which the String field values
will be obtainedMessageException
- if unable to put record into messagevoid putRecord(byte[]... fields) throws MessageException
The specified fields are appended to the message delimited by field delimiters.
If there is already data in the buffer that is not terminated by a record delimiter then a record delimiter will first be written to the message.
fields
- one or more byte array fieldsMessageException
- if unable to put record into messagevoid putRecords(Record... records) throws MessageException
The fields of each record are appended to the end of the message delimited by field delimiters and the records themselves are delimited by record delimiters. Strings are converted to bytes using the character set of the message.
If there is already data in the buffer that is not terminated by a record delimiter then a record delimiter will first be written to the message. Record delimiters will then be written at the start of each subsequent record.
Null entries are interpreted as empty records.
records
- the records - zero or more can be specifiedMessageException
- if unable to put the records into the messagevoid putRecords(Collection<Record> records) throws MessageException
Collection
.
See putRecords(Record...)
.records
- the collection of recordsMessageException
- if unable to put the records into the messagevoid putFields(String... fields) throws MessageException
Converts supplied string(s) to bytes using the message's character set encoding and appends the bytes to the end of the message. Multiple strings are separated by field delimiters.
If there is already data in the buffer which is not terminated by a record or field delimiter then a field delimiter will be written followed by the specified fields separated by field delimiters.
If any field value is null it will be written as an empty field (i.e. a zero length string).
fields
- the list of fieldsMessageException
- if unable to put fields into the record.void putFields(Collection<?> fields) throws MessageException
A collection of any type may be supplied and the toString() value of each object will be converted to bytes using the message's character set encoding and the bytes appended to the end of the message. Multiple values are separated by field delimiters.
If there is already data in the message which is not terminated by a record or field delimiter then a field delimiter will be written followed by the specified fields separated by field delimiters.
If any field value is null it will be written as an empty field (i.e. a zero length string).
fields
- the collection of field objectsMessageException
- if unable to put fields into the recordvoid putFields(byte[]... fields) throws MessageException
Appends the bytes to the end of the message. Multiple fields are separated by field delimiters.
If there is already data in the message which is not terminated by a record or field delimiter then a field delimiter will be written followed by the specified fields separated by field delimiters.
If any field value is null it will be written as an empty field.
fields
- the list of fieldsMessageException
- if unable to put fields into the recordString asString() throws MessageException
The message's character set will be used to convert the message bytes to a String.
This operation does not affect the message pointer.
MessageException
- if unable to return the data as a stringbyte[] asBytes() throws MessageException
This operation does not affect the message pointer.
MessageException
- if unable to return the data as bytesByteBuffer asByteBuffer() throws MessageException
This operation does not affect the message pointer.
The capacity and limit of the new buffer will be the same as the message
length
and the position will be 0.
MessageException
- if unable to return the data as a ByteBufferList<String> asFields() throws MessageException
Fields are delimited by field delimiters
.
If there are no such delimiters then a single field would be returned.
The message's character set will be used to convert the message bytes to a String.
This operation does not affect the message pointer.
MessageException
- if unable to return the data as fieldsList<Record> asRecords() throws MessageException
Records are delimited by record
delimiters
. If there are no such delimiters then a single record would
be returned.
This operation does not affect the message pointer.
MessageException
- if unable to return the data as RecordsList<Record> asRecords(MRecord metadata) throws MessageException
records
.
This is similar to asRecords()
except that the structure of the
supplied metadata is assumed for each record and the records returned can
be accessed using metadata specific methods.
metadata
- the metadata that defines each record. This must either
be a simple MRecord
definition or an MMessage
which defines a single record. The data type of the metadata must
be TopicDataType.RECORD
.MessageException
- if unable to obtain the Records or the Record
data of a Record read violates the Metadata definitionvoid rewind() throws MessageException
Note that such reading operations are NOT threadsafe and if multiple
threads wish to read the same message then a reader
should be used.
MessageException
- if unable to rewindint length() throws MessageException
Note that this is the length of the data part of the message only and does not include header information.
The length returned is the number of bytes within the decoded message.
MessageException
- if unable to obtain the message data lengthboolean hasRemaining() throws MessageException
This simply checks whether there are any more bytes of data beyond the current message pointer.
Note that this is not safe to use when processing record/field type data
(e.g. using nextField()
or nextRecord()
) as it would
not detect a final empty record or field. In those cases you should keep
reading until the nextField/nextRecord method returns null.
MessageException
- if unable to determine whether data remainingint remaining() throws MessageException
MessageException
- if unable to determine the number of remaining
bytesint available() throws MessageException
If the message is in a read only state then this will return 0.
If the message is writable then this will return the number of bytes of bytes of data that may be written before the message becomes full.
It is important to note that this returns the number of free bytes and not necessarily the number of characters that may be written as depending upon the character set in use the number of bytes required to write a character may vary.
MessageException
- if unable to determine the number of free bytesbyte nextByte() throws MessageException
The byte of data at the current position is returned and the position updated.
MessageException
- if unable to return the next byte of datavoid nextBytes(byte[] destination) throws MessageException
Bytes from current message position are transferred into the specified destination array until the destination array is filled. The message position is then updated.
destination
- the destination arrayMessageException
- if the destination array is too longRecord nextRecord() throws MessageException
This returns a record of String data read from the current data buffer position to the next record delimiter within the buffer or the end of the message.
Fields (areas delimited by field delimiters) are unpacked from within the record area. If there are no field delimiters then the returned record will contain only one field.
After calling this method the data buffer position will be moved beyond the record read.
MessageException
- if unable to obtain the next recordRecord nextRecord(MRecord metadata) throws MessageException
This is similar to nextRecord()
except that the structure of the
supplied metadata is assumed for the record and the record returned can
be accessed using metadata specific methods.
metadata
- the metadata that defines the record. This must either be
a simple MRecord
definition or an MMessage
which
defines a single record. The data type of the metadata must be
TopicDataType.RECORD
MessageException
- if unable to obtain the next record or the
record data read violates the metadata definitionString nextField() throws MessageException
This returns a field of String data constructed from bytes read from the current data buffer position to the next field delimiter (or record delimiter) within the buffer or the end of the message.
After calling this method the data buffer pointer will be moved beyond the delimiter found.
MessageException
- if unable to read the next field from the
messagevoid putObject(Object object) throws MessageException
The object to be written must be Serializable
.
The object is appended to the end of the message using an
ObjectOutputStream
.
object
- the object to write to the messageMessageException
- if unable to write the objectObject nextObject() throws MessageException
Bytes will be read from the current message position to the end of the
message as an ObjectInputStream
and a newly instantiated object
will be returned.
MessageException
- if unable to read an object from the messageMessageReader getReader() throws MessageException
This may be used where there is a need for more than one thread to be able to read the same message as the standard relative read and put operations on a message are not thread safe.
Note that any such reader maintains a reference to the message and thus would prevent it from being garbage collected.
MessageException
- if unable to create a reader for the messageInputStream getInputStream()
InputStream
which may be used for reading bytes from
the message.
Reading will take place from the current message position.
OutputStream getOutputStream()
OutputStream
which may be used for writing bytes to
the message.
Writing will take place from the current message position.
Copyright © 2016 Push Technology Ltd. All Rights Reserved.