Skip to content

Commit

Permalink
access: refactor pf_readdir
Browse files Browse the repository at this point in the history
The main advantage is to move the management of the input_item_node_t from all
accesses to the directory demux.
  • Loading branch information
tguillem committed May 20, 2015
1 parent 5fe3389 commit 88ffe15
Show file tree
Hide file tree
Showing 13 changed files with 212 additions and 199 deletions.
6 changes: 5 additions & 1 deletion include/vlc_access.h
Original file line number Diff line number Diff line change
Expand Up @@ -92,7 +92,11 @@ struct access_t
* XXX A access should set one and only one of them */
ssize_t (*pf_read) ( access_t *, uint8_t *, size_t ); /* Return -1 if no data yet, 0 if no more data, else real data read */
block_t *(*pf_block) ( access_t * ); /* Return a block of data in his 'natural' size, NULL if not yet data or eof */
int (*pf_readdir)( access_t *, input_item_node_t * );/* Fills the provided item_node, see doc/browsing.txt for details */

/* pf_readdir: Read the next input_item_t from the directory stream. It
* returns the next input item on success or NULL in case of error or end
* of stream. The item must be released with input_item_Release. */
input_item_t *(*pf_readdir)( access_t * );

/* Called for each seek.
* XXX can be null */
Expand Down
6 changes: 3 additions & 3 deletions include/vlc_stream.h
Original file line number Diff line number Diff line change
Expand Up @@ -67,7 +67,7 @@ struct stream_t
/* */
int (*pf_read) ( stream_t *, void *p_read, unsigned int i_read );
int (*pf_peek) ( stream_t *, const uint8_t **pp_peek, unsigned int i_peek );
int (*pf_readdir)( stream_t *, input_item_node_t * );
input_item_t *(*pf_readdir)( stream_t * );
int (*pf_control)( stream_t *, int i_query, va_list );

/* */
Expand Down Expand Up @@ -134,7 +134,7 @@ VLC_API int stream_Control( stream_t *s, int i_query, ... );
VLC_API block_t * stream_Block( stream_t *s, int i_size );
VLC_API block_t * stream_BlockRemaining( stream_t *s, int i_max_size );
VLC_API char * stream_ReadLine( stream_t * );
VLC_API int stream_ReadDir( stream_t *, input_item_node_t * );
VLC_API input_item_t *stream_ReadDir( stream_t * );

/**
* Get the current position in a stream
Expand Down Expand Up @@ -230,7 +230,7 @@ VLC_API stream_t* stream_FilterNew( stream_t *p_source, const char *psz_stream_f
* Default ReadDir implementation for stream Filter. This implementation just
* forward the pf_readdir call to the p_source stream.
*/
VLC_API int stream_FilterDefaultReadDir( stream_t *s, input_item_node_t *p_node );
VLC_API input_item_t *stream_FilterDefaultReadDir( stream_t *s );

/**
* Sets stream_FilterDefaultReadDir as the pf_readdir callback for this stream filter
Expand Down
19 changes: 7 additions & 12 deletions modules/access/archive/stream.c
Original file line number Diff line number Diff line change
Expand Up @@ -132,39 +132,34 @@ static ssize_t SeekCallback(struct archive *p_archive, void *p_object, ssize_t i
return stream_Tell(p_stream->p_source);
}

static int Browse(stream_t *p_stream, input_item_node_t *p_node)
static input_item_t *Browse(stream_t *p_stream)
{
stream_sys_t *p_sys = p_stream->p_sys;
struct archive_entry *p_entry;
input_item_t *p_item = NULL;

while(archive_read_next_header(p_sys->p_archive, &p_entry) == ARCHIVE_OK)
if (archive_read_next_header(p_sys->p_archive, &p_entry) == ARCHIVE_OK)
{
char *psz_uri = NULL;
char *psz_access_uri = NULL;
int i_ret = asprintf(&psz_access_uri, "%s://%s%c%s", p_stream->psz_access,
p_stream->psz_path, ARCHIVE_SEP_CHAR, archive_entry_pathname(p_entry));
if (i_ret == -1)
goto error;
return NULL;
i_ret = asprintf(&psz_uri, "archive://%s", psz_access_uri);
free(psz_access_uri);
if( i_ret == -1 )
goto error;
return NULL;

input_item_t *p_item = input_item_New(psz_uri, archive_entry_pathname(p_entry));
free( psz_uri );
if(p_item == NULL)
goto error;
return NULL;

input_item_CopyOptions(p_node->p_item, p_item);
input_item_node_AppendItem(p_node, p_item);
msg_Dbg(p_stream, "declaring playlist entry %s", archive_entry_pathname(p_entry));
input_item_Release(p_item);
}

return VLC_SUCCESS;

error:
return VLC_ENOITEM;
return p_item;
}

int StreamOpen(vlc_object_t *p_object)
Expand Down
28 changes: 7 additions & 21 deletions modules/access/directory.c
Original file line number Diff line number Diff line change
Expand Up @@ -353,27 +353,19 @@ void DirClose( vlc_object_t * p_this )
/* This function is a little bit too complex for what it seems to do, but the
* point is to de-recursify directory recusion to avoid overruning the stack
* in case there's a high directory depth */
int DirRead (access_t *p_access, input_item_node_t *p_current_node)
input_item_t* DirRead (access_t *p_access)
{
access_sys_t *p_sys = p_access->p_sys;
input_item_t *p_item = NULL;

while (p_sys->current != NULL
while (!p_item && p_sys->current != NULL
&& p_sys->current->i <= p_sys->current->filec)
{
directory *p_current = p_sys->current;

/* End of the current folder, let's pop directory and node */
if (p_current->i == p_current->filec)
{
directory_pop (p_sys);
p_current_node = p_current_node->p_parent;
continue;
}

char *psz_entry = p_current->filev[p_current->i++];
char *psz_full_uri, *psz_uri;
DIR *handle;
input_item_t *p_new = NULL;
int i_res;

/* Check if it is a directory or even readable */
Expand All @@ -383,7 +375,6 @@ int DirRead (access_t *p_access, input_item_node_t *p_current_node)
|| (i_res == ENTRY_ENOTDIR && has_ext (p_sys->ignored_exts, psz_entry)))
continue;


/* Create an input item for the current entry */
psz_uri = encode_URI_component (psz_entry);
if (psz_uri == NULL
Expand All @@ -398,21 +389,16 @@ int DirRead (access_t *p_access, input_item_node_t *p_current_node)
}

int i_type = i_res == ENTRY_DIR ? ITEM_TYPE_DIRECTORY : ITEM_TYPE_FILE;
p_new = input_item_NewWithType (psz_full_uri, psz_entry,
0, NULL, 0, 0, i_type);
if (p_new == NULL)
p_item = input_item_NewWithType (psz_full_uri, psz_entry,
0, NULL, 0, 0, i_type);
if (p_item == NULL)
{
free (psz_full_uri);
closedir (handle);
continue;
}

input_item_CopyOptions (p_current_node->p_item, p_new);
input_item_node_AppendItem (p_current_node, p_new);

free (psz_full_uri);
input_item_Release (p_new);
}

return VLC_SUCCESS;
return p_item;
}
131 changes: 61 additions & 70 deletions modules/access/dsm/access.c
Original file line number Diff line number Diff line change
Expand Up @@ -107,8 +107,7 @@ static void login_dialog( access_t *p_access );
static int login( access_t *p_access );
static void backslash_path( vlc_url_t *p_url );
static bool get_path( access_t *p_access );
static int add_item( access_t *p_access, input_item_node_t *p_node,
const char *psz_name, int i_type );
static input_item_t* new_item( access_t *p_access, const char *psz_name, int i_type );

struct access_sys_t
{
Expand All @@ -126,6 +125,11 @@ struct access_sys_t
smb_fd i_fd; /**< SMB fd for the file we're reading */
smb_tid i_tid; /**< SMB Tree ID we're connected to */
bool b_is_browsing;

size_t i_browse_count;
size_t i_browse_idx;
smb_share_list shares;
smb_stat_list files;
};

/*****************************************************************************
Expand Down Expand Up @@ -240,6 +244,10 @@ static void Close( vlc_object_t *p_this )
if( p_sys->p_session )
smb_session_destroy( p_sys->p_session );
vlc_UrlClean( &p_sys->url );
if( p_sys->shares )
smb_share_list_destroy( p_sys->shares );
if( p_sys->files )
smb_stat_list_destroy( p_sys->files );
free( p_sys->creds.login );
free( p_sys->creds.password );
free( p_sys->creds.domain );
Expand Down Expand Up @@ -559,137 +567,120 @@ static int Control( access_t *p_access, int i_query, va_list args )
return VLC_SUCCESS;
}

static int add_item( access_t *p_access, input_item_node_t *p_node,
const char *psz_name, int i_type )
static input_item_t *new_item( access_t *p_access, const char *psz_name,
int i_type )
{
access_sys_t *p_sys = p_access->p_sys;
input_item_t *p_item;
char *psz_uri, *psz_option;
char *psz_uri, *psz_option = NULL;
int i_ret;

i_ret = asprintf( &psz_uri, "%s/%s", p_node->p_item->psz_uri, psz_name );
i_ret = asprintf( &psz_uri, "smb://%s/%s", p_access->psz_location, psz_name );
if( i_ret == -1 )
return VLC_ENOMEM;
return NULL;

p_item = input_item_NewWithTypeExt( psz_uri, psz_name, 0, NULL, 0, -1,
i_type, 1 );
free( psz_uri );
if( p_item == NULL )
return VLC_ENOMEM;
return NULL;

/* Here we save on the node the credentials that allowed us to login.
* That way the user isn't prompted more than once for credentials */
i_ret = asprintf( &psz_option, "smb-user=%s", p_sys->creds.login );
if( i_ret == -1 )
return VLC_ENOMEM;
goto bailout;
input_item_AddOption( p_item, psz_option, VLC_INPUT_OPTION_TRUSTED );
free( psz_option );

i_ret = asprintf( &psz_option, "smb-pwd=%s", p_sys->creds.password );
if( i_ret == -1 )
return VLC_ENOMEM;
goto bailout;
input_item_AddOption( p_item, psz_option, VLC_INPUT_OPTION_TRUSTED );
free( psz_option );

i_ret = asprintf( &psz_option, "smb-domain=%s", p_sys->creds.domain );
if( i_ret == -1 )
return VLC_ENOMEM;
goto bailout;
input_item_AddOption( p_item, psz_option, VLC_INPUT_OPTION_TRUSTED );
free( psz_option );

input_item_CopyOptions( p_node->p_item, p_item );
i_ret = input_item_node_AppendItem( p_node, p_item ) != NULL ? VLC_SUCCESS
: VLC_EGENERIC;

input_item_Release( p_item );
return i_ret;
return p_item;
bailout:
if( p_item )
input_item_Release( p_item );
free( psz_option );
return NULL;
}

static int BrowseShare( access_t *p_access, input_item_node_t *p_node )
static input_item_t* BrowseShare( access_t *p_access )
{
access_sys_t *p_sys = p_access->p_sys;
smb_share_list shares;
const char *psz_name;
size_t share_count;
int i_ret;
input_item_t *p_item = NULL;

share_count = smb_share_get_list( p_sys->p_session, &shares );
if( !share_count )
return VLC_ENOITEM;

for( size_t i = 0; i < share_count; i++ )
if( !p_sys->i_browse_count )
p_sys->i_browse_count = smb_share_get_list( p_sys->p_session,
&p_sys->shares );
for( ; !p_item && p_sys->i_browse_idx < p_sys->i_browse_count
; p_sys->i_browse_idx++ )
{
psz_name = smb_share_list_at( shares, i );
psz_name = smb_share_list_at( p_sys->shares, p_sys->i_browse_idx );

if( psz_name[strlen( psz_name ) - 1] == '$')
continue;

i_ret = add_item( p_access, p_node, psz_name, ITEM_TYPE_DIRECTORY );
if( i_ret != VLC_SUCCESS )
goto error;
p_item = new_item( p_access, psz_name, ITEM_TYPE_DIRECTORY );
if( !p_item )
return NULL;
}

smb_share_list_destroy( shares );
return VLC_SUCCESS;
error:
smb_share_list_destroy( shares );
return i_ret;
return p_item;
}

static int BrowseDirectory( access_t *p_access, input_item_node_t *p_node )
static input_item_t* BrowseDirectory( access_t *p_access )
{
access_sys_t *p_sys = p_access->p_sys;
smb_stat_list files;
smb_stat st;
input_item_t *p_item = NULL;
char *psz_query;
const char *psz_name;
size_t files_count;
int i_ret;

if( p_sys->psz_path != NULL )
if( !p_sys->i_browse_count )
{
i_ret = asprintf( &psz_query, "%s\\*", p_sys->psz_path );
if( i_ret == -1 )
return VLC_ENOMEM;
files = smb_find( p_sys->p_session, p_sys->i_tid, psz_query );
free( psz_query );
if( p_sys->psz_path != NULL )
{
i_ret = asprintf( &psz_query, "%s\\*", p_sys->psz_path );
if( i_ret == -1 )
return NULL;
p_sys->files = smb_find( p_sys->p_session, p_sys->i_tid, psz_query );
free( psz_query );
}
else
p_sys->files = smb_find( p_sys->p_session, p_sys->i_tid, "\\*" );
if( p_sys->files == NULL )
return NULL;
p_sys->i_browse_count = smb_stat_list_count( p_sys->files );
}
else
files = smb_find( p_sys->p_session, p_sys->i_tid, "\\*" );

if( files == NULL )
return VLC_ENOITEM;

files_count = smb_stat_list_count( files );
for( size_t i = 0; i < files_count; i++ )
if( p_sys->i_browse_idx < p_sys->i_browse_count )
{
int i_type;

st = smb_stat_list_at( files, i );
st = smb_stat_list_at( p_sys->files, p_sys->i_browse_idx++ );

if( st == NULL ) {
i_ret = VLC_ENOITEM;
goto error;
}
if( st == NULL )
return NULL;

psz_name = smb_stat_name( st );

/* Avoid infinite loop */
if( !strcmp( psz_name, ".") || !strcmp( psz_name, "..") )
continue;
i_type = smb_stat_get( st, SMB_STAT_ISDIR ) ?
ITEM_TYPE_DIRECTORY : ITEM_TYPE_FILE;
i_ret = add_item( p_access, p_node, psz_name, i_type );
if( i_ret != VLC_SUCCESS )
goto error;
p_item = new_item( p_access, psz_name, i_type );
if( !p_item )
return NULL;
}

smb_stat_list_destroy( files );
return VLC_SUCCESS;

error:
smb_stat_list_destroy( files );
return i_ret;
return p_item;
}

static int BrowserInit( access_t *p_access )
Expand Down
2 changes: 1 addition & 1 deletion modules/access/fs.h
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,6 @@ void FileClose (vlc_object_t *);

int DirOpen (vlc_object_t *);
int DirInit (access_t *p_access, DIR *handle);
int DirRead (access_t *, input_item_node_t *);
input_item_t* DirRead (access_t *);
int DirControl (access_t *, int, va_list);
void DirClose (vlc_object_t *);
Loading

0 comments on commit 88ffe15

Please sign in to comment.