diff options
-rw-r--r-- | gdata/gdata-private.h | 3 | ||||
-rw-r--r-- | gdata/gdata-query.c | 45 | ||||
-rw-r--r-- | gdata/gdata-service.c | 15 |
3 files changed, 61 insertions, 2 deletions
diff --git a/gdata/gdata-private.h b/gdata/gdata-private.h index f470561b..8ad24876 100644 --- a/gdata/gdata-private.h +++ b/gdata/gdata-private.h @@ -72,7 +72,10 @@ G_GNUC_INTERNAL void _gdata_service_secure_strfree (GDataSecureString str); #include "gdata-query.h" G_GNUC_INTERNAL void _gdata_query_set_next_uri (GDataQuery *self, const gchar *next_uri); +G_GNUC_INTERNAL void _gdata_query_set_next_uri_end (GDataQuery *self); +G_GNUC_INTERNAL gboolean _gdata_query_is_finished (GDataQuery *self); G_GNUC_INTERNAL void _gdata_query_set_previous_uri (GDataQuery *self, const gchar *previous_uri); +G_GNUC_INTERNAL void _gdata_query_set_previous_uri_end (GDataQuery *self); #include "gdata-parsable.h" G_GNUC_INTERNAL GDataParsable *_gdata_parsable_new_from_xml (GType parsable_type, const gchar *xml, gint length, gpointer user_data, diff --git a/gdata/gdata-query.c b/gdata/gdata-query.c index bf42fe2b..a2a7cd8b 100644 --- a/gdata/gdata-query.c +++ b/gdata/gdata-query.c @@ -66,6 +66,18 @@ struct _GDataQueryPrivate { gboolean is_strict; guint max_results; + /* Pagination management. Supports three states: + * 1. (next_uri == NULL && !use_next_uri): + * Implement pagination by incrementing #GDataQuery:start-index + * internally with each call to gdata_query_next_page(). Stop + * when the returned #GDataFeed is empty. + * 2a. (next_uri != NULL && use_next_uri): + * Implement pagination with an explicit URI for the next page, + * which will be used when gdata_query_next_page() is called. + * 2b. (next_uri == NULL && use_next_uri): + * End of pagination using known URIs; return an empty + * #GDataFeed when gdata_query_next_page() is called. + */ gchar *next_uri; gchar *previous_uri; gboolean use_next_uri; @@ -967,6 +979,25 @@ _gdata_query_set_next_uri (GDataQuery *self, const gchar *next_uri) } void +_gdata_query_set_next_uri_end (GDataQuery *self) +{ + g_return_if_fail (GDATA_IS_QUERY (self)); + + g_free (self->priv->next_uri); + self->priv->next_uri = NULL; + self->priv->use_next_uri = TRUE; + self->priv->use_previous_uri = FALSE; +} + +gboolean +_gdata_query_is_finished (GDataQuery *self) +{ + g_return_val_if_fail (GDATA_IS_QUERY (self), FALSE); + + return (self->priv->next_uri == NULL && self->priv->use_next_uri); +} + +void _gdata_query_set_previous_uri (GDataQuery *self, const gchar *previous_uri) { g_return_if_fail (GDATA_IS_QUERY (self)); @@ -976,6 +1007,17 @@ _gdata_query_set_previous_uri (GDataQuery *self, const gchar *previous_uri) self->priv->use_previous_uri = FALSE; } +void +_gdata_query_set_previous_uri_end (GDataQuery *self) +{ + g_return_if_fail (GDATA_IS_QUERY (self)); + + g_free (self->priv->previous_uri); + self->priv->previous_uri = NULL; + self->priv->use_next_uri = TRUE; + self->priv->use_previous_uri = FALSE; +} + /** * gdata_query_next_page: * @self: a #GDataQuery @@ -1029,7 +1071,8 @@ gdata_query_previous_page (GDataQuery *self) if (priv->previous_uri != NULL) { priv->use_previous_uri = TRUE; priv->use_next_uri = FALSE; - } else if (priv->start_index <= priv->max_results) { + } else if (priv->start_index <= priv->max_results || + (priv->previous_uri == NULL && priv->use_previous_uri)) { return FALSE; } else { priv->start_index -= priv->max_results; diff --git a/gdata/gdata-service.c b/gdata/gdata-service.c index ad4c1bc4..300824b2 100644 --- a/gdata/gdata-service.c +++ b/gdata/gdata-service.c @@ -963,14 +963,27 @@ __gdata_service_query (GDataService *self, GDataAuthorizationDomain *domain, con SoupMessage *message; GDataFeed *feed; + klass = GDATA_SERVICE_GET_CLASS (self); + + /* Are we off the end of the final page? */ + if (query != NULL && _gdata_query_is_finished (query)) { + GTimeVal updated; + + /* Build an empty dummy feed to signify the end of the list. */ + g_get_current_time (&updated); + return _gdata_feed_new (klass->feed_type, "Empty feed", "feed1", + updated.tv_sec); + } + + /* Send the request. */ message = _gdata_service_query (self, domain, feed_uri, query, cancellable, error); if (message == NULL) return NULL; g_assert (message->response_body->data != NULL); - klass = GDATA_SERVICE_GET_CLASS (self); g_assert (klass->parse_feed != NULL); + /* Parse the response. */ feed = klass->parse_feed (self, domain, query, entry_type, message, cancellable, progress_callback, progress_user_data, error); |