[vlc-devel] [PATCH 3/8] gui/skins2: add ThemeLoader::unarchive
Rémi Denis-Courmont
remi at remlab.net
Fri Jan 13 05:47:03 CET 2017
On January 13, 2017 2:21:18 AM GMT+08:00, "Filip Roséen" <filip at atch.se> wrote:
>---
>
>This implementation could be written in a cleaner manner, but it
>requires changes to the core. I will submit an independent patch for a
>refactor of this function at a later time (when some upcoming (soon to
>be proposed) minor changes to the core have been discussed).
>
>---
>modules/gui/skins2/src/theme_loader.cpp | 107
>++++++++++++++++++++++++++++++++
> modules/gui/skins2/src/theme_loader.hpp | 2 +
> 2 files changed, 109 insertions(+)
>
>diff --git a/modules/gui/skins2/src/theme_loader.cpp
>b/modules/gui/skins2/src/theme_loader.cpp
>index 31f1c550df..fb0811d4b4 100644
>--- a/modules/gui/skins2/src/theme_loader.cpp
>+++ b/modules/gui/skins2/src/theme_loader.cpp
>@@ -29,9 +29,13 @@
> #include <fcntl.h>
> #include <sys/stat.h>
> #include <unistd.h>
>+#include <fstream>
>+#include <memory>
>
> #include <vlc_common.h>
> #include <vlc_fs.h>
>+#include <vlc_url.h>
>+#include <vlc_stream_extractor.h>
>
> #include "theme_loader.hpp"
> #include "theme.hpp"
>@@ -351,6 +355,109 @@ bool ThemeLoader::extract( const std::string
>&fileName )
> return result;
> }
>
>+bool ThemeLoader::unarchive( const std::string& fileName, const
>std::string &tempPath )
>+{
>+#define UPTR_HELPER(type,deleter) []( type * data ) { \
>+ return std::unique_ptr< type, decltype( deleter )> ( data,
>deleter ); }
>+
>+ auto make_input_node_ptr = UPTR_HELPER( input_item_node_t,
>&input_item_node_Delete );
>+ auto make_input_item_ptr = UPTR_HELPER( input_item_t,
>&input_item_Release );
>+ auto make_stream_ptr = UPTR_HELPER( stream_t, &vlc_stream_Delete
>);
>+ auto make_cstr_ptr = UPTR_HELPER( char, &std::free );
>+
>+#undef UPTR_HELPER
>+
>+ auto uri = make_cstr_ptr( vlc_path2uri( fileName.c_str(), "file" )
>);
>+ if( !uri )
>+ {
>+ msg_Err( getIntf(), "unable to convert %s to local URI",
>+ fileName.c_str() );
>+ return false;
>+ }
>+
>+ auto input = make_stream_ptr( vlc_stream_NewURL( getIntf(),
>uri.get() ) );
>+ if( !input )
>+ {
>+ msg_Err( getIntf(), "unable to open %s", uri.get() );
>+ return false;
>+ }
>+
>+ stream_t* stream = input.get();
>+ if( vlc_stream_extractor_Attach( &stream, NULL, NULL ) )
>+ {
>+ msg_Err( getIntf(), "unable to attach extractor, treat as
>XML!" );
>+ }
>+ else
>+ {
>+ input.release();
>+ input.reset( stream );
>+
>+ auto item = make_input_item_ptr( input_item_New(
>"vlc://dummy", "vlc://dummy" ) );
>+ auto node = make_input_node_ptr(
>(input_item_node_t*)std::calloc( 1, sizeof( input_item_node_t ) ) );
>+
>+ if( !item || !node )
>+ return false;
>+
>+ node->p_item = item.release();
>+
>+ if( vlc_stream_ReadDir( input.get(), node.get() ) )
>+ {
>+ msg_Err( getIntf(), "unable to read items in %s",
>uri.get() );
>+ return false;
>+ }
>+
>+ for( int i = 0; i < node->i_children; ++i )
>+ {
>+ auto child = node->pp_children[i]->p_item;
>+ auto child_stream = make_stream_ptr( vlc_stream_NewURL(
>getIntf(), uri.get() ) );
>+ if( !child_stream )
>+ {
>+ msg_Err( getIntf(), "unable to open %s for reading",
>child->psz_name );
>+ }
>+
>+ stream_t* stream = child_stream.get();
>+ if( vlc_stream_extractor_Attach( &stream, child->psz_name,
>NULL ) )
>+ {
>+ msg_Err( getIntf(), "unable to locate %s within %s",
>+ child->psz_name, fileName.c_str() );
>+
>+ return false;
>+ }
>+
>+ child_stream.release();
>+ child_stream.reset( stream );
>+
>+ auto out_path = tempPath + "/" + child->psz_name;
>+
>+ { /* create directory tree */
>+ auto out_directory = out_path.substr( 0,
>out_path.find_last_of( '/' ) );
>+
>+ if( makedir( out_directory.c_str() ) == false )
>+ {
>+ msg_Err( getIntf(), "failed to create directory
>tree for %s (%s)",
>+ out_path.c_str(), out_directory.c_str()
>);
>+
>+ return false;
>+ }
>+ }
>+
>+ { /* write data to disk */
>+ std::ofstream out_stream( out_path, std::ios::binary
>);
>+
>+ char buf[1024];
>+ ssize_t n;
>+
>+ while( ( n = vlc_stream_Read( child_stream.get(), buf,
>sizeof buf ) ) > 0 )
>+ out_stream.write( buf, n );
>+
>+ msg_Dbg( getIntf(), "finished writing %zu bytes to
>%s",
>+ size_t{ out_stream.tellp() }, out_path.c_str() );
>+ }
>+ }
>+ }
>+
>+ return true;
>+}
>
> void ThemeLoader::deleteTempFiles( const std::string &path )
> {
>diff --git a/modules/gui/skins2/src/theme_loader.hpp
>b/modules/gui/skins2/src/theme_loader.hpp
>index b922cd367f..e5b35b150f 100644
>--- a/modules/gui/skins2/src/theme_loader.hpp
>+++ b/modules/gui/skins2/src/theme_loader.hpp
>@@ -48,6 +48,8 @@ private:
> */
> bool extract( const std::string &fileName );
>
>+ bool unarchive( const std::string &fileName, const std::string
>&tempPath );
>+
> /// Extract files from a tar.gz archive
> /**
> * Expects strings from the current locale.
>--
>2.11.0
>
>_______________________________________________
>vlc-devel mailing list
>To unsubscribe or modify your subscription options:
>https://mailman.videolan.org/listinfo/vlc-devel
Does C++ file I/O handle the atomic close on exec flag correctly? Does it handle character sets correctly (especially on Windows)? And even if it does, do we want yet another file I/O API?
--
Rémi Denis-Courmont
More information about the vlc-devel
mailing list