Skip to content

Commit

Permalink
Begin unzck app. Working towards #3.
Browse files Browse the repository at this point in the history
  • Loading branch information
bmarwell committed May 31, 2019
1 parent 71a0b45 commit 62c893a
Show file tree
Hide file tree
Showing 16 changed files with 587 additions and 5 deletions.
1 change: 0 additions & 1 deletion .travis.yml
Original file line number Diff line number Diff line change
Expand Up @@ -36,7 +36,6 @@ install:
stages:
- validations
- test
- java11

jobs:
include:
Expand Down
2 changes: 1 addition & 1 deletion CONTRIBUTING.md
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@ Before creating pull requests, please tick these checkboxes in your mind:
- [ ] If this is a PR for a issue, please name it issues/# (e.g. issues/3).
- [ ] Before commiting and creating the PR, please execute:
- [ ] ./mvnw clean install -DskipTests=true -Pcheckstyle,checker
- [ ] ./mvnw -T4 clean install javadoc:jar sources:jar
- [ ] ./mvnw -T4 clean install javadoc:jar source:jar

If it doesn't compile, please fix the errors first. Thank you :)

48 changes: 48 additions & 0 deletions app/pom.xml
Original file line number Diff line number Diff line change
@@ -0,0 +1,48 @@
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<parent>
<artifactId>zchunk-parent</artifactId>
<groupId>io.github.zchunk</groupId>
<version>1.0.0-SNAPSHOT</version>
<relativePath>../pom.xml</relativePath>
</parent>
<modelVersion>4.0.0</modelVersion>

<artifactId>zchunk-app</artifactId>

<dependencies>
<dependency>
<groupId>io.github.zchunk</groupId>
<artifactId>zchunk-bundle-lib</artifactId>
<version>1.0.0-SNAPSHOT</version>
</dependency>

<!-- command line parser for apps -->
<dependency>
<groupId>info.picocli</groupId>
<artifactId>picocli</artifactId>
</dependency>

<dependency>
<groupId>org.checkerframework</groupId>
<artifactId>checker-qual</artifactId>
<scope>provided</scope>
</dependency>

<!-- test dependencies -->
<dependency>
<groupId>org.junit.jupiter</groupId>
<artifactId>junit-jupiter-api</artifactId>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.junit.jupiter</groupId>
<artifactId>junit-jupiter-engine</artifactId>
<scope>test</scope>
</dependency>

</dependencies>

</project>
100 changes: 100 additions & 0 deletions app/src/main/java/io/github/zchunk/app/ZChunk.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,100 @@
/*
* Copyright 2018 The zchunk-java contributors
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/

package io.github.zchunk.app;

import io.github.zchunk.app.commands.Unzck;
import java.util.concurrent.Callable;
import picocli.CommandLine;
import picocli.CommandLine.Command;
import picocli.CommandLine.Option;
import picocli.CommandLine.ParameterException;
import picocli.CommandLine.ParseResult;
import picocli.CommandLine.UnmatchedArgumentException;

@Command(
name = "ZChunk",
subcommands = {
Unzck.class
},
version = "1.0"
)
public class ZChunk implements Callable<Integer> {

@Option(names = {"-v", "--verbose"}, description = "Be verbose.")
private boolean verbose;

@Option(names = {"-h", "-?", "--help", "--usage"}, usageHelp = true, description = "display a help message")
private boolean helpRequested;

@Option(names = {"-V", "--version"}, versionHelp = true)
private boolean showVersion;



/*
Usage: unzck [OPTION...] <file>
unzck - Decompress a zchunk file
-c, --stdout Direct output to stdout
--dict Only extract the dictionary
-v, --verbose Increase verbosity (can be specified more than
once for debugging)
-?, --help Give this help list
--usage Give a short usage message
-V, --version Show program version
*/

public static int main(final String[] args) {
final CommandLine cmd = new CommandLine(new ZChunk());

try {
final ParseResult parseResult = cmd.parseArgs(args);

if (cmd.isUsageHelpRequested()) {
cmd.usage(cmd.getOut());
return cmd.getCommandSpec().exitCodeOnUsageHelp();
}

if (cmd.isVersionHelpRequested()) {
cmd.printVersionHelp(cmd.getOut());
return cmd.getCommandSpec().exitCodeOnVersionHelp();
}

} catch (final ParameterException ex) {
cmd.getErr().println(ex.getMessage());
if (!UnmatchedArgumentException.printSuggestions(ex, cmd.getErr())) {
ex.getCommandLine().usage(cmd.getErr());
}
return cmd.getCommandSpec().exitCodeOnInvalidInput();
}

try {
return cmd.execute(args);
} catch (final RuntimeException ex) {
// exception occurred in business logic
ex.printStackTrace(cmd.getErr());
return cmd.getCommandSpec().exitCodeOnExecutionException();
}

}

@Override
public Integer call() throws Exception {

return -1;
}
}
44 changes: 44 additions & 0 deletions app/src/main/java/io/github/zchunk/app/ZChunkFilename.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,44 @@
/*
* Copyright 2018 The zchunk-java contributors
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/

package io.github.zchunk.app;

import java.io.File;

public final class ZChunkFilename {

private ZChunkFilename() {
// util class
}

/**
* Returns a new file for the current directory replacing .zck with .zdict.
*
* @param zchunkFile
* the input file.
* @return the file name without directory.
*/
public static File getDictFile(final File zchunkFile) {
if (!zchunkFile.getName().endsWith(".zck")) {
throw new UnsupportedOperationException("Cannot acquire target file name");
}

final String newName = zchunkFile.getName().replaceAll("^(.*)\\.zck$", "$1.zdict");

return new File(newName);
}

}
136 changes: 136 additions & 0 deletions app/src/main/java/io/github/zchunk/app/commands/Unzck.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,136 @@
/*
* Copyright 2018 The zchunk-java contributors
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/

package io.github.zchunk.app.commands;

import io.github.zchunk.app.ZChunkFilename;
import io.github.zchunk.app.err.UncompressException;
import io.github.zchunk.fileformat.ZChunk;
import io.github.zchunk.fileformat.ZChunkFile;
import io.github.zchunk.fileformat.util.IOUtil;
import java.io.File;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.util.StringJoiner;
import java.util.concurrent.Callable;
import org.checkerframework.checker.nullness.qual.Nullable;
import picocli.CommandLine.Command;
import picocli.CommandLine.Option;
import picocli.CommandLine.Parameters;

@Command(description = "Unpacks the completely downloaded zck file.",
name = "unzck",
mixinStandardHelpOptions = true)
public class Unzck implements Callable<Integer> {

@Option(names = {"-c", "--stdout"})
private boolean toStdOut;

@Option(names = {"--dict"})
private boolean dictOnly;

@Option(names = {"-o"})
private @Nullable File outputFile;

@Parameters(arity = "1", paramLabel = "FILE")
@SuppressWarnings(value = {"initialization.fields.uninitialized", "dereference.of.nullable"})
private File inputFile;

@Override
public Integer call() {
final ZChunkFile zChunkFile = ZChunk.fromFile(this.inputFile);
if (this.dictOnly) {
return decompressDict(zChunkFile);
}

return -1;
}

private int decompressDict(final ZChunkFile zChunkFile) {
final File target = getTargetFile();
try {
final File targetDir = target.getAbsoluteFile().getParentFile();
if (null == targetDir) {
throw new IllegalStateException("TargetDir Parent is null: [" + target.getAbsolutePath() + "].");
}
targetDir.mkdirs();
target.createNewFile();
final InputStream decompressedDictStream = ZChunk.getDecompressedDictStream(zChunkFile.getHeader(), this.inputFile);
final FileOutputStream fileOutputStream = new FileOutputStream(target);
final int copied = IOUtil.copy(decompressedDictStream, fileOutputStream);

} catch (final FileNotFoundException fnfe) {
throw new UncompressException("Unable to create parent dir or file: [" + target.getAbsolutePath() + "].", fnfe);
} catch (final IOException ex) {
throw new UncompressException("Unable to write file: [" + target.getAbsolutePath() + "].", ex);
}

return 0;
}

private File getTargetFile() {
if (null != this.outputFile) {
return this.outputFile;
}

return ZChunkFilename.getDictFile(this.inputFile);
}

public boolean isToStdOut() {
return this.toStdOut;
}

public void setToStdOut(final boolean toStdOut) {
this.toStdOut = toStdOut;
}

public boolean isDictOnly() {
return this.dictOnly;
}

public void setDictOnly(final boolean dictOnly) {
this.dictOnly = dictOnly;
}

public @Nullable File getOutputFile() {
return this.outputFile;
}

public void setOutputFile(final @Nullable File outputFile) {
this.outputFile = outputFile;
}

public File getInputFile() {
return this.inputFile;
}

public void setInputFile(final File inputFile) {
this.inputFile = inputFile;
}


@Override
public String toString() {
return new StringJoiner(", ", Unzck.class.getSimpleName() + "[", "]")
.add("toStdOut=" + this.toStdOut)
.add("dictOnly=" + this.dictOnly)
.add("outputFile=" + this.outputFile)
.add("inputFile=" + this.inputFile)
.toString();
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
/*
* Copyright 2018 The zchunk-java contributors
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/

package io.github.zchunk.app.err;

import java.util.StringJoiner;

public class UncompressException extends RuntimeException {

private static final long serialVersionUID = -6570432692413525167L;

public UncompressException(final String message, final Throwable cause) {
super(message, cause);
}

@Override
public String toString() {
return new StringJoiner(", ", UncompressException.class.getSimpleName() + "[", "]")
.add("super='" + super.toString() + "'")
.toString();
}
}
Loading

0 comments on commit 62c893a

Please # to comment.