media_list_path.h 9.02 KB
Newer Older
1 2 3 4
/*****************************************************************************
 * media_list_path.h : Some inlined function that allows media_list_path
 * manipulation. This is internal and used only by media_list_player.
 *****************************************************************************
Jean-Baptiste Kempf's avatar
Jean-Baptiste Kempf committed
5
 * Copyright (C) 2005 VLC authors and VideoLAN
6 7 8 9
 * $Id $
 *
 * Authors: Pierre d'Herbemont <pdherbemont # videolan.org>
 *
Jean-Baptiste Kempf's avatar
Jean-Baptiste Kempf committed
10 11 12
 * This program 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
13 14 15 16
 * (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
Jean-Baptiste Kempf's avatar
Jean-Baptiste Kempf committed
17 18
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
 * GNU Lesser General Public License for more details.
19
 *
Jean-Baptiste Kempf's avatar
Jean-Baptiste Kempf committed
20 21 22
 * You should have received a copy of the GNU Lesser General Public License
 * along with this program; if not, write to the Free Software Foundation,
 * Inc., 51 Franklin Street, Fifth Floor, Boston MA 02110-1301, USA.
23 24 25 26 27
 *****************************************************************************/

#ifndef _LIBVLC_MEDIA_LIST_PATH_H
#define _LIBVLC_MEDIA_LIST_PATH_H 1

28 29
typedef int * libvlc_media_list_path_t; /* (Media List Player Internal) */

30 31 32
/**************************************************************************
 *       path_dump (Media List Player Internal)
 **************************************************************************/
33
static inline void libvlc_media_list_path_dump( const libvlc_media_list_path_t path )
34 35 36 37 38 39 40
{
    if(!path)
    {
        printf("NULL path\n");
        return;
    }

41
    for(int i = 0; path[i] != -1; i++)
42 43 44 45
        printf("%s%d", i > 0 ? "/" : "", path[i]);
    printf("\n");
}

46 47 48 49 50
/**************************************************************************
 *       path_empty (Media List Player Internal)
 **************************************************************************/
static inline libvlc_media_list_path_t libvlc_media_list_path_empty( void )
{
51
    libvlc_media_list_path_t ret = xmalloc(sizeof(int));
52 53 54 55 56 57 58 59 60
    ret[0] = -1;
    return ret;
}

/**************************************************************************
 *       path_with_root_index (Media List Player Internal)
 **************************************************************************/
static inline libvlc_media_list_path_t libvlc_media_list_path_with_root_index( int index )
{
61
    libvlc_media_list_path_t ret = xmalloc(sizeof(int)*2);
62 63 64 65 66 67
    ret[0] = index;
    ret[1] = -1;
    return ret;
}

/**************************************************************************
Rémi Denis-Courmont's avatar
Rémi Denis-Courmont committed
68
 *       path_depth (Media List Player Internal)
69
 **************************************************************************/
70
static inline int libvlc_media_list_path_depth( const libvlc_media_list_path_t path )
71 72 73 74 75 76 77 78 79 80 81
{
    int i;
    for( i = 0; path[i] != -1; i++ );
    return i;
}

/**************************************************************************
 *       path_append (Media List Player Internal)
 **************************************************************************/
static inline void libvlc_media_list_path_append( libvlc_media_list_path_t * p_path, int index )
{
Rémi Denis-Courmont's avatar
Rémi Denis-Courmont committed
82
    int old_depth = libvlc_media_list_path_depth( *p_path );
83
    *p_path = xrealloc( *p_path, sizeof(int)*(old_depth+2));
Rémi Denis-Courmont's avatar
Rémi Denis-Courmont committed
84 85
    *p_path[old_depth] = index;
    *p_path[old_depth+1] = -1;
86 87 88 89 90
}

/**************************************************************************
 *       path_copy_by_appending (Media List Player Internal)
 **************************************************************************/
91
static inline libvlc_media_list_path_t libvlc_media_list_path_copy_by_appending( const libvlc_media_list_path_t path, int index )
92 93
{
    libvlc_media_list_path_t ret;
Rémi Denis-Courmont's avatar
Rémi Denis-Courmont committed
94
    int old_depth = libvlc_media_list_path_depth( path );
95
    ret = xmalloc( sizeof(int) * (old_depth + 2) );
96
    memcpy( ret, path, sizeof(int) * old_depth );
Rémi Denis-Courmont's avatar
Rémi Denis-Courmont committed
97 98
    ret[old_depth] = index;
    ret[old_depth+1] = -1;
99 100 101 102 103 104
    return ret;
}

/**************************************************************************
 *       path_copy (Media List Player Internal)
 **************************************************************************/
105
static inline libvlc_media_list_path_t libvlc_media_list_path_copy( const libvlc_media_list_path_t path )
106 107
{
    libvlc_media_list_path_t ret;
Rémi Denis-Courmont's avatar
Rémi Denis-Courmont committed
108
    int depth = libvlc_media_list_path_depth( path );
109
    ret = xmalloc( sizeof(int)*(depth+1) );
Rémi Denis-Courmont's avatar
Rémi Denis-Courmont committed
110
    memcpy( ret, path, sizeof(int)*(depth+1) );
111 112 113 114 115 116 117
    return ret;
}

/**************************************************************************
 *       get_path_rec (Media List Player Internal)
 **************************************************************************/
static libvlc_media_list_path_t
118
get_path_rec( const libvlc_media_list_path_t path, libvlc_media_list_t * p_current_mlist, libvlc_media_t * p_searched_md )
119
{
120 121 122
    int count = libvlc_media_list_count( p_current_mlist );

    for( int i = 0; i < count; i++ )
123
    {
124
        libvlc_media_t * p_md = libvlc_media_list_item_at_index( p_current_mlist, i );
125 126 127 128

        if( p_md == p_searched_md )
            return libvlc_media_list_path_copy_by_appending( path, i ); /* Found! */

129
        libvlc_media_list_t * p_subitems = libvlc_media_subitems( p_md );
130
        libvlc_media_release( p_md );
131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148
        if( p_subitems )
        {
            libvlc_media_list_path_t new_path = libvlc_media_list_path_copy_by_appending( path, i );
            libvlc_media_list_lock( p_subitems );
            libvlc_media_list_path_t ret = get_path_rec( new_path, p_subitems, p_searched_md );
            libvlc_media_list_unlock( p_subitems );
            free( new_path );
            libvlc_media_list_release( p_subitems );
            if( ret )
                return ret; /* Found in sublist! */
        }
    }
    return NULL;
}

/**************************************************************************
 *       path_of_item (Media List Player Internal)
 **************************************************************************/
149
static inline libvlc_media_list_path_t libvlc_media_list_path_of_item( libvlc_media_list_t * p_mlist, libvlc_media_t * p_md )
150 151 152 153 154 155 156 157 158 159 160
{
    libvlc_media_list_path_t path = libvlc_media_list_path_empty();
    libvlc_media_list_path_t ret;
    ret = get_path_rec( path, p_mlist, p_md );
    free( path );
    return ret;
}

/**************************************************************************
 *       item_at_path (Media List Player Internal)
 **************************************************************************/
161
static libvlc_media_t *
162
libvlc_media_list_item_at_path( libvlc_media_list_t * p_mlist, const libvlc_media_list_path_t path )
163 164
{
    libvlc_media_list_t * p_current_mlist = p_mlist;
165 166

    for( int i = 0; path[i] != -1; i++ )
167
    {
168
        libvlc_media_t* p_md = libvlc_media_list_item_at_index( p_current_mlist, path[i] );
169 170 171 172 173 174 175

        if( p_current_mlist != p_mlist )
            libvlc_media_list_release( p_current_mlist );

        if( path[i+1] == -1 )
            return p_md;

176
        p_current_mlist = libvlc_media_subitems( p_md );
177
        libvlc_media_release( p_md );
178

179 180 181 182 183 184 185 186
        if( !p_current_mlist )
            return NULL;

        /* Fetch next one */
    }
    /* Not found, shouldn't happen if the p_path is not empty */
    if( p_current_mlist != p_mlist )
        libvlc_media_list_release( p_current_mlist );
187
    return NULL;
188 189 190 191 192 193
}

/**************************************************************************
 *       parentlist_at_path (Media List Player Internal)
 **************************************************************************/
static libvlc_media_list_t *
194
libvlc_media_list_parentlist_at_path( libvlc_media_list_t * p_mlist, const libvlc_media_list_path_t path )
195 196
{
    libvlc_media_list_t * p_current_mlist = p_mlist;
197 198

    for( int i = 0; path[i] != -1; i++ )
199 200 201 202 203
    {
        if( p_current_mlist != p_mlist )
            libvlc_media_list_release( p_current_mlist );

        if( path[i+1] == -1 )
204 205
        {
            libvlc_media_list_retain(p_current_mlist);
206
            return p_current_mlist;
207
        }
208

209
        libvlc_media_t* p_md = libvlc_media_list_item_at_index( p_current_mlist, path[i] );
210

211
        p_current_mlist = libvlc_media_subitems( p_md );
212
        libvlc_media_release( p_md );
213

214 215 216 217 218 219 220 221
        if( !p_current_mlist )
            return NULL;

        /* Fetch next one */
    }
    /* Not found, shouldn't happen if the p_path is not empty */
    if( p_current_mlist != p_mlist )
        libvlc_media_list_release( p_current_mlist );
222
    return NULL;
223 224 225 226 227 228
}

/**************************************************************************
 *       sublist_at_path (Media List Player Internal)
 **************************************************************************/
static libvlc_media_list_t *
229
libvlc_media_list_sublist_at_path( libvlc_media_list_t * p_mlist, const libvlc_media_list_path_t path )
230 231
{
    libvlc_media_list_t * ret;
232
    libvlc_media_t * p_md = libvlc_media_list_item_at_path( p_mlist, path );
233 234
    if( !p_md )
        return NULL;
235

236
    ret = libvlc_media_subitems( p_md );
237
    libvlc_media_release( p_md );
238

239
    return ret;
240 241 242
}

#endif