Cog/Plugins/OpenMPT/OpenMPT/OMPTMetadataReader.mm
Christopher Snowhill 794a9d2e7c
Some checks failed
Check if Cog buildable / Build Universal Cog.app (push) Has been cancelled
Bug Fix: Chase the dict keys with periods problem
This was a more prolific problem than I thought. Hopefully that's the
last that I need to fix.

Signed-off-by: Christopher Snowhill <kode54@gmail.com>
2025-06-07 06:30:14 -07:00

95 lines
2.2 KiB
Text
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

//
// OMPTMetadataReader.m
// OpenMPT
//
// Created by Christopher Snowhill on 1/4/18.
// Copyright 2018 __LoSnoCo__. All rights reserved.
//
#import "OMPTMetadataReader.h"
#import "OMPTDecoder.h"
#import <libOpenMPT/libopenmpt.hpp>
#import "Logging.H"
@implementation OMPTMetadataReader
+ (NSArray *)fileTypes {
return [OMPTDecoder fileTypes];
}
+ (NSArray *)mimeTypes {
return [OMPTDecoder mimeTypes];
}
+ (float)priority {
return 1.0f;
}
static void setDictionary(NSMutableDictionary *dict, NSString *tag, NSString *value) {
NSString *realKey = [tag stringByReplacingOccurrencesOfString:@"." withString:@""];
NSMutableArray *array = [dict valueForKey:realKey];
if(!array) {
array = [[NSMutableArray alloc] init];
[dict setObject:array forKey:realKey];
}
[array addObject:value];
}
+ (NSDictionary *)metadataForURL:(NSURL *)url {
id audioSourceClass = NSClassFromString(@"AudioSource");
id<CogSource> source = [audioSourceClass audioSourceForURL:url];
if(![source open:url])
return @{};
if(![source seekable])
return @{};
[source seek:0 whence:SEEK_END];
long size = [source tell];
[source seek:0 whence:SEEK_SET];
try {
std::vector<char> data(static_cast<std::size_t>(size));
[source read:data.data() amount:size];
int track_num;
if([[url fragment] length] == 0)
track_num = 0;
else
track_num = [[url fragment] intValue];
std::map<std::string, std::string> ctls;
openmpt::module *mod = new openmpt::module(data, std::clog, ctls);
NSMutableDictionary *dict = [[NSMutableDictionary alloc] init];
std::vector<std::string> keys = mod->get_metadata_keys();
for(std::vector<std::string>::iterator key = keys.begin(); key != keys.end(); ++key) {
@autoreleasepool {
NSString *tag = guess_encoding_of_string((*key).c_str());
NSString *value = guess_encoding_of_string(mod->get_metadata(*key).c_str());
if(*key == "type")
continue;
else if(*key == "type_long") {
setDictionary(dict, @"codec", value);
} else {
setDictionary(dict, tag, value);
}
}
}
delete mod;
return dict;
} catch(std::exception &e) {
ALog(@"Exception caught while reading metadata with OpenMPT: %s", e.what());
return @{};
}
}
@end