1
2 /*
3 Meanwhile - Unofficial Lotus Sametime Community Client Library
4 Copyright (C) 2004 Christopher (siege) O'Brien
5
6 This library is free software; you can redistribute it and/or
7 modify it under the terms of the GNU Library General Public
8 License as published by the Free Software Foundation; either
9 version 2 of the License, or (at your option) any later version.
10
11 This library is distributed in the hope that it will be useful,
12 but WITHOUT ANY WARRANTY; without even the implied warranty of
13 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14 Library General Public License for more details.
15
16 You should have received a copy of the GNU Library General Public
17 License along with this library; if not, write to the Free
18 Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
19 */
20
21 #include <glib.h>
22 #include <string.h>
23
24 #include "mw_common.h"
25
26
27 /** @todo the *_get functions should make sure to clear their
28 structures in the event of failure, to prevent memory leaks */
29
30
31 #define MW16_PUT(b, val) \
32 *(b)++ = ((val) >> 0x08) & 0xff; \
33 *(b)++ = (val) & 0xff;
34
35
36 #define MW16_GET(b, val) \
37 val = (*(b)++ & 0xff) << 8; \
38 val = val | (*(b)++ & 0xff);
39
40
41 #define MW32_PUT(b, val) \
42 *(b)++ = ((val) >> 0x18) & 0xff; \
43 *(b)++ = ((val) >> 0x10) & 0xff; \
44 *(b)++ = ((val) >> 0x08) & 0xff; \
45 *(b)++ = (val) & 0xff;
46
47
48 #define MW32_GET(b, val) \
49 val = (*(b)++ & 0xff) << 0x18; \
50 val = val | (*(b)++ & 0xff) << 0x10; \
51 val = val | (*(b)++ & 0xff) << 0x08; \
52 val = val | (*(b)++ & 0xff);
53
54
55 struct mwPutBuffer {
56 guchar *buf; /**< head of buffer */
57 gsize len; /**< length of buffer */
58
59 guchar *ptr; /**< offset to first unused byte */
60 gsize rem; /**< count of unused bytes remaining */
61 };
62
63
64 struct mwGetBuffer {
65 guchar *buf; /**< head of buffer */
66 gsize len; /**< length of buffer */
67
68 guchar *ptr; /**< offset to first unused byte */
69 gsize rem; /**< count of unused bytes remaining */
70
71 gboolean wrap; /**< TRUE to indicate buf shouldn't be freed */
72 gboolean error; /**< TRUE to indicate an error */
73 };
74
75
76 #define BUFFER_USED(buffer) \
77 ((buffer)->len - (buffer)->rem)
78
79
80 /** ensure that there's at least enough space remaining in the put
81 buffer to fit needed. */
ensure_buffer(struct mwPutBuffer * b,gsize needed)82 static void ensure_buffer(struct mwPutBuffer *b, gsize needed) {
83 if(b->rem < needed) {
84 gsize len = b->len, use = BUFFER_USED(b);
85 guchar *buf;
86
87 /* newly created buffers are empty until written to, and then they
88 have 1024 available */
89 if(! len) len = 1024;
90
91 /* double len until it's large enough to fit needed */
92 while( (len - use) < needed ) len = len << 1;
93
94 /* create the new buffer. if there was anything in the old buffer,
95 copy it into the new buffer and free the old copy */
96 buf = g_malloc(len);
97 if(b->buf) {
98 memcpy(buf, b->buf, use);
99 g_free(b->buf);
100 }
101
102 /* put the new buffer into b */
103 b->buf = buf;
104 b->len = len;
105 b->ptr = buf + use;
106 b->rem = len - use;
107 }
108 }
109
110
111 /** determine if there are at least needed bytes available in the
112 buffer. sets the error flag if there's not at least needed bytes
113 left in the buffer
114
115 @returns true if there's enough data, false if not */
check_buffer(struct mwGetBuffer * b,gsize needed)116 static gboolean check_buffer(struct mwGetBuffer *b, gsize needed) {
117 if(! b->error) b->error = (b->rem < needed);
118 return ! b->error;
119 }
120
121
mwPutBuffer_new()122 struct mwPutBuffer *mwPutBuffer_new() {
123 return g_new0(struct mwPutBuffer, 1);
124 }
125
126
mwPutBuffer_write(struct mwPutBuffer * b,gpointer data,gsize len)127 void mwPutBuffer_write(struct mwPutBuffer *b, gpointer data, gsize len) {
128 g_return_if_fail(b != NULL);
129 g_return_if_fail(data != NULL);
130
131 if(! len) return;
132
133 ensure_buffer(b, len);
134 memcpy(b->ptr, data, len);
135 b->ptr += len;
136 b->rem -= len;
137 }
138
139
mwPutBuffer_free(struct mwPutBuffer * b)140 void mwPutBuffer_free(struct mwPutBuffer *b) {
141 if(! b) return;
142 g_free(b->buf);
143 g_free(b);
144 }
145
146
mwPutBuffer_finalize(struct mwOpaque * to,struct mwPutBuffer * from)147 void mwPutBuffer_finalize(struct mwOpaque *to, struct mwPutBuffer *from) {
148 g_return_if_fail(to != NULL);
149 g_return_if_fail(from != NULL);
150
151 to->len = BUFFER_USED(from);
152 to->data = from->buf;
153
154 g_free(from);
155 }
156
157
mwGetBuffer_new(struct mwOpaque * o)158 struct mwGetBuffer *mwGetBuffer_new(struct mwOpaque *o) {
159 struct mwGetBuffer *b = g_new0(struct mwGetBuffer, 1);
160
161 if(o && o->len) {
162 b->buf = b->ptr = g_memdup(o->data, o->len);
163 b->len = b->rem = o->len;
164 }
165
166 return b;
167 }
168
169
mwGetBuffer_wrap(const struct mwOpaque * o)170 struct mwGetBuffer *mwGetBuffer_wrap(const struct mwOpaque *o) {
171 struct mwGetBuffer *b = g_new0(struct mwGetBuffer, 1);
172
173 if(o && o->len) {
174 b->buf = b->ptr = o->data;
175 b->len = b->rem = o->len;
176 }
177 b->wrap = TRUE;
178
179 return b;
180 }
181
182
mwGetBuffer_read(struct mwGetBuffer * b,gpointer data,gsize len)183 gsize mwGetBuffer_read(struct mwGetBuffer *b, gpointer data, gsize len) {
184 g_return_val_if_fail(b != NULL, 0);
185 g_return_val_if_fail(data != NULL, 0);
186
187 if(b->error) return 0;
188 if(! len) return 0;
189
190 if(b->rem < len)
191 len = b->rem;
192
193 memcpy(data, b->ptr, len);
194 b->ptr += len;
195 b->rem -= len;
196
197 return len;
198 }
199
200
mwGetBuffer_advance(struct mwGetBuffer * b,gsize len)201 gsize mwGetBuffer_advance(struct mwGetBuffer *b, gsize len) {
202 g_return_val_if_fail(b != NULL, 0);
203
204 if(b->error) return 0;
205 if(! len) return 0;
206
207 if(b->rem < len)
208 len = b->rem;
209
210 b->ptr += len;
211 b->rem -= len;
212
213 return len;
214 }
215
216
mwGetBuffer_reset(struct mwGetBuffer * b)217 void mwGetBuffer_reset(struct mwGetBuffer *b) {
218 g_return_if_fail(b != NULL);
219
220 b->rem = b->len;
221 b->ptr = b->buf;
222 b->error = FALSE;
223 }
224
225
mwGetBuffer_remaining(struct mwGetBuffer * b)226 gsize mwGetBuffer_remaining(struct mwGetBuffer *b) {
227 g_return_val_if_fail(b != NULL, 0);
228 return b->rem;
229 }
230
231
mwGetBuffer_error(struct mwGetBuffer * b)232 gboolean mwGetBuffer_error(struct mwGetBuffer *b) {
233 g_return_val_if_fail(b != NULL, TRUE);
234 return b->error;
235 }
236
237
mwGetBuffer_free(struct mwGetBuffer * b)238 void mwGetBuffer_free(struct mwGetBuffer *b) {
239 if(! b) return;
240 if(! b->wrap) g_free(b->buf);
241 g_free(b);
242 }
243
244
245 #define guint16_buflen() 2
246
247
guint16_put(struct mwPutBuffer * b,guint16 val)248 void guint16_put(struct mwPutBuffer *b, guint16 val) {
249 g_return_if_fail(b != NULL);
250
251 ensure_buffer(b, guint16_buflen());
252 MW16_PUT(b->ptr, val);
253 b->rem -= guint16_buflen();
254 }
255
256
guint16_get(struct mwGetBuffer * b,guint16 * val)257 void guint16_get(struct mwGetBuffer *b, guint16 *val) {
258 g_return_if_fail(b != NULL);
259
260 if(b->error) return;
261 g_return_if_fail(check_buffer(b, guint16_buflen()));
262
263 MW16_GET(b->ptr, *val);
264 b->rem -= guint16_buflen();
265 }
266
267
guint16_peek(struct mwGetBuffer * b)268 guint16 guint16_peek(struct mwGetBuffer *b) {
269 guchar *buf = b->buf;
270 guint16 r = 0;
271
272 if(b->rem >= guint16_buflen())
273 MW16_GET(buf, r);
274
275 return r;
276 }
277
278
279 #define guint32_buflen() 4
280
281
guint32_put(struct mwPutBuffer * b,guint32 val)282 void guint32_put(struct mwPutBuffer *b, guint32 val) {
283 g_return_if_fail(b != NULL);
284
285 ensure_buffer(b, guint32_buflen());
286 MW32_PUT(b->ptr, val);
287 b->rem -= guint32_buflen();
288 }
289
290
guint32_get(struct mwGetBuffer * b,guint32 * val)291 void guint32_get(struct mwGetBuffer *b, guint32 *val) {
292 g_return_if_fail(b != NULL);
293
294 if(b->error) return;
295 g_return_if_fail(check_buffer(b, guint32_buflen()));
296
297 MW32_GET(b->ptr, *val);
298 b->rem -= guint32_buflen();
299 }
300
301
guint32_peek(struct mwGetBuffer * b)302 guint32 guint32_peek(struct mwGetBuffer *b) {
303 guchar *buf = b->buf;
304 guint32 r = 0;
305
306 if(b->rem >= guint32_buflen())
307 MW32_GET(buf, r);
308
309 return r;
310 }
311
312
313 #define gboolean_buflen() 1
314
315
gboolean_put(struct mwPutBuffer * b,gboolean val)316 void gboolean_put(struct mwPutBuffer *b, gboolean val) {
317 g_return_if_fail(b != NULL);
318
319 ensure_buffer(b, gboolean_buflen());
320 *(b->ptr) = !! val;
321 b->ptr++;
322 b->rem--;
323 }
324
325
gboolean_get(struct mwGetBuffer * b,gboolean * val)326 void gboolean_get(struct mwGetBuffer *b, gboolean *val) {
327 g_return_if_fail(b != NULL);
328
329 if(b->error) return;
330 g_return_if_fail(check_buffer(b, gboolean_buflen()));
331
332 *val = !! *(b->ptr);
333 b->ptr++;
334 b->rem--;
335 }
336
337
gboolean_peek(struct mwGetBuffer * b)338 gboolean gboolean_peek(struct mwGetBuffer *b) {
339 gboolean v = FALSE;
340
341 if(b->rem >= gboolean_buflen())
342 v = !! *(b->ptr);
343
344 return v;
345 }
346
347
mw_streq(const char * a,const char * b)348 static gboolean mw_streq(const char *a, const char *b) {
349 return (a == b) || (a && b && !strcmp(a, b));
350 }
351
352
mwString_put(struct mwPutBuffer * b,const char * val)353 void mwString_put(struct mwPutBuffer *b, const char *val) {
354 gsize len = 0;
355
356 g_return_if_fail(b != NULL);
357
358 if(val) len = strlen(val);
359
360 guint16_put(b, (guint16) len);
361
362 if(len) {
363 ensure_buffer(b, len);
364 memcpy(b->ptr, val, len);
365 b->ptr += len;
366 b->rem -= len;
367 }
368 }
369
370
mwString_get(struct mwGetBuffer * b,char ** val)371 void mwString_get(struct mwGetBuffer *b, char **val) {
372 guint16 len = 0;
373
374 g_return_if_fail(b != NULL);
375 g_return_if_fail(val != NULL);
376
377 *val = NULL;
378
379 if(b->error) return;
380 guint16_get(b, &len);
381
382 g_return_if_fail(check_buffer(b, (gsize) len));
383
384 if(len) {
385 *val = g_malloc0(len + 1);
386 memcpy(*val, b->ptr, len);
387 b->ptr += len;
388 b->rem -= len;
389 }
390 }
391
392
mwOpaque_put(struct mwPutBuffer * b,const struct mwOpaque * o)393 void mwOpaque_put(struct mwPutBuffer *b, const struct mwOpaque *o) {
394 gsize len;
395
396 g_return_if_fail(b != NULL);
397
398 if(! o) {
399 guint32_put(b, 0x00);
400 return;
401 }
402
403 len = o->len;
404 if(len)
405 g_return_if_fail(o->data != NULL);
406
407 guint32_put(b, (guint32) len);
408
409 if(len) {
410 ensure_buffer(b, len);
411 memcpy(b->ptr, o->data, len);
412 b->ptr += len;
413 b->rem -= len;
414 }
415 }
416
417
mwOpaque_get(struct mwGetBuffer * b,struct mwOpaque * o)418 void mwOpaque_get(struct mwGetBuffer *b, struct mwOpaque *o) {
419 guint32 tmp = 0;
420
421 g_return_if_fail(b != NULL);
422 g_return_if_fail(o != NULL);
423
424 o->len = 0;
425 o->data = NULL;
426
427 if(b->error) return;
428 guint32_get(b, &tmp);
429
430 g_return_if_fail(check_buffer(b, (gsize) tmp));
431
432 o->len = (gsize) tmp;
433 if(tmp > 0) {
434 o->data = g_memdup(b->ptr, tmp);
435 b->ptr += tmp;
436 b->rem -= tmp;
437 }
438 }
439
440
mwOpaque_clear(struct mwOpaque * o)441 void mwOpaque_clear(struct mwOpaque *o) {
442 if(! o) return;
443 g_free(o->data);
444 o->data = NULL;
445 o->len = 0;
446 }
447
448
mwOpaque_free(struct mwOpaque * o)449 void mwOpaque_free(struct mwOpaque *o) {
450 if(! o) return;
451 g_free(o->data);
452 g_free(o);
453 }
454
455
mwOpaque_clone(struct mwOpaque * to,const struct mwOpaque * from)456 void mwOpaque_clone(struct mwOpaque *to, const struct mwOpaque *from) {
457 g_return_if_fail(to != NULL);
458
459 to->len = 0;
460 to->data = NULL;
461
462 if(from) {
463 to->len = from->len;
464 if(to->len)
465 to->data = g_memdup(from->data, to->len);
466 }
467 }
468
469
470 /* 8.2 Common Structures */
471 /* 8.2.1 Login Info block */
472
473
mwLoginInfo_put(struct mwPutBuffer * b,const struct mwLoginInfo * login)474 void mwLoginInfo_put(struct mwPutBuffer *b, const struct mwLoginInfo *login) {
475 g_return_if_fail(b != NULL);
476 g_return_if_fail(login != NULL);
477
478 mwString_put(b, login->login_id);
479 guint16_put(b, login->type);
480 mwString_put(b, login->user_id);
481 mwString_put(b, login->user_name);
482 mwString_put(b, login->community);
483 gboolean_put(b, login->full);
484
485 if(login->full) {
486 mwString_put(b, login->desc);
487 guint32_put(b, login->ip_addr);
488 mwString_put(b, login->server_id);
489 }
490 }
491
492
mwLoginInfo_get(struct mwGetBuffer * b,struct mwLoginInfo * login)493 void mwLoginInfo_get(struct mwGetBuffer *b, struct mwLoginInfo *login) {
494 g_return_if_fail(b != NULL);
495 g_return_if_fail(login != NULL);
496
497 if(b->error) return;
498
499 mwString_get(b, &login->login_id);
500 guint16_get(b, &login->type);
501 mwString_get(b, &login->user_id);
502 mwString_get(b, &login->user_name);
503 mwString_get(b, &login->community);
504 gboolean_get(b, &login->full);
505
506 if(login->full) {
507 mwString_get(b, &login->desc);
508 guint32_get(b, &login->ip_addr);
509 mwString_get(b, &login->server_id);
510 }
511 }
512
513
mwLoginInfo_clear(struct mwLoginInfo * login)514 void mwLoginInfo_clear(struct mwLoginInfo *login) {
515 if(! login) return;
516
517 g_free(login->login_id);
518 g_free(login->user_id);
519 g_free(login->user_name);
520 g_free(login->community);
521 g_free(login->desc);
522 g_free(login->server_id);
523
524 memset(login, 0x00, sizeof(struct mwLoginInfo));
525 }
526
527
mwLoginInfo_clone(struct mwLoginInfo * to,const struct mwLoginInfo * from)528 void mwLoginInfo_clone(struct mwLoginInfo *to,
529 const struct mwLoginInfo *from) {
530
531 g_return_if_fail(to != NULL);
532 g_return_if_fail(from != NULL);
533
534 to->login_id= g_strdup(from->login_id);
535 to->type = from->type;
536 to->user_id = g_strdup(from->user_id);
537 to->user_name = g_strdup(from->user_name);
538 to->community = g_strdup(from->community);
539
540 if( (to->full = from->full) ) {
541 to->desc = g_strdup(from->desc);
542 to->ip_addr = from->ip_addr;
543 to->server_id = g_strdup(from->server_id);
544 }
545 }
546
547
548 /* 8.2.2 Private Info Block */
549
550
mwUserItem_put(struct mwPutBuffer * b,const struct mwUserItem * user)551 void mwUserItem_put(struct mwPutBuffer *b, const struct mwUserItem *user) {
552 g_return_if_fail(b != NULL);
553 g_return_if_fail(user != NULL);
554
555 gboolean_put(b, user->full);
556 mwString_put(b, user->id);
557 mwString_put(b, user->community);
558
559 if(user->full)
560 mwString_put(b, user->name);
561 }
562
563
mwUserItem_get(struct mwGetBuffer * b,struct mwUserItem * user)564 void mwUserItem_get(struct mwGetBuffer *b, struct mwUserItem *user) {
565 g_return_if_fail(b != NULL);
566 g_return_if_fail(user != NULL);
567
568 if(b->error) return;
569
570 gboolean_get(b, &user->full);
571 mwString_get(b, &user->id);
572 mwString_get(b, &user->community);
573
574 if(user->full)
575 mwString_get(b, &user->name);
576 }
577
578
mwUserItem_clear(struct mwUserItem * user)579 void mwUserItem_clear(struct mwUserItem *user) {
580 if(! user) return;
581
582 g_free(user->id);
583 g_free(user->community);
584 g_free(user->name);
585
586 memset(user, 0x00, sizeof(struct mwUserItem));
587 }
588
589
mwUserItem_clone(struct mwUserItem * to,const struct mwUserItem * from)590 void mwUserItem_clone(struct mwUserItem *to,
591 const struct mwUserItem *from) {
592
593 g_return_if_fail(to != NULL);
594 g_return_if_fail(from != NULL);
595
596 to->full = from->full;
597 to->id = g_strdup(from->id);
598 to->community = g_strdup(from->community);
599 to->name = (to->full)? g_strdup(from->name): NULL;
600 }
601
602
mwPrivacyInfo_put(struct mwPutBuffer * b,const struct mwPrivacyInfo * info)603 void mwPrivacyInfo_put(struct mwPutBuffer *b,
604 const struct mwPrivacyInfo *info) {
605 guint32 c;
606
607 g_return_if_fail(b != NULL);
608 g_return_if_fail(info != NULL);
609
610 gboolean_put(b, info->deny);
611 guint32_put(b, info->count);
612
613 for(c = info->count; c--; ) mwUserItem_put(b, info->users + c);
614 }
615
616
mwPrivacyInfo_get(struct mwGetBuffer * b,struct mwPrivacyInfo * info)617 void mwPrivacyInfo_get(struct mwGetBuffer *b, struct mwPrivacyInfo *info) {
618 g_return_if_fail(b != NULL);
619 g_return_if_fail(info != NULL);
620
621 if(b->error) return;
622
623 gboolean_get(b, &info->deny);
624 guint32_get(b, &info->count);
625
626 if(info->count) {
627 guint32 c = info->count;
628 info->users = g_new0(struct mwUserItem, c);
629 while(c--) mwUserItem_get(b, info->users + c);
630 }
631 }
632
633
mwPrivacyInfo_clone(struct mwPrivacyInfo * to,const struct mwPrivacyInfo * from)634 void mwPrivacyInfo_clone(struct mwPrivacyInfo *to,
635 const struct mwPrivacyInfo *from) {
636
637 guint32 c;
638
639 g_return_if_fail(to != NULL);
640 g_return_if_fail(from != NULL);
641
642 to->deny = from->deny;
643 c = to->count = from->count;
644
645 to->users = g_new0(struct mwUserItem, c);
646 while(c--) mwUserItem_clone(to->users+c, from->users+c);
647 }
648
649
mwPrivacyInfo_clear(struct mwPrivacyInfo * info)650 void mwPrivacyInfo_clear(struct mwPrivacyInfo *info) {
651 struct mwUserItem *u;
652 guint32 c;
653
654 g_return_if_fail(info != NULL);
655
656 u = info->users;
657 c = info->count;
658
659 while(c--) mwUserItem_clear(u + c);
660 g_free(u);
661
662 info->count = 0;
663 info->users = NULL;
664 }
665
666
667 /* 8.2.3 User Status Block */
668
669
mwUserStatus_put(struct mwPutBuffer * b,const struct mwUserStatus * stat)670 void mwUserStatus_put(struct mwPutBuffer *b,
671 const struct mwUserStatus *stat) {
672
673 g_return_if_fail(b != NULL);
674 g_return_if_fail(stat != NULL);
675
676 guint16_put(b, stat->status);
677 guint32_put(b, stat->time);
678 mwString_put(b, stat->desc);
679 }
680
681
mwUserStatus_get(struct mwGetBuffer * b,struct mwUserStatus * stat)682 void mwUserStatus_get(struct mwGetBuffer *b, struct mwUserStatus *stat) {
683 g_return_if_fail(b != NULL);
684 g_return_if_fail(stat != NULL);
685
686 if(b->error) return;
687
688 guint16_get(b, &stat->status);
689 guint32_get(b, &stat->time);
690 mwString_get(b, &stat->desc);
691 }
692
693
mwUserStatus_clear(struct mwUserStatus * stat)694 void mwUserStatus_clear(struct mwUserStatus *stat) {
695 if(! stat) return;
696 g_free(stat->desc);
697 memset(stat, 0x00, sizeof(struct mwUserStatus));
698 }
699
700
mwUserStatus_clone(struct mwUserStatus * to,const struct mwUserStatus * from)701 void mwUserStatus_clone(struct mwUserStatus *to,
702 const struct mwUserStatus *from) {
703
704 g_return_if_fail(to != NULL);
705 g_return_if_fail(from != NULL);
706
707 to->status = from->status;
708 to->time = from->time;
709 to->desc = g_strdup(from->desc);
710 }
711
712
713 /* 8.2.4 ID Block */
714
715
mwIdBlock_put(struct mwPutBuffer * b,const struct mwIdBlock * id)716 void mwIdBlock_put(struct mwPutBuffer *b, const struct mwIdBlock *id) {
717 g_return_if_fail(b != NULL);
718 g_return_if_fail(id != NULL);
719
720 mwString_put(b, id->user);
721 mwString_put(b, id->community);
722 }
723
724
mwIdBlock_get(struct mwGetBuffer * b,struct mwIdBlock * id)725 void mwIdBlock_get(struct mwGetBuffer *b, struct mwIdBlock *id) {
726 g_return_if_fail(b != NULL);
727 g_return_if_fail(id != NULL);
728
729 if(b->error) return;
730
731 mwString_get(b, &id->user);
732 mwString_get(b, &id->community);
733 }
734
735
mwIdBlock_clear(struct mwIdBlock * id)736 void mwIdBlock_clear(struct mwIdBlock *id) {
737 if(! id) return;
738
739 g_free(id->user);
740 id->user = NULL;
741
742 g_free(id->community);
743 id->community = NULL;
744 }
745
746
mwIdBlock_clone(struct mwIdBlock * to,const struct mwIdBlock * from)747 void mwIdBlock_clone(struct mwIdBlock *to, const struct mwIdBlock *from) {
748 g_return_if_fail(to != NULL);
749 g_return_if_fail(from != NULL);
750
751 to->user = g_strdup(from->user);
752 to->community = g_strdup(from->community);
753 }
754
755
mwIdBlock_hash(const struct mwIdBlock * idb)756 guint mwIdBlock_hash(const struct mwIdBlock *idb) {
757 return (idb)? g_str_hash(idb->user): 0;
758 }
759
760
mwIdBlock_equal(const struct mwIdBlock * a,const struct mwIdBlock * b)761 gboolean mwIdBlock_equal(const struct mwIdBlock *a,
762 const struct mwIdBlock *b) {
763
764 g_return_val_if_fail(a != NULL, FALSE);
765 g_return_val_if_fail(b != NULL, FALSE);
766
767 return ( mw_streq(a->user, b->user) &&
768 mw_streq(a->community, b->community) );
769 }
770
771
772 /* 8.2.5 Encryption Block */
773
774 /** @todo I think this can be put into cipher */
775
mwEncryptItem_put(struct mwPutBuffer * b,const struct mwEncryptItem * ei)776 void mwEncryptItem_put(struct mwPutBuffer *b,
777 const struct mwEncryptItem *ei) {
778
779 g_return_if_fail(b != NULL);
780 g_return_if_fail(ei != NULL);
781
782 guint16_put(b, ei->id);
783 mwOpaque_put(b, &ei->info);
784
785 }
786
787
mwEncryptItem_get(struct mwGetBuffer * b,struct mwEncryptItem * ei)788 void mwEncryptItem_get(struct mwGetBuffer *b, struct mwEncryptItem *ei) {
789 g_return_if_fail(b != NULL);
790 g_return_if_fail(ei != NULL);
791
792 if(b->error) return;
793
794 guint16_get(b, &ei->id);
795 mwOpaque_get(b, &ei->info);
796 }
797
798
mwEncryptItem_clear(struct mwEncryptItem * ei)799 void mwEncryptItem_clear(struct mwEncryptItem *ei) {
800 if(! ei) return;
801 ei->id = 0x0000;
802 mwOpaque_clear(&ei->info);
803 }
804
805
mwEncryptItem_free(struct mwEncryptItem * ei)806 void mwEncryptItem_free(struct mwEncryptItem *ei) {
807 mwEncryptItem_clear(ei);
808 g_free(ei);
809 }
810
811
812 /* 8.4.2.1 Awareness ID Block */
813
814
815 /** @todo move this into srvc_aware */
816
mwAwareIdBlock_put(struct mwPutBuffer * b,const struct mwAwareIdBlock * idb)817 void mwAwareIdBlock_put(struct mwPutBuffer *b,
818 const struct mwAwareIdBlock *idb) {
819
820 g_return_if_fail(b != NULL);
821 g_return_if_fail(idb != NULL);
822
823 guint16_put(b, idb->type);
824 mwString_put(b, idb->user);
825 mwString_put(b, idb->community);
826 }
827
828
mwAwareIdBlock_get(struct mwGetBuffer * b,struct mwAwareIdBlock * idb)829 void mwAwareIdBlock_get(struct mwGetBuffer *b, struct mwAwareIdBlock *idb) {
830 g_return_if_fail(b != NULL);
831 g_return_if_fail(idb != NULL);
832
833 if(b->error) return;
834
835 guint16_get(b, &idb->type);
836 mwString_get(b, &idb->user);
837 mwString_get(b, &idb->community);
838 }
839
840
mwAwareIdBlock_clone(struct mwAwareIdBlock * to,const struct mwAwareIdBlock * from)841 void mwAwareIdBlock_clone(struct mwAwareIdBlock *to,
842 const struct mwAwareIdBlock *from) {
843
844 g_return_if_fail(to != NULL);
845 g_return_if_fail(from != NULL);
846
847 to->type = from->type;
848 to->user = g_strdup(from->user);
849 to->community = g_strdup(from->community);
850 }
851
852
mwAwareIdBlock_clear(struct mwAwareIdBlock * idb)853 void mwAwareIdBlock_clear(struct mwAwareIdBlock *idb) {
854 if(! idb) return;
855 g_free(idb->user);
856 g_free(idb->community);
857 memset(idb, 0x00, sizeof(struct mwAwareIdBlock));
858 }
859
860
mwAwareIdBlock_hash(const struct mwAwareIdBlock * a)861 guint mwAwareIdBlock_hash(const struct mwAwareIdBlock *a) {
862 return (a)? g_str_hash(a->user): 0;
863 }
864
865
mwAwareIdBlock_equal(const struct mwAwareIdBlock * a,const struct mwAwareIdBlock * b)866 gboolean mwAwareIdBlock_equal(const struct mwAwareIdBlock *a,
867 const struct mwAwareIdBlock *b) {
868
869 g_return_val_if_fail(a != NULL, FALSE);
870 g_return_val_if_fail(b != NULL, FALSE);
871
872 return ( (a->type == b->type) &&
873 mw_streq(a->user, b->user) &&
874 mw_streq(a->community, b->community) );
875 }
876
877
878 /* 8.4.2.4 Snapshot */
879
mwAwareSnapshot_get(struct mwGetBuffer * b,struct mwAwareSnapshot * idb)880 void mwAwareSnapshot_get(struct mwGetBuffer *b, struct mwAwareSnapshot *idb) {
881 guint32 junk;
882 char *empty = NULL;
883
884 g_return_if_fail(b != NULL);
885 g_return_if_fail(idb != NULL);
886
887 guint32_get(b, &junk);
888 mwAwareIdBlock_get(b, &idb->id);
889 mwString_get(b, &idb->group);
890 gboolean_get(b, &idb->online);
891
892 g_free(empty);
893
894 if(idb->online) {
895 mwString_get(b, &idb->alt_id);
896 mwUserStatus_get(b, &idb->status);
897 mwString_get(b, &idb->name);
898 }
899 }
900
901
mwAwareSnapshot_clone(struct mwAwareSnapshot * to,const struct mwAwareSnapshot * from)902 void mwAwareSnapshot_clone(struct mwAwareSnapshot *to,
903 const struct mwAwareSnapshot *from) {
904
905 g_return_if_fail(to != NULL);
906 g_return_if_fail(from != NULL);
907
908 mwAwareIdBlock_clone(&to->id, &from->id);
909 if( (to->online = from->online) ) {
910 to->alt_id = g_strdup(from->alt_id);
911 mwUserStatus_clone(&to->status, &from->status);
912 to->name = g_strdup(from->name);
913 to->group = g_strdup(from->group);
914 }
915 }
916
917
mwAwareSnapshot_clear(struct mwAwareSnapshot * idb)918 void mwAwareSnapshot_clear(struct mwAwareSnapshot *idb) {
919 if(! idb) return;
920 mwAwareIdBlock_clear(&idb->id);
921 mwUserStatus_clear(&idb->status);
922 g_free(idb->alt_id);
923 g_free(idb->name);
924 g_free(idb->group);
925 memset(idb, 0x00, sizeof(struct mwAwareSnapshot));
926 }
927
928