// Copyright (c) .NET Foundation and contributors. All rights reserved. Licensed under the Microsoft Reciprocal License. See LICENSE.TXT file in the project root for full license information.
namespace WixToolset.Dtf.Compression.Cab
{
using System;
using System.IO;
using System.Collections.Generic;
///
/// Engine capable of packing and unpacking archives in the cabinet format.
///
public class CabEngine : CompressionEngine
{
private CabPacker packer;
private CabUnpacker unpacker;
///
/// Creates a new instance of the cabinet engine.
///
public CabEngine()
: base()
{
}
///
/// Disposes of resources allocated by the cabinet engine.
///
/// If true, the method has been called directly
/// or indirectly by a user's code, so managed and unmanaged resources
/// will be disposed. If false, the method has been called by the runtime
/// from inside the finalizer, and only unmanaged resources will be
/// disposed.
protected override void Dispose(bool disposing)
{
if (disposing)
{
if (packer != null)
{
packer.Dispose();
packer = null;
}
if (unpacker != null)
{
unpacker.Dispose();
unpacker = null;
}
}
base.Dispose(disposing);
}
private CabPacker Packer
{
get
{
if (this.packer == null)
{
this.packer = new CabPacker(this);
}
return this.packer;
}
}
private CabUnpacker Unpacker
{
get
{
if (this.unpacker == null)
{
this.unpacker = new CabUnpacker(this);
}
return this.unpacker;
}
}
///
/// Creates a cabinet or chain of cabinets.
///
/// A context interface to handle opening
/// and closing of cabinet and file streams.
/// The paths of the files in the archive (not
/// external file paths).
/// The maximum number of bytes for one
/// cabinet before the contents are chained to the next cabinet, or zero
/// for unlimited cabinet size.
/// The cabinet could not be
/// created.
///
/// The stream context implementation may provide a mapping from the
/// file paths within the cabinet to the external file paths.
/// Smaller folder sizes can make it more efficient to extract
/// individual files out of large cabinet packages.
///
public override void Pack(
IPackStreamContext streamContext,
IEnumerable files,
long maxArchiveSize)
{
this.Packer.CompressionLevel = this.CompressionLevel;
this.Packer.UseTempFiles = this.UseTempFiles;
this.Packer.Pack(streamContext, files, maxArchiveSize);
}
///
/// Checks whether a Stream begins with a header that indicates
/// it is a valid cabinet file.
///
/// Stream for reading the cabinet file.
/// True if the stream is a valid cabinet file
/// (with no offset); false otherwise.
public override bool IsArchive(Stream stream)
{
return this.Unpacker.IsArchive(stream);
}
///
/// Gets information about files in a cabinet or cabinet chain.
///
/// A context interface to handle opening
/// and closing of cabinet and file streams.
/// A predicate that can determine
/// which files to process, optional.
/// Information about files in the cabinet stream.
/// The cabinet provided
/// by the stream context is not valid.
///
/// The predicate takes an internal file
/// path and returns true to include the file or false to exclude it.
///
public override IList GetFileInfo(
IUnpackStreamContext streamContext,
Predicate fileFilter)
{
return this.Unpacker.GetFileInfo(streamContext, fileFilter);
}
///
/// Extracts files from a cabinet or cabinet chain.
///
/// A context interface to handle opening
/// and closing of cabinet and file streams.
/// An optional predicate that can determine
/// which files to process.
/// The cabinet provided
/// by the stream context is not valid.
///
/// The predicate takes an internal file
/// path and returns true to include the file or false to exclude it.
///
public override void Unpack(
IUnpackStreamContext streamContext,
Predicate fileFilter)
{
this.Unpacker.Unpack(streamContext, fileFilter);
}
internal void ReportProgress(ArchiveProgressEventArgs e)
{
base.OnProgress(e);
}
}
}