summaryrefslogtreecommitdiff
path: root/src/util/packet.c
blob: dfac9aff644d0ecd2080c332c7ceb80d13042811 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
#include "packet.h"

struct nn_packet *nn_packet_create(void)
{
    struct nn_packet *packet = al_alloc_object(struct nn_packet);
    nn_buffer_init(&packet->buffer);
    nn_packet_reset(packet);
    return packet;
}

struct nn_packet *nn_packet_clone(struct nn_packet *packet)
{
    al_assert(packet->buffer.alloc >= NNWT_PACKET_HEADER_LENGTH);
    struct nn_packet *c = nn_packet_create();
    u32 size = nn_packet_get_size(packet);
    nn_buffer_ensure_space(&c->buffer, size);
    al_memcpy(nn_buffer_get_ptr(&c->buffer, 0), nn_buffer_get_ptr(&packet->buffer, 0), size);
    c->windex = packet->windex;
    c->rindex = packet->rindex;
    c->opaque = packet->opaque;
    return c;
}

void nn_packet_reset(struct nn_packet *packet)
{
    nn_buffer_ensure_space(&packet->buffer, NNWT_PACKET_HEADER_LENGTH);
    packet->rindex = NNWT_PACKET_HEADER_LENGTH;
    packet->windex = NNWT_PACKET_HEADER_LENGTH;
    packet->opaque = NULL;
}

void nn_packet_write_size(struct nn_packet *packet)
{
    struct nn_buffer *buffer = &packet->buffer;
    al_assert(buffer->alloc >= packet->windex);
    buffer->size = packet->windex;
    if (buffer->size < buffer->alloc / 2) {
        nn_buffer_shrink_to_size(buffer);
    }
    nn_buffer_write(buffer, &packet->windex, 0, sizeof(u32));
}

u32 nn_packet_get_size(struct nn_packet *packet)
{
    return nn_packet_get_u32(packet, 0);
}

#define DEFINE_PACKET_WRITE_FUNC(type) \
    void nn_packet_write_##type(struct nn_packet *packet, type v) \
    { \
        NNWT_PACKET_WRITE_TYPE(packet, type, v); \
    }

DEFINE_PACKET_WRITE_FUNC(u8)
DEFINE_PACKET_WRITE_FUNC(s8)
DEFINE_PACKET_WRITE_FUNC(u16)
DEFINE_PACKET_WRITE_FUNC(s16)
DEFINE_PACKET_WRITE_FUNC(u32)
DEFINE_PACKET_WRITE_FUNC(s32)
DEFINE_PACKET_WRITE_FUNC(u64)
DEFINE_PACKET_WRITE_FUNC(s64)
DEFINE_PACKET_WRITE_FUNC(f32)
DEFINE_PACKET_WRITE_FUNC(f64)

void nn_packet_write_bool(struct nn_packet *packet, bool v)
{
    u8 byte = v ? 1 : 0;
    NNWT_PACKET_WRITE_TYPE(packet, u8, byte);
}

void nn_packet_write_str(struct nn_packet *packet, str *s)
{
    NNWT_PACKET_WRITE_TYPE(packet, u32, s->length);
    NNWT_PACKET_WRITE_DATA(packet, s->data, s->length);
}

void nn_packet_write_buffer(struct nn_packet *packet, struct nn_buffer *buf)
{
    u64 size = (u64)buf->size;
    NNWT_PACKET_WRITE_TYPE(packet, u64, size);
    NNWT_PACKET_WRITE_DATA(packet, nn_buffer_get_ptr(buf, 0), buf->size);
}

#define DEFINE_PACKET_READ_FUNC(type) \
    type nn_packet_read_##type(struct nn_packet *packet) \
    { \
        type r; \
        NNWT_PACKET_READ_TYPE(packet, type, r); \
        return r; \
    }

DEFINE_PACKET_READ_FUNC(u8)
DEFINE_PACKET_READ_FUNC(s8)
DEFINE_PACKET_READ_FUNC(u16)
DEFINE_PACKET_READ_FUNC(s16)
DEFINE_PACKET_READ_FUNC(u32)
DEFINE_PACKET_READ_FUNC(s32)
DEFINE_PACKET_READ_FUNC(u64)
DEFINE_PACKET_READ_FUNC(s64)
DEFINE_PACKET_READ_FUNC(f32)
DEFINE_PACKET_READ_FUNC(f64)

bool nn_packet_read_bool(struct nn_packet *packet)
{
    u8 byte;
    NNWT_PACKET_READ_TYPE(packet, u8, byte);
    return byte == 1;
}

void nn_packet_read_str(struct nn_packet *packet, str *s)
{
    NNWT_PACKET_READ_TYPE(packet, u32, s->length);
    NNWT_PACKET_READ_DATA(packet, s->length, s->data);
    s->alloc = 0;
}

void nn_packet_read_buffer(struct nn_packet *packet, struct nn_buffer *buf)
{
    u64 size;
    NNWT_PACKET_READ_TYPE(packet, u64, size);
    al_assert(sizeof(size_t) > 4 || size <= INT32_MAX);
    buf->size = (size_t)size;
    NNWT_PACKET_READ_DATA(packet, buf->size, buf->data);
    buf->alloc = 0;
}

void nn_packet_write_wstr(struct nn_packet *packet, wstr *w)
{
    NNWT_PACKET_WRITE_TYPE(packet, u32, w->length);
    NNWT_PACKET_WRITE_DATA(packet, w->data, w->length * sizeof(wchar_t));
}

void nn_packet_read_wstr(struct nn_packet *packet, wstr *w)
{
    NNWT_PACKET_READ_TYPE(packet, u32, w->length);
    NNWT_PACKET_READ_DATA(packet, w->length * sizeof(wchar_t), w->data);
    w->alloc = 0;
}

void nn_packet_free(struct nn_packet *packet)
{
    nn_buffer_free(&packet->buffer);
    al_free(packet);
}