Skip to content

Commit a2e56e5

Browse files
committed
MimeDetector added setActive() and clear()
1 parent 28fee5a commit a2e56e5

File tree

1 file changed

+75
-41
lines changed

1 file changed

+75
-41
lines changed

src/AudioTools/CoreAudio/AudioMetaData/MimeDetector.h

Lines changed: 75 additions & 41 deletions
Original file line numberDiff line numberDiff line change
@@ -8,47 +8,50 @@ namespace audio_tools {
88

99
/**
1010
* @brief Abstract interface for classes that can provide MIME type information.
11-
*
12-
* This class defines a simple interface for objects that can determine and provide
13-
* MIME type strings. It serves as a base class for various MIME detection and
14-
* source identification implementations within the audio tools framework.
15-
*
11+
*
12+
* This class defines a simple interface for objects that can determine and
13+
* provide MIME type strings. It serves as a base class for various MIME
14+
* detection and source identification implementations within the audio tools
15+
* framework.
16+
*
1617
* Classes implementing this interface should provide logic to determine the
1718
* appropriate MIME type based on their specific context (e.g., file content,
1819
* stream headers, file extensions, etc.).
19-
*
20-
* @note This is a pure virtual interface class and cannot be instantiated directly.
20+
*
21+
* @note This is a pure virtual interface class and cannot be instantiated
22+
* directly.
2123
* @ingroup codecs
22-
* @ingroup decoder
24+
* @ingroup decoder
2325
* @author Phil Schatzmann
2426
* @copyright GPLv3
2527
*/
2628
class MimeSource {
27-
public:
29+
public:
2830
/**
2931
* @brief Get the MIME type string.
30-
*
32+
*
3133
* Pure virtual method that must be implemented by derived classes to return
3234
* the appropriate MIME type string for the current context.
33-
*
34-
* @return const char* Pointer to a null-terminated string containing the MIME type.
35-
* The string should follow standard MIME type format (e.g., "audio/mpeg").
36-
* Returns nullptr if MIME type cannot be determined.
37-
*
38-
* @note The returned pointer should remain valid for the lifetime of the object
39-
* or until the next call to this method.
35+
*
36+
* @return const char* Pointer to a null-terminated string containing the MIME
37+
* type. The string should follow standard MIME type format (e.g.,
38+
* "audio/mpeg"). Returns nullptr if MIME type cannot be determined.
39+
*
40+
* @note The returned pointer should remain valid for the lifetime of the
41+
* object or until the next call to this method.
4042
*/
4143
virtual const char* mime() = 0;
4244
};
4345

4446
/**
4547
* @brief Logic to detemine the mime type from the content.
4648
* By default the following mime types are supported (audio/aac, audio/mpeg,
47-
* audio/vnd.wave, audio/ogg, audio/flac). You can register your own custom detection logic
48-
* to cover additional file types.
49+
* audio/vnd.wave, audio/ogg, audio/flac). You can register your own custom
50+
* detection logic to cover additional file types.
4951
*
5052
* Please note that the distinction between mp3 and aac is difficult and might
51-
* fail in some cases. FLAC detection supports both native FLAC and OGG FLAC formats.
53+
* fail in some cases. FLAC detection supports both native FLAC and OGG FLAC
54+
* formats.
5255
* @ingroup codecs
5356
* @ingroup decoder
5457
* @author Phil Schatzmann
@@ -57,25 +60,35 @@ class MimeSource {
5760

5861
class MimeDetector : public MimeSource {
5962
public:
60-
MimeDetector() {
61-
setCheck("audio/vnd.wave", checkWAV);
62-
setCheck("audio/flac", checkFLAC);
63-
setCheck("audio/ogg; codecs=flac", checkOggFLAC);
64-
setCheck("audio/ogg; codecs=opus", checkOggOpus);
65-
setCheck("audio/ogg; codec=vorbis", checkOggVorbis);
66-
setCheck("audio/ogg", checkOGG);
67-
setCheck("video/MP2T", checkMP2T);
68-
setCheck("audio/prs.sid", checkSID);
69-
setCheck("audio/m4a", checkM4A);
70-
setCheck("audio/mpeg", checkMP3Ext);
71-
setCheck("audio/aac", checkAACExt);
63+
MimeDetector(bool setupDefault = true) {
64+
if (setupDefault) {
65+
setCheck("audio/vnd.wave", checkWAV);
66+
setCheck("audio/flac", checkFLAC);
67+
setCheck("audio/ogg; codecs=flac", checkOggFLAC);
68+
setCheck("audio/ogg; codecs=opus", checkOggOpus);
69+
setCheck("audio/ogg; codec=vorbis", checkOggVorbis);
70+
setCheck("audio/ogg", checkOGG);
71+
setCheck("video/MP2T", checkMP2T);
72+
setCheck("audio/prs.sid", checkSID);
73+
setCheck("audio/m4a", checkM4A);
74+
setCheck("audio/mpeg", checkMP3Ext);
75+
setCheck("audio/aac", checkAACExt);
76+
}
7277
}
7378

79+
/// Sets is_first to true
7480
bool begin() {
7581
is_first = true;
7682
return true;
7783
}
7884

85+
/// Clears the actual mime and resets the state
86+
void end(){
87+
actual_mime = nullptr;
88+
is_first = true;
89+
}
90+
91+
7992
/// write the header to determine the mime
8093
size_t write(uint8_t* data, size_t len) {
8194
actual_mime = default_mime;
@@ -151,7 +164,7 @@ class MimeDetector : public MimeSource {
151164

152165
static bool checkFLAC(uint8_t* start, size_t len) {
153166
if (len < 4) return false;
154-
167+
155168
// Native FLAC streams start with "fLaC" (0x664C6143)
156169
if (memcmp(start, "fLaC", 4) == 0) {
157170
return true;
@@ -170,12 +183,13 @@ class MimeDetector : public MimeSource {
170183
return true;
171184
}
172185
// Also check for the more specific OGG FLAC header
173-
if (i < len - 5 && start[i] == 0x7F && memcmp(start + i + 1, "FLAC", 4) == 0) {
186+
if (i < len - 5 && start[i] == 0x7F &&
187+
memcmp(start + i + 1, "FLAC", 4) == 0) {
174188
return true;
175189
}
176190
}
177191
}
178-
192+
179193
return false;
180194
}
181195

@@ -202,7 +216,7 @@ class MimeDetector : public MimeSource {
202216
}
203217
}
204218
}
205-
219+
206220
return false;
207221
}
208222

@@ -229,7 +243,7 @@ class MimeDetector : public MimeSource {
229243
}
230244
}
231245
}
232-
246+
233247
return false;
234248
}
235249

@@ -250,10 +264,10 @@ class MimeDetector : public MimeSource {
250264

251265
// prevent false detecton by mp3 files
252266
if (memcmp(header, "ID3", 3) == 0) return false;
253-
254-
// Special hack when we position to start of mdat box
267+
268+
// Special hack when we position to start of mdat box
255269
if (memcmp(header + 4, "mdat", 4) != 0) return true;
256-
270+
257271
// Check for "ftyp" at offset 4
258272
if (memcmp(header + 4, "ftyp", 4) != 0) return false;
259273

@@ -269,10 +283,30 @@ class MimeDetector : public MimeSource {
269283
/// Provides the default mime type if no mime could be determined
270284
void setDefaultMime(const char* mime) { default_mime = mime; }
271285

286+
/// sets the mime rules active or inactive
287+
int setMimeActive(const char* mimePrefix, bool active) {
288+
int result = 0;
289+
for (auto& check : checks) {
290+
if (StrView(check.mime).startsWith(mimePrefix)) {
291+
check.is_active = active;
292+
result++;
293+
}
294+
}
295+
return result;
296+
}
297+
298+
/// Clears all mime rules and resets the actual selection
299+
void clear() {
300+
checks.clear();
301+
actual_mime = nullptr;
302+
is_first = true;
303+
}
304+
272305
protected:
273306
struct Check {
274307
const char* mime = nullptr;
275308
bool (*check)(uint8_t* data, size_t len) = nullptr;
309+
bool is_active = true;
276310
Check(const char* mime, bool (*check)(uint8_t* data, size_t len)) {
277311
this->mime = mime;
278312
this->check = check;
@@ -300,7 +334,7 @@ class MimeDetector : public MimeSource {
300334
const char* lookupMime(uint8_t* data, size_t len) {
301335
for (int j = 0; j < checks.size(); j++) {
302336
Check l_check = checks[j];
303-
if (l_check.check(data, len)) {
337+
if (l_check.is_active && l_check.check(data, len)) {
304338
return l_check.mime;
305339
}
306340
}

0 commit comments

Comments
 (0)