diff options
Diffstat (limited to 'src/lacbytequeue.c')
-rw-r--r-- | src/lacbytequeue.c | 325 |
1 files changed, 0 insertions, 325 deletions
diff --git a/src/lacbytequeue.c b/src/lacbytequeue.c deleted file mode 100644 index 504df0b..0000000 --- a/src/lacbytequeue.c +++ /dev/null @@ -1,325 +0,0 @@ -#include <stdarg.h> -#include <string.h> -#include <glib/gprintf.h> -#include "lac.h" - -struct LacByteQueue -{ - gsize segment_size; - gchar * segment; - gchar * start; - gchar * end; -}; - -static void -initialize (LacByteQueue *queue) -{ - queue->segment_size = 0; - queue->segment = NULL; - queue->start = NULL; - queue->end = NULL; -} - -LacByteQueue * -lac_byte_queue_new (void) -{ - LacByteQueue *queue = g_new0 (LacByteQueue, 1); - - initialize (queue); - - return queue; -} - -gsize -lac_byte_queue_get_length (LacByteQueue *queue) -{ - return queue->end - queue->start; -} - -gchar * -lac_byte_queue_free (LacByteQueue *queue, - gboolean free_data) -{ - gchar *result; - - if (free_data) - { - g_free (queue->segment); - - result = NULL; - } - else - { - result = lac_byte_queue_steal (queue, NULL); - } - - g_free (queue); - - return result; -} - -/* The data returned is owned by the byte queue and becomes invalid - * as soon as any method is called on the queue. - */ -const gchar * -lac_byte_queue_peek (LacByteQueue *queue, - gsize *n_bytes) -{ - if (n_bytes) - *n_bytes = queue->end - queue->start; - - if (queue->start) - { - return queue->start; - } - else - { - /* The result of this function is guaranteed - * to be NULL terminated, so if the queue is - * empty, just return an empty string; - */ - return ""; - } -} - -gboolean -lac_byte_queue_is_empty (LacByteQueue *queue) -{ - return queue->start == queue->end; -} - -static gsize -power_of_two_bigger_than (gsize n) -{ - gsize result = 1; - - while (result <= n) - result *= 2; - - return result; -} - -static void -null_terminate (LacByteQueue *queue) -{ - if (queue->end) - *(queue->end) = '\0'; -} - -static void -ensure_room (LacByteQueue *queue, - gsize extra) -{ - gsize old_data_size = queue->end - queue->start; - gsize new_data_size = old_data_size + extra; - - if (queue->end + new_data_size + 1 > queue->segment + queue->segment_size) - { - gsize new_segment_size = power_of_two_bigger_than (2 * new_data_size); - - memmove (queue->segment, queue->start, old_data_size); - - if (new_segment_size > queue->segment_size) - { - queue->segment_size = new_segment_size; - queue->segment = g_realloc (queue->segment, new_segment_size); - } - - queue->start = queue->segment; - queue->end = queue->start + old_data_size; - - null_terminate (queue); - } -} - -/* This function appends uninitialized data of length @size - * to the queue, then returns a pointer to the added data. - * The intention is that the app can read() into this - * memory, then use lac_byte_queue_pop_tail() to delete the - * area that wasn't read into. Example - * - * guint8 *area = lac_byte_queue_alloc_tail (queue, 8192); - * - * n_read = read (fd, area, 8192); - * - * lac_byte_queue_delete_tail (queue, 8192 - (n_read < 0)? 0 : n_read); - * - * if (n_read < 0) - * { - * lac_byte_queue_delete_tail (queue, 8192); - * handle_error(); - * n_read = 0; - * } - * else - * { - * lac_byte_queue_delete_tail (8192 - n_read); - * - * // enjoy the new data in the queue - * } - */ -gchar * -lac_byte_queue_alloc_tail (LacByteQueue *queue, - gsize size) -{ - ensure_room (queue, size); - - queue->end += size; - - null_terminate (queue); - - return queue->end - size; -} - -void -lac_byte_queue_delete_head (LacByteQueue *queue, - gsize size) -{ - if (queue->end - queue->start < size) - queue->start = queue->end = queue->segment; - else - queue->start += size; -} - -void -lac_byte_queue_delete_tail (LacByteQueue *queue, - gsize size) -{ - if (queue->end - queue->start < size) - queue->start = queue->end = queue->segment; - else - queue->end -= size; - - null_terminate (queue); -} - -void -lac_byte_queue_append (LacByteQueue *queue, - const gchar *bytes, - gsize n_bytes) -{ - if (n_bytes > 0) - { - gchar *tail = lac_byte_queue_alloc_tail (queue, n_bytes); - - memcpy (tail, bytes, n_bytes); - } -} - -void -lac_byte_queue_append_printf (LacByteQueue *queue, - const gchar *fmt, - ...) -{ - gint required; - va_list args; - gchar *buffer; - - g_return_if_fail (fmt != NULL); - - va_start (args, fmt); - - required = g_vsnprintf (NULL, 0, fmt, args) + 1; - - buffer = lac_byte_queue_alloc_tail (queue, required); - - g_vsprintf (buffer, fmt, args); - - va_end (args); -} - -gchar * -lac_byte_queue_steal (LacByteQueue *queue, - gsize *n_bytes) -{ - gchar *result; - - if (n_bytes) - *n_bytes = queue->end - queue->start; - - memmove (queue->segment, queue->start, queue->end - queue->start); - - result = queue->segment; - - initialize (queue); - - return result; -} - -void -lac_byte_queue_swap_content (LacByteQueue *queue1, - LacByteQueue *queue2) -{ - gsize tmp1; - gchar *tmp2; - - tmp1 = queue1->segment_size; - queue1->segment_size = queue2->segment_size; - queue2->segment_size = tmp1; - - tmp2 = queue1->segment; - queue1->segment = queue2->segment; - queue2->segment = tmp2; - - tmp2 = queue1->start; - queue1->start = queue2->start; - queue2->start = tmp2; - - tmp2 = queue1->end; - queue1->end = queue2->end; - queue2->end = tmp2; -} - - -/* Transfer n_bytes data from the head of @src to tail of @dest, - * if possible without copying. The data is appended to @dest's data - * if @dest is not empty - */ -void -lac_byte_queue_transfer_data (LacByteQueue *dest, - LacByteQueue *src, - gssize n_bytes) -{ - gsize total = src->end - src->start; - if (n_bytes < 0 || n_bytes > total) - n_bytes = total; - - if (lac_byte_queue_is_empty (dest)) - { - char *source = src->start; - gboolean swap_contents = FALSE; - - if (n_bytes > total / 2) - { - source = src->start + n_bytes; - n_bytes = total - n_bytes; - swap_contents = TRUE; - } - - lac_byte_queue_append (dest, source, n_bytes); - - if (swap_contents) - { - lac_byte_queue_delete_tail (src, n_bytes); - lac_byte_queue_swap_content (dest, src); - } - else - { - lac_byte_queue_delete_head (src, n_bytes); - } - } - else - { - /* FIXME: - * - * check whether one of the strings fit in the other's segment. - * if both fit, copy the shortest, if only one, copy that one. - * if none, just append. - */ - lac_byte_queue_append (dest, src->start, src->end - src->start); - - if (src->segment) - g_free (src->segment); - - initialize (src); - } -} |