]> git.sesse.net Git - vlc/blob - src/playlist/loadsave.c
mediacodec: don't loop in GetOutput
[vlc] / src / playlist / loadsave.c
1 /*****************************************************************************
2  * loadsave.c : Playlist loading / saving functions
3  *****************************************************************************
4  * Copyright (C) 1999-2004 VLC authors and VideoLAN
5  * $Id$
6  *
7  * Authors: Samuel Hocevar <sam@zoy.org>
8  *
9  * This program is free software; you can redistribute it and/or modify it
10  * under the terms of the GNU Lesser General Public License as published by
11  * the Free Software Foundation; either version 2.1 of the License, or
12  * (at your option) any later version.
13  *
14  * This program is distributed in the hope that it will be useful,
15  * but WITHOUT ANY WARRANTY; without even the implied warranty of
16  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
17  * GNU Lesser General Public License for more details.
18  *
19  * You should have received a copy of the GNU Lesser General Public License
20  * along with this program; if not, write to the Free Software Foundation,
21  * Inc., 51 Franklin Street, Fifth Floor, Boston MA 02110-1301, USA.
22  *****************************************************************************/
23 #ifdef HAVE_CONFIG_H
24 # include "config.h"
25 #endif
26
27 #include <errno.h>
28 #include <sys/types.h>
29 #include <sys/stat.h>
30 #include <unistd.h>
31
32 #include <vlc_common.h>
33 #include <vlc_playlist.h>
34 #include <vlc_events.h>
35 #include "playlist_internal.h"
36 #include "config/configuration.h"
37 #include <vlc_fs.h>
38 #include <vlc_url.h>
39 #include <vlc_modules.h>
40
41 int playlist_Export( playlist_t * p_playlist, const char *psz_filename,
42                      playlist_item_t *p_export_root, const char *psz_type )
43 {
44     if( p_export_root == NULL ) return VLC_EGENERIC;
45
46     playlist_export_t *p_export =
47         vlc_custom_create( p_playlist, sizeof( *p_export ), "playlist export" );
48     if( unlikely(p_export == NULL) )
49         return VLC_ENOMEM;
50
51     msg_Dbg( p_export, "saving %s to file %s",
52              p_export_root->p_input->psz_name, psz_filename );
53
54     int ret = VLC_EGENERIC;
55
56     /* Prepare the playlist_export_t structure */
57     p_export->p_root = p_export_root;
58     p_export->psz_filename = psz_filename;
59     p_export->p_file = vlc_fopen( psz_filename, "wt" );
60     if( p_export->p_file == NULL )
61     {
62         msg_Err( p_export, "could not create playlist file %s: %s",
63                  psz_filename, vlc_strerror_c(errno) );
64         goto out;
65     }
66
67     module_t *p_module;
68
69     /* And call the module ! All work is done now */
70     playlist_Lock( p_playlist );
71     p_module = module_need( p_export, "playlist export", psz_type, true );
72     playlist_Unlock( p_playlist );
73
74     if( p_module != NULL )
75     {
76         module_unneed( p_export, p_module );
77         if( !ferror( p_export->p_file ) )
78             ret = VLC_SUCCESS;
79         else
80             msg_Err( p_playlist, "could not write playlist file: %s",
81                      vlc_strerror_c(errno) );
82     }
83     else
84         msg_Err( p_playlist, "could not export playlist" );
85    fclose( p_export->p_file );
86 out:
87    vlc_object_release( p_export );
88    return ret;
89 }
90
91 int playlist_Import( playlist_t *p_playlist, const char *psz_file )
92 {
93     input_item_t *p_input;
94     const char *const psz_option = "meta-file";
95     char *psz_uri = vlc_path2uri( psz_file, NULL );
96
97     if( psz_uri == NULL )
98         return VLC_EGENERIC;
99
100     p_input = input_item_NewExt( psz_uri, psz_file,
101                                  1, &psz_option, VLC_INPUT_OPTION_TRUSTED, -1 );
102     free( psz_uri );
103
104     playlist_AddInput( p_playlist, p_input, PLAYLIST_APPEND, PLAYLIST_END,
105                        true, false );
106     return input_Read( p_playlist, p_input );
107 }
108
109 /*****************************************************************************
110  * A subitem has been added to the Media Library (Event Callback)
111  *****************************************************************************/
112 static void input_item_subitem_tree_added( const vlc_event_t * p_event,
113                                       void * user_data )
114 {
115     playlist_t *p_playlist = user_data;
116     input_item_node_t *p_root =
117         p_event->u.input_item_subitem_tree_added.p_root;
118
119     PL_LOCK;
120     playlist_InsertInputItemTree ( p_playlist, p_playlist->p_media_library,
121                                    p_root, 0, false );
122     PL_UNLOCK;
123 }
124
125 int playlist_MLLoad( playlist_t *p_playlist )
126 {
127     input_item_t *p_input;
128
129     char *psz_datadir = config_GetUserDir( VLC_DATA_DIR );
130     if( !psz_datadir ) /* XXX: This should never happen */
131     {
132         msg_Err( p_playlist, "no data directory, cannot load media library") ;
133         return VLC_EGENERIC;
134     }
135
136     char *psz_file;
137     if( asprintf( &psz_file, "%s" DIR_SEP "ml.xspf", psz_datadir ) == -1 )
138         psz_file = NULL;
139     free( psz_datadir );
140     if( psz_file == NULL )
141         return VLC_ENOMEM;
142
143     /* lousy check for media library file */
144     struct stat st;
145     if( vlc_stat( psz_file, &st ) )
146     {
147         free( psz_file );
148         return VLC_EGENERIC;
149     }
150
151     char *psz_uri = vlc_path2uri( psz_file, "file/xspf-open" );
152     free( psz_file );
153     if( psz_uri == NULL )
154         return VLC_ENOMEM;
155
156     const char *const options[1] = { "meta-file", };
157     /* that option has to be cleaned in input_item_subitem_tree_added() */
158     /* vlc_gc_decref() in the same function */
159     p_input = input_item_NewExt( psz_uri, _("Media Library"),
160                                  1, options, VLC_INPUT_OPTION_TRUSTED, -1 );
161     free( psz_uri );
162     if( p_input == NULL )
163         return VLC_EGENERIC;
164
165     PL_LOCK;
166     if( p_playlist->p_media_library->p_input )
167         vlc_gc_decref( p_playlist->p_media_library->p_input );
168
169     p_playlist->p_media_library->p_input = p_input;
170
171     vlc_event_attach( &p_input->event_manager, vlc_InputItemSubItemTreeAdded,
172                         input_item_subitem_tree_added, p_playlist );
173     PL_UNLOCK;
174
175     input_Read( p_playlist, p_input );
176
177     vlc_event_detach( &p_input->event_manager, vlc_InputItemSubItemTreeAdded,
178                         input_item_subitem_tree_added, p_playlist );
179
180     return VLC_SUCCESS;
181 }
182
183 int playlist_MLDump( playlist_t *p_playlist )
184 {
185     char *psz_temp;
186
187     psz_temp = config_GetUserDir( VLC_DATA_DIR );
188
189     if( !psz_temp ) /* XXX: This should never happen */
190     {
191         msg_Err( p_playlist, "no data directory, cannot save media library") ;
192         return VLC_EGENERIC;
193     }
194
195     char psz_dirname[ strlen( psz_temp ) + sizeof( DIR_SEP "ml.xspf")];
196     strcpy( psz_dirname, psz_temp );
197     free( psz_temp );
198     if( config_CreateDir( (vlc_object_t *)p_playlist, psz_dirname ) )
199     {
200         return VLC_EGENERIC;
201     }
202
203     strcat( psz_dirname, DIR_SEP "ml.xspf" );
204
205     if ( asprintf( &psz_temp, "%s.tmp%"PRIu32, psz_dirname, (uint32_t)getpid() ) < 1 )
206         return VLC_EGENERIC;
207
208     int i_ret = playlist_Export( p_playlist, psz_temp, p_playlist->p_media_library,
209                      "export-xspf" );
210     if ( i_ret != VLC_SUCCESS )
211     {
212         vlc_unlink( psz_temp );
213         free( psz_temp );
214         return i_ret;
215     }
216
217     i_ret = vlc_rename( psz_temp, psz_dirname );
218     free( psz_temp );
219     if( i_ret == -1 )
220     {
221         msg_Err( p_playlist, "could not rename %s.tmp: %s",
222                  psz_dirname, vlc_strerror_c(errno) );
223         return VLC_EGENERIC;
224     }
225     return VLC_SUCCESS;
226 }