2006-11-17 03:15:40 +00:00
|
|
|
#ifdef HAVE_CONFIG_H
|
|
|
|
#include "config.h"
|
|
|
|
#endif
|
2005-02-11 22:01:19 +00:00
|
|
|
|
|
|
|
#include <rfbbytestream.h>
|
|
|
|
#include <string.h>
|
|
|
|
|
2006-11-17 03:15:40 +00:00
|
|
|
static gint rfb_bytestream_copy_nocheck (RfbBytestream * bs,
|
|
|
|
RfbBuffer * buffer, gint len);
|
|
|
|
|
2005-02-11 22:01:19 +00:00
|
|
|
RfbBytestream *
|
|
|
|
rfb_bytestream_new (void)
|
|
|
|
{
|
|
|
|
return g_new0 (RfbBytestream, 1);
|
|
|
|
}
|
|
|
|
|
2006-11-17 03:15:40 +00:00
|
|
|
void
|
|
|
|
rfb_bytestream_free (RfbBytestream * bs)
|
|
|
|
{
|
|
|
|
g_return_if_fail (bs != NULL);
|
|
|
|
|
|
|
|
g_slist_free (bs->buffer_list);
|
|
|
|
g_free (bs);
|
|
|
|
}
|
|
|
|
|
|
|
|
gint
|
|
|
|
rfb_bytestream_get (RfbBytestream * bs, gint len)
|
2005-02-11 22:01:19 +00:00
|
|
|
{
|
|
|
|
RfbBuffer *buffer;
|
|
|
|
|
2006-11-17 03:15:40 +00:00
|
|
|
g_return_val_if_fail (bs != NULL, 0);
|
|
|
|
|
2005-02-11 22:01:19 +00:00
|
|
|
buffer = bs->get_buffer (len, bs->user_data);
|
|
|
|
|
|
|
|
if (buffer) {
|
2006-11-17 03:15:40 +00:00
|
|
|
// g_print ("got buffer (%d bytes)\n", buffer->length);
|
|
|
|
bs->buffer_list = g_slist_append (bs->buffer_list, buffer);
|
2005-02-11 22:01:19 +00:00
|
|
|
|
|
|
|
bs->length += buffer->length;
|
|
|
|
|
|
|
|
return len;
|
|
|
|
}
|
|
|
|
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
|
|
|
gboolean
|
2006-11-17 03:15:40 +00:00
|
|
|
rfb_bytestream_check (RfbBytestream * bs, gint len)
|
2005-02-11 22:01:19 +00:00
|
|
|
{
|
2006-11-17 03:15:40 +00:00
|
|
|
g_return_val_if_fail (bs != NULL, FALSE);
|
|
|
|
|
2005-02-11 22:01:19 +00:00
|
|
|
while (bs->length < len) {
|
|
|
|
rfb_bytestream_get (bs, len - bs->length);
|
|
|
|
}
|
|
|
|
return TRUE;
|
|
|
|
}
|
|
|
|
|
2006-11-17 03:15:40 +00:00
|
|
|
gint
|
|
|
|
rfb_bytestream_read (RfbBytestream * bs, RfbBuffer ** buffer, gint len)
|
2005-02-11 22:01:19 +00:00
|
|
|
{
|
|
|
|
RfbBuffer *buf;
|
|
|
|
|
2006-11-17 03:15:40 +00:00
|
|
|
g_return_val_if_fail (bs != NULL, 0);
|
|
|
|
g_return_val_if_fail (buffer != NULL, 0);
|
|
|
|
|
2005-02-11 22:01:19 +00:00
|
|
|
rfb_bytestream_check (bs, len);
|
|
|
|
|
|
|
|
buf = rfb_buffer_new_and_alloc (len);
|
|
|
|
rfb_bytestream_copy_nocheck (bs, buf, len);
|
|
|
|
|
|
|
|
rfb_bytestream_flush (bs, len);
|
|
|
|
|
|
|
|
*buffer = buf;
|
|
|
|
return len;
|
|
|
|
}
|
|
|
|
|
2006-11-17 03:15:40 +00:00
|
|
|
gint
|
|
|
|
rfb_bytestream_peek (RfbBytestream * bs, RfbBuffer ** buffer, gint len)
|
2005-02-11 22:01:19 +00:00
|
|
|
{
|
|
|
|
RfbBuffer *buf;
|
|
|
|
|
2006-11-17 03:15:40 +00:00
|
|
|
g_return_val_if_fail (bs != NULL, 0);
|
|
|
|
g_return_val_if_fail (buffer != NULL, 0);
|
|
|
|
|
2005-02-11 22:01:19 +00:00
|
|
|
rfb_bytestream_check (bs, len);
|
|
|
|
|
|
|
|
buf = rfb_buffer_new_and_alloc (len);
|
|
|
|
rfb_bytestream_copy_nocheck (bs, buf, len);
|
|
|
|
|
|
|
|
*buffer = buf;
|
|
|
|
return len;
|
|
|
|
}
|
|
|
|
|
2006-11-17 03:15:40 +00:00
|
|
|
gint
|
|
|
|
rfb_bytestream_flush (RfbBytestream * bs, gint len)
|
2005-02-11 22:01:19 +00:00
|
|
|
{
|
2006-11-17 03:15:40 +00:00
|
|
|
GSList *item;
|
2005-02-11 22:01:19 +00:00
|
|
|
RfbBuffer *buf;
|
2006-11-17 03:15:40 +00:00
|
|
|
gint n;
|
|
|
|
|
|
|
|
g_return_val_if_fail (bs != NULL, 0);
|
2005-02-11 22:01:19 +00:00
|
|
|
|
|
|
|
while ((item = bs->buffer_list)) {
|
|
|
|
buf = (RfbBuffer *) item->data;
|
|
|
|
|
|
|
|
n = MIN (buf->length - bs->offset, len);
|
|
|
|
if (n <= len) {
|
|
|
|
bs->offset = 0;
|
2006-11-17 03:15:40 +00:00
|
|
|
bs->buffer_list = g_slist_delete_link (bs->buffer_list, item);
|
2005-02-11 22:01:19 +00:00
|
|
|
rfb_buffer_free (buf);
|
|
|
|
} else {
|
|
|
|
bs->offset = bs->offset + len;
|
|
|
|
}
|
|
|
|
bs->length -= n;
|
|
|
|
len -= n;
|
|
|
|
if (len == 0)
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
|
|
|
g_assert_not_reached ();
|
|
|
|
return 0;
|
|
|
|
}
|
2006-11-17 03:15:40 +00:00
|
|
|
|
|
|
|
static gint
|
|
|
|
rfb_bytestream_copy_nocheck (RfbBytestream * bs, RfbBuffer * buffer, gint len)
|
|
|
|
{
|
|
|
|
GSList *item;
|
|
|
|
gint offset;
|
|
|
|
gint first_offset;
|
|
|
|
RfbBuffer *frombuf;
|
|
|
|
gint n;
|
|
|
|
|
|
|
|
offset = 0;
|
|
|
|
first_offset = bs->offset;
|
|
|
|
for (item = bs->buffer_list; item; item = item->next) {
|
|
|
|
frombuf = (RfbBuffer *) item->data;
|
|
|
|
n = MIN (len, frombuf->length - first_offset);
|
|
|
|
// g_print ("copying %d bytes from %p\n", n, frombuf);
|
|
|
|
memcpy (buffer->data + offset, frombuf->data + first_offset, n);
|
|
|
|
first_offset = 0;
|
|
|
|
len -= n;
|
|
|
|
offset += n;
|
|
|
|
if (len == 0)
|
|
|
|
return len;
|
|
|
|
}
|
|
|
|
|
|
|
|
g_assert_not_reached ();
|
|
|
|
return 0;
|
|
|
|
}
|