diff options
Diffstat (limited to 'src/internal/utils')
-rw-r--r-- | src/internal/utils/kitbuffer.c | 100 | ||||
-rw-r--r-- | src/internal/utils/kithelpers.c | 30 | ||||
-rw-r--r-- | src/internal/utils/kitringbuffer.c | 172 |
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; +} |