Blame src/common.c

Packit 16808d
Packit 16808d
/*
Packit 16808d
  Meanwhile - Unofficial Lotus Sametime Community Client Library
Packit 16808d
  Copyright (C) 2004  Christopher (siege) O'Brien
Packit 16808d
  
Packit 16808d
  This library is free software; you can redistribute it and/or
Packit 16808d
  modify it under the terms of the GNU Library General Public
Packit 16808d
  License as published by the Free Software Foundation; either
Packit 16808d
  version 2 of the License, or (at your option) any later version.
Packit 16808d
  
Packit 16808d
  This library is distributed in the hope that it will be useful,
Packit 16808d
  but WITHOUT ANY WARRANTY; without even the implied warranty of
Packit 16808d
  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
Packit 16808d
  Library General Public License for more details.
Packit 16808d
  
Packit 16808d
  You should have received a copy of the GNU Library General Public
Packit 16808d
  License along with this library; if not, write to the Free
Packit 16808d
  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
Packit 16808d
*/
Packit 16808d
Packit 16808d
#include <glib.h>
Packit 16808d
#include <string.h>
Packit 16808d
Packit 16808d
#include "mw_common.h"
Packit 16808d
Packit 16808d
Packit 16808d
/** @todo the *_get functions should make sure to clear their
Packit 16808d
    structures in the event of failure, to prevent memory leaks */
Packit 16808d
Packit 16808d
Packit 16808d
#define MW16_PUT(b, val) \
Packit 16808d
  *(b)++ = ((val) >> 0x08) & 0xff; \
Packit 16808d
  *(b)++ = (val) & 0xff;
Packit 16808d
Packit 16808d
Packit 16808d
#define MW16_GET(b, val) \
Packit 16808d
  val = (*(b)++ & 0xff) << 8; \
Packit 16808d
  val = val | (*(b)++ & 0xff);
Packit 16808d
Packit 16808d
Packit 16808d
#define MW32_PUT(b, val) \
Packit 16808d
  *(b)++ = ((val) >> 0x18) & 0xff; \
Packit 16808d
  *(b)++ = ((val) >> 0x10) & 0xff; \
Packit 16808d
  *(b)++ = ((val) >> 0x08) & 0xff; \
Packit 16808d
  *(b)++ = (val) & 0xff;
Packit 16808d
Packit 16808d
Packit 16808d
#define MW32_GET(b, val) \
Packit 16808d
  val = (*(b)++ & 0xff) << 0x18; \
Packit 16808d
  val = val | (*(b)++ & 0xff) << 0x10; \
Packit 16808d
  val = val | (*(b)++ & 0xff) << 0x08; \
Packit 16808d
  val = val | (*(b)++ & 0xff);
Packit 16808d
Packit 16808d
Packit 16808d
struct mwPutBuffer {
Packit 16808d
  guchar *buf;  /**< head of buffer */
Packit 16808d
  gsize len;    /**< length of buffer */
Packit 16808d
Packit 16808d
  guchar *ptr;  /**< offset to first unused byte */
Packit 16808d
  gsize rem;    /**< count of unused bytes remaining */
Packit 16808d
};
Packit 16808d
Packit 16808d
Packit 16808d
struct mwGetBuffer {
Packit 16808d
  guchar *buf;  /**< head of buffer */
Packit 16808d
  gsize len;    /**< length of buffer */
Packit 16808d
Packit 16808d
  guchar *ptr;  /**< offset to first unused byte */
Packit 16808d
  gsize rem;    /**< count of unused bytes remaining */
Packit 16808d
Packit 16808d
  gboolean wrap;   /**< TRUE to indicate buf shouldn't be freed */
Packit 16808d
  gboolean error;  /**< TRUE to indicate an error */
Packit 16808d
};
Packit 16808d
Packit 16808d
Packit 16808d
#define BUFFER_USED(buffer) \
Packit 16808d
  ((buffer)->len - (buffer)->rem)
Packit 16808d
Packit 16808d
Packit 16808d
/** ensure that there's at least enough space remaining in the put
Packit 16808d
    buffer to fit needed. */
Packit 16808d
static void ensure_buffer(struct mwPutBuffer *b, gsize needed) {
Packit 16808d
  if(b->rem < needed) {
Packit 16808d
    gsize len = b->len, use = BUFFER_USED(b);
Packit 16808d
    guchar *buf;
Packit 16808d
Packit 16808d
    /* newly created buffers are empty until written to, and then they
Packit 16808d
       have 1024 available */
Packit 16808d
    if(! len) len = 1024;
Packit 16808d
Packit 16808d
    /* double len until it's large enough to fit needed */
Packit 16808d
    while( (len - use) < needed ) len = len << 1;
Packit 16808d
Packit 16808d
    /* create the new buffer. if there was anything in the old buffer,
Packit 16808d
       copy it into the new buffer and free the old copy */
Packit 16808d
    buf = g_malloc(len);
Packit 16808d
    if(b->buf) {
Packit 16808d
      memcpy(buf, b->buf, use);
Packit 16808d
      g_free(b->buf);
Packit 16808d
    }
Packit 16808d
Packit 16808d
    /* put the new buffer into b */
Packit 16808d
    b->buf = buf;
Packit 16808d
    b->len = len;
Packit 16808d
    b->ptr = buf + use;
Packit 16808d
    b->rem = len - use;
Packit 16808d
  }
Packit 16808d
}
Packit 16808d
Packit 16808d
Packit 16808d
/** determine if there are at least needed bytes available in the
Packit 16808d
    buffer. sets the error flag if there's not at least needed bytes
Packit 16808d
    left in the buffer
Packit 16808d
Packit 16808d
    @returns true if there's enough data, false if not */
Packit 16808d
static gboolean check_buffer(struct mwGetBuffer *b, gsize needed) {
Packit 16808d
  if(! b->error)  b->error = (b->rem < needed);
Packit 16808d
  return ! b->error;
Packit 16808d
}
Packit 16808d
Packit 16808d
Packit 16808d
struct mwPutBuffer *mwPutBuffer_new() {
Packit 16808d
  return g_new0(struct mwPutBuffer, 1);
Packit 16808d
}
Packit 16808d
Packit 16808d
Packit 16808d
void mwPutBuffer_write(struct mwPutBuffer *b, gpointer data, gsize len) {
Packit 16808d
  g_return_if_fail(b != NULL);
Packit 16808d
  g_return_if_fail(data != NULL);
Packit 16808d
Packit 16808d
  if(! len) return;
Packit 16808d
Packit 16808d
  ensure_buffer(b, len);
Packit 16808d
  memcpy(b->ptr, data, len);
Packit 16808d
  b->ptr += len;
Packit 16808d
  b->rem -= len;
Packit 16808d
}
Packit 16808d
Packit 16808d
Packit 16808d
void mwPutBuffer_free(struct mwPutBuffer *b) {
Packit 16808d
  if(! b) return;
Packit 16808d
  g_free(b->buf);
Packit 16808d
  g_free(b);
Packit 16808d
}
Packit 16808d
Packit 16808d
Packit 16808d
void mwPutBuffer_finalize(struct mwOpaque *to, struct mwPutBuffer *from) {
Packit 16808d
  g_return_if_fail(to != NULL);
Packit 16808d
  g_return_if_fail(from != NULL);
Packit 16808d
Packit 16808d
  to->len = BUFFER_USED(from);
Packit 16808d
  to->data = from->buf;
Packit 16808d
Packit 16808d
  g_free(from);
Packit 16808d
}
Packit 16808d
Packit 16808d
Packit 16808d
struct mwGetBuffer *mwGetBuffer_new(struct mwOpaque *o) {
Packit 16808d
  struct mwGetBuffer *b = g_new0(struct mwGetBuffer, 1);
Packit 16808d
Packit 16808d
  if(o && o->len) {
Packit 16808d
    b->buf = b->ptr = g_memdup(o->data, o->len);
Packit 16808d
    b->len = b->rem = o->len;
Packit 16808d
  }
Packit 16808d
Packit 16808d
  return b;
Packit 16808d
}
Packit 16808d
Packit 16808d
Packit 16808d
struct mwGetBuffer *mwGetBuffer_wrap(const struct mwOpaque *o) {
Packit 16808d
  struct mwGetBuffer *b = g_new0(struct mwGetBuffer, 1);
Packit 16808d
Packit 16808d
  if(o && o->len) {
Packit 16808d
    b->buf = b->ptr = o->data;
Packit 16808d
    b->len = b->rem = o->len;
Packit 16808d
  }
Packit 16808d
  b->wrap = TRUE;
Packit 16808d
Packit 16808d
  return b;
Packit 16808d
}
Packit 16808d
Packit 16808d
Packit 16808d
gsize mwGetBuffer_read(struct mwGetBuffer *b, gpointer data, gsize len) {
Packit 16808d
  g_return_val_if_fail(b != NULL, 0);
Packit 16808d
  g_return_val_if_fail(data != NULL, 0);
Packit 16808d
Packit 16808d
  if(b->error) return 0;
Packit 16808d
  if(! len) return 0;
Packit 16808d
Packit 16808d
  if(b->rem < len)
Packit 16808d
    len = b->rem;
Packit 16808d
Packit 16808d
  memcpy(data, b->ptr, len);
Packit 16808d
  b->ptr += len;
Packit 16808d
  b->rem -= len;
Packit 16808d
Packit 16808d
  return len;
Packit 16808d
}
Packit 16808d
Packit 16808d
Packit 16808d
gsize mwGetBuffer_advance(struct mwGetBuffer *b, gsize len) {
Packit 16808d
  g_return_val_if_fail(b != NULL, 0);
Packit 16808d
Packit 16808d
  if(b->error) return 0;
Packit 16808d
  if(! len) return 0;
Packit 16808d
Packit 16808d
  if(b->rem < len)
Packit 16808d
    len = b->rem;
Packit 16808d
Packit 16808d
  b->ptr += len;
Packit 16808d
  b->rem -= len;
Packit 16808d
Packit 16808d
  return len;
Packit 16808d
}
Packit 16808d
Packit 16808d
Packit 16808d
void mwGetBuffer_reset(struct mwGetBuffer *b) {
Packit 16808d
  g_return_if_fail(b != NULL);
Packit 16808d
Packit 16808d
  b->rem = b->len;
Packit 16808d
  b->ptr = b->buf;
Packit 16808d
  b->error = FALSE;
Packit 16808d
}
Packit 16808d
Packit 16808d
Packit 16808d
gsize mwGetBuffer_remaining(struct mwGetBuffer *b) {
Packit 16808d
  g_return_val_if_fail(b != NULL, 0);
Packit 16808d
  return b->rem;
Packit 16808d
}
Packit 16808d
Packit 16808d
Packit 16808d
gboolean mwGetBuffer_error(struct mwGetBuffer *b) {
Packit 16808d
  g_return_val_if_fail(b != NULL, TRUE);
Packit 16808d
  return b->error;
Packit 16808d
}
Packit 16808d
Packit 16808d
Packit 16808d
void mwGetBuffer_free(struct mwGetBuffer *b) {
Packit 16808d
  if(! b) return;
Packit 16808d
  if(! b->wrap) g_free(b->buf);
Packit 16808d
  g_free(b);
Packit 16808d
}
Packit 16808d
Packit 16808d
Packit 16808d
#define guint16_buflen()  2
Packit 16808d
Packit 16808d
Packit 16808d
void guint16_put(struct mwPutBuffer *b, guint16 val) {
Packit 16808d
  g_return_if_fail(b != NULL);
Packit 16808d
Packit 16808d
  ensure_buffer(b, guint16_buflen());
Packit 16808d
  MW16_PUT(b->ptr, val);
Packit 16808d
  b->rem -= guint16_buflen();
Packit 16808d
}
Packit 16808d
Packit 16808d
Packit 16808d
void guint16_get(struct mwGetBuffer *b, guint16 *val) {
Packit 16808d
  g_return_if_fail(b != NULL);
Packit 16808d
Packit 16808d
  if(b->error) return;
Packit 16808d
  g_return_if_fail(check_buffer(b, guint16_buflen()));
Packit 16808d
Packit 16808d
  MW16_GET(b->ptr, *val);
Packit 16808d
  b->rem -= guint16_buflen();
Packit 16808d
}
Packit 16808d
Packit 16808d
Packit 16808d
guint16 guint16_peek(struct mwGetBuffer *b) {
Packit 16808d
  guchar *buf = b->buf;
Packit 16808d
  guint16 r = 0;
Packit 16808d
  
Packit 16808d
  if(b->rem >= guint16_buflen())
Packit 16808d
    MW16_GET(buf, r);
Packit 16808d
Packit 16808d
  return r;
Packit 16808d
}
Packit 16808d
Packit 16808d
Packit 16808d
#define guint32_buflen()  4
Packit 16808d
Packit 16808d
Packit 16808d
void guint32_put(struct mwPutBuffer *b, guint32 val) {
Packit 16808d
  g_return_if_fail(b != NULL);
Packit 16808d
Packit 16808d
  ensure_buffer(b, guint32_buflen());
Packit 16808d
  MW32_PUT(b->ptr, val);
Packit 16808d
  b->rem -= guint32_buflen();
Packit 16808d
}
Packit 16808d
Packit 16808d
Packit 16808d
void guint32_get(struct mwGetBuffer *b, guint32 *val) {
Packit 16808d
  g_return_if_fail(b != NULL);
Packit 16808d
Packit 16808d
  if(b->error) return;
Packit 16808d
  g_return_if_fail(check_buffer(b, guint32_buflen()));
Packit 16808d
Packit 16808d
  MW32_GET(b->ptr, *val);
Packit 16808d
  b->rem -= guint32_buflen();
Packit 16808d
}
Packit 16808d
Packit 16808d
Packit 16808d
guint32 guint32_peek(struct mwGetBuffer *b) {
Packit 16808d
  guchar *buf = b->buf;
Packit 16808d
  guint32 r = 0;
Packit 16808d
Packit 16808d
  if(b->rem >= guint32_buflen())
Packit 16808d
    MW32_GET(buf, r);
Packit 16808d
Packit 16808d
  return r;
Packit 16808d
}
Packit 16808d
Packit 16808d
Packit 16808d
#define gboolean_buflen()  1
Packit 16808d
Packit 16808d
Packit 16808d
void gboolean_put(struct mwPutBuffer *b, gboolean val) {
Packit 16808d
  g_return_if_fail(b != NULL);
Packit 16808d
Packit 16808d
  ensure_buffer(b, gboolean_buflen());
Packit 16808d
  *(b->ptr) = !! val;
Packit 16808d
  b->ptr++;
Packit 16808d
  b->rem--;
Packit 16808d
}
Packit 16808d
Packit 16808d
Packit 16808d
void gboolean_get(struct mwGetBuffer *b, gboolean *val) {
Packit 16808d
  g_return_if_fail(b != NULL);
Packit 16808d
Packit 16808d
  if(b->error) return;
Packit 16808d
  g_return_if_fail(check_buffer(b, gboolean_buflen()));
Packit 16808d
Packit 16808d
  *val = !! *(b->ptr);
Packit 16808d
  b->ptr++;
Packit 16808d
  b->rem--;
Packit 16808d
}
Packit 16808d
Packit 16808d
Packit 16808d
gboolean gboolean_peek(struct mwGetBuffer *b) {
Packit 16808d
  gboolean v = FALSE;
Packit 16808d
Packit 16808d
  if(b->rem >= gboolean_buflen())
Packit 16808d
    v = !! *(b->ptr);
Packit 16808d
Packit 16808d
  return v;
Packit 16808d
}
Packit 16808d
Packit 16808d
Packit 16808d
static gboolean mw_streq(const char *a, const char *b) {
Packit 16808d
  return (a == b) || (a && b && !strcmp(a, b));
Packit 16808d
}
Packit 16808d
Packit 16808d
Packit 16808d
void mwString_put(struct mwPutBuffer *b, const char *val) {
Packit 16808d
  gsize len = 0;
Packit 16808d
Packit 16808d
  g_return_if_fail(b != NULL);
Packit 16808d
Packit 16808d
  if(val) len = strlen(val);
Packit 16808d
Packit 16808d
  guint16_put(b, (guint16) len);
Packit 16808d
Packit 16808d
  if(len) {
Packit 16808d
    ensure_buffer(b, len);
Packit 16808d
    memcpy(b->ptr, val, len);
Packit 16808d
    b->ptr += len;
Packit 16808d
    b->rem -= len;
Packit 16808d
  }
Packit 16808d
}
Packit 16808d
Packit 16808d
Packit 16808d
void mwString_get(struct mwGetBuffer *b, char **val) {
Packit 16808d
  guint16 len = 0;
Packit 16808d
Packit 16808d
  g_return_if_fail(b != NULL);
Packit 16808d
  g_return_if_fail(val != NULL);
Packit 16808d
Packit 16808d
  *val = NULL;
Packit 16808d
Packit 16808d
  if(b->error) return;
Packit 16808d
  guint16_get(b, &len;;
Packit 16808d
Packit 16808d
  g_return_if_fail(check_buffer(b, (gsize) len));
Packit 16808d
Packit 16808d
  if(len) {
Packit 16808d
    *val = g_malloc0(len + 1);
Packit 16808d
    memcpy(*val, b->ptr, len);
Packit 16808d
    b->ptr += len;
Packit 16808d
    b->rem -= len;
Packit 16808d
  }
Packit 16808d
}
Packit 16808d
Packit 16808d
Packit 16808d
void mwOpaque_put(struct mwPutBuffer *b, const struct mwOpaque *o) {
Packit 16808d
  gsize len;
Packit 16808d
Packit 16808d
  g_return_if_fail(b != NULL);
Packit 16808d
Packit 16808d
  if(! o) {
Packit 16808d
    guint32_put(b, 0x00);
Packit 16808d
    return;
Packit 16808d
  }
Packit 16808d
Packit 16808d
  len = o->len;
Packit 16808d
  if(len)
Packit 16808d
    g_return_if_fail(o->data != NULL);
Packit 16808d
  
Packit 16808d
  guint32_put(b, (guint32) len);
Packit 16808d
Packit 16808d
  if(len) {
Packit 16808d
    ensure_buffer(b, len);
Packit 16808d
    memcpy(b->ptr, o->data, len);
Packit 16808d
    b->ptr += len;
Packit 16808d
    b->rem -= len;
Packit 16808d
  }
Packit 16808d
}
Packit 16808d
Packit 16808d
Packit 16808d
void mwOpaque_get(struct mwGetBuffer *b, struct mwOpaque *o) {
Packit 16808d
  guint32 tmp = 0;
Packit 16808d
Packit 16808d
  g_return_if_fail(b != NULL);
Packit 16808d
  g_return_if_fail(o != NULL);
Packit 16808d
Packit 16808d
  o->len = 0;
Packit 16808d
  o->data = NULL;
Packit 16808d
  
Packit 16808d
  if(b->error) return;
Packit 16808d
  guint32_get(b, &tmp);
Packit 16808d
Packit 16808d
  g_return_if_fail(check_buffer(b, (gsize) tmp));
Packit 16808d
Packit 16808d
  o->len = (gsize) tmp;
Packit 16808d
  if(tmp > 0) {
Packit 16808d
    o->data = g_memdup(b->ptr, tmp);
Packit 16808d
    b->ptr += tmp;
Packit 16808d
    b->rem -= tmp;
Packit 16808d
  }
Packit 16808d
}
Packit 16808d
Packit 16808d
Packit 16808d
void mwOpaque_clear(struct mwOpaque *o) {
Packit 16808d
  if(! o) return;
Packit 16808d
  g_free(o->data);
Packit 16808d
  o->data = NULL;
Packit 16808d
  o->len = 0;
Packit 16808d
}
Packit 16808d
Packit 16808d
Packit 16808d
void mwOpaque_free(struct mwOpaque *o) {
Packit 16808d
  if(! o) return;
Packit 16808d
  g_free(o->data);
Packit 16808d
  g_free(o);
Packit 16808d
}
Packit 16808d
Packit 16808d
Packit 16808d
void mwOpaque_clone(struct mwOpaque *to, const struct mwOpaque *from) {
Packit 16808d
  g_return_if_fail(to != NULL);
Packit 16808d
Packit 16808d
  to->len = 0;
Packit 16808d
  to->data = NULL;
Packit 16808d
Packit 16808d
  if(from) {
Packit 16808d
    to->len = from->len;
Packit 16808d
    if(to->len)
Packit 16808d
      to->data = g_memdup(from->data, to->len);
Packit 16808d
  }
Packit 16808d
}
Packit 16808d
Packit 16808d
Packit 16808d
/* 8.2 Common Structures */
Packit 16808d
/* 8.2.1 Login Info block */
Packit 16808d
Packit 16808d
Packit 16808d
void mwLoginInfo_put(struct mwPutBuffer *b, const struct mwLoginInfo *login) {
Packit 16808d
  g_return_if_fail(b != NULL);
Packit 16808d
  g_return_if_fail(login != NULL);
Packit 16808d
Packit 16808d
  mwString_put(b, login->login_id);
Packit 16808d
  guint16_put(b, login->type);
Packit 16808d
  mwString_put(b, login->user_id);
Packit 16808d
  mwString_put(b, login->user_name);
Packit 16808d
  mwString_put(b, login->community);
Packit 16808d
  gboolean_put(b, login->full);
Packit 16808d
Packit 16808d
  if(login->full) {
Packit 16808d
    mwString_put(b, login->desc);
Packit 16808d
    guint32_put(b, login->ip_addr);
Packit 16808d
    mwString_put(b, login->server_id);
Packit 16808d
  }
Packit 16808d
}
Packit 16808d
Packit 16808d
Packit 16808d
void mwLoginInfo_get(struct mwGetBuffer *b, struct mwLoginInfo *login) {
Packit 16808d
  g_return_if_fail(b != NULL);
Packit 16808d
  g_return_if_fail(login != NULL);
Packit 16808d
Packit 16808d
  if(b->error) return;
Packit 16808d
Packit 16808d
  mwString_get(b, &login->login_id);
Packit 16808d
  guint16_get(b, &login->type);
Packit 16808d
  mwString_get(b, &login->user_id);
Packit 16808d
  mwString_get(b, &login->user_name);
Packit 16808d
  mwString_get(b, &login->community);
Packit 16808d
  gboolean_get(b, &login->full);
Packit 16808d
  
Packit 16808d
  if(login->full) {
Packit 16808d
    mwString_get(b, &login->desc);
Packit 16808d
    guint32_get(b, &login->ip_addr);
Packit 16808d
    mwString_get(b, &login->server_id);
Packit 16808d
  }
Packit 16808d
}
Packit 16808d
Packit 16808d
Packit 16808d
void mwLoginInfo_clear(struct mwLoginInfo *login) {
Packit 16808d
  if(! login) return;
Packit 16808d
Packit 16808d
  g_free(login->login_id);
Packit 16808d
  g_free(login->user_id);
Packit 16808d
  g_free(login->user_name);
Packit 16808d
  g_free(login->community);
Packit 16808d
  g_free(login->desc);
Packit 16808d
  g_free(login->server_id);
Packit 16808d
Packit 16808d
  memset(login, 0x00, sizeof(struct mwLoginInfo));
Packit 16808d
}
Packit 16808d
Packit 16808d
Packit 16808d
void mwLoginInfo_clone(struct mwLoginInfo *to,
Packit 16808d
		       const struct mwLoginInfo *from) {
Packit 16808d
Packit 16808d
  g_return_if_fail(to != NULL);
Packit 16808d
  g_return_if_fail(from != NULL);
Packit 16808d
Packit 16808d
  to->login_id= g_strdup(from->login_id);
Packit 16808d
  to->type = from->type;
Packit 16808d
  to->user_id = g_strdup(from->user_id);
Packit 16808d
  to->user_name = g_strdup(from->user_name);
Packit 16808d
  to->community = g_strdup(from->community);
Packit 16808d
Packit 16808d
  if( (to->full = from->full) ) {
Packit 16808d
    to->desc = g_strdup(from->desc);
Packit 16808d
    to->ip_addr = from->ip_addr;
Packit 16808d
    to->server_id = g_strdup(from->server_id);
Packit 16808d
  }
Packit 16808d
}
Packit 16808d
Packit 16808d
Packit 16808d
/* 8.2.2 Private Info Block */
Packit 16808d
Packit 16808d
Packit 16808d
void mwUserItem_put(struct mwPutBuffer *b, const struct mwUserItem *user) {
Packit 16808d
  g_return_if_fail(b != NULL);
Packit 16808d
  g_return_if_fail(user != NULL);
Packit 16808d
Packit 16808d
  gboolean_put(b, user->full);
Packit 16808d
  mwString_put(b, user->id);
Packit 16808d
  mwString_put(b, user->community);
Packit 16808d
  
Packit 16808d
  if(user->full)
Packit 16808d
    mwString_put(b, user->name);
Packit 16808d
}
Packit 16808d
Packit 16808d
Packit 16808d
void mwUserItem_get(struct mwGetBuffer *b, struct mwUserItem *user) {
Packit 16808d
  g_return_if_fail(b != NULL);
Packit 16808d
  g_return_if_fail(user != NULL);
Packit 16808d
Packit 16808d
  if(b->error) return;
Packit 16808d
Packit 16808d
  gboolean_get(b, &user->full);
Packit 16808d
  mwString_get(b, &user->id);
Packit 16808d
  mwString_get(b, &user->community);
Packit 16808d
Packit 16808d
  if(user->full)
Packit 16808d
    mwString_get(b, &user->name);
Packit 16808d
}
Packit 16808d
Packit 16808d
Packit 16808d
void mwUserItem_clear(struct mwUserItem *user) {
Packit 16808d
  if(! user) return;
Packit 16808d
Packit 16808d
  g_free(user->id);
Packit 16808d
  g_free(user->community);
Packit 16808d
  g_free(user->name);
Packit 16808d
Packit 16808d
  memset(user, 0x00, sizeof(struct mwUserItem));
Packit 16808d
}
Packit 16808d
Packit 16808d
Packit 16808d
void mwUserItem_clone(struct mwUserItem *to,
Packit 16808d
		      const struct mwUserItem *from) {
Packit 16808d
Packit 16808d
  g_return_if_fail(to != NULL);
Packit 16808d
  g_return_if_fail(from != NULL);
Packit 16808d
Packit 16808d
  to->full = from->full;
Packit 16808d
  to->id = g_strdup(from->id);
Packit 16808d
  to->community = g_strdup(from->community);
Packit 16808d
  to->name = (to->full)? g_strdup(from->name): NULL;
Packit 16808d
}
Packit 16808d
Packit 16808d
Packit 16808d
void mwPrivacyInfo_put(struct mwPutBuffer *b,
Packit 16808d
		       const struct mwPrivacyInfo *info) {
Packit 16808d
  guint32 c;
Packit 16808d
Packit 16808d
  g_return_if_fail(b != NULL);
Packit 16808d
  g_return_if_fail(info != NULL);
Packit 16808d
Packit 16808d
  gboolean_put(b, info->deny);
Packit 16808d
  guint32_put(b, info->count);
Packit 16808d
Packit 16808d
  for(c = info->count; c--; ) mwUserItem_put(b, info->users + c);
Packit 16808d
}
Packit 16808d
Packit 16808d
Packit 16808d
void mwPrivacyInfo_get(struct mwGetBuffer *b, struct mwPrivacyInfo *info) {
Packit 16808d
  g_return_if_fail(b != NULL);
Packit 16808d
  g_return_if_fail(info != NULL);
Packit 16808d
Packit 16808d
  if(b->error) return;
Packit 16808d
Packit 16808d
  gboolean_get(b, &info->deny);
Packit 16808d
  guint32_get(b, &info->count);
Packit 16808d
Packit 16808d
  if(info->count) {
Packit 16808d
    guint32 c = info->count;
Packit 16808d
    info->users = g_new0(struct mwUserItem, c);
Packit 16808d
    while(c--) mwUserItem_get(b, info->users + c);
Packit 16808d
  }
Packit 16808d
}
Packit 16808d
Packit 16808d
Packit 16808d
void mwPrivacyInfo_clone(struct mwPrivacyInfo *to,
Packit 16808d
			 const struct mwPrivacyInfo *from) {
Packit 16808d
Packit 16808d
  guint32 c;
Packit 16808d
Packit 16808d
  g_return_if_fail(to != NULL);
Packit 16808d
  g_return_if_fail(from != NULL);
Packit 16808d
Packit 16808d
  to->deny = from->deny;
Packit 16808d
  c = to->count = from->count;
Packit 16808d
Packit 16808d
  to->users = g_new0(struct mwUserItem, c);
Packit 16808d
  while(c--) mwUserItem_clone(to->users+c, from->users+c);
Packit 16808d
}
Packit 16808d
Packit 16808d
Packit 16808d
void mwPrivacyInfo_clear(struct mwPrivacyInfo *info) {
Packit 16808d
  struct mwUserItem *u;
Packit 16808d
  guint32 c;
Packit 16808d
Packit 16808d
  g_return_if_fail(info != NULL);
Packit 16808d
Packit 16808d
  u = info->users;
Packit 16808d
  c = info->count;
Packit 16808d
Packit 16808d
  while(c--) mwUserItem_clear(u + c);
Packit 16808d
  g_free(u);
Packit 16808d
Packit 16808d
  info->count = 0;
Packit 16808d
  info->users = NULL;
Packit 16808d
}
Packit 16808d
Packit 16808d
Packit 16808d
/* 8.2.3 User Status Block */
Packit 16808d
Packit 16808d
Packit 16808d
void mwUserStatus_put(struct mwPutBuffer *b,
Packit 16808d
		      const struct mwUserStatus *stat) {
Packit 16808d
Packit 16808d
  g_return_if_fail(b != NULL);
Packit 16808d
  g_return_if_fail(stat != NULL);
Packit 16808d
Packit 16808d
  guint16_put(b, stat->status);
Packit 16808d
  guint32_put(b, stat->time);
Packit 16808d
  mwString_put(b, stat->desc);
Packit 16808d
}
Packit 16808d
Packit 16808d
Packit 16808d
void mwUserStatus_get(struct mwGetBuffer *b, struct mwUserStatus *stat) {
Packit 16808d
  g_return_if_fail(b != NULL);
Packit 16808d
  g_return_if_fail(stat != NULL);
Packit 16808d
Packit 16808d
  if(b->error) return;
Packit 16808d
Packit 16808d
  guint16_get(b, &stat->status);
Packit 16808d
  guint32_get(b, &stat->time);
Packit 16808d
  mwString_get(b, &stat->desc);
Packit d0d0f6
Packit d0d0f6
  // Quick'n ugly hack for recent Sametime clients
Packit d0d0f6
  stat->time = 0;
Packit 16808d
}
Packit 16808d
Packit 16808d
Packit 16808d
void mwUserStatus_clear(struct mwUserStatus *stat) {
Packit 16808d
  if(! stat) return;
Packit 16808d
  g_free(stat->desc);
Packit 16808d
  memset(stat, 0x00, sizeof(struct mwUserStatus));
Packit 16808d
}
Packit 16808d
Packit 16808d
Packit 16808d
void mwUserStatus_clone(struct mwUserStatus *to,
Packit 16808d
			const struct mwUserStatus *from) {
Packit 16808d
Packit 16808d
  g_return_if_fail(to != NULL);
Packit 16808d
  g_return_if_fail(from != NULL);
Packit 16808d
Packit 16808d
  to->status = from->status;
Packit 16808d
  to->time = from->time;
Packit 16808d
  to->desc = g_strdup(from->desc);
Packit 16808d
}
Packit 16808d
Packit 16808d
Packit 16808d
/* 8.2.4 ID Block */
Packit 16808d
Packit 16808d
Packit 16808d
void mwIdBlock_put(struct mwPutBuffer *b, const struct mwIdBlock *id) {
Packit 16808d
  g_return_if_fail(b != NULL);
Packit 16808d
  g_return_if_fail(id != NULL);
Packit 16808d
Packit 16808d
  mwString_put(b, id->user);
Packit 16808d
  mwString_put(b, id->community);
Packit 16808d
}
Packit 16808d
Packit 16808d
Packit 16808d
void mwIdBlock_get(struct mwGetBuffer *b, struct mwIdBlock *id) {
Packit 16808d
  g_return_if_fail(b != NULL);
Packit 16808d
  g_return_if_fail(id != NULL);
Packit 16808d
Packit 16808d
  if(b->error) return;
Packit 16808d
Packit 16808d
  mwString_get(b, &id->user);
Packit 16808d
  mwString_get(b, &id->community);
Packit 16808d
}
Packit 16808d
Packit 16808d
Packit 16808d
void mwIdBlock_clear(struct mwIdBlock *id) {
Packit 16808d
  if(! id) return;
Packit 16808d
Packit 16808d
  g_free(id->user);
Packit 16808d
  id->user = NULL;
Packit 16808d
Packit 16808d
  g_free(id->community);
Packit 16808d
  id->community = NULL;
Packit 16808d
}
Packit 16808d
Packit 16808d
Packit 16808d
void mwIdBlock_clone(struct mwIdBlock *to, const struct mwIdBlock *from) {
Packit 16808d
  g_return_if_fail(to != NULL);
Packit 16808d
  g_return_if_fail(from != NULL);
Packit 16808d
Packit 16808d
  to->user = g_strdup(from->user);
Packit 16808d
  to->community = g_strdup(from->community);
Packit 16808d
}
Packit 16808d
Packit 16808d
Packit 16808d
guint mwIdBlock_hash(const struct mwIdBlock *idb) {
Packit 16808d
  return (idb)? g_str_hash(idb->user): 0;
Packit 16808d
}
Packit 16808d
Packit 16808d
Packit 16808d
gboolean mwIdBlock_equal(const struct mwIdBlock *a,
Packit 16808d
			 const struct mwIdBlock *b) {
Packit 16808d
Packit 16808d
  g_return_val_if_fail(a != NULL, FALSE);
Packit 16808d
  g_return_val_if_fail(b != NULL, FALSE);
Packit 16808d
Packit 16808d
  return ( mw_streq(a->user, b->user) &&
Packit 16808d
	   mw_streq(a->community, b->community) );
Packit 16808d
}
Packit 16808d
Packit 16808d
Packit 16808d
/* 8.2.5 Encryption Block */
Packit 16808d
Packit 16808d
/** @todo I think this can be put into cipher */
Packit 16808d
Packit 16808d
void mwEncryptItem_put(struct mwPutBuffer *b,
Packit 16808d
		       const struct mwEncryptItem *ei) {
Packit 16808d
Packit 16808d
  g_return_if_fail(b != NULL);
Packit 16808d
  g_return_if_fail(ei != NULL);
Packit 16808d
  
Packit 16808d
  guint16_put(b, ei->id);
Packit 16808d
  mwOpaque_put(b, &ei->info);
Packit 16808d
Packit 16808d
}
Packit 16808d
Packit 16808d
Packit 16808d
void mwEncryptItem_get(struct mwGetBuffer *b, struct mwEncryptItem *ei) {
Packit 16808d
  g_return_if_fail(b != NULL);
Packit 16808d
  g_return_if_fail(ei != NULL);
Packit 16808d
Packit 16808d
  if(b->error) return;
Packit 16808d
Packit 16808d
  guint16_get(b, &ei->id);
Packit 16808d
  mwOpaque_get(b, &ei->info);
Packit 16808d
}
Packit 16808d
Packit 16808d
Packit 16808d
void mwEncryptItem_clear(struct mwEncryptItem *ei) {
Packit 16808d
  if(! ei) return;
Packit 16808d
  ei->id = 0x0000;
Packit 16808d
  mwOpaque_clear(&ei->info);
Packit 16808d
}
Packit 16808d
Packit 16808d
Packit 16808d
void mwEncryptItem_free(struct mwEncryptItem *ei) {
Packit 16808d
  mwEncryptItem_clear(ei);
Packit 16808d
  g_free(ei);
Packit 16808d
}
Packit 16808d
Packit 16808d
Packit 16808d
/* 8.4.2.1 Awareness ID Block */
Packit 16808d
Packit 16808d
Packit 16808d
/** @todo move this into srvc_aware */
Packit 16808d
Packit 16808d
void mwAwareIdBlock_put(struct mwPutBuffer *b,
Packit 16808d
			const struct mwAwareIdBlock *idb) {
Packit 16808d
Packit 16808d
  g_return_if_fail(b != NULL);
Packit 16808d
  g_return_if_fail(idb != NULL);
Packit 16808d
Packit 16808d
  guint16_put(b, idb->type);
Packit 16808d
  mwString_put(b, idb->user);
Packit 16808d
  mwString_put(b, idb->community);
Packit 16808d
}
Packit 16808d
Packit 16808d
Packit 16808d
void mwAwareIdBlock_get(struct mwGetBuffer *b, struct mwAwareIdBlock *idb) {
Packit 16808d
  g_return_if_fail(b != NULL);
Packit 16808d
  g_return_if_fail(idb != NULL);
Packit 16808d
Packit 16808d
  if(b->error) return;
Packit 16808d
Packit 16808d
  guint16_get(b, &idb->type);
Packit 16808d
  mwString_get(b, &idb->user);
Packit 16808d
  mwString_get(b, &idb->community);
Packit 16808d
}
Packit 16808d
Packit 16808d
Packit 16808d
void mwAwareIdBlock_clone(struct mwAwareIdBlock *to,
Packit 16808d
			  const struct mwAwareIdBlock *from) {
Packit 16808d
Packit 16808d
  g_return_if_fail(to != NULL);
Packit 16808d
  g_return_if_fail(from != NULL);
Packit 16808d
Packit 16808d
  to->type = from->type;
Packit 16808d
  to->user = g_strdup(from->user);
Packit 16808d
  to->community = g_strdup(from->community);
Packit 16808d
}
Packit 16808d
Packit 16808d
Packit 16808d
void mwAwareIdBlock_clear(struct mwAwareIdBlock *idb) {
Packit 16808d
  if(! idb) return;
Packit 16808d
  g_free(idb->user);
Packit 16808d
  g_free(idb->community);
Packit 16808d
  memset(idb, 0x00, sizeof(struct mwAwareIdBlock));
Packit 16808d
}
Packit 16808d
Packit 16808d
Packit 16808d
guint mwAwareIdBlock_hash(const struct mwAwareIdBlock *a) {
Packit 16808d
  return (a)? g_str_hash(a->user): 0;
Packit 16808d
}
Packit 16808d
Packit 16808d
Packit 16808d
gboolean mwAwareIdBlock_equal(const struct mwAwareIdBlock *a,
Packit 16808d
			      const struct mwAwareIdBlock *b) {
Packit 16808d
Packit 16808d
  g_return_val_if_fail(a != NULL, FALSE);
Packit 16808d
  g_return_val_if_fail(b != NULL, FALSE);
Packit 16808d
  
Packit 16808d
  return ( (a->type == b->type) &&
Packit 16808d
	   mw_streq(a->user, b->user) &&
Packit 16808d
	   mw_streq(a->community, b->community) );
Packit 16808d
}
Packit 16808d
Packit 16808d
Packit 16808d
/* 8.4.2.4 Snapshot */
Packit 16808d
Packit 16808d
void mwAwareSnapshot_get(struct mwGetBuffer *b, struct mwAwareSnapshot *idb) {
Packit 16808d
  guint32 end_of_block;
Packit 16808d
Packit 16808d
  g_return_if_fail(b != NULL);
Packit 16808d
  g_return_if_fail(idb != NULL);
Packit 16808d
Packit 16808d
  guint32_get(b, &end_of_block);
Packit 16808d
  mwAwareIdBlock_get(b, &idb->id);
Packit 16808d
  mwString_get(b, &idb->group);
Packit 16808d
  gboolean_get(b, &idb->online);
Packit 16808d
Packit 16808d
  if(idb->online) {
Packit 16808d
    mwString_get(b, &idb->alt_id);
Packit 16808d
    mwUserStatus_get(b, &idb->status);
Packit 16808d
    mwString_get(b, &idb->name);
Packit 16808d
  }
Packit 16808d
Packit 16808d
  if(b->ptr < b->buf + end_of_block) {
Packit 16808d
    mwGetBuffer_advance(b, b->buf + end_of_block - b->ptr);
Packit 16808d
  }
Packit 16808d
}
Packit 16808d
Packit 16808d
Packit 16808d
void mwAwareSnapshot_clone(struct mwAwareSnapshot *to,
Packit 16808d
			   const struct mwAwareSnapshot *from) {
Packit 16808d
Packit 16808d
  g_return_if_fail(to != NULL);
Packit 16808d
  g_return_if_fail(from != NULL);
Packit 16808d
Packit 16808d
  mwAwareIdBlock_clone(&to->id, &from->id);
Packit 16808d
  if( (to->online = from->online) ) {
Packit 16808d
    to->alt_id = g_strdup(from->alt_id);
Packit 16808d
    mwUserStatus_clone(&to->status, &from->status);
Packit 16808d
    to->name = g_strdup(from->name);
Packit 16808d
    to->group = g_strdup(from->group);
Packit 16808d
  }
Packit 16808d
}
Packit 16808d
Packit 16808d
Packit 16808d
void mwAwareSnapshot_clear(struct mwAwareSnapshot *idb) {
Packit 16808d
  if(! idb) return;
Packit 16808d
  mwAwareIdBlock_clear(&idb->id);
Packit 16808d
  mwUserStatus_clear(&idb->status);
Packit 16808d
  g_free(idb->alt_id);
Packit 16808d
  g_free(idb->name);
Packit 16808d
  g_free(idb->group);
Packit 16808d
  memset(idb, 0x00, sizeof(struct mwAwareSnapshot));
Packit 16808d
}
Packit 16808d