From 268273aaf40e6f3f43ebf689d4815f8c816fb18c Mon Sep 17 00:00:00 2001 From: nathan Date: Sat, 29 Jul 2017 22:11:49 +0200 Subject: [PATCH] Removed Dependency on FastMD5, now uses SHA1 hashes. --- JavaBuilder.iml | 3 +- LICENSE | 7 - LICENSE.LGPLv3 | 165 ---------------- src/dorkbox/build/Project.java | 120 +----------- src/dorkbox/build/ProjectGwt.java | 12 +- src/dorkbox/build/ProjectJar.java | 4 +- src/dorkbox/build/ProjectJava.java | 20 +- src/dorkbox/build/util/Hash.java | 229 +++++++++++++++++++++++ src/dorkbox/build/util/ShutdownHook.java | 10 +- 9 files changed, 260 insertions(+), 310 deletions(-) delete mode 100644 LICENSE.LGPLv3 create mode 100644 src/dorkbox/build/util/Hash.java diff --git a/JavaBuilder.iml b/JavaBuilder.iml index 8c5afa8..7c0db3a 100644 --- a/JavaBuilder.iml +++ b/JavaBuilder.iml @@ -34,10 +34,9 @@ - - \ No newline at end of file + diff --git a/LICENSE b/LICENSE index 160caef..5315a53 100644 --- a/LICENSE +++ b/LICENSE @@ -14,13 +14,6 @@ Copyright 2010, dorkbox, llc - - FastMD5 - LGPL v3 License - http://www.twmacinta.com/myjava/fast_md5.php - Copyright 1996, Santeri Paavolainen, Helsinki Finland - Many changes Copyright 2002 - 2010 Timothy W Macinta - Originally written by Santeri Paavolainen, Helsinki Finland 1996 - - - FilenameUtils.java (normalize + dependencies) - Apache 2.0 License http://commons.apache.org/proper/commons-io/ Copyright 2013, ASF diff --git a/LICENSE.LGPLv3 b/LICENSE.LGPLv3 deleted file mode 100644 index 65c5ca8..0000000 --- a/LICENSE.LGPLv3 +++ /dev/null @@ -1,165 +0,0 @@ - GNU LESSER GENERAL PUBLIC LICENSE - Version 3, 29 June 2007 - - Copyright (C) 2007 Free Software Foundation, Inc. - Everyone is permitted to copy and distribute verbatim copies - of this license document, but changing it is not allowed. - - - This version of the GNU Lesser General Public License incorporates -the terms and conditions of version 3 of the GNU General Public -License, supplemented by the additional permissions listed below. - - 0. Additional Definitions. - - As used herein, "this License" refers to version 3 of the GNU Lesser -General Public License, and the "GNU GPL" refers to version 3 of the GNU -General Public License. - - "The Library" refers to a covered work governed by this License, -other than an Application or a Combined Work as defined below. - - An "Application" is any work that makes use of an interface provided -by the Library, but which is not otherwise based on the Library. -Defining a subclass of a class defined by the Library is deemed a mode -of using an interface provided by the Library. - - A "Combined Work" is a work produced by combining or linking an -Application with the Library. The particular version of the Library -with which the Combined Work was made is also called the "Linked -Version". - - The "Minimal Corresponding Source" for a Combined Work means the -Corresponding Source for the Combined Work, excluding any source code -for portions of the Combined Work that, considered in isolation, are -based on the Application, and not on the Linked Version. - - The "Corresponding Application Code" for a Combined Work means the -object code and/or source code for the Application, including any data -and utility programs needed for reproducing the Combined Work from the -Application, but excluding the System Libraries of the Combined Work. - - 1. Exception to Section 3 of the GNU GPL. - - You may convey a covered work under sections 3 and 4 of this License -without being bound by section 3 of the GNU GPL. - - 2. Conveying Modified Versions. - - If you modify a copy of the Library, and, in your modifications, a -facility refers to a function or data to be supplied by an Application -that uses the facility (other than as an argument passed when the -facility is invoked), then you may convey a copy of the modified -version: - - a) under this License, provided that you make a good faith effort to - ensure that, in the event an Application does not supply the - function or data, the facility still operates, and performs - whatever part of its purpose remains meaningful, or - - b) under the GNU GPL, with none of the additional permissions of - this License applicable to that copy. - - 3. Object Code Incorporating Material from Library Header Files. - - The object code form of an Application may incorporate material from -a header file that is part of the Library. You may convey such object -code under terms of your choice, provided that, if the incorporated -material is not limited to numerical parameters, data structure -layouts and accessors, or small macros, inline functions and templates -(ten or fewer lines in length), you do both of the following: - - a) Give prominent notice with each copy of the object code that the - Library is used in it and that the Library and its use are - covered by this License. - - b) Accompany the object code with a copy of the GNU GPL and this license - document. - - 4. Combined Works. - - You may convey a Combined Work under terms of your choice that, -taken together, effectively do not restrict modification of the -portions of the Library contained in the Combined Work and reverse -engineering for debugging such modifications, if you also do each of -the following: - - a) Give prominent notice with each copy of the Combined Work that - the Library is used in it and that the Library and its use are - covered by this License. - - b) Accompany the Combined Work with a copy of the GNU GPL and this license - document. - - c) For a Combined Work that displays copyright notices during - execution, include the copyright notice for the Library among - these notices, as well as a reference directing the user to the - copies of the GNU GPL and this license document. - - d) Do one of the following: - - 0) Convey the Minimal Corresponding Source under the terms of this - License, and the Corresponding Application Code in a form - suitable for, and under terms that permit, the user to - recombine or relink the Application with a modified version of - the Linked Version to produce a modified Combined Work, in the - manner specified by section 6 of the GNU GPL for conveying - Corresponding Source. - - 1) Use a suitable shared library mechanism for linking with the - Library. A suitable mechanism is one that (a) uses at run time - a copy of the Library already present on the user's computer - system, and (b) will operate properly with a modified version - of the Library that is interface-compatible with the Linked - Version. - - e) Provide Installation Information, but only if you would otherwise - be required to provide such information under section 6 of the - GNU GPL, and only to the extent that such information is - necessary to install and execute a modified version of the - Combined Work produced by recombining or relinking the - Application with a modified version of the Linked Version. (If - you use option 4d0, the Installation Information must accompany - the Minimal Corresponding Source and Corresponding Application - Code. If you use option 4d1, you must provide the Installation - Information in the manner specified by section 6 of the GNU GPL - for conveying Corresponding Source.) - - 5. Combined Libraries. - - You may place library facilities that are a work based on the -Library side by side in a single library together with other library -facilities that are not Applications and are not covered by this -License, and convey such a combined library under terms of your -choice, if you do both of the following: - - a) Accompany the combined library with a copy of the same work based - on the Library, uncombined with any other library facilities, - conveyed under the terms of this License. - - b) Give prominent notice with the combined library that part of it - is a work based on the Library, and explaining where to find the - accompanying uncombined form of the same work. - - 6. Revised Versions of the GNU Lesser General Public License. - - The Free Software Foundation may publish revised and/or new versions -of the GNU Lesser General Public License from time to time. Such new -versions will be similar in spirit to the present version, but may -differ in detail to address new problems or concerns. - - Each version is given a distinguishing version number. If the -Library as you received it specifies that a certain numbered version -of the GNU Lesser General Public License "or any later version" -applies to it, you have the option of following the terms and -conditions either of that published version or of any later version -published by the Free Software Foundation. If the Library as you -received it does not specify a version number of the GNU Lesser -General Public License, you may choose any version of the GNU Lesser -General Public License ever published by the Free Software Foundation. - - If the Library as you received it specifies that a proxy can decide -whether future versions of the GNU Lesser General Public License shall -apply, that proxy's public statement of acceptance of any version is -permanent authorization for you to choose that version for the -Library. diff --git a/src/dorkbox/build/Project.java b/src/dorkbox/build/Project.java index d5eee73..4da1cc6 100644 --- a/src/dorkbox/build/Project.java +++ b/src/dorkbox/build/Project.java @@ -28,7 +28,6 @@ import java.util.List; import java.util.Map; import java.util.Set; -import org.bouncycastle.crypto.digests.MD5Digest; import org.slf4j.Logger; import com.esotericsoftware.kryo.Kryo; @@ -37,16 +36,15 @@ import com.esotericsoftware.kryo.io.Input; import com.esotericsoftware.kryo.io.Output; import com.esotericsoftware.minlog.Log; import com.esotericsoftware.wildcard.Paths; -import com.twmacinta.util.MD5; import dorkbox.BuildOptions; import dorkbox.BuildVersion; import dorkbox.Builder; import dorkbox.build.util.BuildLog; +import dorkbox.build.util.Hash; import dorkbox.build.util.OutputFile; import dorkbox.build.util.ShutdownHook; import dorkbox.license.License; -import dorkbox.util.Base64Fast; import dorkbox.util.FileUtil; import dorkbox.util.OS; import dorkbox.util.SerializationManager; @@ -160,7 +158,7 @@ class Project> { try { String oldHash = Builder.settings.get("BUILD", String.class); - String hashedContents = generateChecksums(paths); + String hashedContents = Hash.generateChecksums(paths); if (oldHash != null) { if (!oldHash.equals(hashedContents)) { @@ -185,6 +183,8 @@ class Project> { } catch (IOException e) { e.printStackTrace(); } + + Hash.forceRebuildAll = forceRebuildAll; } public static @@ -235,7 +235,6 @@ class Project> { // used to make sure licenses are called in the correct spot private transient boolean calledLicenseBefore = false; - transient Paths checksumPaths = new Paths(); protected List licenses = new ArrayList(); protected BuildOptions buildOptions; @@ -259,6 +258,8 @@ class Project> { // true if we should rebuild this project boolean forceRebuild = false; + protected transient Hash hash; + /** * Temporary projects are always built, but not always exported to maven (this is controlled by the parent, non-temp project * recursively) @@ -341,6 +342,8 @@ class Project> { this.stagingDir = FileUtil.normalize(STAGING + File.separator + lowerCase_outputDir); // must call this method, because it's not overridden by jar type outputFile0(new File(this.stagingDir.getParentFile(), this.name + getExtension()).getAbsolutePath(), null); + + hash = new Hash(projectName, buildOptions); } /** @@ -522,7 +525,7 @@ class Project> { */ public T depends(final Paths dependencies) { - checksumPaths.add(dependencies); + hash.add(dependencies); sourceDependencies.add(dependencies); return (T) this; @@ -793,111 +796,6 @@ class Project> { } } - -/////////////////////////////////////////////////////////////////////////////////////////////////////// -//// CHECKSUM LOGIC -/////////////////////////////////////////////////////////////////////////////////////////////////////// - - /** - * Add a path to be checksum'd. - */ - @SuppressWarnings("WeakerAccess") - public final - void checksum(Paths path) { - this.checksumPaths.add(path); - } - - /** - * @return true if the checksums for path match the saved checksums and the jar file exists, false if the check failed and the - * project needs to rebuild - */ - boolean verifyChecksums() throws IOException { - if (forceRebuildAll || this.buildOptions.compiler.forceRebuild) { - return false; - } - - // check to see if our SOURCES *and check-summed files* have changed. - String hashedContents = generateChecksums(this.checksumPaths); - String checkContents = Builder.settings.get(this.name, String.class); - - return hashedContents != null && hashedContents.equals(checkContents); - } - - /** - * Saves the checksums for a given path - */ - void saveChecksums() throws IOException { - // by default, we save the build. When building a 'test' build, we opt to NOT save the build hashes, so that a 'normal' build - // will then compile. - if (!buildOptions.compiler.saveBuild) { - return; - } - - // hash/save the sources *and check-summed files* files - String hashedContents = generateChecksums(this.checksumPaths); - Builder.settings.save(this.name, hashedContents); - } - - /** - * Generates checksums for the given path - */ - public static - String generateChecksum(File file) throws IOException { - synchronized (Project.class) { - // calculate the hash of file - boolean found = false; - if (file.isFile() && file.canRead()) { - found = true; - } - - if (!found) { - return null; - } - - byte[] hashBytes = MD5.getHash(file); - - return Base64Fast.encodeToString(hashBytes, false); - } - } - - /** - * Generates checksums for the given path - */ - public static - String generateChecksums(Paths... paths) throws IOException { - synchronized (Project.class) { - // calculate the hash of all the files in the source path - Set names = new HashSet(64); - - for (Paths path : paths) { - names.addAll(path.getPaths()); - } - - // hash of hash of files. faster than using java to hash files - MD5Digest md5_digest = new MD5Digest(); - - boolean found = false; - for (String name : names) { - File file = new File(name); - if (file.isFile() && file.canRead()) { - found = true; - - byte[] hashBytes = MD5.getHash(file); - md5_digest.update(hashBytes, 0, hashBytes.length); - } - } - - if (!found) { - return null; - } - - byte[] hashBytes = new byte[md5_digest.getDigestSize()]; - md5_digest.doFinal(hashBytes, 0); - - return Base64Fast.encodeToString(hashBytes, false); - } - } - public T version(BuildVersion version) { this.version = version; diff --git a/src/dorkbox/build/ProjectGwt.java b/src/dorkbox/build/ProjectGwt.java index 98db6cd..c9fa98d 100644 --- a/src/dorkbox/build/ProjectGwt.java +++ b/src/dorkbox/build/ProjectGwt.java @@ -110,7 +110,7 @@ class ProjectGwt extends Project { if (srcDir.endsWith("src")) { String parent = new File(srcDir).getAbsoluteFile() .getParent(); - checksum(new Paths(parent)); + hash.add(parent); } return sourcePath(new Paths(srcDir, "./")); @@ -356,16 +356,15 @@ class ProjectGwt extends Project { * * @return true if the checksums for path match the saved checksums and the jar file exists */ - @Override boolean verifyChecksums() throws IOException { - boolean sourceHashesSame = super.verifyChecksums(); + boolean sourceHashesSame = hash.verifyChecksums(); if (!sourceHashesSame) { return false; } // if the sources are the same, check the output dir if (this.stagingDir.exists()) { - String dirChecksum = generateChecksum(this.stagingDir); + String dirChecksum = hash.generateChecksum(this.stagingDir); String checkContents = Builder.settings.get(this.stagingDir.getAbsolutePath(), String.class); return dirChecksum != null && dirChecksum.equals(checkContents); @@ -377,7 +376,6 @@ class ProjectGwt extends Project { /** * GWT only cares about the output dir (it doesn't make jars for compiling) Saves the checksums for a given path */ - @Override void saveChecksums() throws IOException { // by default, we save the build. When building a 'test' build, we opt to NOT save the build hashes, so that a 'normal' build // will then compile. @@ -385,11 +383,11 @@ class ProjectGwt extends Project { return; } - super.saveChecksums(); + hash.saveChecksums(); // hash/save the output files (if there are any) if (this.stagingDir.exists()) { - String fileChecksum = generateChecksum(this.stagingDir); + String fileChecksum = hash.generateChecksum(this.stagingDir); Builder.settings.save(this.stagingDir.getAbsolutePath(), fileChecksum); } } diff --git a/src/dorkbox/build/ProjectJar.java b/src/dorkbox/build/ProjectJar.java index afb8644..9ec269c 100644 --- a/src/dorkbox/build/ProjectJar.java +++ b/src/dorkbox/build/ProjectJar.java @@ -88,9 +88,9 @@ public class ProjectJar extends Project { public ProjectJar outputFileNoWarn(final String outputFile, final String outputSourceFile) { - this.checksumPaths.addFile(outputFile); + hash.add(outputFile); if (outputSourceFile != null) { - this.checksumPaths.addFile(outputSourceFile); + hash.add(outputSourceFile); } return super.outputFile(outputFile, outputSourceFile); diff --git a/src/dorkbox/build/ProjectJava.java b/src/dorkbox/build/ProjectJava.java index aed7441..251ca4d 100644 --- a/src/dorkbox/build/ProjectJava.java +++ b/src/dorkbox/build/ProjectJava.java @@ -98,7 +98,7 @@ class ProjectJava extends Project { this.sourcePaths.add(sourcePaths); // ALWAYS add the source paths to be checksumed! - checksum(sourcePaths); + hash.add(sourcePaths); return this; } @@ -110,7 +110,7 @@ class ProjectJava extends Project { ProjectJava sourcePath(String srcDir) { if (srcDir.endsWith("src")) { String parent = new File(srcDir).getAbsoluteFile().getParent(); - checksum(new Paths(parent)); + hash.add(new Paths(parent)); } return sourcePath(new Paths(srcDir, "./")); @@ -217,7 +217,7 @@ class ProjectJava extends Project { // also, we DO NOT check jar versions/etc here (that happens later) // if true, this means that the files ARE the same and they have not changed - final boolean b = project.verifyChecksums(); + final boolean b = project.hash.verifyChecksums(); shouldBuild |= !b; } } @@ -905,14 +905,13 @@ class ProjectJava extends Project { * @return true if the checksums for path match the saved checksums. If there is a JAR file, it also checks to see if it is built & * matches the saved checksums. If it's a temp project (and specifies a jar) the jarChecksum is ignored (so only checksums based on source code changes) */ - @Override boolean verifyChecksums() throws IOException { // if temporary + we override the status, we ALWAYS build it if (this.temporary && this.overrideTemporary) { return false; } - boolean sourceHashesSame = super.verifyChecksums(); + boolean sourceHashesSame = hash.verifyChecksums(); if (!sourceHashesSame) { return false; } @@ -926,7 +925,7 @@ class ProjectJava extends Project { final File originalOutputFile = this.outputFile.getOriginal(); if (originalOutputFile.canRead()) { - String jarChecksum = generateChecksum(originalOutputFile); + String jarChecksum = hash.generateChecksum(originalOutputFile); String checkContents = Builder.settings.get(this.name + ":" + originalOutputFile.getAbsolutePath(), String.class); boolean outputFileGood = jarChecksum != null && jarChecksum.equals(checkContents); @@ -939,7 +938,7 @@ class ProjectJava extends Project { final File originalOutputFileSource = this.outputFile.getSourceOriginal(); // now check the src.zip file (if there was one). - jarChecksum = generateChecksum(originalOutputFileSource); + jarChecksum = hash.generateChecksum(originalOutputFileSource); checkContents = Builder.settings.get(this.name + ":" + originalOutputFileSource.getAbsolutePath(), String.class); return jarChecksum != null && jarChecksum.equals(checkContents); @@ -961,7 +960,6 @@ class ProjectJava extends Project { * Saves the checksums for a given path - PER PROJECT (otherwise updating a jar in one place, and saving it's checksum, will verify * it everywhere else) */ - @Override void saveChecksums() throws IOException { // by default, we save the build. When building a 'test' build, we opt to NOT save the build hashes, so that a 'normal' build // will then compile. @@ -969,21 +967,21 @@ class ProjectJava extends Project { return; } - super.saveChecksums(); + hash.saveChecksums(); // when we verify checksums, we verify the ORIGINAL (if there is version info) -- and when we SAVE checksums, we save the NEW version final File currentOutputFile = this.outputFile.get(); // hash/save the jar file (if there was one) if (currentOutputFile.exists()) { - String fileChecksum = generateChecksum(currentOutputFile); + String fileChecksum = hash.generateChecksum(currentOutputFile); Builder.settings.save(this.name + ":" + currentOutputFile.getAbsolutePath(), fileChecksum); if (this.jarable != null && this.jarable.includeSourceAsSeparate) { final File currentOutputFileSource = this.outputFile.getSource(); // now check the src.zip file (if there was one). - fileChecksum = generateChecksum(currentOutputFileSource); + fileChecksum = hash.generateChecksum(currentOutputFileSource); Builder.settings.save(this.name + ":" + currentOutputFileSource.getAbsolutePath(), fileChecksum); } diff --git a/src/dorkbox/build/util/Hash.java b/src/dorkbox/build/util/Hash.java new file mode 100644 index 0000000..8aab642 --- /dev/null +++ b/src/dorkbox/build/util/Hash.java @@ -0,0 +1,229 @@ +/* + * Copyright 2012 dorkbox, llc + * + * 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 dorkbox.build.util; + +import java.io.File; +import java.io.FileInputStream; +import java.io.IOException; +import java.nio.ByteBuffer; +import java.nio.channels.FileChannel; +import java.security.MessageDigest; +import java.security.NoSuchAlgorithmException; +import java.util.HashSet; +import java.util.Set; + +import com.esotericsoftware.wildcard.Paths; + +import dorkbox.BuildOptions; +import dorkbox.Builder; +import dorkbox.build.Project; +import dorkbox.util.Base64Fast; +import dorkbox.util.IO; + +/** + * CHECKSUM LOGIC + */ +@SuppressWarnings({"Convert2Diamond", "AnonymousHasLambdaAlternative"}) +public +class Hash { + + private static final ThreadLocal digestThreadLocal = new ThreadLocal() { + @Override + protected + MessageDigest initialValue() { + try { + return MessageDigest.getInstance("SHA-1"); + } catch (NoSuchAlgorithmException ignored) { + // will never happen, since SHA1 is part of java. + return null; + } + } + }; + + + // set by Project.java + public static boolean forceRebuildAll = false; + + private transient Paths checksumPaths = new Paths(); + private final String projectName; + private BuildOptions buildOptions; + + public + Hash(final String projectName, BuildOptions buildOptions) { + this.projectName = projectName; + this.buildOptions = buildOptions; + } + + /** + * Add paths to be checksum'd. + */ + public + void add(final Paths paths) { + this.checksumPaths.add(paths); + } + + public + void add(final String file) { + this.checksumPaths.addFile(file); + } + + /** + * @return true if the checksums for path match the saved checksums and the jar file exists, false if the check failed and the + * project needs to rebuild + */ + public + boolean verifyChecksums() throws IOException { + if (forceRebuildAll || this.buildOptions.compiler.forceRebuild) { + return false; + } + + // check to see if our SOURCES *and check-summed files* have changed. + String hashedContents = generateChecksums(this.checksumPaths); + String checkContents = Builder.settings.get(this.projectName, String.class); + + return hashedContents != null && hashedContents.equals(checkContents); + } + + /** + * Saves the checksums for a given path + */ + public + void saveChecksums() throws IOException { + // hash/save the sources *and check-summed files* files + String hashedContents = generateChecksums(this.checksumPaths); + Builder.settings.save(this.projectName, hashedContents); + } + + + + + + + + /** + * Generates checksums for the given path + */ + public static + String generateChecksum(File file) throws IOException { + synchronized (Project.class) { + // calculate the hash of file + boolean found = false; + if (file.isFile() && file.canRead()) { + found = true; + } + + if (!found) { + return null; + } + + MessageDigest sha1 = digestThreadLocal.get(); + sha1.reset(); + + FileInputStream inputStream = null; + try { + inputStream = new FileInputStream(file); + FileChannel channel = inputStream.getChannel(); + + long length = file.length(); + if (length > Integer.MAX_VALUE) { + // you could make this work with some care, + // but this code does not bother. + throw new IOException("File " + file.getAbsolutePath() + " is too large."); + } + + ByteBuffer buffer = channel.map(FileChannel.MapMode.READ_ONLY, 0, length); + + int bufsize = 1024 * 8; + byte[] temp = new byte[bufsize]; + int bytesRead = 0; + + while (bytesRead < length) { + int numBytes = (int) length - bytesRead >= bufsize ? bufsize : (int) length - bytesRead; + buffer.get(temp, 0, numBytes); + sha1.update(temp, 0, numBytes); + bytesRead += numBytes; + } + + byte[] hashBytes = sha1.digest(); + return Base64Fast.encodeToString(hashBytes, false); + } finally { + IO.closeQuietly(inputStream); + } + } + } + + /** + * Generates checksums for the given path + */ + public static + String generateChecksums(Paths... paths) throws IOException { + synchronized (Project.class) { + // calculate the hash of all the files in the source path + Set names = new HashSet(64); + + for (Paths path : paths) { + names.addAll(path.getPaths()); + } + + // hash of all files. faster than using java to hash files + MessageDigest sha1 = digestThreadLocal.get(); + sha1.reset(); + + int bufsize = 1024 * 8; + byte[] temp = new byte[bufsize]; + int bytesRead = 0; + + boolean found = false; + for (String name : names) { + File file = new File(name); + if (file.isFile() && file.canRead()) { + found = true; + + FileInputStream inputStream = null; + try { + inputStream = new FileInputStream(file); + FileChannel channel = inputStream.getChannel(); + + long length = file.length(); + if (length > Integer.MAX_VALUE) { + // you could make this work with some care, + // but this code does not bother. + throw new IOException("File " + file.getAbsolutePath() + " is too large."); + } + + ByteBuffer buffer = channel.map(FileChannel.MapMode.READ_ONLY, 0, length); + + while (bytesRead < length) { + int numBytes = (int) length - bytesRead >= bufsize ? bufsize : (int) length - bytesRead; + buffer.get(temp, 0, numBytes); + sha1.update(temp, 0, numBytes); + bytesRead += numBytes; + } + } finally { + IO.closeQuietly(inputStream); + } + } + } + + if (!found) { + return null; + } + + byte[] hashBytes = sha1.digest(); + return Base64Fast.encodeToString(hashBytes, false); + } + } +} diff --git a/src/dorkbox/build/util/ShutdownHook.java b/src/dorkbox/build/util/ShutdownHook.java index 053a5ff..ed2b801 100644 --- a/src/dorkbox/build/util/ShutdownHook.java +++ b/src/dorkbox/build/util/ShutdownHook.java @@ -15,12 +15,12 @@ */ package dorkbox.build.util; -import com.esotericsoftware.wildcard.Paths; -import dorkbox.Builder; -import dorkbox.build.Project; - import java.io.IOException; +import com.esotericsoftware.wildcard.Paths; + +import dorkbox.Builder; + public class ShutdownHook implements Runnable { private final Paths paths; @@ -36,7 +36,7 @@ class ShutdownHook implements Runnable { try { BuildLog.start(); BuildLog.println("Saving build file checksums."); - String hashedContents = Project.generateChecksums(paths); + String hashedContents = Hash.generateChecksums(paths); Builder.settings.save("BUILD", hashedContents); BuildLog.finish(); } catch (IOException e) {