Metadata: Add helper for optional values

Add NSDictionary initWithOptionalObjects:forKeys:count: helper, to work
around several places that may have been setting nil dictionary valies
on placeholder dictionaries. Hopefully this fixes the crash someone
logged recently.

Signed-off-by: Christopher Snowhill <kode54@gmail.com>
This commit is contained in:
Christopher Snowhill 2025-06-20 19:42:43 -07:00
parent b8b52e4164
commit 01ea0435d0
12 changed files with 117 additions and 23 deletions

View file

@ -101,6 +101,8 @@
83A349752D5C50A10096D530 /* DSPHRTFNode.h in Headers */ = {isa = PBXBuildFile; fileRef = 83A349742D5C50A10096D530 /* DSPHRTFNode.h */; settings = {ATTRIBUTES = (Public, ); }; }; 83A349752D5C50A10096D530 /* DSPHRTFNode.h in Headers */ = {isa = PBXBuildFile; fileRef = 83A349742D5C50A10096D530 /* DSPHRTFNode.h */; settings = {ATTRIBUTES = (Public, ); }; };
83A349772D5C50B20096D530 /* DSPHRTFNode.m in Sources */ = {isa = PBXBuildFile; fileRef = 83A349762D5C50B20096D530 /* DSPHRTFNode.m */; }; 83A349772D5C50B20096D530 /* DSPHRTFNode.m in Sources */ = {isa = PBXBuildFile; fileRef = 83A349762D5C50B20096D530 /* DSPHRTFNode.m */; };
83B74281289E027F005AAC28 /* CogAudio-Bridging-Header.h in Headers */ = {isa = PBXBuildFile; fileRef = 83B74280289E027F005AAC28 /* CogAudio-Bridging-Header.h */; }; 83B74281289E027F005AAC28 /* CogAudio-Bridging-Header.h in Headers */ = {isa = PBXBuildFile; fileRef = 83B74280289E027F005AAC28 /* CogAudio-Bridging-Header.h */; };
83CB56652E06464D003DD379 /* NSDictionary+Optional.h in Headers */ = {isa = PBXBuildFile; fileRef = 83CB56632E06464D003DD379 /* NSDictionary+Optional.h */; };
83CB56662E06464D003DD379 /* NSDictionary+Optional.m in Sources */ = {isa = PBXBuildFile; fileRef = 83CB56642E06464D003DD379 /* NSDictionary+Optional.m */; };
83F843202D5C6272008C123B /* HeadphoneFilter.h in Headers */ = {isa = PBXBuildFile; fileRef = 83F8431E2D5C6272008C123B /* HeadphoneFilter.h */; settings = {ATTRIBUTES = (Public, ); }; }; 83F843202D5C6272008C123B /* HeadphoneFilter.h in Headers */ = {isa = PBXBuildFile; fileRef = 83F8431E2D5C6272008C123B /* HeadphoneFilter.h */; settings = {ATTRIBUTES = (Public, ); }; };
83F843212D5C6272008C123B /* HeadphoneFilter.mm in Sources */ = {isa = PBXBuildFile; fileRef = 83F8431F2D5C6272008C123B /* HeadphoneFilter.mm */; }; 83F843212D5C6272008C123B /* HeadphoneFilter.mm in Sources */ = {isa = PBXBuildFile; fileRef = 83F8431F2D5C6272008C123B /* HeadphoneFilter.mm */; };
83F843232D5C66DA008C123B /* DSPEqualizerNode.h in Headers */ = {isa = PBXBuildFile; fileRef = 83F843222D5C66DA008C123B /* DSPEqualizerNode.h */; settings = {ATTRIBUTES = (Public, ); }; }; 83F843232D5C66DA008C123B /* DSPEqualizerNode.h in Headers */ = {isa = PBXBuildFile; fileRef = 83F843222D5C66DA008C123B /* DSPEqualizerNode.h */; settings = {ATTRIBUTES = (Public, ); }; };
@ -231,6 +233,8 @@
83A349742D5C50A10096D530 /* DSPHRTFNode.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = DSPHRTFNode.h; sourceTree = "<group>"; }; 83A349742D5C50A10096D530 /* DSPHRTFNode.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = DSPHRTFNode.h; sourceTree = "<group>"; };
83A349762D5C50B20096D530 /* DSPHRTFNode.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = DSPHRTFNode.m; sourceTree = "<group>"; }; 83A349762D5C50B20096D530 /* DSPHRTFNode.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = DSPHRTFNode.m; sourceTree = "<group>"; };
83B74280289E027F005AAC28 /* CogAudio-Bridging-Header.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = "CogAudio-Bridging-Header.h"; sourceTree = "<group>"; }; 83B74280289E027F005AAC28 /* CogAudio-Bridging-Header.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = "CogAudio-Bridging-Header.h"; sourceTree = "<group>"; };
83CB56632E06464D003DD379 /* NSDictionary+Optional.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "NSDictionary+Optional.h"; path = "../Utils/NSDictionary+Optional.h"; sourceTree = SOURCE_ROOT; };
83CB56642E06464D003DD379 /* NSDictionary+Optional.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; name = "NSDictionary+Optional.m"; path = "../Utils/NSDictionary+Optional.m"; sourceTree = SOURCE_ROOT; };
83F8431E2D5C6272008C123B /* HeadphoneFilter.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = HeadphoneFilter.h; sourceTree = "<group>"; }; 83F8431E2D5C6272008C123B /* HeadphoneFilter.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = HeadphoneFilter.h; sourceTree = "<group>"; };
83F8431F2D5C6272008C123B /* HeadphoneFilter.mm */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.objcpp; path = HeadphoneFilter.mm; sourceTree = "<group>"; }; 83F8431F2D5C6272008C123B /* HeadphoneFilter.mm */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.objcpp; path = HeadphoneFilter.mm; sourceTree = "<group>"; };
83F843222D5C66DA008C123B /* DSPEqualizerNode.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = DSPEqualizerNode.h; sourceTree = "<group>"; }; 83F843222D5C66DA008C123B /* DSPEqualizerNode.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = DSPEqualizerNode.h; sourceTree = "<group>"; };
@ -427,6 +431,8 @@
17D21CDC0B8BE5B400D1EBDE /* Utils */ = { 17D21CDC0B8BE5B400D1EBDE /* Utils */ = {
isa = PBXGroup; isa = PBXGroup;
children = ( children = (
83CB56632E06464D003DD379 /* NSDictionary+Optional.h */,
83CB56642E06464D003DD379 /* NSDictionary+Optional.m */,
839065F22853338700636FBB /* dsd2float.h */, 839065F22853338700636FBB /* dsd2float.h */,
8328995527CB51B700D7F028 /* SHA256Digest.h */, 8328995527CB51B700D7F028 /* SHA256Digest.h */,
8328995627CB51B700D7F028 /* SHA256Digest.m */, 8328995627CB51B700D7F028 /* SHA256Digest.m */,
@ -611,6 +617,7 @@
83A3496D2D5C40490096D530 /* DSPFSurroundNode.h in Headers */, 83A3496D2D5C40490096D530 /* DSPFSurroundNode.h in Headers */,
83A3496B2D5C3F430096D530 /* DSPRubberbandNode.h in Headers */, 83A3496B2D5C3F430096D530 /* DSPRubberbandNode.h in Headers */,
17D21CA50B8BE4BA00D1EBDE /* InputNode.h in Headers */, 17D21CA50B8BE4BA00D1EBDE /* InputNode.h in Headers */,
83CB56652E06464D003DD379 /* NSDictionary+Optional.h in Headers */,
833738EA2D5EA52500278628 /* DSPDownmixNode.h in Headers */, 833738EA2D5EA52500278628 /* DSPDownmixNode.h in Headers */,
83F843232D5C66DA008C123B /* DSPEqualizerNode.h in Headers */, 83F843232D5C66DA008C123B /* DSPEqualizerNode.h in Headers */,
834A41A9287A90AB00EB9D9B /* freesurround_decoder.h in Headers */, 834A41A9287A90AB00EB9D9B /* freesurround_decoder.h in Headers */,
@ -765,6 +772,7 @@
8EC122600B993BD500C5B3AD /* ConverterNode.m in Sources */, 8EC122600B993BD500C5B3AD /* ConverterNode.m in Sources */,
835DD2672ACAF1D90057E319 /* OutputCoreAudio.m in Sources */, 835DD2672ACAF1D90057E319 /* OutputCoreAudio.m in Sources */,
83A349722D5C41810096D530 /* FSurroundFilter.mm in Sources */, 83A349722D5C41810096D530 /* FSurroundFilter.mm in Sources */,
83CB56662E06464D003DD379 /* NSDictionary+Optional.m in Sources */,
8E8D3D300CBAEE6E00135C1B /* AudioContainer.m in Sources */, 8E8D3D300CBAEE6E00135C1B /* AudioContainer.m in Sources */,
B0575F300D687A4000411D77 /* Helper.m in Sources */, B0575F300D687A4000411D77 /* Helper.m in Sources */,
835DD2742ACAF5AD0057E319 /* lpc.c in Sources */, 835DD2742ACAF5AD0057E319 /* lpc.c in Sources */,

View file

@ -178,6 +178,7 @@
83BC5AC320E4CE8D00631CD4 /* SpotlightPanel.xib in Resources */ = {isa = PBXBuildFile; fileRef = 178456C00F6320B5007E8021 /* SpotlightPanel.xib */; }; 83BC5AC320E4CE8D00631CD4 /* SpotlightPanel.xib in Resources */ = {isa = PBXBuildFile; fileRef = 178456C00F6320B5007E8021 /* SpotlightPanel.xib */; };
83BC5AC420E4CE9000631CD4 /* Feedback.xib in Resources */ = {isa = PBXBuildFile; fileRef = 17D1B1DA0F6330D400694C57 /* Feedback.xib */; }; 83BC5AC420E4CE9000631CD4 /* Feedback.xib in Resources */ = {isa = PBXBuildFile; fileRef = 17D1B1DA0F6330D400694C57 /* Feedback.xib */; };
83BCB8DE17FC971300760340 /* FFMPEG.bundle in CopyFiles */ = {isa = PBXBuildFile; fileRef = B09E94350D747F7B0064F138 /* FFMPEG.bundle */; settings = {ATTRIBUTES = (CodeSignOnCopy, ); }; }; 83BCB8DE17FC971300760340 /* FFMPEG.bundle in CopyFiles */ = {isa = PBXBuildFile; fileRef = B09E94350D747F7B0064F138 /* FFMPEG.bundle */; settings = {ATTRIBUTES = (CodeSignOnCopy, ); }; };
83CB565E2E064607003DD379 /* NSDictionary+Optional.m in Sources */ = {isa = PBXBuildFile; fileRef = 83CB565D2E064607003DD379 /* NSDictionary+Optional.m */; };
83D0380F24A40DFB004CF90F /* CogAssets.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = 83D0380E24A40DF2004CF90F /* CogAssets.xcassets */; }; 83D0380F24A40DFB004CF90F /* CogAssets.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = 83D0380E24A40DF2004CF90F /* CogAssets.xcassets */; };
83F9D8071A884C54007ABEC2 /* SilenceDecoder.bundle in CopyFiles */ = {isa = PBXBuildFile; fileRef = 83F9D7F61A884B46007ABEC2 /* SilenceDecoder.bundle */; settings = {ATTRIBUTES = (CodeSignOnCopy, RemoveHeadersOnCopy, ); }; }; 83F9D8071A884C54007ABEC2 /* SilenceDecoder.bundle in CopyFiles */ = {isa = PBXBuildFile; fileRef = 83F9D7F61A884B46007ABEC2 /* SilenceDecoder.bundle */; settings = {ATTRIBUTES = (CodeSignOnCopy, RemoveHeadersOnCopy, ); }; };
83F9FFEF2D6EB75B00026576 /* Sentry in Frameworks */ = {isa = PBXBuildFile; productRef = 83F9FFEE2D6EB75B00026576 /* Sentry */; }; 83F9FFEF2D6EB75B00026576 /* Sentry in Frameworks */ = {isa = PBXBuildFile; productRef = 83F9FFEE2D6EB75B00026576 /* Sentry */; };
@ -1037,6 +1038,8 @@
83BC5AD820E4D0D900631CD4 /* en */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = en; path = en.lproj/SpotlightPanel.strings; sourceTree = "<group>"; }; 83BC5AD820E4D0D900631CD4 /* en */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = en; path = en.lproj/SpotlightPanel.strings; sourceTree = "<group>"; };
83BC5ADA20E4D0E900631CD4 /* en */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = en; path = en.lproj/Feedback.strings; sourceTree = "<group>"; }; 83BC5ADA20E4D0E900631CD4 /* en */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = en; path = en.lproj/Feedback.strings; sourceTree = "<group>"; };
83BC5ADC20E4D0EC00631CD4 /* es */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = es; path = es.lproj/Feedback.strings; sourceTree = "<group>"; }; 83BC5ADC20E4D0EC00631CD4 /* es */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = es; path = es.lproj/Feedback.strings; sourceTree = "<group>"; };
83CB565C2E064607003DD379 /* NSDictionary+Optional.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = "NSDictionary+Optional.h"; sourceTree = "<group>"; };
83CB565D2E064607003DD379 /* NSDictionary+Optional.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = "NSDictionary+Optional.m"; sourceTree = "<group>"; };
83D0380E24A40DF2004CF90F /* CogAssets.xcassets */ = {isa = PBXFileReference; lastKnownFileType = folder.assetcatalog; path = CogAssets.xcassets; sourceTree = "<group>"; }; 83D0380E24A40DF2004CF90F /* CogAssets.xcassets */ = {isa = PBXFileReference; lastKnownFileType = folder.assetcatalog; path = CogAssets.xcassets; sourceTree = "<group>"; };
83D3C5FC201C674D005564CB /* AdPlug.xcodeproj */ = {isa = PBXFileReference; lastKnownFileType = "wrapper.pb-project"; name = AdPlug.xcodeproj; path = Plugins/AdPlug/AdPlug.xcodeproj; sourceTree = "<group>"; }; 83D3C5FC201C674D005564CB /* AdPlug.xcodeproj */ = {isa = PBXFileReference; lastKnownFileType = "wrapper.pb-project"; name = AdPlug.xcodeproj; path = Plugins/AdPlug/AdPlug.xcodeproj; sourceTree = "<group>"; };
83E5EFAC1FFEF78100659F0F /* OpenMPT.xcodeproj */ = {isa = PBXFileReference; lastKnownFileType = "wrapper.pb-project"; name = OpenMPT.xcodeproj; path = Plugins/OpenMPT/OpenMPT.xcodeproj; sourceTree = "<group>"; }; 83E5EFAC1FFEF78100659F0F /* OpenMPT.xcodeproj */ = {isa = PBXFileReference; lastKnownFileType = "wrapper.pb-project"; name = OpenMPT.xcodeproj; path = Plugins/OpenMPT/OpenMPT.xcodeproj; sourceTree = "<group>"; };
@ -1208,6 +1211,8 @@
177EC0110B8BC2CF0000BC8C /* Utils */ = { 177EC0110B8BC2CF0000BC8C /* Utils */ = {
isa = PBXGroup; isa = PBXGroup;
children = ( children = (
83CB565C2E064607003DD379 /* NSDictionary+Optional.h */,
83CB565D2E064607003DD379 /* NSDictionary+Optional.m */,
834A42C4287B01B600EB9D9B /* AudioChunk.h */, 834A42C4287B01B600EB9D9B /* AudioChunk.h */,
8384912518080F2D00E7332D /* Logging.h */, 8384912518080F2D00E7332D /* Logging.h */,
07E18DF10D62B38400BB0E11 /* NSArray+ShuffleUtils.h */, 07E18DF10D62B38400BB0E11 /* NSArray+ShuffleUtils.h */,
@ -2575,6 +2580,7 @@
839E876E2D5DA0AC00A13526 /* RubberbandEngineTransformer.m in Sources */, 839E876E2D5DA0AC00A13526 /* RubberbandEngineTransformer.m in Sources */,
838A33842D06CF4100D0D770 /* SpectrumWindowController.m in Sources */, 838A33842D06CF4100D0D770 /* SpectrumWindowController.m in Sources */,
83B61E2829A82A0200CD0580 /* LyricsWindowController.m in Sources */, 83B61E2829A82A0200CD0580 /* LyricsWindowController.m in Sources */,
83CB565E2E064607003DD379 /* NSDictionary+Optional.m in Sources */,
56462EB20D634206000AB68C /* SpotlightPlaylistController.m in Sources */, 56462EB20D634206000AB68C /* SpotlightPlaylistController.m in Sources */,
07E18DF30D62B38400BB0E11 /* NSArray+ShuffleUtils.m in Sources */, 07E18DF30D62B38400BB0E11 /* NSArray+ShuffleUtils.m in Sources */,
56C63D910D647DF300EAE25A /* NSComparisonPredicate+CogPredicate.m in Sources */, 56C63D910D647DF300EAE25A /* NSComparisonPredicate+CogPredicate.m in Sources */,

View file

@ -33,6 +33,7 @@
838EE8BB29A8600900CD0580 /* tr */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = tr; path = tr.lproj/InfoPlist.strings; sourceTree = "<group>"; }; 838EE8BB29A8600900CD0580 /* tr */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = tr; path = tr.lproj/InfoPlist.strings; sourceTree = "<group>"; };
839DA7D0274A2EA9001B18E5 /* AudioMetadataReader.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = AudioMetadataReader.h; path = ../../Audio/AudioMetadataReader.h; sourceTree = "<group>"; }; 839DA7D0274A2EA9001B18E5 /* AudioMetadataReader.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = AudioMetadataReader.h; path = ../../Audio/AudioMetadataReader.h; sourceTree = "<group>"; };
839DA7D3274A2FD4001B18E5 /* NSDictionary+Merge.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = "NSDictionary+Merge.h"; path = "../../Utils/NSDictionary+Merge.h"; sourceTree = "<group>"; }; 839DA7D3274A2FD4001B18E5 /* NSDictionary+Merge.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = "NSDictionary+Merge.h"; path = "../../Utils/NSDictionary+Merge.h"; sourceTree = "<group>"; };
83CB56672E0649B4003DD379 /* NSDictionary+Optional.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "NSDictionary+Optional.h"; path = "../../Utils/NSDictionary+Optional.h"; sourceTree = "<group>"; };
83D833AB2DF95A89009970AF /* CogAudio.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; path = CogAudio.framework; sourceTree = BUILT_PRODUCTS_DIR; }; 83D833AB2DF95A89009970AF /* CogAudio.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; path = CogAudio.framework; sourceTree = BUILT_PRODUCTS_DIR; };
83F0E6B5287CAB4100D84594 /* pl */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = pl; path = pl.lproj/InfoPlist.strings; sourceTree = "<group>"; }; 83F0E6B5287CAB4100D84594 /* pl */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = pl; path = pl.lproj/InfoPlist.strings; sourceTree = "<group>"; };
8D5B49B6048680CD000E48DA /* CueSheet.bundle */ = {isa = PBXFileReference; explicitFileType = wrapper.cfbundle; includeInIndex = 0; path = CueSheet.bundle; sourceTree = BUILT_PRODUCTS_DIR; }; 8D5B49B6048680CD000E48DA /* CueSheet.bundle */ = {isa = PBXFileReference; explicitFileType = wrapper.cfbundle; includeInIndex = 0; path = CueSheet.bundle; sourceTree = BUILT_PRODUCTS_DIR; };
@ -99,6 +100,7 @@
832EE93A288F888600B03467 /* SandboxBroker.h */, 832EE93A288F888600B03467 /* SandboxBroker.h */,
834A42B2287AF59900EB9D9B /* AudioChunk.h */, 834A42B2287AF59900EB9D9B /* AudioChunk.h */,
839DA7D3274A2FD4001B18E5 /* NSDictionary+Merge.h */, 839DA7D3274A2FD4001B18E5 /* NSDictionary+Merge.h */,
83CB56672E0649B4003DD379 /* NSDictionary+Optional.h */,
839DA7D0274A2EA9001B18E5 /* AudioMetadataReader.h */, 839DA7D0274A2EA9001B18E5 /* AudioMetadataReader.h */,
8384912A180814D900E7332D /* Logging.h */, 8384912A180814D900E7332D /* Logging.h */,
8E8D423C0CBB0FF600135C1B /* Plugin.h */, 8E8D423C0CBB0FF600135C1B /* Plugin.h */,

View file

@ -13,6 +13,7 @@
#import "AudioMetadataReader.h" #import "AudioMetadataReader.h"
#import "NSDictionary+Merge.h" #import "NSDictionary+Merge.h"
#import "NSDictionary+Optional.h"
@implementation CueSheetMetadataReader @implementation CueSheetMetadataReader
@ -100,20 +101,31 @@
} }
+ (NSDictionary *)processDataForTrack:(CueSheetTrack *)track { + (NSDictionary *)processDataForTrack:(CueSheetTrack *)track {
NSMutableDictionary *cuesheetMetadata = [[NSMutableDictionary alloc] init]; const NSString* keys[] = {
@"artist",
if([track artist]) [cuesheetMetadata setValue:[track artist] forKey:@"artist"]; @"album",
if([track album]) [cuesheetMetadata setValue:[track album] forKey:@"album"]; @"title",
if([track title]) [cuesheetMetadata setValue:[track title] forKey:@"title"]; @"track",
if([[track track] intValue]) [cuesheetMetadata setValue:@([[track track] intValue]) forKey:@"track"]; @"genre",
if([track genre]) [cuesheetMetadata setValue:[track genre] forKey:@"genre"]; @"year",
if([[track year] intValue]) [cuesheetMetadata setValue:@([[track year] intValue]) forKey:@"year"]; @"replaygain_album_gain",
if([track albumGain]) [cuesheetMetadata setValue:@([track albumGain]) forKey:@"replaygain_album_gain"]; @"replaygain_album_peak",
if([track albumPeak]) [cuesheetMetadata setValue:@([track albumPeak]) forKey:@"replaygain_album_peak"]; @"replaygain_track_gain",
if([track trackGain]) [cuesheetMetadata setValue:@([track trackGain]) forKey:@"replaygain_track_gain"]; @"replaygain_track_peak"
if([track trackPeak]) [cuesheetMetadata setValue:@([track trackPeak]) forKey:@"replaygain_track_peak"]; };
const id values[] = {
return [NSDictionary dictionaryWithDictionary:cuesheetMetadata]; [track artist],
[track album],
[track title],
@([[track track] intValue]),
[track genre],
@([[track year] intValue]),
@([track albumGain]),
@([track albumPeak]),
@([track trackGain]),
@([track trackPeak])
};
return [NSDictionary initWithOptionalObjects:values forKeys:keys count:sizeof(keys) / sizeof(keys[0])];
} }
@end @end

View file

@ -11,6 +11,8 @@
#import "Logging.h" #import "Logging.h"
#import "NSDictionary+Optional.h"
#import <stdlib.h> #import <stdlib.h>
#import <string.h> #import <string.h>
@ -628,7 +630,19 @@ static void http_stream_reset(HTTPSource *fp) {
} }
- (NSDictionary *)metadata { - (NSDictionary *)metadata {
return @{ @"genre": genre, @"album": album, @"artist": artist, @"title": title }; const NSString* keys[] = {
@"genre",
@"album",
@"artist",
@"title"
};
const id values[] = {
genre,
album,
artist,
title
};
return [NSDictionary initWithOptionalObjects:values forKeys:keys count:sizeof(keys) / sizeof(keys[0])];
} }
- (BOOL)seekable { - (BOOL)seekable {

View file

@ -38,6 +38,7 @@
8356BD1727B3B7340074E50C /* libcurl.tbd */ = {isa = PBXFileReference; lastKnownFileType = "sourcecode.text-based-dylib-definition"; name = libcurl.tbd; path = usr/lib/libcurl.tbd; sourceTree = SDKROOT; }; 8356BD1727B3B7340074E50C /* libcurl.tbd */ = {isa = PBXFileReference; lastKnownFileType = "sourcecode.text-based-dylib-definition"; name = libcurl.tbd; path = usr/lib/libcurl.tbd; sourceTree = SDKROOT; };
83747C362862DC0D0021245F /* Shared.xcconfig */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.xcconfig; path = Shared.xcconfig; sourceTree = "<group>"; }; 83747C362862DC0D0021245F /* Shared.xcconfig */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.xcconfig; path = Shared.xcconfig; sourceTree = "<group>"; };
8384912F1808180000E7332D /* Logging.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = Logging.h; path = ../../Utils/Logging.h; sourceTree = "<group>"; }; 8384912F1808180000E7332D /* Logging.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = Logging.h; path = ../../Utils/Logging.h; sourceTree = "<group>"; };
83CB56682E064E50003DD379 /* NSDictionary+Optional.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "NSDictionary+Optional.h"; path = "../../Utils/NSDictionary+Optional.h"; sourceTree = "<group>"; };
8D5B49B6048680CD000E48DA /* HTTPSource.bundle */ = {isa = PBXFileReference; explicitFileType = wrapper.cfbundle; includeInIndex = 0; path = HTTPSource.bundle; sourceTree = BUILT_PRODUCTS_DIR; }; 8D5B49B6048680CD000E48DA /* HTTPSource.bundle */ = {isa = PBXFileReference; explicitFileType = wrapper.cfbundle; includeInIndex = 0; path = HTTPSource.bundle; sourceTree = BUILT_PRODUCTS_DIR; };
8D5B49B7048680CD000E48DA /* Info.plist */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = "<group>"; }; 8D5B49B7048680CD000E48DA /* Info.plist */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = "<group>"; };
D2F7E65807B2D6F200F64583 /* CoreData.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = CoreData.framework; path = /System/Library/Frameworks/CoreData.framework; sourceTree = "<absolute>"; }; D2F7E65807B2D6F200F64583 /* CoreData.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = CoreData.framework; path = /System/Library/Frameworks/CoreData.framework; sourceTree = "<absolute>"; };
@ -91,6 +92,7 @@
08FB77AFFE84173DC02AAC07 /* Classes */ = { 08FB77AFFE84173DC02AAC07 /* Classes */ = {
isa = PBXGroup; isa = PBXGroup;
children = ( children = (
83CB56682E064E50003DD379 /* NSDictionary+Optional.h */,
834A42B9287AFAB500EB9D9B /* AudioChunk.h */, 834A42B9287AFAB500EB9D9B /* AudioChunk.h */,
8384912F1808180000E7332D /* Logging.h */, 8384912F1808180000E7332D /* Logging.h */,
17ADB6340B97A8B400257CA2 /* Plugin.h */, 17ADB6340B97A8B400257CA2 /* Plugin.h */,

View file

@ -12,6 +12,8 @@
#import "Logging.h" #import "Logging.h"
#import "NSDictionary+Optional.h"
#import <libvgm/player/droplayer.hpp> #import <libvgm/player/droplayer.hpp>
#import <libvgm/player/gymplayer.hpp> #import <libvgm/player/gymplayer.hpp>
#import <libvgm/player/s98player.hpp> #import <libvgm/player/s98player.hpp>
@ -160,13 +162,21 @@ static std::string FCC2Str(UINT32 fcc) {
DataLoader_Deinit(dLoad); DataLoader_Deinit(dLoad);
free(fileData); free(fileData);
NSDictionary* dict = @{ @"codec": system, const NSString* keys[] = {
@"album": album, @"codec",
@"title": title, @"album",
@"artist": artist, @"title",
@"year": year }; @"artist",
@"year"
return dict; };
const id values[] = {
system,
album,
title,
artist,
year
};
return [NSDictionary initWithOptionalObjects:values forKeys:keys count:sizeof(keys) / sizeof(keys[0])];
} }
@end @end

View file

@ -47,6 +47,7 @@
83747C312862DBE80021245F /* Shared.xcconfig */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.xcconfig; path = Shared.xcconfig; sourceTree = "<group>"; }; 83747C312862DBE80021245F /* Shared.xcconfig */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.xcconfig; path = Shared.xcconfig; sourceTree = "<group>"; };
8384912E1808175400E7332D /* Logging.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = Logging.h; path = ../../Utils/Logging.h; sourceTree = "<group>"; }; 8384912E1808175400E7332D /* Logging.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = Logging.h; path = ../../Utils/Logging.h; sourceTree = "<group>"; };
838EE8C829A8600B00CD0580 /* tr */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = tr; path = tr.lproj/InfoPlist.strings; sourceTree = "<group>"; }; 838EE8C829A8600B00CD0580 /* tr */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = tr; path = tr.lproj/InfoPlist.strings; sourceTree = "<group>"; };
83CB56692E064F48003DD379 /* NSDictionary+Optional.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "NSDictionary+Optional.h"; path = "../../Utils/NSDictionary+Optional.h"; sourceTree = "<group>"; };
83F0E6C2287CAB4300D84594 /* pl */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = pl; path = pl.lproj/InfoPlist.strings; sourceTree = "<group>"; }; 83F0E6C2287CAB4300D84594 /* pl */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = pl; path = pl.lproj/InfoPlist.strings; sourceTree = "<group>"; };
83FAF8A518ADD4D100057CAF /* PlaylistController.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = PlaylistController.h; path = ../../Playlist/PlaylistController.h; sourceTree = "<group>"; }; 83FAF8A518ADD4D100057CAF /* PlaylistController.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = PlaylistController.h; path = ../../Playlist/PlaylistController.h; sourceTree = "<group>"; };
8D5B49B6048680CD000E48DA /* libvgmPlayer.bundle */ = {isa = PBXFileReference; explicitFileType = wrapper.cfbundle; includeInIndex = 0; path = libvgmPlayer.bundle; sourceTree = BUILT_PRODUCTS_DIR; }; 8D5B49B6048680CD000E48DA /* libvgmPlayer.bundle */ = {isa = PBXFileReference; explicitFileType = wrapper.cfbundle; includeInIndex = 0; path = libvgmPlayer.bundle; sourceTree = BUILT_PRODUCTS_DIR; };
@ -108,6 +109,7 @@
08FB77AFFE84173DC02AAC07 /* Classes */ = { 08FB77AFFE84173DC02AAC07 /* Classes */ = {
isa = PBXGroup; isa = PBXGroup;
children = ( children = (
83CB56692E064F48003DD379 /* NSDictionary+Optional.h */,
834A42AC287AF18E00EB9D9B /* AudioChunk.h */, 834A42AC287AF18E00EB9D9B /* AudioChunk.h */,
17C8F33B0CBED3BE008D969D /* libvgmContainer.h */, 17C8F33B0CBED3BE008D969D /* libvgmContainer.h */,
17C8F33C0CBED3BE008D969D /* libvgmContainer.mm */, 17C8F33C0CBED3BE008D969D /* libvgmContainer.mm */,

View file

@ -14,6 +14,8 @@
#import "Logging.h" #import "Logging.h"
#import "NSDictionary+Optional.h"
#import "id3tag.h" #import "id3tag.h"
#import "CVbriHeader.h" #import "CVbriHeader.h"
@ -376,7 +378,19 @@ static int mp3_seek_callback(uint64_t position, void *user_data) {
} }
- (NSDictionary *)metadata { - (NSDictionary *)metadata {
return @{ @"artist": artist, @"album": album, @"title": title, @"genre": genre }; const NSString* keys[] = {
@"artist",
@"album",
@"title",
@"genre"
};
const id values[] = {
artist,
album,
title,
genre
};
return [NSDictionary initWithOptionalObjects:values forKeys:keys count:sizeof(keys) / sizeof(keys[0])];
} }
+ (NSArray *)fileTypes { + (NSArray *)fileTypes {

View file

@ -26,6 +26,7 @@
83747C272862DB9F0021245F /* Shared.xcconfig */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.xcconfig; path = Shared.xcconfig; sourceTree = "<group>"; }; 83747C272862DB9F0021245F /* Shared.xcconfig */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.xcconfig; path = Shared.xcconfig; sourceTree = "<group>"; };
83B73B612D8FC0A900A57F08 /* minimp3.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = minimp3.h; sourceTree = "<group>"; }; 83B73B612D8FC0A900A57F08 /* minimp3.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = minimp3.h; sourceTree = "<group>"; };
83B73B622D8FC0A900A57F08 /* minimp3_ex.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = minimp3_ex.h; sourceTree = "<group>"; }; 83B73B622D8FC0A900A57F08 /* minimp3_ex.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = minimp3_ex.h; sourceTree = "<group>"; };
83CB566A2E064FAC003DD379 /* NSDictionary+Optional.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "NSDictionary+Optional.h"; path = "../../Utils/NSDictionary+Optional.h"; sourceTree = "<group>"; };
83F97B6728600F9300A70B97 /* CVbriHeader.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = CVbriHeader.c; sourceTree = "<group>"; }; 83F97B6728600F9300A70B97 /* CVbriHeader.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = CVbriHeader.c; sourceTree = "<group>"; };
83F97B6828600F9300A70B97 /* CVbriHeader.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = CVbriHeader.h; sourceTree = "<group>"; }; 83F97B6828600F9300A70B97 /* CVbriHeader.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = CVbriHeader.h; sourceTree = "<group>"; };
/* End PBXFileReference section */ /* End PBXFileReference section */
@ -51,6 +52,7 @@
834A42BB287AFB0700EB9D9B /* AudioChunk.h */, 834A42BB287AFB0700EB9D9B /* AudioChunk.h */,
8372C93A27C786DD00E250C9 /* HTTPSource.h */, 8372C93A27C786DD00E250C9 /* HTTPSource.h */,
8372C93927C7866B00E250C9 /* Logging.h */, 8372C93927C7866B00E250C9 /* Logging.h */,
83CB566A2E064FAC003DD379 /* NSDictionary+Optional.h */,
8372C93827C7865A00E250C9 /* Plugin.h */, 8372C93827C7865A00E250C9 /* Plugin.h */,
8372C93327C7861300E250C9 /* MP3Decoder.h */, 8372C93327C7861300E250C9 /* MP3Decoder.h */,
8372C93427C7861300E250C9 /* MP3Decoder.m */, 8372C93427C7861300E250C9 /* MP3Decoder.m */,

View file

@ -0,0 +1,7 @@
#import <Foundation/Foundation.h>
@interface NSDictionary (Optional)
+ (NSDictionary *)initWithOptionalObjects:(const id _Nonnull [_Nullable])objects forKeys:(id<NSCopying> const[])keys count:(NSUInteger)cnt;
@end

View file

@ -0,0 +1,15 @@
#import "NSDictionary+Merge.h"
@implementation NSDictionary (Optional)
+ (NSDictionary *)initWithOptionalObjects:(const id _Nonnull [_Nullable])objects forKeys:(id<NSCopying> const[])keys count:(NSUInteger)cnt {
NSMutableDictionary *dictionary = [[NSMutableDictionary alloc] init];
for(NSUInteger i = 0; i < cnt; ++i) {
if(keys[i] && objects[i]) {
[dictionary setObject:objects[i] forKey:keys[i]];
}
}
return [NSDictionary dictionaryWithDictionary:dictionary];
}
@end