source: roaraudio/libroar/memmgr.c @ 5002:35d2d75c1504

Last change on this file since 5002:35d2d75c1504 was 5002:35d2d75c1504, checked in by phi, 11 years ago

added roar_mm_strlcpy(), roar_mm_strlcat() and roar_mm_strtok_r()

File size: 7.6 KB
Line 
1//memmgr.c:
2
3/*
4 *      Copyright (C) Philipp 'ph3-der-loewe' Schafft - 2010-2011
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
52ssize_t roar_mm_sizeof(void * buf) {
53 if ( buf == NULL ) {
54  roar_err_set(ROAR_ERROR_FAULT);
55  return -1;
56 }
57
58 if ( buf == _libroar_null_buffer_check )
59  return 0;
60
61 roar_err_set(ROAR_ERROR_NOTSUP);
62 return -1;
63}
64
65void * roar_mm_calloc(size_t nmemb, size_t size) {
66 void * ret;
67
68 if ( nmemb == 0 || size == 0 ) {
69  _libroar_null_buffer_check();
70  return _libroar_null_buffer;
71 }
72
73#ifdef ROAR_HAVE_CALLOC
74 roar_err_clear_all();
75 ret = calloc(nmemb, size);
76
77 if ( ret == NULL )
78  roar_err_update();
79
80 return ret;
81#else
82 ret = roar_mm_malloc(nmemb*size);
83 if ( ret == NULL )
84  return NULL;
85
86 memset(ret, 0, nmemb*size);
87
88 return ret;
89#endif
90}
91
92void * roar_mm_malloc(size_t size) {
93 void * ret;
94
95 if ( size == 0 ) {
96  _libroar_null_buffer_check();
97  return _libroar_null_buffer;
98 }
99
100#ifdef ROAR_HAVE_MALLOC
101 roar_err_clear_all();
102 ret = malloc(size);
103
104 if ( ret == NULL )
105  roar_err_update();
106
107 return ret;
108#elif defined(ROAR_HAVE_CALLOC)
109 return roar_mm_calloc(1, size);
110#elif defined(ROAR_HAVE_REALLOC)
111 return roar_mm_realloc(NULL, size);
112#else
113 _err(ROAR_ERROR_NOSYS);
114#endif
115}
116
117int    roar_mm_free(void *ptr) {
118
119 if ( ptr == _libroar_null_buffer ) {
120  _libroar_null_buffer_check();
121  return 0;
122 }
123
124#ifdef ROAR_HAVE_FREE
125 free(ptr);
126 return 0;
127#elif defined(ROAR_HAVE_REALLOC)
128 if ( roar_mm_realloc(ptr, 0) != _libroar_null_buffer )
129  return -1;
130 return 0;
131#else
132 roar_err_set(ROAR_ERROR_NOSYS);
133 return -1;
134#endif
135}
136
137void * roar_mm_realloc(void *ptr, size_t size) {
138 void * ret;
139#ifndef ROAR_HAVE_REALLOC
140 ssize_t len;
141#endif
142
143 if ( ptr == NULL )
144  return roar_mm_malloc(size);
145
146 if ( size == 0 ) {
147  roar_mm_free(ptr);
148  _libroar_null_buffer_check();
149  return _libroar_null_buffer;
150 }
151
152#ifdef ROAR_HAVE_REALLOC
153 roar_err_clear_all();
154 ret = realloc(ptr, size);
155
156 if ( ret == NULL )
157  roar_err_update();
158
159 return ret;
160#else
161 len = roar_mm_sizeof(ptr);
162 if ( len == -1 )
163  return NULL;
164
165 ret = roar_mm_malloc(size);
166 if ( ret == NULL )
167  return NULL;
168
169 memcpy(ret, ptr, len > (ssize_t)size ? size : len);
170
171 return ret;
172#endif
173}
174#endif
175
176void * roar_mm_memdup(const void * s, size_t len) {
177 void * ret;
178
179 if ( s == NULL )
180  _err(ROAR_ERROR_FAULT);
181
182#ifdef ROAR_USE_MEMMGR
183 if ( len == 0 ) {
184  _libroar_null_buffer_check();
185  return _libroar_null_buffer;
186 }
187#endif
188
189 ret = roar_mm_malloc(len);
190
191 if ( ret == NULL )
192  return NULL;
193
194 memcpy(ret, s, len);
195
196 return ret;
197}
198
199void roar_mm_free_retvoid(void *ptr) {
200 roar_mm_free(ptr);
201}
202
203#if defined(ROAR_USE_MEMMGR) || !defined(ROAR_HAVE_STRDUP)
204char * roar_mm_strdup(const char *s) {
205 void * ret;
206#ifndef ROAR_HAVE_STRDUP
207 ssize_t len;
208#endif
209
210 if ( s == NULL )
211  _err(ROAR_ERROR_FAULT);
212
213#ifdef ROAR_HAVE_STRDUP
214 roar_err_clear_all();
215 ret = strdup(s);
216
217 if ( ret == NULL )
218  roar_err_update();
219#else
220 len = roar_mm_strlen(s);
221 if ( len == -1 )
222  return NULL;
223
224 ret = roar_mm_memdup(s, len+1);
225#endif
226
227 return ret;
228}
229#endif
230
231#if defined(ROAR_USE_MEMMGR) || !defined(ROAR_HAVE_STRNDUP)
232char *roar_mm_strndup(const char *s, size_t n) {
233 void * ret;
234#ifndef ROAR_HAVE_STRNDUP
235 ssize_t len;
236#endif
237
238 if ( s == NULL )
239  _err(ROAR_ERROR_FAULT);
240
241#ifdef ROAR_USE_MEMMGR
242 if ( n == 0 ) {
243  _libroar_null_buffer_check();
244  return _libroar_null_buffer;
245 }
246#endif
247
248#ifdef ROAR_HAVE_STRNDUP
249 roar_err_clear_all();
250 ret = strndup(s, n);
251
252 if ( ret == NULL )
253  roar_err_update();
254#else
255 len = roar_mm_strnlen(s, n);
256 if ( len == -1 )
257  return NULL;
258
259 ret = roar_mm_memdup(s, len+1);
260#endif
261
262 return ret;
263}
264#endif
265
266#ifndef ROAR_HAVE_STRLEN
267ssize_t roar_mm_strlen(const char *s) {
268 size_t ret = 0;
269
270 if ( s == NULL ) {
271  roar_err_set(ROAR_ERROR_FAULT);
272  return -1;
273 }
274
275 for (; *s != 0; s++, ret++);
276
277 return ret;
278}
279#endif
280
281ssize_t roar_mm_strnlen(const char *s, size_t maxlen) {
282 size_t ret = 0;
283
284 if ( s == NULL ) {
285  roar_err_set(ROAR_ERROR_FAULT);
286  return -1;
287 }
288
289#ifdef ROAR_HAVE_STRNLEN
290 ret = strnlen(s, maxlen);
291#else
292 for (; ret < maxlen && *s != 0; s++, ret++);
293#endif
294
295 if ( ret == maxlen ) {
296  roar_err_set(ROAR_ERROR_MSGSIZE);
297  return -1;
298 }
299
300 return ret;
301}
302
303
304#ifndef ROAR_HAVE_STRLCPY
305ssize_t roar_mm_strlcpy(char *dst, const char *src, size_t size) {
306 ssize_t len;
307
308 if ( dst == NULL || src == NULL ) {
309  roar_err_set(ROAR_ERROR_FAULT);
310  return -1;
311 }
312
313 if ( size == 0 )
314  return 0;
315
316 len = roar_mm_strlen(src);
317 if ( len == -1 )
318  return -1;
319
320 if ( len < (ssize_t)size ) {
321  memcpy(dst, src, len);
322  dst[len] = 0;
323 } else {
324  memcpy(dst, src, size - 1);
325  dst[size-1] = 0;
326 }
327
328 return len;
329}
330#endif
331
332#ifndef ROAR_HAVE_STRLCAT
333ssize_t roar_mm_strlcat(char *dst, const char *src, size_t size) {
334 ssize_t slen;
335 ssize_t dlen;
336 int err;
337
338 if ( dst == NULL || src == NULL ) {
339  roar_err_set(ROAR_ERROR_FAULT);
340  return -1;
341 }
342
343 if ( size == 0 )
344  return 0;
345
346 slen = roar_mm_strlen(src);
347 if ( slen == -1 )
348  return -1;
349
350 dlen = roar_mm_strnlen(dst, size);
351 err  = roar_error;
352 if ( dlen == -1 && err == ROAR_ERROR_MSGSIZE )
353  dlen = size;
354
355 if ( dlen == -1 )
356  return -1;
357
358 if ( (dlen + slen) < (ssize_t)size ) {
359  memcpy(dst+dlen, src, slen);
360  dst[dlen+slen] = 0;
361 } else if ( dlen != size ) {
362  memcpy(dst+dlen, src, size-dlen-1);
363  dst[size-1] = 0;
364 }
365
366 return dlen+slen;
367}
368#endif
369
370#ifndef ROAR_HAVE_STRTOK_R
371char * roar_mm_strtok_r(char *str, const char *delim, char **saveptr) {
372 char * next;
373
374 if ( delim == NULL || saveptr == NULL ) {
375  roar_err_set(ROAR_ERROR_FAULT);
376  return NULL;
377 }
378
379 if ( delim[0] == 0 ) {
380  roar_err_set(ROAR_ERROR_NOTSUP);
381  return NULL;
382 }
383
384 if ( delim[1] != 0 ) {
385  roar_err_set(ROAR_ERROR_NOTSUP);
386  return NULL;
387 }
388
389 if ( str != NULL ) {
390  next = str;
391 } else {
392  next = *saveptr;
393 }
394
395 if ( next == NULL ) {
396  roar_err_set(ROAR_ERROR_NODATA);
397  return NULL;
398 }
399
400 *saveptr = strstr(next, delim);
401
402 if ( *saveptr != NULL ) {
403  **saveptr = 0;
404  (*saveptr)++;
405 }
406
407 return next;
408}
409#endif
410
411//ll
Note: See TracBrowser for help on using the repository browser.