#############################################################################
## Name: MyZlibCompress.pm
## Purpose: LibZip::Build::MyZlibCompress
## Author: Graciliano M. P.
## Modified by:
## Created: 2004-06-06
## RCS-ID:
## Copyright: (c) 2004 Graciliano M. P.
## Licence: This program is free software; you can redistribute it and/or
## modify it under the same terms as Perl itself
##
## This module will compress unsing Compress::Zlib and will be able to
## decompress this data with Compress::Zlib::Perl (pure Perl).
##
#############################################################################
package LibZip::Build::MyZlibCompress ;
use 5.006 ;
use strict qw(vars) ;
use vars qw($VERSION) ;
$VERSION = '0.01' ;
use LibZip::CORE ;
use Compress::Zlib ;
use MIME::Base64 qw() ;
use LibZip::MyFile ;
########
# VARS #
########
my $BLK_SIZE = 1024 * 250 ;
my $RE_FIXBIN_OK ;
{
my $qr_ok ;
my @ok = ( 9 , (32..91) , (93..95) , (97..126) , 128 , (130..137) , (139..140) , 142 , (145..156) , (158..159) , (161..172) , (174..255)) ;
foreach my $ok_i ( @ok ) {
my $s = pack("C", $ok_i ) ;
my $re = qr/\Q$s\E/ ;
if ( $re =~ /xism:\\/ ) { $s = "\\" . $s ;}
$qr_ok .= $s ;
}
$RE_FIXBIN_OK = qr/[^$qr_ok]/s ;
}
##########
# MY_TAR #
##########
sub my_tar {
my ( %files ) = @_ ;
my $tar ;
foreach my $file (sort keys %files ) {
my $name = $files{$file} || $file ;
$name =~ s/^[\\\/]+// ;
my $comp = my_compress( cat($file) ) ;
$tar .= pack("V", length($name) ) . $name ;
$tar .= pack("V", length($comp) ) . $comp ;
}
return $tar ;
}
############
# MY_UNTAR #
############
sub my_untar {
my ( $tar_file ) = @_ ;
my $tar = (length($tar_file) < 1024*4 && -e $tar_file) ? cat($tar_file) : $tar_file ;
my $lng = length($tar) ;
my %files ;
my ( $sz , $name ) ;
for(my $i = 0 ; $i < $lng ;) {
$sz = unpack("V", substr($tar , $i , 4) ) ; $i += 4 ;
$name = substr($tar , $i , $sz) ; $i += $sz ;
$sz = unpack("V", substr($tar , $i , 4) ) ; $i += 4 ;
$files{$name} = my_uncompress( split_bloks( substr($tar , $i , $sz) ) ) ; $i += $sz ;
}
return \%files ;
}
################
# MY_SAVE_TREE #
################
sub my_save_tree {
my $dir = shift ;
my $tree = shift ;
LibZip::File::Path::mkpath($dir) if ( !-d $dir );
foreach my $Key (sort keys %$tree ) {
my $name = "$dir/$Key" ;
my ( $volumeName, $dirName, $fileName ) = LibZip::File::Spec->splitpath($name) ;
$dirName = LibZip::File::Spec->catpath( $volumeName, $dirName, '' ) ;
LibZip::File::Path::mkpath($dirName) if ( !-d $dirName ) ;
save($name , $$tree{$Key}) ;
}
}
###############
# MY_COMPRESS #
###############
sub my_compress {
my ( $data ) = @_ ;
my @compressed ;
my $sizes ;
my $lng = length($data) ;
for(my $i = 0 ; $i < $lng ; $i += $BLK_SIZE ) {
my ($d, $status) = deflateInit( -WindowBits => MAX_WBITS ) ;
my $blk = substr($data , $i , $BLK_SIZE) ; ## need to copy first.
$d->deflate($blk) ;
my ($out2, $status2) = $d->flush() ;
push(@compressed , $out2) ;
$sizes .= pack("V", length($out2) ) ;
}
my $size_blk ;
{
my ($d, $status) = deflateInit( -WindowBits => MAX_WBITS ) ;
$d->deflate($sizes) ;
my ($out2, $status2) = $d->flush() ;
$size_blk = pack("V", length($out2) ) . $out2 ;
}
return (join('',$size_blk,@compressed) , @compressed ) if wantarray ;
return join('',$size_blk,@compressed) ;
}
#################
# MY_UNCOMPRESS #
#################
sub my_uncompress {
my ( @blks ) = @_ ;
my $uncompressed ;
foreach my $blks_i ( @blks ) {
my ($d, $status) = inflateInit( -WindowBits => - MAX_WBITS ) ;
my ($out, $status) = $d->inflate($blks_i) ;
$uncompressed .= $out ;
}
return $uncompressed ;
}
###############
# SPLIT_BLOKS #
###############
sub split_bloks {
my $sz_blk_size = unpack("V", substr($_[0] , 0 , 4) ) ;
my $blk_size = substr($_[0] , 4 , $sz_blk_size) ;
my $total = 4 + $sz_blk_size ;
$blk_size = my_uncompress($blk_size) ;
my (@sizes) = ( $blk_size =~ /(....)/gs );
my $i = $sz_blk_size + 4 ;
my @blks ;
foreach my $sizes_i ( @sizes ) {
$sizes_i = unpack("V", $sizes_i ) ;
push(@blks , substr($_[0] , $i , $sizes_i) ) ;
$i += $sizes_i ;
}
return @blks ;
}
##############
# FIX_BINARY #
##############
sub fix_binary {
$_[0] =~ s/($RE_FIXBIN_OK)/ my $n = unpack("C", $1) ; "\n$n\n" /ges ;
return $_[0] ;
}
################
# UNFIX_BINARY #
################
sub unfix_binary {
$_[0] =~ s/\n(\d+)\n/ pack("C", $1) /ges ;
return $_[0] ;
}
#######################
# MY_UNCOMPRESS_SPLIT #
#######################
sub my_uncompress_split { return my_uncompress( split_bloks(@_) ) ;}
#############
# FIXBINARY #
#############
sub my_compress_fixbin { return fix_binary( my_compress($_[0]) ) ;}
sub my_uncompress_fixbin { return my_uncompress( split_bloks( unfix_binary($_[0]) ) ) ;}
sub my_tar_fixbin { return fix_binary( my_tar(@_) ) ;}
sub my_untar_fixbin { return my_untar( unfix_binary($_[0]) ) ;}
##########
# BASE64 #
##########
sub my_compress_base64 { return MIME::Base64::encode_base64( my_compress($_[0]) ) ;}
sub my_uncompress_base64 { return my_uncompress( split_bloks( MIME::Base64::decode_base64($_[0]) ) ) ;}
sub my_tar_base64 { return MIME::Base64::encode_base64( my_tar(@_) ) ;}
sub my_untar_base64 { return my_untar( MIME::Base64::decode_base64($_[0]) ) ;}
#######
# END #
#######
1;