package Win32::Cabinet;

require 5.005_62;
use strict;
use warnings;
use Carp;

require Exporter;
require DynaLoader;

our @ISA = qw(Exporter DynaLoader);

# Items to export into callers namespace by default. Note: do not export
# names by default without a very good reason. Use EXPORT_OK instead.
# Do not simply export all your public functions/methods/constants.

# This allows declaration	use Win32::Cabinet ':all';
# If you do not need this, moving things directly into @EXPORT or @EXPORT_OK
# will save memory.
our %EXPORT_TAGS = ( 'all' => [ qw(
	CB_MAX_CABINET_NAME
	CB_MAX_CAB_PATH
	CB_MAX_CHUNK
	CB_MAX_DISK
	CB_MAX_DISK_NAME
	CB_MAX_FILENAME
	DIAMONDAPI
	FALSE
	FAR
	HUGE
	INCLUDED_FCI
	INCLUDED_TYPES_FCI_FDI
	NULL
	STATIC
	TRUE
	_A_EXEC
	_A_NAME_IS_UTF
	statusCabinet
	statusFile
	statusFolder
	tcompBAD
	tcompLZX_WINDOW_HI
	tcompLZX_WINDOW_LO
	tcompMASK_LZX_WINDOW
	tcompMASK_QUANTUM_LEVEL
	tcompMASK_QUANTUM_MEM
	tcompMASK_RESERVED
	tcompMASK_TYPE
	tcompQUANTUM_LEVEL_HI
	tcompQUANTUM_LEVEL_LO
	tcompQUANTUM_MEM_HI
	tcompQUANTUM_MEM_LO
	tcompSHIFT_LZX_WINDOW
	tcompSHIFT_QUANTUM_LEVEL
	tcompSHIFT_QUANTUM_MEM
	tcompTYPE_LZX
	tcompTYPE_MSZIP
	tcompTYPE_NONE
	tcompTYPE_QUANTUM
) ] );

our @EXPORT_OK = ( @{ $EXPORT_TAGS{'all'} } );

our @EXPORT = qw(
	CB_MAX_CABINET_NAME
	CB_MAX_CAB_PATH
	CB_MAX_CHUNK
	CB_MAX_DISK
	CB_MAX_DISK_NAME
	CB_MAX_FILENAME
	DIAMONDAPI
	FALSE
	FAR
	HUGE
	INCLUDED_FCI
	INCLUDED_TYPES_FCI_FDI
	NULL
	STATIC
	TRUE
	_A_EXEC
	_A_NAME_IS_UTF
	statusCabinet
	statusFile
	statusFolder
	tcompBAD
	tcompLZX_WINDOW_HI
	tcompLZX_WINDOW_LO
	tcompMASK_LZX_WINDOW
	tcompMASK_QUANTUM_LEVEL
	tcompMASK_QUANTUM_MEM
	tcompMASK_RESERVED
	tcompMASK_TYPE
	tcompQUANTUM_LEVEL_HI
	tcompQUANTUM_LEVEL_LO
	tcompQUANTUM_MEM_HI
	tcompQUANTUM_MEM_LO
	tcompSHIFT_LZX_WINDOW
	tcompSHIFT_QUANTUM_LEVEL
	tcompSHIFT_QUANTUM_MEM
	tcompTYPE_LZX
	tcompTYPE_MSZIP
	tcompTYPE_NONE
	tcompTYPE_QUANTUM
);
our $VERSION = '0.01';

sub AUTOLOAD {
    # This AUTOLOAD is used to 'autoload' constants from the constant()
    # XS function.  If a constant is not found then control is passed
    # to the AUTOLOAD in AutoLoader.

    my $constname;
    our $AUTOLOAD;
    ($constname = $AUTOLOAD) =~ s/.*:://;
    croak "& not defined" if $constname eq 'constant';
    my $val = constant($constname, @_ ? $_[0] : 0);
    if ($! != 0) {
	if ($! =~ /Invalid/ || $!{EINVAL}) {
	    $AutoLoader::AUTOLOAD = $AUTOLOAD;
	    goto &AutoLoader::AUTOLOAD;
	}
	else {
	    croak "Your vendor has not defined Win32::Cabinet macro $constname";
	}
    }
    {
	no strict 'refs';
	# Fixed between 5.005_53 and 5.005_61
	if ($] >= 5.00561) {
	    *$AUTOLOAD = sub () { $val };
	}
	else {
	    *$AUTOLOAD = sub { $val };
	}
    }
    goto &$AUTOLOAD;
}

bootstrap Win32::Cabinet $VERSION;

1;
__END__

=head1 NAME

Win32::Cabinet - Perl extension for creating and extracting cabinet archives

=head1 SYNOPSIS

    use Win32::Cabinet;

    # Creating cabinet files
    my $cab = Win32::Cabinet->new();
    $cab->Create('Foo', 'Foo.cab', '../');
    $cab->AddFile("$dir/$file", $file, 0);
    $cab->Write();

    # Extracting Cabinet files
    $cab = Win32::Cabinet->new();
    $cab->Open();
    $cab->Extract('Komodo-0.1.1.101.cab', '../');

=head1 DESCRIPTION

This module provides the functionality to create and extract the contents
of Micrsoft cabinet archives.

=head1 METHODS

=head2 Win32::Cabinet->new()

Create a new Win32::Cabinet object. Returns a Win32::Cabinet object.

=head2 $cab->Create($disk, $file_name, $dir_name)

Create a new cabinet file. $disk is the name of the disk the cabinet archive
will reside on. Currently this parameter is not really used but must be set
to something. $file_name is the file name of the cabinet archive on disk.
$dir_name is the name of the directory in which the cabinet archive will be
created. Returns 1 if successful and 0 otherwise.

=head2 $cab->AddFile($src, $target, 0)

Add a file to the cabinet archive. $src is the full pathname of the file on
disk to be added to the cabinet archive. $target is the name of the file within
the cabinet archive. Cabinet files have no support for internal directory
structures that mirror directory structures in the file system. For this reason
every file within a cabinet archive must have a unique name. Using an MD5 hash
of the source file name, including the directory part, works well for creating
unique file names within the cabinet. Returns 1 if successful and 0 otherwise.

=head2 $cab->Write()

Flush the cabinet archive to disk.  Returns 1 if successful and 0 otherwise.

=head2 $cab->Open()

Open an existing cabinet file for reading. Returns 1 if successful and 0
otherwise.

=head2 $cab->Extract($file_name, $dir_name)

Extract all of the files from a cabinet archive. $file_name is the file name of
the cabinet archive. $dir_name is the name of the directory into which files
will be extracted. Returns 1 if successful and 0 otherwise.

=head1 TODO

=item *

Support setting cabinet file creation parameters:

=over 4

=item cb

The cb field, the media size, specifies the maximum size of a cabinet which
will be created by FCI.  If necessary, multiple cabinets will be created.  To
ensure that only one cabinet is created, a sufficiently large number should be
used for this parameter.

=item cbFolderThresh

The cbFolderThresh field specifies the maximum number of compressed bytes which
may reside in a folder before a new folder is created.  A higher folder
threshold improves compression performance (since creating a new folder resets
the compression history), but increases random access time to the folder.

=back

=head1 SEE ALSO

L<MD5>, L<perl>

=head1 COPYRIGHT

Copyright (c) 2000 ActiveState Corp. All rights reserved.

=cut
