xwords/xwords4/common/xwlist.c
Eric House c4312a2158 new files that may replace GSList in relaycon
If I want to move relaycon into common so Android can use it (assuming
the jni code starts including json-c and libcurl so it can handle
networking) I'll need a replacement for GSList. This is a start.
2017-11-04 09:27:33 -07:00

127 lines
3.2 KiB
C

/* -*-mode: C; fill-column: 78; c-basic-offset: 4; -*- */
/*
* Copyright 2009 by Eric House (xwords@eehouse.org). All rights reserved.
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
* as published by the Free Software Foundation; either version 2
* of the License, or (at your option) any later version.
*
* This program 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 General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
*/
#include "xwlist.h"
#define MAX_HERE 16
typedef struct XWList {
XP_U16 len;
XP_U16 size;
elem* list;
MPSLOT
} XWList;
XWList*
mk_list(MPFORMAL XP_U16 XP_UNUSED(sizeHint))
{
XWList* list = XP_CALLOC( mpool, sizeof(*list));
MPASSIGN( list->mpool, mpool);
return list;
}
void
list_append( XWList* self, elem one )
{
if ( self->size == 0 ) { /* initial case */
self->size = 2;
self->list = XP_MALLOC( self->mpool, self->size * sizeof(self->list[0]) );
}
if ( self->len == self->size ) { /* need to grow? */
self->size *= 2;
self->list = XP_REALLOC( self->mpool, self->list, self->size * sizeof(self->list[0]) );
}
self->list[self->len++] = one;
XP_LOGF( "%s(): put %p at position %d (size: %d)", __func__, one, self->len-1, self->size );
}
XP_U16
list_get_len( const XWList* list )
{
return list->len;
}
void
list_remove_front( XWList* self, elem* out, XP_U16* countp )
{
const XP_U16 nMoved = XP_MIN( *countp, self->len );
XP_MEMCPY( out, self->list, nMoved * sizeof(out[0]) );
*countp = nMoved;
// Now copy the survivors down
self->len -= nMoved;
XP_MEMMOVE( &self->list[0], &self->list[nMoved], self->len * sizeof(self->list[0]));
}
void
list_remove_back(XWList* XP_UNUSED(self), elem* XP_UNUSED(here), XP_U16* XP_UNUSED(count))
{
}
void
list_free( XWList* self, destructor proc, void* closure )
{
if ( !!proc ) {
for ( XP_U16 ii = 0; ii < self->len; ++ii ) {
(*proc)(self->list[ii], closure);
}
}
if ( !!self->list ) {
XP_FREE( self->mpool, self->list );
}
XP_FREE( self->mpool, self );
}
#ifdef DEBUG
static void
dest(elem elem, void* XP_UNUSED(closure))
{
XP_LOGF( "%s(%p)", __func__, elem);
}
void
list_test_lists(MPFORMAL_NOCOMMA)
{
XWList* list = mk_list( mpool, 16 );
for ( char* ii = 0; ii < (char*)100; ++ii ) {
(void)list_append( list, ii );
}
XP_ASSERT( list_get_len(list) == 100 );
char* prev = 0;
while ( 0 < list_get_len( list ) ) {
elem here;
XP_U16 count = 1;
list_remove_front( list, &here, &count );
XP_LOGF( "%s(): got here: %p", __func__, here );
XP_ASSERT( count == 1 );
XP_ASSERT( prev++ == here );
}
for ( char* ii = 0; ii < (char*)10; ++ii ) {
(void)list_append( list, ii );
}
list_free( list, dest, NULL );
}
#endif