Spelling fix.
[samba.git] / source3 / lib / talloc.c
1 /* 
2    Unix SMB/Netbios implementation.
3    Version 3.0
4    Samba temporary memory allocation functions
5    Copyright (C) Andrew Tridgell 2000
6    
7    This program is free software; you can redistribute it and/or modify
8    it under the terms of the GNU General Public License as published by
9    the Free Software Foundation; either version 2 of the License, or
10    (at your option) any later version.
11    
12    This program is distributed in the hope that it will be useful,
13    but WITHOUT ANY WARRANTY; without even the implied warranty of
14    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
15    GNU General Public License for more details.
16    
17    You should have received a copy of the GNU General Public License
18    along with this program; if not, write to the Free Software
19    Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
20 */
21
22 /* this is a very simple temporary memory allocator. To use it do the following:
23
24    1) when you first want to allocate a pool of meomry use
25    talloc_init() and save the resulting context pointer somewhere
26
27    2) to allocate memory use talloc()
28
29    3) when _all_ of the memory allocated using this context is no longer needed
30    use talloc_destroy()
31
32    talloc does not zero the memory. It guarantees memory of a
33    TALLOC_ALIGN alignment
34 */
35
36 #include "includes.h"
37
38 /* initialise talloc context. */
39 TALLOC_CTX *talloc_init(void)
40 {
41         TALLOC_CTX *t;
42
43         t = (TALLOC_CTX *)malloc(sizeof(*t));
44         if (!t) return NULL;
45
46         t->list = NULL;
47         t->total_alloc_size = 0;
48
49         return t;
50 }
51
52 /* allocate a bit of memory from the specified pool */
53 void *talloc(TALLOC_CTX *t, size_t size)
54 {
55         void *p;
56         struct talloc_chunk *tc;
57
58         if (size == 0) return NULL;
59
60         p = malloc(size);
61         if (!p) return p;
62
63         tc = malloc(sizeof(*tc));
64         if (!tc) {
65                 free(p);
66                 return NULL;
67         }
68
69         tc->ptr = p;
70         tc->size = size;
71         tc->next = t->list;
72         t->list = tc;
73         t->total_alloc_size += size;
74
75         return p;
76 }
77
78 /* a talloc version of realloc */
79 void *talloc_realloc(TALLOC_CTX *t, void *ptr, size_t size)
80 {
81         struct talloc_chunk *tc;
82
83         for (tc=t->list; tc; tc=tc->next) {
84                 if (tc->ptr == ptr) {
85                         ptr = realloc(ptr, size);
86                         if (ptr) {
87                                 t->total_alloc_size += (size - tc->size);
88                                 tc->size = size;
89                                 tc->ptr = ptr;
90                         }
91                         return ptr;
92                 }
93         }
94         return NULL;
95 }
96
97 /* destroy a whole pool */
98 void talloc_destroy_pool(TALLOC_CTX *t)
99 {
100         struct talloc_chunk *c;
101         
102         if (!t)
103                 return;
104
105         while (t->list) {
106                 c = t->list->next;
107                 if (t->list->ptr) free(t->list->ptr);
108                 free(t->list);
109                 t->list = c;
110         }
111
112         t->list = NULL;
113         t->total_alloc_size = 0;
114 }
115
116 /* destroy a whole pool including the context */
117 void talloc_destroy(TALLOC_CTX *t)
118 {
119         if (!t)
120                 return;
121         talloc_destroy_pool(t);
122         memset(t, 0, sizeof(*t));
123         free(t);
124 }
125
126 /* return the current total size of the pool. */
127 size_t talloc_pool_size(TALLOC_CTX *t)
128 {
129         return t->total_alloc_size;
130 }
131
132 /* talloc and zero memory. */
133 void *talloc_zero(TALLOC_CTX *t, size_t size)
134 {
135         void *p = talloc(t, size);
136
137         if (p)
138                 memset(p, '\0', size);
139
140         return p;
141 }
142
143 /* memdup with a talloc. */
144 void *talloc_memdup(TALLOC_CTX *t, void *p, size_t size)
145 {
146         void *newp = talloc(t,size);
147
148         if (!newp)
149                 return 0;
150
151         memcpy(newp, p, size);
152
153         return newp;
154 }
155
156 /* strdup with a talloc */
157 char *talloc_strdup(TALLOC_CTX *t, char *p)
158 {
159         return talloc_memdup(t, p, strlen(p) + 1);
160 }