Sun, 05 Jun 2005 02:50:13 +0000
[gaim-migrate @ 12790]
importing meanwhile library for use in the sametime plugin
| 10969 | 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 | char *buf; /**< head of buffer */ | |
| 57 | gsize len; /**< length of buffer */ | |
| 58 | ||
| 59 | char *ptr; /**< offset to first unused byte */ | |
| 60 | gsize rem; /**< count of unused bytes remaining */ | |
| 61 | }; | |
| 62 | ||
| 63 | ||
| 64 | struct mwGetBuffer { | |
| 65 | char *buf; /**< head of buffer */ | |
| 66 | gsize len; /**< length of buffer */ | |
| 67 | ||
| 68 | char *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. */ | |
| 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 | char *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 */ | |
| 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 | ||
| 122 | struct mwPutBuffer *mwPutBuffer_new() { | |
| 123 | return g_new0(struct mwPutBuffer, 1); | |
| 124 | } | |
| 125 | ||
| 126 | ||
| 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 | ||
| 140 | void mwPutBuffer_free(struct mwPutBuffer *b) { | |
| 141 | if(! b) return; | |
| 142 | g_free(b->buf); | |
| 143 | g_free(b); | |
| 144 | } | |
| 145 | ||
| 146 | ||
| 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 | ||
| 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 | ||
| 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 = (char *) o->data; | |
| 175 | b->len = b->rem = o->len; | |
| 176 | } | |
| 177 | b->wrap = TRUE; | |
| 178 | ||
| 179 | return b; | |
| 180 | } | |
| 181 | ||
| 182 | ||
| 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 | ||
| 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 | ||
| 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 | ||
| 226 | gsize mwGetBuffer_remaining(struct mwGetBuffer *b) { | |
| 227 | g_return_val_if_fail(b != NULL, 0); | |
| 228 | return b->rem; | |
| 229 | } | |
| 230 | ||
| 231 | ||
| 232 | gboolean mwGetBuffer_error(struct mwGetBuffer *b) { | |
| 233 | g_return_val_if_fail(b != NULL, TRUE); | |
| 234 | return b->error; | |
| 235 | } | |
| 236 | ||
| 237 | ||
| 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 | ||
| 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 | ||
| 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 | ||
| 268 | guint16 guint16_peek(struct mwGetBuffer *b) { | |
| 269 | char *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 | ||
| 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 | ||
| 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 | ||
| 302 | guint32 guint32_peek(struct mwGetBuffer *b) { | |
| 303 | char *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 | ||
| 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 | ||
| 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 | ||
| 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 | ||
| 348 | gboolean mw_streq(const char *a, const char *b) { | |
| 349 | return (a == b) || (a && b && !strcmp(a, b)); | |
| 350 | } | |
| 351 | ||
| 352 | ||
| 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 | ||
| 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 | ||
| 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 | ||
| 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 | ||
| 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 | ||
| 449 | void mwOpaque_free(struct mwOpaque *o) { | |
| 450 | if(! o) return; | |
| 451 | g_free(o->data); | |
| 452 | g_free(o); | |
| 453 | } | |
| 454 | ||
| 455 | ||
| 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 | ||
| 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 | ||
| 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 | ||
| 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 | ||
| 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 | ||
| 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 | ||
| 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 | ||
| 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 | ||
| 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 | ||
| 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 | ||
| 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 | ||
| 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 | ||
| 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 | ||
| 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 | ||
| 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 | ||
| 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 | ||
| 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 | ||
| 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 | ||
| 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 | ||
| 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 | ||
| 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 | ||
| 756 | guint mwIdBlock_hash(const struct mwIdBlock *idb) { | |
| 757 | return (idb)? g_str_hash(idb->user): 0; | |
| 758 | } | |
| 759 | ||
| 760 | ||
| 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 | ||
| 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 | ||
| 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 | ||
| 799 | void mwEncryptItem_clear(struct mwEncryptItem *ei) { | |
| 800 | if(! ei) return; | |
| 801 | ei->id = 0x0000; | |
| 802 | mwOpaque_clear(&ei->info); | |
| 803 | } | |
| 804 | ||
| 805 | ||
| 806 | /* 8.4.2.1 Awareness ID Block */ | |
| 807 | ||
| 808 | ||
| 809 | /** @todo move this into srvc_aware */ | |
| 810 | ||
| 811 | void mwAwareIdBlock_put(struct mwPutBuffer *b, | |
| 812 | const struct mwAwareIdBlock *idb) { | |
| 813 | ||
| 814 | g_return_if_fail(b != NULL); | |
| 815 | g_return_if_fail(idb != NULL); | |
| 816 | ||
| 817 | guint16_put(b, idb->type); | |
| 818 | mwString_put(b, idb->user); | |
| 819 | mwString_put(b, idb->community); | |
| 820 | } | |
| 821 | ||
| 822 | ||
| 823 | void mwAwareIdBlock_get(struct mwGetBuffer *b, struct mwAwareIdBlock *idb) { | |
| 824 | g_return_if_fail(b != NULL); | |
| 825 | g_return_if_fail(idb != NULL); | |
| 826 | ||
| 827 | if(b->error) return; | |
| 828 | ||
| 829 | guint16_get(b, &idb->type); | |
| 830 | mwString_get(b, &idb->user); | |
| 831 | mwString_get(b, &idb->community); | |
| 832 | } | |
| 833 | ||
| 834 | ||
| 835 | void mwAwareIdBlock_clone(struct mwAwareIdBlock *to, | |
| 836 | const struct mwAwareIdBlock *from) { | |
| 837 | ||
| 838 | g_return_if_fail(to != NULL); | |
| 839 | g_return_if_fail(from != NULL); | |
| 840 | ||
| 841 | to->type = from->type; | |
| 842 | to->user = g_strdup(from->user); | |
| 843 | to->community = g_strdup(from->community); | |
| 844 | } | |
| 845 | ||
| 846 | ||
| 847 | void mwAwareIdBlock_clear(struct mwAwareIdBlock *idb) { | |
| 848 | if(! idb) return; | |
| 849 | g_free(idb->user); | |
| 850 | g_free(idb->community); | |
| 851 | memset(idb, 0x00, sizeof(struct mwAwareIdBlock)); | |
| 852 | } | |
| 853 | ||
| 854 | ||
| 855 | guint mwAwareIdBlock_hash(const struct mwAwareIdBlock *a) { | |
| 856 | return (a)? g_str_hash(a->user): 0; | |
| 857 | } | |
| 858 | ||
| 859 | ||
| 860 | gboolean mwAwareIdBlock_equal(const struct mwAwareIdBlock *a, | |
| 861 | const struct mwAwareIdBlock *b) { | |
| 862 | ||
| 863 | g_return_val_if_fail(a != NULL, FALSE); | |
| 864 | g_return_val_if_fail(b != NULL, FALSE); | |
| 865 | ||
| 866 | return ( (a->type == b->type) && | |
| 867 | mw_streq(a->user, b->user) && | |
| 868 | mw_streq(a->community, b->community) ); | |
| 869 | } | |
| 870 | ||
| 871 | ||
| 872 | /* 8.4.2.4 Snapshot */ | |
| 873 | ||
| 874 | void mwAwareSnapshot_get(struct mwGetBuffer *b, struct mwAwareSnapshot *idb) { | |
| 875 | guint32 junk; | |
| 876 | char *empty = NULL; | |
| 877 | ||
| 878 | g_return_if_fail(b != NULL); | |
| 879 | g_return_if_fail(idb != NULL); | |
| 880 | ||
| 881 | guint32_get(b, &junk); | |
| 882 | mwAwareIdBlock_get(b, &idb->id); | |
| 883 | mwString_get(b, &idb->group); | |
| 884 | gboolean_get(b, &idb->online); | |
| 885 | ||
| 886 | g_free(empty); | |
| 887 | ||
| 888 | if(idb->online) { | |
| 889 | mwString_get(b, &idb->alt_id); | |
| 890 | mwUserStatus_get(b, &idb->status); | |
| 891 | mwString_get(b, &idb->name); | |
| 892 | } | |
| 893 | } | |
| 894 | ||
| 895 | ||
| 896 | void mwAwareSnapshot_clone(struct mwAwareSnapshot *to, | |
| 897 | const struct mwAwareSnapshot *from) { | |
| 898 | ||
| 899 | g_return_if_fail(to != NULL); | |
| 900 | g_return_if_fail(from != NULL); | |
| 901 | ||
| 902 | mwAwareIdBlock_clone(&to->id, &from->id); | |
| 903 | if( (to->online = from->online) ) { | |
| 904 | to->alt_id = g_strdup(from->alt_id); | |
| 905 | mwUserStatus_clone(&to->status, &from->status); | |
| 906 | to->name = g_strdup(from->name); | |
| 907 | to->group = g_strdup(from->group); | |
| 908 | } | |
| 909 | } | |
| 910 | ||
| 911 | ||
| 912 | void mwAwareSnapshot_clear(struct mwAwareSnapshot *idb) { | |
| 913 | if(! idb) return; | |
| 914 | mwAwareIdBlock_clear(&idb->id); | |
| 915 | mwUserStatus_clear(&idb->status); | |
| 916 | g_free(idb->alt_id); | |
| 917 | g_free(idb->name); | |
| 918 | g_free(idb->group); | |
| 919 | memset(idb, 0x00, sizeof(struct mwAwareSnapshot)); | |
| 920 | } | |
| 921 | ||
| 922 | ||
| 923 | const char *mwLoginType_getName(enum mwLoginType type) { | |
| 924 | switch(type) { | |
| 925 | case mwLogin_LIB: | |
| 926 | return "Lotus Binary Library"; | |
| 927 | ||
| 928 | case mwLogin_JAVA_WEB: | |
| 929 | return "Lotus Java Client Applet"; | |
| 930 | ||
| 931 | case mwLogin_BINARY: | |
| 932 | return "Lotus Sametime"; | |
| 933 | ||
| 934 | case mwLogin_JAVA_APP: | |
| 935 | return "Lotus Java Client Application"; | |
| 936 | ||
| 937 | case mwLogin_NOTES_6_5: | |
| 938 | return "Lotus Notes Client 6.5.2+"; | |
| 939 | ||
| 940 | case mwLogin_NOTES_7_0: | |
| 941 | return "Lotus Notes Client 7"; | |
| 942 | ||
| 943 | case mwLogin_ICT: | |
| 944 | return "IBM Community Tools (ICT)"; | |
| 945 | ||
| 946 | case mwLogin_NOTESBUDDY: | |
| 947 | case mwLogin_NOTESBUDDY_4_15: | |
| 948 | return "Alphaworks NotesBuddy"; | |
| 949 | ||
| 950 | case mwLogin_SANITY: | |
| 951 | return "Sanity"; | |
| 952 | ||
| 953 | case mwLogin_ST_PERL: | |
| 954 | return "ST-Send-Message"; | |
| 955 | ||
| 956 | case mwLogin_PMR_ALERT: | |
| 957 | return "PMR Alert"; | |
| 958 | ||
| 959 | case mwLogin_TRILLIAN: | |
| 960 | case mwLogin_TRILLIAN_IBM: | |
| 961 | return "Trillian"; | |
| 962 | ||
| 963 | case mwLogin_MEANWHILE: | |
| 964 | return "Meanwhile"; | |
| 965 | ||
| 966 | case mwLogin_MW_PYTHON: | |
| 967 | return "Meanwhile Python"; | |
| 968 | ||
| 969 | case mwLogin_MW_GAIM: | |
| 970 | return "Meanwhile Gaim"; | |
| 971 | ||
| 972 | case mwLogin_MW_ADIUM: | |
| 973 | return "Meanwhile Adium"; | |
| 974 | ||
| 975 | case mwLogin_MW_KOPETE: | |
| 976 | return "Meanwhile Kopete"; | |
| 977 | ||
| 978 | default: | |
| 979 | return NULL; | |
| 980 | } | |
| 981 | } | |
| 982 |