153a5a1b3Sopenharmony_ci/*** 253a5a1b3Sopenharmony_ci This file is part of PulseAudio. 353a5a1b3Sopenharmony_ci 453a5a1b3Sopenharmony_ci Copyright 2004-2006 Lennart Poettering 553a5a1b3Sopenharmony_ci 653a5a1b3Sopenharmony_ci PulseAudio is free software; you can redistribute it and/or modify 753a5a1b3Sopenharmony_ci it under the terms of the GNU Lesser General Public License as 853a5a1b3Sopenharmony_ci published by the Free Software Foundation; either version 2.1 of the 953a5a1b3Sopenharmony_ci License, or (at your option) any later version. 1053a5a1b3Sopenharmony_ci 1153a5a1b3Sopenharmony_ci PulseAudio is distributed in the hope that it will be useful, but 1253a5a1b3Sopenharmony_ci WITHOUT ANY WARRANTY; without even the implied warranty of 1353a5a1b3Sopenharmony_ci MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 1453a5a1b3Sopenharmony_ci Lesser General Public License for more details. 1553a5a1b3Sopenharmony_ci 1653a5a1b3Sopenharmony_ci You should have received a copy of the GNU Lesser General Public 1753a5a1b3Sopenharmony_ci License along with PulseAudio; if not, see <http://www.gnu.org/licenses/>. 1853a5a1b3Sopenharmony_ci***/ 1953a5a1b3Sopenharmony_ci 2053a5a1b3Sopenharmony_ci#ifdef HAVE_CONFIG_H 2153a5a1b3Sopenharmony_ci#include <config.h> 2253a5a1b3Sopenharmony_ci#endif 2353a5a1b3Sopenharmony_ci 2453a5a1b3Sopenharmony_ci#include <stdio.h> 2553a5a1b3Sopenharmony_ci#include <stdlib.h> 2653a5a1b3Sopenharmony_ci#include <string.h> 2753a5a1b3Sopenharmony_ci#include <errno.h> 2853a5a1b3Sopenharmony_ci 2953a5a1b3Sopenharmony_ci#include <pulsecore/macro.h> 3053a5a1b3Sopenharmony_ci#include <pulsecore/core-util.h> 3153a5a1b3Sopenharmony_ci 3253a5a1b3Sopenharmony_ci#include "memchunk.h" 3353a5a1b3Sopenharmony_ci 3453a5a1b3Sopenharmony_cipa_memchunk* pa_memchunk_make_writable(pa_memchunk *c, size_t min) { 3553a5a1b3Sopenharmony_ci pa_mempool *pool; 3653a5a1b3Sopenharmony_ci pa_memblock *n; 3753a5a1b3Sopenharmony_ci size_t l; 3853a5a1b3Sopenharmony_ci void *tdata, *sdata; 3953a5a1b3Sopenharmony_ci 4053a5a1b3Sopenharmony_ci pa_assert(c); 4153a5a1b3Sopenharmony_ci pa_assert(c->memblock); 4253a5a1b3Sopenharmony_ci 4353a5a1b3Sopenharmony_ci if (pa_memblock_ref_is_one(c->memblock) && 4453a5a1b3Sopenharmony_ci !pa_memblock_is_read_only(c->memblock) && 4553a5a1b3Sopenharmony_ci pa_memblock_get_length(c->memblock) >= c->index+min) 4653a5a1b3Sopenharmony_ci return c; 4753a5a1b3Sopenharmony_ci 4853a5a1b3Sopenharmony_ci l = PA_MAX(c->length, min); 4953a5a1b3Sopenharmony_ci 5053a5a1b3Sopenharmony_ci pool = pa_memblock_get_pool(c->memblock); 5153a5a1b3Sopenharmony_ci n = pa_memblock_new(pool, l); 5253a5a1b3Sopenharmony_ci pa_mempool_unref(pool), pool = NULL; 5353a5a1b3Sopenharmony_ci 5453a5a1b3Sopenharmony_ci sdata = pa_memblock_acquire(c->memblock); 5553a5a1b3Sopenharmony_ci tdata = pa_memblock_acquire(n); 5653a5a1b3Sopenharmony_ci 5753a5a1b3Sopenharmony_ci memcpy(tdata, (uint8_t*) sdata + c->index, c->length); 5853a5a1b3Sopenharmony_ci 5953a5a1b3Sopenharmony_ci pa_memblock_release(c->memblock); 6053a5a1b3Sopenharmony_ci pa_memblock_release(n); 6153a5a1b3Sopenharmony_ci 6253a5a1b3Sopenharmony_ci pa_memblock_unref(c->memblock); 6353a5a1b3Sopenharmony_ci 6453a5a1b3Sopenharmony_ci c->memblock = n; 6553a5a1b3Sopenharmony_ci c->index = 0; 6653a5a1b3Sopenharmony_ci 6753a5a1b3Sopenharmony_ci return c; 6853a5a1b3Sopenharmony_ci} 6953a5a1b3Sopenharmony_ci 7053a5a1b3Sopenharmony_cipa_memchunk* pa_memchunk_reset(pa_memchunk *c) { 7153a5a1b3Sopenharmony_ci pa_assert(c); 7253a5a1b3Sopenharmony_ci 7353a5a1b3Sopenharmony_ci memset(c, 0, sizeof(*c)); 7453a5a1b3Sopenharmony_ci 7553a5a1b3Sopenharmony_ci return c; 7653a5a1b3Sopenharmony_ci} 7753a5a1b3Sopenharmony_ci 7853a5a1b3Sopenharmony_cipa_memchunk *pa_memchunk_will_need(const pa_memchunk *c) { 7953a5a1b3Sopenharmony_ci void *p; 8053a5a1b3Sopenharmony_ci 8153a5a1b3Sopenharmony_ci pa_assert(c); 8253a5a1b3Sopenharmony_ci pa_assert(c->memblock); 8353a5a1b3Sopenharmony_ci 8453a5a1b3Sopenharmony_ci /* A version of pa_memblock_will_need() that works on memchunks 8553a5a1b3Sopenharmony_ci * instead of memblocks */ 8653a5a1b3Sopenharmony_ci 8753a5a1b3Sopenharmony_ci p = pa_memblock_acquire_chunk(c); 8853a5a1b3Sopenharmony_ci pa_will_need(p, c->length); 8953a5a1b3Sopenharmony_ci pa_memblock_release(c->memblock); 9053a5a1b3Sopenharmony_ci 9153a5a1b3Sopenharmony_ci return (pa_memchunk*) c; 9253a5a1b3Sopenharmony_ci} 9353a5a1b3Sopenharmony_ci 9453a5a1b3Sopenharmony_cipa_memchunk* pa_memchunk_memcpy(pa_memchunk *dst, pa_memchunk *src) { 9553a5a1b3Sopenharmony_ci void *p, *q; 9653a5a1b3Sopenharmony_ci 9753a5a1b3Sopenharmony_ci pa_assert(dst); 9853a5a1b3Sopenharmony_ci pa_assert(src); 9953a5a1b3Sopenharmony_ci pa_assert(dst->length == src->length); 10053a5a1b3Sopenharmony_ci 10153a5a1b3Sopenharmony_ci p = pa_memblock_acquire(dst->memblock); 10253a5a1b3Sopenharmony_ci q = pa_memblock_acquire(src->memblock); 10353a5a1b3Sopenharmony_ci 10453a5a1b3Sopenharmony_ci memmove((uint8_t*) p + dst->index, 10553a5a1b3Sopenharmony_ci (uint8_t*) q + src->index, 10653a5a1b3Sopenharmony_ci dst->length); 10753a5a1b3Sopenharmony_ci 10853a5a1b3Sopenharmony_ci pa_memblock_release(dst->memblock); 10953a5a1b3Sopenharmony_ci pa_memblock_release(src->memblock); 11053a5a1b3Sopenharmony_ci 11153a5a1b3Sopenharmony_ci return dst; 11253a5a1b3Sopenharmony_ci} 11353a5a1b3Sopenharmony_ci 11453a5a1b3Sopenharmony_cibool pa_memchunk_isset(pa_memchunk *chunk) { 11553a5a1b3Sopenharmony_ci pa_assert(chunk); 11653a5a1b3Sopenharmony_ci 11753a5a1b3Sopenharmony_ci return 11853a5a1b3Sopenharmony_ci chunk->memblock || 11953a5a1b3Sopenharmony_ci chunk->index > 0 || 12053a5a1b3Sopenharmony_ci chunk->length > 0; 12153a5a1b3Sopenharmony_ci} 122