2 Copyright (c) 2008 Instituto Nokia de Tecnologia
5 Redistribution and use in source and binary forms, with or without modification,
6 are permitted provided that the following conditions are met:
8 * Redistributions of source code must retain the above copyright notice,
9 this list of conditions and the following disclaimer.
10 * Redistributions in binary form must reproduce the above copyright notice,
11 this list of conditions and the following disclaimer in the documentation
12 and/or other materials provided with the distribution.
13 * Neither the name of the INdT nor the names of its contributors
14 may be used to endorse or promote products derived from this software
15 without specific prior written permission.
17 THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
18 AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
19 IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
20 ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
21 LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
22 CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
23 SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
24 INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
25 CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
26 ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
27 POSSIBILITY OF SUCH DAMAGE.
31 * @author Adenilson Cavalcanti da Silva <adenilson.silva@indt.org.br>
32 * @date Thu Jun 26 07:37:03 2008
34 * @brief libgcal google contacts user public API.
36 * Use this functions to handle common tasks when dealing with google contacts.
48 #include "gcal_parser.h"
49 #include "internal_gcal.h"
52 /** Strings associated with phone number types */
53 const char* gcal_phone_type_str
[] = {
54 "assistant", // P_ASSISTANT
55 "callback", // P_CALLBACK
57 "company_main", // P_COMPANY_MAIN
60 "home_fax", // P_HOME_FAX
65 "other_fax", // P_OTHER_FAX
69 "tty_tdd", // P_TTY_TDD
71 "work_fax", // P_WORK_FAX
72 "work_mobile", // P_WORK_MOBILE
73 "work_pager" // P_WORK_PAGER
76 /** Strings associated with email types */
77 const char* gcal_email_type_str
[] = {
83 gcal_contact_t
gcal_contact_new(char *raw_xml
)
85 gcal_contact_t contact
= NULL
;
89 contact
= (gcal_contact_t
) malloc(sizeof(struct gcal_contact
));
93 gcal_init_contact(contact
);
97 /* Builds a doc, parse and init object */
98 doc
= build_dom_document(raw_xml
);
102 result
= extract_all_contacts(doc
, contact
, 1);
103 clean_dom_document(doc
);
114 void gcal_contact_delete(gcal_contact_t contact
)
119 gcal_destroy_contact(contact
);
124 int gcal_get_contacts(gcal_t gcalobj
, struct gcal_contact_array
*contact_array
)
128 contact_array
->length
= 0;
130 if ((!gcalobj
) || (!contact_array
))
133 result
= gcal_dump(gcalobj
, "GData-Version: 3.0");
135 contact_array
->entries
= NULL
;
136 contact_array
->length
= 0;
140 contact_array
->entries
= gcal_get_all_contacts(gcalobj
,
141 &contact_array
->length
);
142 if (!contact_array
->entries
)
151 void gcal_cleanup_contacts(struct gcal_contact_array
*contacts
)
156 gcal_destroy_contacts(contacts
->entries
, contacts
->length
);
157 contacts
->length
= 0;
158 contacts
->entries
= NULL
;
163 int gcal_add_contact(gcal_t gcalobj
, gcal_contact_t contact
)
166 struct gcal_contact updated
;
167 gcal_init_contact(&updated
);
169 if ((!gcalobj
) || (!contact
))
173 result
= gcal_create_contact(gcalobj
, contact
, &updated
);
177 /* Swap updated fields: id, updated, edit_uri, etag, photo url */
178 if (contact
->common
.id
)
179 free(contact
->common
.id
);
180 contact
->common
.id
= updated
.common
.id
;
181 updated
.common
.id
= NULL
;
183 if (contact
->common
.updated
)
184 free(contact
->common
.updated
);
185 contact
->common
.updated
= updated
.common
.updated
;
186 updated
.common
.updated
= NULL
;
188 if (contact
->common
.edit_uri
)
189 free(contact
->common
.edit_uri
);
190 contact
->common
.edit_uri
= updated
.common
.edit_uri
;
191 updated
.common
.edit_uri
= NULL
;
193 if (contact
->common
.etag
)
194 free(contact
->common
.etag
);
195 contact
->common
.etag
= updated
.common
.etag
;
196 updated
.common
.etag
= NULL
;
199 free(contact
->photo
);
200 contact
->photo
= updated
.photo
;
201 updated
.photo
= NULL
;
203 /* Cleanup updated contact */
204 gcal_destroy_contact(&updated
);
210 int gcal_update_contact(gcal_t gcalobj
, gcal_contact_t contact
)
213 struct gcal_contact updated
;
214 gcal_init_contact(&updated
);
216 if ((!gcalobj
) || (!contact
))
220 result
= gcal_edit_contact(gcalobj
, contact
, &updated
);
224 /* Swap updated fields: updated, edit_uri, etag */
225 if (contact
->common
.updated
)
226 free(contact
->common
.updated
);
227 contact
->common
.updated
= updated
.common
.updated
;
228 updated
.common
.updated
= NULL
;
230 if (contact
->common
.edit_uri
)
231 free(contact
->common
.edit_uri
);
232 contact
->common
.edit_uri
= updated
.common
.edit_uri
;
233 updated
.common
.edit_uri
= NULL
;
235 if (contact
->common
.etag
)
236 free(contact
->common
.etag
);
237 contact
->common
.etag
= updated
.common
.etag
;
238 updated
.common
.etag
= NULL
;
241 free(contact
->photo
);
242 contact
->photo
= updated
.photo
;
243 updated
.photo
= NULL
;
245 /* Cleanup updated contact */
246 gcal_destroy_contact(&updated
);
252 int gcal_erase_contact(gcal_t gcalobj
, gcal_contact_t contact
)
255 if ((!gcalobj
) || (!contact
))
258 result
= gcal_delete_contact(gcalobj
, contact
);
263 int gcal_get_updated_contacts(gcal_t gcal_obj
,
264 struct gcal_contact_array
*contacts
,
269 contacts
->length
= 0;
271 if ((!gcal_obj
) || (!contacts
))
274 result
= gcal_query_updated(gcal_obj
, timestamp
, "GData-Version: 3.0");
276 contacts
->entries
= NULL
;
277 contacts
->length
= 0;
281 contacts
->entries
= gcal_get_all_contacts(gcal_obj
, &contacts
->length
);
282 if (contacts
->entries
)
288 gcal_contact_t
gcal_contact_element(struct gcal_contact_array
*contacts
,
292 struct gcal_contact
*contact
= NULL
;
293 if ((!contacts
) || (_index
> (contacts
->length
- 1)) ||
294 (contacts
->length
== 0))
297 contact
= &contacts
->entries
[_index
];
301 char *gcal_contact_get_xml(gcal_contact_t contact
)
305 return gcal_get_xml(&(contact
->common
));
308 char *gcal_contact_get_id(gcal_contact_t contact
)
312 return gcal_get_id(&(contact
->common
));
315 char *gcal_contact_get_updated(gcal_contact_t contact
)
319 return gcal_get_updated(&(contact
->common
));
322 char *gcal_contact_get_title(gcal_contact_t contact
)
326 return gcal_get_title(&(contact
->common
));
329 char *gcal_contact_get_url(gcal_contact_t contact
)
333 return gcal_get_url(&(contact
->common
));
336 char *gcal_contact_get_etag(gcal_contact_t contact
)
340 return gcal_get_etag(&(contact
->common
));
343 char gcal_contact_is_deleted(gcal_contact_t contact
)
347 return gcal_get_deleted(&(contact
->common
));
351 /* This are the fields unique to calendar contacts */
352 int gcal_contact_get_emails_count(gcal_contact_t contact
)
356 return contact
->emails_nr
;
359 int gcal_contact_get_pref_email(gcal_contact_t contact
)
363 return contact
->pref_email
;
366 char *gcal_contact_get_email_address(gcal_contact_t contact
, int i
)
370 if (!(contact
->emails_field
) || (i
>= contact
->emails_nr
))
372 return contact
->emails_field
[i
];
375 gcal_email_type
gcal_contact_get_email_address_type(gcal_contact_t contact
, int i
)
377 gcal_email_type result
= E_INVALID
;
382 if (!(contact
->emails_type
) || (i
>= contact
->emails_nr
))
384 for (j
= 0; j
< E_ITEMS_COUNT
; j
++)
385 if (!strcmp(contact
->emails_type
[i
], gcal_email_type_str
[j
]))
390 char *gcal_contact_get_content(gcal_contact_t contact
)
394 return contact
->content
;
397 char *gcal_contact_get_organization(gcal_contact_t contact
)
401 return contact
->org_name
;
404 char *gcal_contact_get_profission(gcal_contact_t contact
)
408 return contact
->org_title
;
411 char *gcal_contact_get_im(gcal_contact_t contact
)
418 char *gcal_contact_get_homepage(gcal_contact_t contact
)
422 return contact
->homepage
;
425 char *gcal_contact_get_blog(gcal_contact_t contact
)
429 return contact
->blog
;
432 int gcal_contact_get_phone_numbers_count(gcal_contact_t contact
)
436 return contact
->phone_numbers_nr
;
439 char *gcal_contact_get_phone_number(gcal_contact_t contact
, int i
)
443 if (!(contact
->phone_numbers_field
) || (i
>= contact
->phone_numbers_nr
))
445 return contact
->phone_numbers_field
[i
];
448 gcal_phone_type
gcal_contact_get_phone_number_type(gcal_contact_t contact
, int i
)
450 gcal_phone_type result
= P_INVALID
;
455 if (!(contact
->phone_numbers_type
) || (i
>= contact
->phone_numbers_nr
))
457 for (j
= 0; j
< P_ITEMS_COUNT
; j
++)
458 if (!strcmp(contact
->phone_numbers_type
[i
], gcal_phone_type_str
[j
]))
463 char *gcal_contact_get_address(gcal_contact_t contact
)
467 return contact
->post_address
;
470 char *gcal_contact_get_structured_address(gcal_contact_t contact
, const char *address_field_key
)
472 struct gcal_structured_postal_address
*temp_structured_address
;
477 for(temp_structured_address
= contact
->structured_address
; temp_structured_address
!= NULL
; temp_structured_address
= temp_structured_address
->next_address_field
)
479 if(!strcmp(address_field_key
,temp_structured_address
->address_field_key
))
480 return temp_structured_address
->address_field_value
;
485 int gcal_contact_get_groupMembership_count(gcal_contact_t contact
)
489 return contact
->groupMembership_nr
;
492 char *gcal_contact_get_groupMembership(gcal_contact_t contact
, int i
)
496 if (!(contact
->groupMembership
) || (i
>= contact
->groupMembership_nr
))
498 return contact
->groupMembership
[i
];
501 char *gcal_contact_get_photo(gcal_contact_t contact
)
506 return contact
->photo_data
;
509 unsigned int gcal_contact_get_photolength(gcal_contact_t contact
)
514 return contact
->photo_length
;
517 char *gcal_contact_get_birthday(gcal_contact_t contact
)
521 return contact
->birthday
;
524 /* Here starts the gcal_contact setters */
525 int gcal_contact_set_title(gcal_contact_t contact
, const char *field
)
529 if ((!contact
) || (!field
))
532 if (contact
->common
.title
)
533 free(contact
->common
.title
);
535 contact
->common
.title
= strdup(field
);
536 if (contact
->common
.title
)
542 int gcal_contact_delete_email_addresses(gcal_contact_t contact
)
550 if (contact
->emails_nr
> 0) {
551 for (temp
= 0; temp
< contact
->emails_nr
; temp
++) {
552 if (contact
->emails_field
[temp
])
553 free(contact
->emails_field
[temp
]);
554 if (contact
->emails_type
[temp
])
555 free(contact
->emails_type
[temp
]);
557 free(contact
->emails_field
);
558 free(contact
->emails_type
);
561 contact
->emails_nr
= contact
->pref_email
= 0;
562 contact
->emails_field
= contact
->emails_type
= 0;
569 int gcal_contact_add_email_address(gcal_contact_t contact
, const char *field
, gcal_email_type type
, int pref
)
573 if ((!contact
) || (!field
) || (type
<0) || (type
>=E_ITEMS_COUNT
))
576 contact
->emails_field
= (char**) realloc(contact
->emails_field
, (contact
->emails_nr
+1) * sizeof(char*));
577 contact
->emails_field
[contact
->emails_nr
] = strdup(field
);
579 contact
->emails_type
= (char**) realloc(contact
->emails_type
, (contact
->emails_nr
+1) * sizeof(char*));
580 contact
->emails_type
[contact
->emails_nr
] = strdup(gcal_email_type_str
[type
]);
583 contact
->pref_email
= contact
->emails_nr
;
585 contact
->emails_nr
++;
592 int gcal_contact_set_url(gcal_contact_t contact
, const char *field
)
596 if ((!contact
) || (!field
))
599 if (contact
->common
.edit_uri
)
600 free(contact
->common
.edit_uri
);
602 contact
->common
.edit_uri
= strdup(field
);
603 if (contact
->common
.edit_uri
)
610 int gcal_contact_set_id(gcal_contact_t contact
, const char *field
)
614 if ((!contact
) || (!field
))
617 if (contact
->common
.id
)
618 free(contact
->common
.id
);
620 contact
->common
.id
= strdup(field
);
621 if (contact
->common
.id
)
628 int gcal_contact_set_etag(gcal_contact_t contact
, const char *field
)
632 if ((!contact
) || (!field
))
635 if (contact
->common
.etag
)
636 free(contact
->common
.etag
);
638 contact
->common
.etag
= strdup(field
);
639 if (contact
->common
.etag
)
645 int gcal_contact_delete_phone_numbers(gcal_contact_t contact
)
653 if (contact
->phone_numbers_nr
> 0) {
654 for (temp
= 0; temp
< contact
->phone_numbers_nr
; temp
++) {
655 if (contact
->phone_numbers_field
[temp
])
656 free(contact
->phone_numbers_field
[temp
]);
657 if (contact
->phone_numbers_type
[temp
])
658 free(contact
->phone_numbers_type
[temp
]);
660 free(contact
->phone_numbers_field
);
661 free(contact
->phone_numbers_type
);
664 contact
->phone_numbers_nr
= 0;
671 int gcal_contact_add_phone_number(gcal_contact_t contact
, const char *field
, gcal_phone_type type
)
675 if ((!contact
) || (!field
) || (type
<0) || (type
>=P_ITEMS_COUNT
))
678 contact
->phone_numbers_field
= (char**) realloc(contact
->phone_numbers_field
, (contact
->phone_numbers_nr
+1) * sizeof(char*));
679 contact
->phone_numbers_field
[contact
->phone_numbers_nr
] = strdup(field
);
681 contact
->phone_numbers_type
= (char**) realloc(contact
->phone_numbers_type
, (contact
->phone_numbers_nr
+1) * sizeof(char*));
682 contact
->phone_numbers_type
[contact
->phone_numbers_nr
] = strdup(gcal_phone_type_str
[type
]);
684 contact
->phone_numbers_nr
++;
691 int gcal_contact_set_address(gcal_contact_t contact
, const char *field
)
695 if ((!contact
) || (!field
))
698 if (contact
->post_address
)
699 free(contact
->post_address
);
701 contact
->post_address
= strdup(field
);
702 if (contact
->post_address
)
708 int gcal_contact_set_structured_address(gcal_contact_t contact
, const char *address_field_key
, const char *address_field_value
)
710 struct gcal_structured_postal_address
*temp_structured_address
;
715 if(address_field_value
== NULL
)
716 address_field_value
= "";
718 if(contact
->structured_address
->address_field_key
== NULL
) {
719 contact
->structured_address
->address_field_key
= (char *)malloc(strlen(address_field_key
)+1);
720 strcpy(contact
->structured_address
->address_field_key
,address_field_key
);
722 contact
->structured_address
->address_field_value
= (char *)malloc(strlen(address_field_value
)+1);
723 strcpy(contact
->structured_address
->address_field_value
,address_field_value
);
725 contact
->structured_address
->next_address_field
= NULL
;
728 for(temp_structured_address
= contact
->structured_address
; ; temp_structured_address
= temp_structured_address
->next_address_field
) {
729 if(!strcmp(address_field_key
,temp_structured_address
->address_field_key
)) {
730 if(temp_structured_address
->address_field_value
!= NULL
) {
731 free(temp_structured_address
->address_field_value
);
732 temp_structured_address
->address_field_value
= (char *)malloc(strlen(address_field_value
)+1);
733 strcpy(temp_structured_address
->address_field_value
,address_field_value
);
737 if(temp_structured_address
->next_address_field
== NULL
) {
738 temp_structured_address
->next_address_field
= (struct gcal_structured_postal_address
*)malloc(sizeof(struct gcal_structured_postal_address
));
739 temp_structured_address
= temp_structured_address
->next_address_field
;
741 temp_structured_address
->address_field_key
= (char *)malloc(strlen(address_field_key
)+1);
742 strcpy(temp_structured_address
->address_field_key
,address_field_key
);
744 temp_structured_address
->address_field_value
= (char *)malloc(strlen(address_field_value
)+1);
745 strcpy(temp_structured_address
->address_field_value
,address_field_value
);
747 temp_structured_address
->next_address_field
= NULL
;
755 int gcal_contact_delete_groupMembership(gcal_contact_t contact
)
763 if (contact
->groupMembership_nr
> 0) {
764 for (temp
= 0; temp
< contact
->groupMembership_nr
; temp
++) {
765 if (contact
->groupMembership
[temp
])
766 free(contact
->groupMembership
[temp
]);
768 free(contact
->groupMembership
);
771 contact
->groupMembership_nr
= 0;
778 int gcal_contact_add_groupMembership(gcal_contact_t contact
, char *field
)
782 if ((!contact
) || (!field
))
785 contact
->groupMembership
= (char**) realloc(contact
->groupMembership
, (contact
->groupMembership_nr
+1) * sizeof(char*));
786 contact
->groupMembership
[contact
->groupMembership_nr
] = strdup(field
);
788 contact
->groupMembership_nr
++;
795 int gcal_contact_set_profission(gcal_contact_t contact
, const char *field
)
799 if ((!contact
) || (!field
))
802 if (contact
->org_title
)
803 free(contact
->org_title
);
805 contact
->org_title
= strdup(field
);
806 if (contact
->org_title
)
813 int gcal_contact_set_organization(gcal_contact_t contact
, const char *field
)
817 if ((!contact
) || (!field
))
820 if (contact
->org_name
)
821 free(contact
->org_name
);
823 contact
->org_name
= strdup(field
);
824 if (contact
->org_name
)
830 int gcal_contact_set_content(gcal_contact_t contact
, const char *field
)
834 if ((!contact
) || (!field
))
837 if (contact
->content
)
838 free(contact
->content
);
840 contact
->content
= strdup(field
);
841 if (contact
->content
)
848 int gcal_contact_set_photo(gcal_contact_t contact
, const char *field
,
853 if ((!contact
) || (!field
))
856 if (contact
->photo_data
)
857 if (contact
->photo_length
> 1)
858 free(contact
->photo_data
);
860 if (!(contact
->photo_data
= malloc(length
* sizeof(unsigned char))))
863 memcpy(contact
->photo_data
, field
, length
);
864 contact
->photo_length
= length
;
870 int gcal_contact_set_birthday(gcal_contact_t contact
, const char *field
)
874 if ((!contact
) || (!field
))
877 if (contact
->birthday
)
878 free(contact
->birthday
);
880 contact
->birthday
= strdup(field
);
881 if (contact
->birthday
)
887 int gcal_contact_set_homepage(gcal_contact_t contact
, const char *field
)
891 if ((!contact
) || (!field
))
894 if (contact
->homepage
)
895 free(contact
->homepage
);
897 contact
->homepage
= strdup(field
);
898 if (contact
->homepage
)
904 int gcal_contact_set_blog(gcal_contact_t contact
, const char *field
)
908 if ((!contact
) || (!field
))
914 contact
->blog
= strdup(field
);