[evolution-ews] Map the ews-oab-props with EContactField's and form EContact. Store the EContact into the db with th
- From: Chenthill Palanisamy <pchen src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [evolution-ews] Map the ews-oab-props with EContactField's and form EContact. Store the EContact into the db with th
- Date: Fri, 8 Jul 2011 15:33:21 +0000 (UTC)
commit 331178f12940ff2b31d31ebc8aee80b552231650
Author: Chenthill Palanisamy <pchenthill novell com>
Date: Fri Jul 8 21:00:03 2011 +0530
Map the ews-oab-props with EContactField's and form EContact.
Store the EContact into the db with the file offset data.
Use GFileStream itself as GDataStream is not seekable.
src/addressbook/ews-oab-decoder.c | 433 ++++++++++++++++++++++++++++++-------
src/addressbook/ews-oab-decoder.h | 1 +
2 files changed, 361 insertions(+), 73 deletions(-)
---
diff --git a/src/addressbook/ews-oab-decoder.c b/src/addressbook/ews-oab-decoder.c
index 55d4157..84f8900 100644
--- a/src/addressbook/ews-oab-decoder.c
+++ b/src/addressbook/ews-oab-decoder.c
@@ -23,12 +23,14 @@
#include <stdlib.h>
#include <glib/gstdio.h>
+#include <libebook/e-vcard.h>
+
#include "ews-oab-decoder.h"
#include "ews-oab-props.h"
G_DEFINE_TYPE (EwsOabDecoder, ews_oab_decoder, G_TYPE_OBJECT)
-#define d(x)
+#define d(x) x
#define GET_PRIVATE(o) \
(G_TYPE_INSTANCE_GET_PRIVATE ((o), EWS_TYPE_OAB_DECODER, EwsOabDecoderPrivate))
@@ -40,14 +42,153 @@ typedef struct _EwsOabDecoderPrivate EwsOabDecoderPrivate;
struct _EwsOabDecoderPrivate {
gchar *cache_dir;
+ gchar *folder_id;
GFileInputStream *fis;
- GDataInputStream *dis;
EBookBackendSqliteDB *ebsdb;
guint32 total_records;
GSList *hdr_props;
GSList *oab_props;
+
+ GHashTable *prop_index_dict;
+};
+
+/* The of properties which will be accumulated and later set in EContact */
+typedef struct {
+ EContactAddress *addr;
+} EwsDeferredSet;
+
+static void
+ews_populate_simple_string (EContact *contact, EContactField field, gpointer value, gpointer user_data)
+{
+ const gchar *str = (const gchar *) value;
+ e_contact_set (contact, field, str);
+}
+
+static void
+ews_deffered_populate_physical_address (EwsDeferredSet *dset, guint32 prop_id, gpointer value)
+{
+ gchar *val = g_strdup ((gchar *)value);
+
+ if (!dset->addr)
+ dset->addr = g_new0 (EContactAddress, 1);
+
+ switch (prop_id) {
+ case EWS_PT_STREET_ADDRESS:
+ dset->addr->street = val;
+ break;
+ case EWS_PT_LOCALITY:
+ dset->addr->locality = val;
+ break;
+ case EWS_PT_STATE_OR_PROVINCE:
+ dset->addr->region = val;
+ break;
+ case EWS_PT_POSTAL_CODE:
+ dset->addr->code = val;
+ break;
+ case EWS_PT_COUNTRY:
+ dset->addr->country = val;
+ break;
+ default:
+ g_free (val);
+ break;
+ }
+}
+
+static void
+ews_populate_phone_numbers (EContact *contact, EContactField field, gpointer value, gpointer user_data)
+{
+ GSList *values = (GSList *) value;
+ gint i, len;
+
+ /* Just the two phone numbers from the list. it would be either business or home phone number. I don't
+ see a cleaner way than this at the moment */
+ len = g_slist_length (values);
+ for (i = 0; i < 2 && i < len; i++) {
+ const gchar *val = g_slist_nth_data (values, i);
+ e_contact_set (contact, field + i, val);
+ }
+}
+
+static void
+ews_populate_string_list (EContact *contact, EContactField field, gpointer value, gpointer user_data)
+{
+ GSList *sl_values = (GSList *) value, *sl;
+ GList *l_values = NULL;
+
+
+ for (sl = sl_values; sl != NULL; sl = g_slist_next (sl)) {
+ const gchar *val = (gchar *) sl_values->data;
+ l_values = g_list_prepend (l_values, g_strdup (val));
+ }
+
+ l_values = g_list_reverse (l_values);
+ e_contact_set (contact, field, l_values);
+
+ g_list_free (l_values);
+}
+
+static void
+ews_populate_photo (EContact *contact, EContactField field, gpointer value, gpointer user_data)
+{
+ EwsOabDecoder *eod = EWS_OAB_DECODER (user_data);
+ EwsOabDecoderPrivate *priv = GET_PRIVATE (eod);
+ const gchar *val = (gchar *) value;
+ EContactPhoto *photo = g_new0 (EContactPhoto, 1);
+ gchar *fullname = e_contact_get (contact, E_CONTACT_FULL_NAME);
+ gchar *filename = NULL, *pic_name = NULL;
+
+ /* Rename the binary file to fullname.png */
+ if (fullname) {
+ pic_name = g_strconcat (fullname, ".png", NULL);
+ filename = g_build_filename (priv->cache_dir, pic_name, NULL);
+ g_rename (val, filename);
+ } else
+ filename = g_strdup (val);
+
+ photo->type = E_CONTACT_PHOTO_TYPE_URI;
+ photo->data.uri = filename;
+
+ e_contact_set (contact, field, (gpointer) photo);
+
+ g_free (photo);
+ g_free (fullname);
+ g_free (pic_name);
+ g_free (filename);
+}
+
+static const struct prop_field_mapping {
+ guint32 prop_id;
+ EContactField field;
+ void (*populate_function) (EContact *contact, EContactField field, gpointer value, gpointer user_data);
+ void (*defered_populate_function) (EwsDeferredSet *dset, guint32 prop_id, gpointer value);
+} prop_map [] = {
+ {EWS_PT_SMTP_ADDRESS, E_CONTACT_EMAIL_1, ews_populate_simple_string},
+ {EWS_PT_DISPLAY_NAME, E_CONTACT_FULL_NAME, ews_populate_simple_string},
+ {EWS_PT_ACCOUNT, E_CONTACT_NICKNAME, ews_populate_simple_string},
+ {EWS_PT_SURNAME, E_CONTACT_FAMILY_NAME, ews_populate_simple_string},
+ {EWS_PT_GIVEN_NAME, E_CONTACT_GIVEN_NAME, ews_populate_simple_string},
+ {EWS_PT_BUS_TEL_NUMBER, E_CONTACT_PHONE_BUSINESS, ews_populate_simple_string},
+ {EWS_PT_STREET_ADDRESS, E_CONTACT_ADDRESS_WORK, NULL, ews_deffered_populate_physical_address},
+ {EWS_PT_LOCALITY, E_CONTACT_ADDRESS_WORK, NULL, ews_deffered_populate_physical_address},
+ {EWS_PT_STATE_OR_PROVINCE, E_CONTACT_ADDRESS_WORK, NULL, ews_deffered_populate_physical_address},
+ {EWS_PT_POSTAL_CODE, E_CONTACT_ADDRESS_WORK, NULL, ews_deffered_populate_physical_address},
+ {EWS_PT_COUNTRY, E_CONTACT_ADDRESS_WORK, NULL, ews_deffered_populate_physical_address},
+ {EWS_PT_TITLE, E_CONTACT_TITLE, ews_populate_simple_string},
+ {EWS_PT_COMPANY_NAME, E_CONTACT_ORG, ews_populate_simple_string},
+ {EWS_PT_ASSISTANT, E_CONTACT_ASSISTANT, ews_populate_simple_string},
+ {EWS_PT_DEPARTMENT_NAME, E_CONTACT_ORG_UNIT, ews_populate_simple_string},
+ {EWS_PT_HOME_TEL_NUMBER, E_CONTACT_PHONE_HOME, ews_populate_simple_string},
+ {EWS_PT_BUS_TEL_NUMBERS, E_CONTACT_PHONE_BUSINESS, ews_populate_phone_numbers},
+ {EWS_PT_HOME_TEL_NUMBERS, E_CONTACT_PHONE_HOME, ews_populate_phone_numbers},
+ {EWS_PT_PRIMARY_FAX_NUMBER, E_CONTACT_PHONE_BUSINESS_FAX, ews_populate_simple_string},
+ {EWS_PT_MOB_TEL_NUMBER, E_CONTACT_PHONE_MOBILE, ews_populate_simple_string},
+ {EWS_PT_ASSISTANT_TEL_NUMBER, E_CONTACT_PHONE_ASSISTANT, ews_populate_simple_string},
+ {EWS_PT_PAGER_NUMBER, E_CONTACT_PHONE_PAGER, ews_populate_simple_string},
+ {EWS_PT_COMMENT, E_CONTACT_NOTE, ews_populate_simple_string},
+ {EWS_PT_DL_MEMBERS, E_CONTACT_EMAIL, ews_populate_string_list},
+ {EWS_PT_THUMBNAIL_PHOTO, E_CONTACT_PHOTO, ews_populate_photo}
};
static void
@@ -59,15 +200,25 @@ ews_oab_decoder_finalize (GObject *object)
g_free (priv->cache_dir);
priv->cache_dir = NULL;
}
-
+
+ if (priv->folder_id) {
+ g_free (priv->folder_id);
+ priv->folder_id = NULL;
+ }
+
if (priv->ebsdb) {
g_object_unref (priv->ebsdb);
priv->ebsdb = NULL;
}
- if (priv->dis) {
- g_object_unref (priv->dis);
- priv->dis = NULL;
+ if (priv->fis) {
+ g_object_unref (priv->fis);
+ priv->fis = NULL;
+ }
+
+ if (priv->prop_index_dict) {
+ g_hash_table_destroy (priv->prop_index_dict);
+ priv->prop_index_dict = NULL;
}
G_OBJECT_CLASS (ews_oab_decoder_parent_class)->finalize (object);
@@ -87,13 +238,19 @@ static void
ews_oab_decoder_init (EwsOabDecoder *self)
{
EwsOabDecoderPrivate *priv = GET_PRIVATE (self);
+ gint i;
priv->cache_dir = NULL;
+
+ priv->prop_index_dict = g_hash_table_new (g_direct_hash, g_direct_equal);
+ for (i = 1; i <= G_N_ELEMENTS (prop_map); i++)
+ g_hash_table_insert (priv->prop_index_dict, GINT_TO_POINTER (prop_map[i-1].prop_id), GINT_TO_POINTER (i));
}
EwsOabDecoder*
ews_oab_decoder_new (const gchar *oab_filename,
const gchar *cache_dir,
+ const gchar *folder_id,
EBookBackendSqliteDB *ebsdb,
GError **error)
{
@@ -110,11 +267,10 @@ ews_oab_decoder_new (const gchar *oab_filename,
if (err)
goto exit;
- priv->dis = g_data_input_stream_new ((GInputStream *) priv->fis);
priv->ebsdb = g_object_ref (ebsdb);
priv->cache_dir = g_strdup (cache_dir);
+ priv->folder_id = g_strdup (folder_id);
- g_data_input_stream_set_byte_order (priv->dis, G_DATA_STREAM_BYTE_ORDER_LITTLE_ENDIAN);
exit:
if (gf)
g_object_unref (gf);
@@ -140,6 +296,62 @@ ews_oab_decoder_error_quark (void)
return quark;
}
+/* endian-neutral reading of little-endian data */
+#define __egi32(a,n) ( ((((unsigned char *) a)[n+3]) << 24) | \
+ ((((unsigned char *) a)[n+2]) << 16) | \
+ ((((unsigned char *) a)[n+1]) << 8) | \
+ ((((unsigned char *) a)[n+0])))
+#define EndGetI64(a) ((((unsigned long long int) __egi32(a,4)) << 32) | \
+ ((unsigned int) __egi32(a,0)))
+#define EndGetI32(a) __egi32(a,0)
+#define EndGetI16(a) ((((a)[1])<<8)|((a)[0]))
+
+static guint32
+ews_oab_read_uint32 (GInputStream *is, GCancellable *cancellable, GError **error)
+{
+ gchar *str = g_malloc0 (4);
+ guint32 ret = 0;
+
+ g_input_stream_read (is, str, 4, cancellable, error);
+ if (!*error)
+ ret = EndGetI32 (str);
+
+ g_free (str);
+ return ret;
+}
+
+static guint16
+ews_oab_read_uint16 (GInputStream *is, GCancellable *cancellable, GError **error)
+{
+ gchar *str = g_malloc0 (2);
+ guint16 ret = 0;
+
+ g_input_stream_read (is, str, 2, cancellable, error);
+ if (!*error)
+ ret = EndGetI16 (str);
+
+ g_free (str);
+ return ret;
+}
+
+/* Read upto the stop char include the same */
+static gchar *
+ews_oab_read_upto (GInputStream *is, gchar stop, GCancellable *cancellable, GError **error)
+{
+ gchar c = -1;
+ GString *str;
+
+ str = g_string_new (NULL);
+ do {
+ g_input_stream_read (is, &c, 1, cancellable, error);
+ if (c == stop)
+ break;
+ str = g_string_append_c (str, c);
+ } while (!*error);
+
+ return g_string_free (str, FALSE);
+}
+
typedef struct {
guint32 version;
guint32 serial;
@@ -154,7 +366,7 @@ ews_read_oab_header (EwsOabDecoder *eod, GCancellable *cancellable, GError **err
o_hdr = g_new0 (EwsOabHdr, 1);
- o_hdr->version = g_data_input_stream_read_uint32 (priv->dis, cancellable, error);
+ o_hdr->version = ews_oab_read_uint32 (G_INPUT_STREAM (priv->fis), cancellable, error);
if (*error)
goto exit;
@@ -163,10 +375,10 @@ ews_read_oab_header (EwsOabDecoder *eod, GCancellable *cancellable, GError **err
goto exit;
}
- o_hdr->serial = g_data_input_stream_read_uint32 (priv->dis, cancellable, error);
+ o_hdr->serial = ews_oab_read_uint32 (G_INPUT_STREAM (priv->fis), cancellable, error);
if (*error)
goto exit;
- o_hdr->total_recs = g_data_input_stream_read_uint32 (priv->dis, cancellable, error);
+ o_hdr->total_recs = ews_oab_read_uint32 (G_INPUT_STREAM (priv->fis), cancellable, error);
exit:
if (*error) {
@@ -186,7 +398,7 @@ ews_decode_hdr_props (EwsOabDecoder *eod, gboolean oab_hdrs, GCancellable *cance
GSList **props;
/* number of properties */
- num_props = g_data_input_stream_read_uint32 (priv->dis, cancellable, error);
+ num_props = ews_oab_read_uint32 (G_INPUT_STREAM (priv->fis), cancellable, error);
if (*error)
return FALSE;
@@ -198,13 +410,13 @@ ews_decode_hdr_props (EwsOabDecoder *eod, gboolean oab_hdrs, GCancellable *cance
for (i = 0; i < num_props; i++) {
guint32 prop_id, flags;
- prop_id = g_data_input_stream_read_uint32 (priv->dis, cancellable, error);
- d(g_print ("%x \n", prop_id);)
+ prop_id = ews_oab_read_uint32 (G_INPUT_STREAM (priv->fis), cancellable, error);
+ d(g_print ("%X \n", prop_id);)
*props = g_slist_prepend (*props, GUINT_TO_POINTER (prop_id));
if (*error)
return FALSE;
- flags = g_data_input_stream_read_uint32 (priv->dis, cancellable, error);
+ flags = ews_oab_read_uint32 (G_INPUT_STREAM (priv->fis), cancellable, error);
if (*error)
return FALSE;
@@ -225,7 +437,7 @@ ews_decode_metadata (EwsOabDecoder *eod, GCancellable *cancellable, GError **err
guint32 size;
/* Size */
- size = g_data_input_stream_read_uint32 (priv->dis, cancellable, error);
+ size = ews_oab_read_uint32 (G_INPUT_STREAM (priv->fis), cancellable, error);
if (*error)
return FALSE;
@@ -257,11 +469,11 @@ ews_decode_uint32 (EwsOabDecoder *eod, GCancellable *cancellable, GError **error
{
EwsOabDecoderPrivate *priv = GET_PRIVATE (eod);
guint8 first;
- guint32 ret = -1, num;
+ guint32 ret = 0, num;
- first = g_data_input_stream_read_byte (priv->dis, cancellable, error);
+ g_input_stream_read (G_INPUT_STREAM (priv->fis), &first, 1, cancellable, error);
if (*error)
- goto exit;
+ return ret;
if (first & 0x80)
num = first & 0x0F;
@@ -269,18 +481,18 @@ ews_decode_uint32 (EwsOabDecoder *eod, GCancellable *cancellable, GError **error
return (guint32) first;
if (num == 1) {
- ret = g_data_input_stream_read_byte (priv->dis, cancellable, error);
- goto exit;
+ g_input_stream_read (G_INPUT_STREAM (priv->fis), &first, 1, cancellable, error);
+ return (guint32) first;
}
if (num == 2)
- ret = (guint16) g_data_input_stream_read_uint16 (priv->dis, cancellable, error);
+ ret = ews_oab_read_uint16 (G_INPUT_STREAM (priv->fis), cancellable, error);
if (num == 3) {
gchar *tmp, *str = g_malloc0 (num + 1);
- g_input_stream_read (G_INPUT_STREAM (priv->dis), str, num, cancellable, error);
+ g_input_stream_read (G_INPUT_STREAM (priv->fis), str, num, cancellable, error);
/* not sure if its the right way to do, test it */
- tmp = g_strconcat ("0000", str, NULL);
+ tmp = g_strconcat ("0", str, NULL);
ret = atoi (tmp);
ret = GUINT32_SWAP_LE_BE (ret);
@@ -288,9 +500,8 @@ ews_decode_uint32 (EwsOabDecoder *eod, GCancellable *cancellable, GError **error
g_free (str);
g_free (tmp);
} else if (num == 4)
- ret = g_data_input_stream_read_uint32 (priv->dis, cancellable, error);
+ ret = ews_oab_read_uint32 (G_INPUT_STREAM (priv->fis), cancellable, error);
-exit:
return ret;
}
@@ -307,7 +518,7 @@ ews_decode_binary (EwsOabDecoder *eod, GCancellable *cancellable, GError **error
return NULL;
binary = g_malloc (len);
- g_input_stream_read (G_INPUT_STREAM (priv->dis), binary, len, cancellable, error);
+ g_input_stream_read (G_INPUT_STREAM (priv->fis), binary, len, cancellable, error);
if (*error)
goto exit;
@@ -340,7 +551,7 @@ ews_decode_oab_prop (EwsOabDecoder *eod, guint32 prop_id, GCancellable *cancella
val = ews_decode_uint32 (eod, cancellable, error);
ret_val = GUINT_TO_POINTER (val);
- d(g_print ("prop id %x prop type: int32 value %d \n", prop_id, val);)
+ d(g_print ("prop id %X prop type: int32 value %d \n", prop_id, val);)
break;
}
@@ -348,29 +559,27 @@ ews_decode_oab_prop (EwsOabDecoder *eod, guint32 prop_id, GCancellable *cancella
{
guchar val;
- val = g_data_input_stream_read_byte (priv->dis, cancellable, error);
+ g_input_stream_read (G_INPUT_STREAM (priv->fis), &val, 1, cancellable, error);
ret_val = GUINT_TO_POINTER ((guint) val);
- d(g_print ("prop id %x prop type: bool value %d \n", prop_id, val);)
+ d(g_print ("prop id %X prop type: bool value %d \n", prop_id, val);)
break;
}
case EWS_PTYP_STRING8:
case EWS_PTYP_STRING:
{
- gsize len;
gchar *val;
- val= g_data_input_stream_read_upto (priv->dis, "\0", 1, &len, cancellable, error);
- g_data_input_stream_read_byte (priv->dis, cancellable, error);
+ val = ews_oab_read_upto (G_INPUT_STREAM (priv->fis), '\0', cancellable, error);
ret_val = (gpointer) val;
- d(g_print ("prop id %x prop type: string value %s \n", prop_id, val);)
+ d(g_print ("prop id %X prop type: string value %s \n", prop_id, val);)
break;
}
case EWS_PTYP_BINARY:
{
ret_val = ews_decode_binary (eod, cancellable, error);
- d(g_print ("prop id %x prop type: binary value %s \n", prop_id, (gchar *) ret_val);)
+ d(g_print ("prop id %X prop type: binary value %s \n", prop_id, (gchar *) ret_val);)
break;
}
case EWS_PTYP_MULTIPLEINTEGER32:
@@ -384,7 +593,7 @@ ews_decode_oab_prop (EwsOabDecoder *eod, guint32 prop_id, GCancellable *cancella
num = ews_decode_uint32 (eod, cancellable, error);
if (*error)
break;
- d(g_print ("prop id %x prop type: multi-num %d \n", prop_id, num);)
+ d(g_print ("prop id %X prop type: multi-num %d \n", prop_id, num);)
for (i = 0; i < num; i++) {
gpointer val;
@@ -396,7 +605,7 @@ ews_decode_oab_prop (EwsOabDecoder *eod, guint32 prop_id, GCancellable *cancella
val = GUINT_TO_POINTER (v);
list = g_slist_prepend (list, val);
- d(g_print ("prop id %x prop type: multi-int32 %d \n", prop_id, v);)
+ d(g_print ("prop id %X prop type: multi-int32 %d \n", prop_id, v);)
if (*error) {
g_slist_free (list);
return NULL;
@@ -406,15 +615,10 @@ ews_decode_oab_prop (EwsOabDecoder *eod, guint32 prop_id, GCancellable *cancella
if (prop_type == EWS_PTYP_MULTIPLEBINARY) {
val = ews_decode_binary (eod, cancellable, error);
-
- d(g_print ("prop id %x prop type: multi-string %s \n", prop_id, val);)
+ d(g_print ("prop id %X prop type: multi-string %s \n", prop_id, val);)
} else {
- gsize len;
-
- val= g_data_input_stream_read_upto (priv->dis, "\0", 1, &len, cancellable, error);
- g_data_input_stream_read_byte (priv->dis, cancellable, error);
-
- d(g_print ("prop id %x prop type: multi-string %s \n", prop_id, val);)
+ val = ews_oab_read_upto (G_INPUT_STREAM (priv->fis), '\0', cancellable, error);
+ d(g_print ("prop id %X prop type: multi-string %s \n", prop_id, val);)
}
if (*error) {
@@ -454,7 +658,8 @@ ews_destroy_oab_prop (guint32 prop_id, gpointer val, gboolean delete_files)
g_free ((gchar *) val);
break;
case EWS_PTYP_MULTIPLEBINARY:
- g_slist_foreach ((GSList *)val, (GFunc) g_unlink, NULL);
+ if (delete_files)
+ g_slist_foreach ((GSList *)val, (GFunc) g_unlink, NULL);
case EWS_PTYP_MULTIPLESTRING8:
case EWS_PTYP_MULTIPLESTRING:
g_slist_foreach ((GSList *)val, (GFunc) g_free, NULL);
@@ -471,36 +676,35 @@ ews_destroy_oab_prop (guint32 prop_id, gpointer val, gboolean delete_files)
* ews_decode_addressbook_record
* @eod:
* @contact: Pass a valid EContact for decoding the address-book record. NULL in case of header record.
- * @props:
+ * @props:
+ * @dset: used to collect multiple properties that needs to be combined and stored as one EContactField
* @cancellable:
* @error:
*
- * Decodes the header and address-book records.
+ * Decodes the address-book records starting from presence bit array.
+ *
+ *
* Returns:
**/
static gboolean
-ews_decode_addressbook_record (EwsOabDecoder *eod, EContact *contact, GSList *props, GCancellable *cancellable, GError **error)
+ews_decode_addressbook_record (EwsOabDecoder *eod, EContact *contact, EwsDeferredSet *dset, GSList *props, GCancellable *cancellable, GError **error)
{
EwsOabDecoderPrivate *priv = GET_PRIVATE (eod);
guint bit_array_size, i, len;
gchar *bit_str;
gboolean ret = TRUE;
- goffset offset;
-
- /* fetch the offset */
- offset = g_seekable_tell ((GSeekable *) priv->fis);
len = g_slist_length (props);
bit_array_size = (guint) ceil (len/8.0);
bit_str = g_malloc0 (bit_array_size);
- g_input_stream_read (G_INPUT_STREAM (priv->dis), bit_str, bit_array_size, cancellable, error);
+ g_input_stream_read (G_INPUT_STREAM (priv->fis), bit_str, bit_array_size, cancellable, error);
if (*error) {
ret = FALSE;
goto exit;
}
for (i = 0; i < len; i++) {
- gpointer val;
+ gpointer val, index;
guint32 prop_id;
if (!ews_is_bit_set (bit_str, i))
@@ -512,13 +716,19 @@ ews_decode_addressbook_record (EwsOabDecoder *eod, EContact *contact, GSList *pr
val = ews_decode_oab_prop (eod, prop_id, cancellable, error);
/* Check the contact map and store the data in EContact */
- if (contact) {
-
+ index = g_hash_table_lookup (priv->prop_index_dict, GINT_TO_POINTER (prop_id));
+ if (contact && index) {
+ gint i = GPOINTER_TO_INT (index);
+
+ if (prop_map [i-1].populate_function)
+ prop_map [i-1].populate_function (contact, prop_map[i-1].field, val, (gpointer) eod);
+ else
+ prop_map [i-1].defered_populate_function (dset, prop_id, val);
}
- /* Store the contact summary into the db along with the offset */
-
- ews_destroy_oab_prop (prop_id, val, *error ? TRUE : FALSE);
+ /* delete the binary file if we do not have the property in the index or if there
+ was an error */
+ ews_destroy_oab_prop (prop_id, val, (*error || !index) ? TRUE : FALSE);
if (*error)
goto exit;
}
@@ -530,7 +740,7 @@ exit:
return ret;
}
-/* Decodes the hrd and address-book records and stores the address-book records inside the db */
+/* Decodes the hdr and address-book records and stores the address-book records inside the db */
static gboolean
ews_decode_and_store_oab_records (EwsOabDecoder *eod, GCancellable *cancellable, GError **error)
{
@@ -538,8 +748,8 @@ ews_decode_and_store_oab_records (EwsOabDecoder *eod, GCancellable *cancellable,
gboolean ret = TRUE;
guint32 size, i;
- size = g_data_input_stream_read_uint32 (priv->dis, cancellable, error);
- ews_decode_addressbook_record (eod, NULL, priv->hdr_props, cancellable, error);
+ size = ews_oab_read_uint32 (G_INPUT_STREAM (priv->fis), cancellable, error);
+ ews_decode_addressbook_record (eod, NULL, NULL, priv->hdr_props, cancellable, error);
if (*error) {
ret = FALSE;
goto exit;
@@ -547,25 +757,66 @@ ews_decode_and_store_oab_records (EwsOabDecoder *eod, GCancellable *cancellable,
for (i = 0; i < priv->total_records; i++) {
EContact *contact;
+ EwsDeferredSet *dset;
+ gchar *uid = NULL, *bdata = NULL;
+ goffset offset;
contact = e_contact_new ();
- size = g_data_input_stream_read_uint32 (priv->dis, cancellable, error);
- ews_decode_addressbook_record (eod, contact, priv->oab_props, cancellable, error);
- if (*error) {
- g_object_unref (contact);
- ret = FALSE;
- goto exit;
- }
+ dset = g_new0 (EwsDeferredSet, 1);
+ size = ews_oab_read_uint32 (G_INPUT_STREAM (priv->fis), cancellable, error);
+
+ /* fetch the offset */
+ offset = g_seekable_tell ((GSeekable *) priv->fis);
+
+ ews_decode_addressbook_record (eod, contact, dset, priv->oab_props, cancellable, error);
+ if (*error)
+ goto error;
- /* Store the contact summary into db with its offset */
+ if (dset->addr)
+ e_contact_set (contact, E_CONTACT_ADDRESS_WORK, dset->addr);
+
+ /* set the smtp address as contact's uid */
+ uid = (gchar *) e_contact_get (contact, E_CONTACT_EMAIL_1);
+ e_contact_set (contact, E_CONTACT_UID, uid);
+ /* convert the offset to string */
+ bdata = g_strdup_printf ("%"G_GOFFSET_FORMAT, offset);
+
+ d(g_print ("%s \n", e_vcard_to_string ((EVCard *) contact, EVC_FORMAT_VCARD_30));)
+
+ /* Store the contact inside the db with the offset */
+ e_book_backend_sqlitedb_add_contact (priv->ebsdb, priv->folder_id, contact, FALSE, error);
+ if (*error)
+ goto error;
+
+ e_book_backend_sqlitedb_set_contact_bdata (priv->ebsdb, priv->folder_id, uid, bdata, error);
+
+error:
g_object_unref (contact);
+ e_contact_address_free (dset->addr);
+ g_free (dset);
+ g_free (uid);
+ g_free (bdata);
+
+ if (*error) {
+ ret = FALSE;
+ goto exit;
+ }
}
exit:
return ret;
}
+static gboolean
+ews_store_oab_props (EwsOabDecoder *eod, GError **error)
+{
+ gboolean ret = TRUE;
+ /* TODO Implement */
+
+ return ret;
+}
+
/**
* ews_oab_decoder_decode
* @eod:
@@ -600,6 +851,10 @@ ews_oab_decoder_decode (EwsOabDecoder *eod,
goto exit;
ret = ews_decode_and_store_oab_records (eod, cancellable, &err);
+ if (!ret)
+ goto exit;
+
+ ret = ews_store_oab_props (eod, &err);
exit:
if (o_hdr)
@@ -628,20 +883,25 @@ ews_oab_decoder_get_contact_from_offset (EwsOabDecoder *eod,
GError **error)
{
EwsOabDecoderPrivate *priv = GET_PRIVATE (eod);
+ EwsDeferredSet *dset;
EContact *contact = NULL;
- if (!g_seekable_seek ((GSeekable *) priv->dis, offset, G_SEEK_CUR, cancellable, error))
+ if (!g_seekable_seek ((GSeekable *) priv->fis, offset, G_SEEK_CUR, cancellable, error))
return NULL;
/* priv->oab_props = fetch from sqlite db */
contact = e_contact_new ();
- ews_decode_addressbook_record (eod, contact, priv->oab_props, cancellable, error);
+ dset = g_new0 (EwsDeferredSet, 1);
+ ews_decode_addressbook_record (eod, contact, dset, priv->oab_props, cancellable, error);
if (*error) {
g_object_unref (contact);
contact = NULL;
}
+ e_contact_address_free (dset->addr);
+ g_free (dset);
+
if (priv->oab_props) {
g_slist_free (priv->oab_props);
priv->oab_props = NULL;
@@ -649,3 +909,30 @@ ews_oab_decoder_get_contact_from_offset (EwsOabDecoder *eod,
return contact;
}
+
+/*
+gint
+main (gint argc, gchar *argv [])
+{
+ EBookBackendSqliteDB *ebsdb;
+ EwsOabDecoder *eod;
+ GError *err = NULL;
+
+ g_type_init ();
+ g_thread_init (NULL);
+
+ if (argc != 3) {
+ g_print ("Pass the oab filename and cache dir as argument \n");
+ return -1;
+ }
+
+ ebsdb = e_book_backend_sqlitedb_new (argv [2], "dum", "de", "dum", FALSE, NULL);
+ eod = ews_oab_decoder_new (argv [1], argv [2], "de", ebsdb, &err);
+ if (!ews_oab_decoder_decode (eod, NULL, &err)) {
+ g_print ("Unable to decode %s \n", err->message);
+ }
+
+
+ if (err)
+ g_clear_error (&err);
+} */
diff --git a/src/addressbook/ews-oab-decoder.h b/src/addressbook/ews-oab-decoder.h
index 9f0cb55..8e09e86 100644
--- a/src/addressbook/ews-oab-decoder.h
+++ b/src/addressbook/ews-oab-decoder.h
@@ -60,6 +60,7 @@ GType ews_oab_decoder_get_type (void);
EwsOabDecoder* ews_oab_decoder_new (const gchar *oab_filename,
const gchar *cache_dir,
+ const gchar *folder_id,
EBookBackendSqliteDB *ebsdb,
GError **error);
gboolean ews_oab_decoder_decode (EwsOabDecoder *eod,
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]