Struct Message Types

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.

Configuring a Struct Message Type

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:

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

The byte order specifiers are as follows:

Specifier

Byte Order

@

Native (little-endian for AMPS server)

=

Native (little-endian for AMPS server)

<

Little-endian

>

Big-endian

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:

struct data_type
{
   int32_t  id;
   int32_t  internal_id;
   float    price;
   char     label[32];
   char     code[16];
   char     routing_instructions[32];
};

A message type declaration that would make the id, price, and code members available to AMPS could be constructed as follows:

<MessageType>
   <Name>sample_struct_type</Name>
   <Module>struct</Module>
   <Field>/id = i</Field>
   <Field>/ignored = 4x</Field>
   <Field>/price = f</Field>
   <Field>/ignored = 32x</Field>
   <Field>/code = 16s</Field>
</MessageType>

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.

Limitations of Struct Message Types

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

Last updated

Copyright 2013-2024 60East Technologies, Inc.