summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorDario Freddi <dario.freddi@collabora.com>2012-09-01 03:48:33 +0200
committerDario Freddi <dario.freddi@collabora.com>2012-09-01 03:48:33 +0200
commit22134a711ae8a202922607e27c96af847a4bfb34 (patch)
tree783fa286d47adf365ceb51e6f230a05897b83608
parent804144754de76b7a976a52380808399292e08320 (diff)
Handle partial data bufferingdrf-tubes-ice-udp
-rw-r--r--src/tube-stream.c73
1 files changed, 72 insertions, 1 deletions
diff --git a/src/tube-stream.c b/src/tube-stream.c
index 1eaf32d15..e47956684 100644
--- a/src/tube-stream.c
+++ b/src/tube-stream.c
@@ -109,6 +109,13 @@ struct {
guint16 size;
} TubePacketHeader;
+typedef struct {
+ guint connection_id;
+ gchar *partial_buffer;
+ guint partial_buffer_length;
+ guint total_buffer_length;
+} TubePartialData;
+
/* signals */
enum
{
@@ -205,6 +212,7 @@ struct _GabbleTubeStreamPrivate
GHashTable *buffers_for_connection_id;
GHashTable *length_for_buffers;
+ TubePartialData *tube_partial_data;
};
typedef struct
@@ -1380,6 +1388,7 @@ gabble_tube_stream_init (GabbleTubeStream *self)
g_direct_equal, NULL, NULL);
priv->length_for_buffers = g_hash_table_new_full (g_direct_hash,
g_direct_equal, NULL, NULL);
+ priv->tube_partial_data = NULL;
priv->address_type = TP_SOCKET_ADDRESS_TYPE_UNIX;
priv->address = NULL;
@@ -2509,6 +2518,47 @@ nice_data_received_cb (NiceAgent *agent,
guint16 size;
gchar *real_buffer;
+ if (priv->tube_partial_data != NULL)
+ {
+ TubePartialData *partial_data = priv->tube_partial_data;
+ connection_id = partial_data->connection_id;
+ size = partial_data->total_buffer_length;
+
+ /* We are still receiving stuff. */
+ if (partial_data->total_buffer_length <= partial_data->partial_buffer_length + len)
+ {
+ real_buffer = g_malloc (partial_data->total_buffer_length);
+
+ memcpy (real_buffer, partial_data->partial_buffer,
+ partial_data->partial_buffer_length);
+ memcpy (real_buffer + partial_data->partial_buffer_length,
+ buffer, partial_data->total_buffer_length - partial_data->partial_buffer_length);
+ }
+ else
+ {
+ real_buffer = g_malloc (partial_data->partial_buffer_length + len);
+
+ memcpy (real_buffer, partial_data->partial_buffer,
+ partial_data->partial_buffer_length);
+ memcpy (real_buffer + partial_data->partial_buffer_length,
+ buffer, len);
+
+ g_free (partial_data->partial_buffer);
+
+ partial_data->partial_buffer_length += len;
+ partial_data->partial_buffer = real_buffer;
+
+ priv->tube_partial_data = partial_data;
+
+ /* Return - there is nothing left to do here */
+ return;
+ }
+
+ current_position += partial_data->total_buffer_length - partial_data->partial_buffer_length;
+
+ goto send_data;
+ }
+
connection_id = buffer[current_position];
size = *((guint16 *) &buffer[current_position + 1]);
real_buffer = &buffer[current_position + 3];
@@ -2543,11 +2593,25 @@ nice_data_received_cb (NiceAgent *agent,
continue;
}
+send_data:
+
/* Let's check if we got the full message */
if (current_position > len)
{
- /* Bad luck - only part of the message came through. Let's try and handle this case. */
+ /* Bad luck - only part of the message came through. Let's try and handle this case.
+ * It is guaranteed if we got here that partial_data is NULL. */
+ TubePartialData *partial_data = g_new (TubePartialData, 1);
+
DEBUG ("Partial data");
+
+ partial_data->connection_id = connection_id;
+ partial_data->partial_buffer_length = size - (current_position - len);
+ partial_data->total_buffer_length = size;
+
+ partial_data->partial_buffer = g_malloc (partial_data->partial_buffer_length);
+ memcpy (partial_data->partial_buffer, real_buffer, partial_data->partial_buffer_length);
+
+ priv->tube_partial_data = partial_data;
return;
}
@@ -2588,6 +2652,13 @@ nice_data_received_cb (NiceAgent *agent,
}
g_object_unref (transport);
+
+ if (priv->tube_partial_data != NULL)
+ {
+ g_free (real_buffer);
+ g_free (priv->tube_partial_data->partial_buffer);
+ g_free (priv->tube_partial_data);
+ }
}
}