Archive-Zip-SimpleZip

 view release on metacpan or  search on metacpan

lib/Archive/Zip/SimpleUnzip.pm  view on Meta::CPAN

}

sub DESTROY
{
    my $self = shift;
}

sub resetter
{
    my $inner = shift;
    my $member = shift;


    *$inner->{NewStream} = 0 ;
    *$inner->{EndStream} = 0 ;
    *$inner->{TotalInflatedBytesRead} = 0;
    *$inner->{Info}{TrailerLength} = 0;

    # disable streaming if present & set sizes from central dir
    # TODO - this will only allow a single file to be read at a time.
    #        police it or fix it.
    *$inner->{ZipData}{Streaming} = 0;
    *$inner->{ZipData}{Crc32} = $member->{CRC32};
    *$inner->{ZipData}{CompressedLen} = $member->{CompressedLength};
    *$inner->{ZipData}{UnCompressedLen} = $member->{UncompressedLength};
    *$inner->{CompressedInputLengthRemaining} =
            *$inner->{CompressedInputLength} = $member->{CompressedLength};
}

sub _readLocalHeader
{
    my $self = shift;
    my $member = shift;

    my $inner = $self->{Inner};

    resetter($inner, $member);

    my $status = $inner->smartSeek($member->{LocalHeaderOffset}, 0, SEEK_SET);
    $inner->_readFullZipHeader() ;
    $member->{DataOffset} = $inner->smartTell();
}

sub comment
{
    my $self = shift;

    return $self->{Comment} ;
}

sub _mkMember
{
    my $self = shift;
    my $member = shift;

    $self->_readLocalHeader($member);

    my %member ;
    $member{Inner}  = $self->{Inner};
    $member{Info} = $member;
    #Scalar::Util::weaken $member{Inner}; # for 5.8


    return bless \%member, 'Archive::Zip::SimpleUnzip::Member';
}

sub member
{
    my $self = shift;
    my $name = shift;

    return _setError(undef, undef, "Member '$name' not in zip")
        if ! defined $name ;

    my $member = $self->{Members}{$name};

    return _setError(undef, undef, "Member '$name' not in zip")
        if ! defined $member ;

    return $self->_mkMember($member) ;
}

sub open
{
    my $self = shift;
    my $name = shift;

    my $member = $self->{Members}{$name};

    # TODO - get to return unef
    die "Member '$name' not in zip file\n"
        if ! defined $member ;

     $self->_readLocalHeader($member);

#    return $self->{Inner};
    my $z = IO::Compress::Base::Common::createSelfTiedObject("Archive::Zip::SimpleUnzip::Handle", \$SimpleUnzipError) ;

    *$z->{Open} = 1 ;
    *$z->{SZ} = $self->{Inner};
    Scalar::Util::weaken *$z->{SZ}; # for 5.8

    $z;
}

sub extract # to file - return actual path or pass/fail?
{
    my $self = shift;
    my $name = shift;
    my $out  = shift;

    my $member = $self->member($name)
        or return undef ;

    return $member->extract(defined $out ? $out : $name);
}

sub getCanonicalPath
{
    my $self = shift;
    my $name = shift;

    return _canonicalPath($name);
}



sub _isDirectory
{
    my $self = shift;
    my $name = shift ;

    return substr($name, -1, 1) eq '/' &&
        $self->{Info}{UncompressedLength} == 0  ;
}

sub content
{
    my $self = shift;
    my $name = shift;

    my $member = $self->member($name)
        or return undef ;

    return $member->content();
}

sub exists
{
    my $self = shift;
    my $name = shift;

   return exists $self->{Members}{$name};
}

sub names
{
    my $self = shift ;
    return wantarray ? map { $_->{Name} } @{ $self->{CD} } : scalar @{ $self->{CD} } ;
}

lib/Archive/Zip/SimpleUnzip.pm  view on Meta::CPAN

#    getExtra
#    compressedSize - 64 bit alert
#    uncompressedSize
#    time
#    isStored
#    compressionName
#

    sub compressedSize
    {
        my $self = shift;
#        $self->_stdPreq() or return 0 ;

        return $self->{Info}{CompressedLength};
    }

    sub uncompressedSize
    {
        my $self = shift;
#        $self->_stdPreq() or return 0 ;

        return $self->{Info}{UncompressedLength};
    }

    sub content
    {
        my $self = shift;
        my $data ;

        my $inner = $self->{Inner};

        $inner->reset() if $self->{NeedsReset}; $self->{NeedsReset} ++ ;
        Archive::Zip::SimpleUnzip::resetter($inner, $self->{Info});

        $inner->smartSeek($self->{Info}{DataOffset}, 0, SEEK_SET);
        $self->{Inner}->read($data, $self->{Info}{UncompressedLength});

        return $data;
    }

    sub open
    {
        my $self = shift;

#        return  return $self->{Inner} ;

#        my $handle = Symbol::gensym();
#        tie *$handle, "Archive::Zip::SimpleUnzip::Handle", $self->{SZ}{UnZip};
#        return $handle;

        my $z = IO::Compress::Base::Common::createSelfTiedObject("Archive::Zip::SimpleUnzip::Handle", \$SimpleUnzipError) ;

        *$z->{Open} = 1 ;
        *$z->{SZ} = $self->{Inner};

        my $inner = $self->{Inner};
        $inner->reset() if $self->{NeedsReset}; $self->{NeedsReset} ++ ;
        Archive::Zip::SimpleUnzip::resetter($self->{Inner}, $self->{Info});
        $inner->smartSeek($self->{Info}{DataOffset}, 0, SEEK_SET);

        Scalar::Util::weaken *$z->{SZ}; # for 5.8

        $z;
    }

    sub close
    {
        my $self = shift;
        return 1;
    }

    sub comment
    {
        my $self = shift;

        return $self->{Info}{Comment};
    }

    sub _canonicalPath
    {
        my $name = shift ;

        # Not an absolute path
        $name =~ s#^/+## ;

        # Remove trailing slash
        $name =~ s#/+$## ;

        $name =~ s#/+#/#g ;

        # Drop any ".." and "." paths
        # Use of ".." is unsafe
        my @paths = split '/', $name ;
        my @have =  grep { ! m#^\.(\.)?$# } @paths ;

        return @have ;

        $name = join '/', grep { ! m#^\.(\.)?$# } @paths ;

        # use Perl::OSType;
        # my $type = Perl::OSType::os_type();
        # if ( $type eq 'Unix' )
        # {
        # }
        # # TODO Win32
    }

    sub canonicalName
    {
        my $self = shift;

        return join '/', _canonicalPath($self->{Info}{Name});
    }

    sub extract # to file
    {
        my $self = shift;
        my $out  = shift;

        my $path ;
        my $filename ;



( run in 1.997 second using v1.01-cache-2.11-cpan-39bf76dae61 )