// // DumbContainer.m // Dumb // // Created by Christopher Snowhill on 10/4/13. // Copyright 2013 __NoWork, Inc__. All rights reserved. // #import #import "DumbContainer.h" #import "DumbDecoder.h" #import "Logging.h" @interface DumbCallbackData : NSObject { @public NSString *baseUrl; @public NSMutableArray *tracks; } @end @implementation DumbCallbackData @end @implementation DumbContainer + (NSArray *)fileTypes { return [DumbDecoder fileTypes]; } + (NSArray *)mimeTypes { return nil; } + (float)priority { return 1.0f; } int scanCallback(void *data, int startOrder, long length) { NSObject *_cbData = (__bridge NSObject *)(data); DumbCallbackData *cbData = (id)_cbData; [cbData->tracks addObject:[NSURL URLWithString:[cbData->baseUrl stringByAppendingFormat:@"#%i", startOrder]]]; return 0; } + (NSArray *)urlsForContainerURL:(NSURL *)url { if([url fragment]) { // input url already has fragment defined - no need to expand further return [NSMutableArray arrayWithObject:url]; } id audioSourceClass = NSClassFromString(@"AudioSource"); id source = [audioSourceClass audioSourceForURL:url]; if(![source open:url]) return 0; if(![source seekable]) return 0; [source seek:0 whence:SEEK_END]; long size = [source tell]; [source seek:0 whence:SEEK_SET]; void *data = malloc(size); [source read:data amount:size]; DUMBFILE *df = dumbfile_open_memory_and_free(data, size); if(!df) { ALog(@"Open failed for file: %@", [url absoluteString]); return NO; } NSMutableArray *tracks = [NSMutableArray array]; int i; int subsongs = dumb_get_psm_subsong_count(df); if(subsongs) { dumbfile_close(df); for(i = 0; i < subsongs; ++i) { [tracks addObject:[NSURL URLWithString:[[url absoluteString] stringByAppendingFormat:@"#%i", i]]]; } } else { dumbfile_seek(df, 0, SEEK_SET); DUH *duh; NSString *ext = [[url pathExtension] lowercaseString]; duh = dumb_read_any_quick(df, [ext isEqualToString:@"mod"] ? 0 : 1, 0); dumbfile_close(df); if(duh) { DumbCallbackData *data = [[DumbCallbackData alloc] init]; data->baseUrl = [url absoluteString]; data->tracks = tracks; dumb_it_scan_for_playable_orders(duh_get_it_sigdata(duh), scanCallback, (__bridge void *)data); } } return tracks; } @end