From 33b49c3de409b982b319889a91cbbbf450d7ec16 Mon Sep 17 00:00:00 2001 From: Chris Moeller Date: Fri, 4 Oct 2013 16:32:58 -0700 Subject: [PATCH] Added transparent archive unpacking of the first contained within the archive, for any non-archive file name extension --- Plugins/FileSource/FileSource.h | 7 ++ Plugins/FileSource/FileSource.m | 83 ++++++++++++++++++- .../FileSource.xcodeproj/project.pbxproj | 54 ++++++++++++ 3 files changed, 142 insertions(+), 2 deletions(-) diff --git a/Plugins/FileSource/FileSource.h b/Plugins/FileSource/FileSource.h index f556479a9..99961b779 100644 --- a/Plugins/FileSource/FileSource.h +++ b/Plugins/FileSource/FileSource.h @@ -8,10 +8,17 @@ #import +#import + #import "Plugin.h" @interface FileSource : NSObject { + fex_t *fex; + const void *data; + NSUInteger offset; + NSUInteger size; + FILE *_fd; NSURL *_url; diff --git a/Plugins/FileSource/FileSource.m b/Plugins/FileSource/FileSource.m index 2dc249e9a..e95733b7c 100644 --- a/Plugins/FileSource/FileSource.m +++ b/Plugins/FileSource/FileSource.m @@ -11,9 +11,57 @@ @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]; + + 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([[url path] UTF8String], "r"); @@ -27,17 +75,43 @@ - (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); + } + return (fseek(_fd, position, whence) == 0); } - (long)tell { - return ftell(_fd); + if ( fex ) return offset; + else return ftell(_fd); } - (long)read:(void *)buffer amount:(long)amount { - return fread(buffer, 1, amount, _fd); + 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 @@ -47,6 +121,11 @@ fclose(_fd); _fd = NULL; } + + if ( fex ) { + fex_close( fex ); + fex = NULL; + } } - (NSURL *)url diff --git a/Plugins/FileSource/FileSource.xcodeproj/project.pbxproj b/Plugins/FileSource/FileSource.xcodeproj/project.pbxproj index f78370def..ba89a0973 100644 --- a/Plugins/FileSource/FileSource.xcodeproj/project.pbxproj +++ b/Plugins/FileSource/FileSource.xcodeproj/project.pbxproj @@ -8,9 +8,27 @@ /* Begin PBXBuildFile section */ 17ADB41A0B979AEB00257CA2 /* FileSource.m in Sources */ = {isa = PBXBuildFile; fileRef = 17ADB4190B979AEB00257CA2 /* FileSource.m */; }; + 8335FF7017FF767A002D8DD2 /* File_Extractor.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 8335FF6D17FF765A002D8DD2 /* File_Extractor.framework */; }; 8D5B49B4048680CD000E48DA /* Cocoa.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 1058C7ADFEA557BF11CA2CBB /* Cocoa.framework */; }; /* End PBXBuildFile section */ +/* Begin PBXContainerItemProxy section */ + 8335FF6C17FF765A002D8DD2 /* PBXContainerItemProxy */ = { + isa = PBXContainerItemProxy; + containerPortal = 8335FF6817FF765A002D8DD2 /* File_Extractor.xcodeproj */; + proxyType = 2; + remoteGlobalIDString = 8359FF3C17FEF39F0060F3ED; + remoteInfo = File_Extractor; + }; + 8335FF6E17FF766F002D8DD2 /* PBXContainerItemProxy */ = { + isa = PBXContainerItemProxy; + containerPortal = 8335FF6817FF765A002D8DD2 /* File_Extractor.xcodeproj */; + proxyType = 1; + remoteGlobalIDString = 8359FF3B17FEF39F0060F3ED; + remoteInfo = File_Extractor; + }; +/* End PBXContainerItemProxy section */ + /* Begin PBXFileReference section */ 089C1672FE841209C02AAC07 /* Foundation.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = Foundation.framework; path = /System/Library/Frameworks/Foundation.framework; sourceTree = ""; }; 089C167FFE841241C02AAC07 /* AppKit.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = AppKit.framework; path = /System/Library/Frameworks/AppKit.framework; sourceTree = ""; }; @@ -19,6 +37,7 @@ 17ADB4180B979AEB00257CA2 /* FileSource.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = FileSource.h; sourceTree = ""; }; 17ADB4190B979AEB00257CA2 /* FileSource.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = FileSource.m; sourceTree = ""; }; 32DBCF630370AF2F00C91783 /* FileSource_Prefix.pch */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = FileSource_Prefix.pch; sourceTree = ""; }; + 8335FF6817FF765A002D8DD2 /* File_Extractor.xcodeproj */ = {isa = PBXFileReference; lastKnownFileType = "wrapper.pb-project"; name = File_Extractor.xcodeproj; path = ../../Frameworks/File_Extractor/File_Extractor.xcodeproj; sourceTree = ""; }; 8D5B49B6048680CD000E48DA /* FileSource.bundle */ = {isa = PBXFileReference; explicitFileType = wrapper.cfbundle; includeInIndex = 0; path = FileSource.bundle; sourceTree = BUILT_PRODUCTS_DIR; }; 8D5B49B7048680CD000E48DA /* Info.plist */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = ""; }; D2F7E65807B2D6F200F64583 /* CoreData.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = CoreData.framework; path = /System/Library/Frameworks/CoreData.framework; sourceTree = ""; }; @@ -29,6 +48,7 @@ isa = PBXFrameworksBuildPhase; buildActionMask = 2147483647; files = ( + 8335FF7017FF767A002D8DD2 /* File_Extractor.framework in Frameworks */, 8D5B49B4048680CD000E48DA /* Cocoa.framework in Frameworks */, ); runOnlyForDeploymentPostprocessing = 0; @@ -78,6 +98,7 @@ 1058C7ACFEA557BF11CA2CBB /* Linked Frameworks */ = { isa = PBXGroup; children = ( + 8335FF6817FF765A002D8DD2 /* File_Extractor.xcodeproj */, 1058C7ADFEA557BF11CA2CBB /* Cocoa.framework */, ); name = "Linked Frameworks"; @@ -109,6 +130,14 @@ name = "Other Sources"; sourceTree = ""; }; + 8335FF6917FF765A002D8DD2 /* Products */ = { + isa = PBXGroup; + children = ( + 8335FF6D17FF765A002D8DD2 /* File_Extractor.framework */, + ); + name = Products; + sourceTree = ""; + }; /* End PBXGroup section */ /* Begin PBXNativeTarget section */ @@ -123,6 +152,7 @@ buildRules = ( ); dependencies = ( + 8335FF6F17FF766F002D8DD2 /* PBXTargetDependency */, ); name = "FileSource Plugin"; productInstallPath = "$(HOME)/Library/Bundles"; @@ -147,6 +177,12 @@ ); mainGroup = 089C166AFE841209C02AAC07 /* FileSource */; projectDirPath = ""; + projectReferences = ( + { + ProductGroup = 8335FF6917FF765A002D8DD2 /* Products */; + ProjectRef = 8335FF6817FF765A002D8DD2 /* File_Extractor.xcodeproj */; + }, + ); projectRoot = ""; targets = ( 8D5B49AC048680CD000E48DA /* FileSource Plugin */, @@ -154,6 +190,16 @@ }; /* End PBXProject section */ +/* Begin PBXReferenceProxy section */ + 8335FF6D17FF765A002D8DD2 /* File_Extractor.framework */ = { + isa = PBXReferenceProxy; + fileType = wrapper.framework; + path = File_Extractor.framework; + remoteRef = 8335FF6C17FF765A002D8DD2 /* PBXContainerItemProxy */; + sourceTree = BUILT_PRODUCTS_DIR; + }; +/* End PBXReferenceProxy section */ + /* Begin PBXResourcesBuildPhase section */ 8D5B49AF048680CD000E48DA /* Resources */ = { isa = PBXResourcesBuildPhase; @@ -175,6 +221,14 @@ }; /* End PBXSourcesBuildPhase section */ +/* Begin PBXTargetDependency section */ + 8335FF6F17FF766F002D8DD2 /* PBXTargetDependency */ = { + isa = PBXTargetDependency; + name = File_Extractor; + targetProxy = 8335FF6E17FF766F002D8DD2 /* PBXContainerItemProxy */; + }; +/* End PBXTargetDependency section */ + /* Begin XCBuildConfiguration section */ 1DEB913B08733D840010E9CD /* Debug */ = { isa = XCBuildConfiguration;