From 9960f299ac3476d6d4c0d25d95a5891f6eab15dd Mon Sep 17 00:00:00 2001 From: Andrea Canciani Date: Wed, 24 Nov 2010 12:07:51 +0100 Subject: [PATCH] array: Add read-only accessor It is sometimes useful to read the elements of a const cairo_array_t, but it is currently only possible by ignoring the const qualifier. The _cairo_array_index_const function allows read-only access to the array elements. This is needed to enable accessing const cairo_array_t's without having to manually remove the const qualifier (which happens in the to-be-merged mesh pattern code, for example). --- src/cairo-array.c | 51 ++++++++++++++++++++++++++++++++++++++++++----- src/cairoint.h | 3 +++ 2 files changed, 49 insertions(+), 5 deletions(-) diff --git a/src/cairo-array.c b/src/cairo-array.c index 44ea3bd95..fde5d73e7 100644 --- a/src/cairo-array.c +++ b/src/cairo-array.c @@ -182,6 +182,50 @@ _cairo_array_index (cairo_array_t *array, unsigned int index) return array->elements + index * array->element_size; } +/** + * _cairo_array_index_const: + * @array: a #cairo_array_t + * Returns: A pointer to the object stored at @index. + * + * If the resulting value is assigned to a pointer to an object of the same + * element_size as initially passed to _cairo_array_init() then that + * pointer may be used for further direct indexing with []. For + * example: + * + * + * cairo_array_t array; + * const double *values; + * + * _cairo_array_init (&array, sizeof(double)); + * ... calls to _cairo_array_append() here ... + * + * values = _cairo_array_index_const (&array, 0); + * for (i = 0; i < _cairo_array_num_elements (&array); i++) + * ... read values[i] here ... + * + **/ +const void * +_cairo_array_index_const (const cairo_array_t *array, unsigned int index) +{ + /* We allow an index of 0 for the no-elements case. + * This makes for cleaner calling code which will often look like: + * + * elements = _cairo_array_index_const (array, num_elements); + * for (i=0; i < num_elements; i++) { + * ... read elements[i] here ... + * } + * + * which in the num_elements==0 case gets the NULL pointer here, + * but never dereferences it. + */ + if (index == 0 && array->num_elements == 0) + return NULL; + + assert (index < array->num_elements); + + return array->elements + index * array->element_size; +} + /** * _cairo_array_copy_element: * @array: a #cairo_array_t @@ -192,7 +236,7 @@ _cairo_array_index (cairo_array_t *array, unsigned int index) void _cairo_array_copy_element (cairo_array_t *array, int index, void *dst) { - memcpy (dst, _cairo_array_index (array, index), array->element_size); + memcpy (dst, _cairo_array_index_const (array, index), array->element_size); } /** @@ -454,11 +498,8 @@ _cairo_user_data_array_copy (cairo_user_data_array_t *dst, _cairo_user_data_array_init (dst); } - if (src->num_elements == 0) - return CAIRO_STATUS_SUCCESS; - return _cairo_array_append_multiple (dst, - _cairo_array_index (src, 0), + _cairo_array_index_const (src, 0), src->num_elements); } diff --git a/src/cairoint.h b/src/cairoint.h index 030c265e9..85e98566f 100644 --- a/src/cairoint.h +++ b/src/cairoint.h @@ -328,6 +328,9 @@ _cairo_array_allocate (cairo_array_t *array, cairo_private void * _cairo_array_index (cairo_array_t *array, unsigned int index); +cairo_private const void * +_cairo_array_index_const (const cairo_array_t *array, unsigned int index); + cairo_private void _cairo_array_copy_element (cairo_array_t *array, int index, void *dst);