From 41f6aea8fdbc744c13bc461056a2d694a5c4d06f Mon Sep 17 00:00:00 2001 From: Lennart Poettering Date: Sat, 17 Jul 2004 14:12:30 +0000 Subject: rename src to polyp git-svn-id: file:///home/lennart/svn/public/pulseaudio/trunk@90 fefdeb5f-60dc-0310-8127-8f9354f1896f --- polyp/memchunk.c | 149 +++++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 149 insertions(+) create mode 100644 polyp/memchunk.c (limited to 'polyp/memchunk.c') diff --git a/polyp/memchunk.c b/polyp/memchunk.c new file mode 100644 index 00000000..d27ca61a --- /dev/null +++ b/polyp/memchunk.c @@ -0,0 +1,149 @@ +/* $Id$ */ + +/*** + This file is part of polypaudio. + + polypaudio is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published + by the Free Software Foundation; either version 2 of the License, + or (at your option) any later version. + + polypaudio is distributed in the hope that it will be useful, but + WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + General Public License for more details. + + You should have received a copy of the GNU General Public License + along with polypaudio; if not, write to the Free Software + Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 + USA. +***/ + +#ifdef HAVE_CONFIG_H +#include +#endif + +#include +#include +#include +#include + +#include "memchunk.h" + +void pa_memchunk_make_writable(struct pa_memchunk *c) { + struct pa_memblock *n; + assert(c && c->memblock && c->memblock->ref >= 1); + + if (c->memblock->ref == 1) + return; + + n = pa_memblock_new(c->length); + assert(n); + memcpy(n->data, c->memblock->data+c->index, c->length); + pa_memblock_unref(c->memblock); + c->memblock = n; + c->index = 0; +} + + +struct pa_mcalign { + size_t base; + struct pa_memchunk chunk; + uint8_t *buffer; + size_t buffer_fill; +}; + +struct pa_mcalign *pa_mcalign_new(size_t base) { + struct pa_mcalign *m; + assert(base); + + m = malloc(sizeof(struct pa_mcalign)); + assert(m); + m->base = base; + m->chunk.memblock = NULL; + m->chunk.length = m->chunk.index = 0; + m->buffer = NULL; + m->buffer_fill = 0; + return m; +} + +void pa_mcalign_free(struct pa_mcalign *m) { + assert(m); + + free(m->buffer); + + if (m->chunk.memblock) + pa_memblock_unref(m->chunk.memblock); + + free(m); +} + +void pa_mcalign_push(struct pa_mcalign *m, const struct pa_memchunk *c) { + assert(m && c && !m->chunk.memblock && c->memblock && c->length); + + m->chunk = *c; + pa_memblock_ref(m->chunk.memblock); +} + +int pa_mcalign_pop(struct pa_mcalign *m, struct pa_memchunk *c) { + assert(m && c && m->base > m->buffer_fill); + int ret; + + if (!m->chunk.memblock) + return -1; + + if (m->buffer_fill) { + size_t l = m->base - m->buffer_fill; + if (l > m->chunk.length) + l = m->chunk.length; + assert(m->buffer && l); + + memcpy(m->buffer + m->buffer_fill, m->chunk.memblock->data + m->chunk.index, l); + m->buffer_fill += l; + m->chunk.index += l; + m->chunk.length -= l; + + if (m->chunk.length == 0) { + m->chunk.length = m->chunk.index = 0; + pa_memblock_unref(m->chunk.memblock); + m->chunk.memblock = NULL; + } + + assert(m->buffer_fill <= m->base); + if (m->buffer_fill == m->base) { + c->memblock = pa_memblock_new_dynamic(m->buffer, m->base); + assert(c->memblock); + c->index = 0; + c->length = m->base; + m->buffer = NULL; + m->buffer_fill = 0; + + return 0; + } + + return -1; + } + + m->buffer_fill = m->chunk.length % m->base; + + if (m->buffer_fill) { + assert(!m->buffer); + m->buffer = malloc(m->base); + assert(m->buffer); + m->chunk.length -= m->buffer_fill; + memcpy(m->buffer, m->chunk.memblock->data + m->chunk.index + m->chunk.length, m->buffer_fill); + } + + if (m->chunk.length) { + *c = m->chunk; + pa_memblock_ref(c->memblock); + ret = 0; + } else + ret = -1; + + m->chunk.length = m->chunk.index = 0; + pa_memblock_unref(m->chunk.memblock); + m->chunk.memblock = NULL; + + return ret; +} -- cgit