]> git.meshlink.io Git - catta/blob - avahi-common/malloc.c
19e1e590014a56c2e8b2aa56dcb043ebf1b7289b
[catta] / avahi-common / malloc.c
1 /* $Id$ */
2
3 /***
4   This file is part of avahi.
5  
6   avahi is free software; you can redistribute it and/or modify it
7   under the terms of the GNU Lesser General Public License as
8   published by the Free Software Foundation; either version 2.1 of the
9   License, or (at your option) any later version.
10  
11   avahi is distributed in the hope that it will be useful, but WITHOUT
12   ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
13   or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General
14   Public License for more details.
15  
16   You should have received a copy of the GNU Lesser General Public
17   License along with avahi; if not, write to the Free Software
18   Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307
19   USA.
20 ***/
21
22 #ifdef HAVE_CONFIG_H
23 #include <config.h>
24 #endif
25
26 #include <stdlib.h>
27 #include <string.h>
28 #include <assert.h>
29 #include <stdio.h>
30
31 #include "malloc.h"
32
33 static const AvahiAllocator *allocator = NULL;
34
35 void *avahi_malloc(size_t size) {
36
37     if (size <= 0)
38         return NULL;
39     
40     if (!allocator)
41         return malloc(size);
42
43     assert(allocator->malloc);
44     return allocator->malloc(size);
45 }
46
47 void *avahi_malloc0(size_t size) {
48     void *p;
49
50     if (size <= 0)
51         return NULL;
52
53     if (!allocator)
54         return calloc(1, size);
55
56     if (allocator->calloc)
57         return allocator->calloc(1, size);
58
59     assert(allocator->malloc);
60     if ((p = allocator->malloc(size)))
61         memset(p, 0, size);
62
63     return p;
64 }
65
66 void avahi_free(void *p) {
67
68     if (!p)
69         return;
70     
71     if (!allocator) {
72         free(p);
73         return;
74     }
75
76     assert(allocator->free);
77     allocator->free(p);
78 }
79
80 void *avahi_realloc(void *p, size_t size) {
81
82     if (!allocator)
83         return realloc(p, size);
84
85     assert(allocator->realloc);
86     return allocator->realloc(p, size);
87 }
88
89 char *avahi_strdup(const char *s) {
90     char *r;
91     size_t size;
92     
93     if (!s)
94         return NULL;
95
96     size = strlen(s);
97     if (!(r = avahi_malloc(size+1)))
98         return NULL;
99
100     memcpy(r, s, size+1);
101     return r;
102 }
103
104 char *avahi_strndup(const char *s, size_t max) {
105     char *r;
106     size_t size;
107     
108     if (!s)
109         return NULL;
110
111     size = strlen(s);
112
113     if (size > max)
114         size = max;
115     
116     if (!(r = avahi_malloc(size+1)))
117         return NULL;
118
119     memcpy(r, s, size);
120     r[size] = 0;
121     return r;
122 }
123
124 /* Change the allocator */
125 void avahi_set_allocator(const AvahiAllocator *a) {
126     allocator = a;
127 }
128
129 char *avahi_strdup_vprintf(const char *fmt, va_list ap) {
130     size_t len = 100;
131     char *buf;
132     
133     assert(fmt);
134
135     if (!(buf = avahi_malloc(len)))
136         return NULL;
137
138     for (;;) {
139         int n;
140         char *nbuf;
141         
142         n = vsnprintf(buf, len, fmt, ap);
143
144         if (n >= 0 && n < (int) len)
145             return buf;
146
147         if (n >= 0)
148             len = n+1;
149         else
150             len *= 2;
151
152         if (!(nbuf = avahi_realloc(buf, len))) {
153             avahi_free(buf);
154             return NULL;
155         }
156
157         buf = nbuf;
158     }
159 }
160
161 char *avahi_strdup_printf(const char *fmt, ... ) {
162     char *s;
163     va_list ap;
164     
165     va_start(ap, fmt);
166     s = avahi_strdup_vprintf(fmt, ap);
167     va_end(ap);
168
169     return s;
170 }
171