Ejemplo n.º 1
0
/**
 * gdata_entry_new_from_xml:
 * @entry_xml: the xml tree
 * Returns a GDataEntry object:
 **/
GDataEntry *
gdata_entry_new_from_xml (const gchar *entry_xml)
{
	GDataEntry *entry = NULL;
	xmlDocPtr doc;
	xmlNodePtr cur;

	g_return_val_if_fail (entry_xml != NULL && *entry_xml != '\0', NULL);
	doc = xmlReadMemory (entry_xml, strlen(entry_xml), "feed.xml", NULL, 0);

	if (doc == NULL)
		return NULL;

	cur = xmlDocGetRootElement (doc);
	if (cur == NULL)
		xmlFree (doc);

	while (cur != NULL) {
		if (!xmlStrcmp (cur->name,(xmlChar *)"entry"))
			entry = gdata_entry_new_from_xmlptr (doc, cur);
		cur = cur->next;
	}
	/*Free them */
	xmlFreeDoc (doc);
	xmlFreeNode (cur);

	if (!GDATA_IS_ENTRY(entry))
		return NULL;

	return entry;
}
Ejemplo n.º 2
0
/**
 * gdata_access_handler_update_rule:
 * @self: a #GDataAccessHandler
 * @service: a #GDataService
 * @rule: the #GDataAccessRule to update
 * @cancellable: optional #GCancellable object, or %NULL
 * @error: a #GError, or %NULL
 *
 * Updates @rule in the access control list of the #GDataAccessHandler.
 *
 * The service will return an updated version of the rule, which is the return value of this function on success.
 *
 * If @cancellable is not %NULL, then the operation can be cancelled by triggering the @cancellable object from another thread.
 * If the operation was cancelled, the error %G_IO_ERROR_CANCELLED will be returned.
 *
 * If there is an error updating the rule, a %GDATA_SERVICE_ERROR_WITH_UPDATE error will be returned.
 *
 * Return value: an updated #GDataAccessRule, or %NULL
 *
 * Since: 0.3.0
 **/
GDataAccessRule *
gdata_access_handler_update_rule (GDataAccessHandler *self, GDataService *service, GDataAccessRule *rule, GCancellable *cancellable, GError **error)
{
	GDataServiceClass *klass;
	GDataAccessRule *updated_rule;
	SoupMessage *message;
	gchar *upload_data;
	guint status;

	g_return_val_if_fail (GDATA_IS_ENTRY (self), NULL);
	g_return_val_if_fail (GDATA_IS_SERVICE (service), NULL);
	g_return_val_if_fail (GDATA_IS_ACCESS_RULE (rule), NULL);

	message = get_soup_message (self, rule, SOUP_METHOD_PUT);

	/* Make sure subclasses set their headers */
	klass = GDATA_SERVICE_GET_CLASS (service);
	if (klass->append_query_headers != NULL)
		klass->append_query_headers (service, message);

	/* Looks like ACLs don't support ETags */

	/* Append the data */
	upload_data = gdata_entry_get_xml (GDATA_ENTRY (rule));
	soup_message_set_request (message, "application/atom+xml", SOUP_MEMORY_TAKE, upload_data, strlen (upload_data));

	/* Send the message */
	status = _gdata_service_send_message (service, message, error);
	if (status == SOUP_STATUS_NONE) {
		g_object_unref (message);
		return NULL;
	}

	/* Check for cancellation */
	if (g_cancellable_set_error_if_cancelled (cancellable, error) == TRUE) {
		g_object_unref (message);
		return NULL;
	}

	if (status != 200) {
		/* Error */
		g_assert (klass->parse_error_response != NULL);
		klass->parse_error_response (service, GDATA_SERVICE_ERROR_WITH_UPDATE, status, message->reason_phrase, message->response_body->data,
					     message->response_body->length, error);
		g_object_unref (message);
		return NULL;
	}

	/* Build the updated entry */
	g_assert (message->response_body->data != NULL);

	/* Parse the XML; create and return a new GDataEntry of the same type as @entry */
	updated_rule = GDATA_ACCESS_RULE (_gdata_entry_new_from_xml (G_OBJECT_TYPE (rule), message->response_body->data,
								     message->response_body->length, error));
	g_object_unref (message);

	return updated_rule;
}
Ejemplo n.º 3
0
/**
 * gdata_access_handler_delete_rule:
 * @self: a #GDataAccessHandler
 * @service: a #GDataService
 * @rule: the #GDataAccessRule to delete
 * @cancellable: optional #GCancellable object, or %NULL
 * @error: a #GError, or %NULL
 *
 * Deletes @rule from the access control list of the #GDataAccessHandler.
 *
 * If @cancellable is not %NULL, then the operation can be cancelled by triggering the @cancellable object from another thread.
 * If the operation was cancelled, the error %G_IO_ERROR_CANCELLED will be returned.
 *
 * If there is an error deleting the rule, a %GDATA_SERVICE_ERROR_WITH_DELETION error will be returned, unless the @rule was the owner's
 * rule; in which case, %GDATA_SERVICE_ERROR_FORBIDDEN will be returned without any network activity.
 *
 * Return value: %TRUE on success, %FALSE otherwise
 *
 * Since: 0.3.0
 **/
gboolean
gdata_access_handler_delete_rule (GDataAccessHandler *self, GDataService *service, GDataAccessRule *rule, GCancellable *cancellable, GError **error)
{
	GDataServiceClass *klass;
	GDataAccessHandlerIface *iface;
	SoupMessage *message;
	guint status;

	g_return_val_if_fail (GDATA_IS_ENTRY (self), FALSE);
	g_return_val_if_fail (GDATA_IS_SERVICE (service), FALSE);
	g_return_val_if_fail (GDATA_IS_ACCESS_RULE (rule), FALSE);

	/* The owner of the access handler can't be deleted */
	iface = GDATA_ACCESS_HANDLER_GET_IFACE (self);
	g_assert (iface->is_owner_rule != NULL);
	if (iface->is_owner_rule (rule) == TRUE) {
		g_set_error_literal (error, GDATA_SERVICE_ERROR, GDATA_SERVICE_ERROR_FORBIDDEN,
				     _("The owner's rule may not be deleted."));
		return FALSE;
	}

	message = get_soup_message (self, rule, SOUP_METHOD_DELETE);

	/* Make sure subclasses set their headers */
	klass = GDATA_SERVICE_GET_CLASS (service);
	if (klass->append_query_headers != NULL)
		klass->append_query_headers (service, message);

	/* Looks like ACLs don't support ETags */

	/* Send the message */
	status = _gdata_service_send_message (service, message, error);
	if (status == SOUP_STATUS_NONE) {
		g_object_unref (message);
		return FALSE;
	}

	/* Check for cancellation */
	if (g_cancellable_set_error_if_cancelled (cancellable, error) == TRUE) {
		g_object_unref (message);
		return FALSE;
	}

	if (status != 200) {
		/* Error */
		g_assert (klass->parse_error_response != NULL);
		klass->parse_error_response (service, GDATA_SERVICE_ERROR_WITH_DELETION, status, message->reason_phrase, message->response_body->data,
					     message->response_body->length, error);
		g_object_unref (message);
		return FALSE;
	}

	g_object_unref (message);

	return TRUE;
}
Ejemplo n.º 4
0
/**
 * gdata_entry_get_organizations:
 * @entry: A #GDataEntry object.
 * Returns the list of organizations of entry.
 **/
GSList *
gdata_entry_get_organizations (GDataEntry *entry)
{
	GDataEntryPrivate *priv;

	g_return_val_if_fail (entry != NULL, NULL);
	g_return_val_if_fail (GDATA_IS_ENTRY (entry), NULL);

	priv = GDATA_ENTRY_GET_PRIVATE (entry);
	return priv->organizations;
}
Ejemplo n.º 5
0
/**
 * gdata_entry_get_status:
 * @entry: A #GDataEntry object.
 * Returns the status of the Event.
 **/
gchar *
gdata_entry_get_status (GDataEntry *entry)
{
	GDataEntryPrivate *priv;

	g_return_val_if_fail(entry !=NULL, NULL);
	g_return_val_if_fail(GDATA_IS_ENTRY (entry), NULL);

	priv = GDATA_ENTRY_GET_PRIVATE(entry);
	return priv->status;
}
Ejemplo n.º 6
0
/**
 * gdata_entry_get_title:
 * @entry: A #GDataEntry object.
 * Returns the title of the Entry.
 **/
gchar *
gdata_entry_get_title (GDataEntry *entry)
{
	GDataEntryPrivate *priv;

	g_return_val_if_fail (entry !=NULL, NULL);
	g_return_val_if_fail (GDATA_IS_ENTRY (entry), NULL);

	priv = GDATA_ENTRY_GET_PRIVATE (entry);
	return g_hash_table_lookup (priv->field_table, "title");
}
Ejemplo n.º 7
0
/**
 * gdata_entry_get_postal_addresses:
 * @entry: A #GDataEntry object.
 * Returns the list of postal addresses of entry.
 **/
GSList *
gdata_entry_get_postal_addresses (GDataEntry *entry)
{
	GDataEntryPrivate *priv;

	g_return_val_if_fail (entry != NULL, NULL);
	g_return_val_if_fail (GDATA_IS_ENTRY (entry), NULL);

	priv = GDATA_ENTRY_GET_PRIVATE (entry);
	return priv->postal_addresses;
}
Ejemplo n.º 8
0
/**
 * gdata_access_handler_get_rules:
 * @self: a #GDataAccessHandler
 * @service: a #GDataService
 * @cancellable: optional #GCancellable object, or %NULL
 * @progress_callback: a #GDataQueryProgressCallback to call when a rule is loaded, or %NULL
 * @progress_user_data: data to pass to the @progress_callback function
 * @error: a #GError, or %NULL
 *
 * Retrieves a #GDataFeed containing all the access rules which apply to the given #GDataAccessHandler. Only the owner of a #GDataAccessHandler may
 * view its rule feed.
 *
 * If @cancellable is not %NULL, then the operation can be cancelled by triggering the @cancellable object from another thread.
 * If the operation was cancelled, the error %G_IO_ERROR_CANCELLED will be returned.
 *
 * A %GDATA_SERVICE_ERROR_WITH_QUERY will be returned if the server indicates there is a problem with the query.
 *
 * For each rule in the response feed, @progress_callback will be called in the main thread. If there was an error parsing the XML response,
 * a #GDataParserError will be returned.
 *
 * Return value: a #GDataFeed of access control rules, or %NULL; unref with g_object_unref()
 *
 * Since: 0.3.0
 **/
GDataFeed *
gdata_access_handler_get_rules (GDataAccessHandler *self, GDataService *service, GCancellable *cancellable, GDataQueryProgressCallback progress_callback,
				gpointer progress_user_data, GError **error)
{
	GDataServiceClass *klass;
	GDataFeed *feed;
	GDataLink *link;
	SoupMessage *message;
	guint status;

	/* TODO: async version */
	g_return_val_if_fail (GDATA_IS_ENTRY (self), NULL);
	g_return_val_if_fail (GDATA_IS_SERVICE (service), NULL);

	/* Get the ACL URI */
	link = gdata_entry_look_up_link (GDATA_ENTRY (self), "http://schemas.google.com/acl/2007#accessControlList");
	g_assert (link != NULL);
	message = soup_message_new (SOUP_METHOD_GET, link->href);

	/* Make sure subclasses set their headers */
	klass = GDATA_SERVICE_GET_CLASS (service);
	if (klass->append_query_headers != NULL)
		klass->append_query_headers (service, message);

	/* Send the message */
	status = _gdata_service_send_message (service, message, error);
	if (status == SOUP_STATUS_NONE) {
		g_object_unref (message);
		return NULL;
	}

	/* Check for cancellation */
	if (g_cancellable_set_error_if_cancelled (cancellable, error) == TRUE) {
		g_object_unref (message);
		return NULL;
	}

	if (status != 200) {
		/* Error */
		g_assert (klass->parse_error_response != NULL);
		klass->parse_error_response (service, GDATA_SERVICE_ERROR_WITH_QUERY, status, message->reason_phrase, message->response_body->data,
					     message->response_body->length, error);
		g_object_unref (message);
		return NULL;
	}

	g_assert (message->response_body->data != NULL);

	feed = _gdata_feed_new_from_xml (GDATA_TYPE_FEED, message->response_body->data, message->response_body->length, GDATA_TYPE_ACCESS_RULE,
					 progress_callback, progress_user_data, error);
	g_object_unref (message);

	return feed;
}
Ejemplo n.º 9
0
gboolean
gdata_entry_is_recurrent (GDataEntry *entry)
{
	GDataEntryPrivate *priv;

	g_return_val_if_fail (entry != NULL, 0);
	g_return_val_if_fail (GDATA_IS_ENTRY (entry), 0);

	priv = GDATA_ENTRY_GET_PRIVATE (entry);
	return priv->is_recurrent;
}
Ejemplo n.º 10
0
GSList *
gdata_entry_get_attendee_list (GDataEntry *entry)
{
	GDataEntryPrivate *priv;

	g_return_val_if_fail (entry != NULL, NULL);
	g_return_val_if_fail (GDATA_IS_ENTRY(entry), NULL);

	priv = GDATA_ENTRY_GET_PRIVATE(entry);
	return priv->attendees;
}
Ejemplo n.º 11
0
/**
 * gdata_entry_is_deleted:
 * @entry: A #GDataEntry object.
 * Returns whether this entry is marked (remotely) as deleted.
 **/
gboolean
gdata_entry_is_deleted (GDataEntry *entry)
{
	GDataEntryPrivate *priv;

	g_return_val_if_fail(entry !=NULL, TRUE);
	g_return_val_if_fail(GDATA_IS_ENTRY (entry), TRUE);

	priv = GDATA_ENTRY_GET_PRIVATE(entry);
	return priv->is_deleted;
}
Ejemplo n.º 12
0
/* Returns the description of the entry */
gchar *
gdata_entry_get_description (GDataEntry *entry)
{
	GDataEntryPrivate *priv;

	g_return_val_if_fail (entry !=NULL, NULL);
	g_return_val_if_fail (GDATA_IS_ENTRY (entry), NULL);

	priv = GDATA_ENTRY_GET_PRIVATE (entry);
	return NULL;
}
Ejemplo n.º 13
0
/**
 * gdata_entry_set_postal_addresses:
 * @entry: A #GDataEntry object.
 * @addresses: A list of postal addresses.
 * Sets the list of postal addresses.
 **/
void
gdata_entry_set_postal_addresses (GDataEntry *entry, GSList *addresses)
{
	GDataEntryPrivate *priv;

	g_return_if_fail (GDATA_IS_ENTRY(entry));

	priv = GDATA_ENTRY_GET_PRIVATE(entry);
	priv->postal_addresses = addresses;
	priv->entry_needs_update = TRUE;
}
Ejemplo n.º 14
0
/**
 * gdata_entry_set_phone_numbers:
 * @entry: A #GDataEntry object.
 * @numbers: A list of phone numbers.
 * Sets the list of phone numbers.
 **/
void
gdata_entry_set_phone_numbers (GDataEntry *entry, GSList *numbers)
{
	GDataEntryPrivate *priv;

	g_return_if_fail (GDATA_IS_ENTRY(entry));

	priv = GDATA_ENTRY_GET_PRIVATE(entry);
	priv->phone_numbers = numbers;
	priv->entry_needs_update = TRUE;
}
Ejemplo n.º 15
0
/**
 * gdata_entry_set_organizations:
 * @entry: A #GDataEntry object.
 * @orgs: A list of organizations.
 * Sets the list of organizations.
 **/
void
gdata_entry_set_organizations (GDataEntry *entry, GSList *orgs)
{
	GDataEntryPrivate *priv;

	g_return_if_fail (GDATA_IS_ENTRY(entry));

	priv = GDATA_ENTRY_GET_PRIVATE(entry);
	priv->organizations = orgs;
	priv->entry_needs_update = TRUE;
}
Ejemplo n.º 16
0
/**
 * gdata_entry_set_location:
 * @entry: A GDataEntry object.
 * @location: Location of the event.
 * Sets the location of the event.
 **/
void
gdata_entry_set_location (GDataEntry *entry, const gchar *location)
{
	GDataEntryPrivate *priv;

	g_return_if_fail (location !=NULL);
	g_return_if_fail (GDATA_IS_ENTRY(entry));

	priv = GDATA_ENTRY_GET_PRIVATE(entry);
	priv->location = g_strdup (location);
	priv->entry_needs_update = TRUE;
}
Ejemplo n.º 17
0
/**
 * gdata_entry_set_end_time:
 * @entry: A GDataEntry object.
 * @end_time: The end time of the event.
 * Sets the end time of the event.
 **/
void
gdata_entry_set_end_time (GDataEntry *entry, const gchar *end_time)
{
	GDataEntryPrivate *priv;

	g_return_if_fail(end_time !=NULL);
	g_return_if_fail(GDATA_IS_ENTRY (entry));

	priv = GDATA_ENTRY_GET_PRIVATE(entry);
	priv->end_time = g_strdup(end_time);
	priv->entry_needs_update = TRUE;
}
Ejemplo n.º 18
0
/**
 * gdata_entry_set_reminder:
 * @entry: A GDataEntry object.
 * @reminder: The reminder set.
 * Sets the reminder of the Event.
 **/
void
gdata_entry_set_reminder (GDataEntry *entry, const gchar *reminder)
{
	GDataEntryPrivate *priv;

	g_return_if_fail(reminder !=NULL);
	g_return_if_fail(GDATA_IS_ENTRY (entry));

	priv = GDATA_ENTRY_GET_PRIVATE(entry);
	priv->reminder = g_strdup (reminder);
	priv->entry_needs_update = TRUE;
}
Ejemplo n.º 19
0
/**
 * gdata_entry_set_status:
 * @entry: A GDataEntry object.
 * @status: The status of the event.
 * Sets the status of the Event.
 **/
void
gdata_entry_set_status (GDataEntry *entry, const gchar *status)
{
	GDataEntryPrivate *priv;

	g_return_if_fail(status!=NULL);
	g_return_if_fail(GDATA_IS_ENTRY(entry));

	priv = GDATA_ENTRY_GET_PRIVATE(entry);
	priv->status = g_strdup (status);
	priv->entry_needs_update = TRUE;
}
Ejemplo n.º 20
0
/**
 * gdata_entry_set_categories:
 * @entry: A GDataEntry object.
 * @categories: A list of categories.
 * Sets the list of categories of the Entry.
 **/
void
gdata_entry_set_categories (GDataEntry *entry, GSList *categories)
{
	GDataEntryPrivate *priv;

	g_return_if_fail(categories !=NULL);
	g_return_if_fail(GDATA_IS_ENTRY(entry));

	priv = GDATA_ENTRY_GET_PRIVATE(entry);
	priv->categories = categories;
	priv->entry_needs_update = TRUE;
}
Ejemplo n.º 21
0
/**
 * gdata_entry_set_id:
 * @entry: A #GDataEntry object.
 * @id: Id of the entry.
 * Sets the list of authors.
 **/
void
gdata_entry_set_id (GDataEntry *entry, gchar *id)
{
	GDataEntryPrivate *priv;

	g_return_if_fail (id !=NULL);
	g_return_if_fail (GDATA_IS_ENTRY(entry));

	priv = GDATA_ENTRY_GET_PRIVATE(entry);
	priv->id = g_strdup(id);
	priv->entry_needs_update = TRUE;
}
Ejemplo n.º 22
0
/**
 * gdata_entry_set_author:
 * @entry: A #GDataEntry object.
 * @author: A list of authors.
 * Sets the list of authors.
 **/
void
gdata_entry_set_author (GDataEntry *entry, GSList *author)
{
	GDataEntryPrivate *priv;

	g_return_if_fail (author !=NULL);
	g_return_if_fail (GDATA_IS_ENTRY(entry));

	priv = GDATA_ENTRY_GET_PRIVATE(entry);
	priv->authors = author;
	priv->entry_needs_update = TRUE;
}
Ejemplo n.º 23
0
/**
 * gdata_entry_set_transparency:
 * @entry: A GDataEntry object.
 * @transparency: Transparency of the Entry.
 * Sets the transparency of the entry.
 **/
void
gdata_entry_set_transparency (GDataEntry *entry, const gchar *transparency)
{
	GDataEntryPrivate *priv;

	g_return_if_fail (transparency !=NULL);
	g_return_if_fail (GDATA_IS_ENTRY(entry));

	priv = GDATA_ENTRY_GET_PRIVATE(entry);
	priv->transparency = g_strdup (transparency);
	priv->entry_needs_update = TRUE;
}
Ejemplo n.º 24
0
/**
 * gdata_entry_set_links:
 * @entry: A GDataEntry object.
 * @links: A list of links associated.
 * Sets the links of the Event.
 **/
void
gdata_entry_set_links (GDataEntry *entry, GSList *links)
{
	GDataEntryPrivate *priv;

	g_return_if_fail( links !=NULL);
	g_return_if_fail(GDATA_IS_ENTRY(entry));

	priv = GDATA_ENTRY_GET_PRIVATE(entry);
	priv->links = links;
	priv->entry_needs_update = TRUE;
}
Ejemplo n.º 25
0
/**
 * gdata_entry_set_title:
 * @entry: A GDataEntry object.
 * @title: title of the event.
 * Sets the title of the Entry.
 **/
void
gdata_entry_set_title (GDataEntry *entry, const gchar *title)
{
	GDataEntryPrivate *priv;

	g_return_if_fail(title !=NULL);
	g_return_if_fail(GDATA_IS_ENTRY (entry));

	priv = GDATA_ENTRY_GET_PRIVATE (entry);
	priv->title = g_strdup(title);
	g_hash_table_insert (priv->field_table, g_strdup("title"), g_strdup(title));
	priv->entry_needs_update = TRUE;
}
Ejemplo n.º 26
0
/**
 * gdata_entry_set_content:
 * @entry: A GDataEntry object.
 * @content: The content of the event.
 * Sets the content of the Entry.
 **/
void
gdata_entry_set_content (GDataEntry *entry, const gchar *content)
{
	GDataEntryPrivate *priv;

	g_return_if_fail(content !=NULL);
	g_return_if_fail(GDATA_IS_ENTRY(entry));

	priv = GDATA_ENTRY_GET_PRIVATE(entry);
	priv->content = g_strdup (content);
	priv->entry_needs_update = TRUE;
	g_hash_table_insert (priv->field_table, g_strdup("content"), g_strdup (content));
}
Ejemplo n.º 27
0
void
gdata_entry_set_attendee_list (GDataEntry *entry, GSList *attendees)
{
	GDataEntryPrivate *priv;

	g_return_if_fail (entry != NULL);
	g_return_if_fail (GDATA_IS_ENTRY(entry));
	g_return_if_fail (attendees != NULL);

	priv = GDATA_ENTRY_GET_PRIVATE(entry);
	priv->attendees = attendees;
	priv->has_attendees = TRUE;
}
Ejemplo n.º 28
0
/**
 * gdata_entry_get_primary_postal_address:
 * @entry: A #GDataEntry object.
 * Returns the the primary postal address.
 **/
GDataEntryPostalAddress *
gdata_entry_get_primary_postal_address (GDataEntry *entry)
{
	GDataEntryPrivate *priv;
	GSList *itr;

	g_return_val_if_fail (entry != NULL, NULL);
	g_return_val_if_fail (GDATA_IS_ENTRY (entry), NULL);

	priv = GDATA_ENTRY_GET_PRIVATE (entry);

	itr = priv->postal_addresses;
	while (itr) {
		GDataEntryPostalAddress *address = itr->data;
		if (address->primary)
			return address;
		itr = itr->next;
	}
	return NULL;
}
Ejemplo n.º 29
0
/**
 * gdata_entry_get_edit_link:
 * @entry: A #GDataEntry object.
 * Returns the edit link of the entry
 **/
gchar *
gdata_entry_get_edit_link (GDataEntry *entry)
{
	GSList *list;
	GDataEntryLink *link;
	gchar *edit_link = NULL;

	g_return_val_if_fail(GDATA_IS_ENTRY(entry), NULL);
	list = gdata_entry_get_links (entry);

	while (list) {
		link = list->data;
		if (!g_ascii_strcasecmp (link->rel, "edit")) {
			edit_link = g_strdup(link->href);
		}
		list = g_slist_next (list);
	}

	return edit_link;
}
Ejemplo n.º 30
0
/**
 * gdata_entry_get_primary_phone_number:
 * @entry: A #GDataEntry object.
 * Returns the the primary phone number.
 **/
GDataEntryPhoneNumber *
gdata_entry_get_primary_phone_number (GDataEntry *entry)
{
	GDataEntryPrivate *priv;
	GSList *itr;

	g_return_val_if_fail (entry != NULL, NULL);
	g_return_val_if_fail (GDATA_IS_ENTRY (entry), NULL);

	priv = GDATA_ENTRY_GET_PRIVATE (entry);

	itr = priv->phone_numbers;
	while (itr) {
		GDataEntryPhoneNumber *number = itr->data;
		if (number->primary)
			return number;
		itr = itr->next;
	}
	return NULL;
}