/**********************************************************************
* hb_list implementation
**********************************************************************
* Basic and slow, but enough for what we need
*********************************************************************/
#define HB_LIST_DEFAULT_SIZE 20
struct hb_list_s
{
/* Pointers to items in the list */
void ** items;
/* How many (void *) allocated in 'items' */
int items_alloc;
/* How many valid pointers in 'items' */
int items_count;
};
/**********************************************************************
* hb_list_init
**********************************************************************
* Allocates an empty list ready for HB_LIST_DEFAULT_SIZE items
*********************************************************************/
hb_list_t * hb_list_init()
{
hb_list_t * l;
l = calloc( sizeof( hb_list_t ), 1 );
l->items = calloc( HB_LIST_DEFAULT_SIZE * sizeof( void * ), 1 );
l->items_alloc = HB_LIST_DEFAULT_SIZE;
return l;
}
/**********************************************************************
* hb_list_count
**********************************************************************
* Returns the number of items currently in the list
*********************************************************************/
int hb_list_count( hb_list_t * l )
{
return l->items_count;
}
/**********************************************************************
* hb_list_add
**********************************************************************
* Adds an item at the end of the list, making it bigger if necessary.
* Can safely be called with a NULL pointer to add, it will be ignored.
*********************************************************************/
void hb_list_add( hb_list_t * l, void * p )
{
if( !p )
{
return;
}
if( l->items_count == l->items_alloc )
{
/* We need a bigger boat */
l->items_alloc += HB_LIST_DEFAULT_SIZE;
l->items = realloc( l->items,
l->items_alloc * sizeof( void * ) );
}
l->items[l->items_count] = p;
(l->items_count)++;
}
/**********************************************************************
* hb_list_rem
**********************************************************************
* Remove an item from the list. Bad things will happen if called
* with a NULL pointer or if the item is not in the list.
*********************************************************************/
void hb_list_rem( hb_list_t * l, void * p )
{
int i;
/* Find the item in the list */
for( i = 0; i < l->items_count; i++ )
{
if( l->items[i] == p )
{
break;
}
}
/* Shift all items after it sizeof( void * ) bytes earlier */
memmove( &l->items[i], &l->items[i+1],
( l->items_count - i - 1 ) * sizeof( void * ) );
(l->items_count)--;
}
/**********************************************************************
* hb_list_item
**********************************************************************
* Returns item at position i, or NULL if there are not that many
* items in the list
*********************************************************************/
void * hb_list_item( hb_list_t * l, int i )
{
if( i < 0 || i >= l->items_count )
{
return NULL;
}
return l->items[i];
}
/**********************************************************************
* hb_list_bytes
**********************************************************************
* Assuming all items are of type hb_buffer_t, returns the total
* number of bytes in the list
*********************************************************************/
int hb_list_bytes( hb_list_t * l )
{
hb_buffer_t * buf;
int ret;
int i;
ret = 0;
for( i = 0; i < hb_list_count( l ); i++ )
{
buf = hb_list_item( l, i );
ret += buf->size - buf->cur;
}
return ret;
}
/**********************************************************************
* hb_list_seebytes
**********************************************************************
* Assuming all items are of type hb_buffer_t, copy bytes from
* the list to , keeping the list unmodified.
*********************************************************************/
void hb_list_seebytes( hb_list_t * l, uint8_t * dst, int size )
{
hb_buffer_t * buf;
int copied;
int copying;
int i;
for( i = 0, copied = 0; copied < size; i++ )
{
buf = hb_list_item( l, i );
copying = MIN( buf->size - buf->cur, size - copied );
memcpy( &dst[copied], &buf->data[buf->cur], copying );
copied += copying;
}
}
/**********************************************************************
* hb_list_getbytes
**********************************************************************
* Assuming all items are of type hb_buffer_t, copy
bytes from
* the list to . What's copied is removed from the list.
* The variable pointed by is set to the PTS of the buffer the
* first byte has been got from.
* The variable pointed by is set to the position of that byte
* in that buffer.
*********************************************************************/
void hb_list_getbytes( hb_list_t * l, uint8_t * dst, int size,
uint64_t * pts, uint64_t * pos )
{
hb_buffer_t * buf;
int copied;
int copying;
uint8_t has_pts;
/* So we won't have to deal with NULL pointers */
uint64_t dummy1, dummy2;
if( !pts ) pts = &dummy1;
if( !pos ) pos = &dummy2;
for( copied = 0, has_pts = 0; copied < size; )
{
buf = hb_list_item( l, 0 );
copying = MIN( buf->size - buf->cur, size - copied );
memcpy( &dst[copied], &buf->data[buf->cur], copying );
if( !has_pts )
{
*pts = buf->start;
*pos = buf->cur;
has_pts = 1;
}
buf->cur += copying;
if( buf->cur >= buf->size )
{
hb_list_rem( l, buf );
hb_buffer_close( &buf );
}
copied += copying;
}
}
/**********************************************************************
* hb_list_empty
**********************************************************************
* Assuming all items are of type hb_buffer_t, close them all and
* close the list.
*********************************************************************/
void hb_list_empty( hb_list_t ** _l )
{
hb_list_t * l = *_l;
hb_buffer_t * b;
while( ( b = hb_list_item( l, 0 ) ) )
{
hb_list_rem( l, b );
hb_buffer_close( &b );
}
hb_list_close( _l );
}
/**********************************************************************
* hb_list_close
**********************************************************************
* Free memory allocated by hb_list_init. Does NOT free contents of
* items still in the list.
*********************************************************************/
void hb_list_close( hb_list_t ** _l )
{
hb_list_t * l = *_l;
free( l->items );
free( l );
*_l = NULL;
}