2011-03-21 20:18:07 +01:00
|
|
|
|
using System;
|
|
|
|
|
using System.Collections.Generic;
|
|
|
|
|
using System.Text;
|
|
|
|
|
using System.IO;
|
|
|
|
|
|
|
|
|
|
namespace DSDecmp.Formats
|
|
|
|
|
{
|
|
|
|
|
/// <summary>
|
|
|
|
|
/// Base class for compression formats.
|
|
|
|
|
/// </summary>
|
|
|
|
|
public abstract class CompressionFormat
|
|
|
|
|
{
|
|
|
|
|
/// <summary>
|
|
|
|
|
/// 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.
|
|
|
|
|
/// </summary>
|
|
|
|
|
/// <param name="file">The name of the file to check.</param>
|
|
|
|
|
/// <returns>False if the file can certainly not be decompressed using this decompressor.
|
|
|
|
|
/// True if the file may potentially be decompressed using this decompressor.</returns>
|
|
|
|
|
public 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);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/// <summary>
|
|
|
|
|
/// 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.
|
|
|
|
|
/// </summary>
|
|
|
|
|
/// <param name="stream">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.</param>
|
|
|
|
|
/// <returns>False if the data can certainly not be decompressed using this decompressor.
|
|
|
|
|
/// True if the data may potentially be decompressed using this decompressor.</returns>
|
|
|
|
|
public abstract bool Supports(Stream stream);
|
|
|
|
|
|
|
|
|
|
/// <summary>
|
|
|
|
|
/// Decompresses the given file, writing the deocmpressed data to the given output file.
|
|
|
|
|
/// The output file will be overwritten if it already exists.
|
|
|
|
|
/// Assumes <code>Supports(infile)</code> returns <code>true</code>.
|
|
|
|
|
/// </summary>
|
|
|
|
|
/// <param name="infile">The file to decompress.</param>
|
|
|
|
|
/// <param name="outfile">The target location of the decompressed file.</param>
|
|
|
|
|
public void Decompress(string infile, string outfile)
|
|
|
|
|
{
|
2011-04-05 18:41:43 +02:00
|
|
|
|
// make sure the output directory exists
|
|
|
|
|
string outDirectory = Path.GetDirectoryName(outfile);
|
|
|
|
|
if (!Directory.Exists(outDirectory))
|
|
|
|
|
Directory.CreateDirectory(outDirectory);
|
2011-03-21 20:18:07 +01:00
|
|
|
|
// 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);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/// <summary>
|
|
|
|
|
/// Decompresses the given stream, writing the decompressed data to the given output stream.
|
|
|
|
|
/// Assumes <code>Supports(instream)</code> returns <code>true</code>.
|
|
|
|
|
/// After this call, the input stream will be positioned at the end of the compressed stream,
|
|
|
|
|
/// or at the initial position + <code>inLength</code>, whichever comes first.
|
|
|
|
|
/// </summary>
|
|
|
|
|
/// <param name="instream">The stream to decompress. At the end of this method, the position
|
|
|
|
|
/// of this stream is directly after the compressed data.</param>
|
|
|
|
|
/// <param name="inLength">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.</param>
|
|
|
|
|
/// <param name="outstream">The stream to write the decompressed data to.</param>
|
|
|
|
|
/// <exception cref="NotEnoughDataException">When the given length of the input data
|
|
|
|
|
/// is not enough to properly decompress the input.</exception>
|
|
|
|
|
public abstract void Decompress(Stream instream, long inLength, Stream outstream);
|
|
|
|
|
|
|
|
|
|
/// <summary>
|
|
|
|
|
/// Compresses the given input file, and writes the compressed data to the given
|
|
|
|
|
/// output file.
|
|
|
|
|
/// </summary>
|
|
|
|
|
/// <param name="infile">The file to compress.</param>
|
|
|
|
|
/// <param name="outfile">The file to write the compressed data to.</param>
|
2011-04-04 15:07:07 +02:00
|
|
|
|
/// <returns>The size of the compressed file.</returns>
|
|
|
|
|
public int Compress(string infile, string outfile)
|
2011-03-21 20:18:07 +01:00
|
|
|
|
{
|
2011-04-05 18:41:43 +02:00
|
|
|
|
// make sure the output directory exists
|
|
|
|
|
string outDirectory = Path.GetDirectoryName(outfile);
|
|
|
|
|
if (!Directory.Exists(outDirectory))
|
|
|
|
|
Directory.CreateDirectory(outDirectory);
|
2011-03-21 20:18:07 +01:00
|
|
|
|
// open the proper Streams, and delegate to the format-specific code.
|
|
|
|
|
using (FileStream inStream = File.Open(infile, FileMode.Open),
|
|
|
|
|
outStream = File.Create(outfile))
|
|
|
|
|
{
|
2011-04-04 15:07:07 +02:00
|
|
|
|
return this.Compress(inStream, inStream.Length, outStream);
|
2011-03-21 20:18:07 +01:00
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/// <summary>
|
|
|
|
|
/// Compresses the next <code>inLength</code> bytes from the input stream,
|
|
|
|
|
/// and writes the compressed data to the given output stream.
|
|
|
|
|
/// </summary>
|
|
|
|
|
/// <param name="instream">The stream to read plaintext data from.</param>
|
|
|
|
|
/// <param name="inLength">The length of the plaintext data.</param>
|
|
|
|
|
/// <param name="outstream">The stream to write the compressed data to.</param>
|
2011-04-04 15:07:07 +02:00
|
|
|
|
/// <returns>The size of the compressed stream.</returns>
|
|
|
|
|
public abstract int Compress(Stream instream, long inLength, Stream outstream);
|
2011-03-21 20:18:07 +01:00
|
|
|
|
}
|
|
|
|
|
}
|