using System; using System.Collections.Generic; using System.Text; using System.IO; namespace DSDecmp.Formats { /// /// Base class for compression formats. /// public abstract class CompressionFormat { /// /// Checks if the decompressor for this format supports the given file. Assumes the /// file exists. Returns false when it is certain that the given file is not supported. /// False positives may occur, as this method should not do any decompression, and /// may mis-interpret a similar file format as compressed. /// /// The name of the file to check. /// False if the file can certainly not be decompressed using this decompressor. /// True if the file may potentially be decompressed using this decompressor. public virtual bool Supports(string file) { // open the file, and delegate to the decompressor-specific code. using (FileStream fstr = new FileStream(file, FileMode.Open)) { return this.Supports(fstr, fstr.Length); } } /// /// Checks if the decompressor for this format supports the data from the given stream. /// Returns false when it is certain that the given data is not supported. /// False positives may occur, as this method should not do any decompression, and may /// mis-interpret a similar data format as compressed. /// /// The stream that may or may not contain compressed data. The /// position of this stream may change during this call, but will be returned to its /// original position when the method returns. /// The length of the input stream. /// False if the data can certainly not be decompressed using this decompressor. /// True if the data may potentially be decompressed using this decompressor. public abstract bool Supports(Stream stream, long inLength); /// /// Decompresses the given file, writing the deocmpressed data to the given output file. /// The output file will be overwritten if it already exists. /// Assumes Supports(infile) returns true. /// /// The file to decompress. /// The target location of the decompressed file. public virtual void Decompress(string infile, string outfile) { // make sure the output directory exists string outDirectory = Path.GetDirectoryName(outfile); if (!Directory.Exists(outDirectory)) Directory.CreateDirectory(outDirectory); // open the two given files, and delegate to the format-specific code. using (FileStream inStream = new FileStream(infile, FileMode.Open), outStream = new FileStream(outfile, FileMode.Create)) { this.Decompress(inStream, inStream.Length, outStream); } } /// /// Decompresses the given stream, writing the decompressed data to the given output stream. /// Assumes Supports(instream) returns true. /// After this call, the input stream will be positioned at the end of the compressed stream, /// or at the initial position + inLength, whichever comes first. /// /// The stream to decompress. At the end of this method, the position /// of this stream is directly after the compressed data. /// The length of the input data. Not necessarily all of the /// input data may be read (if there is padding, for example), however never more than /// this number of bytes is read from the input stream. /// The stream to write the decompressed data to. /// The length of the output data. /// When the given length of the input data /// is not enough to properly decompress the input. public abstract long Decompress(Stream instream, long inLength, Stream outstream); /// /// Compresses the given input file, and writes the compressed data to the given /// output file. /// /// The file to compress. /// The file to write the compressed data to. /// The size of the compressed file. public int Compress(string infile, string outfile) { // make sure the output directory exists string outDirectory = Path.GetDirectoryName(outfile); if (!Directory.Exists(outDirectory)) Directory.CreateDirectory(outDirectory); // open the proper Streams, and delegate to the format-specific code. using (FileStream inStream = File.Open(infile, FileMode.Open), outStream = File.Create(outfile)) { return this.Compress(inStream, inStream.Length, outStream); } } /// /// Compresses the next inLength bytes from the input stream, /// and writes the compressed data to the given output stream. /// /// The stream to read plaintext data from. /// The length of the plaintext data. /// The stream to write the compressed data to. /// The size of the compressed stream. public abstract int Compress(Stream instream, long inLength, Stream outstream); } }