Implement create_default_audio_* functions in gntmedia.c.
line source
/**
* @file object.c MSNObject API
*
* purple
*
* Purple is the legal property of its developers, whose names are too numerous
* to list here. Please refer to the COPYRIGHT file distributed with this
* source distribution.
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02111-1301 USA
*/
#include "object.h"
#include "debug.h"
/* Sha1 stuff */
#include "cipher.h"
/* Base64 stuff */
#include "util.h"
#define GET_STRING_TAG(field, id) \
if ((tag = strstr(str, id "=\"")) != NULL) \
{ \
tag += strlen(id "=\""); \
c = strchr(tag, '"'); \
if (c != NULL) \
{ \
if (obj->field != NULL) \
g_free(obj->field); \
obj->field = g_strndup(tag, c - tag); \
} \
}
#define GET_INT_TAG(field, id) \
if ((tag = strstr(str, id "=\"")) != NULL) \
{ \
char buf[16]; \
size_t offset; \
tag += strlen(id "=\""); \
c = strchr(tag, '"'); \
if (c != NULL) \
{ \
memset(buf, 0, sizeof(buf)); \
offset = c - tag; \
if (offset >= sizeof(buf)) \
offset = sizeof(buf) - 1; \
strncpy(buf, tag, offset); \
obj->field = atoi(buf); \
} \
}
static GList *local_objs;
MsnObject *
msn_object_new(void)
{
MsnObject *obj;
obj = g_new0(MsnObject, 1);
msn_object_set_type(obj, MSN_OBJECT_UNKNOWN);
msn_object_set_friendly(obj, "AAA=");
return obj;
}
MsnObject *
msn_object_new_from_string(const char *str)
{
MsnObject *obj;
char *tag, *c;
g_return_val_if_fail(str != NULL, NULL);
if (strncmp(str, "<msnobj ", 8))
return NULL;
obj = msn_object_new();
GET_STRING_TAG(creator, "Creator");
GET_INT_TAG(size, "Size");
GET_INT_TAG(type, "Type");
GET_STRING_TAG(location, "Location");
GET_STRING_TAG(friendly, "Friendly");
GET_STRING_TAG(sha1d, "SHA1D");
GET_STRING_TAG(sha1c, "SHA1C");
/* If we are missing any of the required elements then discard the object */
/* SHA1C is not always sent anymore */
if (obj->creator == NULL || obj->size == 0 || obj->type == 0
|| obj->location == NULL || obj->friendly == NULL
|| obj->sha1d == NULL /*|| obj->sha1c == NULL*/) {
purple_debug_error("msn", "Discarding invalid msnobj: '%s'\n", str);
msn_object_destroy(obj);
obj = NULL;
}
return obj;
}
MsnObject*
msn_object_new_from_image(PurpleStoredImage *img, const char *location,
const char *creator, MsnObjectType type)
{
MsnObject *msnobj;
PurpleCipherContext *ctx;
char *buf;
gconstpointer data;
size_t size;
char *base64;
unsigned char digest[20];
msnobj = NULL;
if (img == NULL)
return msnobj;
size = purple_imgstore_get_size(img);
data = purple_imgstore_get_data(img);
/* New object */
msnobj = msn_object_new();
msn_object_set_local(msnobj);
msn_object_set_type(msnobj, type);
msn_object_set_location(msnobj, location);
msn_object_set_creator(msnobj, creator);
msn_object_set_image(msnobj, img);
/* Compute the SHA1D field. */
memset(digest, 0, sizeof(digest));
ctx = purple_cipher_context_new_by_name("sha1", NULL);
purple_cipher_context_append(ctx, data, size);
purple_cipher_context_digest(ctx, sizeof(digest), digest, NULL);
base64 = purple_base64_encode(digest, sizeof(digest));
msn_object_set_sha1d(msnobj, base64);
g_free(base64);
msn_object_set_size(msnobj, size);
/* Compute the SHA1C field. */
buf = g_strdup_printf(
"Creator%sSize%dType%dLocation%sFriendly%sSHA1D%s",
msn_object_get_creator(msnobj),
msn_object_get_size(msnobj),
msn_object_get_type(msnobj),
msn_object_get_location(msnobj),
msn_object_get_friendly(msnobj),
msn_object_get_sha1d(msnobj));
memset(digest, 0, sizeof(digest));
purple_cipher_context_reset(ctx, NULL);
purple_cipher_context_append(ctx, (const guchar *)buf, strlen(buf));
purple_cipher_context_digest(ctx, sizeof(digest), digest, NULL);
purple_cipher_context_destroy(ctx);
g_free(buf);
base64 = purple_base64_encode(digest, sizeof(digest));
msn_object_set_sha1c(msnobj, base64);
g_free(base64);
return msnobj;
}
void
msn_object_destroy(MsnObject *obj)
{
g_return_if_fail(obj != NULL);
g_free(obj->creator);
g_free(obj->location);
g_free(obj->friendly);
g_free(obj->sha1d);
g_free(obj->sha1c);
purple_imgstore_unref(obj->img);
if (obj->local)
local_objs = g_list_remove(local_objs, obj);
g_free(obj);
}
char *
msn_object_to_string(const MsnObject *obj)
{
char *str;
const char *sha1c;
g_return_val_if_fail(obj != NULL, NULL);
sha1c = msn_object_get_sha1c(obj);
str = g_strdup_printf("<msnobj Creator=\"%s\" Size=\"%d\" Type=\"%d\" "
"Location=\"%s\" Friendly=\"%s\" SHA1D=\"%s\""
"%s%s%s/>",
msn_object_get_creator(obj),
msn_object_get_size(obj),
msn_object_get_type(obj),
msn_object_get_location(obj),
msn_object_get_friendly(obj),
msn_object_get_sha1d(obj),
sha1c ? " SHA1C=\"" : "",
sha1c ? sha1c : "",
sha1c ? "\"" : "");
return str;
}
void
msn_object_set_creator(MsnObject *obj, const char *creator)
{
g_return_if_fail(obj != NULL);
if (obj->creator != NULL)
g_free(obj->creator);
obj->creator = (creator == NULL ? NULL : g_strdup(creator));
}
void
msn_object_set_size(MsnObject *obj, int size)
{
g_return_if_fail(obj != NULL);
obj->size = size;
}
void
msn_object_set_type(MsnObject *obj, MsnObjectType type)
{
g_return_if_fail(obj != NULL);
obj->type = type;
}
void
msn_object_set_location(MsnObject *obj, const char *location)
{
g_return_if_fail(obj != NULL);
if (obj->location != NULL)
g_free(obj->location);
obj->location = (location == NULL ? NULL : g_strdup(location));
}
void
msn_object_set_friendly(MsnObject *obj, const char *friendly)
{
g_return_if_fail(obj != NULL);
if (obj->friendly != NULL)
g_free(obj->friendly);
obj->friendly = (friendly == NULL ? NULL : g_strdup(friendly));
}
void
msn_object_set_sha1d(MsnObject *obj, const char *sha1d)
{
g_return_if_fail(obj != NULL);
if (obj->sha1d != NULL)
g_free(obj->sha1d);
obj->sha1d = (sha1d == NULL ? NULL : g_strdup(sha1d));
}
void
msn_object_set_sha1c(MsnObject *obj, const char *sha1c)
{
g_return_if_fail(obj != NULL);
if (obj->sha1c != NULL)
g_free(obj->sha1c);
obj->sha1c = (sha1c == NULL ? NULL : g_strdup(sha1c));
}
const char *
msn_object_get_creator(const MsnObject *obj)
{
g_return_val_if_fail(obj != NULL, NULL);
return obj->creator;
}
int
msn_object_get_size(const MsnObject *obj)
{
g_return_val_if_fail(obj != NULL, 0);
return obj->size;
}
MsnObjectType
msn_object_get_type(const MsnObject *obj)
{
g_return_val_if_fail(obj != NULL, MSN_OBJECT_UNKNOWN);
return obj->type;
}
const char *
msn_object_get_location(const MsnObject *obj)
{
g_return_val_if_fail(obj != NULL, NULL);
return obj->location;
}
const char *
msn_object_get_friendly(const MsnObject *obj)
{
g_return_val_if_fail(obj != NULL, NULL);
return obj->friendly;
}
const char *
msn_object_get_sha1d(const MsnObject *obj)
{
g_return_val_if_fail(obj != NULL, NULL);
return obj->sha1d;
}
const char *
msn_object_get_sha1c(const MsnObject *obj)
{
g_return_val_if_fail(obj != NULL, NULL);
return obj->sha1c;
}
const char *
msn_object_get_sha1(const MsnObject *obj)
{
g_return_val_if_fail(obj != NULL, NULL);
if(obj->sha1c != NULL) {
return obj->sha1c;
} else {
return obj->sha1d;
}
}
static MsnObject *
msn_object_find_local(const char *sha1)
{
GList *l;
g_return_val_if_fail(sha1 != NULL, NULL);
for (l = local_objs; l != NULL; l = l->next)
{
MsnObject *local_obj = l->data;
if (!strcmp(msn_object_get_sha1(local_obj), sha1))
return local_obj;
}
return NULL;
}
void
msn_object_set_local(MsnObject *obj)
{
g_return_if_fail(obj != NULL);
obj->local = TRUE;
local_objs = g_list_append(local_objs, obj);
}
void
msn_object_set_image(MsnObject *obj, PurpleStoredImage *img)
{
g_return_if_fail(obj != NULL);
g_return_if_fail(img != NULL);
/* obj->local = TRUE; */
purple_imgstore_unref(obj->img);
obj->img = purple_imgstore_ref(img);
}
PurpleStoredImage *
msn_object_get_image(const MsnObject *obj)
{
MsnObject *local_obj;
g_return_val_if_fail(obj != NULL, NULL);
local_obj = msn_object_find_local(msn_object_get_sha1(obj));
if (local_obj != NULL)
return local_obj->img;
return NULL;
}