summaryrefslogtreecommitdiff
path: root/toxcore/group.c
diff options
context:
space:
mode:
authorirungentoo <irungentoo@gmail.com>2014-09-25 15:10:54 -0400
committerirungentoo <irungentoo@gmail.com>2014-09-25 15:10:54 -0400
commitaca2d618435388fb3029c9db6d9ea1c5ba427cbe (patch)
tree77aca87a9538af083a6503338fe85d8b67a2566f /toxcore/group.c
parentd2640103649b4513d2fc4d7bbb291fa941023ebf (diff)
Some code written for new group chats.
Diffstat (limited to 'toxcore/group.c')
-rw-r--r--toxcore/group.c331
1 files changed, 331 insertions, 0 deletions
diff --git a/toxcore/group.c b/toxcore/group.c
new file mode 100644
index 00000000..65ae078c
--- /dev/null
+++ b/toxcore/group.c
@@ -0,0 +1,331 @@
1/* group.c
2 *
3 * Slightly better groupchats implementation.
4 *
5 * Copyright (C) 2014 Tox project All Rights Reserved.
6 *
7 * This file is part of Tox.
8 *
9 * Tox is free software: you can redistribute it and/or modify
10 * it under the terms of the GNU General Public License as published by
11 * the Free Software Foundation, either version 3 of the License, or
12 * (at your option) any later version.
13 *
14 * Tox is distributed in the hope that it will be useful,
15 * but WITHOUT ANY WARRANTY; without even the implied warranty of
16 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
17 * GNU General Public License for more details.
18 *
19 * You should have received a copy of the GNU General Public License
20 * along with Tox. If not, see <http://www.gnu.org/licenses/>.
21 *
22 */
23
24#ifdef HAVE_CONFIG_H
25#include "config.h"
26#endif
27
28#include "group.h"
29#include "util.h"
30
31/* return 1 if the con_number is not valid.
32 * return 0 if the con_number is valid.
33 */
34static uint8_t con_number_not_valid(const Group_Chats *g_c, int con_number)
35{
36 if ((unsigned int)con_number >= g_c->num_cons)
37 return 1;
38
39 if (g_c->cons == NULL)
40 return 1;
41
42 if (g_c->cons[con_number].status == GROUPCON_STATUS_NONE)
43 return 1;
44
45 return 0;
46}
47
48
49/* Set the size of the groupchat connections list to num.
50 *
51 * return -1 if realloc fails.
52 * return 0 if it succeeds.
53 */
54static int realloc_groupcons(Group_Chats *g_c, uint32_t num)
55{
56 if (num == 0) {
57 free(g_c->cons);
58 g_c->cons = NULL;
59 return 0;
60 }
61
62 Group_Connection *newgroup_cons = realloc(g_c->cons, num * sizeof(Group_Connection));
63
64 if (newgroup_cons == NULL)
65 return -1;
66
67 g_c->cons = newgroup_cons;
68 return 0;
69}
70
71/* Create a new empty groupchat connection.
72 *
73 * return -1 on failure.
74 * return con_number on success.
75 */
76static int create_group_con(Group_Chats *g_c)
77{
78 uint32_t i;
79
80 for (i = 0; i < g_c->num_cons; ++i) {
81 if (g_c->cons[i].status == GROUPCON_STATUS_NONE)
82 return i;
83 }
84
85 int id = -1;
86
87 if (realloc_groupcons(g_c, g_c->num_cons + 1) == 0) {
88 id = g_c->num_cons;
89 ++g_c->num_cons;
90 memset(&(g_c->cons[id]), 0, sizeof(Group_Connection));
91 }
92
93 return id;
94}
95
96/* Wipe a groupchat connection.
97 *
98 * return -1 on failure.
99 * return 0 on success.
100 */
101static int wipe_group_con(Group_Chats *g_c, int con_number)
102{
103 if (con_number_not_valid(g_c, con_number))
104 return -1;
105
106 uint32_t i;
107 memset(&(g_c->cons[con_number]), 0 , sizeof(Group_c));
108
109 for (i = g_c->num_cons; i != 0; --i) {
110 if (g_c->cons[i - 1].status != GROUPCON_STATUS_NONE)
111 break;
112 }
113
114 if (g_c->num_cons != i) {
115 g_c->num_cons = i;
116 realloc_groupcons(g_c, g_c->num_cons);
117 }
118
119 return 0;
120}
121
122static Group_Connection *get_con_group(Group_Chats *g_c, int con_number)
123{
124 if (con_number_not_valid(g_c, con_number))
125 return 0;
126
127 return &g_c->cons[con_number];
128}
129
130/* return 1 if the groupnumber is not valid.
131 * return 0 if the groupnumber is valid.
132 */
133static uint8_t groupnumber_not_valid(const Group_Chats *g_c, int groupnumber)
134{
135 if ((unsigned int)groupnumber >= g_c->num_chats)
136 return 1;
137
138 if (g_c->chats == NULL)
139 return 1;
140
141 if (g_c->chats[groupnumber].status == GROUPCHAT_STATUS_NONE)
142 return 1;
143
144 return 0;
145}
146
147
148/* Set the size of the groupchat list to num.
149 *
150 * return -1 if realloc fails.
151 * return 0 if it succeeds.
152 */
153static int realloc_groupchats(Group_Chats *g_c, uint32_t num)
154{
155 if (num == 0) {
156 free(g_c->chats);
157 g_c->chats = NULL;
158 return 0;
159 }
160
161 Group_c *newgroup_chats = realloc(g_c->chats, num * sizeof(Group_c));
162
163 if (newgroup_chats == NULL)
164 return -1;
165
166 g_c->chats = newgroup_chats;
167 return 0;
168}
169
170
171/* Create a new empty groupchat connection.
172 *
173 * return -1 on failure.
174 * return groupnumber on success.
175 */
176static int create_group_chat(Group_Chats *g_c)
177{
178 uint32_t i;
179
180 for (i = 0; i < g_c->num_chats; ++i) {
181 if (g_c->chats[i].status == GROUPCHAT_STATUS_NONE)
182 return i;
183 }
184
185 int id = -1;
186
187 if (realloc_groupchats(g_c, g_c->num_chats + 1) == 0) {
188 id = g_c->num_chats;
189 ++g_c->num_chats;
190 memset(&(g_c->chats[id]), 0, sizeof(Group_c));
191 }
192
193 return id;
194}
195
196
197/* Wipe a groupchat.
198 *
199 * return -1 on failure.
200 * return 0 on success.
201 */
202static int wipe_group_chat(Group_Chats *g_c, int groupnumber)
203{
204 if (groupnumber_not_valid(g_c, groupnumber))
205 return -1;
206
207 uint32_t i;
208 memset(&(g_c->chats[groupnumber]), 0 , sizeof(Group_c));
209
210 for (i = g_c->num_chats; i != 0; --i) {
211 if (g_c->chats[i - 1].status != GROUPCHAT_STATUS_NONE)
212 break;
213 }
214
215 if (g_c->num_chats != i) {
216 g_c->num_chats = i;
217 realloc_groupchats(g_c, g_c->num_chats);
218 }
219
220 return 0;
221}
222
223static Group_c *get_group_c(Group_Chats *g_c, int groupnumber)
224{
225 if (groupnumber_not_valid(g_c, groupnumber))
226 return 0;
227
228 return &g_c->chats[groupnumber];
229}
230
231/*
232 * check if peer with client_id is in peer array.
233 *
234 * return peer number if peer is in chat.
235 * return -1 if peer is not in chat.
236 *
237 * TODO: make this more efficient.
238 */
239
240static int peer_in_chat(const Group_c *chat, const uint8_t *client_id)
241{
242 uint32_t i;
243
244 for (i = 0; i < chat->numpeers; ++i)
245 if (id_equal(chat->group[i].client_id, client_id))
246 return i;
247
248 return -1;
249}
250
251/*
252 * Add a peer to the group chat.
253 *
254 * return peernum if success or peer already in chat.
255 * return -1 if error.
256 */
257static int addpeer(Group_c *chat, const uint8_t *client_id)
258{
259 int peernum = peer_in_chat(chat, client_id);
260
261 if (peernum != -1)
262 return peernum;
263
264 Group_Peer *temp;
265 temp = realloc(chat->group, sizeof(Group_Peer) * (chat->numpeers + 1));
266
267 if (temp == NULL)
268 return -1;
269
270 memset(&(temp[chat->numpeers]), 0, sizeof(Group_Peer));
271 chat->group = temp;
272
273 id_copy(chat->group[chat->numpeers].client_id, client_id);
274 chat->group[chat->numpeers].last_recv = unix_time();
275 chat->group[chat->numpeers].last_recv_msgping = unix_time();
276 ++chat->numpeers;
277
278 //if (chat->peer_namelistchange != NULL)
279 // (*chat->peer_namelistchange)(chat, chat->numpeers - 1, CHAT_CHANGE_PEER_ADD, chat->group_namelistchange_userdata);
280
281 return (chat->numpeers - 1);
282}
283
284
285/* Creates a new groupchat and puts it in the chats array.
286 *
287 * return group number on success.
288 * return -1 on failure.
289 */
290int temp_c_add_groupchat(Group_Chats *g_c)
291{
292 int groupnumber = create_group_chat(g_c);
293
294 Group_c *g = get_group_c(g_c, groupnumber);
295
296 if (!g) {
297 return -1;
298 }
299
300 g->status = GROUPCHAT_STATUS_VALID;
301 return groupnumber;
302}
303
304/* Create new groupchat instance. */
305Group_Chats *new_groupchats(Messenger *m)
306{
307 if (!m)
308 return NULL;
309
310 Group_Chats *temp = calloc(1, sizeof(Group_Chats));
311
312 if (temp == NULL)
313 return NULL;
314
315 temp->m = m;
316 return temp;
317}
318
319/* main groupchats loop. */
320void do_groupchats(Group_Chats *g_c)
321{
322 //TODO
323}
324
325/* Free everything related with group chats. */
326void kill_groupchats(Group_Chats *g_c)
327{
328 //TODO
329 free(g_c);
330}
331