From 1c46967d58623a9267092d5062219fd48b1ae22a Mon Sep 17 00:00:00 2001 From: Stefano Pigozzi Date: Wed, 8 Jan 2020 01:16:15 +0100 Subject: [PATCH] I have done enough for tonight --- .../steffo/cleaver/gui/panels/ChopPanel.java | 10 +- .../cleaver/gui/panels/JobsTablePanel.java | 10 +- .../gui/panels/rows/option/CompressRow.java | 15 +-- .../gui/panels/rows/option/CryptRow.java | 13 +- .../gui/panels/rows/option/KeyRow.java | 4 +- .../gui/panels/rows/option/SplitRow.java | 21 ++-- .../cleaver/logic/config/CompressConfig.java | 13 -- .../cleaver/logic/config/DeflateConfig.java | 11 ++ .../cleaver/logic/config/ICompressConfig.java | 7 ++ .../steffo/cleaver/logic/config/IConfig.java | 14 +++ .../cleaver/logic/config/ICryptConfig.java | 7 ++ .../cleaver/logic/config/ISplitConfig.java | 7 ++ .../cleaver/logic/config/MergeConfig.java | 53 -------- .../cleaver/logic/config/PartsConfig.java | 28 +++++ .../{CryptConfig.java => PasswordConfig.java} | 8 +- .../cleaver/logic/config/SizeConfig.java | 28 +++++ .../logic/config/SplitByPartsConfig.java | 43 ------- .../logic/config/SplitBySizeConfig.java | 46 ------- .../cleaver/logic/config/SplitConfig.java | 29 ----- src/eu/steffo/cleaver/logic/job/ChopJob.java | 83 ++++++------- src/eu/steffo/cleaver/logic/job/Job.java | 16 ++- .../steffo/cleaver/logic/job/StitchJob.java | 113 ++---------------- .../output/CleaverCryptOutputStream.java | 16 ++- ....java => CleaverDeflaterOutputStream.java} | 27 ++--- .../output/CleaverForkFileOutputStream.java | 89 ++++++++++++++ .../output/CleaverSimpleFileOutputStream.java | 24 ++++ .../output/CleaverSplitFileOutputStream.java | 13 -- .../stream/output/ICleaverOutputStream.java | 2 +- src/module-info.java | 9 +- 29 files changed, 334 insertions(+), 425 deletions(-) delete mode 100644 src/eu/steffo/cleaver/logic/config/CompressConfig.java create mode 100644 src/eu/steffo/cleaver/logic/config/DeflateConfig.java create mode 100644 src/eu/steffo/cleaver/logic/config/ICompressConfig.java create mode 100644 src/eu/steffo/cleaver/logic/config/IConfig.java create mode 100644 src/eu/steffo/cleaver/logic/config/ICryptConfig.java create mode 100644 src/eu/steffo/cleaver/logic/config/ISplitConfig.java delete mode 100644 src/eu/steffo/cleaver/logic/config/MergeConfig.java create mode 100644 src/eu/steffo/cleaver/logic/config/PartsConfig.java rename src/eu/steffo/cleaver/logic/config/{CryptConfig.java => PasswordConfig.java} (68%) create mode 100644 src/eu/steffo/cleaver/logic/config/SizeConfig.java delete mode 100644 src/eu/steffo/cleaver/logic/config/SplitByPartsConfig.java delete mode 100644 src/eu/steffo/cleaver/logic/config/SplitBySizeConfig.java delete mode 100644 src/eu/steffo/cleaver/logic/config/SplitConfig.java rename src/eu/steffo/cleaver/logic/stream/output/{CleaverCompressOutputStream.java => CleaverDeflaterOutputStream.java} (80%) create mode 100644 src/eu/steffo/cleaver/logic/stream/output/CleaverForkFileOutputStream.java create mode 100644 src/eu/steffo/cleaver/logic/stream/output/CleaverSimpleFileOutputStream.java diff --git a/src/eu/steffo/cleaver/gui/panels/ChopPanel.java b/src/eu/steffo/cleaver/gui/panels/ChopPanel.java index 14456cc..8e4de2e 100644 --- a/src/eu/steffo/cleaver/gui/panels/ChopPanel.java +++ b/src/eu/steffo/cleaver/gui/panels/ChopPanel.java @@ -4,11 +4,9 @@ import eu.steffo.cleaver.gui.panels.rows.CreateJobButtonRow; import eu.steffo.cleaver.gui.panels.rows.option.CompressRow; import eu.steffo.cleaver.gui.panels.rows.option.CryptRow; import eu.steffo.cleaver.gui.panels.rows.option.SplitRow; +import eu.steffo.cleaver.logic.config.*; import eu.steffo.cleaver.logic.job.ChopJob; import eu.steffo.cleaver.logic.job.Job; -import eu.steffo.cleaver.logic.config.CompressConfig; -import eu.steffo.cleaver.logic.config.CryptConfig; -import eu.steffo.cleaver.logic.config.SplitConfig; import javax.swing.*; import java.awt.event.ActionListener; @@ -85,7 +83,7 @@ public class ChopPanel extends CreateJobPanel { } for(File file : fileSelectPanel.getSelectedFiles()) { - SplitConfig sc; + ISplitConfig sc; try { sc = splitRow.getSplitConfig(file.length()); } catch (NumberFormatException exc) { @@ -93,9 +91,9 @@ public class ChopPanel extends CreateJobPanel { return; } - CryptConfig cc = cryptRow.getCryptConfig(); + ICryptConfig cc = cryptRow.getCryptConfig(); - CompressConfig zc = compressRow.getCompressConfig(); + ICompressConfig zc = compressRow.getCompressConfig(); Job job = new ChopJob(file, sc, cc, zc, onProgressChange); jobs.add(job); diff --git a/src/eu/steffo/cleaver/gui/panels/JobsTablePanel.java b/src/eu/steffo/cleaver/gui/panels/JobsTablePanel.java index d700f92..1521875 100644 --- a/src/eu/steffo/cleaver/gui/panels/JobsTablePanel.java +++ b/src/eu/steffo/cleaver/gui/panels/JobsTablePanel.java @@ -1,9 +1,7 @@ package eu.steffo.cleaver.gui.panels; +import eu.steffo.cleaver.logic.config.*; import eu.steffo.cleaver.logic.job.Job; -import eu.steffo.cleaver.logic.config.CompressConfig; -import eu.steffo.cleaver.logic.config.CryptConfig; -import eu.steffo.cleaver.logic.config.SplitConfig; import javax.swing.*; import javax.swing.table.AbstractTableModel; @@ -82,15 +80,15 @@ public class JobsTablePanel extends JPanel { case 1: return job.getFile().getAbsolutePath(); case 2: - SplitConfig s = job.getSplitConfig(); + ISplitConfig s = job.getSplitConfig(); if(s == null) return ""; return s.toString(); case 3: - CryptConfig k = job.getCryptConfig(); + ICryptConfig k = job.getCryptConfig(); if(k == null) return ""; return k.toString(); case 4: - CompressConfig c = job.getCompressConfig(); + ICompressConfig c = job.getCompressConfig(); if(c == null) return ""; return c.toString(); case 5: diff --git a/src/eu/steffo/cleaver/gui/panels/rows/option/CompressRow.java b/src/eu/steffo/cleaver/gui/panels/rows/option/CompressRow.java index 1122f45..82f371c 100644 --- a/src/eu/steffo/cleaver/gui/panels/rows/option/CompressRow.java +++ b/src/eu/steffo/cleaver/gui/panels/rows/option/CompressRow.java @@ -1,11 +1,12 @@ package eu.steffo.cleaver.gui.panels.rows.option; -import eu.steffo.cleaver.logic.config.CompressConfig; +import eu.steffo.cleaver.logic.config.DeflateConfig; +import eu.steffo.cleaver.logic.config.ICompressConfig; import javax.swing.*; /** - * A {@link OptionRow} allowing the {@link CompressConfig configuration of the compress step} of the file chop process. + * A {@link OptionRow} allowing the {@link DeflateConfig configuration of the compress step} of the file chop process. * * @see eu.steffo.cleaver.gui.panels.ChopPanel */ @@ -32,17 +33,17 @@ public class CompressRow extends OptionRow { } /** - * Create a {@link CompressConfig} from the settings in this {@link OptionRow}. - * @return The resulting {@link CompressConfig}, or {@literal null} if the {@link #compressionCheckBox} is unticked. + * Create a {@link DeflateConfig} from the settings in this {@link OptionRow}. + * @return The resulting {@link DeflateConfig}, or {@literal null} if the {@link #compressionCheckBox} is unticked. */ - public CompressConfig getCompressConfig() { + public ICompressConfig getCompressConfig() { if(!compressionCheckBox.isSelected()) { return null; } - return new CompressConfig(); + return new DeflateConfig(); } - public void setCompressConfig(CompressConfig cfg) { + public void setCompressConfig(DeflateConfig cfg) { if(cfg == null) { compressionCheckBox.setSelected(false); } diff --git a/src/eu/steffo/cleaver/gui/panels/rows/option/CryptRow.java b/src/eu/steffo/cleaver/gui/panels/rows/option/CryptRow.java index 5c8c962..3f22835 100644 --- a/src/eu/steffo/cleaver/gui/panels/rows/option/CryptRow.java +++ b/src/eu/steffo/cleaver/gui/panels/rows/option/CryptRow.java @@ -1,11 +1,12 @@ package eu.steffo.cleaver.gui.panels.rows.option; -import eu.steffo.cleaver.logic.config.CryptConfig; +import eu.steffo.cleaver.logic.config.PasswordConfig; +import eu.steffo.cleaver.logic.config.ICryptConfig; import javax.swing.*; /** - * A {@link OptionRow} allowing the {@link CryptConfig configuration of the crypt step} of the file chop process. + * A {@link OptionRow} allowing the {@link PasswordConfig configuration of the crypt step} of the file chop process. * * @see eu.steffo.cleaver.gui.panels.ChopPanel */ @@ -65,14 +66,14 @@ public class CryptRow extends OptionRow { } /** - * Create a {@link CryptConfig} from the settings in this {@link OptionRow}. - * @return The resulting {@link CryptConfig}, or {@literal null} if the {@link #cryptCheckBox} is unticked. + * Create a {@link PasswordConfig} from the settings in this {@link OptionRow}. + * @return The resulting {@link PasswordConfig}, or {@literal null} if the {@link #cryptCheckBox} is unticked. */ - public CryptConfig getCryptConfig() { + public ICryptConfig getCryptConfig() { if(!cryptCheckBox.isSelected()) { return null; } - return new CryptConfig(keyTextField.getText()); + return new PasswordConfig(keyTextField.getText()); } @Override diff --git a/src/eu/steffo/cleaver/gui/panels/rows/option/KeyRow.java b/src/eu/steffo/cleaver/gui/panels/rows/option/KeyRow.java index 88c6bbc..0d8e70e 100644 --- a/src/eu/steffo/cleaver/gui/panels/rows/option/KeyRow.java +++ b/src/eu/steffo/cleaver/gui/panels/rows/option/KeyRow.java @@ -1,11 +1,11 @@ package eu.steffo.cleaver.gui.panels.rows.option; -import eu.steffo.cleaver.logic.config.CryptConfig; +import eu.steffo.cleaver.logic.config.PasswordConfig; import javax.swing.*; /** - * A {@link OptionRow} allowing the {@link CryptConfig configuration of the crypt step} of the file stitch process. + * A {@link OptionRow} allowing the {@link PasswordConfig configuration of the crypt step} of the file stitch process. * * This configuration is used only if the selected *.chp file specifies that the *.cXX are encrypted. * diff --git a/src/eu/steffo/cleaver/gui/panels/rows/option/SplitRow.java b/src/eu/steffo/cleaver/gui/panels/rows/option/SplitRow.java index 11f1fb4..d3592aa 100644 --- a/src/eu/steffo/cleaver/gui/panels/rows/option/SplitRow.java +++ b/src/eu/steffo/cleaver/gui/panels/rows/option/SplitRow.java @@ -1,15 +1,16 @@ package eu.steffo.cleaver.gui.panels.rows.option; -import eu.steffo.cleaver.logic.config.SplitByPartsConfig; -import eu.steffo.cleaver.logic.config.SplitBySizeConfig; -import eu.steffo.cleaver.logic.config.SplitConfig; +import eu.steffo.cleaver.logic.config.PartsConfig; +import eu.steffo.cleaver.logic.config.ISplitConfig; +import eu.steffo.cleaver.logic.config.SizeConfig; +import eu.steffo.cleaver.logic.config.IConfig; import javax.swing.*; import javax.swing.event.DocumentEvent; import javax.swing.event.DocumentListener; /** - * A {@link OptionRow} allowing the {@link SplitConfig configuration of the split step} of the file chop process. + * A {@link OptionRow} allowing the {@link IConfig configuration of the split step} of the file chop process. * * @see eu.steffo.cleaver.gui.panels.ChopPanel */ @@ -149,19 +150,19 @@ public class SplitRow extends OptionRow { } /** - * Create a {@link SplitConfig} from the settings in this {@link OptionRow}. - * @param fileSize The size of the file that the {@link SplitConfig} is being generated for. - * @return The resulting {@link SplitConfig}, or {@literal null} if the {@link #splitCheckBox} is unticked. + * Create a {@link IConfig} from the settings in this {@link OptionRow}. + * @param fileSize The size of the file that the {@link IConfig} is being generated for. + * @return The resulting {@link IConfig}, or {@literal null} if the {@link #splitCheckBox} is unticked. */ - public SplitConfig getSplitConfig(long fileSize) throws NumberFormatException { + public ISplitConfig getSplitConfig(long fileSize) throws NumberFormatException { if(!splitCheckBox.isSelected()) { return null; } else if(!sizeTextField.getText().equals("")) { - return new SplitBySizeConfig(Integer.parseInt(sizeTextField.getText()), fileSize); + return new SizeConfig(Long.parseLong(sizeTextField.getText())); } else if(!partsTextField.getText().equals("")) { - return new SplitByPartsConfig(Integer.parseInt(partsTextField.getText()), fileSize); + return new PartsConfig(Integer.parseInt(partsTextField.getText())); } else return null; } diff --git a/src/eu/steffo/cleaver/logic/config/CompressConfig.java b/src/eu/steffo/cleaver/logic/config/CompressConfig.java deleted file mode 100644 index 65d1a57..0000000 --- a/src/eu/steffo/cleaver/logic/config/CompressConfig.java +++ /dev/null @@ -1,13 +0,0 @@ -package eu.steffo.cleaver.logic.config; - -import eu.steffo.cleaver.logic.job.Job; - -/** - * A class containing the configuration for the compression step of a {@link Job Job}. - */ -public class CompressConfig { - @Override - public String toString() { - return "Yes (Deflate)"; - } -} diff --git a/src/eu/steffo/cleaver/logic/config/DeflateConfig.java b/src/eu/steffo/cleaver/logic/config/DeflateConfig.java new file mode 100644 index 0000000..7469b7e --- /dev/null +++ b/src/eu/steffo/cleaver/logic/config/DeflateConfig.java @@ -0,0 +1,11 @@ +package eu.steffo.cleaver.logic.config; + +/** + * A {@link IConfig} for compressing a file with the Deflate algorithm. + */ +public class DeflateConfig implements ICompressConfig { + @Override + public String toString() { + return "Yes (Deflate)"; + } +} diff --git a/src/eu/steffo/cleaver/logic/config/ICompressConfig.java b/src/eu/steffo/cleaver/logic/config/ICompressConfig.java new file mode 100644 index 0000000..f95cf3a --- /dev/null +++ b/src/eu/steffo/cleaver/logic/config/ICompressConfig.java @@ -0,0 +1,7 @@ +package eu.steffo.cleaver.logic.config; + +/** + * A {@link IConfig} for the Compress step of the {@link eu.steffo.cleaver.logic.job.ChopJob Chop}/{@link eu.steffo.cleaver.logic.job.StitchJob Stitch} process. + */ +public interface ICompressConfig extends IConfig { +} diff --git a/src/eu/steffo/cleaver/logic/config/IConfig.java b/src/eu/steffo/cleaver/logic/config/IConfig.java new file mode 100644 index 0000000..a322cdf --- /dev/null +++ b/src/eu/steffo/cleaver/logic/config/IConfig.java @@ -0,0 +1,14 @@ +package eu.steffo.cleaver.logic.config; + +import eu.steffo.cleaver.logic.job.Job; + +/** + * An interface for the configuration of a step of a {@link Job Job}. + */ +public interface IConfig { + /** + * @return The string representation of the {@link IConfig}, to be used in the jobs table. + * @see eu.steffo.cleaver.gui.panels.JobsTablePanel + */ + String toString(); +} diff --git a/src/eu/steffo/cleaver/logic/config/ICryptConfig.java b/src/eu/steffo/cleaver/logic/config/ICryptConfig.java new file mode 100644 index 0000000..35bcbe5 --- /dev/null +++ b/src/eu/steffo/cleaver/logic/config/ICryptConfig.java @@ -0,0 +1,7 @@ +package eu.steffo.cleaver.logic.config; + +/** + * A {@link IConfig} for the Crypt step of the {@link eu.steffo.cleaver.logic.job.ChopJob Chop}/{@link eu.steffo.cleaver.logic.job.StitchJob Stitch} process. + */ +public interface ICryptConfig extends IConfig { +} diff --git a/src/eu/steffo/cleaver/logic/config/ISplitConfig.java b/src/eu/steffo/cleaver/logic/config/ISplitConfig.java new file mode 100644 index 0000000..56b790a --- /dev/null +++ b/src/eu/steffo/cleaver/logic/config/ISplitConfig.java @@ -0,0 +1,7 @@ +package eu.steffo.cleaver.logic.config; + +/** + * A {@link IConfig} for the Split step of the {@link eu.steffo.cleaver.logic.job.ChopJob Chop}/{@link eu.steffo.cleaver.logic.job.StitchJob Stitch} process. + */ +public interface ISplitConfig extends IConfig { +} diff --git a/src/eu/steffo/cleaver/logic/config/MergeConfig.java b/src/eu/steffo/cleaver/logic/config/MergeConfig.java deleted file mode 100644 index fcea8f0..0000000 --- a/src/eu/steffo/cleaver/logic/config/MergeConfig.java +++ /dev/null @@ -1,53 +0,0 @@ -package eu.steffo.cleaver.logic.config; - -/** - * A {@link SplitConfig} created by reading a *.chp file, containing the number of parts and their size, but not the resulting file size. - */ -public class MergeConfig extends SplitConfig { - /** - * The size of the parts the file was split in. - */ - private long partSize; - - /** - * The number of parts the file was split in. - */ - private int parts; - - /** - * The total size of the original file. - */ - private long totalSize; - - /** - * Construct a new MergeConfig. - * @param partSize The size of the parts the file was split in. - * @param parts The number of parts the file was split in. - * @param totalSize The total size of the original file. - */ - public MergeConfig(long partSize, int parts, long totalSize) { - this.partSize = partSize; - this.parts = parts; - this.totalSize = totalSize; - } - - @Override - public long getPartSize() { - return partSize; - } - - @Override - public int getPartCount() { - return parts; - } - - @Override - public long getTotalSize() { - return totalSize; - } - - @Override - public String toString() { - return String.format("%d parts (%d bytes)", parts, partSize); - } -} diff --git a/src/eu/steffo/cleaver/logic/config/PartsConfig.java b/src/eu/steffo/cleaver/logic/config/PartsConfig.java new file mode 100644 index 0000000..151ca19 --- /dev/null +++ b/src/eu/steffo/cleaver/logic/config/PartsConfig.java @@ -0,0 +1,28 @@ +package eu.steffo.cleaver.logic.config; + +/** + * A {@link IConfig} for splitting a file in a specific number of parts. + */ +public class PartsConfig implements ISplitConfig { + /** + * The number of parts the file should be split in. + */ + private int parts; + + /** + * Construct a new SplitByPartsConfig. + * @param parts The number of parts the file should be split in. + */ + public PartsConfig(int parts) { + this.parts = parts; + } + + @Override + public String toString() { + return String.format("%d parts", this.parts); + } + + public int getPartCount() { + return parts; + } +} diff --git a/src/eu/steffo/cleaver/logic/config/CryptConfig.java b/src/eu/steffo/cleaver/logic/config/PasswordConfig.java similarity index 68% rename from src/eu/steffo/cleaver/logic/config/CryptConfig.java rename to src/eu/steffo/cleaver/logic/config/PasswordConfig.java index db2667c..26ca099 100644 --- a/src/eu/steffo/cleaver/logic/config/CryptConfig.java +++ b/src/eu/steffo/cleaver/logic/config/PasswordConfig.java @@ -1,18 +1,16 @@ package eu.steffo.cleaver.logic.config; -import eu.steffo.cleaver.logic.job.Job; - /** - * A class containing the configuration for the encryption/decryption step of a {@link Job Job}. + * A config for encrypting a file with an arbitrary length password. */ -public class CryptConfig { +public class PasswordConfig implements ICryptConfig { protected final String key; /** * Construct a new CryptConfig with a specific encryption key. * @param key The encryption key. */ - public CryptConfig(String key) { + public PasswordConfig(String key) { this.key = key; } diff --git a/src/eu/steffo/cleaver/logic/config/SizeConfig.java b/src/eu/steffo/cleaver/logic/config/SizeConfig.java new file mode 100644 index 0000000..f945a81 --- /dev/null +++ b/src/eu/steffo/cleaver/logic/config/SizeConfig.java @@ -0,0 +1,28 @@ +package eu.steffo.cleaver.logic.config; + +/** + * A {@link IConfig} for splitting a file in parts of a specific part size. + */ +public class SizeConfig implements ISplitConfig { + /** + * The size of the parts to split the file in. + */ + private long partSize; + + /** + * Construct a new SplitBySizeConfig. + * @param partSize The size of the parts to split the file in. + */ + public SizeConfig(long partSize) { + this.partSize = partSize; + } + + @Override + public String toString() { + return String.format("%d bytes", this.partSize); + } + + public long getPartSize() { + return partSize; + } +} diff --git a/src/eu/steffo/cleaver/logic/config/SplitByPartsConfig.java b/src/eu/steffo/cleaver/logic/config/SplitByPartsConfig.java deleted file mode 100644 index 70d9440..0000000 --- a/src/eu/steffo/cleaver/logic/config/SplitByPartsConfig.java +++ /dev/null @@ -1,43 +0,0 @@ -package eu.steffo.cleaver.logic.config; - -public class SplitByPartsConfig extends SplitConfig { - /** - * The number of parts the file should be split in. - */ - private int parts; - - /** - * The total size of the file to split. - */ - private long totalSize; - - /** - * Construct a new SplitByPartsConfig. - * @param parts The number of parts the file should be split in. - * @param totalSize The total size of the file to split. - */ - public SplitByPartsConfig(int parts, long totalSize) { - this.parts = parts; - this.totalSize = totalSize; - } - - @Override - public String toString() { - return String.format("%d parts", this.parts); - } - - @Override - public long getPartSize() { - return (int)Math.ceil((double) totalSize / (double)parts); - } - - @Override - public int getPartCount() { - return parts; - } - - @Override - public long getTotalSize() { - return totalSize; - } -} diff --git a/src/eu/steffo/cleaver/logic/config/SplitBySizeConfig.java b/src/eu/steffo/cleaver/logic/config/SplitBySizeConfig.java deleted file mode 100644 index 21b8c2e..0000000 --- a/src/eu/steffo/cleaver/logic/config/SplitBySizeConfig.java +++ /dev/null @@ -1,46 +0,0 @@ -package eu.steffo.cleaver.logic.config; - -/** - * A {@link SplitConfig} for splitting a file in parts of a specific part size. - */ -public class SplitBySizeConfig extends SplitConfig { - /** - * The size of the parts to split the file in. - */ - private long partSize; - - /** - * The total size of the file to split. - */ - private long totalSize; - - /** - * Construct a new SplitBySizeConfig. - * @param partSize The size of the parts to split the file in. - * @param totalSize The total size of the file to split. - */ - public SplitBySizeConfig(long partSize, long totalSize) { - this.partSize = partSize; - this.totalSize = totalSize; - } - - @Override - public String toString() { - return String.format("%d bytes", this.partSize); - } - - @Override - public long getPartSize() { - return partSize; - } - - @Override - public int getPartCount() { - return (int)Math.ceil((double) totalSize / (double)partSize); - } - - @Override - public long getTotalSize() { - return totalSize; - } -} diff --git a/src/eu/steffo/cleaver/logic/config/SplitConfig.java b/src/eu/steffo/cleaver/logic/config/SplitConfig.java deleted file mode 100644 index 2bd9387..0000000 --- a/src/eu/steffo/cleaver/logic/config/SplitConfig.java +++ /dev/null @@ -1,29 +0,0 @@ -package eu.steffo.cleaver.logic.config; - -import eu.steffo.cleaver.logic.job.Job; - -/** - * A class containing the configuration for the split/merge step of a {@link Job Job}. - */ -public abstract class SplitConfig { - /** - * @return The size in bytes of a single part of the file. - */ - public abstract long getPartSize(); - - /** - * @return The number of parts the file should be split in. - */ - public abstract int getPartCount(); - - /** - * @return The total size of the original file. - */ - public abstract long getTotalSize(); - - /** - * @return The string representation of the {@link SplitConfig}, to be used in the jobs table. - * @see eu.steffo.cleaver.gui.panels.JobsTablePanel - */ - public abstract String toString(); -} diff --git a/src/eu/steffo/cleaver/logic/job/ChopJob.java b/src/eu/steffo/cleaver/logic/job/ChopJob.java index 2ad69de..90ac72d 100644 --- a/src/eu/steffo/cleaver/logic/job/ChopJob.java +++ b/src/eu/steffo/cleaver/logic/job/ChopJob.java @@ -1,15 +1,12 @@ package eu.steffo.cleaver.logic.job; import eu.steffo.cleaver.errors.ProgrammingError; -import eu.steffo.cleaver.logic.config.CompressConfig; -import eu.steffo.cleaver.logic.config.CryptConfig; -import eu.steffo.cleaver.logic.stream.output.CleaverCryptOutputStream; +import eu.steffo.cleaver.logic.config.*; +import eu.steffo.cleaver.logic.stream.output.*; import eu.steffo.cleaver.logic.progress.ErrorProgress; import eu.steffo.cleaver.logic.progress.FinishedProgress; import eu.steffo.cleaver.logic.progress.Progress; import eu.steffo.cleaver.logic.progress.WorkingProgress; -import eu.steffo.cleaver.logic.config.SplitConfig; -import eu.steffo.cleaver.logic.stream.output.CleaverSplitFileOutputStream; import org.w3c.dom.Document; import org.w3c.dom.Element; @@ -21,7 +18,6 @@ import javax.xml.transform.TransformerFactory; import javax.xml.transform.dom.DOMSource; import javax.xml.transform.stream.StreamResult; import java.io.*; -import java.util.zip.DeflaterOutputStream; /** * A {@link Job} that converts regular files into chopped (*.chp + *.cXX) files. @@ -29,20 +25,20 @@ import java.util.zip.DeflaterOutputStream; public class ChopJob extends Job { private final File file; - private final SplitConfig splitConfig; - private final CryptConfig cryptConfig; - private final CompressConfig compressConfig; + private final ISplitConfig splitConfig; + private final ICryptConfig cryptConfig; + private final ICompressConfig compressConfig; /** * Create a new ChopJob (with progress updates support). * @param file The file to be chopped. - * @param splitConfig The configuration for the split step. - * @param cryptConfig The configuration for the crypt step. - * @param compressConfig The configuration for the compress step. + * @param splitConfig The configuration for the Split step. + * @param cryptConfig The configuration for the Crypt step. + * @param compressConfig The configuration for the Compress step. * @param onProgressChange A {@link Runnable} that should be invoked when {@link #setProgress(Progress)} is called. * @see Job#Job(Runnable) */ - public ChopJob(File file, SplitConfig splitConfig, CryptConfig cryptConfig, CompressConfig compressConfig, Runnable onProgressChange) { + public ChopJob(File file, ISplitConfig splitConfig, ICryptConfig cryptConfig, ICompressConfig compressConfig, Runnable onProgressChange) { super(onProgressChange); this.file = file; this.splitConfig = splitConfig; @@ -53,13 +49,13 @@ public class ChopJob extends Job { /** * Create a new ChopJob (without progress updates support). * @param file The file to be chopped. - * @param splitConfig The configuration for the split step. - * @param cryptConfig The configuration for the crypt step. - * @param compressConfig The configuration for the compress step. - * @see ChopJob#ChopJob(File, SplitConfig, CryptConfig, CompressConfig, Runnable) + * @param splitConfig The configuration for the Split step. + * @param cryptConfig The configuration for the Crypt step. + * @param compressConfig The configuration for the Compress step. + * @see ChopJob#ChopJob(File, ISplitConfig, ICryptConfig, ICompressConfig, Runnable) * @see Job#Job() */ - public ChopJob(File file, SplitConfig splitConfig, CryptConfig cryptConfig, CompressConfig compressConfig) { + public ChopJob(File file, ISplitConfig splitConfig, ICryptConfig cryptConfig, ICompressConfig compressConfig) { this(file, splitConfig, cryptConfig, compressConfig, null); } @@ -74,17 +70,17 @@ public class ChopJob extends Job { } @Override - public SplitConfig getSplitConfig() { + public ISplitConfig getSplitConfig() { return splitConfig; } @Override - public CryptConfig getCryptConfig() { + public ICryptConfig getCryptConfig() { return cryptConfig; } @Override - public CompressConfig getCompressConfig() { + public ICompressConfig getCompressConfig() { return compressConfig; } @@ -94,19 +90,22 @@ public class ChopJob extends Job { InputStream inputStream = new FileInputStream(file); OutputStream outputStream; - if(splitConfig != null) { - outputStream = new CleaverSplitFileOutputStream(file.getAbsolutePath(), splitConfig.getPartSize()); + if(splitConfig instanceof SizeConfig) { + outputStream = new CleaverSplitFileOutputStream(file.getAbsolutePath(), ((SizeConfig)splitConfig).getPartSize()); + } + else if(splitConfig instanceof PartsConfig) { + outputStream = new CleaverForkFileOutputStream(file.getAbsolutePath(), ((PartsConfig)splitConfig).getPartCount()); } else { - outputStream = new FileOutputStream(String.format("%s.c0", file.getAbsolutePath())); + outputStream = new CleaverSimpleFileOutputStream(file.getAbsolutePath()); } - if(compressConfig != null) { - outputStream = new DeflaterOutputStream(outputStream); + if(compressConfig instanceof DeflateConfig) { + outputStream = new CleaverDeflaterOutputStream(outputStream); } - if(cryptConfig != null) { - outputStream = new CleaverCryptOutputStream(outputStream, cryptConfig.getKey()); + if(cryptConfig instanceof PasswordConfig) { + outputStream = new CleaverCryptOutputStream(outputStream, ((PasswordConfig)cryptConfig).getKey()); } //Create the .chp file @@ -121,26 +120,6 @@ public class ChopJob extends Job { Element root = doc.createElement("Cleaver"); doc.appendChild(root); - Element original = doc.createElement("Original"); - original.setTextContent(file.getName()); - root.appendChild(original); - - if(splitConfig != null) { - root.appendChild(splitConfig.toElement(doc)); - } - if(compressConfig != null) { - root.appendChild(compressConfig.toElement(doc)); - } - if(cryptConfig != null) { - root.appendChild(cryptConfig.toElement(doc)); - } - - TransformerFactory transformerFactory = TransformerFactory.newInstance(); - Transformer transformer = transformerFactory.newTransformer(); - DOMSource source = new DOMSource(doc); - StreamResult result = new StreamResult(String.format("%s.chp", file.getAbsolutePath())); - transformer.transform(source, result); - //Pipe everything to the output int bytesUntilNextUpdate = 2048; this.setProgress(new WorkingProgress()); @@ -158,6 +137,14 @@ public class ChopJob extends Job { inputStream.close(); outputStream.close(); + root.appendChild(((ICleaverOutputStream)outputStream).toElement(doc)); + + TransformerFactory transformerFactory = TransformerFactory.newInstance(); + Transformer transformer = transformerFactory.newTransformer(); + DOMSource source = new DOMSource(doc); + StreamResult result = new StreamResult(String.format("%s.chp", file.getAbsolutePath())); + transformer.transform(source, result); + this.setProgress(new FinishedProgress()); } catch (Throwable e) { e.printStackTrace(); diff --git a/src/eu/steffo/cleaver/logic/job/Job.java b/src/eu/steffo/cleaver/logic/job/Job.java index aa05a32..8b4c2fd 100644 --- a/src/eu/steffo/cleaver/logic/job/Job.java +++ b/src/eu/steffo/cleaver/logic/job/Job.java @@ -3,11 +3,9 @@ package eu.steffo.cleaver.logic.job; import java.io.File; import javax.swing.SwingUtilities; -import eu.steffo.cleaver.logic.config.CompressConfig; -import eu.steffo.cleaver.logic.config.CryptConfig; +import eu.steffo.cleaver.logic.config.*; import eu.steffo.cleaver.logic.progress.NotStartedProgress; import eu.steffo.cleaver.logic.progress.Progress; -import eu.steffo.cleaver.logic.config.SplitConfig; /** * A {@link Thread} that allows access to the basic . @@ -62,19 +60,19 @@ public abstract class Job extends Thread { } /** - * @return The {@link SplitConfig} of the job. If {@literal null}, the job shouldn't handle file splitting/merging. + * @return The {@link IConfig} for the Split step of the job. If {@literal null}, the job shouldn't handle file splitting/merging. */ - public abstract SplitConfig getSplitConfig(); + public abstract ISplitConfig getSplitConfig(); /** - * @return The {@link CryptConfig} of the job. If {@literal null}, the job shouldn't handle file encryption/decryption. + * @return The {@link IConfig} for the Crypt step of the job. If {@literal null}, the job shouldn't handle file encryption/decryption. */ - public abstract CryptConfig getCryptConfig(); + public abstract ICryptConfig getCryptConfig(); /** - * @return The {@link CompressConfig} of the job. If {@literal null}, the job shouldn't handle file compression/decompression. + * @return The {@link IConfig} for the Compress step of the job. If {@literal null}, the job shouldn't handle file compression/decompression. */ - public abstract CompressConfig getCompressConfig(); + public abstract ICompressConfig getCompressConfig(); /** * Set the progress of the job to a different value. diff --git a/src/eu/steffo/cleaver/logic/job/StitchJob.java b/src/eu/steffo/cleaver/logic/job/StitchJob.java index ff01e94..a8dce3d 100644 --- a/src/eu/steffo/cleaver/logic/job/StitchJob.java +++ b/src/eu/steffo/cleaver/logic/job/StitchJob.java @@ -2,10 +2,7 @@ package eu.steffo.cleaver.logic.job; import eu.steffo.cleaver.errors.ChpFileError; import eu.steffo.cleaver.errors.ProgrammingError; -import eu.steffo.cleaver.logic.config.CompressConfig; -import eu.steffo.cleaver.logic.config.CryptConfig; -import eu.steffo.cleaver.logic.config.MergeConfig; -import eu.steffo.cleaver.logic.config.SplitConfig; +import eu.steffo.cleaver.logic.config.*; import eu.steffo.cleaver.logic.stream.input.CryptInputStream; import eu.steffo.cleaver.logic.progress.ErrorProgress; import eu.steffo.cleaver.logic.progress.FinishedProgress; @@ -25,15 +22,16 @@ import javax.xml.parsers.ParserConfigurationException; import java.io.*; import java.util.zip.InflaterInputStream; + /** * A {@link Job} that converts chopped (*.chp + *.cXX) files back into regular files. */ public class StitchJob extends Job { private File resultFile; private File chpFile; - private SplitConfig splitConfig = null; - private CryptConfig cryptConfig = null; - private CompressConfig compressConfig = null; + private ISplitConfig splitConfig = null; + private ICryptConfig cryptConfig = null; + private ICompressConfig compressConfig = null; /** * Construct a StitchJob, specifying the *.chp file to import the settings from. @@ -84,17 +82,17 @@ public class StitchJob extends Job { } @Override - public SplitConfig getSplitConfig() { + public ISplitConfig getSplitConfig() { return splitConfig; } @Override - public CryptConfig getCryptConfig() { + public ICryptConfig getCryptConfig() { return cryptConfig; } @Override - public CompressConfig getCompressConfig() { + public ICompressConfig getCompressConfig() { return compressConfig; } @@ -125,104 +123,17 @@ public class StitchJob extends Job { } /** - * Read a {@link Document} and set the {@link SplitConfig}, {@link CryptConfig} and {@link CompressConfig} of this job accordingly. + * Read a {@link Document} and set the {@link IConfig}, {@link PasswordConfig} and {@link DeflateConfig} of this job accordingly. * @param doc The {@link Document} to be read. - * @param cryptKey The encryption key to use in the {@link CryptConfig}. + * @param cryptKey The encryption key to use in the {@link PasswordConfig}. * @throws ChpFileError If there's an error while parsing the *.chp file. */ protected void parseChp(Document doc, String cryptKey) throws ChpFileError { - Element root = doc.getDocumentElement(); - - NodeList originals = root.getElementsByTagName("Original"); - NodeList splits = root.getElementsByTagName("Split"); - NodeList crypts = root.getElementsByTagName("Crypt"); - NodeList compresses = root.getElementsByTagName("Compress"); - - Node originalNode = originals.item(0); - Node splitNode = splits.item(0); - Node cryptNode = crypts.item(0); - Node compressNode = compresses.item(0); - - if(originalNode == null) { - throw new ChpFileError("No original filename found ( tag)"); - } - Element original = (Element)originalNode; - //The resulting file will be in the same directory of the *.chp file - resultFile = new File(chpFile.getAbsoluteFile().getParentFile().getAbsolutePath().concat("/" + original.getTextContent())); - - if(splitNode != null) { - Element split = (Element)splitNode; - - long partSize; - try { - partSize = Long.parseLong(split.getAttribute("part-size")); - } catch(NumberFormatException e) { - throw new ChpFileError("Corrupt part size data."); - } - - int parts; - try { - parts = Integer.parseInt(split.getAttribute("parts")); - } catch(NumberFormatException e) { - throw new ChpFileError("Corrupt parts data."); - } - - long totalSize; - try { - totalSize = Long.parseLong(split.getAttribute("total-size")); - } catch(NumberFormatException e) { - throw new ChpFileError("Corrupt total size data."); - } - - splitConfig = new MergeConfig(partSize, parts, totalSize); - } - if(cryptNode != null) { - cryptConfig = new CryptConfig(cryptKey); - } - if(compressNode != null) { - compressConfig = new CompressConfig(); - } + //TODO } @Override public void run() { - try { - InputStream inputStream; - OutputStream outputStream = new FileOutputStream(resultFile); - - if (splitConfig != null) { - inputStream = new CleaverSplitFileInputStream(resultFile.getPath(), splitConfig.getPartSize()); - } - else { - inputStream = new FileInputStream(String.format("%s.c0", resultFile.getAbsolutePath())); - } - - if (compressConfig != null) { - inputStream = new InflaterInputStream(inputStream); - } - - if (cryptConfig != null) { - inputStream = new CryptInputStream(inputStream, cryptConfig.getKey()); - } - - //Pipe everything to the output - int bytesUntilNextUpdate = 2048; - this.setProgress(new WorkingProgress()); - - int i; - while((i = inputStream.read()) != -1) { - outputStream.write(i); - bytesUntilNextUpdate -= 1; - if(bytesUntilNextUpdate <= 0) { - this.setProgress(new WorkingProgress((float)(resultFile.length() - inputStream.available()) / (float)resultFile.length())); - bytesUntilNextUpdate = 2048; - } - } - - this.setProgress(new FinishedProgress()); - } catch (Throwable e) { - e.printStackTrace(); - this.setProgress(new ErrorProgress(e)); - } + //TODO } } diff --git a/src/eu/steffo/cleaver/logic/stream/output/CleaverCryptOutputStream.java b/src/eu/steffo/cleaver/logic/stream/output/CleaverCryptOutputStream.java index 69cc1f4..ef45cae 100644 --- a/src/eu/steffo/cleaver/logic/stream/output/CleaverCryptOutputStream.java +++ b/src/eu/steffo/cleaver/logic/stream/output/CleaverCryptOutputStream.java @@ -78,7 +78,7 @@ public class CleaverCryptOutputStream extends FilterOutputStream implements ICle /** * Generate a new Initialization Vector with the specified size. - * @param size The size of the initialization vector. + * @param size The size in bytes of the initialization vector. * @return The generated IV. */ protected IvParameterSpec generateIV(int size) { @@ -103,15 +103,18 @@ public class CleaverCryptOutputStream extends FilterOutputStream implements ICle * @throws NoSuchAlgorithmException If the {@link #ENCRYPTION_ALGORITHM} is invalid. * @throws InvalidKeySpecException If the generated {@link KeySpec} is invalid. */ - private void createCipher(char[] key) throws NoSuchPaddingException, NoSuchAlgorithmException, InvalidKeySpecException, InvalidAlgorithmParameterException, InvalidKeyException { + private void initCipher(char[] key) throws NoSuchPaddingException, NoSuchAlgorithmException, InvalidKeySpecException, InvalidAlgorithmParameterException, InvalidKeyException { //Setup the cipher object cipher = Cipher.getInstance(getTransformationString()); //"Convert" the secret key to a AES secret key SecretKey aes = new SecretKeySpec(generatePasswordKey(key).getEncoded(), ENCRYPTION_ALGORITHM); + //Generate the initialization vector + IvParameterSpec iv = generateIV(1); + //Init the cipher instance - cipher.init(Cipher.ENCRYPT_MODE, aes, generateIV(1)); + cipher.init(Cipher.ENCRYPT_MODE, aes, iv); } /** @@ -123,8 +126,9 @@ public class CleaverCryptOutputStream extends FilterOutputStream implements ICle public CleaverCryptOutputStream(OutputStream out, String key) { super(out); try { - createCipher(key.toCharArray()); + initCipher(key.toCharArray()); } catch (NoSuchPaddingException | NoSuchAlgorithmException | InvalidKeySpecException | InvalidAlgorithmParameterException | InvalidKeyException e) { + //This should never happen... e.printStackTrace(); } } @@ -169,6 +173,10 @@ public class CleaverCryptOutputStream extends FilterOutputStream implements ICle keyLengthAttr.setValue(Integer.toString(KEY_LENGTH)); element.setAttributeNode(keyLengthAttr); + Attr ivAttr = doc.createAttribute("iv"); + ivAttr.setValue(Byte.toString(cipher.getIV()[0])); + element.setAttributeNode(ivAttr); + return element; } } diff --git a/src/eu/steffo/cleaver/logic/stream/output/CleaverCompressOutputStream.java b/src/eu/steffo/cleaver/logic/stream/output/CleaverDeflaterOutputStream.java similarity index 80% rename from src/eu/steffo/cleaver/logic/stream/output/CleaverCompressOutputStream.java rename to src/eu/steffo/cleaver/logic/stream/output/CleaverDeflaterOutputStream.java index 6bd19c8..2325845 100644 --- a/src/eu/steffo/cleaver/logic/stream/output/CleaverCompressOutputStream.java +++ b/src/eu/steffo/cleaver/logic/stream/output/CleaverDeflaterOutputStream.java @@ -8,12 +8,12 @@ import java.io.OutputStream; import java.util.zip.Deflater; import java.util.zip.DeflaterOutputStream; -public class CleaverCompressOutputStream extends DeflaterOutputStream implements ICleaverOutputStream { +public class CleaverDeflaterOutputStream extends DeflaterOutputStream implements ICleaverOutputStream { /** * Construct a new CleaverCompressOutputStream and ensure the passed {@link OutputStream} implements {@link ICleaverOutputStream}. * @see DeflaterOutputStream#DeflaterOutputStream(OutputStream, Deflater, int, boolean) */ - public CleaverCompressOutputStream(OutputStream out, Deflater def, int size, boolean syncFlush) { + public CleaverDeflaterOutputStream(OutputStream out, Deflater def, int size, boolean syncFlush) { super(out, def, size, syncFlush); if(!(out instanceof ICleaverOutputStream)) { throw new IllegalArgumentException("The OutputStream passed to the CleaverCompressOutputStream must implement ICleaverOutputStream."); @@ -24,7 +24,7 @@ public class CleaverCompressOutputStream extends DeflaterOutputStream implements * Construct a new CleaverCompressOutputStream and ensure the passed {@link OutputStream} implements {@link ICleaverOutputStream}. * @see DeflaterOutputStream#DeflaterOutputStream(OutputStream, Deflater, int) */ - public CleaverCompressOutputStream(OutputStream out, Deflater def, int size) { + public CleaverDeflaterOutputStream(OutputStream out, Deflater def, int size) { super(out, def, size); if(!(out instanceof ICleaverOutputStream)) { throw new IllegalArgumentException("The OutputStream passed to the CleaverCompressOutputStream must implement ICleaverOutputStream."); @@ -35,7 +35,7 @@ public class CleaverCompressOutputStream extends DeflaterOutputStream implements * Construct a new CleaverCompressOutputStream and ensure the passed {@link OutputStream} implements {@link ICleaverOutputStream}. * @see DeflaterOutputStream#DeflaterOutputStream(OutputStream, Deflater, boolean) */ - public CleaverCompressOutputStream(OutputStream out, Deflater def, boolean syncFlush) { + public CleaverDeflaterOutputStream(OutputStream out, Deflater def, boolean syncFlush) { super(out, def, syncFlush); if(!(out instanceof ICleaverOutputStream)) { throw new IllegalArgumentException("The OutputStream passed to the CleaverCompressOutputStream must implement ICleaverOutputStream."); @@ -46,7 +46,7 @@ public class CleaverCompressOutputStream extends DeflaterOutputStream implements * Construct a new CleaverCompressOutputStream and ensure the passed {@link OutputStream} implements {@link ICleaverOutputStream}. * @see DeflaterOutputStream#DeflaterOutputStream(OutputStream, Deflater) */ - public CleaverCompressOutputStream(OutputStream out, Deflater def) { + public CleaverDeflaterOutputStream(OutputStream out, Deflater def) { super(out, def); if(!(out instanceof ICleaverOutputStream)) { throw new IllegalArgumentException("The OutputStream passed to the CleaverCompressOutputStream must implement ICleaverOutputStream."); @@ -57,7 +57,7 @@ public class CleaverCompressOutputStream extends DeflaterOutputStream implements * Construct a new CleaverCompressOutputStream and ensure the passed {@link OutputStream} implements {@link ICleaverOutputStream}. * @see DeflaterOutputStream#DeflaterOutputStream(OutputStream, boolean) */ - public CleaverCompressOutputStream(OutputStream out, boolean syncFlush) { + public CleaverDeflaterOutputStream(OutputStream out, boolean syncFlush) { super(out, syncFlush); if(!(out instanceof ICleaverOutputStream)) { throw new IllegalArgumentException("The OutputStream passed to the CleaverCompressOutputStream must implement ICleaverOutputStream."); @@ -68,31 +68,20 @@ public class CleaverCompressOutputStream extends DeflaterOutputStream implements * Construct a new CleaverCompressOutputStream and ensure the passed {@link OutputStream} implements {@link ICleaverOutputStream}. * @see DeflaterOutputStream#DeflaterOutputStream(OutputStream) */ - public CleaverCompressOutputStream(OutputStream out) { + public CleaverDeflaterOutputStream(OutputStream out) { super(out); if(!(out instanceof ICleaverOutputStream)) { throw new IllegalArgumentException("The OutputStream passed to the CleaverCompressOutputStream must implement ICleaverOutputStream."); } } - /** - * @return The name of the used compression algorithm (currently only {@literal Deflate}). - */ - public String getAlgorithm() { - return "Deflate"; - } - @Override public Element toElement(Document doc) { - Element element = doc.createElement("Compress"); + Element element = doc.createElement("Deflate"); Element child = ((ICleaverOutputStream)out).toElement(doc); element.appendChild(child); - Attr algorithmAttr = doc.createAttribute("algorithm"); - algorithmAttr.setValue(getAlgorithm()); - element.setAttributeNode(algorithmAttr); - return element; } } diff --git a/src/eu/steffo/cleaver/logic/stream/output/CleaverForkFileOutputStream.java b/src/eu/steffo/cleaver/logic/stream/output/CleaverForkFileOutputStream.java new file mode 100644 index 0000000..1a1fd2c --- /dev/null +++ b/src/eu/steffo/cleaver/logic/stream/output/CleaverForkFileOutputStream.java @@ -0,0 +1,89 @@ +package eu.steffo.cleaver.logic.stream.output; + +import org.w3c.dom.Attr; +import org.w3c.dom.Document; +import org.w3c.dom.Element; + +import java.io.*; + +/** + * A custom {@link OutputStream} that writes the bytes received in input in multiple files with a progressively increasing number (.c1, .c2, .c3, and so on). + * + * Bytes are written one at a time to the files in a round-robin format until the stream is exausted. + */ +public class CleaverForkFileOutputStream extends OutputStream implements ICleaverOutputStream { + private final String fileBaseName; + private FileOutputStream[] fileOutputStreams; + private int writeTo; + private long partSize; + + /** + * Construct a CleaverForkFileOutputStream. + * @param fileBaseName The name of the files without the extension. If it is {@literal example}, the created files will be {@literal example.c1}, {@literal example.c2}, and so on. + * @param parts The number of parts to be created. + */ + public CleaverForkFileOutputStream(String fileBaseName, int parts) throws FileNotFoundException { + this.fileBaseName = fileBaseName; + this.fileOutputStreams = new FileOutputStream[parts]; + for(int i = 0; i < parts; i++) { + File file = new File(String.format("%s.c%s", fileBaseName, i)); + this.fileOutputStreams[i] = new FileOutputStream(file); + } + this.writeTo = 0; + this.partSize = 1; + } + + @Override + public Element toElement(Document doc) { + Element element = doc.createElement("Fork"); + element.setTextContent(fileBaseName); + + Attr partSizeAttr = doc.createAttribute("part-size"); + partSizeAttr.setValue(Long.toString(partSize)); + element.setAttributeNode(partSizeAttr); + + Attr partCountAttr = doc.createAttribute("parts"); + partCountAttr.setValue(Long.toString(fileOutputStreams.length)); + element.setAttributeNode(partCountAttr); + + return element; + } + + @Override + public void write(int b) throws IOException { + fileOutputStreams[writeTo].write(b); + writeTo += 1; + if(writeTo >= fileOutputStreams.length) { + writeTo = 0; + partSize += 1; + } + } + + /** + * @return The name of the files without the extension. If it is {@literal example}, the created files will be {@literal example.c1}, {@literal example.c2}, and so on. + */ + public String getFileBaseName() { + return fileBaseName; + } + + /** + * @return The current maximum size of a part, in bytes. + */ + public long getPartSize() { + return partSize; + } + + /** + * @return The number of file parts to create. + */ + public int getParts() { + return fileOutputStreams.length; + } + + /** + * @return The number of the next file where a byte should be written, from 0 to the number of parts -1. + */ + public int getWriteTo() { + return writeTo; + } +} diff --git a/src/eu/steffo/cleaver/logic/stream/output/CleaverSimpleFileOutputStream.java b/src/eu/steffo/cleaver/logic/stream/output/CleaverSimpleFileOutputStream.java new file mode 100644 index 0000000..1794030 --- /dev/null +++ b/src/eu/steffo/cleaver/logic/stream/output/CleaverSimpleFileOutputStream.java @@ -0,0 +1,24 @@ +package eu.steffo.cleaver.logic.stream.output; + +import org.w3c.dom.Document; +import org.w3c.dom.Element; + +import java.io.FileNotFoundException; +import java.io.FileOutputStream; + +public class CleaverSimpleFileOutputStream extends FileOutputStream implements ICleaverOutputStream { + private final String fileBaseName; + + public CleaverSimpleFileOutputStream(String fileBaseName) throws FileNotFoundException { + super(String.format("%s.c0", fileBaseName)); + this.fileBaseName = fileBaseName; + } + + @Override + public Element toElement(Document doc) { + Element element = doc.createElement("Simple"); + element.setTextContent(fileBaseName); + + return element; + } +} diff --git a/src/eu/steffo/cleaver/logic/stream/output/CleaverSplitFileOutputStream.java b/src/eu/steffo/cleaver/logic/stream/output/CleaverSplitFileOutputStream.java index af236b4..5d35357 100644 --- a/src/eu/steffo/cleaver/logic/stream/output/CleaverSplitFileOutputStream.java +++ b/src/eu/steffo/cleaver/logic/stream/output/CleaverSplitFileOutputStream.java @@ -17,7 +17,6 @@ public class CleaverSplitFileOutputStream extends OutputStream implements ICleav private final String fileBaseName; private long currentByteCount; private long maximumByteCount; - private long totalByteCount; private int currentFileCount; /** @@ -60,7 +59,6 @@ public class CleaverSplitFileOutputStream extends OutputStream implements ICleav } currentFileOutputStream.write(b); currentByteCount += 1; - totalByteCount += 1; } @Override @@ -96,13 +94,6 @@ public class CleaverSplitFileOutputStream extends OutputStream implements ICleav return currentFileCount; } - /** - * @return The number of bytes that have already been written. - */ - public long getTotalByteCount() { - return totalByteCount; - } - @Override public Element toElement(Document doc) { Element element = doc.createElement("Split"); @@ -116,10 +107,6 @@ public class CleaverSplitFileOutputStream extends OutputStream implements ICleav partCountAttr.setValue(Long.toString(currentFileCount)); element.setAttributeNode(partCountAttr); - Attr totalSizeAttr = doc.createAttribute("total-size"); - totalSizeAttr.setValue(Long.toString(totalByteCount)); - element.setAttributeNode(totalSizeAttr); - return element; } } diff --git a/src/eu/steffo/cleaver/logic/stream/output/ICleaverOutputStream.java b/src/eu/steffo/cleaver/logic/stream/output/ICleaverOutputStream.java index 1d23a5a..adbad29 100644 --- a/src/eu/steffo/cleaver/logic/stream/output/ICleaverOutputStream.java +++ b/src/eu/steffo/cleaver/logic/stream/output/ICleaverOutputStream.java @@ -11,5 +11,5 @@ public interface ICleaverOutputStream extends ICleaverStream { * @param doc The {@link Document} the {@link Element} should be created in. * @return The created {@link Element}. */ - public Element toElement(Document doc); + Element toElement(Document doc); } diff --git a/src/module-info.java b/src/module-info.java index 3e398ff..7545cfa 100644 --- a/src/module-info.java +++ b/src/module-info.java @@ -13,9 +13,10 @@ open module eu.steffo.cleaver { exports eu.steffo.cleaver.gui.panels; exports eu.steffo.cleaver.gui.panels.rows; exports eu.steffo.cleaver.gui.panels.rows.option; - exports eu.steffo.cleaver.logic; - exports eu.steffo.cleaver.logic.compress; - exports eu.steffo.cleaver.logic.crypt; exports eu.steffo.cleaver.logic.progress; - exports eu.steffo.cleaver.logic.split; + exports eu.steffo.cleaver.logic.config; + exports eu.steffo.cleaver.logic.job; + exports eu.steffo.cleaver.logic.stream; + exports eu.steffo.cleaver.logic.stream.input; + exports eu.steffo.cleaver.logic.stream.output; } \ No newline at end of file