annotate foosdk/sdk/foobar2000/SDK/input.cpp @ 1:20d02a178406 default tip

*: check in everything else yay
author Paper <paper@tflc.us>
date Mon, 05 Jan 2026 02:15:46 -0500
parents
children
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
rev   line source
1
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
1 #include "foobar2000-sdk-pch.h"
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
2 #include <exception>
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
3 #include "input.h"
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
4 #include "input_impl.h"
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
5 #include "album_art.h"
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
6 #include "file_info_impl.h"
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
7
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
8 service_ptr input_entry::open(const GUID & whatFor, file::ptr hint, const char * path, event_logger::ptr logger, abort_callback & aborter) {
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
9
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
10 #ifdef FOOBAR2000_DESKTOP
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
11 if ( whatFor == input_stream_info_reader::class_guid ) {
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
12 input_entry_v2::ptr v2;
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
13 if ( v2 &= this ) {
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
14 GUID g = v2->get_guid();
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
15 for (auto p : input_stream_info_reader_entry::enumerate()) {
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
16 if (p->get_guid() == g) {
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
17 return p->open(path, hint, aborter);
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
18 }
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
19 }
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
20 }
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
21 throw exception_io_unsupported_format();
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
22 }
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
23 #endif
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
24 if ( whatFor == album_art_extractor_instance::class_guid ) {
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
25 input_entry_v2::ptr v2;
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
26 if (v2 &= this) {
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
27 GUID g = v2->get_guid();
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
28 for (auto p : album_art_extractor::enumerate()) {
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
29 if (p->get_guid() == g) {
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
30 return p->open(hint, path, aborter);
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
31 }
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
32 }
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
33 }
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
34 throw exception_io_unsupported_format();
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
35 }
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
36 if ( whatFor == album_art_editor_instance::class_guid ) {
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
37 input_entry_v2::ptr v2;
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
38 if (v2 &= this) {
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
39 GUID g = v2->get_guid();
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
40 for (auto p : album_art_editor::enumerate()) {
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
41 if (p->get_guid() == g) {
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
42 return p->open(hint, path, aborter);
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
43 }
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
44 }
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
45 }
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
46 throw exception_io_unsupported_format();
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
47 }
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
48
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
49 input_entry_v3::ptr v3;
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
50
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
51 if (v3 &= this) {
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
52 return v3->open_v3( whatFor, hint, path, logger, aborter );
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
53 } else {
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
54 if (whatFor == input_decoder::class_guid) {
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
55 input_decoder::ptr obj;
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
56 open(obj, hint, path, aborter);
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
57 if ( logger.is_valid() ) {
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
58 input_decoder_v2::ptr v2;
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
59 if (v2 &= obj) v2->set_logger(logger);
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
60 }
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
61 return obj;
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
62 }
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
63 if (whatFor == input_info_reader::class_guid) {
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
64 input_info_reader::ptr obj;
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
65 open(obj, hint, path, aborter);
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
66 return obj;
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
67 }
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
68 if (whatFor == input_info_writer::class_guid) {
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
69 input_info_writer::ptr obj;
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
70 open(obj, hint, path, aborter);
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
71 return obj;
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
72 }
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
73 }
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
74
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
75 throw pfc::exception_not_implemented();
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
76 }
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
77
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
78 bool input_entry::g_find_service_by_path(service_ptr_t<input_entry> & p_out,const char * p_path)
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
79 {
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
80 auto ext = pfc::string_extension(p_path);
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
81 return g_find_service_by_path(p_out, p_path, ext );
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
82 }
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
83
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
84 bool input_entry::g_find_service_by_path(service_ptr_t<input_entry> & p_out,const char * p_path, const char * p_ext)
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
85 {
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
86 for (auto ptr : enumerate()) {
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
87 if (ptr->is_our_path(p_path,p_ext)) {
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
88 p_out = ptr;
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
89 return true;
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
90 }
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
91 }
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
92 return false;
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
93 }
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
94
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
95 bool input_entry::g_find_service_by_content_type(service_ptr_t<input_entry> & p_out,const char * p_content_type)
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
96 {
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
97 for (auto ptr : enumerate()) {
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
98 if (ptr->is_our_content_type(p_content_type)) {
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
99 p_out = ptr;
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
100 return true;
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
101 }
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
102 }
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
103 return false;
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
104 }
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
105
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
106
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
107 #if 0
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
108 static void prepare_for_open(service_ptr_t<input_entry> & p_service,service_ptr_t<file> & p_file,const char * p_path,filesystem::t_open_mode p_open_mode,abort_callback & p_abort,bool p_from_redirect)
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
109 {
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
110 if (p_file.is_empty())
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
111 {
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
112 service_ptr_t<filesystem> fs;
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
113 if (filesystem::g_get_interface(fs,p_path)) {
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
114 if (fs->supports_content_types()) {
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
115 fs->open(p_file,p_path,p_open_mode,p_abort);
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
116 }
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
117 }
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
118 }
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
119
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
120 if (p_file.is_valid())
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
121 {
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
122 pfc::string8 content_type;
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
123 if (p_file->get_content_type(content_type))
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
124 {
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
125 if (input_entry::g_find_service_by_content_type(p_service,content_type))
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
126 return;
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
127 }
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
128 }
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
129
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
130 if (input_entry::g_find_service_by_path(p_service,p_path))
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
131 {
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
132 if (p_from_redirect && p_service->is_redirect()) throw exception_io_unsupported_format();
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
133 return;
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
134 }
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
135
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
136 throw exception_io_unsupported_format();
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
137 }
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
138 #endif
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
139
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
140 bool input_entry::g_find_inputs_by_content_type(pfc::list_base_t<service_ptr_t<input_entry> > & p_out, const char * p_content_type, bool p_from_redirect) {
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
141 auto filter = [=] (input_entry::ptr p) {
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
142 return !(p_from_redirect && p->is_redirect());
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
143 };
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
144 return g_find_inputs_by_content_type_ex(p_out, p_content_type, filter );
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
145 }
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
146
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
147 bool input_entry::g_find_inputs_by_path(pfc::list_base_t<service_ptr_t<input_entry> > & p_out, const char * p_path, bool p_from_redirect) {
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
148 auto filter = [=] (input_entry::ptr p) {
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
149 return !(p_from_redirect && p->is_redirect());
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
150 };
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
151 return g_find_inputs_by_path_ex(p_out, p_path, filter);
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
152 }
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
153
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
154 bool input_entry::g_find_inputs_by_content_type_ex(pfc::list_base_t<service_ptr_t<input_entry> > & p_out, const char * p_content_type, input_filter_t filter ) {
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
155 bool ret = false;
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
156 for (auto ptr : enumerate()) {
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
157 if (filter(ptr)) {
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
158 if (ptr->is_our_content_type(p_content_type)) { p_out.add_item(ptr); ret = true; }
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
159 }
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
160 }
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
161 return ret;
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
162 }
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
163
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
164 bool input_entry::g_find_inputs_by_path_ex(pfc::list_base_t<service_ptr_t<input_entry> > & p_out, const char * p_path, input_filter_t filter ) {
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
165 auto extension = pfc::string_extension(p_path);
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
166 bool ret = false;
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
167 for( auto ptr : enumerate()) {
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
168 GUID guid = pfc::guid_null;
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
169 input_entry_v3::ptr ex;
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
170 if ( ex &= ptr ) guid = ex->get_guid();
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
171 if ( filter(ptr) ) {
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
172 if (ptr->is_our_path(p_path, extension)) { p_out.add_item(ptr); ret = true; }
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
173 }
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
174 }
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
175 return ret;
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
176 }
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
177
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
178 static GUID input_get_guid( input_entry::ptr e ) {
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
179 #ifdef FOOBAR2000_DESKTOP
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
180 input_entry_v2::ptr p;
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
181 if ( p &= e ) return p->get_guid();
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
182 #endif
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
183 return pfc::guid_null;
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
184 }
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
185
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
186 service_ptr input_entry::g_open_from_list(input_entry_list_t const & p_list, const GUID & whatFor, service_ptr_t<file> p_filehint, const char * p_path, event_logger::ptr logger, abort_callback & p_abort, GUID * outGUID) {
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
187 const t_size count = p_list.get_count();
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
188 if ( count == 0 ) {
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
189 // sanity
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
190 throw exception_io_unsupported_format();
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
191 } else if (count == 1) {
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
192 auto ret = p_list[0]->open(whatFor, p_filehint, p_path, logger, p_abort);
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
193 if ( outGUID != nullptr ) * outGUID = input_get_guid( p_list[0] );
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
194 return ret;
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
195 } else {
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
196 std::exception_ptr errData, errUnsupported;
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
197 for (t_size n = 0; n < count; n++) {
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
198 try {
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
199 auto ret = p_list[n]->open(whatFor, p_filehint, p_path, logger, p_abort);
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
200 if (outGUID != nullptr) * outGUID = input_get_guid(p_list[n]);
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
201 return ret;
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
202 } catch (exception_io_no_handler_for_path const &) {
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
203 //do nothing, skip over
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
204 } catch(exception_io_unsupported_format const &) {
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
205 if (!errUnsupported) errUnsupported = std::current_exception();
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
206 } catch (exception_io_data const &) {
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
207 if (!errData) errData = std::current_exception();
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
208 }
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
209 }
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
210 if (errData) std::rethrow_exception(errData);
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
211 if (errUnsupported) std::rethrow_exception(errUnsupported);
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
212 throw exception_io_unsupported_format();
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
213 }
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
214 }
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
215
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
216 #ifdef FOOBAR2000_DESKTOP
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
217 service_ptr input_manager::open_v2(const GUID & whatFor, file::ptr hint, const char * path, bool fromRedirect, event_logger::ptr logger, abort_callback & aborter, GUID * outUsedEntry) {
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
218 // We're wrapping open_v2() on top of old open().
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
219 // Assert on GUIDs that old open() is known to recognize.
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
220 PFC_ASSERT(whatFor == input_decoder::class_guid || whatFor == input_info_reader::class_guid || whatFor == input_info_writer::class_guid || whatFor == input_stream_selector::class_guid);
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
221
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
222 {
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
223 input_manager_v2::ptr v2;
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
224 if ( v2 &= this ) {
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
225 return v2->open_v2( whatFor, hint, path, fromRedirect, logger, aborter, outUsedEntry );
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
226 }
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
227 }
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
228
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
229 auto ret = open( whatFor, hint, path, fromRedirect, aborter, outUsedEntry );
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
230
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
231 #ifdef FB2K_HAVE_EVENT_LOGGER
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
232 if ( logger.is_valid() ) {
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
233 input_decoder_v2::ptr dec;
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
234 if (dec &= ret) {
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
235 dec->set_logger(logger);
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
236 }
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
237 }
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
238 #endif
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
239 return ret;
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
240 }
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
241 #endif
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
242
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
243 service_ptr input_entry::g_open(const GUID & whatFor, file::ptr p_filehint, const char * p_path, event_logger::ptr logger, abort_callback & p_abort, bool p_from_redirect) {
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
244
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
245 #ifdef FOOBAR2000_DESKTOP
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
246 return input_manager_v2::get()->open_v2(whatFor, p_filehint, p_path, p_from_redirect, logger, p_abort);
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
247 #else // FOOBAR2000_DESKTOP or not
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
248 const bool needWriteAcecss = !!(whatFor == input_info_writer::class_guid);
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
249
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
250 service_ptr_t<file> l_file = p_filehint;
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
251 if (l_file.is_empty()) {
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
252 service_ptr_t<filesystem> fs;
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
253 if (filesystem::g_get_interface(fs, p_path)) {
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
254 if (fs->supports_content_types()) {
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
255 fs->open(l_file, p_path, needWriteAcecss ? filesystem::open_mode_write_existing : filesystem::open_mode_read, p_abort);
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
256 }
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
257 }
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
258 }
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
259
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
260 if (l_file.is_valid()) {
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
261 pfc::string8 content_type;
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
262 if (l_file->get_content_type(content_type)) {
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
263 pfc::list_t< input_entry::ptr > list;
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
264 #if PFC_DEBUG
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
265 FB2K_DebugLog() << "attempting input open by content type: " << content_type;
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
266 #endif
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
267 if (g_find_inputs_by_content_type(list, content_type, p_from_redirect)) {
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
268 try {
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
269 return g_open_from_list(list, whatFor, l_file, p_path, logger, p_abort);
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
270 } catch (exception_io_unsupported_format const &) {
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
271 #if PFC_DEBUG
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
272 FB2K_DebugLog() << "Failed to open by content type, using fallback";
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
273 #endif
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
274 }
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
275 }
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
276 }
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
277 }
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
278
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
279 #if PFC_DEBUG
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
280 FB2K_DebugLog() << "attempting input open by path: " << p_path;
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
281 #endif
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
282 {
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
283 pfc::list_t< input_entry::ptr > list;
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
284 if (g_find_inputs_by_path(list, p_path, p_from_redirect)) {
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
285 return g_open_from_list(list, whatFor, l_file, p_path, logger, p_abort);
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
286 }
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
287 }
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
288
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
289 throw exception_io_unsupported_format();
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
290 #endif // not FOOBAR2000_DESKTOP
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
291 }
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
292
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
293 void input_entry::g_open_for_decoding(service_ptr_t<input_decoder> & p_instance,service_ptr_t<file> p_filehint,const char * p_path,abort_callback & p_abort,bool p_from_redirect) {
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
294 TRACK_CALL_TEXT("input_entry::g_open_for_decoding");
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
295 p_instance ^= g_open(input_decoder::class_guid, p_filehint, p_path, nullptr, p_abort, p_from_redirect);
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
296 }
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
297
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
298 void input_entry::g_open_for_info_read(service_ptr_t<input_info_reader> & p_instance,service_ptr_t<file> p_filehint,const char * p_path,abort_callback & p_abort,bool p_from_redirect) {
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
299 TRACK_CALL_TEXT("input_entry::g_open_for_info_read");
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
300 p_instance ^= g_open(input_info_reader::class_guid, p_filehint, p_path, nullptr, p_abort, p_from_redirect);
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
301 }
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
302
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
303 void input_entry::g_open_for_info_write(service_ptr_t<input_info_writer> & p_instance,service_ptr_t<file> p_filehint,const char * p_path,abort_callback & p_abort,bool p_from_redirect) {
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
304 TRACK_CALL_TEXT("input_entry::g_open_for_info_write");
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
305 p_instance ^= g_open(input_info_writer::class_guid, p_filehint, p_path, nullptr, p_abort, p_from_redirect);
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
306 }
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
307
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
308 void input_entry::g_open_for_info_write_timeout(service_ptr_t<input_info_writer> & p_instance,service_ptr_t<file> p_filehint,const char * p_path,abort_callback & p_abort,double p_timeout,bool p_from_redirect) {
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
309 pfc::lores_timer timer;
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
310 timer.start();
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
311 for(;;) {
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
312 try {
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
313 g_open_for_info_write(p_instance,p_filehint,p_path,p_abort,p_from_redirect);
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
314 break;
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
315 } catch(exception_io_sharing_violation const &) {
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
316 if (timer.query() > p_timeout) throw;
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
317 p_abort.sleep(0.01);
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
318 }
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
319 }
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
320 }
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
321
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
322 bool input_entry::g_is_supported_path(const char * p_path)
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
323 {
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
324 auto ext = pfc::string_extension (p_path);
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
325 for( auto ptr : enumerate() ) {
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
326 if (ptr->is_our_path(p_path,ext)) return true;
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
327 }
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
328 return false;
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
329 }
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
330
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
331
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
332
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
333 void input_open_file_helper(service_ptr_t<file> & p_file,const char * p_path,t_input_open_reason p_reason,abort_callback & p_abort)
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
334 {
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
335 if (p_file.is_empty()) {
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
336 switch(p_reason) {
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
337 default:
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
338 uBugCheck();
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
339 case input_open_info_read:
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
340 case input_open_decode:
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
341 filesystem::g_open(p_file,p_path,filesystem::open_mode_read,p_abort);
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
342 break;
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
343 case input_open_info_write:
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
344 filesystem::g_open(p_file,p_path,filesystem::open_mode_write_existing,p_abort);
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
345 break;
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
346 }
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
347 } else {
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
348 p_file->reopen(p_abort);
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
349 }
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
350 }
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
351
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
352 uint32_t input_entry::g_flags_for_path( const char * path, uint32_t mask ) {
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
353 #if defined(FOOBAR2000_DESKTOP) && FOOBAR2000_TARGET_VERSION >= 80
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
354 return input_manager_v3::get()->flags_for_path(path, mask);
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
355 #else
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
356 #ifdef FOOBAR2000_DESKTOP
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
357 input_manager_v3::ptr api;
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
358 if ( input_manager_v3::tryGet(api) ) {
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
359 return api->flags_for_path(path, mask);
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
360 }
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
361 #endif
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
362 uint32_t ret = 0;
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
363 service_enum_t<input_entry> e; input_entry::ptr p;
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
364 auto ext = pfc::string_extension(path);
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
365 while(e.next(p)) {
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
366 uint32_t f = p->get_flags() & mask;
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
367 if ( f != 0 && p->is_our_path( path, ext ) ) ret |= f;;
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
368 }
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
369 return ret;
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
370 #endif
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
371 }
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
372 uint32_t input_entry::g_flags_for_content_type( const char * ct, uint32_t mask ) {
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
373 #if defined(FOOBAR2000_DESKTOP) && FOOBAR2000_TARGET_VERSION >= 80
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
374 return input_manager_v3::get()->flags_for_content_type(ct, mask);
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
375 #else
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
376 #ifdef FOOBAR2000_DESKTOP
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
377 input_manager_v3::ptr api;
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
378 if ( input_manager_v3::tryGet(api) ) {
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
379 return api->flags_for_content_type( ct, mask );
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
380 }
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
381 #endif
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
382 uint32_t ret = 0;
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
383 service_enum_t<input_entry> e; input_entry::ptr p;
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
384 while(e.next(p)) {
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
385 uint32_t f = p->get_flags() & mask;
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
386 if ( f != 0 && p->is_our_content_type(ct) ) ret |= f;
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
387 }
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
388 return ret;
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
389 #endif
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
390 }
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
391
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
392 bool input_entry::g_are_parallel_reads_slow(const char * path) {
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
393 return g_flags_for_path(path, flag_parallel_reads_slow) != 0;
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
394 }
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
395
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
396 void input_entry_v3::open_for_decoding(service_ptr_t<input_decoder> & p_instance, service_ptr_t<file> p_filehint, const char * p_path, abort_callback & p_abort) {
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
397 p_instance ^= open_v3( input_decoder::class_guid, p_filehint, p_path, nullptr, p_abort );
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
398 }
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
399 void input_entry_v3::open_for_info_read(service_ptr_t<input_info_reader> & p_instance, service_ptr_t<file> p_filehint, const char * p_path, abort_callback & p_abort) {
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
400 p_instance ^= open_v3(input_info_reader::class_guid, p_filehint, p_path, nullptr, p_abort);
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
401 }
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
402 void input_entry_v3::open_for_info_write(service_ptr_t<input_info_writer> & p_instance, service_ptr_t<file> p_filehint, const char * p_path, abort_callback & p_abort) {
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
403 p_instance ^= open_v3(input_info_writer::class_guid, p_filehint, p_path, nullptr, p_abort);
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
404 }
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
405
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
406 void input_info_writer::remove_tags_fallback(abort_callback & abort) {
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
407 uint32_t total = this->get_subsong_count();
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
408 file_info_impl blank;
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
409 for( uint32_t walk = 0; walk < total; ++ walk ) {
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
410 this->set_info( this->get_subsong(walk), blank, abort );
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
411 }
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
412 this->commit( abort );
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
413 }
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
414
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
415 t_filestats input_info_reader_v2::get_file_stats(abort_callback& a) {
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
416 return this->get_stats2(stats2_size | stats2_timestamp, a).to_legacy();
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
417 }
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
418
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
419 t_filestats2 input_info_reader::get_stats2_(const char* fallbackPath, uint32_t f, abort_callback& a) {
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
420 t_filestats2 ret;
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
421 input_info_reader_v2::ptr v2;
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
422 if (v2 &= this) {
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
423 ret = v2->get_stats2(f, a);
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
424 } else if ((f & ~stats2_legacy) == 0) {
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
425 t_filestats subset = this->get_file_stats(a);
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
426 ret.m_size = subset.m_size;
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
427 ret.m_timestamp = subset.m_timestamp;
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
428 } else {
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
429 try {
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
430 auto fs = filesystem::tryGet(fallbackPath);
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
431 if (fs.is_valid()) ret = fs->get_stats2_(fallbackPath, f, a);
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
432 } catch (exception_io const &) {}
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
433 }
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
434 return ret;
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
435 }
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
436
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
437 GUID input_entry::get_guid_() {
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
438 auto ret = pfc::guid_null;
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
439 input_entry_v2::ptr v2;
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
440 if ( v2 &= this ) ret = v2->get_guid();
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
441 return ret;
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
442 }
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
443
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
444 const char* input_entry::get_name_() {
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
445 const char * ret = "<legacy object>";
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
446 input_entry_v2::ptr v2;
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
447 if ( v2 &= this ) ret = v2->get_name();
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
448 return ret;
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
449 }
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
450
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
451 input_entry::ptr input_entry::g_find_by_guid(const GUID& guid) {
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
452 for (auto ptr : enumerate()) {
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
453 input_entry_v2::ptr v2;
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
454 if (v2 &= ptr) {
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
455 if ( guid == v2->get_guid() ) return v2;
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
456 }
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
457 }
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
458 return nullptr;
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
459 }