// // FileSource.m // FileSource // // Created by Vincent Spader on 3/1/07. // Copyright 2007 __MyCompanyName__. All rights reserved. // #import "FileSource.h" #import "SandboxBroker.h" @implementation FileSource + (void)initialize { fex_init(); } - (id)init { self = [super init]; if(self) { fex = NULL; _fd = NULL; } return self; } - (BOOL)open:(NSURL *)url { [self setURL:url]; id sandboxBrokerClass = NSClassFromString(@"SandboxBroker"); id sandboxBroker = [sandboxBrokerClass sharedSandboxBroker]; sbHandle = [sandboxBroker beginFolderAccess:url]; NSString *path = [url path]; fex_type_t type; fex_err_t error = fex_identify_file(&type, [path UTF8String]); if(!error && type && strcmp(fex_type_name(type), "file")) { error = fex_open_type(&fex, [path UTF8String], type); if(!error) { while(!fex_done(fex)) { NSString *name = [[NSString stringWithUTF8String:fex_name(fex)] lowercaseString]; if([name hasSuffix:@".diz"] || [name hasSuffix:@".txt"] || [name hasSuffix:@".nfo"]) { error = fex_next(fex); if(error) return NO; continue; } break; } if(fex_done(fex)) return NO; error = fex_data(fex, &data); if(error) return NO; size = fex_size(fex); offset = 0; return YES; } else return NO; } _fd = fopen([path UTF8String], "r"); return (_fd != NULL); } - (BOOL)seekable { return YES; } - (BOOL)seek:(long)position whence:(int)whence { if(fex) { switch(whence) { case SEEK_CUR: position += offset; break; case SEEK_END: position += size; break; } offset = position; return (position >= 0) && (position < size); } if(_fd == NULL) { offset = 0; size = 0; return NO; } return (fseek(_fd, position, whence) == 0); } - (long)tell { if(fex) return offset; else return ftell(_fd); } - (long)read:(void *)buffer amount:(long)amount { if(fex) { if(amount + offset > size) amount = size - offset; memcpy(buffer, (const char *)data + offset, amount); offset += amount; return amount; } else { return fread(buffer, 1, amount, _fd); } } - (void)close { if(_fd) { fclose(_fd); _fd = NULL; } if(fex) { fex_close(fex); fex = NULL; } if(sbHandle) { id sandboxBrokerClass = NSClassFromString(@"SandboxBroker"); id sandboxBroker = [sandboxBrokerClass sharedSandboxBroker]; [sandboxBroker endFolderAccess:sbHandle]; sbHandle = NULL; } } - (NSURL *)url { return _url; } - (NSString *)mimeType { return nil; } - (void)setURL:(NSURL *)url { _url = url; } + (NSArray *)schemes { return @[@"file"]; } - (void)dealloc { [self close]; } @end