[vlc-devel] [PATCH 2/2] playlist: export: allow export to memory
Francois Cartegnie
fcvlcdev at free.fr
Thu Jul 24 17:24:44 CEST 2014
---
include/vlc_playlist.h | 4 ++
modules/misc/Modules.am | 1 +
modules/misc/playlist/export.c | 50 ++++++++++++++++++-
modules/misc/playlist/export.h | 34 +++++++++++++
modules/misc/playlist/html.c | 41 ++++++++-------
modules/misc/playlist/m3u.c | 55 ++++++++++++--------
modules/misc/playlist/xspf.c | 111 +++++++++++++++++++++++------------------
src/libvlccore.sym | 1 +
src/playlist/loadsave.c | 70 ++++++++++++++++++++------
9 files changed, 263 insertions(+), 104 deletions(-)
create mode 100644 modules/misc/playlist/export.h
diff --git a/include/vlc_playlist.h b/include/vlc_playlist.h
index 49dcd15..0c2a62b 100644
--- a/include/vlc_playlist.h
+++ b/include/vlc_playlist.h
@@ -128,6 +128,9 @@ typedef struct playlist_export_t
VLC_COMMON_MEMBERS
const char *psz_filename;
FILE *p_file;
+ uint8_t *p_buffer;
+ size_t i_buffer_length;
+ size_t i_buffer;
playlist_item_t *p_root;
} playlist_export_t;
@@ -308,6 +311,7 @@ VLC_API int playlist_Status( playlist_t * );
* \return VLC_SUCCESS on success
*/
VLC_API int playlist_Export( playlist_t *p_playlist, const char *psz_name, playlist_item_t *p_export_root, const char *psz_type );
+VLC_API int playlist_ExportMemory( playlist_t *p_playlist, uint8_t **p_buffer, playlist_item_t *p_export_root, const char *psz_type );
/**
* Open a playlist file, add its content to the current playlist
diff --git a/modules/misc/Modules.am b/modules/misc/Modules.am
index 62a54d1..ce0bfef 100644
--- a/modules/misc/Modules.am
+++ b/modules/misc/Modules.am
@@ -10,6 +10,7 @@ libexport_plugin_la_SOURCES = \
playlist/html.c \
playlist/m3u.c \
playlist/xspf.c \
+ playlist/export.h \
playlist/export.c
misc_LTLIBRARIES += libexport_plugin.la
diff --git a/modules/misc/playlist/export.c b/modules/misc/playlist/export.c
index a42ef39..fbf2acf 100644
--- a/modules/misc/playlist/export.c
+++ b/modules/misc/playlist/export.c
@@ -28,8 +28,9 @@
# include "config.h"
#endif
-#include <vlc_common.h>
+#include "export.h"
#include <vlc_plugin.h>
+#include <vlc_charset.h>
/***************************************************************************
* Prototypes
@@ -71,3 +72,50 @@ vlc_module_begin ()
set_callbacks( Export_HTML, NULL )
vlc_module_end ()
+
+/*****************************************************************************
+ * Definitions
+ *****************************************************************************/
+void export_write_to_memory( playlist_export_t *p_export, const char *psz_format, ... )
+{
+ va_list args;
+ va_start( args, psz_format );
+ char *psz_buffer;
+ int i_ret = vasprintf( &psz_buffer, psz_format, args );
+ va_end( args );
+
+ if (i_ret > 0)
+ {
+ if ( p_export->i_buffer + i_ret + 1 > p_export->i_buffer_length )
+ {
+ size_t i_newsize = __MAX( p_export->i_buffer_length * 2, p_export->i_buffer_length + i_ret + 1 );
+ char *psz_newbuf = realloc( p_export->p_buffer, i_newsize );
+ if (psz_newbuf)
+ {
+ p_export->p_buffer = (uint8_t *) psz_newbuf;
+ p_export->i_buffer_length = i_newsize;
+ }
+ }
+
+ if ( p_export->i_buffer + i_ret + 1 <= p_export->i_buffer_length ) /* realloc can fail */
+ strncpy( (char *)p_export->p_buffer + p_export->i_buffer, psz_buffer, i_ret );
+ p_export->i_buffer += i_ret;
+ free(psz_buffer);
+ }
+}
+
+void export_write_to_file( playlist_export_t *p_export, const char *psz_format, ... )
+{
+ va_list args;
+ va_start( args, psz_format );
+ vfprintf( p_export->p_file, psz_format, args );
+ va_end( args );
+}
+
+void export_write_to_file_utf8( playlist_export_t *p_export, const char *psz_format, ... )
+{
+ va_list args;
+ va_start( args, psz_format );
+ utf8_vfprintf( p_export->p_file, psz_format, args );
+ va_end( args );
+}
diff --git a/modules/misc/playlist/export.h b/modules/misc/playlist/export.h
new file mode 100644
index 0000000..67e9a40
--- /dev/null
+++ b/modules/misc/playlist/export.h
@@ -0,0 +1,34 @@
+/*****************************************************************************
+ * export.h : Playlist export module
+ *****************************************************************************
+ * Copyright (C) 2014 the VideoLAN team
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (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
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU 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.
+ *****************************************************************************/
+
+/*****************************************************************************
+ * Preamble
+ *****************************************************************************/
+#include <vlc_common.h>
+#include <vlc_playlist.h>
+
+/***************************************************************************
+ * Prototypes
+ ***************************************************************************/
+typedef void(*export_writer_t)(playlist_export_t *, const char *, ...);
+
+void export_write_to_memory( playlist_export_t *p_export, const char *psz_format, ... );
+void export_write_to_file( playlist_export_t *p_export, const char *psz_format, ... );
+void export_write_to_file_utf8( playlist_export_t *p_export, const char *psz_format, ... );
diff --git a/modules/misc/playlist/html.c b/modules/misc/playlist/html.c
index 8c9d00c..1e7085f 100644
--- a/modules/misc/playlist/html.c
+++ b/modules/misc/playlist/html.c
@@ -25,8 +25,8 @@
# include "config.h"
#endif
-#include <vlc_common.h>
-#include <vlc_playlist.h>
+#include "export.h"
+
#include <vlc_input.h>
#include <vlc_strings.h>
@@ -42,7 +42,8 @@ int Export_HTML( vlc_object_t *p_this );
* @param p_export: the export structure
* @param p_root: the current node
*/
-static void DoChildren( playlist_export_t *p_export, playlist_item_t *p_root )
+static void DoChildren( playlist_export_t *p_export, export_writer_t pf_writer,
+ playlist_item_t *p_root )
{
/* Go through the playlist and add items */
for( int i = 0; i < p_root->i_children ; i++)
@@ -55,7 +56,7 @@ static void DoChildren( playlist_export_t *p_export, playlist_item_t *p_root )
if( p_current->i_children >= 0 )
{
- DoChildren( p_export, p_current );
+ DoChildren( p_export, pf_writer, p_current );
continue;
}
@@ -79,9 +80,9 @@ static void DoChildren( playlist_export_t *p_export, playlist_item_t *p_root )
// Print the artist if we have one
if( psz_artist && *psz_artist )
- fprintf( p_export->p_file, " <li>%s - %s (%02d:%02d)</li>\n", psz_artist, psz_name, min, sec );
+ pf_writer( p_export, " <li>%s - %s (%02d:%02d)</li>\n", psz_artist, psz_name, min, sec );
else
- fprintf( p_export->p_file, " <li>%s (%2d:%2d)</li>\n", psz_name, min, sec );
+ pf_writer( p_export, " <li>%s (%2d:%2d)</li>\n", psz_name, min, sec );
free( psz_artist );
}
@@ -89,20 +90,12 @@ static void DoChildren( playlist_export_t *p_export, playlist_item_t *p_root )
}
}
-
-/**
- * Export the playlist as an HTML page
- * @param p_this: the playlist
- * @return VLC_SUCCESS if everything goes fine
- */
-int Export_HTML( vlc_object_t *p_this )
+static int Export_HTML_internal( playlist_export_t *p_export, export_writer_t pf_writer )
{
- playlist_export_t *p_export = (playlist_export_t *)p_this;
-
msg_Dbg( p_export, "saving using HTML format" );
/* Write header */
- fprintf( p_export->p_file, "<?xml version=\"1.0\" encoding=\"utf-8\" ?>\n"
+ pf_writer( p_export, "<?xml version=\"1.0\" encoding=\"utf-8\" ?>\n"
"<!DOCTYPE html PUBLIC \"-//W3C//DTD XHTML 1.1//EN\" \"http://www.w3.org/TR/xhtml11/DTD/xhtml11.dtd\">\n"
"<html xmlns=\"http://www.w3.org/1999/xhtml\" xml:lang=\"en\">\n"
"<head>\n"
@@ -131,13 +124,25 @@ int Export_HTML( vlc_object_t *p_this )
" <ol>\n" );
// Call the playlist constructor
- DoChildren( p_export, p_export->p_root );
+ DoChildren( p_export, pf_writer, p_export->p_root );
// Print the footer
- fprintf( p_export->p_file, " </ol>\n"
+ pf_writer( p_export, " </ol>\n"
" <hr />\n"
"</body>\n"
"</html>" );
return VLC_SUCCESS;
}
+/**
+ * Export the playlist as an HTML page
+ * @param p_this: the playlist
+ * @return VLC_SUCCESS if everything goes fine
+ */
+int Export_HTML( vlc_object_t *p_this )
+{
+ playlist_export_t *p_export = (playlist_export_t *)p_this;
+ export_writer_t pf_writer = (p_export->p_file)? export_write_to_file
+ : export_write_to_memory;
+ return Export_HTML_internal( p_export, pf_writer );
+}
diff --git a/modules/misc/playlist/m3u.c b/modules/misc/playlist/m3u.c
index 72e9581..35b2555 100644
--- a/modules/misc/playlist/m3u.c
+++ b/modules/misc/playlist/m3u.c
@@ -29,8 +29,8 @@
# include "config.h"
#endif
-#include <vlc_common.h>
-#include <vlc_playlist.h>
+#include "export.h"
+
#include <vlc_input.h>
#include <vlc_meta.h>
#include <vlc_charset.h>
@@ -47,11 +47,11 @@ int Export_M3U8( vlc_object_t * );
/*****************************************************************************
* Export_M3U: main export function
*****************************************************************************/
-static void DoChildren( playlist_export_t *p_export, playlist_item_t *p_root,
- int (*pf_fprintf) (FILE *, const char *, ...) )
+static void DoChildren( playlist_export_t *p_export, export_writer_t pf_writer,
+ playlist_item_t *p_root )
{
/* Write header */
- fputs( "#EXTM3U\n", p_export->p_file );
+ pf_writer( p_export, "#EXTM3U\n" );
/* Go through the playlist and add items */
for( int i = 0; i< p_root->i_children ; i++)
@@ -64,7 +64,7 @@ static void DoChildren( playlist_export_t *p_export, playlist_item_t *p_root,
if( p_current->i_children >= 0 )
{
- DoChildren( p_export, p_current, pf_fprintf );
+ DoChildren( p_export, pf_writer, p_current );
continue;
}
@@ -83,14 +83,14 @@ static void DoChildren( playlist_export_t *p_export, playlist_item_t *p_root,
if( psz_artist && *psz_artist )
{
/* write EXTINF with artist */
- pf_fprintf( p_export->p_file, "#EXTINF:%"PRIu64",%s - %s\n",
- i_duration / CLOCK_FREQ, psz_artist, psz_name);
+ pf_writer( p_export, "#EXTINF:%"PRIu64",%s - %s\n",
+ i_duration / CLOCK_FREQ, psz_artist, psz_name);
}
else
{
/* write EXTINF without artist */
- pf_fprintf( p_export->p_file, "#EXTINF:%"PRIu64",%s\n",
- i_duration / CLOCK_FREQ, psz_name);
+ pf_writer( p_export, "#EXTINF:%"PRIu64",%s\n",
+ i_duration / CLOCK_FREQ, psz_name);
}
free( psz_artist );
}
@@ -100,10 +100,10 @@ static void DoChildren( playlist_export_t *p_export, playlist_item_t *p_root,
vlc_mutex_lock( &p_current->p_input->lock );
for( int j = 0; j < p_current->p_input->i_options; j++ )
{
- pf_fprintf( p_export->p_file, "#EXTVLCOPT:%s\n",
- p_current->p_input->ppsz_options[j][0] == ':' ?
- p_current->p_input->ppsz_options[j] + 1 :
- p_current->p_input->ppsz_options[j] );
+ pf_writer( p_export, "#EXTVLCOPT:%s\n",
+ p_current->p_input->ppsz_options[j][0] == ':' ?
+ p_current->p_input->ppsz_options[j] + 1 :
+ p_current->p_input->ppsz_options[j] );
}
vlc_mutex_unlock( &p_current->p_input->lock );
@@ -114,27 +114,40 @@ static void DoChildren( playlist_export_t *p_export, playlist_item_t *p_root,
free( psz_uri );
psz_uri = psz_path;
}
- fprintf( p_export->p_file, "%s\n", psz_uri );
+ pf_writer( p_export, "%s\n", psz_uri );
free( psz_uri );
}
}
-int Export_M3U( vlc_object_t *p_this )
+static int Export_M3U_internal( playlist_export_t *p_export, export_writer_t pf_writer )
{
- playlist_export_t *p_export = (playlist_export_t *)p_this;
-
msg_Dbg( p_export, "saving using M3U format");
- DoChildren( p_export, p_export->p_root, utf8_fprintf );
+ DoChildren( p_export, pf_writer, p_export->p_root );
return VLC_SUCCESS;
}
-int Export_M3U8( vlc_object_t *p_this )
+int Export_M3U( vlc_object_t *p_this )
{
playlist_export_t *p_export = (playlist_export_t *)p_this;
+ /* FIXME: win32 encoding with memory output */
+ export_writer_t pf_writer = (p_export->p_file)? export_write_to_file_utf8
+ : export_write_to_memory;
+ return Export_M3U_internal( p_export, pf_writer );
+}
+static int Export_M3U8_internal( playlist_export_t *p_export, export_writer_t pf_writer )
+{
msg_Dbg( p_export, "saving using M3U8 format");
- DoChildren( p_export, p_export->p_root, fprintf );
+ DoChildren( p_export, pf_writer, p_export->p_root );
return VLC_SUCCESS;
}
+
+int Export_M3U8( vlc_object_t *p_this )
+{
+ playlist_export_t *p_export = (playlist_export_t *)p_this;
+ export_writer_t pf_writer = (p_export->p_file)? export_write_to_file
+ : export_write_to_memory;
+ return Export_M3U8_internal( p_export, pf_writer );
+}
diff --git a/modules/misc/playlist/xspf.c b/modules/misc/playlist/xspf.c
index e41cd25..cf5a1c7 100644
--- a/modules/misc/playlist/xspf.c
+++ b/modules/misc/playlist/xspf.c
@@ -30,8 +30,8 @@
# include "config.h"
#endif
-#include <vlc_common.h>
-#include <vlc_playlist.h>
+#include "export.h"
+
#include <vlc_input.h>
#include <vlc_strings.h>
#include <vlc_url.h>
@@ -51,13 +51,14 @@ static char *input_xml( input_item_t *p_item, char *(*func)(input_item_t *) )
}
/**
- * \brief exports one item to file or traverse if item is a node
+ * \brief exports one item using writer function or traverse if item is a node
+ * \param p_export playlist export structure
+ * \param pf_writer pointer to export_writer function
* \param p_item playlist item to export
- * \param p_file file to write xml-converted item to
* \param p_i_count counter for track identifiers
*/
-static void xspf_export_item( playlist_item_t *p_item, FILE *p_file,
- int *p_i_count )
+static void xspf_export_item( playlist_export_t *p_export, export_writer_t pf_writer,
+ playlist_item_t *p_item, int *p_i_count )
{
if( !p_item ) return;
@@ -65,7 +66,7 @@ static void xspf_export_item( playlist_item_t *p_item, FILE *p_file,
if( p_item->i_children > 0 )
{
for( int i = 0; i < p_item->i_children; i++ )
- xspf_export_item( p_item->pp_children[i], p_file, p_i_count );
+ xspf_export_item( p_export, pf_writer, p_item->pp_children[i], p_i_count );
return;
}
@@ -78,18 +79,18 @@ static void xspf_export_item( playlist_item_t *p_item, FILE *p_file,
mtime_t i_duration;
/* leaves can be written directly */
- fputs( "\t\t<track>\n", p_file );
+ pf_writer( p_export, "\t\t<track>\n" );
/* -> the location */
char *psz_uri = input_xml( p_input, input_item_GetURI );
if( psz_uri && *psz_uri )
- fprintf( p_file, "\t\t\t<location>%s</location>\n", psz_uri );
+ pf_writer( p_export, "\t\t\t<location>%s</location>\n", psz_uri );
/* -> the name/title (only if different from uri)*/
psz = input_xml( p_input, input_item_GetTitle );
if( psz && strcmp( psz_uri, psz ) )
- fprintf( p_file, "\t\t\t<title>%s</title>\n", psz );
+ pf_writer( p_export, "\t\t\t<title>%s</title>\n", psz );
free( psz );
free( psz_uri );
@@ -101,13 +102,13 @@ static void xspf_export_item( playlist_item_t *p_item, FILE *p_file,
/* -> the artist/creator */
psz = input_xml( p_input, input_item_GetArtist );
if( psz && *psz )
- fprintf( p_file, "\t\t\t<creator>%s</creator>\n", psz );
+ pf_writer( p_export, "\t\t\t<creator>%s</creator>\n", psz );
free( psz );
/* -> the album */
psz = input_xml( p_input, input_item_GetAlbum );
if( psz && *psz )
- fprintf( p_file, "\t\t\t<album>%s</album>\n", psz );
+ pf_writer( p_export, "\t\t\t<album>%s</album>\n", psz );
free( psz );
/* -> the track number */
@@ -118,39 +119,39 @@ static void xspf_export_item( playlist_item_t *p_item, FILE *p_file,
free( psz );
if( i_tracknum > 0 )
- fprintf( p_file, "\t\t\t<trackNum>%i</trackNum>\n", i_tracknum );
+ pf_writer( p_export, "\t\t\t<trackNum>%i</trackNum>\n", i_tracknum );
}
/* -> the description */
psz = input_xml( p_input, input_item_GetDescription );
if( psz && *psz )
- fprintf( p_file, "\t\t\t<annotation>%s</annotation>\n", psz );
+ pf_writer( p_export, "\t\t\t<annotation>%s</annotation>\n", psz );
free( psz );
psz = input_xml( p_input, input_item_GetURL );
if( psz && *psz )
- fprintf( p_file, "\t\t\t<info>%s</info>\n", psz );
+ pf_writer( p_export, "\t\t\t<info>%s</info>\n", psz );
free( psz );
psz = input_xml( p_input, input_item_GetArtURL );
if( psz && *psz )
- fprintf( p_file, "\t\t\t<image>%s</image>\n", psz );
+ pf_writer( p_export, "\t\t\t<image>%s</image>\n", psz );
free( psz );
xspfexportitem_end:
/* -> the duration */
i_duration = input_item_GetDuration( p_item->p_input );
if( i_duration > 0 )
- fprintf( p_file, "\t\t\t<duration>%"PRIu64"</duration>\n",
+ pf_writer( p_export, "\t\t\t<duration>%"PRIu64"</duration>\n",
i_duration / 1000 );
/* export the intenal id and the input's options (bookmarks, ...)
* in <extension> */
- fputs( "\t\t\t<extension application=\""
- "http://www.videolan.org/vlc/playlist/0\">\n", p_file );
+ pf_writer( p_export, "\t\t\t<extension application=\""
+ "http://www.videolan.org/vlc/playlist/0\">\n" );
/* print the id and increase the counter */
- fprintf( p_file, "\t\t\t\t<vlc:id>%i</vlc:id>\n", *p_i_count );
+ pf_writer( p_export, "\t\t\t\t<vlc:id>%i</vlc:id>\n", *p_i_count );
( *p_i_count )++;
for( int i = 0; i < p_item->p_input->i_options; i++ )
@@ -165,21 +166,22 @@ xspfexportitem_end:
if ( psz_ret == NULL )
continue;
- fprintf( p_file, "\t\t\t\t<vlc:option>%s</vlc:option>\n", psz_ret );
+ pf_writer( p_export, "\t\t\t\t<vlc:option>%s</vlc:option>\n", psz_ret );
free( psz_ret );
}
- fputs( "\t\t\t</extension>\n", p_file );
- fputs( "\t\t</track>\n", p_file );
+ pf_writer( p_export, "\t\t\t</extension>\n" );
+ pf_writer( p_export, "\t\t</track>\n" );
}
/**
- * \brief exports one item in extension to file and traverse if item is a node
+ * \brief exports one item in extension using writer funciton and traverse if item is a node
+ * \param p_export playlist export structure
+ * \param pf_writer pointer to export_writer function
* \param p_item playlist item to export
- * \param p_file file to write xml-converted item to
* \param p_i_count counter for track identifiers
*/
-static void xspf_extension_item( playlist_item_t *p_item, FILE *p_file,
- int *p_i_count )
+static void xspf_extension_item( playlist_export_t *p_export, export_writer_t pf_writer,
+ playlist_item_t *p_item, int *p_i_count )
{
if( !p_item ) return;
@@ -190,43 +192,42 @@ static void xspf_extension_item( playlist_item_t *p_item, FILE *p_file,
char *psz_temp = NULL;
if( p_item->p_input->psz_name )
psz_temp = convert_xml_special_chars( p_item->p_input->psz_name );
- fprintf( p_file, "\t\t<vlc:node title=\"%s\">\n",
- psz_temp ? psz_temp : "" );
+ pf_writer( p_export, "\t\t<vlc:node title=\"%s\">\n",
+ psz_temp ? psz_temp : "" );
free( psz_temp );
for( i = 0; i < p_item->i_children; i++ )
{
- xspf_extension_item( p_item->pp_children[i], p_file, p_i_count );
+ xspf_extension_item( p_export, pf_writer, p_item->pp_children[i], p_i_count );
}
- fprintf( p_file, "\t\t</vlc:node>\n" );
+ pf_writer( p_export, "\t\t</vlc:node>\n" );
return;
}
/* print leaf and increase the counter */
- fprintf( p_file, "\t\t\t<vlc:item tid=\"%i\"/>\n", *p_i_count );
+ pf_writer( p_export, "\t\t\t<vlc:item tid=\"%i\"/>\n", *p_i_count );
( *p_i_count )++;
return;
}
/**
- * \brief Prints the XSPF header to file, writes each item by xspf_export_item()
- * and closes the open xml elements
- * \param p_this the VLC playlist object
- * \return VLC_SUCCESS if some memory is available, otherwise VLC_ENONMEM
+ * \brief exports playlist using writer function and traverse if item is a node
+ * \param p_export playlist export structure
+ * \param pf_writer pointer to export_writer function
+ * \return VLC_SUCCESS on success
*/
-int xspf_export_playlist( vlc_object_t *p_this )
+static int xspf_export_playlist_internal( playlist_export_t *p_export, export_writer_t pf_writer )
{
- const playlist_export_t *p_export = (playlist_export_t *)p_this;
int i, i_count;
char *psz_temp;
playlist_item_t *p_node = p_export->p_root;
/* write XSPF XML header */
- fprintf( p_export->p_file, "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n" );
- fprintf( p_export->p_file,
+ pf_writer( p_export, "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n" );
+ pf_writer( p_export,
"<playlist xmlns=\"http://xspf.org/ns/0/\" " \
"xmlns:vlc=\"http://www.videolan.org/vlc/playlist/ns/0/\" " \
"version=\"1\">\n" );
@@ -237,33 +238,47 @@ int xspf_export_playlist( vlc_object_t *p_this )
psz_temp = convert_xml_special_chars( p_node->p_input->psz_name );
if( *psz_temp )
{
- fprintf( p_export->p_file, "\t<title>%s</title>\n", psz_temp );
+ pf_writer( p_export, "\t<title>%s</title>\n", psz_temp );
}
free( psz_temp );
/* export all items in a flat format */
- fprintf( p_export->p_file, "\t<trackList>\n" );
+ pf_writer( p_export, "\t<trackList>\n" );
i_count = 0;
for( i = 0; i < p_node->i_children; i++ )
{
- xspf_export_item( p_node->pp_children[i], p_export->p_file,
+ xspf_export_item( p_export, pf_writer, p_node->pp_children[i],
&i_count );
}
- fprintf( p_export->p_file, "\t</trackList>\n" );
+ pf_writer( p_export, "\t</trackList>\n" );
/* export the tree structure in <extension> */
- fprintf( p_export->p_file, "\t<extension application=\"" \
+ pf_writer( p_export, "\t<extension application=\"" \
"http://www.videolan.org/vlc/playlist/0\">\n" );
i_count = 0;
for( i = 0; i < p_node->i_children; i++ )
{
- xspf_extension_item( p_node->pp_children[i], p_export->p_file,
+ xspf_extension_item( p_export, pf_writer, p_node->pp_children[i],
&i_count );
}
- fprintf( p_export->p_file, "\t</extension>\n" );
+ pf_writer( p_export, "\t</extension>\n" );
/* close the header elements */
- fprintf( p_export->p_file, "</playlist>\n" );
+ pf_writer( p_export, "</playlist>\n" );
return VLC_SUCCESS;
}
+
+/**
+ * \brief Prints the XSPF header to file, writes each item by xspf_export_item()
+ * and closes the open xml elements
+ * \param p_this the VLC playlist object
+ * \return VLC_SUCCESS if some memory is available, otherwise VLC_ENONMEM
+ */
+int xspf_export_playlist( vlc_object_t *p_this )
+{
+ playlist_export_t *p_export = (playlist_export_t *)p_this;
+ export_writer_t pf_writer = (p_export->p_file)? export_write_to_file
+ : export_write_to_memory;
+ return xspf_export_playlist_internal( p_export, pf_writer );
+}
diff --git a/src/libvlccore.sym b/src/libvlccore.sym
index 325c8f6..23bbf02 100644
--- a/src/libvlccore.sym
+++ b/src/libvlccore.sym
@@ -323,6 +323,7 @@ playlist_CurrentPlayingItem
playlist_Deactivate
playlist_DeleteFromInput
playlist_Export
+playlist_ExportMemory
playlist_GetNextLeaf
playlist_GetPrevLeaf
playlist_GetNodeDuration
diff --git a/src/playlist/loadsave.c b/src/playlist/loadsave.c
index 605059f..25001d5 100644
--- a/src/playlist/loadsave.c
+++ b/src/playlist/loadsave.c
@@ -38,30 +38,44 @@
#include <vlc_url.h>
#include <vlc_modules.h>
-int playlist_Export( playlist_t * p_playlist, const char *psz_filename,
- playlist_item_t *p_export_root, const char *psz_type )
+static int playlist_Export_Internal( playlist_t * p_playlist, const char *psz_filename,
+ uint8_t **pp_buffer, playlist_item_t *p_export_root,
+ const char *psz_type )
{
- if( p_export_root == NULL ) return VLC_EGENERIC;
+ if( p_export_root == NULL
+ || (psz_filename == NULL && pp_buffer == NULL)
+ || (psz_filename && pp_buffer) )
+ return VLC_EGENERIC;
playlist_export_t *p_export =
vlc_custom_create( p_playlist, sizeof( *p_export ), "playlist export" );
if( unlikely(p_export == NULL) )
return VLC_ENOMEM;
- msg_Dbg( p_export, "saving %s to file %s",
- p_export_root->p_input->psz_name, psz_filename );
+ if ( psz_filename )
+ msg_Dbg( p_export, "saving %s to file %s",
+ p_export_root->p_input->psz_name, psz_filename );
+ else
+ msg_Dbg( p_export, "exporting %s to memory", p_export_root->p_input->psz_name );
int ret = VLC_EGENERIC;
/* Prepare the playlist_export_t structure */
p_export->p_root = p_export_root;
p_export->psz_filename = psz_filename;
- p_export->p_file = vlc_fopen( psz_filename, "wt" );
- if( p_export->p_file == NULL )
+ p_export->p_buffer = NULL;
+ p_export->i_buffer_length = 0;
+ p_export->i_buffer = 0;
+ p_export->p_file = NULL;
+ if (psz_filename)
{
- msg_Err( p_export, "could not create playlist file %s: %s",
- psz_filename, vlc_strerror_c(errno) );
- goto out;
+ p_export->p_file = vlc_fopen( psz_filename, "wt" );
+ if( p_export->p_file == NULL )
+ {
+ msg_Err( p_export, "could not create playlist file %s: %s",
+ psz_filename, vlc_strerror_c(errno) );
+ goto out;
+ }
}
module_t *p_module;
@@ -74,20 +88,44 @@ int playlist_Export( playlist_t * p_playlist, const char *psz_filename,
if( p_module != NULL )
{
module_unneed( p_export, p_module );
- if( !ferror( p_export->p_file ) )
- ret = VLC_SUCCESS;
+ if ( p_export->p_file )
+ {
+ if( !ferror( p_export->p_file ) )
+ ret = VLC_SUCCESS;
+ else
+ msg_Err( p_playlist, "could not write playlist file: %s",
+ vlc_strerror_c(errno) );
+ }
+ else if ( p_export->p_buffer == NULL )
+ {
+ msg_Err( p_playlist, "could not export playlist to memory" );
+ }
else
- msg_Err( p_playlist, "could not write playlist file: %s",
- vlc_strerror_c(errno) );
+ ret = VLC_SUCCESS;
}
else
- msg_Err( p_playlist, "could not export playlist" );
- fclose( p_export->p_file );
+ msg_Err( p_playlist, "could not export playlist (can't load module)" );
+
+ if ( p_export->p_file )
+ fclose( p_export->p_file );
+ else
+ *pp_buffer = p_export->p_buffer;
out:
vlc_object_release( p_export );
return ret;
}
+int playlist_ExportMemory( playlist_t *p_playlist, uint8_t **p_buffer, playlist_item_t *p_export_root, const char *psz_type )
+{
+ return playlist_Export_Internal( p_playlist, NULL, p_buffer, p_export_root, psz_type );
+}
+
+int playlist_Export( playlist_t * p_playlist, const char *psz_filename,
+ playlist_item_t *p_export_root, const char *psz_type )
+{
+ return playlist_Export_Internal( p_playlist, psz_filename, NULL, p_export_root, psz_type );
+}
+
int playlist_Import( playlist_t *p_playlist, const char *psz_file )
{
input_item_t *p_input;
--
1.9.3
More information about the vlc-devel
mailing list