ascii-chat
Binary v0.15.83-53-gb711d8720
Library lib/v0.3.2-701-gb711d8720
Video chat in your terminal
Loading...
Searching...
No Matches
decoder.c File Reference

Go to the source code of this file.

Functions

void packet_decoder_reset (packet_decoder_t *decoder)
bool packet_decoder_pending (const packet_decoder_t *decoder)
asciichat_error_t packet_decoder_feed (packet_decoder_t *decoder, const void *data, size_t length, packet_decoder_fn emit, void *arg)

Function Documentation

◆ packet_decoder_feed()

asciichat_error_t packet_decoder_feed ( packet_decoder_t * decoder,
const void * data,
size_t length,
packet_decoder_fn emit,
void * arg )

Definition at line 19 of file network/packet/decoder.c.

20 {
21 if (!decoder || (!data && length) || !emit || decoder->failed)
22 return SET_ERRNO(ERROR_INVALID_PARAM, "Invalid packet decoder input");
23 const uint8_t *input = data;
24 while (length) {
25 if (decoder->header_used < sizeof(packet_header_t)) {
26 size_t take = MIN(length, sizeof(packet_header_t) - decoder->header_used);
27 memcpy(decoder->header + decoder->header_used, input, take);
28 decoder->header_used += take;
29 input += take;
30 length -= take;
31 if (decoder->header_used != sizeof(packet_header_t))
32 break;
33 packet_header_t header;
34 memcpy(&header, decoder->header, sizeof(header));
35 size_t payload = NET_TO_HOST_U32(header.length);
36 size_t limit = decoder->max_payload ? MIN(decoder->max_payload, MAX_PACKET_SIZE) : MAX_PACKET_SIZE;
37 if (NET_TO_HOST_U64(header.magic) != PACKET_MAGIC || payload > limit) {
38 decoder->failed = true;
39 return SET_ERRNO(ERROR_NETWORK_PROTOCOL, "Invalid incremental packet header");
40 }
41 decoder->size = sizeof(header) + payload;
42 buffer_workspace_t workspace = {.data = decoder->packet};
43 if (buffer_workspace_reserve(&workspace, NULL, decoder->size) != ASCIICHAT_OK) {
44 decoder->failed = true;
45 return SET_ERRNO(ERROR_MEMORY, "Incremental packet exceeds buffer budget");
46 }
47 decoder->packet = workspace.data;
48 memcpy(decoder->packet, &header, sizeof(header));
49 decoder->used = sizeof(header);
50 }
51 size_t take = MIN(length, decoder->size - decoder->used);
52 if (take)
53 memcpy(decoder->packet + decoder->used, input, take);
54 decoder->used += take;
55 input += take;
56 length -= take;
57 if (decoder->used != decoder->size)
58 break;
59 asciichat_error_t result = packet_validate(decoder->packet, decoder->size, decoder->max_payload, NULL);
60 if (result == ASCIICHAT_OK)
61 result = emit(decoder->packet, decoder->size, arg);
62 // The callback borrows this storage; retain it for the next framed packet.
63 decoder->header_used = decoder->used = decoder->size = 0;
64 if (result != ASCIICHAT_OK) {
65 decoder->failed = true;
66 return result;
67 }
68 }
69 return ASCIICHAT_OK;
70}
#define SET_ERRNO(code,...)
asciichat_error_t buffer_workspace_reserve(buffer_workspace_t *workspace, buffer_domain_t *domain, size_t capacity)
Definition buffer.c:356
#define NET_TO_HOST_U64(val)
Definition endian.h:228
#define NET_TO_HOST_U32(val)
Definition endian.h:81
#define MIN(a, b)
Return the minimum of two values.
Definition common.h:170
unsigned char uint8_t
Definition common.h:60
asciichat_error_t
Error and exit codes - unified status values (0-255).
Definition error_codes.h:44
@ ERROR_NETWORK_PROTOCOL
Definition error_codes.h:76
@ ERROR_MEMORY
Definition error_codes.h:51
@ ASCIICHAT_OK
Definition error_codes.h:46
@ ERROR_INVALID_PARAM
asciichat_error_t packet_validate(const void *packet, size_t length, size_t limit, packet_header_t *output)
Definition packet.c:86
#define MAX_PACKET_SIZE
Maximum packet size (5MB).
Definition packet.h:130
#define PACKET_MAGIC
Packet magic number (alias for MAGIC_PACKET_VALID).
Definition packet.h:270
Owns the temporary storage used by buffer workspace. The data pointers and size or cursor fields desc...
Definition buffer.h:102
size_t max_payload
Zero uses MAX_PACKET_SIZE; set before the first feed.
uint8_t header[sizeof(packet_header_t)]
Fixed prefix shared by every ACIP packet on the wire.
Definition packet.h:628

References ASCIICHAT_OK, buffer_workspace_reserve(), buffer_workspace_t::data, ERROR_INVALID_PARAM, ERROR_MEMORY, ERROR_NETWORK_PROTOCOL, packet_decoder_t::failed, packet_decoder_t::header, packet_decoder_t::header_used, MAX_PACKET_SIZE, packet_decoder_t::max_payload, MIN, NET_TO_HOST_U32, NET_TO_HOST_U64, packet_decoder_t::packet, PACKET_MAGIC, packet_validate(), SET_ERRNO, packet_decoder_t::size, and packet_decoder_t::used.

Referenced by quic_stream_read().

◆ packet_decoder_pending()

bool packet_decoder_pending ( const packet_decoder_t * decoder)

Definition at line 15 of file network/packet/decoder.c.

15 {
16 return decoder && decoder->header_used != 0;
17}

References packet_decoder_t::header_used.

Referenced by quic_stream_finish().

◆ packet_decoder_reset()

void packet_decoder_reset ( packet_decoder_t * decoder)

Definition at line 8 of file network/packet/decoder.c.

8 {
9 if (decoder) {
10 buffer_release(decoder->packet);
11 memset(decoder, 0, sizeof(*decoder));
12 }
13}
#define buffer_release(data)
Definition buffer.h:91

References buffer_release, and packet_decoder_t::packet.

Referenced by quic_stream_reset().