Unicode metadata: Change most logic to use guesser
Most file formats the player supports may or may not have UTF-8 safe strings in their metadata. This should not be assumed to be UTF-8, and when it is assumed, it results in nil NSString objects, which results in inline initializers crashing due to uncaught exceptions. Signed-off-by: Christopher Snowhill <kode54@gmail.com>swiftingly
parent
f7dc6beda1
commit
8cf37cadf3
|
@ -60,9 +60,9 @@
|
|||
NSString *artist = @"";
|
||||
|
||||
if(!p_player->gettitle().empty())
|
||||
title = [NSString stringWithUTF8String:p_player->gettitle().c_str()];
|
||||
title = guess_encoding_of_string(p_player->gettitle().c_str());
|
||||
if(!p_player->getauthor().empty())
|
||||
artist = [NSString stringWithUTF8String:p_player->getauthor().c_str()];
|
||||
artist = guess_encoding_of_string(p_player->getauthor().c_str());
|
||||
|
||||
delete p_player;
|
||||
delete p_emu;
|
||||
|
|
|
@ -53,7 +53,7 @@ static NSString *g_make_unpack_path(NSString *archive, NSString *file, NSString
|
|||
NSMutableArray *files = [NSMutableArray array];
|
||||
|
||||
while(!fex_done(fex)) {
|
||||
NSString *name = [NSString stringWithUTF8String:fex_name(fex)];
|
||||
NSString *name = guess_encoding_of_string(fex_name(fex));
|
||||
if([[NSClassFromString(@"AudioPlayer") fileTypes] containsObject:[[name pathExtension] lowercaseString]])
|
||||
[files addObject:[NSURL URLWithDataRepresentation:[g_make_unpack_path([url path], name, @"fex") dataUsingEncoding:NSUTF8StringEncoding] relativeToURL:nil]];
|
||||
fex_next(fex);
|
||||
|
|
|
@ -92,7 +92,7 @@ static BOOL g_parse_unpack_path(NSString *src, NSString **archive, NSString **fi
|
|||
}
|
||||
|
||||
while(!fex_done(fex)) {
|
||||
if([file isEqualToString:[NSString stringWithUTF8String:fex_name(fex)]])
|
||||
if([file isEqualToString:guess_encoding_of_string(fex_name(fex))])
|
||||
break;
|
||||
fex_next(fex);
|
||||
}
|
||||
|
|
|
@ -523,7 +523,7 @@ static uint8_t reverse_bits[0x100];
|
|||
if(formatCtx->metadata) {
|
||||
while((tag = av_dict_get(formatCtx->metadata, "", tag, AV_DICT_IGNORE_SUFFIX))) {
|
||||
if(!strcasecmp(tag->key, "streamtitle")) {
|
||||
NSString *artistTitle = [NSString stringWithUTF8String:tag->value];
|
||||
NSString *artistTitle = guess_encoding_of_string(tag->value);
|
||||
NSArray *splitValues = [artistTitle componentsSeparatedByString:@" - "];
|
||||
_artist = @"";
|
||||
_title = [splitValues objectAtIndex:0];
|
||||
|
@ -532,37 +532,37 @@ static uint8_t reverse_bits[0x100];
|
|||
_title = [splitValues objectAtIndex:1];
|
||||
}
|
||||
} else if(!strcasecmp(tag->key, "icy-url")) {
|
||||
_album = [NSString stringWithUTF8String:tag->value];
|
||||
_album = guess_encoding_of_string(tag->value);
|
||||
} else if(!strcasecmp(tag->key, "icy-genre")) {
|
||||
_genre = [NSString stringWithUTF8String:tag->value];
|
||||
_genre = guess_encoding_of_string(tag->value);
|
||||
} else if(!strcasecmp(tag->key, "album")) {
|
||||
_album = [NSString stringWithUTF8String:tag->value];
|
||||
_album = guess_encoding_of_string(tag->value);
|
||||
} else if(!strcasecmp(tag->key, "album_artist")) {
|
||||
_albumartist = [NSString stringWithUTF8String:tag->value];
|
||||
_albumartist = guess_encoding_of_string(tag->value);
|
||||
} else if(!strcasecmp(tag->key, "artist")) {
|
||||
_artist = [NSString stringWithUTF8String:tag->value];
|
||||
_artist = guess_encoding_of_string(tag->value);
|
||||
} else if(!strcasecmp(tag->key, "title")) {
|
||||
_title = [NSString stringWithUTF8String:tag->value];
|
||||
_title = guess_encoding_of_string(tag->value);
|
||||
} else if(!strcasecmp(tag->key, "date")) {
|
||||
NSString *dateString = [NSString stringWithUTF8String:tag->value];
|
||||
NSString *dateString = guess_encoding_of_string(tag->value);
|
||||
_year = @([dateString intValue]);
|
||||
} else if(!strcasecmp(tag->key, "track")) {
|
||||
NSString *trackString = [NSString stringWithUTF8String:tag->value];
|
||||
NSString *trackString = guess_encoding_of_string(tag->value);
|
||||
_track = @([trackString intValue]);
|
||||
} else if(!strcasecmp(tag->key, "disc")) {
|
||||
NSString *discString = [NSString stringWithUTF8String:tag->value];
|
||||
NSString *discString = guess_encoding_of_string(tag->value);
|
||||
_disc = @([discString intValue]);
|
||||
} else if(!strcasecmp(tag->key, "replaygain_album_gain")) {
|
||||
NSString *rgValue = [NSString stringWithUTF8String:tag->value];
|
||||
NSString *rgValue = guess_encoding_of_string(tag->value);
|
||||
_replayGainAlbumGain = [rgValue floatValue];
|
||||
} else if(!strcasecmp(tag->key, "replaygain_album_peak")) {
|
||||
NSString *rgValue = [NSString stringWithUTF8String:tag->value];
|
||||
NSString *rgValue = guess_encoding_of_string(tag->value);
|
||||
_replayGainAlbumPeak = [rgValue floatValue];
|
||||
} else if(!strcasecmp(tag->key, "replaygain_track_gain")) {
|
||||
NSString *rgValue = [NSString stringWithUTF8String:tag->value];
|
||||
NSString *rgValue = guess_encoding_of_string(tag->value);
|
||||
_replayGainTrackGain = [rgValue floatValue];
|
||||
} else if(!strcasecmp(tag->key, "replaygain_track_peak")) {
|
||||
NSString *rgValue = [NSString stringWithUTF8String:tag->value];
|
||||
NSString *rgValue = guess_encoding_of_string(tag->value);
|
||||
_replayGainTrackPeak = [rgValue floatValue];
|
||||
}
|
||||
}
|
||||
|
@ -886,18 +886,18 @@ static uint8_t reverse_bits[0x100];
|
|||
}
|
||||
|
||||
- (NSDictionary *)properties {
|
||||
return @{@"channels": [NSNumber numberWithInt:channels],
|
||||
@"channelConfig": [NSNumber numberWithUnsignedInt:channelConfig],
|
||||
@"bitsPerSample": [NSNumber numberWithInt:bitsPerSample],
|
||||
@"Unsigned": [NSNumber numberWithBool:(bitsPerSample == 8)],
|
||||
@"sampleRate": [NSNumber numberWithFloat:frequency],
|
||||
@"floatingPoint": [NSNumber numberWithBool:floatingPoint],
|
||||
@"totalFrames": [NSNumber numberWithDouble:totalFrames],
|
||||
@"bitrate": [NSNumber numberWithInt:bitrate],
|
||||
@"seekable": [NSNumber numberWithBool:seekable],
|
||||
@"codec": [NSString stringWithUTF8String:avcodec_get_name(codecCtx->codec_id)],
|
||||
@"endian": @"host",
|
||||
@"encoding": lossy ? @"lossy" : @"lossless"};
|
||||
return @{ @"channels": [NSNumber numberWithInt:channels],
|
||||
@"channelConfig": [NSNumber numberWithUnsignedInt:channelConfig],
|
||||
@"bitsPerSample": [NSNumber numberWithInt:bitsPerSample],
|
||||
@"Unsigned": [NSNumber numberWithBool:(bitsPerSample == 8)],
|
||||
@"sampleRate": [NSNumber numberWithFloat:frequency],
|
||||
@"floatingPoint": [NSNumber numberWithBool:floatingPoint],
|
||||
@"totalFrames": [NSNumber numberWithDouble:totalFrames],
|
||||
@"bitrate": [NSNumber numberWithInt:bitrate],
|
||||
@"seekable": [NSNumber numberWithBool:seekable],
|
||||
@"codec": guess_encoding_of_string(avcodec_get_name(codecCtx->codec_id)),
|
||||
@"endian": @"host",
|
||||
@"encoding": lossy ? @"lossy" : @"lossless" };
|
||||
}
|
||||
|
||||
- (NSDictionary *)metadata {
|
||||
|
|
|
@ -95,18 +95,18 @@
|
|||
|
||||
gme_delete(emu);
|
||||
|
||||
NSString *title = [NSString stringWithUTF8String:info->song];
|
||||
NSString *title = guess_encoding_of_string(info->song);
|
||||
if(!title || ![title length]) {
|
||||
// this is needed to distinguish between different tracks in NSF, for example
|
||||
// otherwise they will all be displayed as 'blahblah.nsf' in playlist
|
||||
title = [[url lastPathComponent] stringByAppendingFormat:@" [%d]", track_num];
|
||||
}
|
||||
|
||||
NSDictionary *dict = @{@"genre": [NSString stringWithUTF8String:info->system],
|
||||
@"album": [NSString stringWithUTF8String:info->game],
|
||||
@"title": title,
|
||||
@"artist": [NSString stringWithUTF8String:info->author],
|
||||
@"track": [NSNumber numberWithInt:track_num + 1]};
|
||||
NSDictionary *dict = @{ @"genre": guess_encoding_of_string(info->system),
|
||||
@"album": guess_encoding_of_string(info->game),
|
||||
@"title": title,
|
||||
@"artist": guess_encoding_of_string(info->author),
|
||||
@"track": [NSNumber numberWithInt:track_num + 1] };
|
||||
|
||||
gme_free_info(info);
|
||||
|
||||
|
|
|
@ -223,9 +223,9 @@ static int parse_time_crap(NSString *value) {
|
|||
static int psf_info_meta(void *context, const char *name, const char *value) {
|
||||
struct psf_info_meta_state *state = (struct psf_info_meta_state *)context;
|
||||
|
||||
NSString *tag = [NSString stringWithUTF8String:name];
|
||||
NSString *tag = guess_encoding_of_string(name);
|
||||
NSString *taglc = [tag lowercaseString];
|
||||
NSString *svalue = [NSString stringWithUTF8String:value];
|
||||
NSString *svalue = guess_encoding_of_string(value);
|
||||
|
||||
if(svalue == nil)
|
||||
return 0;
|
||||
|
@ -307,8 +307,8 @@ typedef struct {
|
|||
static int psf1_info(void *context, const char *name, const char *value) {
|
||||
struct psf1_load_state *state = (struct psf1_load_state *)context;
|
||||
|
||||
NSString *sname = [[NSString stringWithUTF8String:name] lowercaseString];
|
||||
NSString *svalue = [NSString stringWithUTF8String:value];
|
||||
NSString *sname = [guess_encoding_of_string(name) lowercaseString];
|
||||
NSString *svalue = guess_encoding_of_string(value);
|
||||
|
||||
if(!state->refresh && [sname isEqualToString:@"_refresh"]) {
|
||||
state->refresh = [svalue intValue];
|
||||
|
@ -808,8 +808,8 @@ static int twosf_loader(void *context, const uint8_t *exe, size_t exe_size,
|
|||
static int twosf_info(void *context, const char *name, const char *value) {
|
||||
struct twosf_loader_state *state = (struct twosf_loader_state *)context;
|
||||
|
||||
NSString *sname = [[NSString stringWithUTF8String:name] lowercaseString];
|
||||
NSString *svalue = [NSString stringWithUTF8String:value];
|
||||
NSString *sname = [guess_encoding_of_string(name) lowercaseString];
|
||||
NSString *svalue = guess_encoding_of_string(value);
|
||||
|
||||
if([sname isEqualToString:@"_frames"]) {
|
||||
state->initial_frames = [svalue intValue];
|
||||
|
@ -844,8 +844,8 @@ static int usf_loader(void *context, const uint8_t *exe, size_t exe_size,
|
|||
static int usf_info(void *context, const char *name, const char *value) {
|
||||
struct usf_loader_state *uUsf = (struct usf_loader_state *)context;
|
||||
|
||||
NSString *sname = [[NSString stringWithUTF8String:name] lowercaseString];
|
||||
NSString *svalue = [NSString stringWithUTF8String:value];
|
||||
NSString *sname = [guess_encoding_of_string(name) lowercaseString];
|
||||
NSString *svalue = guess_encoding_of_string(value);
|
||||
|
||||
if([sname isEqualToString:@"_enablecompare"] && [svalue length])
|
||||
uUsf->enablecompare = 1;
|
||||
|
|
|
@ -48,7 +48,7 @@
|
|||
if(!tune)
|
||||
return nil;
|
||||
|
||||
NSString *title = [[NSString stringWithUTF8String:tune->ht_Name] stringByTrimmingCharactersInSet:[NSCharacterSet whitespaceCharacterSet]];
|
||||
NSString *title = [guess_encoding_of_string(tune->ht_Name) stringByTrimmingCharactersInSet:[NSCharacterSet whitespaceCharacterSet]];
|
||||
|
||||
hvl_FreeTune(tune);
|
||||
|
||||
|
|
|
@ -62,18 +62,18 @@
|
|||
midi_meta_data_item item;
|
||||
bool remap_display_name = !metadata.get_item("title", item);
|
||||
|
||||
NSArray *allowedKeys = @[@"title", @"artist", @"album", @"year"];
|
||||
NSArray *allowedKeys = @[@"title", @"artist", @"albumartist", @"album", @"year", @"genre"];
|
||||
|
||||
NSMutableDictionary *dict = [NSMutableDictionary dictionaryWithCapacity:10];
|
||||
|
||||
for(size_t i = 0; i < metadata.get_count(); ++i) {
|
||||
const midi_meta_data_item &item = metadata[i];
|
||||
NSString *name = [[NSString stringWithUTF8String:item.m_name.c_str()] lowercaseString];
|
||||
NSString *name = [guess_encoding_of_string(item.m_name.c_str()) lowercaseString];
|
||||
if(![name isEqualToString:@"type"]) {
|
||||
if(remap_display_name && [name isEqualToString:@"display_name"])
|
||||
name = @"title";
|
||||
if([allowedKeys containsObject:name])
|
||||
[dict setObject:[NSString stringWithUTF8String:item.m_value.c_str()] forKey:name];
|
||||
[dict setObject:guess_encoding_of_string(item.m_value.c_str()) forKey:name];
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -65,15 +65,15 @@
|
|||
|
||||
for(std::vector<std::string>::iterator key = keys.begin(); key != keys.end(); ++key) {
|
||||
if(*key == "title")
|
||||
title = [NSString stringWithUTF8String:mod->get_metadata(*key).c_str()];
|
||||
title = guess_encoding_of_string(mod->get_metadata(*key).c_str());
|
||||
else if(*key == "artist")
|
||||
artist = [NSString stringWithUTF8String:mod->get_metadata(*key).c_str()];
|
||||
artist = guess_encoding_of_string(mod->get_metadata(*key).c_str());
|
||||
/*else if ( *key == "message" )
|
||||
comment = [NSString stringWithUTF8String: mod->get_metadata( *key ).c_str()];*/
|
||||
comment = guess_encoding_of_string(mod->get_metadata( *key ).c_str());*/
|
||||
else if(*key == "date")
|
||||
date = [NSString stringWithUTF8String:mod->get_metadata(*key).c_str()];
|
||||
date = guess_encoding_of_string(mod->get_metadata(*key).c_str());
|
||||
else if(*key == "type_long")
|
||||
type = [NSString stringWithUTF8String:mod->get_metadata(*key).c_str()];
|
||||
type = guess_encoding_of_string(mod->get_metadata(*key).c_str());
|
||||
}
|
||||
|
||||
delete mod;
|
||||
|
|
|
@ -65,15 +65,15 @@
|
|||
|
||||
for(std::vector<std::string>::iterator key = keys.begin(); key != keys.end(); ++key) {
|
||||
if(*key == "title")
|
||||
title = [NSString stringWithUTF8String:mod->get_metadata(*key).c_str()];
|
||||
title = guess_encoding_of_string(mod->get_metadata(*key).c_str());
|
||||
else if(*key == "artist")
|
||||
artist = [NSString stringWithUTF8String:mod->get_metadata(*key).c_str()];
|
||||
artist = guess_encoding_of_string(mod->get_metadata(*key).c_str());
|
||||
/*else if ( *key == "message" )
|
||||
comment = [NSString stringWithUTF8String: mod->get_metadata( *key ).c_str()];*/
|
||||
comment = guess_encoding_of_string(mod->get_metadata( *key ).c_str());*/
|
||||
else if(*key == "date")
|
||||
date = [NSString stringWithUTF8String:mod->get_metadata(*key).c_str()];
|
||||
date = guess_encoding_of_string(mod->get_metadata(*key).c_str());
|
||||
else if(*key == "type_long")
|
||||
type = [NSString stringWithUTF8String:mod->get_metadata(*key).c_str()];
|
||||
type = guess_encoding_of_string(mod->get_metadata(*key).c_str());
|
||||
}
|
||||
|
||||
delete mod;
|
||||
|
|
|
@ -139,11 +139,11 @@ static std::string FCC2Str(UINT32 fcc) {
|
|||
const char* const* tagList = player->GetTags();
|
||||
for(const char* const* t = tagList; *t; t += 2) {
|
||||
if(!strcmp(t[0], "TITLE"))
|
||||
title = [NSString stringWithUTF8String:t[1]];
|
||||
title = guess_encoding_of_string(t[1]);
|
||||
else if(!strcmp(t[0], "ARTIST"))
|
||||
artist = [NSString stringWithUTF8String:t[1]];
|
||||
artist = guess_encoding_of_string(t[1]);
|
||||
else if(!strcmp(t[0], "GAME"))
|
||||
album = [NSString stringWithUTF8String:t[1]];
|
||||
album = guess_encoding_of_string(t[1]);
|
||||
else if(!strcmp(t[0], "DATE")) {
|
||||
char* end;
|
||||
unsigned long theYear = strtoul(t[1], &end, 10);
|
||||
|
|
|
@ -52,9 +52,9 @@
|
|||
const SidTuneInfo *info = tune->getInfo();
|
||||
|
||||
unsigned int count = info->numberOfInfoStrings();
|
||||
NSString *title = count >= 1 ? [[NSString stringWithUTF8String:info->infoString(0)] stringByTrimmingCharactersInSet:[NSCharacterSet whitespaceCharacterSet]] : @"";
|
||||
NSString *title = count >= 1 ? [guess_encoding_of_string(info->infoString(0)) stringByTrimmingCharactersInSet:[NSCharacterSet whitespaceCharacterSet]] : @"";
|
||||
NSString *titletag = info->songs() > 1 ? @"album" : @"title";
|
||||
NSString *artist = count >= 2 ? [[NSString stringWithUTF8String:info->infoString(1)] stringByTrimmingCharactersInSet:[NSCharacterSet whitespaceCharacterSet]] : @"";
|
||||
NSString *artist = count >= 2 ? [guess_encoding_of_string(info->infoString(1)) stringByTrimmingCharactersInSet:[NSCharacterSet whitespaceCharacterSet]] : @"";
|
||||
|
||||
delete tune;
|
||||
|
||||
|
|
|
@ -115,7 +115,7 @@ static NSString *get_description_tag(const char *description, const char *tag, c
|
|||
tags = vgmstream_tags_init(&tag_key, &tag_val);
|
||||
vgmstream_tags_reset(tags, [filename UTF8String]);
|
||||
while(vgmstream_tags_next_tag(tags, tagFile)) {
|
||||
NSString *value = [NSString stringWithUTF8String:tag_val];
|
||||
NSString *value = guess_encoding_of_string(tag_val);
|
||||
if(!strncasecmp(tag_key, "REPLAYGAIN_", strlen("REPLAYGAIN_"))) {
|
||||
if(!strncasecmp(tag_key + strlen("REPLAYGAIN_"), "TRACK_", strlen("TRACK_"))) {
|
||||
if(!strcasecmp(tag_key + strlen("REPLAYGAIN_TRACK_"), "GAIN")) {
|
||||
|
@ -167,7 +167,7 @@ static NSString *get_description_tag(const char *description, const char *tag, c
|
|||
|
||||
if([title isEqualToString:@""]) {
|
||||
if(stream->num_streams > 1) {
|
||||
title = [NSString stringWithFormat:@"%@ - %s", [[urlTrimmed URLByDeletingPathExtension] lastPathComponent], stream->stream_name];
|
||||
title = [NSString stringWithFormat:@"%@ - %@", [[urlTrimmed URLByDeletingPathExtension] lastPathComponent], guess_encoding_of_string(stream->stream_name)];
|
||||
} else {
|
||||
title = [[urlTrimmed URLByDeletingPathExtension] lastPathComponent];
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue