Struct Message Types
Last updated
Last updated
Copyright 2013-2024 60East Technologies, Inc.
AMPS includes a message type that allows the server to parse and interpret binary data in a fixed format. When configuring the message type, you must include a definition of the format.
This format is designed to allow AMPS to process messages serialized from raw memory, such as would be specified in a C-language struct
.
To configure a struct
message type, you must define each field that AMPS will use. This does not necessarily have to match the original definition of the data. It is possible to "skip over" parts of the binary data that AMPS should ignore by declaring that data to be padding.
A struct
message type definition must include one or more Field
elements, specified in the order in which the data appears in the message. Each Field
specifies the name of the field, and the type and length of the data to be used for that Field
. The specifier for a field is composed of: field name =
data format specifier where the field name is the XPath identifier that AMPS will use for this field and the data format specifier is a specifier for the type of data and number of bytes for this field.
The data format specifier is modeled after the specifiers for the Python struct
module. The format requires a data type specifier. The data type specifier may be preceded by an optional byte order specifier. For variable-width data types (for example, strings), include an optional byte order specifier and an optional count specifier.
The following data type specifiers are recognized by the module:
The byte order specifiers are as follows:
If no byte order is specified, AMPS assumes a little-endian byte order to match the native byte order of the AMPS server.
For example, given the following C struct:
A message type declaration that would make the id
, price
, and code
members available to AMPS could be constructed as follows:
This configuration declares that the message will be interpreted as follows:
The first four bytes of the message will be interpreted as a (little-endian) integer, and that value will be considered to be the /id
field of the message.
The next four bytes are skipped as padding -- notice that, although a field name is required in the specifier syntax, padding bytes are ignored by AMPS, so there is no field named /ignored
generated. However, if the message is pretty-printed (or displayed in Galvanometer), AMPS will indicate that there are padding bytes present for this field.
The next four bytes are interpreted as a (little-endian) float, and that value will be considered the value of the /price
field.
The next 32 bytes (the label
in the C struct) are skipped as padding. Again, if the message is pretty-printed (or displayed in Galvanometer), AMPS will indicate that there are padding bytes present for this field.
The next 16 bytes of the message are an AMPS string that will be used for the value of the /code
field.
Any remaining bytes (the routing_instructions
from the C struct, in this case) are ignored. If the message is pretty-printed (or displayed in Galvanometer), AMPS will indicate that there are extra bytes present.
Since the struct
message type requires a specific, fixed definition for messages, AMPS does not support operations that construct messages that may contain arbitrary values. In particular, message types defined using the struct
message type do not support:
Creating a View with a struct
message type as the MessageType
. AMPS allows you to aggregate struct
message types and project the results as another message type, but the destination MessageType
for a View cannot be a struct
message type.
Creating an aggregated subscription for a topic that contains messages of a struct
message type.
Subscriptions to AMPS internal topics (for example, /AMPS/ClientStatus
).
Enriching or preprocessing messages of a struct
message type.
Delta publish or delta subscribe
Select lists
Specifier
C Type
Size (bytes)
AMPS Type
x
n/a
(number of bytes must be specified)
padding bytes, ignored by AMPS
c
char
1 (number of bytes may be specified)
string
b
signed char
1
integer
B
unsigned char
1
integer
?
bool
(as though stdbool.h
were included)
1
boolean
h
short
2
integer
H
unsigned short
2
integer
i
int
4
integer
I
unsigned int
4
integer
l
long
4
integer
L
unsigned long
4
integer
q
long long
8
integer
Q
unsigned long long
8
integer
n
ssize_t
integer
N
size_t
integer
f
float
4
double
d
double
8
double
s
char[]
Number of bytes must be specified.
AMPS will interpret the specified number of bytes as the string.
string
S
char[]
Number of bytes must be specified.
AMPS will interpret the string up to the first NULL character or the number of bytes specified.
string
p
uint8_t
followed by char[]
Number of bytes must be specified.
AMPS will consume the number of bytes specified in the Field
configuration. The first byte of data specifies the length of the string. Only that number of bytes, starting with the second byte of the data, will be interpreted as the value.
string
Specifier
Byte Order
@
Native (little-endian for AMPS server)
=
Native (little-endian for AMPS server)
<
Little-endian
>
Big-endian