1
0
Fork 0
mirror of https://github.com/transmission/transmission synced 2024-12-26 09:37:56 +00:00
transmission/libtransmission/ptrarray.c
Jordan Lee 879a2afcbd Update the copyright year in the source code comments.
The Berne Convention says that the copyright year is moot, so instead of adding another year to each file as in previous years, I've removed the year altogether from the source code comments in libtransmission, gtk, qt, utils, daemon, and cli.

Juliusz's copyright notice in tr-dht and Johannes' copyright notice in tr-lpd have been left alone; it didn't seem appropriate to modify them.
2011-01-19 13:48:47 +00:00

218 lines
4.7 KiB
C

/*
* This file Copyright (C) Mnemosyne LLC
*
* This file is licensed by the GPL version 2. Works owned by the
* Transmission project are granted a special exemption to clause 2(b)
* so that the bulk of its code can remain under the MIT license.
* This exemption does not extend to derived works not owned by
* the Transmission project.
*
* $Id$
*/
#include <assert.h>
#include <stdlib.h>
#include <string.h> /* memmove */
#include "ptrarray.h"
#include "utils.h"
#define FLOOR 32
const tr_ptrArray TR_PTR_ARRAY_INIT = { NULL, 0, 0 };
void
tr_ptrArrayDestruct( tr_ptrArray * p, PtrArrayForeachFunc func )
{
assert( p );
assert( p->items || !p->n_items );
if( func )
tr_ptrArrayForeach( p, func );
tr_free( p->items );
memset( p, ~0, sizeof( tr_ptrArray ) );
}
void
tr_ptrArrayForeach( tr_ptrArray * t,
PtrArrayForeachFunc func )
{
int i;
assert( t );
assert( t->items || !t->n_items );
assert( func );
for( i = 0; i < t->n_items; ++i )
func( t->items[i] );
}
void**
tr_ptrArrayPeek( tr_ptrArray * t,
int * size )
{
*size = t->n_items;
return t->items;
}
void*
tr_ptrArrayNth( tr_ptrArray* t,
int i )
{
assert( t );
assert( i >= 0 );
assert( i < t->n_items );
return t->items[i];
}
int
tr_ptrArrayInsert( tr_ptrArray * t,
void * ptr,
int pos )
{
if( t->n_items >= t->n_alloc )
{
t->n_alloc = MAX( FLOOR, t->n_alloc * 2 );
t->items = tr_renew( void*, t->items, t->n_alloc );
}
if( pos < 0 || pos > t->n_items )
pos = t->n_items;
else
memmove( t->items + pos + 1,
t->items + pos,
sizeof( void* ) * ( t->n_items - pos ) );
t->items[pos] = ptr;
t->n_items++;
return pos;
}
void*
tr_ptrArrayPop( tr_ptrArray* t )
{
void * ret = NULL;
if( t->n_items )
ret = t->items[--t->n_items];
return ret;
}
void
tr_ptrArrayErase( tr_ptrArray * t,
int begin,
int end )
{
assert( begin >= 0 );
if( end < 0 ) end = t->n_items;
assert( begin < end );
assert( end <= t->n_items );
memmove( t->items + begin,
t->items + end,
sizeof( void* ) * ( t->n_items - end ) );
t->n_items -= ( end - begin );
}
/**
***
**/
int
tr_ptrArrayLowerBound( const tr_ptrArray * t,
const void * ptr,
int compare( const void *,
const void * ),
tr_bool * exact_match )
{
int len = t->n_items;
int first = 0;
while( len > 0 )
{
int half = len / 2;
int middle = first + half;
const int c = compare( t->items[middle], ptr );
if( c < 0 )
{
first = middle + 1;
len = len - half - 1;
}
else if( !c )
{
if( exact_match )
*exact_match = TRUE;
return middle;
break;
}
else
{
len = half;
}
}
if( exact_match )
*exact_match = FALSE;
return first;
}
#ifdef NDEBUG
#define assertSortedAndUnique(a,b)
#else
static void
assertSortedAndUnique( const tr_ptrArray * t,
int compare(const void*, const void*) )
{
int i;
for( i = 0; i < t->n_items - 2; ++i )
assert( compare( t->items[i], t->items[i + 1] ) <= 0 );
}
#endif
int
tr_ptrArrayInsertSorted( tr_ptrArray * t,
void * ptr,
int compare(const void*, const void*) )
{
const int pos = tr_ptrArrayLowerBound( t, ptr, compare, NULL );
const int ret = tr_ptrArrayInsert( t, ptr, pos );
//assertSortedAndUnique( t, compare );
return ret;
}
void*
tr_ptrArrayFindSorted( tr_ptrArray * t,
const void * ptr,
int compare(const void*, const void*) )
{
tr_bool match;
const int pos = tr_ptrArrayLowerBound( t, ptr, compare, &match );
return match ? t->items[pos] : NULL;
}
void*
tr_ptrArrayRemoveSorted( tr_ptrArray * t,
const void * ptr,
int compare(const void*, const void*) )
{
void * ret = NULL;
tr_bool match;
const int pos = tr_ptrArrayLowerBound( t, ptr, compare, &match );
if( match )
{
ret = t->items[pos];
tr_ptrArrayErase( t, pos, pos + 1 );
}
assertSortedAndUnique( t, compare );
return ret;
}