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();
123 pthread_setspecific(ring_key, br);
135static buffer_ring *get_buffer_ring_global(
void)
137 if (global_buffer_ring == 0) {
138 global_buffer_ring = buffer_ring_new();
140 return (global_buffer_ring);
148static buffer_ring *get_buffer_ring(
void)
150#if ICAL_SYNC_MODE == ICAL_SYNC_MODE_PTHREAD
151 return (get_buffer_ring_pthread());
153 return get_buffer_ring_global();
160 buffer_ring *br = get_buffer_ring();
174 br->ring[br->pos] = buf;
197 memset(buf, 0, size);
208 br = get_buffer_ring();
213 icalmemory_free_ring_byval(br);
214#if ICAL_SYNC_MODE == ICAL_SYNC_MODE_PTHREAD
215 pthread_setspecific(ring_key, 0);
217 global_buffer_ring = 0;
226 if (!str || str[0] ==
'\0') {
230 const size_t len_b = strlen(str) + 1;
237 strncpy(b, str, len_b);
251 l = (strlen(s) + 1) *
sizeof(
char);
262#if defined(MEMORY_CONSISTENCY)
263static ICAL_GLOBAL_VAR icalmemory_malloc_f global_icalmem_malloc = &test_malloc;
264#elif defined(ICALMEMORY_DEFAULT_MALLOC) && !defined(S_SPLINT_S)
265static ICAL_GLOBAL_VAR icalmemory_malloc_f global_icalmem_malloc = &ICALMEMORY_DEFAULT_MALLOC;
267static ICAL_GLOBAL_VAR icalmemory_malloc_f global_icalmem_malloc = NULL;
270#if defined(MEMORY_CONSISTENCY)
271static ICAL_GLOBAL_VAR icalmemory_realloc_f global_icalmem_realloc = &test_realloc;
272#elif defined(ICALMEMORY_DEFAULT_REALLOC) && !defined(S_SPLINT_S)
273static ICAL_GLOBAL_VAR icalmemory_realloc_f global_icalmem_realloc = &ICALMEMORY_DEFAULT_REALLOC;
275static ICAL_GLOBAL_VAR icalmemory_realloc_f global_icalmem_realloc = NULL;
278#if defined(MEMORY_CONSISTENCY)
279static ICAL_GLOBAL_VAR icalmemory_free_f global_icalmem_free = &test_free;
280#elif defined(ICALMEMORY_DEFAULT_FREE) && !defined(S_SPLINT_S)
281static ICAL_GLOBAL_VAR icalmemory_free_f global_icalmem_free = &ICALMEMORY_DEFAULT_FREE;
283static ICAL_GLOBAL_VAR icalmemory_free_f global_icalmem_free = NULL;
287 icalmemory_realloc_f f_realloc,
288 icalmemory_free_f f_free)
290 global_icalmem_malloc = f_malloc;
291 global_icalmem_realloc = f_realloc;
292 global_icalmem_free = f_free;
296 icalmemory_realloc_f *f_realloc,
297 icalmemory_free_f *f_free)
300 *f_malloc = global_icalmem_malloc;
303 *f_realloc = global_icalmem_realloc;
306 *f_free = global_icalmem_free;
319 if (global_icalmem_malloc == NULL) {
324 b = global_icalmem_malloc(size);
340 if (global_icalmem_realloc == NULL) {
345 b = global_icalmem_realloc(buf, size);
357 if (global_icalmem_free == NULL) {
362 global_icalmem_free(buf);
370 size_t data_length, final_length, string_length;
372#if !defined(ICAL_NO_INTERNAL_DEBUG)
373 icalerror_check_arg_rv((buf != 0),
"buf");
374 icalerror_check_arg_rv((*buf != 0),
"*buf");
375 icalerror_check_arg_rv((pos != 0),
"pos");
376 icalerror_check_arg_rv((*pos != 0),
"*pos");
377 icalerror_check_arg_rv((buf_size != 0),
"buf_size");
378 icalerror_check_arg_rv((*buf_size != 0),
"*buf_size");
379 icalerror_check_arg_rv((
string != 0),
"string");
382 string_length = strlen(
string);
383 data_length = (size_t)*pos - (
size_t)*buf;
384 final_length = data_length + string_length;
386 if (final_length >= (
size_t)*buf_size) {
387 *buf_size = (*buf_size) * 2 + final_length;
395 new_pos = (
void *)((
size_t)new_buf + data_length);
401 strcpy(*pos,
string);
403 *pos += string_length;
411 size_t data_length, final_length;
413#if !defined(ICAL_NO_INTERNAL_DEBUG)
414 icalerror_check_arg_rv((buf != 0),
"buf");
415 icalerror_check_arg_rv((*buf != 0),
"*buf");
416 icalerror_check_arg_rv((pos != 0),
"pos");
417 icalerror_check_arg_rv((*pos != 0),
"*pos");
418 icalerror_check_arg_rv((buf_size != 0),
"buf_size");
419 icalerror_check_arg_rv((*buf_size != 0),
"*buf_size");
422 data_length = (size_t)*pos - (
size_t)*buf;
424 final_length = data_length + 2;
426 if (final_length > (
size_t)*buf_size) {
427 *buf_size = (*buf_size) * 2 + final_length + 1;
435 new_pos = (
void *)((
size_t)new_buf + data_length);
461#define UNSAFE_CHARS ";:,"
464static bool icalmemory_is_safe_char(
unsigned char character,
bool quoted)
466 if (character ==
' ' || character ==
'\t' || character ==
'!') {
470 if (character < 0x23 || character == 0x7f || character > 0xf8 ||
471 (!quoted && strchr(UNSAFE_CHARS, character))) {
479 size_t *buf_size,
const char *
string)
485 if (!*
string || strpbrk(
string, UNSAFE_CHARS) != 0) {
491 for (p =
string; *p; p++) {
507 if (icalmemory_is_safe_char((
unsigned char)*p, quoted)) {
516 if (quoted ==
true) {
522 size_t *buf_size,
const char *
string)
527 for (p =
string; *p; p++) {
538 }
else if (p[1] ==
'^') {
541 }
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.