summaryrefslogtreecommitdiff
path: root/src/internal/utils
diff options
context:
space:
mode:
Diffstat (limited to 'src/internal/utils')
-rw-r--r--src/internal/utils/kitbuffer.c100
-rw-r--r--src/internal/utils/kithelpers.c30
-rw-r--r--src/internal/utils/kitringbuffer.c172
3 files changed, 302 insertions, 0 deletions
diff --git a/src/internal/utils/kitbuffer.c b/src/internal/utils/kitbuffer.c
new file mode 100644
index 0000000..0133154
--- /dev/null
+++ b/src/internal/utils/kitbuffer.c
@@ -0,0 +1,100 @@
+#include <stdlib.h>
+#include <assert.h>
+
+#include "kitchensink/internal/utils/kitbuffer.h"
+
+Kit_Buffer* Kit_CreateBuffer(unsigned int size, Kit_BufferFreeCallback free_cb) {
+ Kit_Buffer *b = calloc(1, sizeof(Kit_Buffer));
+ if(b == NULL) {
+ return NULL;
+ }
+ b->size = size;
+ b->free_cb = free_cb;
+ b->data = calloc(size, sizeof(void*));
+ if(b->data == NULL) {
+ free(b);
+ return NULL;
+ }
+ return b;
+}
+
+void Kit_DestroyBuffer(Kit_Buffer *buffer) {
+ if(buffer == NULL) return;
+ Kit_ClearBuffer(buffer);
+ free(buffer->data);
+ free(buffer);
+}
+
+void Kit_ClearBuffer(Kit_Buffer *buffer) {
+ void *data;
+ if(buffer->free_cb == NULL)
+ return;
+ while((data = Kit_ReadBuffer(buffer)) != NULL) {
+ buffer->free_cb(data);
+ }
+}
+
+void* Kit_ReadBuffer(Kit_Buffer *buffer) {
+ assert(buffer != NULL);
+ if(buffer->read_p < buffer->write_p) {
+ void *out = buffer->data[buffer->read_p % buffer->size];
+ buffer->data[buffer->read_p % buffer->size] = NULL;
+ buffer->read_p++;
+ if(buffer->read_p >= buffer->size) {
+ buffer->read_p = buffer->read_p % buffer->size;
+ buffer->write_p = buffer->write_p % buffer->size;
+ }
+ return out;
+ }
+ return NULL;
+}
+
+void* Kit_PeekBuffer(const Kit_Buffer *buffer) {
+ assert(buffer != NULL);
+ if(buffer->read_p < buffer->write_p) {
+ return buffer->data[buffer->read_p % buffer->size];
+ }
+ return NULL;
+}
+
+void Kit_AdvanceBuffer(Kit_Buffer *buffer) {
+ assert(buffer != NULL);
+ if(buffer->read_p < buffer->write_p) {
+ buffer->data[buffer->read_p % buffer->size] = NULL;
+ buffer->read_p++;
+ if(buffer->read_p >= buffer->size) {
+ buffer->read_p = buffer->read_p % buffer->size;
+ buffer->write_p = buffer->write_p % buffer->size;
+ }
+ }
+}
+
+void Kit_ForEachItemInBuffer(const Kit_Buffer *buffer, Kit_ForEachItemCallback cb, void *userdata) {
+ unsigned int read_p = buffer->read_p;
+ unsigned int write_p = buffer->write_p;
+ while(read_p < write_p) {
+ cb(buffer->data[read_p++ % buffer->size], userdata);
+ if(read_p >= buffer->size) {
+ read_p = read_p % buffer->size;
+ write_p = write_p % buffer->size;
+ }
+ }
+}
+
+int Kit_WriteBuffer(Kit_Buffer *buffer, void *ptr) {
+ assert(buffer != NULL);
+ assert(ptr != NULL);
+
+ if(!Kit_IsBufferFull(buffer)) {
+ buffer->data[buffer->write_p % buffer->size] = ptr;
+ buffer->write_p++;
+ return 0;
+ }
+ return 1;
+}
+
+int Kit_IsBufferFull(const Kit_Buffer *buffer) {
+ int len = buffer->write_p - buffer->read_p;
+ int k = (len >= buffer->size);
+ return k;
+}
diff --git a/src/internal/utils/kithelpers.c b/src/internal/utils/kithelpers.c
new file mode 100644
index 0000000..c68f1c7
--- /dev/null
+++ b/src/internal/utils/kithelpers.c
@@ -0,0 +1,30 @@
+#include <libavutil/time.h>
+#include <libavutil/avstring.h>
+
+#include "kitchensink/internal/utils/kithelpers.h"
+
+static const char * const font_mime[] = {
+ "application/x-font-ttf",
+ "application/x-font-truetype",
+ "application/x-truetype-font",
+ "application/x-font-opentype",
+ "application/vnd.ms-opentype",
+ "application/font-sfnt",
+ NULL
+};
+
+double _GetSystemTime() {
+ return (double)av_gettime() / 1000000.0;
+}
+
+bool attachment_is_font(AVStream *stream) {
+ AVDictionaryEntry *tag = av_dict_get(stream->metadata, "mimetype", NULL, AV_DICT_MATCH_CASE);
+ if(tag) {
+ for(int n = 0; font_mime[n]; n++) {
+ if(av_strcasecmp(font_mime[n], tag->value) == 0) {
+ return true;
+ }
+ }
+ }
+ return false;
+}
diff --git a/src/internal/utils/kitringbuffer.c b/src/internal/utils/kitringbuffer.c
new file mode 100644
index 0000000..70fd24f
--- /dev/null
+++ b/src/internal/utils/kitringbuffer.c
@@ -0,0 +1,172 @@
+/*
+ * Ringbuffer
+ *
+ * Copyright (c) 2017, Tuomas Virtanen
+ * license: MIT; see LICENSE for details.
+*/
+
+#include <stdlib.h>
+#include <string.h>
+#include <stdio.h>
+#include <assert.h>
+
+#include "kitchensink/internal/utils/kitringbuffer.h"
+
+/**
+ * Creates a new ringbuffer with the given size.
+ * @param size Size for the new ringbuffer
+ * @return Ringbuffer handle
+ */
+Kit_RingBuffer* Kit_CreateRingBuffer(unsigned int size) {
+ Kit_RingBuffer *rb = calloc(1, sizeof(Kit_RingBuffer));
+ if(rb == NULL) return NULL;
+ rb->size = size;
+ rb->data = malloc(size);
+ if(rb->data == NULL) {
+ free(rb);
+ return NULL;
+ }
+ return rb;
+}
+
+/**
+ * Deletes the given ringbuffer.
+ * @param rb Ringbuffer to be deleted.
+ */
+void Kit_DestroyRingBuffer(Kit_RingBuffer* rb) {
+ if(rb == NULL) return;
+ free(rb->data);
+ free(rb);
+}
+
+/**
+ * Writes to the given ringbuffer. If given length is larger than the amount
+ * the ringbuffer can fit, only the data that fits will be written.
+ * @param rb Ringbuffer to write to.
+ * @param data Data to write
+ * @param len Data length
+ * @return Amount of data that was actually written.
+ */
+int Kit_WriteRingBuffer(Kit_RingBuffer *rb, const char* data, int len) {
+ int k;
+ len = (len > (rb->size - rb->len)) ? (rb->size - rb->len) : len;
+ if(rb->len < rb->size) {
+ if(len + rb->wpos > rb->size) {
+ k = (len + rb->wpos) % rb->size;
+ memcpy((rb->data + rb->wpos), data, len - k);
+ memcpy(rb->data, data+(len-k), k);
+ } else {
+ memcpy((rb->data + rb->wpos), data, len);
+ }
+ rb->len += len;
+ rb->wpos += len;
+ if(rb->wpos >= rb->size) {
+ rb->wpos = rb->wpos % rb->size;
+ }
+ return len;
+ }
+ return 0;
+}
+
+/**
+ * Reads data from ringbuffer. If ringbuffer has less data than was requested,
+ * only the available data will be read.
+ * @param rb Ringbuffer to read from.
+ * @param data Buffer to read into.
+ * @param len How much data do we want
+ * @return Amount of data that was actually read.
+ */
+int Kit_ReadRingBuffer(Kit_RingBuffer *rb, char* data, int len) {
+ int k;
+ len = (len > rb->len) ? rb->len : len;
+ if(rb->len > 0) {
+ if(len + rb->rpos > rb->size) {
+ k = (len + rb->rpos) % rb->size;
+ memcpy(data, (rb->data + rb->rpos), len-k);
+ memcpy(data+(len-k), (rb->data), k);
+ } else {
+ memcpy(data, (rb->data + rb->rpos), len);
+ }
+ rb->len -= len;
+ rb->rpos += len;
+ if(rb->rpos >= rb->size) {
+ rb->rpos = rb->rpos % rb->size;
+ }
+ return len;
+ }
+ return 0;
+}
+
+/**
+ * Peeks into the given ringbuffer. Technically same as rb_read, but does not advance
+ * the internal position pointer. In other words, you may peek as many times as you wish,
+ * and will always get the same data.
+ * @param rb Ringbuffer to peek into.
+ * @param data Buffer to read into
+ * @param len How much data do we need
+ * @return Amount of data actually read
+ */
+int Kit_PeekRingBuffer(const Kit_RingBuffer *rb, char* data, int len) {
+ int k;
+ len = (len > rb->len) ? rb->len : len;
+ if(rb->len > 0) {
+ if(len + rb->rpos > rb->size) {
+ k = (len + rb->rpos) % rb->size;
+ memcpy(data, (rb->data + rb->rpos), len-k);
+ memcpy(data+(len-k), (rb->data), k);
+ } else {
+ memcpy(data, (rb->data + rb->rpos), len);
+ }
+ return len;
+ }
+ return 0;
+}
+
+/**
+ * Advances the internal position counter by given amount. Note that counter can only be
+ * advanced by the amount of unreadable data in ringbuffer.
+ * @param rb Ringbuffer to handle
+ * @param len How much should the position counter be increased
+ * @return How much the position counter was actually increased.
+ */
+int Kit_AdvanceRingBuffer(Kit_RingBuffer *rb, int len) {
+ len = (len > rb->len) ? rb->len : len;
+ if(rb->len > 0) {
+ rb->len -= len;
+ rb->rpos += len;
+ if(rb->rpos >= rb->size) {
+ rb->rpos = rb->rpos % rb->size;
+ }
+ return len;
+ }
+ return 0;
+}
+
+/**
+ * Returns the current length of the Ringbuffer. In other words, how much data
+ * the ringbuffer contains
+ * @param rb Ringbuffer to handle
+ * @return Data in ringbuffer (in bytes).
+ */
+int Kit_GetRingBufferLength(const Kit_RingBuffer *rb) {
+ return rb->len;
+}
+
+/**
+ * Returns the size of the ringbuffer. In other words, the maximum amount of data
+ * the ringbuffer can hold.
+ * @param rb Ringbuffer to handle
+ * @return Size of the ringbuffer
+ */
+int Kit_GetRingBufferSize(const Kit_RingBuffer *rb) {
+ return rb->size;
+}
+
+/**
+ * Returns the free size of the ringbuffer.
+ * @param rb Ringbuffer to handle
+ * @return Free size in the ringbuffer
+ */
+int Kit_GetRingBufferFree(const Kit_RingBuffer *rb) {
+ return rb->size - rb->len;
+}