diff --git a/.travis.yml b/.travis.yml
index 09f1c28..3f5c93a 100644
--- a/.travis.yml
+++ b/.travis.yml
@@ -19,18 +19,12 @@ stages:
jobs:
include:
- stage: validations
- script: mvn checkstyle:check
+ script: mvn clean install -DskipTests=true
name: "Code validations (format, binary compatibilty, whitesource, etc.)"
- stage: test
script: mvn clean test
- name: "Run tests for Java 8"
-
- # Test against Java 11
- - stage: java11
- script: mvn clean test
- env: TRAVIS_JDK=adopt-openj9@1.11.0-2
- name: "Run tests for Java 11"
+ name: "Run tests for every java"
cache:
directories:
diff --git a/build/checkstyle/checkstyle.xml b/build/checkstyle/checkstyle.xml
new file mode 100644
index 0000000..da1d94b
--- /dev/null
+++ b/build/checkstyle/checkstyle.xml
@@ -0,0 +1,288 @@
+
+
+
+
+
+
+
+
If your input value was {@code 0xffffffffffffffff}, this method will throw no exception and happily overflow and return {@code + * -1L}.
+ */ @Value.Lazy long getUnsignedLongValue(); + /** + * Tries to fit the value into an int. As int conversion is often needed for array indexing, this will always throw an {@link + * ArithmeticException}, if + * the content value does not fit into a signed integer. + * + * @return an int representing the {@link #getValue()} value. + */ @Value.Lazy int getIntValue(); } diff --git a/compressedint/src/main/java/de/bmarwell/zchunk/compressedint/CompressedIntFactory.java b/compressedint/src/main/java/de/bmarwell/zchunk/compressedint/CompressedIntFactory.java index bf9af56..e909fdd 100644 --- a/compressedint/src/main/java/de/bmarwell/zchunk/compressedint/CompressedIntFactory.java +++ b/compressedint/src/main/java/de/bmarwell/zchunk/compressedint/CompressedIntFactory.java @@ -25,6 +25,19 @@ private CompressedIntFactory() { // util class } + /** + * Try to parse a compressed in from a given byte array. + * + * @param input + * the input byte array. + * @return a compressed int if it was parseable. + * @throws IllegalArgumentException + * if the byte array has zero-length. + * @throws IllegalArgumentException + * if the byte array length (byte count) is larger than {@link CompressedIntUtil#MAX_COMPRESSED_INT_LENGTH}. + * @throws NullPointerException + * if input is {@code null}. + */ public static CompressedInt fromCompressedBytes(final byte[] input) { if (input.length > CompressedIntUtil.MAX_COMPRESSED_INT_LENGTH) { throw new IllegalArgumentException( @@ -52,6 +65,19 @@ public static CompressedInt valueOf(final long unsignedLongValue) { return fromCompressedBytes(unsignedBytes); } + /** + * Directly takes an open {@link InputStream} and tries to read as many bytes as it takes for the compressed integer to end. + * + *Does not close the stream. That is the caller‘s responsibility.
+ * + * @param inputStream + * the not-closed stream to read from. + * @return a compresssed int. + * @throws IOException + * if we cannot read from the underlying stream. + * @throws IllegalArgumentException + * if the compressed int size (bytes read) will exceed {@link CompressedIntUtil#MAX_COMPRESSED_INT_LENGTH}. + */ public static CompressedInt readCompressedInt(final InputStream inputStream) throws IOException { int currentByte; int byteCounter = 0; diff --git a/compressedint/src/main/java/de/bmarwell/zchunk/compressedint/CompressedIntUtil.java b/compressedint/src/main/java/de/bmarwell/zchunk/compressedint/CompressedIntUtil.java index 3f53340..fae80fe 100644 --- a/compressedint/src/main/java/de/bmarwell/zchunk/compressedint/CompressedIntUtil.java +++ b/compressedint/src/main/java/de/bmarwell/zchunk/compressedint/CompressedIntUtil.java @@ -45,7 +45,14 @@ private CompressedIntUtil() { // private util } - + /** + * Compress a long to a compressed int. The long will be interpreted as positive, which may be confusing. + * + *E.g. All positive numbers will come out as expected. All negative numbers will exceed that value. + * The highest number you can convert is -{@code -1L}, which is interpreted as {@code 18446744073709551615 (2^64 - 1)}.
+ * + * @return a byte array which will never exceed the length of MAX_COMPRESSED_INT_LENGTH and will never have leading all-zero bytes. + */ public static byte[] compress(final long unsignedIntValue) { long modValue = unsignedIntValue; final byte[] tmp = new byte[MAX_COMPRESSED_INT_LENGTH]; @@ -73,6 +80,18 @@ public static byte[] compress(final long unsignedIntValue) { return out; } + /** + * Decompresses an unsignedint's bytevalue. + * + *The result is stored as {@link BigInteger}, because values might exceed overflow {@link Long#MAX_VALUE} and end up as + * negative. With BigInteger, no such information is lost.
+ * + * @param compressedUnsignedInt + * the bytearray holding a compressed int to decompress. + * @return a {@link BigInteger} object holding the uncompressed unsigned int value. + * @throws IllegalArgumentException + * if parameter {@code compressedUnsignedInt::length} exceeds the value of {@link #MAX_COMPRESSED_INT_LENGTH}. + */ public static BigInteger decompress(final byte[] compressedUnsignedInt) { if (compressedUnsignedInt.length > MAX_COMPRESSED_INT_LENGTH) { throw new IllegalArgumentException("Compressed int too big!"); diff --git a/compression/compression-api/pom.xml b/compression/compression-api/pom.xml index e63e3ec..7e0cc74 100644 --- a/compression/compression-api/pom.xml +++ b/compression/compression-api/pom.xml @@ -24,7 +24,7 @@Warning! Unstable API, this might change to Optional some day.
+ * + * @param compressionType + * the compression type value as defined in {@code zchunk_format.txt}. + * @return a compression algorithm which can decompress an input stream. + */ public static CompressionAlgorithm forType(final long compressionType) { return Optional.ofNullable(getTypeMappings().get(compressionType)) .flatMap(ReflectionUtil::newInstance) diff --git a/compression/compression-api/src/main/java/de/bmarwell/zchunk/compression/api/internal/ReflectionUtil.java b/compression/compression-api/src/main/java/de/bmarwell/zchunk/compression/api/internal/ReflectionUtil.java index e5d7ee7..d2518fd 100644 --- a/compression/compression-api/src/main/java/de/bmarwell/zchunk/compression/api/internal/ReflectionUtil.java +++ b/compression/compression-api/src/main/java/de/bmarwell/zchunk/compression/api/internal/ReflectionUtil.java @@ -43,6 +43,17 @@ private ReflectionUtil() { // util } + /** + * Will try to load classes implementing clazz, from any package below rootpackage. + * + * @param rootPackage + * the root package to search in. + * @param clazz + * the class which should be implemented by the found classes. + * @param
* Current values:
- * 0 = SHA-1
- * 1 = SHA-256
- * 2 = SHA-512
- * 3 = SHA-512/128 (first 128 bits of SHA-512 checksum)
+ * 0 = SHA-1
+ * 1 = SHA-256
+ * 2 = SHA-512
+ * 3 = SHA-512/128 (first 128 bits of SHA-512 checksum)
+ *
* +=================+==========================+==================+ * | Index size (ci) | Chunk checksum type (ci) | Chunk count (ci) | diff --git a/fileformat/src/main/java/de/bmarwell/zchunk/fileformat/ZChunkHeaderLead.java b/fileformat/src/main/java/de/bmarwell/zchunk/fileformat/ZChunkHeaderLead.java index 82e8898..26e6314 100644 --- a/fileformat/src/main/java/de/bmarwell/zchunk/fileformat/ZChunkHeaderLead.java +++ b/fileformat/src/main/java/de/bmarwell/zchunk/fileformat/ZChunkHeaderLead.java @@ -24,7 +24,7 @@ import org.immutables.value.Value; /** - * The lead:
+ * The lead. * *
* +-+-+-+-+-+====================+==================+=================+
diff --git a/fileformat/src/main/java/de/bmarwell/zchunk/fileformat/ZChunkHeaderPreface.java b/fileformat/src/main/java/de/bmarwell/zchunk/fileformat/ZChunkHeaderPreface.java index b337753..1c56ace 100644 --- a/fileformat/src/main/java/de/bmarwell/zchunk/fileformat/ZChunkHeaderPreface.java +++ b/fileformat/src/main/java/de/bmarwell/zchunk/fileformat/ZChunkHeaderPreface.java @@ -31,7 +31,6 @@ * +===============+============+========================+
*
* (Optional elements will only be set if flag 1 is set to 1)
- ** +=============================+
* | Optional element count (ci) |
* +=============================+
diff --git a/fileformat/src/main/java/de/bmarwell/zchunk/fileformat/err/InvalidFileException.java b/fileformat/src/main/java/de/bmarwell/zchunk/fileformat/err/InvalidFileException.java index 81e7f2b..fbcf624 100644 --- a/fileformat/src/main/java/de/bmarwell/zchunk/fileformat/err/InvalidFileException.java +++ b/fileformat/src/main/java/de/bmarwell/zchunk/fileformat/err/InvalidFileException.java @@ -23,6 +23,8 @@ public class InvalidFileException extends RuntimeException { + private static final long serialVersionUID = -1329481614175727163L; + private final @Nullable File sourceFile; public InvalidFileException(final String message) { diff --git a/fileformat/src/main/java/de/bmarwell/zchunk/fileformat/util/ChecksumUtil.java b/fileformat/src/main/java/de/bmarwell/zchunk/fileformat/util/ChecksumUtil.java index d1a1266..42affa9 100644 --- a/fileformat/src/main/java/de/bmarwell/zchunk/fileformat/util/ChecksumUtil.java +++ b/fileformat/src/main/java/de/bmarwell/zchunk/fileformat/util/ChecksumUtil.java @@ -135,10 +135,10 @@ private static byte[] getPrefaceBytes(final ZChunkHeaderPreface preface) { ); if (preface.hasOptionalElements()) { + // TODO: optional elements header final byte[] prefaceWithOptional = concat( prefaceBytes, preface.getOptionalElementCount().getCompressedBytes() - // TODO: optional elements header ); return prefaceWithOptional; @@ -210,19 +210,19 @@ public static boolean isValidData(final ZChunkHeader zChunkHeader, final File fi } - public static boolean allChunksAreValid(final ZChunkHeader zChunkFile, final File file) { - return zChunkFile.getIndex().getChunkInfoSortedByIndex().stream() - .allMatch(chunk -> chunkIsValid(chunk, zChunkFile, file)); + public static boolean allChunksAreValid(final ZChunkHeader zchunkFile, final File file) { + return zchunkFile.getIndex().getChunkInfoSortedByIndex().stream() + .allMatch(chunk -> chunkIsValid(chunk, zchunkFile, file)); } - private static boolean chunkIsValid(final ZChunkHeaderChunkInfo chunk, final ZChunkHeader zChunkFile, final File file) { - final long chunkOffset = OffsetUtil.getChunkOffset(zChunkFile, chunk.getCurrentIndex()); + private static boolean chunkIsValid(final ZChunkHeaderChunkInfo chunk, final ZChunkHeader zchunkFile, final File file) { + final long chunkOffset = OffsetUtil.getChunkOffset(zchunkFile, chunk.getCurrentIndex()); try (final FileInputStream fis = new FileInputStream(file)) { fis.skip(chunkOffset); final byte[] chunkData = new byte[chunk.getChunkLength().getIntValue()]; fis.read(chunkData); - final byte[] digest = zChunkFile.getIndex().getChunkChecksumType().digest(chunkData); + final byte[] digest = zchunkFile.getIndex().getChunkChecksumType().digest(chunkData); return Arrays.equals(chunk.getChunkChecksum(), digest); } catch (final IOException ioEx) { diff --git a/pom.xml b/pom.xml index 076c5f5..0ab4277 100644 --- a/pom.xml +++ b/pom.xml @@ -94,6 +94,11 @@ +true +true ++ @@ -107,8 +112,51 @@ + + +-Xlint:all,-processing ++ + +org.apache.maven.plugins +maven-checkstyle-plugin +3.0.0 ++ ++ ${maven.multiModuleProjectDirectory}/build/checkstyle/checkstyle.xml + ++ ${maven.multiModuleProjectDirectory}/build/checkstyle/header.txt + +UTF-8 +true +true +false ++ ++ +com.puppycrawl.tools +checkstyle +8.20 ++ + +org.apache.maven.plugins +maven-checkstyle-plugin +3.0.0 ++ ++ +checkstyle-check +validate ++ +check +