diff options
Diffstat (limited to 'addressbook/backend/ebook/e-card.c')
-rw-r--r-- | addressbook/backend/ebook/e-card.c | 441 |
1 files changed, 350 insertions, 91 deletions
diff --git a/addressbook/backend/ebook/e-card.c b/addressbook/backend/ebook/e-card.c index 0029694d35..f6218804f1 100644 --- a/addressbook/backend/ebook/e-card.c +++ b/addressbook/backend/ebook/e-card.c @@ -18,13 +18,49 @@ #include <e-card.h> #include <e-card-pairs.h> -#define is_a_prop_of(obj,prop) isAPropertyOf (obj,prop) -#define str_val(obj) the_str = (vObjectValueType (obj))? fakeCString (vObjectUStringZValue (obj)) : calloc (1, 1) -#define has(obj,prop) (vo = isAPropertyOf (obj, prop)) +#define is_a_prop_of(obj,prop) (isAPropertyOf ((obj),(prop))) +#define str_val(obj) (the_str = (vObjectValueType (obj))? fakeCString (vObjectUStringZValue (obj)) : calloc (1, 1)) +#define has(obj,prop) (vo = isAPropertyOf ((obj), (prop))) #if 0 static VObject *card_convert_to_vobject (ECard *crd); #endif +static void parse(ECard *card, VObject *vobj); +static void e_card_init (ECard *card); +static void e_card_class_init (ECardClass *klass); + +static void e_card_destroy (GtkObject *object); + +static void assign_string(VObject *vobj, char **string); + +static void e_card_name_free(ECardName *name); +char *e_v_object_get_child_value(VObject *vobj, char *name); +static ECardDate e_card_date_from_string (char *str); + +static void parse_bday(ECard *card, VObject *object); +static void parse_full_name(ECard *card, VObject *object); +static void parse_name(ECard *card, VObject *object); +static void parse_email(ECard *card, VObject *object); +static void parse_phone(ECard *card, VObject *object); +static void parse_address(ECard *card, VObject *object); + +static ECardPhoneFlags get_phone_flags (VObject *vobj); +static ECardAddressFlags get_address_flags (VObject *vobj); + +typedef void (* ParsePropertyFunc) (ECard *card, VObject *object); + +struct { + char *key; + ParsePropertyFunc function; +} attribute_jump_array[] = +{ + { VCFullNameProp, parse_full_name }, + { VCNameProp, parse_name }, + { VCBirthDateProp, parse_bday }, + { VCEmailAddressProp, parse_email }, + { VCTelephoneProp, parse_phone }, + { VCAdrProp, parse_address } +}; /** * e_card_get_type: @@ -45,12 +81,8 @@ e_card_get_type (void) "ECard", sizeof (ECard), sizeof (ECardClass), - NULL, - NULL, -#if 0 (GtkClassInitFunc) e_card_class_init, (GtkObjectInitFunc) e_card_init, -#endif NULL, /* reserved_1 */ NULL, /* reserved_2 */ (GtkClassInitFunc) NULL @@ -64,7 +96,16 @@ e_card_get_type (void) ECard *e_card_new (char *vcard) { - return E_CARD(gtk_type_new(e_card_get_type())); + ECard *card = E_CARD(gtk_type_new(e_card_get_type())); + VObject *vobj = Parse_MIME(vcard, strlen(vcard)); + while(vobj) { + VObject *next; + parse(card, vobj); + next = nextVObjectInList(vobj); + cleanVObject(vobj); + vobj = next; + } + return card; } char *e_card_get_id (ECard *card) @@ -77,21 +118,183 @@ char *e_card_get_vcard (ECard *card) return NULL; } +static void +parse_name(ECard *card, VObject *vobj) +{ + if ( card->name ) { + e_card_name_free(card->name); + } + card->name = g_new(ECardName, 1); -#if 0 + card->name->family = e_v_object_get_child_value (vobj, VCFamilyNameProp); + card->name->given = e_v_object_get_child_value (vobj, VCGivenNameProp); + card->name->additional = e_v_object_get_child_value (vobj, VCAdditionalNamesProp); + card->name->prefix = e_v_object_get_child_value (vobj, VCNamePrefixesProp); + card->name->suffix = e_v_object_get_child_value (vobj, VCNameSuffixesProp); +} + +static void +parse_full_name(ECard *card, VObject *vobj) +{ + if ( card->fname ) + g_free(card->fname); + assign_string(vobj, &(card->fname)); +} + +static void +parse_email(ECard *card, VObject *vobj) +{ + char *next_email; + assign_string(vobj, &next_email); + card->email = g_list_append(card->email, next_email); +} + +static void +parse_bday(ECard *card, VObject *vobj) +{ + if ( vObjectValueType (vobj) ) { + char *str = fakeCString (vObjectUStringZValue (vobj)); + if ( card->bday ) + g_free(card->bday); + card->bday = g_new(ECardDate, 1); + *(card->bday) = e_card_date_from_string(str); + free(str); + } +} + +static void +parse_phone(ECard *card, VObject *vobj) +{ + ECardPhone *next_phone = g_new(ECardPhone, 1); + assign_string(vobj, &(next_phone->number)); + next_phone->flags = get_phone_flags(vobj); + card->phone = g_list_append(card->phone, next_phone); +} + +static void +parse_address(ECard *card, VObject *vobj) +{ + ECardDeliveryAddress *next_addr = g_new(ECardDeliveryAddress, 1); + + next_addr->flags = get_address_flags (vobj); + next_addr->po = e_v_object_get_child_value (vobj, VCPostalBoxProp); + next_addr->ext = e_v_object_get_child_value (vobj, VCExtAddressProp); + next_addr->street = e_v_object_get_child_value (vobj, VCStreetAddressProp); + next_addr->city = e_v_object_get_child_value (vobj, VCCityProp); + next_addr->region = e_v_object_get_child_value (vobj, VCRegionProp); + next_addr->code = e_v_object_get_child_value (vobj, VCPostalCodeProp); + next_addr->country = e_v_object_get_child_value (vobj, VCCountryNameProp); + next_addr->description = e_v_object_get_child_value (vobj, VCDescriptionProp); + + card->address = g_list_append(card->address, next_addr); +} + +static void +parse_attribute(ECard *card, VObject *vobj) +{ + ParsePropertyFunc function = g_hash_table_lookup(E_CARD_CLASS(GTK_OBJECT(card)->klass)->attribute_jump_table, vObjectName(vobj)); + if ( function ) + function(card, vobj); +} + +static void +parse(ECard *card, VObject *vobj) +{ + VObjectIterator iterator; + initPropIterator(&iterator, vobj); + while(moreIteration (&iterator)) { + parse_attribute(card, nextVObject(&iterator)); + } +} + +static void +e_card_class_init (ECardClass *klass) +{ + int i; + GtkObjectClass *object_class; + + object_class = GTK_OBJECT_CLASS(klass); + + klass->attribute_jump_table = g_hash_table_new(g_str_hash, g_str_equal); + + for ( i = 0; i < sizeof(attribute_jump_array) / sizeof(attribute_jump_array[0]); i++ ) { + g_hash_table_insert(klass->attribute_jump_table, attribute_jump_array[i].key, attribute_jump_array[i].function); + } + + object_class->destroy = e_card_destroy; +} + +static void +e_card_phone_free (ECardPhone *phone) +{ + if ( phone ) { + if ( phone->number ) + g_free(phone->number); + g_free(phone); + } +} + +static void +e_card_delivery_address_free (ECardDeliveryAddress *addr) +{ + if ( addr ) { + if ( addr->po ) + g_free(addr->po); + if ( addr->ext ) + g_free(addr->ext); + if ( addr->street ) + g_free(addr->street); + if ( addr->city ) + g_free(addr->city); + if ( addr->region ) + g_free(addr->region); + if ( addr->code ) + g_free(addr->code); + if ( addr->country ) + g_free(addr->country); + if ( addr->description ) + g_free(addr->description); + g_free(addr); + } +} /* * ECard lifecycle management and vCard loading/saving. */ +static void +e_card_destroy (GtkObject *object) +{ + ECard *card = E_CARD(object); + if ( card->fname ) + g_free(card->fname); + if ( card->name ) + e_card_name_free(card->name); + if ( card->bday ) + g_free(card->bday); + g_list_foreach(card->email, (GFunc)g_free, NULL); + g_list_free(card->email); + g_list_foreach(card->phone, (GFunc)e_card_phone_free, NULL); + g_list_free(card->phone); + g_list_foreach(card->address, (GFunc)e_card_delivery_address_free, NULL); + g_list_free(card->address); +} + /** - * e_card_new: + * e_card_init: */ -ECard * -e_card_new (void) +static void +e_card_init (ECard *card) { - ECard *c; - + + card->fname = NULL; + card->name = NULL; + card->bday = NULL; + card->email = NULL; + card->phone = NULL; + card->address = NULL; +#if 0 + c = g_new0 (ECard, 1); c->fname = @@ -144,9 +347,19 @@ e_card_new (void) c->key.prop.type = PROP_KEY; return c; +#endif } static void +assign_string(VObject *vobj, char **string) +{ + char *str = (vObjectValueType (vobj) ? fakeCString (vObjectUStringZValue (vobj)) : calloc(1, 1)); + *string = g_strdup(str); + free(str); +} + +#if 0 +static void e_card_str_free (CardStrProperty *sp) { g_free (sp->str); @@ -436,20 +649,6 @@ get_addr_type (VObject *o) return ret; } -static int -get_phone_type (VObject *o) -{ - VObject *vo; - int ret = 0; - int i; - - for (i = 0; phone_pairs[i].str; i++) - if (has (o, phone_pairs[i].str)) - ret |= phone_pairs[i].id; - - return ret; -} - static enum EMailType get_email_type (VObject *o) { @@ -609,69 +808,6 @@ e_card_get_name (VObject *o) return name; } -static CardBDay -strtoCardBDay (char *str) -{ - char *s; - int i; - CardBDay bday; - - bday.year = 0; - bday.month = 0; - bday.day = 0; - - if (strchr (str, '-')) { - for (s = strtok (str, "-"), i = 0; s; - s = strtok (NULL, "-"), i++) - switch (i) { - case 0: - bday.year = atoi (s); - break; - case 1: - bday.month = atoi (s); - break; - case 2: - bday.day = atoi (s); - break; - default: - g_warning ("? < Too many values for BDay property."); - } - - if (i < 2) - g_warning ("? < Too few values for BDay property."); - } else { - if (strlen (str) >= 8) { - bday.day = atoi (str + 6); - str[6] = 0; - bday.month = atoi (str + 4); - str[4] = 0; - bday.year = atoi (str); - } else - g_warning ("? < Bad format for BDay property."); - } - - return bday; -} - -static ECardDelAddr * -e_card_get_del_addr (VObject *o) -{ - ECardDelAddr *addr; - - addr = g_new0 (ECardDelAddr, 1); - - addr->type = get_addr_type (o); - addr->po = e_card_prop_get_substr (o, VCPostalBoxProp); - addr->ext = e_card_prop_get_substr (o, VCExtAddressProp); - addr->street = e_card_prop_get_substr (o, VCStreetAddressProp); - addr->city = e_card_prop_get_substr (o, VCCityProp); - addr->region = e_card_prop_get_substr (o, VCRegionProp); - addr->code = e_card_prop_get_substr (o, VCPostalBoxProp); - addr->country = e_card_prop_get_substr (o, VCCountryNameProp); - - return addr; -} - static CardDelLabel * get_CardDelLabel (VObject *o) { @@ -1912,3 +2048,126 @@ card_save (Card *crd, FILE *fp) cleanVObject (object); } #endif + +static ECardDate +e_card_date_from_string (char *str) +{ + ECardDate date; + int length; + + date.year = 0; + date.month = 0; + date.day = 0; + + length = strlen(str); + + if (length == 10 ) { + date.year = str[0] * 1000 + str[1] * 100 + str[2] * 10 + str[3] - '0' * 1111; + date.month = str[5] * 10 + str[6] - '0' * 11; + date.day = str[8] * 10 + str[9] - '0' * 11; + } else if ( length == 8 ) { + date.year = str[0] * 1000 + str[1] * 100 + str[2] * 10 + str[3] - '0' * 1111; + date.month = str[4] * 10 + str[5] - '0' * 11; + date.day = str[6] * 10 + str[7] - '0' * 11; + } + + return date; +} + +static void +e_card_name_free(ECardName *name) +{ + if ( name ) { + if ( name->prefix ) + g_free(name->prefix); + if ( name->given ) + g_free(name->given); + if ( name->additional ) + g_free(name->additional); + if ( name->family ) + g_free(name->family); + if ( name->suffix ) + g_free(name->suffix); + g_free ( name ); + } +} + +char * +e_v_object_get_child_value(VObject *vobj, char *name) +{ + char *ret_val; + VObjectIterator iterator; + initPropIterator(&iterator, vobj); + while(moreIteration (&iterator)) { + VObject *attribute = nextVObject(&iterator); + const char *id = vObjectName(attribute); + if ( ! strcmp(id, name) ) { + assign_string(attribute, &ret_val); + return ret_val; + } + } + ret_val = g_new(char, 1); + *ret_val = 0; + return ret_val; +} + +static ECardPhoneFlags +get_phone_flags (VObject *vobj) +{ + ECardPhoneFlags ret = 0; + int i; + + struct { + char *id; + ECardPhoneFlags flag; + } phone_pairs[] = { + { VCPreferredProp, E_CARD_PHONE_PREF }, + { VCWorkProp, E_CARD_PHONE_WORK }, + { VCHomeProp, E_CARD_PHONE_HOME }, + { VCVoiceProp, E_CARD_PHONE_VOICE }, + { VCFaxProp, E_CARD_PHONE_FAX }, + { VCMessageProp, E_CARD_PHONE_MSG }, + { VCCellularProp, E_CARD_PHONE_CELL }, + { VCPagerProp, E_CARD_PHONE_PAGER }, + { VCBBSProp, E_CARD_PHONE_BBS }, + { VCModemProp, E_CARD_PHONE_MODEM }, + { VCCarProp, E_CARD_PHONE_CAR }, + { VCISDNProp, E_CARD_PHONE_ISDN }, + { VCVideoProp, E_CARD_PHONE_VIDEO }, + }; + + for (i = 0; i < sizeof(phone_pairs) / sizeof(phone_pairs[0]); i++) { + if (isAPropertyOf (vobj, phone_pairs[i].id)) { + ret |= phone_pairs[i].flag; + } + } + + return ret; +} + +static ECardAddressFlags +get_address_flags (VObject *vobj) +{ + ECardAddressFlags ret = 0; + int i; + + struct { + char *id; + ECardAddressFlags flag; + } addr_pairs[] = { + { VCDomesticProp, ADDR_DOM }, + { VCInternationalProp, ADDR_INTL }, + { VCPostalProp, ADDR_POSTAL }, + { VCParcelProp, ADDR_PARCEL }, + { VCHomeProp, ADDR_HOME }, + { VCWorkProp, ADDR_WORK }, + }; + + for (i = 0; i < sizeof(addr_pairs) / sizeof(addr_pairs[0]); i++) { + if (isAPropertyOf (vobj, addr_pairs[i].id)) { + ret |= addr_pairs[i].flag; + } + } + + return ret; +} |