summaryrefslogtreecommitdiffabout
path: root/libical/src/libical/icalmemory.c
Unidiff
Diffstat (limited to 'libical/src/libical/icalmemory.c') (more/less context) (ignore whitespace changes)
-rw-r--r--libical/src/libical/icalmemory.c287
1 files changed, 287 insertions, 0 deletions
diff --git a/libical/src/libical/icalmemory.c b/libical/src/libical/icalmemory.c
new file mode 100644
index 0000000..297ead8
--- a/dev/null
+++ b/libical/src/libical/icalmemory.c
@@ -0,0 +1,287 @@
1/* -*- Mode: C -*-
2 ======================================================================
3 FILE: icalmemory.c
4 CREATOR: eric 30 June 1999
5
6 $Id$
7 $Locker$
8
9 The contents of this file are subject to the Mozilla Public License
10 Version 1.0 (the "License"); you may not use this file except in
11 compliance with the License. You may obtain a copy of the License at
12 http://www.mozilla.org/MPL/
13
14 Software distributed under the License is distributed on an "AS IS"
15 basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
16 the License for the specific language governing rights and
17 limitations under the License.
18
19
20 This program is free software; you can redistribute it and/or modify
21 it under the terms of either:
22
23 The LGPL as published by the Free Software Foundation, version
24 2.1, available at: http://www.fsf.org/copyleft/lesser.html
25
26 Or:
27
28 The Mozilla Public License Version 1.0. You may obtain a copy of
29 the License at http://www.mozilla.org/MPL/
30
31 The Original Code is icalmemory.h
32
33 ======================================================================*/
34
35/* libical often passes strings back to the caller. To make these
36 * interfaces simple, I did not want the caller to have to pass in a
37 * memory buffer, but having libical pass out newly allocated memory
38 * makes it difficult to de-allocate the memory.
39 *
40 * The ring buffer in this scheme makes it possible for libical to pass
41 * out references to memory which the caller does not own, and be able
42 * to de-allocate the memory later. The ring allows libical to have
43 * several buffers active simultaneously, which is handy when creating
44 * string representations of components. */
45
46#define ICALMEMORY_C
47
48#ifdef HAVE_CONFIG_H
49#include "config.h"
50#endif
51
52#ifdef DMALLOC
53#include "dmalloc.h"
54#endif
55
56#include "icalmemory.h"
57#include "icalerror.h"
58
59#include <stdio.h> /* for printf (debugging) */
60#include <stdlib.h> /* for malloc, realloc */
61#include <string.h> /* for memset(), strdup */
62
63#define BUFFER_RING_SIZE 25
64#define MIN_BUFFER_SIZE 200
65
66void icalmemory_free_tmp_buffer (void* buf);
67
68
69/* HACK. Not threadsafe */
70void* buffer_ring[BUFFER_RING_SIZE];
71int buffer_pos = -1;
72int initialized = 0;
73
74/* Add an existing buffer to the buffer ring */
75void icalmemory_add_tmp_buffer(void* buf)
76{
77 /* I don't think I need this -- I think static arrays are
78 initialized to 0 as a standard part of C, but I am not sure. */
79 if (initialized == 0){
80 int i;
81 for(i=0; i<BUFFER_RING_SIZE; i++){
82 buffer_ring[i] = 0;
83 }
84 initialized = 1;
85 }
86
87 /* Wrap around the ring */
88 if(++buffer_pos == BUFFER_RING_SIZE){
89 buffer_pos = 0;
90 }
91
92 /* Free buffers as their slots are overwritten */
93 if ( buffer_ring[buffer_pos] != 0){
94 free( buffer_ring[buffer_pos]);
95 buffer_ring[buffer_pos] = 0;
96 }
97
98 /* Assign the buffer to a slot */
99 buffer_ring[buffer_pos] = buf;
100}
101
102/* Create a new temporary buffer on the ring. Libical owns these and
103 wil deallocate them. */
104void*
105icalmemory_tmp_buffer (size_t size)
106{
107 char *buf;
108
109 if (size < MIN_BUFFER_SIZE){
110 size = MIN_BUFFER_SIZE;
111 }
112
113 buf = (void*)malloc(size);
114
115 if( buf == 0){
116 icalerror_set_errno(ICAL_NEWFAILED_ERROR);
117 return 0;
118 }
119
120 memset(buf,0,size);
121
122 icalmemory_add_tmp_buffer(buf);
123
124 return buf;
125}
126
127void icalmemory_free_ring()
128{
129
130 int i;
131 for(i=0; i<BUFFER_RING_SIZE; i++){
132 if ( buffer_ring[i] != 0){
133 free( buffer_ring[i]);
134 }
135 buffer_ring[i] = 0;
136 }
137
138 initialized = 1;
139
140}
141
142
143
144/* Like strdup, but the buffer is on the ring. */
145char*
146icalmemory_tmp_copy(const char* str)
147{
148 char* b = icalmemory_tmp_buffer(strlen(str)+1);
149
150 strcpy(b,str);
151
152 return b;
153}
154
155
156char* icalmemory_strdup(const char *s)
157{
158 return strdup(s);
159}
160
161void
162icalmemory_free_tmp_buffer (void* buf)
163{
164 if(buf == 0)
165 {
166 return;
167 }
168
169 free(buf);
170}
171
172
173/* These buffer routines create memory the old fashioned way -- so the
174 caller will have to delocate the new memory */
175
176void* icalmemory_new_buffer(size_t size)
177{
178 void *b = malloc(size);
179
180 if( b == 0){
181 icalerror_set_errno(ICAL_NEWFAILED_ERROR);
182 return 0;
183 }
184
185 memset(b,0,size);
186
187 return b;
188}
189
190void* icalmemory_resize_buffer(void* buf, size_t size)
191{
192 void *b = realloc(buf, size);
193
194 if( b == 0){
195 icalerror_set_errno(ICAL_NEWFAILED_ERROR);
196 return 0;
197 }
198
199 return b;
200}
201
202void icalmemory_free_buffer(void* buf)
203{
204 free(buf);
205}
206
207void
208icalmemory_append_string(char** buf, char** pos, size_t* buf_size,
209 const char* string)
210{
211 char *new_buf;
212 char *new_pos;
213
214 size_t data_length, final_length, string_length;
215
216#ifndef ICAL_NO_INTERNAL_DEBUG
217 icalerror_check_arg_rv( (buf!=0),"buf");
218 icalerror_check_arg_rv( (*buf!=0),"*buf");
219 icalerror_check_arg_rv( (pos!=0),"pos");
220 icalerror_check_arg_rv( (*pos!=0),"*pos");
221 icalerror_check_arg_rv( (buf_size!=0),"buf_size");
222 icalerror_check_arg_rv( (*buf_size!=0),"*buf_size");
223 icalerror_check_arg_rv( (string!=0),"string");
224#endif
225
226 string_length = strlen(string);
227 data_length = (size_t)*pos - (size_t)*buf;
228 final_length = data_length + string_length;
229
230 if ( final_length >= (size_t) *buf_size) {
231
232
233 *buf_size = (*buf_size) * 2 + final_length;
234
235 new_buf = realloc(*buf,*buf_size);
236
237 new_pos = (void*)((size_t)new_buf + data_length);
238
239 *pos = new_pos;
240 *buf = new_buf;
241 }
242
243 strcpy(*pos, string);
244
245 *pos += string_length;
246}
247
248
249void
250icalmemory_append_char(char** buf, char** pos, size_t* buf_size,
251 char ch)
252{
253 char *new_buf;
254 char *new_pos;
255
256 size_t data_length, final_length;
257
258#ifndef ICAL_NO_INTERNAL_DEBUG
259 icalerror_check_arg_rv( (buf!=0),"buf");
260 icalerror_check_arg_rv( (*buf!=0),"*buf");
261 icalerror_check_arg_rv( (pos!=0),"pos");
262 icalerror_check_arg_rv( (*pos!=0),"*pos");
263 icalerror_check_arg_rv( (buf_size!=0),"buf_size");
264 icalerror_check_arg_rv( (*buf_size!=0),"*buf_size");
265#endif
266
267 data_length = (size_t)*pos - (size_t)*buf;
268
269 final_length = data_length + 2;
270
271 if ( final_length > (size_t) *buf_size ) {
272
273
274 *buf_size = (*buf_size) * 2 + final_length +1;
275
276 new_buf = realloc(*buf,*buf_size);
277
278 new_pos = (void*)((size_t)new_buf + data_length);
279
280 *pos = new_pos;
281 *buf = new_buf;
282 }
283
284 **pos = ch;
285 *pos += 1;
286 **pos = 0;
287}