Coverage Report

Created: 2024-01-26 01:52

/work/toxcore/events/friend_message.c
Line
Count
Source (jump to first uncovered line)
1
/* SPDX-License-Identifier: GPL-3.0-or-later
2
 * Copyright © 2023-2024 The TokTok team.
3
 */
4
5
#include "events_alloc.h"
6
7
#include <assert.h>
8
#include <stdlib.h>
9
#include <string.h>
10
11
#include "../bin_pack.h"
12
#include "../bin_unpack.h"
13
#include "../ccompat.h"
14
#include "../mem.h"
15
#include "../tox.h"
16
#include "../tox_events.h"
17
#include "../tox_pack.h"
18
#include "../tox_unpack.h"
19
20
21
/*****************************************************
22
 *
23
 * :: struct and accessors
24
 *
25
 *****************************************************/
26
27
28
struct Tox_Event_Friend_Message {
29
    uint32_t friend_number;
30
    Tox_Message_Type type;
31
    uint8_t *message;
32
    uint32_t message_length;
33
};
34
35
non_null()
36
static void tox_event_friend_message_set_friend_number(Tox_Event_Friend_Message *friend_message,
37
        uint32_t friend_number)
38
41.5k
{
39
41.5k
    assert(friend_message != nullptr);
40
41.5k
    friend_message->friend_number = friend_number;
41
41.5k
}
42
uint32_t tox_event_friend_message_get_friend_number(const Tox_Event_Friend_Message *friend_message)
43
0
{
44
0
    assert(friend_message != nullptr);
45
0
    return friend_message->friend_number;
46
0
}
47
48
non_null()
49
static void tox_event_friend_message_set_type(Tox_Event_Friend_Message *friend_message,
50
        Tox_Message_Type type)
51
41.5k
{
52
41.5k
    assert(friend_message != nullptr);
53
41.5k
    friend_message->type = type;
54
41.5k
}
55
Tox_Message_Type tox_event_friend_message_get_type(const Tox_Event_Friend_Message *friend_message)
56
105
{
57
105
    assert(friend_message != nullptr);
58
105
    return friend_message->type;
59
105
}
60
61
non_null(1) nullable(2)
62
static bool tox_event_friend_message_set_message(Tox_Event_Friend_Message *friend_message,
63
        const uint8_t *message, uint32_t message_length)
64
41.5k
{
65
41.5k
    assert(friend_message != nullptr);
66
67
41.5k
    if (friend_message->message != nullptr) {
68
0
        free(friend_message->message);
69
0
        friend_message->message = nullptr;
70
0
        friend_message->message_length = 0;
71
0
    }
72
73
41.5k
    if (message == nullptr) {
74
0
        assert(message_length == 0);
75
0
        return true;
76
0
    }
77
78
41.5k
    uint8_t *message_copy = (uint8_t *)malloc(message_length);
79
80
41.5k
    if (message_copy == nullptr) {
81
5
        return false;
82
5
    }
83
84
41.5k
    memcpy(message_copy, message, message_length);
85
41.5k
    friend_message->message = message_copy;
86
41.5k
    friend_message->message_length = message_length;
87
41.5k
    return true;
88
41.5k
}
89
uint32_t tox_event_friend_message_get_message_length(const Tox_Event_Friend_Message *friend_message)
90
110
{
91
110
    assert(friend_message != nullptr);
92
110
    return friend_message->message_length;
93
110
}
94
const uint8_t *tox_event_friend_message_get_message(const Tox_Event_Friend_Message *friend_message)
95
110
{
96
110
    assert(friend_message != nullptr);
97
110
    return friend_message->message;
98
110
}
99
100
non_null()
101
static void tox_event_friend_message_construct(Tox_Event_Friend_Message *friend_message)
102
41.6k
{
103
41.6k
    *friend_message = (Tox_Event_Friend_Message) {
104
41.6k
        0
105
41.6k
    };
106
41.6k
}
107
non_null()
108
static void tox_event_friend_message_destruct(Tox_Event_Friend_Message *friend_message, const Memory *mem)
109
41.5k
{
110
41.5k
    free(friend_message->message);
111
41.5k
}
112
113
bool tox_event_friend_message_pack(
114
    const Tox_Event_Friend_Message *event, Bin_Pack *bp)
115
9
{
116
9
    return bin_pack_array(bp, 3)
117
9
           && bin_pack_u32(bp, event->friend_number)
118
9
           && tox_message_type_pack(event->type, bp)
119
9
           && bin_pack_bin(bp, event->message, event->message_length);
120
9
}
121
122
non_null()
123
static bool tox_event_friend_message_unpack_into(
124
    Tox_Event_Friend_Message *event, Bin_Unpack *bu)
125
7
{
126
7
    assert(event != nullptr);
127
7
    if (!bin_unpack_array_fixed(bu, 3, nullptr)) {
128
2
        return false;
129
2
    }
130
131
5
    return bin_unpack_u32(bu, &event->friend_number)
132
5
           && tox_message_type_unpack(&event->type, bu)
133
5
           && bin_unpack_bin(bu, &event->message, &event->message_length);
134
7
}
135
136
137
/*****************************************************
138
 *
139
 * :: new/free/add/get/size/unpack
140
 *
141
 *****************************************************/
142
143
const Tox_Event_Friend_Message *tox_event_get_friend_message(const Tox_Event *event)
144
4
{
145
4
    return event->type == TOX_EVENT_FRIEND_MESSAGE ? event->data.friend_message : nullptr;
146
4
}
147
148
Tox_Event_Friend_Message *tox_event_friend_message_new(const Memory *mem)
149
41.6k
{
150
41.6k
    Tox_Event_Friend_Message *const friend_message =
151
41.6k
        (Tox_Event_Friend_Message *)mem_alloc(mem, sizeof(Tox_Event_Friend_Message));
152
153
41.6k
    if (friend_message == nullptr) {
154
6
        return nullptr;
155
6
    }
156
157
41.6k
    tox_event_friend_message_construct(friend_message);
158
41.6k
    return friend_message;
159
41.6k
}
160
161
void tox_event_friend_message_free(Tox_Event_Friend_Message *friend_message, const Memory *mem)
162
41.5k
{
163
41.5k
    if (friend_message != nullptr) {
164
41.5k
        tox_event_friend_message_destruct(friend_message, mem);
165
41.5k
    }
166
41.5k
    mem_delete(mem, friend_message);
167
41.5k
}
168
169
non_null()
170
static Tox_Event_Friend_Message *tox_events_add_friend_message(Tox_Events *events, const Memory *mem)
171
41.6k
{
172
41.6k
    Tox_Event_Friend_Message *const friend_message = tox_event_friend_message_new(mem);
173
174
41.6k
    if (friend_message == nullptr) {
175
5
        return nullptr;
176
5
    }
177
178
41.5k
    Tox_Event event;
179
41.5k
    event.type = TOX_EVENT_FRIEND_MESSAGE;
180
41.5k
    event.data.friend_message = friend_message;
181
182
41.5k
    tox_events_add(events, &event);
183
41.5k
    return friend_message;
184
41.6k
}
185
186
bool tox_event_friend_message_unpack(
187
    Tox_Event_Friend_Message **event, Bin_Unpack *bu, const Memory *mem)
188
8
{
189
8
    assert(event != nullptr);
190
8
    assert(*event == nullptr);
191
8
    *event = tox_event_friend_message_new(mem);
192
193
8
    if (*event == nullptr) {
194
1
        return false;
195
1
    }
196
197
7
    return tox_event_friend_message_unpack_into(*event, bu);
198
8
}
199
200
non_null()
201
static Tox_Event_Friend_Message *tox_event_friend_message_alloc(void *user_data)
202
41.6k
{
203
41.6k
    Tox_Events_State *state = tox_events_alloc(user_data);
204
41.6k
    assert(state != nullptr);
205
206
41.6k
    if (state->events == nullptr) {
207
4
        return nullptr;
208
4
    }
209
210
41.6k
    Tox_Event_Friend_Message *friend_message = tox_events_add_friend_message(state->events, state->mem);
211
212
41.6k
    if (friend_message == nullptr) {
213
5
        state->error = TOX_ERR_EVENTS_ITERATE_MALLOC;
214
5
        return nullptr;
215
5
    }
216
217
41.5k
    return friend_message;
218
41.6k
}
219
220
221
/*****************************************************
222
 *
223
 * :: event handler
224
 *
225
 *****************************************************/
226
227
228
void tox_events_handle_friend_message(Tox *tox, uint32_t friend_number, Tox_Message_Type type, const uint8_t *message, size_t length,
229
        void *user_data)
230
41.6k
{
231
41.6k
    Tox_Event_Friend_Message *friend_message = tox_event_friend_message_alloc(user_data);
232
233
41.6k
    if (friend_message == nullptr) {
234
9
        return;
235
9
    }
236
237
41.5k
    tox_event_friend_message_set_friend_number(friend_message, friend_number);
238
41.5k
    tox_event_friend_message_set_type(friend_message, type);
239
41.5k
    tox_event_friend_message_set_message(friend_message, message, length);
240
41.5k
}