App-zipdetails
view release on metacpan or search on metacpan
bin/zipdetails view on Meta::CPAN
# Auto-generate getter/setter
*$method = sub {
$_[0]->{$name} = $_[1]
if @_ == 2;
return $_[0]->{$name} ;
}
unless defined $done->{$method};
++ $done->{$method};
}
}
}
{
package BaseEntry ;
sub new
{
my $class = shift ;
state $index = 0;
my %fields = (
'index' => $index ++,
'zip64' => 0,
'offsetStart' => 0,
'offsetEnd' => 0,
'inCentralDir' => 0,
'encapsulated' => 0, # enclosed in outer zip
'childrenCount' => 0, # this entry is a zip with enclosed children
'streamed' => 0,
'languageEncodingFlag' => 0,
'entryType' => 0,
) ;
my $self = bless {}, $class;
FieldsAndAccessors::Add($class, $self, \%fields) ;
return $self;
}
sub increment_childrenCount
{
my $self = shift;
$self->{childrenCount} ++;
}
}
{
package LocalCentralEntryBase ;
use parent -norequire , 'BaseEntry' ;
sub new
{
my $class = shift ;
my $self = $class->SUPER::new();
my %fields = (
# fields from the header
'centralHeaderOffset' => 0,
'localHeaderOffset' => 0,
'extractVersion' => 0,
'generalPurposeFlags' => 0,
'compressedMethod' => 0,
'lastModDateTime' => 0,
'crc32' => 0,
'compressedSize' => 0,
'uncompressedSize' => 0,
'filename' => '',
'outputFilename' => '',
# inferred data
# 'InCentralDir' => 0,
# 'zip64' => 0,
'zip64ExtraPresent' => 0,
'zip64SizesPresent' => 0,
'payloadOffset' => 0,
# zip64 extra
'zip64_compressedSize' => undef,
'zip64_uncompressedSize' => undef,
'zip64_localHeaderOffset' => undef,
'zip64_diskNumber' => undef,
'zip64_diskNumberPresent' => 0,
# Values direct from the header before merging any Zip64 values
'std_compressedSize' => undef,
'std_uncompressedSize' => undef,
'std_localHeaderOffset' => undef,
'std_diskNumber' => undef,
# AES
'aesStrength' => 0,
'aesValid' => 0,
# Minizip CD encryption
'minizip_secure' => 0,
) ;
FieldsAndAccessors::Add($class, $self, \%fields) ;
return $self;
}
}
{
package Zip64EndCentralHeaderEntry ;
use parent -norequire , 'LocalCentralEntryBase' ;
sub new
{
my $class = shift ;
my $self = $class->SUPER::new();
my %fields = (
'inCentralDir' => 1,
) ;
FieldsAndAccessors::Add($class, $self, \%fields) ;
return $self;
}
}
{
package CentralDirectoryEntry;
use parent -norequire , 'LocalCentralEntryBase' ;
use constant Offset_VersionMadeBy => 4;
use constant Offset_VersionNeededToExtract => 6;
use constant Offset_GeneralPurposeFlags => 8;
use constant Offset_CompressionMethod => 10;
use constant Offset_ModificationTime => 12;
use constant Offset_ModificationDate => 14;
use constant Offset_CRC32 => 16;
use constant Offset_CompressedSize => 20;
use constant Offset_UncompressedSize => 24;
use constant Offset_FilenameLength => 28;
use constant Offset_ExtraFieldLength => 30;
use constant Offset_FileCommentLength => 32;
use constant Offset_DiskNumber => 34;
use constant Offset_InternalAttributes => 36;
use constant Offset_ExternalAttributes => 38;
use constant Offset_RelativeOffsetToLocal => 42;
use constant Offset_Filename => 46;
sub new
{
my $class = shift ;
my $offset = shift;
# check for existing entry
return $CentralDirectory->{byCentralOffset}{$offset}
if defined $offset && defined $CentralDirectory->{byCentralOffset}{$offset} ;
my $self = $class->SUPER::new();
my %fields = (
'diskNumber' => 0,
'comment' => "",
'ldEntry' => undef,
) ;
FieldsAndAccessors::Add($class, $self, \%fields) ;
$self->inCentralDir(1) ;
$self->entryType(::ZIP_CENTRAL_HDR_SIG) ;
return $self;
}
}
{
package CentralDirectory;
sub new
{
my $class = shift ;
my %object = (
'entries' => [],
'count' => 0,
'byLocalOffset' => {},
'byCentralOffset' => {},
'byName' => {},
'offset2Index' => {},
'normalized_filenames' => {},
'CentralDirectoryOffset' => 0,
'CentralDirectorySize' => 0,
'zip64' => 0,
'encryptedCD' => 0,
'minizip_secure' => 0,
'alreadyScanned' => 0,
) ;
bless \%object, $class;
}
sub addEntry
{
my $self = shift ;
my $entry = shift ;
my $localHeaderOffset = $entry->localHeaderOffset ;
my $CentralDirectoryOffset = $entry->centralHeaderOffset ;
my $filename = $entry->filename ;
Nesting::add($entry);
# Create a reference from Central to Local header entries
my $ldEntry = Nesting::getLdEntryByOffset($localHeaderOffset);
if ($ldEntry)
{
$entry->ldEntry($ldEntry) ;
# LD -> CD
bin/zipdetails view on Meta::CPAN
$self->{minizip_secure} = 1 ;
}
sub isMiniZipEncrypted
{
my $self = shift ;
return $self->{minizip_secure};
}
sub isEncryptedCD
{
my $self = shift ;
return $self->{encryptedCD} && ! $self->{minizip_secure};
}
sub normalize_filename
{
# check if there is a filename that already exists
# with the same name when normalized to lower case
my $self = shift ;
my $entry = shift;
my $filename = shift;
my $nFilename = lc $filename;
my $lookup = $self->{normalized_filenames}{$nFilename};
# if ($lookup && $lookup ne $filename)
if ($lookup)
{
return $lookup,
}
$self->{normalized_filenames}{$nFilename} = $entry;
return undef;
}
}
{
package LocalDirectoryEntry;
use parent -norequire , 'LocalCentralEntryBase' ;
use constant Offset_VersionNeededToExtract => 4;
use constant Offset_GeneralPurposeFlags => 6;
use constant Offset_CompressionMethod => 8;
use constant Offset_ModificationTime => 10;
use constant Offset_ModificationDate => 12;
use constant Offset_CRC32 => 14;
use constant Offset_CompressedSize => 18;
use constant Offset_UncompressedSize => 22;
use constant Offset_FilenameLength => 26;
use constant Offset_ExtraFieldLength => 27;
use constant Offset_Filename => 30;
sub new
{
my $class = shift ;
my $self = $class->SUPER::new();
my %fields = (
'streamedMatch' => 0,
'readDataDescriptor' => 0,
'cdEntryIndex' => {},
'cdEntryList' => [],
) ;
FieldsAndAccessors::Add($class, $self, \%fields) ;
$self->inCentralDir(0) ;
$self->entryType(::ZIP_LOCAL_HDR_SIG) ;
return $self;
}
sub addCdEntry
{
my $self = shift ;
my $entry = shift;
# don't want encapsulated entries
# and protect against duplicates
return
if $entry->encapsulated ||
$self->{cdEntryIndex}{$entry->index} ++ >= 1;
push @{ $self->{cdEntryList} }, $entry ;
}
sub getCdEntry
{
my $self = shift ;
return []
if ! $self->{cdEntryList} ;
return $self->{cdEntryList}[0] ;
}
sub getCdEntries
{
my $self = shift ;
return $self->{cdEntryList} ;
}
}
{
package LocalDirectory;
sub new
{
my $class = shift ;
my %object = (
'entries' => [],
'count' => 0,
'byLocalOffset' => {},
'byName' => {},
'offset2Index' => {},
( run in 1.406 second using v1.01-cache-2.11-cpan-364913b4093 )