fstrm
0.4.0
Frame Streams implementation in C
|
fstrm_control
is an interface for encoding and decoding Frame Streams control frames.
Two types of frames are possible in a Frame Streams byte stream: data frames and control frames. Both are variable length byte sequences prefixed by a 32-bit big endian unsigned integer (the frame length) specifying the length of the following byte sequence. If this frame length value is greater than zero, the frame length specifies the data frame length, and a data frame follows it. If the frame length is zero (i.e., it is the four byte sequence 00 00 00 00
), this is an escape sequence, which means that a control frame follows. The control frame itself is prefixed by a 32-bit big endian unsigned integer (the control frame length) specifying the length of the following control frame payload.
There are two types of control frames used for uni-directional streams: START
and STOP
. These control frame types bracket the stream of data frames. START
indicates the beginning of the stream and communicates metadata about the stream to follow, and STOP
indicates the end of the stream.
Bi-directional streams make use of three additional control frame types: READY
, ACCEPT
, and FINISH
. These control frame types are used in a simple handshake protocol between sender and receiver.
A uni-directional Frame Streams byte stream normally consists of the following:
START
control frame.START
, STOP
, ACCEPT
, READY
, or FINISH
.STOP
control frame.The START
and STOP
control frames are not optional. The START
control frame must appear at the beginning of the byte stream, and the STOP
control frame must appear at the end of the byte stream. (If the byte stream has an end.) START
control frames must not appear anywhere other than at the beginning of the byte stream, and STOP
control frames must not appear anywhere other than at the end of the byte stream. Only one START
control frame and only one STOP
control frame may appear in a Frame Streams byte stream.
Control frames may optionally include zero or more control frame fields. There is currently one type of control frame field defined: CONTENT_TYPE
. This field specifies a variable length byte sequence describing the encoding of data frames that appear in the Frame Streams byte stream. This field is used by cooperating programs to unambiguously identify how to interpret the data frames in a particular Frame Streams byte stream. For instance, this field may specify a particular schema to use to interpret the data frames appearing in the byte stream. Zero, one, or more CONTENT_TYPE
fields may appear in READY
or ACCEPT
control frames. Zero or one CONTENT_TYPE
fields may appear in START
control frames. No CONTENT_TYPE
fields may appear in STOP
or FINISH
control frames.
A uni-directional Frame Streams encoder would normally produce a byte stream as follows:
START
control frame.00 00 00 00
that precedes control frames.START
control frame. It may optionally specify a CONTENT_TYPE
field.STOP
control frame.00 00 00 00
that precedes control frames.STOP
control frame.A uni-directional Frame Streams decoder would normally process the byte stream as follows:
START
control frame.00 00 00 00
that precedes control frames.START
control frame. It may optionally specify a CONTENT_TYPE
field.START
control frame.STOP
control frame, the end of the Frame Streams byte stream has occurred, and no frames follow. Break out of the decoding loop and halt processing. (READY
, ACCEPT
, START
, and FINISH
may not occur here. For forward compatibility, control frames of types other than the types READY
, ACCEPT
, START
, STOP
, and FINISH
must be ignored here. No control frames specified in the future may alter the encoding of succeeding frames.)The functions fstrm_control_encode() and fstrm_control_decode() are provided to encode and decode control frames. See the detailed descriptions of those functions for code examples showing their usage.
Macros | |
#define | FSTRM_CONTROL_FRAME_LENGTH_MAX 512 |
The maximum length in bytes of an "Accept", "Start", or "Stop" control frame payload. More... | |
#define | FSTRM_CONTROL_FIELD_CONTENT_TYPE_LENGTH_MAX 256 |
The maximum length in bytes of a "Content Type" control frame field payload. More... | |
Enumerations | |
enum | fstrm_control_type |
Control frame types. More... | |
enum | fstrm_control_field |
Control frame field types. More... | |
enum | fstrm_control_flag |
Flags for controlling the behavior of the encoding and decoding functions. More... | |
Functions | |
const char * | fstrm_control_type_to_str (fstrm_control_type type) |
Convert an fstrm_control_type enum value to a string representation. More... | |
const char * | fstrm_control_field_type_to_str (fstrm_control_field f_type) |
Convert an fstrm_control_field enum value to a string representation. More... | |
struct fstrm_control * | fstrm_control_init (void) |
Initialize an fstrm_control object. More... | |
void | fstrm_control_destroy (struct fstrm_control **c) |
Destroy an fstrm_control object. More... | |
void | fstrm_control_reset (struct fstrm_control *c) |
Reinitialize an fstrm_control object. More... | |
fstrm_res | fstrm_control_get_type (const struct fstrm_control *c, fstrm_control_type *type) |
Retrieve the type of the control frame. More... | |
fstrm_res | fstrm_control_set_type (struct fstrm_control *c, fstrm_control_type type) |
Set the type of the control frame. More... | |
fstrm_res | fstrm_control_get_num_field_content_type (const struct fstrm_control *c, size_t *n_content_type) |
Retrieve the number of "Content Type" fields present in the control frame. More... | |
fstrm_res | fstrm_control_get_field_content_type (const struct fstrm_control *c, const size_t idx, const uint8_t **content_type, size_t *len_content_type) |
Retrieve a "Content Type" field from the control frame. More... | |
fstrm_res | fstrm_control_add_field_content_type (struct fstrm_control *c, const uint8_t *content_type, size_t len_content_type) |
Add a "Content Type" field to the control frame. More... | |
fstrm_res | fstrm_control_match_field_content_type (const struct fstrm_control *c, const uint8_t *match, const size_t len_match) |
Check if the control frame matches a particular content type value. More... | |
fstrm_res | fstrm_control_decode (struct fstrm_control *c, const void *control_frame, size_t len_control_frame, const uint32_t flags) |
Decode a control frame from a buffer. More... | |
fstrm_res | fstrm_control_encoded_size (const struct fstrm_control *c, size_t *len_control_frame, const uint32_t flags) |
Calculate the number of bytes needed to serialize the control frame. More... | |
fstrm_res | fstrm_control_encode (const struct fstrm_control *c, void *control_frame, size_t *len_control_frame, const uint32_t flags) |
Encode a control frame into a buffer. More... | |
#define FSTRM_CONTROL_FRAME_LENGTH_MAX 512 |
The maximum length in bytes of an "Accept", "Start", or "Stop" control frame payload.
This excludes the escape sequence and the control frame length.
#define FSTRM_CONTROL_FIELD_CONTENT_TYPE_LENGTH_MAX 256 |
The maximum length in bytes of a "Content Type" control frame field payload.
This excludes the field type and payload length.
enum fstrm_control_type |
Control frame types.
enum fstrm_control_field |
enum fstrm_control_flag |
Flags for controlling the behavior of the encoding and decoding functions.
Enumerator | |
---|---|
FSTRM_CONTROL_FLAG_WITH_HEADER | Set to control whether to include the control frame header in encoding/decoding operations. Causes fstrm_control_encode() and fstrm_control_encoded_size() to include the control frame header containing the escape sequence and control frame payload length in the encoded output. Otherwise, only the control frame payload itself is encoded. Tells fstrm_control_decode() that the input buffer to be decoded begins with the control frame header containing the escape sequence and control frame payload length. (Note that this requires the caller to peek at the input buffer to calculate the right buffer length.) Otherwise, the input buffer begins with the control frame payload. |
const char* fstrm_control_type_to_str | ( | fstrm_control_type | type | ) |
Convert an fstrm_control_type
enum value to a string representation.
Unknown values are represented as "FSTRM_CONTROL_UNKNOWN"
.
type | The fstrm_control_type enum value. |
const char* fstrm_control_field_type_to_str | ( | fstrm_control_field | f_type | ) |
Convert an fstrm_control_field
enum value to a string representation.
Unknown values are represented as "FSTRM_CONTROL_FIELD_UNKNOWN"
.
f_type | The fstrm_control_field enum value. |
struct fstrm_control* fstrm_control_init | ( | void | ) |
Initialize an fstrm_control
object.
This object represents Frame Streams control frames and is used for encoding and decoding control frames.
fstrm_control
object. void fstrm_control_destroy | ( | struct fstrm_control ** | c | ) |
Destroy an fstrm_control
object.
[in] | c | Pointer to an fstrm_control object. |
void fstrm_control_reset | ( | struct fstrm_control * | c | ) |
Reinitialize an fstrm_control
object.
This resets the internal state to default values.
c | fstrm_control object. |
fstrm_res fstrm_control_get_type | ( | const struct fstrm_control * | c, |
fstrm_control_type * | type | ||
) |
Retrieve the type of the control frame.
c | fstrm_control object. | |
[out] | type | Type of the control frame. |
fstrm_res_success | |
fstrm_res_failure |
fstrm_res fstrm_control_set_type | ( | struct fstrm_control * | c, |
fstrm_control_type | type | ||
) |
Set the type of the control frame.
c | fstrm_control object. | |
[in] | type | Type of the control frame. |
fstrm_res_success | |
fstrm_res_failure |
fstrm_res fstrm_control_get_num_field_content_type | ( | const struct fstrm_control * | c, |
size_t * | n_content_type | ||
) |
Retrieve the number of "Content Type" fields present in the control frame.
c | fstrm_control object. | |
[out] | n_content_type | The number of "Content Type" fields. |
fstrm_res_success | |
fstrm_res_failure |
fstrm_res fstrm_control_get_field_content_type | ( | const struct fstrm_control * | c, |
const size_t | idx, | ||
const uint8_t ** | content_type, | ||
size_t * | len_content_type | ||
) |
Retrieve a "Content Type" field from the control frame.
This function returns a reference which must not be modified. Control frames may contain zero, one, or more "Content Type" fields.
c | fstrm_control object. | |
[in] | idx | The index of the "Content Type" field to retrieve. |
[out] | content_type | Pointer to where the reference to the "Content Type" string will be stored. Note that this string is not NUL-terminated and may contain embedded NULs. |
[out] | len_content_type | The number of bytes in content_type . |
fstrm_res_success | The control frame has a "Content Type" field. |
fstrm_res_failure | The control frame does not have a "Content Type" field. |
fstrm_res fstrm_control_add_field_content_type | ( | struct fstrm_control * | c, |
const uint8_t * | content_type, | ||
size_t | len_content_type | ||
) |
Add a "Content Type" field to the control frame.
This function makes a copy of the provided string. This function may be called multiple times, in which case multiple "Content Type" fields will be added to the control frame.
The "Content Type" fields are removed on a call to fstrm_control_reset().
c | fstrm_control object. | |
[in] | content_type | The "Content Type" string to copy. Note that this string is not NUL-terminated and may contain embedded NULs. |
[in] | len_content_type | The number of bytes in content_type . |
fstrm_res_success | The "Content Type" field was successfully added. |
fstrm_res_failure | The "Content Type" string is too long. |
fstrm_res fstrm_control_match_field_content_type | ( | const struct fstrm_control * | c, |
const uint8_t * | match, | ||
const size_t | len_match | ||
) |
Check if the control frame matches a particular content type value.
That is, the content type given in the match
and len_match
parameters is checked for compatibility with the content types (if any) specified in the control frame.
c | fstrm_control object. |
match | The "Content Type" string to match. Note that this string is not NUL-terminated and may contain embedded NULs. May be NULL, in which case the control frame must not have any content type fields in order to match. |
len_match | The number of bytes in match . |
fstrm_res_success | A match was found. |
fstrm_res_failure | A match was not found. |
fstrm_res fstrm_control_decode | ( | struct fstrm_control * | c, |
const void * | control_frame, | ||
size_t | len_control_frame, | ||
const uint32_t | flags | ||
) |
Decode a control frame from a buffer.
The buffer starts with either the escape sequence or the control frame payload depending on whether the FSTRM_CONTROL_FLAG_WITH_HEADER
flag is set or not. In either case, the 'len_control_frame' parameter must be exact. Underflow or overflow is not permitted.
The following code example shows a function that decodes a control frame payload:
c | fstrm_control object. Its state will be overwritten. | |
[in] | control_frame | Buffer containing the serialized control frame. |
[in] | len_control_frame | The number of bytes in control_frame . This parameter must specify the exact number of bytes in the control frame. |
flags | Flags controlling the decoding process. See fstrm_control_flag. |
fstrm_res_success | |
fstrm_res_failure |
fstrm_res fstrm_control_encoded_size | ( | const struct fstrm_control * | c, |
size_t * | len_control_frame, | ||
const uint32_t | flags | ||
) |
Calculate the number of bytes needed to serialize the control frame.
c | fstrm_control object. | |
[out] | len_control_frame | The number of bytes needed to encode c . |
flags | Flags controlling the encoding process. See fstrm_control_flag. |
fstrm_res_success | |
fstrm_res_failure |
fstrm_res fstrm_control_encode | ( | const struct fstrm_control * | c, |
void * | control_frame, | ||
size_t * | len_control_frame, | ||
const uint32_t | flags | ||
) |
Encode a control frame into a buffer.
Since a Frame Streams control frame is a variable length byte sequence of up to FSTRM_CONTROL_FRAME_LENGTH_MAX bytes, this function can be used in two different ways. The first way is to call fstrm_control_encoded_size() to obtain the exact number of bytes needed to encode the frame, and then pass a buffer of this exact size to fstrm_control_encode(). The following example shows this usage:
The second way to use fstrm_control_encode() is to allocate a statically sized buffer of FSTRM_CONTROL_FRAME_LENGTH_MAX bytes. The exact number of bytes serialized by the encoder will be returned in the len_control_frame
parameter. The following example shows this usage:
c | fstrm_control object. | |
[out] | control_frame | The buffer in which to serialize the control frame. |
[in,out] | len_control_frame | The size in bytes of control_frame . On a successful return, contains the number of bytes actually written into control_frame . |
flags | Flags controlling the encoding process. See fstrm_control_flag. |
fstrm_res_success | |
fstrm_res_failure |