Skip to content

Commit

Permalink
add Zip mode to noz and fix some noz bugs
Browse files Browse the repository at this point in the history
  • Loading branch information
NSProgrammer committed Apr 23, 2018
1 parent cf86ebe commit ea8481d
Show file tree
Hide file tree
Showing 10 changed files with 237 additions and 33 deletions.
9 changes: 7 additions & 2 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,12 +2,17 @@

## History

### 1.10.1 (April 23, 2018) - Nolan O'Brien

- Add _Zip Mode_ support to `noz`
- Fix `noz` bugs

### 1.10.0 (June 3, 2017) - Nolan O'Brien

- add convenience file-to-file compression/decompression functions in `NOZUtils.h`
- add CLI for ZipUtilities (called `noz`)
- add CLI for _ZipUtilities_ (called `noz`)
- NOTE: Zip Mode is not yet implemented
- fix NOZUnzipper file size measurement bug
- fix `NOZUnzipper` file size measurement bug

### 1.9.3 (Feb 20, 2017) - Nolan O'Brien

Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,91 @@
<?xml version="1.0" encoding="UTF-8"?>
<Scheme
LastUpgradeVersion = "0930"
version = "1.3">
<BuildAction
parallelizeBuildables = "YES"
buildImplicitDependencies = "YES">
<BuildActionEntries>
<BuildActionEntry
buildForTesting = "YES"
buildForRunning = "YES"
buildForProfiling = "YES"
buildForArchiving = "YES"
buildForAnalyzing = "YES">
<BuildableReference
BuildableIdentifier = "primary"
BlueprintIdentifier = "1C70521A1EBEBBF20071C2FF"
BuildableName = "noz"
BlueprintName = "noz"
ReferencedContainer = "container:ZipUtilities.xcodeproj">
</BuildableReference>
</BuildActionEntry>
</BuildActionEntries>
</BuildAction>
<TestAction
buildConfiguration = "Debug"
selectedDebuggerIdentifier = "Xcode.DebuggerFoundation.Debugger.LLDB"
selectedLauncherIdentifier = "Xcode.DebuggerFoundation.Launcher.LLDB"
shouldUseLaunchSchemeArgsEnv = "YES">
<Testables>
</Testables>
<MacroExpansion>
<BuildableReference
BuildableIdentifier = "primary"
BlueprintIdentifier = "1C70521A1EBEBBF20071C2FF"
BuildableName = "noz"
BlueprintName = "noz"
ReferencedContainer = "container:ZipUtilities.xcodeproj">
</BuildableReference>
</MacroExpansion>
<AdditionalOptions>
</AdditionalOptions>
</TestAction>
<LaunchAction
buildConfiguration = "Release"
selectedDebuggerIdentifier = ""
selectedLauncherIdentifier = "Xcode.IDEFoundation.Launcher.PosixSpawn"
launchStyle = "0"
useCustomWorkingDirectory = "NO"
ignoresPersistentStateOnLaunch = "NO"
debugDocumentVersioning = "YES"
debugServiceExtension = "internal"
allowLocationSimulation = "YES">
<BuildableProductRunnable
runnableDebuggingMode = "0">
<BuildableReference
BuildableIdentifier = "primary"
BlueprintIdentifier = "1C70521A1EBEBBF20071C2FF"
BuildableName = "noz"
BlueprintName = "noz"
ReferencedContainer = "container:ZipUtilities.xcodeproj">
</BuildableReference>
</BuildableProductRunnable>
<AdditionalOptions>
</AdditionalOptions>
</LaunchAction>
<ProfileAction
buildConfiguration = "Release"
shouldUseLaunchSchemeArgsEnv = "YES"
savedToolIdentifier = ""
useCustomWorkingDirectory = "NO"
debugDocumentVersioning = "YES">
<BuildableProductRunnable
runnableDebuggingMode = "0">
<BuildableReference
BuildableIdentifier = "primary"
BlueprintIdentifier = "1C70521A1EBEBBF20071C2FF"
BuildableName = "noz"
BlueprintName = "noz"
ReferencedContainer = "container:ZipUtilities.xcodeproj">
</BuildableReference>
</BuildableProductRunnable>
</ProfileAction>
<AnalyzeAction
buildConfiguration = "Debug">
</AnalyzeAction>
<ArchiveAction
buildConfiguration = "Release"
revealArchiveInOrganizer = "YES">
</ArchiveAction>
</Scheme>
6 changes: 5 additions & 1 deletion ZipUtilities.xcodeproj/xcshareddata/xcschemes/noz.xcscheme
Original file line number Diff line number Diff line change
Expand Up @@ -77,9 +77,13 @@
isEnabled = "NO">
</CommandLineArgument>
<CommandLineArgument
argument = "-z"
argument = "-u"
isEnabled = "YES">
</CommandLineArgument>
<CommandLineArgument
argument = "-z -M Brotli 101 -c &quot;Encoded (101) using Brotli&quot; -o ~/Desktop/XC9.zip -i /Applications/Xcode_9_GM.app -m Brotli -l 10 "
isEnabled = "NO">
</CommandLineArgument>
<CommandLineArgument
argument = "-u -M ZStandard 102 -M Brotli 101 -M LZMA 14 -M LZ4 256 -M LZFSE 2049 -b ~/Desktop/TestNOZ -i ~/Desktop/maniac-mansion.zip -e -o MANIAC.EXE -m Deflate Maniac\ Mansion/Game/MANIAC.EXE -e Maniac\ Mansion/Music/Midi/dave.mid -e Maniac\ Mansion/Manual\ and\ cheats/walkthrough.txt -e Maniac\ Mansion/Manual\ and\ cheats/Manual/ca1.jpeg"
isEnabled = "NO">
Expand Down
3 changes: 3 additions & 0 deletions ZipUtilities/NOZCompress.h
Original file line number Diff line number Diff line change
Expand Up @@ -172,4 +172,7 @@ typedef BOOL(^NOZCompressionShouldExcludeFileBlock)(NSString* filePath);

@end

//! Enumerate files in directory. Returns `nil` if `directoryPath` is not a directory.
FOUNDATION_EXTERN NSArray<NOZFileZipEntry *> *NOZEntriesFromDirectory(NSString *directoryPath);

NS_ASSUME_NONNULL_END
10 changes: 6 additions & 4 deletions ZipUtilities/NOZCompress.m
Original file line number Diff line number Diff line change
Expand Up @@ -39,8 +39,6 @@ typedef NS_ENUM(NSUInteger, NOZCompressStep)
NOZCompressStepClose
};

static NSArray<NOZFileZipEntry *> * __nonnull NOZEntriesFromDirectory(NSString * __nonnull directoryPath);

#define kCancelledError NOZErrorCreate(NOZErrorCodeCompressCancelled, nil)

@interface NOZCompressDelegateInternal : NSObject <NOZCompressDelegate>
Expand Down Expand Up @@ -517,11 +515,15 @@ - (NSString *)description

@end

static NSArray<NOZFileZipEntry *> * NOZEntriesFromDirectory(NSString * directoryPath)
NSArray<NOZFileZipEntry *> * NOZEntriesFromDirectory(NSString * directoryPath)
{
NSMutableArray<NOZFileZipEntry *> *entries = [[NSMutableArray alloc] init];
NSFileManager *fm = [NSFileManager defaultManager];
NSDirectoryEnumerator *enumerator = [fm enumeratorAtPath:directoryPath];
if (!enumerator) {
return nil;
}

NSMutableArray<NOZFileZipEntry *> *entries = [[NSMutableArray alloc] init];
NSString *filePath = nil;
while (nil != (filePath = enumerator.nextObject)) {
NSString *fullPath = [directoryPath stringByAppendingPathComponent:filePath];
Expand Down
3 changes: 2 additions & 1 deletion noz/NOZCLI.h
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@
@class MethodInfo;

FOUNDATION_EXTERN int NOZCLI_main(NSString *exe, NSString *exeDir, NSString *currentDir, NSArray<NSString *> *args);
FOUNDATION_EXTERN void NOZCLI_printUsage(NSString *exe);
FOUNDATION_EXTERN void NOZCLI_printUsage(NSString *exe, NSString *modeFlag);

FOUNDATION_EXTERN void NOZCLI_registerExtraEncoders(void);

Expand All @@ -28,6 +28,7 @@ FOUNDATION_EXTERN NSArray<MethodInfo *> *NOZCLI_allMethods(void);
FOUNDATION_EXTERN NSArray<MethodInfo *> *NOZCLI_allUnsupportedMethods(void);
FOUNDATION_EXTERN NSArray<MethodInfo *> *NOZCLI_allDefaultMethods(void);
FOUNDATION_EXTERN NSArray<MethodInfo *> *NOZCLI_allExtendedMethods(void);
FOUNDATION_EXTERN BOOL NOZCLI_registerMethodToNumberMap(NSDictionary<NSString *, NSNumber *> *methodToNumberMap);

FOUNDATION_EXTERN NSArray<Class> *NOZCLI_allModes(void);

Expand Down
33 changes: 32 additions & 1 deletion noz/NOZCLI.m
Original file line number Diff line number Diff line change
Expand Up @@ -112,7 +112,7 @@ int NOZCLI_main(NSString *exe, NSString *exeDir, NSString *currentDir, NSArray<N
return -1;
}

void NOZCLI_printUsage(NSString *exe)
void NOZCLI_printUsage(NSString *exe, NSString *modeFlag)
{
if (exe) {
exe = @"noz";
Expand All @@ -122,6 +122,16 @@ void NOZCLI_printUsage(NSString *exe)

NSArray<Class> *modes = NOZCLI_allModes();

if (modeFlag) {
// if a mode was selected, just print how to use that mode
for (Class mode in modes) {
if ([[mode modeFlag] isEqualToString:modeFlag]) {
modes = @[mode];
break;
}
}
}

for (Class mode in modes) {
NSString *modeDescription = [NSString stringWithFormat:@"%@ mode:\n\t%@ %@ %@", [mode modeName], exe, [mode modeFlag], [mode modeExecutionDescription]];
printf("%s\n", modeDescription.UTF8String);
Expand Down Expand Up @@ -310,3 +320,24 @@ void NOZCLI_registerExtraEncoders(void)

return methods;
}

BOOL NOZCLI_registerMethodToNumberMap(NSDictionary<NSString *, NSNumber *> * __nullable methodToNumberMap)
{
NOZCompressionLibrary *lib = [NOZCompressionLibrary sharedInstance];
NSMutableDictionary<NSNumber *, MethodInfo *> *methodMap = [[NSMutableDictionary alloc] init];
for (NSString *methodName in methodToNumberMap.allKeys) {
MethodInfo *methodInfo = NOZCLI_lookupMethodByName(methodName);
if (!methodInfo) {
printf("No such method name: %s\n", methodName.UTF8String);
return NO;
}
NSNumber *methodNumber = methodToNumberMap[methodName];
methodMap[methodNumber] = methodInfo;
}
for (NSNumber *methodNumber in methodMap.allKeys) {
MethodInfo *methodInfo = methodMap[methodNumber];
[lib setEncoder:methodInfo.encoder forMethod:methodNumber.unsignedShortValue];
[lib setDecoder:methodInfo.decoder forMethod:methodNumber.unsignedShortValue];
}
return YES;
}
23 changes: 6 additions & 17 deletions noz/NOZCLIUnzipMode.m
Original file line number Diff line number Diff line change
Expand Up @@ -190,21 +190,8 @@ + (NSString *)modeExtraArgumentsSectionName:(NSUInteger)sectionIndex

+ (int)run:(NOZCLIUnzipModeInfo *)info
{
NOZCompressionLibrary *lib = [NOZCompressionLibrary sharedInstance];
NSMutableDictionary<NSNumber *, MethodInfo *> *methodMap = [[NSMutableDictionary alloc] init];
for (NSString *methodName in info.methodToNumberMap.allKeys) {
MethodInfo *methodInfo = NOZCLI_lookupMethodByName(methodName);
if (!methodInfo) {
printf("No such method name: %s\n", methodName.UTF8String);
return -1;
}
NSNumber *methodNumber = info.methodToNumberMap[methodName];
methodMap[methodNumber] = methodInfo;
}
for (NSNumber *methodNumber in methodMap.allKeys) {
MethodInfo *methodInfo = methodMap[methodNumber];
[lib setEncoder:methodInfo.encoder forMethod:methodNumber.unsignedShortValue];
[lib setDecoder:methodInfo.decoder forMethod:methodNumber.unsignedShortValue];
if (!NOZCLI_registerMethodToNumberMap(info.methodToNumberMap)) {
return -1;
}

if (0 == info.entryInfos.count) {
Expand Down Expand Up @@ -302,12 +289,14 @@ @implementation NOZCLIUnzipModeEntryInfo
return nil;
}

NSUInteger prevIndex = NSNotFound;
NSUInteger prevIndex = 0;
do {
const NSUInteger curIndex = eIndexes.firstIndex;
[eIndexes removeIndex:curIndex];
if (prevIndex != NSNotFound) {
[entryArgs addObject:[args subarrayWithRange:NSMakeRange(prevIndex, curIndex - prevIndex)]];
if (prevIndex != curIndex) {
[entryArgs addObject:[args subarrayWithRange:NSMakeRange(prevIndex, curIndex - prevIndex)]];
}
if (!eIndexes.count) {
[entryArgs addObject:[args subarrayWithRange:NSMakeRange(curIndex, args.count - curIndex)]];
}
Expand Down
85 changes: 80 additions & 5 deletions noz/NOZCLIZipMode.m
Original file line number Diff line number Diff line change
Expand Up @@ -167,8 +167,81 @@ + (NSString *)modeExtraArgumentsSectionName:(NSUInteger)sectionIndex

+ (int)run:(NOZCLIZipModeInfo *)info
{
printf("NYI!\n");
return -1;
if (!info) {
return -1;
}

if (!NOZCLI_registerMethodToNumberMap(info.methodToNumberMap)) {
return -1;
}

NSError *error;
NOZZipper *zipper = [[NOZZipper alloc] initWithZipFile:info.outputFile];
zipper.globalComment = info.globalComment;

if (![zipper openWithMode:NOZZipperModeCreate error:&error]) {
NOZCLI_printError(error);
return -1;
}

for (NOZCLIZipModeEntryInfo *entryInfo in info.entryInfos) {
MethodInfo *methodInfo = (entryInfo.methodName) ? NOZCLI_lookupMethodByName(entryInfo.methodName) : NOZCLI_lookupMethod(NOZCompressionMethodDeflate);
if (!methodInfo) {
printf("unrecognized compression method '%s'\n", entryInfo.methodName.UTF8String);
return -1;
}

UInt16 overrideMethodNumber = methodInfo.method;
if (entryInfo.methodName && info.methodToNumberMap[entryInfo.methodName]) {
overrideMethodNumber = info.methodToNumberMap[entryInfo.methodName].unsignedShortValue;
}

// TODO - support preventing recursion
// TODO - support avoiding hidden files

NSFileManager *fm = [NSFileManager defaultManager];
NSDirectoryEnumerator *enumerator = [fm enumeratorAtPath:entryInfo.entryPath];
if (!enumerator) {
NOZFileZipEntry *entry = [[NOZFileZipEntry alloc] initWithFilePath:entryInfo.entryPath];
if (![self _zip:zipper entry:entry methodInfo:methodInfo entryInfo:entryInfo method:overrideMethodNumber]) {
return -1;
}
} else {
NSString *filePath = nil;
while (nil != (filePath = enumerator.nextObject)) {
NSString *fullPath = [entryInfo.entryPath stringByAppendingPathComponent:filePath];
BOOL isDir = NO;
if ([fm fileExistsAtPath:fullPath isDirectory:&isDir] && !isDir) {
NOZFileZipEntry *entry = [[NOZFileZipEntry alloc] initWithFilePath:fullPath name:filePath];
if (![self _zip:zipper entry:entry methodInfo:methodInfo entryInfo:entryInfo method:overrideMethodNumber]) {
return -1;
}
}
}
}
}

if (![zipper closeAndReturnError:&error]) {
NOZCLI_printError(error);
return -1;
}

return 0;
}

+ (BOOL)_zip:(NOZZipper *)zipper entry:(NOZFileZipEntry *)entry methodInfo:(MethodInfo *)methodInfo entryInfo:(NOZCLIZipModeEntryInfo *)entryInfo method:(NOZCompressionMethod)method
{
entry.compressionMethod = method;
entry.compressionLevel = NOZCompressionLevelFromCustomEncoderLevel(1, 1 + methodInfo.levels, entryInfo.level ? (NSUInteger)[entryInfo.level integerValue] : methodInfo.defaultLevel);
entry.comment = entryInfo.comment;

printf("%s ...\n", entry.filePath.UTF8String);
NSError *error;
if (![zipper addEntry:entry progressBlock:NULL error:&error]) {
NOZCLI_printError(error);
return NO;
}
return YES;
}

@end
Expand All @@ -187,12 +260,14 @@ @implementation NOZCLIZipModeEntryInfo
return nil;
}

NSUInteger prevIndex = NSNotFound;
NSUInteger prevIndex = 0;
do {
const NSUInteger curIndex = eIndexes.firstIndex;
[eIndexes removeIndex:curIndex];
if (prevIndex != NSNotFound) {
[entryArgs addObject:[args subarrayWithRange:NSMakeRange(prevIndex, curIndex - prevIndex)]];
if (prevIndex != curIndex) {
[entryArgs addObject:[args subarrayWithRange:NSMakeRange(prevIndex, curIndex - prevIndex)]];
}
if (!eIndexes.count) {
[entryArgs addObject:[args subarrayWithRange:NSMakeRange(curIndex, args.count - curIndex)]];
}
Expand Down Expand Up @@ -276,7 +351,7 @@ + (instancetype)entryFromArgs:(NSArray<NSString *> *)args environmentPath:(NSStr
}
}

entryPath = NOZCLI_normalizedPath(envPath, envPath);
entryPath = NOZCLI_normalizedPath(envPath, entryPath);
if (!entryPath) {
return nil;
}
Expand Down
7 changes: 5 additions & 2 deletions noz/main.m
Original file line number Diff line number Diff line change
Expand Up @@ -26,8 +26,11 @@ int main(int argc, const char * argv[])
retVal = NOZCLI_main(exe, path, currentDir, args);
}

if (retVal == -1) {
NOZCLI_printUsage(exe);
if (retVal != 0) {
if (retVal != -1) {
printf("\n\n----------------------------------------\n\n");
}
NOZCLI_printUsage(exe, args.firstObject);
}
}

Expand Down

0 comments on commit ea8481d

Please sign in to comment.