diff --git a/src/main/java/net/szum123321/textile_backup/core/FileTreeHashBuilder.java b/src/main/java/net/szum123321/textile_backup/core/FileTreeHashBuilder.java new file mode 100644 index 0000000..a6084e6 --- /dev/null +++ b/src/main/java/net/szum123321/textile_backup/core/FileTreeHashBuilder.java @@ -0,0 +1,66 @@ +/* + A simple backup mod for Fabric + Copyright (C) 2022 Szum123321 + + This program is free software: you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program. If not, see . +*/ + +package net.szum123321.textile_backup.core; + +import java.io.IOException; +import java.nio.ByteBuffer; +import java.nio.charset.StandardCharsets; +import java.nio.file.Files; +import java.nio.file.Path; +import java.util.function.Supplier; +import java.util.zip.Checksum; + +public class FileTreeHashBuilder { + private final static ThreadLocal buff = + ThreadLocal.withInitial(() -> new byte[Long.BYTES]); + private final Object lock = new Object(); + private final Supplier hasherProvider; + private long hash = 0, filesProcessed = 0, filesTotalSize = 0; + + public FileTreeHashBuilder(Supplier provider) { hasherProvider = provider; } + + public void update(Path path, long newHash) throws IOException { + byte[] raw = buff.get(); + var hasher = hasherProvider.get(); + + long size = Files.size(path); + + hasher.update(ByteBuffer.wrap(raw).putLong(size).array()); + hasher.update(path.toString().getBytes(StandardCharsets.UTF_8)); + hasher.update(ByteBuffer.wrap(raw).putLong(hash).array()); + + synchronized (lock) { + //This way exact order of files processed doesn't matter. + this.hash ^= hasher.getValue(); + filesProcessed++; + filesTotalSize += size; + } + } + + public long getValue() { + var hasher = hasherProvider.get(); + byte[] raw = buff.get(); + + hasher.update(ByteBuffer.wrap(raw).putLong(hash).array()); + hasher.update(ByteBuffer.wrap(raw).putLong(filesProcessed).array()); + hasher.update(ByteBuffer.wrap(raw).putLong(filesTotalSize).array()); + + return hasher.getValue(); + } +} diff --git a/src/main/java/net/szum123321/textile_backup/core/create/FileInputStreamSupplier.java b/src/main/java/net/szum123321/textile_backup/core/create/FileInputStreamSupplier.java index 465c004..1f9daf8 100644 --- a/src/main/java/net/szum123321/textile_backup/core/create/FileInputStreamSupplier.java +++ b/src/main/java/net/szum123321/textile_backup/core/create/FileInputStreamSupplier.java @@ -1,3 +1,21 @@ +/* + A simple backup mod for Fabric + Copyright (C) 2022 Szum123321 + + This program is free software: you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program. If not, see . +*/ + package net.szum123321.textile_backup.core.create; import net.szum123321.textile_backup.TextileBackup; @@ -16,7 +34,6 @@ public record FileInputStreamSupplier(Path path, String name, CompressionStatus. @Override public InputStream getInputStream() throws IOException { try { - //TODO: put in hasher return new HashingInputStream(Files.newInputStream(path), path, null, builder); } catch (IOException e) { builder.update(path, e); diff --git a/src/main/java/net/szum123321/textile_backup/core/create/HashingInputStream.java b/src/main/java/net/szum123321/textile_backup/core/create/HashingInputStream.java index 612b625..0b50904 100644 --- a/src/main/java/net/szum123321/textile_backup/core/create/HashingInputStream.java +++ b/src/main/java/net/szum123321/textile_backup/core/create/HashingInputStream.java @@ -1,3 +1,21 @@ +/* + A simple backup mod for Fabric + Copyright (C) 2022 Szum123321 + + This program is free software: you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program. If not, see . +*/ + package net.szum123321.textile_backup.core.create; import net.szum123321.textile_backup.core.CompressionStatus; diff --git a/src/main/java/net/szum123321/textile_backup/core/create/InputSupplier.java b/src/main/java/net/szum123321/textile_backup/core/create/InputSupplier.java index 246df54..e90e8d4 100644 --- a/src/main/java/net/szum123321/textile_backup/core/create/InputSupplier.java +++ b/src/main/java/net/szum123321/textile_backup/core/create/InputSupplier.java @@ -1,3 +1,21 @@ +/* + A simple backup mod for Fabric + Copyright (C) 2022 Szum123321 + + This program is free software: you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program. If not, see . +*/ + package net.szum123321.textile_backup.core.create; import org.apache.commons.compress.parallel.InputStreamSupplier; @@ -5,10 +23,8 @@ import org.apache.commons.compress.parallel.InputStreamSupplier; import java.io.IOException; import java.io.InputStream; import java.nio.file.Path; - public interface InputSupplier extends InputStreamSupplier { InputStream getInputStream() throws IOException; Path getPath(); - String getName(); } diff --git a/src/main/java/net/szum123321/textile_backup/core/restore/HashingOutputStream.java b/src/main/java/net/szum123321/textile_backup/core/restore/HashingOutputStream.java new file mode 100644 index 0000000..6757fa4 --- /dev/null +++ b/src/main/java/net/szum123321/textile_backup/core/restore/HashingOutputStream.java @@ -0,0 +1,55 @@ +/* + A simple backup mod for Fabric + Copyright (C) 2022 Szum123321 + + This program is free software: you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program. If not, see . +*/ + +package net.szum123321.textile_backup.core.restore; + +import org.jetbrains.annotations.NotNull; + +import java.io.FilterOutputStream; +import java.io.IOException; +import java.io.OutputStream; +import java.nio.file.Path; +import java.util.zip.Checksum; + +public class HashingOutputStream extends FilterOutputStream { + private final Path path; + private final Checksum hasher; + + public HashingOutputStream(OutputStream out, Path path, Checksum hasher) { + super(out); + this.path = path; + this.hasher = hasher; + } + + @Override + public void write(int b) throws IOException { + super.write(b); + hasher.update(b); + } + + @Override + public void write(byte[] @NotNull b, int off, int len) throws IOException { + super.write(b, off, len); + hasher.update(b, off, len); + } + + @Override + public void close() throws IOException { + super.close(); + } +}