/cpw/tomkiewicz/gg11: aae07f956000: Merge from trunk
Tomasz Wasilczyk
tomkiewicz at cpw.pidgin.im
Tue Oct 23 06:53:17 EDT 2012
Changeset: aae07f956000feac1ac8965aafd280173b748bb9
Author: Tomasz Wasilczyk <tomkiewicz at cpw.pidgin.im>
Date: 2012-10-23 12:51 +0200
Branch: default
URL: http://hg.pidgin.im/cpw/tomkiewicz/gg11/rev/aae07f956000
Description:
Merge from trunk
diffstat:
libpurple/glibcompat.h | 29 +++++++++++++----------
libpurple/http.c | 60 ++++++++++++++++++++++++++++++++++++++++++++++++++
libpurple/http.h | 27 ++++++++++++++++++++++
3 files changed, 103 insertions(+), 13 deletions(-)
diffs (220 lines):
diff --git a/libpurple/glibcompat.h b/libpurple/glibcompat.h
--- a/libpurple/glibcompat.h
+++ b/libpurple/glibcompat.h
@@ -25,31 +25,34 @@
* Also, any public API should not depend on this file.
*/
+#if !GLIB_CHECK_VERSION(2, 20, 0)
+
+#define G_OFFSET_FORMAT G_GINT64_FORMAT
+
#if !GLIB_CHECK_VERSION(2, 28, 0)
+static inline gint64 g_get_monotonic_time(void)
+{
+ GTimeVal time_s;
+
+ g_get_current_time(&time_s);
+
+ return ((gint64)time_s.tv_sec << 32) | time_s.tv_usec;
+}
+
static inline void g_list_free_full(GList *list, GDestroyNotify free_func)
{
- GList *it;
- it = g_list_first(list);
- while (it)
- {
- free_func(it->data);
- it = g_list_next(it);
- }
+ g_list_foreach(list, (GFunc)free_func, NULL);
g_list_free(list);
}
static inline void g_slist_free_full(GSList *list, GDestroyNotify free_func)
{
- GSList *it = list;
- while (it)
- {
- free_func(it->data);
- it = g_slist_next(it);
- }
+ g_slist_foreach(list, (GFunc)free_func, NULL);
g_slist_free(list);
}
#endif /* 2.28.0 */
+#endif /* 2.20.0 */
#endif /* _PIDGINGLIBCOMPAT_H_ */
diff --git a/libpurple/http.c b/libpurple/http.c
--- a/libpurple/http.c
+++ b/libpurple/http.c
@@ -78,6 +78,7 @@ struct _PurpleHttpConnection
PurpleConnection *gc;
PurpleHttpCallback callback;
gpointer user_data;
+ gboolean is_reading;
PurpleHttpURL *url;
PurpleHttpRequest *request;
@@ -103,6 +104,11 @@ struct _PurpleHttpConnection
GList *link_global, *link_gc;
guint timeout_handle;
+
+ PurpleHttpProgressWatcher watcher;
+ gpointer watcher_user_data;
+ guint watcher_interval_threshold;
+ gint64 watcher_last_call;
};
struct _PurpleHttpResponse
@@ -149,6 +155,7 @@ static time_t purple_http_rfc1123_to_tim
static PurpleHttpConnection * purple_http_connection_new(
PurpleHttpRequest *request, PurpleConnection *gc);
static void purple_http_connection_terminate(PurpleHttpConnection *hc);
+static void purple_http_conn_notify_progress_watcher(PurpleHttpConnection *hc);
static PurpleHttpResponse * purple_http_response_new(void);
static void purple_http_response_free(PurpleHttpResponse *response);
@@ -662,6 +669,8 @@ static void _purple_http_recv_body_data(
hc->data_length_got += len;
}
+ purple_http_conn_notify_progress_watcher(hc);
+
if (len == 0)
return;
@@ -1017,12 +1026,14 @@ static void _purple_http_send(gpointer _
if (writing_headers) {
hc->request_header_written += written;
+ purple_http_conn_notify_progress_watcher(hc);
if (hc->request_header_written < hc->request_header->len)
return;
if (hc->request->contents_length > 0)
return;
} else {
hc->request_contents_written += written;
+ purple_http_conn_notify_progress_watcher(hc);
if (hc->contents_reader_buffer)
g_string_erase(hc->contents_reader_buffer, 0, written);
if (hc->request_contents_written < hc->request->contents_length)
@@ -1030,6 +1041,7 @@ static void _purple_http_send(gpointer _
}
/* request is completely written, let's read the response */
+ hc->is_reading = TRUE;
purple_input_remove(hs->inpa);
hs->inpa = 0;
if (hs->is_ssl)
@@ -1192,6 +1204,8 @@ static gboolean _purple_http_reconnect(P
hc->in_chunk = FALSE;
hc->chunks_done = FALSE;
+ purple_http_conn_notify_progress_watcher(hc);
+
return TRUE;
}
@@ -1387,6 +1401,52 @@ PurpleConnection * purple_http_conn_get_
return http_conn->gc;
}
+void purple_http_conn_set_progress_watcher(PurpleHttpConnection *http_conn,
+ PurpleHttpProgressWatcher watcher, gpointer user_data,
+ guint interval_threshold)
+{
+ g_return_if_fail(http_conn != NULL);
+
+ http_conn->watcher = watcher;
+ http_conn->watcher_user_data = user_data;
+ http_conn->watcher_interval_threshold = interval_threshold;
+}
+
+static void purple_http_conn_notify_progress_watcher(
+ PurpleHttpConnection *hc)
+{
+ gint64 now;
+ gboolean reading_state;
+ int processed, total;
+
+ g_return_if_fail(hc != NULL);
+
+ if (hc->watcher == NULL)
+ return;
+
+ reading_state = hc->is_reading;
+ if (reading_state) {
+ total = hc->length_expected;
+ processed = hc->length_got;
+ } else {
+ total = hc->request->contents_length;
+ processed = hc->request_contents_written;
+ if (total == 0)
+ total = -1;
+ }
+ if (total != -1 && total < processed) {
+ purple_debug_warning("http", "Processed too much\n");
+ total = processed;
+ }
+
+ now = g_get_monotonic_time();
+ if (hc->watcher_last_call + hc->watcher_interval_threshold
+ > now && processed != total)
+ return;
+ hc->watcher_last_call = now;
+ hc->watcher(hc, reading_state, processed, total, hc->watcher_user_data);
+}
+
/*** Cookie jar API ***********************************************************/
static PurpleHttpCookie * purple_http_cookie_new(const gchar *value);
diff --git a/libpurple/http.h b/libpurple/http.h
--- a/libpurple/http.h
+++ b/libpurple/http.h
@@ -95,6 +95,19 @@ typedef void (*PurpleHttpContentWriter)(
PurpleHttpResponse *response, const gchar *buffer, size_t offset,
size_t length, gpointer user_data);
+/**
+ * An callback for watching HTTP connection progress.
+ *
+ * @param http_conn The HTTP Connection.
+ * @param reading_state FALSE, is we are sending the request, TRUE, when reading
+ * the response.
+ * @param processed The amount of data already processed.
+ * @param total Total amount of data (in current state).
+ * @param user_data The user data passed with callback function.
+ */
+typedef void (*PurpleHttpProgressWatcher)(PurpleHttpConnection *http_conn,
+ gboolean reading_state, int processed, int total, gpointer user_data);
+
G_BEGIN_DECLS
/**************************************************************************/
@@ -184,6 +197,20 @@ PurpleHttpCookieJar * purple_http_conn_g
PurpleConnection * purple_http_conn_get_purple_connection(
PurpleHttpConnection *http_conn);
+/**
+ * Sets the watcher, called after writing or reading data to/from HTTP stream.
+ * May be used for updating transfer progress gauge.
+ *
+ * @param http_conn The HTTP connection.
+ * @param watcher The watcher.
+ * @param user_data The user data to pass to the callback function.
+ * @param interval_threshold Minimum interval (in microseconds) of calls to
+ * watcher.
+ */
+void purple_http_conn_set_progress_watcher(PurpleHttpConnection *http_conn,
+ PurpleHttpProgressWatcher watcher, gpointer user_data,
+ guint interval_threshold);
+
/*@}*/
More information about the Commits
mailing list