uni_msg_len
, uni_msg_space
,
uni_msg_leading
, uni_msg_size
,
uni_msg_ensure
,
uni_msg_append
,
uni_msg_extend
, uni_msg_alloc
,
uni_msg_build
,
uni_msg_destroy
,
uni_msg_strip32
,
uni_msg_get32
,
uni_msg_append32
,
uni_msg_append8
,
uni_msg_trail32
, uni_msg_dup
—
ATM signalling library - message buffers
Begemot ATM signalling library (libunimsg, -lunimsg)
#include <uni4/unimsg.h>
size_t
uni_msg_len
(const
struct uni_msg *msg);
size_t
uni_msg_space
(const
struct uni_msg *msg);
size_t
uni_msg_leading
(const
struct uni_msg *msg);
size_t
uni_msg_size
(const
struct uni_msg *msg);
int
uni_msg_ensure
(struct
uni_msg *msg, size_t
bytes);
int
uni_msg_append
(struct
uni_msg *msg, void
*buf, size_t
buflen);
int
uni_msg_extend
(struct
uni_msg *msg, size_t
bytes);
struct uni_msg *
uni_msg_alloc
(size_t
space);
struct uni_msg *
uni_msg_build
(void
*buf, ...);
void
uni_msg_destroy
(struct
uni_msg *msg);
u_int
uni_msg_strip32
(struct
uni_msg *msg);
u_int
uni_msg_get32
(struct
uni_msg *msg);
int
uni_msg_append32
(struct
uni_msg *msg, u_int
value);
int
uni_msg_append8
(struct
uni_msg *msg, u_int
byte);
u_int
uni_msg_trail32
(const
struct uni_msg *msg, int
n);
struct uni_msg *
uni_msg_dup
(const
struct uni_msg *msg);
These functions are used to manipulate variable sized message. They are inspired
by BSD mbufs and SysV stream buffers, but somewhat simplified because
signalling generally is a low bandwidth task. All the functions operation on a
uni_msg
data structure:
struct uni_msg {
u_char *b_wptr; /* tail pointer */
u_char *b_rptr; /* head pointer */
u_char *b_buf; /* data buffer */
u_char *b_lim; /* end of data buffer */
};
The field b_buf points to the begin of a
memory block that is used to store the actual message and the field
b_lim points just to the first byte behind that
buffer. This buffer is allocated separate from the structure itself and the
user calling any of the above functions with a non const
struct uni_msg argument should expect the buffer to be
reallocated and hence not hold pointers into the buffer accross call to
these functions. The pointer b_rptr points to the
first used byte in the message and b_wptr to the first
unused byte behind all used bytes. If the message is empty, both pointers
point to the same place somewhere in the allocated buffer.
There are several functions and macros that return various sizes
and lengths. The macro uni_msg_len
() returns the
actual size of the message (the number of used bytes). The macro
uni_msg_space
() returns the number of bytes that are
left unused behind the used space. The macro
uni_msg_leading
() returns the number of bytes that
are unused before the used space and the macro
uni_msg_size
() returns the maximum size of the
message (that is the size of the allocated buffer).
Two functions may be used to create new messages: The function
uni_msg_alloc
() allocates the message structure and
a buffer to hold at least space bytes (In fact it
allocates a couple of bytes more). If the allocation fails NULL is returned.
The pointers are setup so that there is no leading space in the buffer. The
function uni_msg_build
() constructs a new message
from a variable number of buffers. The arguments are pairs of
void * pointers to buffers and
size_t buffer sizes, terminated by a NULL pointer. The
function computes the total resulting message size, allocates a message and
copies all the buffers into the message. The message is built to have no
leading space. If the allocation fails, NULL is returned.
The function uni_msg_destroy
() deallocates
the buffer pointed to by the message and the message itself. It is save to
pass a message with a NULL buffer, but not a NULL message.
The function uni_msg_dup
() returns a copy
of a message with exact the same leading space.
A number of functions are used to add bytes to an existing
message. The function uni_msg_extend
() extends the
message buffer to have space for at least bytes
additional byte at the end. The leading space does not change. This function
may reallocate the message buffer. The function returns 0 on success and
ENOMEM if the reallocation fails. In this case the message buffer is not
changed. The macro uni_msg_ensure
() checks whether
the message has space for additional bytes bytes. If
not it calls uni_msg_extend
() to make the message
buffer larger. The macro returns 0 on success or ENOMEM if there is not
enough space and the reallocation fails. In this case the message buffer is
not changed. The function uni_msg_append
() appends
buflen bytes from the buffer pointed to by
buf to the message. The function
uni_msg_append8
() appends one byte to the message
and the function uni_msg_append32
() appends a 32-bit
value in network byte order to the message (b_wptr
needs not to be aligned). All three functions call
uni_msg_ensure
() to make sure, that the buffer
contents fit into the message. They return 0 on success and ENOMEM if the
buffer is too small and the reallocation fails. In this case the message
buffer is not changed.
A number of functions can be used to retrieve parts of the
message. The function uni_msg_strip32
() returns the
last four bytes of the message as a 32-bit integer assumed to be in network
byte order. It adjusts b_wptr to remove these four
bytes from the message. b_wptr does not need to be
aligned. The function uni_msg_get32
() returns the
first four bytes of the message as a 32-bit integer assumed to be in network
byte order. It adjusts b_rptr to remove these four
bytes from the message. b_rptr does not need to be
aligned. The function uni_msg_trail32
() returns the
n 'th 32-bit integer from the buffer counted from the
end of the buffer. The integer is assumed to be in network byte order. A
value of -1 for n returns the last four bytes of the
buffer, a value of -2 the four bytes just before the last four bytes and so
on. All three functions do not check that the message is large enough.
Hartmut Brandt ⟨harti@FreeBSD.org⟩