source: roaraudio/libroar/memmgr.c @ 5381:430b1d26e12d

Last change on this file since 5381:430b1d26e12d was 5381:430b1d26e12d, checked in by phi, 12 years ago

updated copyright years

File size: 7.7 KB
Line 
1//memmgr.c:
2
3/*
4 *      Copyright (C) Philipp 'ph3-der-loewe' Schafft - 2010-2012
5 *
6 *  This file is part of libroar a part of RoarAudio,
7 *  a cross-platform sound system for both, home and professional use.
8 *  See README for details.
9 *
10 *  This file is free software; you can redistribute it and/or modify
11 *  it under the terms of the GNU General Public License version 3
12 *  as published by the Free Software Foundation.
13 *
14 *  libroar is distributed in the hope that it will be useful,
15 *  but WITHOUT ANY WARRANTY; without even the implied warranty of
16 *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
17 *  GNU General Public License for more details.
18 *
19 *  You should have received a copy of the GNU General Public License
20 *  along with this software; see the file COPYING.  If not, write to
21 *  the Free Software Foundation, 51 Franklin Street, Fifth Floor,
22 *  Boston, MA 02110-1301, USA.
23 *
24 *  NOTE for everyone want's to change something and send patches:
25 *  read README and HACKING! There a addition information on
26 *  the license of this document you need to read before you send
27 *  any patches.
28 *
29 *  NOTE for uses of non-GPL (LGPL,...) software using libesd, libartsc
30 *  or libpulse*:
31 *  The libs libroaresd, libroararts and libroarpulse link this lib
32 *  and are therefore GPL. Because of this it may be illigal to use
33 *  them with any software that uses libesd, libartsc or libpulse*.
34 */
35
36#include "libroar.h"
37
38#ifdef ROAR_USE_MEMMGR
39#define NULL_BUFFER_CONST "RoarAudio"
40static char _libroar_null_buffer[] = NULL_BUFFER_CONST; // A byte sequense >= 8 byte.
41
42static inline void _libroar_null_buffer_check(void) {
43 if ( memcmp(_libroar_null_buffer, NULL_BUFFER_CONST, sizeof(_libroar_null_buffer)) != 0 )
44  roar_panic(ROAR_FATAL_ERROR_MEMORY_CORRUPTION_GUARD, NULL);
45 memcpy(_libroar_null_buffer, NULL_BUFFER_CONST, sizeof(_libroar_null_buffer));
46}
47#endif
48
49#define _err(x) do { roar_err_set((x)); return NULL; } while (0)
50
51#ifdef ROAR_USE_MEMMGR
52
53int     roar_mm_reset(void) {
54 // currently this does nothing.
55 // we need to free pools and such here later.
56 return 0;
57}
58
59ssize_t roar_mm_sizeof(void * buf) {
60 if ( buf == NULL ) {
61  roar_err_set(ROAR_ERROR_FAULT);
62  return -1;
63 }
64
65 if ( buf == _libroar_null_buffer_check )
66  return 0;
67
68 roar_err_set(ROAR_ERROR_NOTSUP);
69 return -1;
70}
71
72void * roar_mm_calloc(size_t nmemb, size_t size) {
73 void * ret;
74
75 if ( nmemb == 0 || size == 0 ) {
76  _libroar_null_buffer_check();
77  return _libroar_null_buffer;
78 }
79
80#ifdef ROAR_HAVE_CALLOC
81 roar_err_clear_all();
82 ret = calloc(nmemb, size);
83
84 if ( ret == NULL )
85  roar_err_update();
86
87 return ret;
88#else
89 ret = roar_mm_malloc(nmemb*size);
90 if ( ret == NULL )
91  return NULL;
92
93 memset(ret, 0, nmemb*size);
94
95 return ret;
96#endif
97}
98
99void * roar_mm_malloc(size_t size) {
100 void * ret;
101
102 if ( size == 0 ) {
103  _libroar_null_buffer_check();
104  return _libroar_null_buffer;
105 }
106
107#ifdef ROAR_HAVE_MALLOC
108 roar_err_clear_all();
109 ret = malloc(size);
110
111 if ( ret == NULL )
112  roar_err_update();
113
114 return ret;
115#elif defined(ROAR_HAVE_CALLOC)
116 return roar_mm_calloc(1, size);
117#elif defined(ROAR_HAVE_REALLOC)
118 return roar_mm_realloc(NULL, size);
119#else
120 _err(ROAR_ERROR_NOSYS);
121#endif
122}
123
124int    roar_mm_free(void *ptr) {
125
126 if ( ptr == _libroar_null_buffer ) {
127  _libroar_null_buffer_check();
128  return 0;
129 }
130
131#ifdef ROAR_HAVE_FREE
132 free(ptr);
133 return 0;
134#elif defined(ROAR_HAVE_REALLOC)
135 if ( roar_mm_realloc(ptr, 0) != _libroar_null_buffer )
136  return -1;
137 return 0;
138#else
139 roar_err_set(ROAR_ERROR_NOSYS);
140 return -1;
141#endif
142}
143
144void * roar_mm_realloc(void *ptr, size_t size) {
145 void * ret;
146#ifndef ROAR_HAVE_REALLOC
147 ssize_t len;
148#endif
149
150 if ( ptr == NULL )
151  return roar_mm_malloc(size);
152
153 if ( size == 0 ) {
154  roar_mm_free(ptr);
155  _libroar_null_buffer_check();
156  return _libroar_null_buffer;
157 }
158
159#ifdef ROAR_HAVE_REALLOC
160 roar_err_clear_all();
161 ret = realloc(ptr, size);
162
163 if ( ret == NULL )
164  roar_err_update();
165
166 return ret;
167#else
168 len = roar_mm_sizeof(ptr);
169 if ( len == -1 )
170  return NULL;
171
172 ret = roar_mm_malloc(size);
173 if ( ret == NULL )
174  return NULL;
175
176 memcpy(ret, ptr, len > (ssize_t)size ? size : len);
177
178 return ret;
179#endif
180}
181#endif
182
183void * roar_mm_memdup(const void * s, size_t len) {
184 void * ret;
185
186 if ( s == NULL )
187  _err(ROAR_ERROR_FAULT);
188
189#ifdef ROAR_USE_MEMMGR
190 if ( len == 0 ) {
191  _libroar_null_buffer_check();
192  return _libroar_null_buffer;
193 }
194#endif
195
196 ret = roar_mm_malloc(len);
197
198 if ( ret == NULL )
199  return NULL;
200
201 memcpy(ret, s, len);
202
203 return ret;
204}
205
206void roar_mm_free_retvoid(void *ptr) {
207 roar_mm_free(ptr);
208}
209
210#if defined(ROAR_USE_MEMMGR) || !defined(ROAR_HAVE_STRDUP)
211char * roar_mm_strdup(const char *s) {
212 void * ret;
213#ifndef ROAR_HAVE_STRDUP
214 ssize_t len;
215#endif
216
217 if ( s == NULL )
218  _err(ROAR_ERROR_FAULT);
219
220#ifdef ROAR_HAVE_STRDUP
221 roar_err_clear_all();
222 ret = strdup(s);
223
224 if ( ret == NULL )
225  roar_err_update();
226#else
227 len = roar_mm_strlen(s);
228 if ( len == -1 )
229  return NULL;
230
231 ret = roar_mm_memdup(s, len+1);
232#endif
233
234 return ret;
235}
236#endif
237
238#if defined(ROAR_USE_MEMMGR) || !defined(ROAR_HAVE_STRNDUP)
239char *roar_mm_strndup(const char *s, size_t n) {
240 void * ret;
241#ifndef ROAR_HAVE_STRNDUP
242 ssize_t len;
243#endif
244
245 if ( s == NULL )
246  _err(ROAR_ERROR_FAULT);
247
248#ifdef ROAR_USE_MEMMGR
249 if ( n == 0 ) {
250  _libroar_null_buffer_check();
251  return _libroar_null_buffer;
252 }
253#endif
254
255#ifdef ROAR_HAVE_STRNDUP
256 roar_err_clear_all();
257 ret = strndup(s, n);
258
259 if ( ret == NULL )
260  roar_err_update();
261#else
262 len = roar_mm_strnlen(s, n);
263 if ( len == -1 )
264  return NULL;
265
266 ret = roar_mm_memdup(s, len+1);
267#endif
268
269 return ret;
270}
271#endif
272
273#ifndef ROAR_HAVE_STRLEN
274ssize_t roar_mm_strlen(const char *s) {
275 size_t ret = 0;
276
277 if ( s == NULL ) {
278  roar_err_set(ROAR_ERROR_FAULT);
279  return -1;
280 }
281
282 for (; *s != 0; s++, ret++);
283
284 return ret;
285}
286#endif
287
288ssize_t roar_mm_strnlen(const char *s, size_t maxlen) {
289 size_t ret = 0;
290
291 if ( s == NULL ) {
292  roar_err_set(ROAR_ERROR_FAULT);
293  return -1;
294 }
295
296#ifdef ROAR_HAVE_STRNLEN
297 ret = strnlen(s, maxlen);
298#else
299 for (; ret < maxlen && *s != 0; s++, ret++);
300#endif
301
302 if ( ret == maxlen ) {
303  roar_err_set(ROAR_ERROR_MSGSIZE);
304  return -1;
305 }
306
307 return ret;
308}
309
310
311#ifndef ROAR_HAVE_STRLCPY
312ssize_t roar_mm_strlcpy(char *dst, const char *src, size_t size) {
313 ssize_t len;
314
315 if ( dst == NULL || src == NULL ) {
316  roar_err_set(ROAR_ERROR_FAULT);
317  return -1;
318 }
319
320 if ( size == 0 )
321  return 0;
322
323 len = roar_mm_strlen(src);
324 if ( len == -1 )
325  return -1;
326
327 if ( len < (ssize_t)size ) {
328  memcpy(dst, src, len);
329  dst[len] = 0;
330 } else {
331  memcpy(dst, src, size - 1);
332  dst[size-1] = 0;
333 }
334
335 return len;
336}
337#endif
338
339#ifndef ROAR_HAVE_STRLCAT
340ssize_t roar_mm_strlcat(char *dst, const char *src, size_t size) {
341 ssize_t slen;
342 ssize_t dlen;
343 int err;
344
345 if ( dst == NULL || src == NULL ) {
346  roar_err_set(ROAR_ERROR_FAULT);
347  return -1;
348 }
349
350 if ( size == 0 )
351  return 0;
352
353 slen = roar_mm_strlen(src);
354 if ( slen == -1 )
355  return -1;
356
357 dlen = roar_mm_strnlen(dst, size);
358 err  = roar_error;
359 if ( dlen == -1 && err == ROAR_ERROR_MSGSIZE )
360  dlen = size;
361
362 if ( dlen == -1 )
363  return -1;
364
365 if ( (dlen + slen) < (ssize_t)size ) {
366  memcpy(dst+dlen, src, slen);
367  dst[dlen+slen] = 0;
368 } else if ( dlen != (ssize_t)size ) {
369  memcpy(dst+dlen, src, size-dlen-1);
370  dst[size-1] = 0;
371 }
372
373 return dlen+slen;
374}
375#endif
376
377#ifndef ROAR_HAVE_STRTOK_R
378char * roar_mm_strtok_r(char *str, const char *delim, char **saveptr) {
379 char * next;
380
381 if ( delim == NULL || saveptr == NULL ) {
382  roar_err_set(ROAR_ERROR_FAULT);
383  return NULL;
384 }
385
386 if ( delim[0] == 0 ) {
387  roar_err_set(ROAR_ERROR_NOTSUP);
388  return NULL;
389 }
390
391 if ( delim[1] != 0 ) {
392  roar_err_set(ROAR_ERROR_NOTSUP);
393  return NULL;
394 }
395
396 if ( str != NULL ) {
397  next = str;
398 } else {
399  next = *saveptr;
400 }
401
402 if ( next == NULL ) {
403  roar_err_set(ROAR_ERROR_NODATA);
404  return NULL;
405 }
406
407 *saveptr = strstr(next, delim);
408
409 if ( *saveptr != NULL ) {
410  **saveptr = 0;
411  (*saveptr)++;
412 }
413
414 return next;
415}
416#endif
417
418//ll
Note: See TracBrowser for help on using the repository browser.