jancity/src/transport/src/heap.c

94 lines
1.9 KiB
C

#include <transport.h>
#include <transport_private.h>
#include <stdlib.h>
static void *alloc_common(void)
{
struct transport_common *const ret = malloc(sizeof *ret);
if (ret)
*ret = (const struct transport_common){0};
return ret;
}
static void *alloc_ack(void)
{
struct transport_packet_ack *const ret = malloc(sizeof *ret);
if (ret)
*ret = (const struct transport_packet_ack){0};
return ret;
}
static void *alloc_data(void)
{
struct transport_packet_data *const ret = malloc(sizeof *ret);
if (ret)
*ret = (const struct transport_packet_data){0};
return ret;
}
union transport_packet *transport_packet_alloc(const enum transport_packet_type t)
{
static void *(*const alloc[])(void) =
{
[TRANSPORT_PACKET_TYPE_CONNECT] = alloc_common,
[TRANSPORT_PACKET_TYPE_DISCONNECT] = alloc_common,
[TRANSPORT_PACKET_TYPE_NACK] = alloc_common,
[TRANSPORT_PACKET_TYPE_ACK] = alloc_ack,
[TRANSPORT_PACKET_TYPE_DATA] = alloc_data
};
union transport_packet *const ret = alloc[t]();
if (!ret)
return NULL;
ret->common.type = t;
return ret;
}
int transport_append(struct transport_handle *const h,
union transport_packet *const p)
{
h->packets = realloc(h->packets, (h->n_packets + 1) * sizeof *h->packets);
if (!h->packets)
return -1;
h->packets[h->n_packets++] = p;
return 0;
}
void transport_packet_free(union transport_packet *const p)
{
free(p);
}
int transport_pop(struct transport_handle *const h)
{
if (!h->n_packets)
return -1;
union transport_packet *const p = h->packets[--h->n_packets];
if (h->n_packets)
{
if (!(h->packets = realloc(h->packets,
h->n_packets * sizeof *h->packets)))
return -1;
}
else
{
free(h->packets);
h->packets = NULL;
}
transport_packet_free(p);
return 0;
}