19#include "icalerror_p.h"
20#if defined(MEMORY_CONSISTENCY)
21#include "test-malloc.h"
31#define BUFFER_RING_SIZE 2500
37#define MIN_BUFFER_SIZE 200
47#if ICAL_SYNC_MODE != ICAL_SYNC_MODE_PTHREAD
51static ICAL_GLOBAL_VAR buffer_ring *global_buffer_ring = 0;
59static void icalmemory_free_ring_byval(buffer_ring *br)
69#if ICAL_SYNC_MODE == ICAL_SYNC_MODE_PTHREAD
72static pthread_key_t ring_key;
73static pthread_once_t ring_key_once = PTHREAD_ONCE_INIT;
75static void ring_destroy(
void *buf)
77 icalmemory_free_ring_byval((buffer_ring *)buf);
78 pthread_setspecific(ring_key, NULL);
81static void ring_key_alloc(
void)
83 pthread_key_create(&ring_key, ring_destroy);
91static buffer_ring *buffer_ring_new(
void)
108#if ICAL_SYNC_MODE == ICAL_SYNC_MODE_PTHREAD
112static buffer_ring *get_buffer_ring_pthread(
void)
116 pthread_once(&ring_key_once, ring_key_alloc);
118 br = pthread_getspecific(ring_key);
121 br = buffer_ring_new();
122 pthread_setspecific(ring_key, br);
133static buffer_ring *get_buffer_ring_global(
void)
135 if (global_buffer_ring == 0) {
136 global_buffer_ring = buffer_ring_new();
138 return (global_buffer_ring);
146static buffer_ring *get_buffer_ring(
void)
148#if ICAL_SYNC_MODE == ICAL_SYNC_MODE_PTHREAD
149 return (get_buffer_ring_pthread());
151 return get_buffer_ring_global();
158 buffer_ring *br = get_buffer_ring();
172 br->ring[br->pos] = buf;
195 memset(buf, 0, size);
206 br = get_buffer_ring();
211 icalmemory_free_ring_byval(br);
212#if ICAL_SYNC_MODE == ICAL_SYNC_MODE_PTHREAD
213 pthread_setspecific(ring_key, 0);
215 global_buffer_ring = 0;
224 if (!str || str[0] ==
'\0') {
228 const size_t len_b = strlen(str) + 1;
235 strncpy(b, str, len_b);
249 l = (strlen(s) + 1) *
sizeof(
char);
260#if defined(MEMORY_CONSISTENCY)
261static ICAL_GLOBAL_VAR icalmemory_malloc_f global_icalmem_malloc = &test_malloc;
262#elif defined(ICALMEMORY_DEFAULT_MALLOC) && !defined(S_SPLINT_S)
263static ICAL_GLOBAL_VAR icalmemory_malloc_f global_icalmem_malloc = &ICALMEMORY_DEFAULT_MALLOC;
265static ICAL_GLOBAL_VAR icalmemory_malloc_f global_icalmem_malloc = NULL;
268#if defined(MEMORY_CONSISTENCY)
269static ICAL_GLOBAL_VAR icalmemory_realloc_f global_icalmem_realloc = &test_realloc;
270#elif defined(ICALMEMORY_DEFAULT_REALLOC) && !defined(S_SPLINT_S)
271static ICAL_GLOBAL_VAR icalmemory_realloc_f global_icalmem_realloc = &ICALMEMORY_DEFAULT_REALLOC;
273static ICAL_GLOBAL_VAR icalmemory_realloc_f global_icalmem_realloc = NULL;
276#if defined(MEMORY_CONSISTENCY)
277static ICAL_GLOBAL_VAR icalmemory_free_f global_icalmem_free = &test_free;
278#elif defined(ICALMEMORY_DEFAULT_FREE) && !defined(S_SPLINT_S)
279static ICAL_GLOBAL_VAR icalmemory_free_f global_icalmem_free = &ICALMEMORY_DEFAULT_FREE;
281static ICAL_GLOBAL_VAR icalmemory_free_f global_icalmem_free = NULL;
285 icalmemory_realloc_f f_realloc,
286 icalmemory_free_f f_free)
288 global_icalmem_malloc = f_malloc;
289 global_icalmem_realloc = f_realloc;
290 global_icalmem_free = f_free;
294 icalmemory_realloc_f *f_realloc,
295 icalmemory_free_f *f_free)
298 *f_malloc = global_icalmem_malloc;
301 *f_realloc = global_icalmem_realloc;
304 *f_free = global_icalmem_free;
317 if (global_icalmem_malloc == NULL) {
322 b = global_icalmem_malloc(size);
338 if (global_icalmem_realloc == NULL) {
343 b = global_icalmem_realloc(buf, size);
355 if (global_icalmem_free == NULL) {
360 global_icalmem_free(buf);
368 size_t data_length, final_length, string_length;
370#if !defined(ICAL_NO_INTERNAL_DEBUG)
371 icalerror_check_arg_rv((buf != 0),
"buf");
372 icalerror_check_arg_rv((*buf != 0),
"*buf");
373 icalerror_check_arg_rv((pos != 0),
"pos");
374 icalerror_check_arg_rv((*pos != 0),
"*pos");
375 icalerror_check_arg_rv((buf_size != 0),
"buf_size");
376 icalerror_check_arg_rv((*buf_size != 0),
"*buf_size");
377 icalerror_check_arg_rv((
string != 0),
"string");
380 string_length = strlen(
string);
381 data_length = (size_t)*pos - (
size_t)*buf;
382 final_length = data_length + string_length;
384 if (final_length >= (
size_t)*buf_size) {
385 *buf_size = (*buf_size) * 2 + final_length;
393 new_pos = (
void *)((
size_t)new_buf + data_length);
399 strcpy(*pos,
string);
401 *pos += string_length;
409 size_t data_length, final_length;
411#if !defined(ICAL_NO_INTERNAL_DEBUG)
412 icalerror_check_arg_rv((buf != 0),
"buf");
413 icalerror_check_arg_rv((*buf != 0),
"*buf");
414 icalerror_check_arg_rv((pos != 0),
"pos");
415 icalerror_check_arg_rv((*pos != 0),
"*pos");
416 icalerror_check_arg_rv((buf_size != 0),
"buf_size");
417 icalerror_check_arg_rv((*buf_size != 0),
"*buf_size");
420 data_length = (size_t)*pos - (
size_t)*buf;
422 final_length = data_length + 2;
424 if (final_length > (
size_t)*buf_size) {
425 *buf_size = (*buf_size) * 2 + final_length + 1;
433 new_pos = (
void *)((
size_t)new_buf + data_length);
459#define UNSAFE_CHARS ";:,"
462static bool icalmemory_is_safe_char(
unsigned char character,
bool quoted)
464 if (character ==
' ' || character ==
'\t' || character ==
'!') {
468 if (character < 0x23 || character == 0x7f || character > 0xf8 ||
469 (!quoted && strchr(UNSAFE_CHARS, character))) {
477 size_t *buf_size,
const char *
string)
483 if (!*
string || strpbrk(
string, UNSAFE_CHARS) != 0) {
489 for (p =
string; *p; p++) {
505 if (icalmemory_is_safe_char((
unsigned char)*p, quoted)) {
514 if (quoted ==
true) {
520 size_t *buf_size,
const char *
string)
525 for (p =
string; *p; p++) {
536 }
else if (p[1] ==
'^') {
539 }
else if (p[1] ==
'\'') {
void icalerror_set_errno(icalerrorenum x)
Sets the icalerrno to a given error.
#define MIN_BUFFER_SIZE
Determines the minimal size of buffers in the ring that are created with icalmemory_tmp_buffer().
void icalmemory_free_ring(void)
Frees all memory used in the ring.
void icalmemory_free_buffer(void *buf)
Releases a buffer.
char * icalmemory_strdup(const char *s)
Creates a duplicate of a string.
void icalmemory_append_decoded_string(char **buf, char **pos, size_t *buf_size, const char *string)
void icalmemory_append_string(char **buf, char **pos, size_t *buf_size, const char *string)
Appends a string to a buffer.
void * icalmemory_resize_buffer(void *buf, size_t size)
Resizes a buffer created with icalmemory_new_buffer().
void * icalmemory_new_buffer(size_t size)
Creates new buffer with the specified size.
char * icalmemory_tmp_copy(const char *str)
Creates a copy of the given string, stored on the ring buffer, and returns it.
void icalmemory_append_encoded_string(char **buf, char **pos, size_t *buf_size, const char *string)
void icalmemory_append_char(char **buf, char **pos, size_t *buf_size, char ch)
Appends a character to a buffer.
void icalmemory_get_mem_alloc_funcs(icalmemory_malloc_f *f_malloc, icalmemory_realloc_f *f_realloc, icalmemory_free_f *f_free)
Returns the functions used for memory management.
void icalmemory_add_tmp_buffer(void *buf)
Adds an externally allocated buffer to the ring.
void icalmemory_set_mem_alloc_funcs(icalmemory_malloc_f f_malloc, icalmemory_realloc_f f_realloc, icalmemory_free_f f_free)
Configures the functions to use for memory management.
void * icalmemory_tmp_buffer(size_t size)
Creates a new temporary buffer on the ring and returns it.
#define BUFFER_RING_SIZE
Determines the size of the ring buffer used for keeping track of temporary buffers.
Common memory management routines.