contrib: Import gdkarrayimpl.c from GDK
We'll use this in the next patch to reimplement GcalEventList. Part-of: <https://gitlab.gnome.org/GNOME/gnome-calendar/-/merge_requests/757>
This commit is contained in:
@@ -0,0 +1,334 @@
|
|||||||
|
/*
|
||||||
|
* Copyright © 2020 Benjamin Otte
|
||||||
|
*
|
||||||
|
* This library is free software; you can redistribute it and/or
|
||||||
|
* modify it under the terms of the GNU Lesser General Public
|
||||||
|
* License as published by the Free Software Foundation; either
|
||||||
|
* version 2.1 of the License, or (at your option) any later version.
|
||||||
|
*
|
||||||
|
* This library is distributed in the hope that it will be useful,
|
||||||
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||||
|
* Lesser General Public License for more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU Lesser General Public
|
||||||
|
* License along with this library. If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
*
|
||||||
|
* Authors: Benjamin Otte <otte@gnome.org>
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include <glib.h>
|
||||||
|
|
||||||
|
G_BEGIN_DECLS
|
||||||
|
|
||||||
|
#ifndef GDK_ARRAY_TYPE_NAME
|
||||||
|
#define GDK_ARRAY_TYPE_NAME GdkArray
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifndef GDK_ARRAY_NAME
|
||||||
|
#define GDK_ARRAY_NAME gdk_array
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifndef GDK_ARRAY_ELEMENT_TYPE
|
||||||
|
#define GDK_ARRAY_ELEMENT_TYPE gpointer
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifdef GDK_ARRAY_PREALLOC
|
||||||
|
#if GDK_ARRAY_PREALLOC == 0
|
||||||
|
#undef GDK_ARRAY_PREALLOC
|
||||||
|
#endif
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifdef GDK_ARRAY_NULL_TERMINATED
|
||||||
|
#define GDK_ARRAY_REAL_SIZE(_size) ((_size) + 1)
|
||||||
|
#define GDK_ARRAY_MAX_SIZE (G_MAXSIZE / sizeof (_T_) - 1)
|
||||||
|
#else
|
||||||
|
#define GDK_ARRAY_REAL_SIZE(_size) (_size)
|
||||||
|
#define GDK_ARRAY_MAX_SIZE (G_MAXSIZE / sizeof (_T_))
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/* make this readable */
|
||||||
|
#define _T_ GDK_ARRAY_ELEMENT_TYPE
|
||||||
|
#define GdkArray GDK_ARRAY_TYPE_NAME
|
||||||
|
#define gdk_array_paste_more(GDK_ARRAY_NAME, func_name) GDK_ARRAY_NAME ## _ ## func_name
|
||||||
|
#define gdk_array_paste(GDK_ARRAY_NAME, func_name) gdk_array_paste_more (GDK_ARRAY_NAME, func_name)
|
||||||
|
#define gdk_array(func_name) gdk_array_paste (GDK_ARRAY_NAME, func_name)
|
||||||
|
|
||||||
|
typedef struct GdkArray GdkArray;
|
||||||
|
|
||||||
|
struct GdkArray
|
||||||
|
{
|
||||||
|
_T_ *start;
|
||||||
|
_T_ *end;
|
||||||
|
_T_ *end_allocation;
|
||||||
|
#ifdef GDK_ARRAY_PREALLOC
|
||||||
|
_T_ preallocated[GDK_ARRAY_REAL_SIZE(GDK_ARRAY_PREALLOC)];
|
||||||
|
#endif
|
||||||
|
};
|
||||||
|
|
||||||
|
/* no G_GNUC_UNUSED here, if you don't use an array type, remove it. */
|
||||||
|
static inline void
|
||||||
|
gdk_array(init) (GdkArray *self)
|
||||||
|
{
|
||||||
|
#ifdef GDK_ARRAY_PREALLOC
|
||||||
|
self->start = self->preallocated;
|
||||||
|
self->end = self->start;
|
||||||
|
self->end_allocation = self->start + GDK_ARRAY_PREALLOC;
|
||||||
|
#ifdef GDK_ARRAY_NULL_TERMINATED
|
||||||
|
*self->start = *(_T_[1]) { 0 };
|
||||||
|
#endif
|
||||||
|
#else
|
||||||
|
self->start = NULL;
|
||||||
|
self->end = NULL;
|
||||||
|
self->end_allocation = NULL;
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
|
G_GNUC_UNUSED static inline gsize
|
||||||
|
gdk_array(get_capacity) (const GdkArray *self)
|
||||||
|
{
|
||||||
|
return self->end_allocation - self->start;
|
||||||
|
}
|
||||||
|
|
||||||
|
G_GNUC_UNUSED static inline gsize
|
||||||
|
gdk_array(get_size) (const GdkArray *self)
|
||||||
|
{
|
||||||
|
return self->end - self->start;
|
||||||
|
}
|
||||||
|
|
||||||
|
static inline void
|
||||||
|
gdk_array(free_elements) (_T_ *start,
|
||||||
|
_T_ *end)
|
||||||
|
{
|
||||||
|
#ifdef GDK_ARRAY_FREE_FUNC
|
||||||
|
_T_ *e;
|
||||||
|
for (e = start; e < end; e++)
|
||||||
|
#ifdef GDK_ARRAY_BY_VALUE
|
||||||
|
GDK_ARRAY_FREE_FUNC (e);
|
||||||
|
#else
|
||||||
|
GDK_ARRAY_FREE_FUNC (*e);
|
||||||
|
#endif
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
|
/* no G_GNUC_UNUSED here */
|
||||||
|
static inline void
|
||||||
|
gdk_array(clear) (GdkArray *self)
|
||||||
|
{
|
||||||
|
gdk_array(free_elements) (self->start, self->end);
|
||||||
|
|
||||||
|
#ifdef GDK_ARRAY_PREALLOC
|
||||||
|
if (self->start != self->preallocated)
|
||||||
|
#endif
|
||||||
|
g_free_sized (self->start, gdk_array(get_capacity) (self) * sizeof (_T_));
|
||||||
|
gdk_array(init) (self);
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* gdk_array_steal:
|
||||||
|
* @self: the array
|
||||||
|
*
|
||||||
|
* Steals all data in the array and clears the array.
|
||||||
|
*
|
||||||
|
* If you need to know the size of the data, you should query it
|
||||||
|
* beforehand.
|
||||||
|
*
|
||||||
|
* Returns: The array's data
|
||||||
|
**/
|
||||||
|
G_GNUC_UNUSED static inline _T_ *
|
||||||
|
gdk_array(steal) (GdkArray *self)
|
||||||
|
{
|
||||||
|
_T_ *result;
|
||||||
|
|
||||||
|
#ifdef GDK_ARRAY_PREALLOC
|
||||||
|
if (self->start == self->preallocated)
|
||||||
|
{
|
||||||
|
gsize size = GDK_ARRAY_REAL_SIZE (gdk_array(get_size) (self));
|
||||||
|
result = g_new (_T_, size);
|
||||||
|
memcpy (result, self->preallocated, sizeof (_T_) * size);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
#endif
|
||||||
|
result = self->start;
|
||||||
|
|
||||||
|
gdk_array(init) (self);
|
||||||
|
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
G_GNUC_UNUSED static inline _T_ *
|
||||||
|
gdk_array(get_data) (const GdkArray *self)
|
||||||
|
{
|
||||||
|
return self->start;
|
||||||
|
}
|
||||||
|
|
||||||
|
G_GNUC_UNUSED static inline _T_ *
|
||||||
|
gdk_array(index) (const GdkArray *self,
|
||||||
|
gsize pos)
|
||||||
|
{
|
||||||
|
return self->start + pos;
|
||||||
|
}
|
||||||
|
|
||||||
|
G_GNUC_UNUSED static inline gboolean
|
||||||
|
gdk_array(is_empty) (const GdkArray *self)
|
||||||
|
{
|
||||||
|
return self->end == self->start;
|
||||||
|
}
|
||||||
|
|
||||||
|
G_GNUC_UNUSED static inline void
|
||||||
|
gdk_array(reserve) (GdkArray *self,
|
||||||
|
gsize n)
|
||||||
|
{
|
||||||
|
gsize new_capacity, size, capacity;
|
||||||
|
|
||||||
|
if (G_UNLIKELY (n > GDK_ARRAY_MAX_SIZE))
|
||||||
|
g_error ("requesting array size of %zu, but maximum size is %zu", n, GDK_ARRAY_MAX_SIZE);
|
||||||
|
|
||||||
|
capacity = gdk_array(get_capacity) (self);
|
||||||
|
if (n <= capacity)
|
||||||
|
return;
|
||||||
|
|
||||||
|
size = gdk_array(get_size) (self);
|
||||||
|
/* capacity * 2 can overflow, that's why we MAX() */
|
||||||
|
new_capacity = MAX (GDK_ARRAY_REAL_SIZE (n), capacity * 2);
|
||||||
|
|
||||||
|
#ifdef GDK_ARRAY_PREALLOC
|
||||||
|
if (self->start == self->preallocated)
|
||||||
|
{
|
||||||
|
self->start = g_new (_T_, new_capacity);
|
||||||
|
memcpy (self->start, self->preallocated, sizeof (_T_) * GDK_ARRAY_REAL_SIZE (size));
|
||||||
|
}
|
||||||
|
else
|
||||||
|
#endif
|
||||||
|
#ifdef GDK_ARRAY_NULL_TERMINATED
|
||||||
|
if (self->start == NULL)
|
||||||
|
{
|
||||||
|
self->start = g_new (_T_, new_capacity);
|
||||||
|
*self->start = *(_T_[1]) { 0 };
|
||||||
|
}
|
||||||
|
else
|
||||||
|
#endif
|
||||||
|
self->start = g_renew (_T_, self->start, new_capacity);
|
||||||
|
|
||||||
|
self->end = self->start + size;
|
||||||
|
self->end_allocation = self->start + new_capacity;
|
||||||
|
#ifdef GDK_ARRAY_NULL_TERMINATED
|
||||||
|
self->end_allocation--;
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
|
G_GNUC_UNUSED static inline void
|
||||||
|
gdk_array(splice) (GdkArray *self,
|
||||||
|
gsize pos,
|
||||||
|
gsize removed,
|
||||||
|
gboolean stolen,
|
||||||
|
#ifdef GDK_ARRAY_BY_VALUE
|
||||||
|
const _T_ *additions,
|
||||||
|
#else
|
||||||
|
_T_ *additions,
|
||||||
|
#endif
|
||||||
|
gsize added)
|
||||||
|
{
|
||||||
|
gsize size;
|
||||||
|
gsize remaining;
|
||||||
|
|
||||||
|
size = gdk_array(get_size) (self);
|
||||||
|
g_assert (pos + removed <= size);
|
||||||
|
remaining = size - pos - removed;
|
||||||
|
|
||||||
|
if (!stolen)
|
||||||
|
gdk_array(free_elements) (gdk_array(index) (self, pos),
|
||||||
|
gdk_array(index) (self, pos + removed));
|
||||||
|
|
||||||
|
gdk_array(reserve) (self, size - removed + added);
|
||||||
|
|
||||||
|
if (GDK_ARRAY_REAL_SIZE (remaining) && removed != added)
|
||||||
|
memmove (gdk_array(index) (self, pos + added),
|
||||||
|
gdk_array(index) (self, pos + removed),
|
||||||
|
GDK_ARRAY_REAL_SIZE (remaining) * sizeof (_T_));
|
||||||
|
|
||||||
|
if (added)
|
||||||
|
{
|
||||||
|
if (additions)
|
||||||
|
memcpy (gdk_array(index) (self, pos),
|
||||||
|
additions,
|
||||||
|
added * sizeof (_T_));
|
||||||
|
#ifndef GDK_ARRAY_NO_MEMSET
|
||||||
|
else
|
||||||
|
memset (gdk_array(index) (self, pos), 0, added * sizeof (_T_));
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/* might overflow, but does the right thing */
|
||||||
|
self->end += added - removed;
|
||||||
|
}
|
||||||
|
|
||||||
|
G_GNUC_UNUSED static void
|
||||||
|
gdk_array(set_size) (GdkArray *self,
|
||||||
|
gsize new_size)
|
||||||
|
{
|
||||||
|
gsize old_size = gdk_array(get_size) (self);
|
||||||
|
if (new_size > old_size)
|
||||||
|
gdk_array(splice) (self, old_size, 0, FALSE, NULL, new_size - old_size);
|
||||||
|
else
|
||||||
|
gdk_array(splice) (self, new_size, old_size - new_size, FALSE, NULL, 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
G_GNUC_UNUSED static void
|
||||||
|
gdk_array(append) (GdkArray *self,
|
||||||
|
#ifdef GDK_ARRAY_BY_VALUE
|
||||||
|
_T_ *value)
|
||||||
|
#else
|
||||||
|
_T_ value)
|
||||||
|
#endif
|
||||||
|
{
|
||||||
|
gdk_array(splice) (self,
|
||||||
|
gdk_array(get_size) (self),
|
||||||
|
0,
|
||||||
|
FALSE,
|
||||||
|
#ifdef GDK_ARRAY_BY_VALUE
|
||||||
|
value,
|
||||||
|
#else
|
||||||
|
&value,
|
||||||
|
#endif
|
||||||
|
1);
|
||||||
|
}
|
||||||
|
|
||||||
|
#ifdef GDK_ARRAY_BY_VALUE
|
||||||
|
G_GNUC_UNUSED static _T_ *
|
||||||
|
gdk_array(get) (const GdkArray *self,
|
||||||
|
gsize pos)
|
||||||
|
{
|
||||||
|
return gdk_array(index) (self, pos);
|
||||||
|
}
|
||||||
|
#else
|
||||||
|
G_GNUC_UNUSED static _T_
|
||||||
|
gdk_array(get) (const GdkArray *self,
|
||||||
|
gsize pos)
|
||||||
|
{
|
||||||
|
return *gdk_array(index) (self, pos);
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifndef GDK_ARRAY_NO_UNDEF
|
||||||
|
|
||||||
|
#undef _T_
|
||||||
|
#undef GdkArray
|
||||||
|
#undef gdk_array_paste_more
|
||||||
|
#undef gdk_array_paste
|
||||||
|
#undef gdk_array
|
||||||
|
#undef GDK_ARRAY_REAL_SIZE
|
||||||
|
#undef GDK_ARRAY_MAX_SIZE
|
||||||
|
|
||||||
|
#undef GDK_ARRAY_BY_VALUE
|
||||||
|
#undef GDK_ARRAY_ELEMENT_TYPE
|
||||||
|
#undef GDK_ARRAY_FREE_FUNC
|
||||||
|
#undef GDK_ARRAY_NAME
|
||||||
|
#undef GDK_ARRAY_NULL_TERMINATED
|
||||||
|
#undef GDK_ARRAY_PREALLOC
|
||||||
|
#undef GDK_ARRAY_TYPE_NAME
|
||||||
|
#undef GDK_ARRAY_NO_MEMSET
|
||||||
|
#endif
|
||||||
|
|
||||||
|
G_END_DECLS
|
||||||
@@ -0,0 +1 @@
|
|||||||
|
calendar_incs += include_directories('.')
|
||||||
@@ -59,6 +59,7 @@ calendar_incs = [
|
|||||||
|
|
||||||
sources = files()
|
sources = files()
|
||||||
subdir('appdata')
|
subdir('appdata')
|
||||||
|
subdir('contrib')
|
||||||
subdir('core')
|
subdir('core')
|
||||||
subdir('gui')
|
subdir('gui')
|
||||||
subdir('search')
|
subdir('search')
|
||||||
|
|||||||
Reference in New Issue
Block a user