-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy patharchive_renamer.h
122 lines (104 loc) · 3.59 KB
/
archive_renamer.h
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
#ifndef _ARCHIVE_RENAMER_H_
#define _ARCHIVE_RENAMER_H_
#include <foobar2000.h>
#define archive_renamed_factory(src_ext, impl_ext) \
namespace src_ext##impl_ext { \
extern char const ext_##src_ext[] = #src_ext; \
extern char const ext_##impl_ext[] = #impl_ext; \
static archive_factory_t<archive_renamed<ext_##src_ext, ext_##impl_ext>> g_archive_renamed_factory; \
}
template <const char * src_ext, const char * impl_ext>
class archive_renamed : public archive_impl
{
class archive_renamed_callback : public archive_callback
{
archive_callback & m_callback;
pfc::string8 m_extension;
public:
archive_renamed_callback( archive_callback & p_callback, const char * p_extension ) : m_callback( p_callback ), m_extension( p_extension ) { }
virtual bool on_entry( archive * owner, const char * url, const t_filestats & p_stats, const service_ptr_t<file> & p_reader )
{
pfc::string8 m_url, archive, file;
archive_impl::g_parse_unpack_path( url, archive, file );
archive_impl::g_make_unpack_path( m_url, pfc::string_replace_extension( archive, m_extension ), file, impl_ext );
return m_callback.on_entry( owner, m_url, p_stats, p_reader );
}
bool is_aborting() const {return m_callback.is_aborting();}
abort_callback_event get_abort_event() const {return m_callback.get_abort_event();}
};
static bool g_query_renamed_service( service_ptr_t<archive> & p_arch, pfc::string8 & p_path, const char * p_archive, const char * p_file )
{
g_make_unpack_path( p_path, p_archive, p_file, impl_ext );
service_enum_t<filesystem> e;
service_ptr_t<filesystem> f;
while( e.next( f ) )
{
service_ptr_t<archive> arch;
if (f->service_query_t(arch))
{
if (arch->is_our_path(p_path))
{
p_arch = arch;
return true;
}
}
}
return false;
}
public:
virtual bool supports_content_types()
{
return false;
}
virtual const char * get_archive_type()
{
return src_ext;
}
virtual t_filestats get_stats_in_archive( const char * p_archive, const char * p_file, abort_callback & p_abort )
{
#if 0
pfc::string8 m_path;
service_ptr_t< archive > m_arch;
if (g_query_renamed_service( m_arch, m_path, p_archive, p_file ))
{
bool dummy;
t_filestats m_stats;
m_arch->get_stats( m_path, m_stats, dummy, p_abort );
return m_stats;
}
else
#endif
throw exception_io_unsupported_format();
}
virtual void open_archive( service_ptr_t< file > & p_out, const char * p_archive, const char * p_file, abort_callback & p_abort )
{
#if 0
pfc::string8 m_path;
service_ptr_t< archive > m_arch;
if (g_query_renamed_service( m_arch, m_path, p_archive, p_file ))
{
m_arch->open( p_out, m_path, open_mode_read, p_abort );
}
else
#endif
throw exception_io_unsupported_format();
}
virtual void archive_list( const char * path, const service_ptr_t< file > & p_reader, archive_callback & p_out, bool p_want_readers )
{
pfc::string_extension p_extension( path );
if ( stricmp_utf8( p_extension, src_ext ) )
throw exception_io_unsupported_format();
pfc::string8 m_path;
service_ptr_t< archive > m_arch;
if (g_query_renamed_service( m_arch, m_path, path, src_ext ))
{
service_ptr_t< file > m_file = p_reader;
if ( m_file.is_empty() )
filesystem::g_open( m_file, path, filesystem::open_mode_read, p_out );
archive_renamed_callback m_out( p_out, p_extension );
m_arch->archive_list( pfc::string_replace_extension(path, impl_ext), m_file, m_out, p_want_readers );
}
else throw exception_io_unsupported_format();
}
};
#endif