You've already forked pgbackrest
mirror of
https://github.com/pgbackrest/pgbackrest.git
synced 2025-09-16 09:06:18 +02:00
ZLib stuff starting to look good. All references removed from File and using binary_xfer for all de/compression.
This commit is contained in:
@@ -15,9 +15,6 @@ use File::Path qw(make_path remove_tree);
|
|||||||
use Digest::SHA;
|
use Digest::SHA;
|
||||||
use File::stat;
|
use File::stat;
|
||||||
use Fcntl ':mode';
|
use Fcntl ':mode';
|
||||||
use IO::Compress::Gzip qw(gzip $GzipError);
|
|
||||||
use IO::Uncompress::Gunzip qw(gunzip $GunzipError);
|
|
||||||
use IO::String;
|
|
||||||
|
|
||||||
use lib dirname($0) . '/../lib';
|
use lib dirname($0) . '/../lib';
|
||||||
use BackRest::Exception;
|
use BackRest::Exception;
|
||||||
@@ -130,6 +127,11 @@ sub new
|
|||||||
$self->{oRemote} = $oRemote;
|
$self->{oRemote} = $oRemote;
|
||||||
$self->{iThreadIdx} = $iThreadIdx;
|
$self->{iThreadIdx} = $iThreadIdx;
|
||||||
|
|
||||||
|
if (!defined($self->{strRemote}) || $self->{strRemote} eq NONE)
|
||||||
|
{
|
||||||
|
$self->{oRemote} = new BackRest::Remote();
|
||||||
|
}
|
||||||
|
|
||||||
# If remote is defined check parameters and open session
|
# If remote is defined check parameters and open session
|
||||||
if (defined($self->{strRemote}) && $self->{strRemote} ne NONE)
|
if (defined($self->{strRemote}) && $self->{strRemote} ne NONE)
|
||||||
{
|
{
|
||||||
@@ -523,25 +525,8 @@ sub compress
|
|||||||
# Run locally
|
# Run locally
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
# Compress the file
|
# Use copy to compress the file
|
||||||
if (!gzip($strPathOp => "${strPathOp}.gz"))
|
$self->copy($strPathType, $strFile, $strPathType, "${strFile}.gz", false, true);
|
||||||
{
|
|
||||||
my $strError = "${strPathOp} could not be compressed:" . $!;
|
|
||||||
my $iErrorCode = COMMAND_ERR_FILE_READ;
|
|
||||||
|
|
||||||
if (!$self->exists($strPathType, $strFile))
|
|
||||||
{
|
|
||||||
$strError = "${strPathOp} does not exist";
|
|
||||||
$iErrorCode = COMMAND_ERR_FILE_MISSING;
|
|
||||||
}
|
|
||||||
|
|
||||||
if ($strPathType eq PATH_ABSOLUTE)
|
|
||||||
{
|
|
||||||
confess &log(ERROR, $strError, $iErrorCode);
|
|
||||||
}
|
|
||||||
|
|
||||||
confess &log(ERROR, "${strDebug}: " . $strError);
|
|
||||||
}
|
|
||||||
|
|
||||||
# Remove the old file
|
# Remove the old file
|
||||||
unlink($strPathOp)
|
unlink($strPathOp)
|
||||||
@@ -821,53 +806,8 @@ sub hash_size
|
|||||||
|
|
||||||
if ($bCompressed)
|
if ($bCompressed)
|
||||||
{
|
{
|
||||||
my $bFirst = true;
|
($strHash, $iSize) =
|
||||||
my $tCompressedBuffer;
|
$self->{oRemote}->binary_xfer($hFile, undef, 'in', undef, false, false);
|
||||||
my $tUncompressedBuffer;
|
|
||||||
my $iBlockSize;
|
|
||||||
my $iBlockIn;
|
|
||||||
my $oGzip;
|
|
||||||
|
|
||||||
do
|
|
||||||
{
|
|
||||||
# Read a block from the file
|
|
||||||
$iBlockSize = sysread($hFile, $tCompressedBuffer, 4194304,
|
|
||||||
defined($tCompressedBuffer) ? length($tCompressedBuffer) : 0);
|
|
||||||
|
|
||||||
if (!defined($iBlockSize))
|
|
||||||
{
|
|
||||||
confess &log(ERROR, "${strFileOp} could not be read: " . $!);
|
|
||||||
}
|
|
||||||
|
|
||||||
# If this is the first block then initialize Gunzip
|
|
||||||
if ($bFirst)
|
|
||||||
{
|
|
||||||
# Initialize Gunzip
|
|
||||||
$oGzip = new IO::Uncompress::Gunzip(\$tCompressedBuffer, Transparent => 0, BlockSize => 4194304)
|
|
||||||
or confess "IO::Uncompress::Gunzip failed: $GunzipError";
|
|
||||||
|
|
||||||
# Clear first block flag
|
|
||||||
$bFirst = false;
|
|
||||||
}
|
|
||||||
|
|
||||||
# Loop while there is more data to uncompress
|
|
||||||
while (!$oGzip->eof())
|
|
||||||
{
|
|
||||||
# Decompress the block
|
|
||||||
$iBlockIn = $oGzip->read($tUncompressedBuffer);
|
|
||||||
|
|
||||||
if ($iBlockIn < 0)
|
|
||||||
{
|
|
||||||
confess &log(ERROR, "unable to decompress stream ($iBlockIn): ${GunzipError}");
|
|
||||||
}
|
|
||||||
|
|
||||||
$iSize += length($tUncompressedBuffer);
|
|
||||||
$oSHA->add($tUncompressedBuffer);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
while ($iBlockSize > 0);
|
|
||||||
|
|
||||||
$oGzip->close();
|
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
@@ -888,11 +828,11 @@ sub hash_size
|
|||||||
$oSHA->add($tBuffer);
|
$oSHA->add($tBuffer);
|
||||||
}
|
}
|
||||||
while ($iBlockSize > 0);
|
while ($iBlockSize > 0);
|
||||||
|
|
||||||
|
$strHash = $oSHA->hexdigest();
|
||||||
}
|
}
|
||||||
|
|
||||||
close($hFile);
|
close($hFile);
|
||||||
|
|
||||||
$strHash = $oSHA->hexdigest();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return $strHash, $iSize;
|
return $strHash, $iSize;
|
||||||
@@ -1596,13 +1536,21 @@ sub copy
|
|||||||
{
|
{
|
||||||
my @stryToken = split(/ /, $strOutput);
|
my @stryToken = split(/ /, $strOutput);
|
||||||
|
|
||||||
if ($bDestinationRemote && ($stryToken[1] eq '?' || $stryToken[1] eq '?'))
|
if ($bDestinationRemote && ($stryToken[1] eq '?' || $stryToken[2] eq '?'))
|
||||||
{
|
{
|
||||||
confess &log(ERROR, "checksum/size should have been returned from remote: ${strOutput}");
|
confess &log(ERROR, "checksum/size should have been returned from remote: ${strOutput}");
|
||||||
}
|
}
|
||||||
|
|
||||||
$strChecksum = $stryToken[1];
|
if ($stryToken[1] ne '?')
|
||||||
$iFileSize = $stryToken[2];
|
{
|
||||||
|
$strChecksum = $stryToken[1];
|
||||||
|
$iFileSize = $stryToken[2];
|
||||||
|
}
|
||||||
|
|
||||||
|
if ($stryToken[2] ne '?')
|
||||||
|
{
|
||||||
|
$iFileSize = $stryToken[2];
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
@@ -1637,14 +1585,16 @@ sub copy
|
|||||||
# If the source is compressed and the destination is not then decompress
|
# If the source is compressed and the destination is not then decompress
|
||||||
if ($bSourceCompressed && !$bDestinationCompress)
|
if ($bSourceCompressed && !$bDestinationCompress)
|
||||||
{
|
{
|
||||||
gunzip($hSourceFile => $hDestinationFile)
|
($strChecksum, $iFileSize) =
|
||||||
or die confess &log(ERROR, "${strDebug}: unable to uncompress: " . $GunzipError);
|
$self->{oRemote}->binary_xfer($hSourceFile, $hDestinationFile, 'in', undef, false, false);
|
||||||
}
|
}
|
||||||
|
# If the source is not compressed and the destination is then compress
|
||||||
elsif (!$bSourceCompressed && $bDestinationCompress)
|
elsif (!$bSourceCompressed && $bDestinationCompress)
|
||||||
{
|
{
|
||||||
gzip($hSourceFile => $hDestinationFile)
|
($strChecksum, $iFileSize) =
|
||||||
or die confess &log(ERROR, "${strDebug}: unable to compress: " . $GzipError);
|
$self->{oRemote}->binary_xfer($hSourceFile, $hDestinationFile, 'out', false, undef, false);
|
||||||
}
|
}
|
||||||
|
# Else straight copy
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
cp($hSourceFile, $hDestinationFile)
|
cp($hSourceFile, $hDestinationFile)
|
||||||
@@ -1690,8 +1640,11 @@ sub copy
|
|||||||
# Move the file from tmp to final destination
|
# Move the file from tmp to final destination
|
||||||
$self->move(PATH_ABSOLUTE, $strDestinationTmpOp, PATH_ABSOLUTE, $strDestinationOp, true);
|
$self->move(PATH_ABSOLUTE, $strDestinationTmpOp, PATH_ABSOLUTE, $strDestinationOp, true);
|
||||||
|
|
||||||
# Get the checksum and size
|
# Get the checksum and size if they are not already set
|
||||||
($strChecksum, $iFileSize) = $self->hash_size(PATH_ABSOLUTE, $strDestinationOp, $bDestinationCompress);
|
if (!defined($strChecksum) || !defined($iFileSize))
|
||||||
|
{
|
||||||
|
($strChecksum, $iFileSize) = $self->hash_size(PATH_ABSOLUTE, $strDestinationOp, $bDestinationCompress);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return $bResult, $strChecksum, $iFileSize;
|
return $bResult, $strChecksum, $iFileSize;
|
||||||
|
@@ -15,6 +15,7 @@ use POSIX ':sys_wait_h';
|
|||||||
use Scalar::Util 'blessed';
|
use Scalar::Util 'blessed';
|
||||||
use IO::Compress::Gzip qw($GzipError);
|
use IO::Compress::Gzip qw($GzipError);
|
||||||
use IO::Uncompress::Gunzip qw($GunzipError);
|
use IO::Uncompress::Gunzip qw($GunzipError);
|
||||||
|
use Compress::Raw::Zlib;
|
||||||
|
|
||||||
use lib dirname($0) . '/../lib';
|
use lib dirname($0) . '/../lib';
|
||||||
use BackRest::Exception;
|
use BackRest::Exception;
|
||||||
@@ -357,50 +358,61 @@ sub block_read
|
|||||||
my $self = shift;
|
my $self = shift;
|
||||||
my $hIn = shift;
|
my $hIn = shift;
|
||||||
my $strBlockRef = shift;
|
my $strBlockRef = shift;
|
||||||
|
my $bProtocol = shift;
|
||||||
|
|
||||||
# Read the block header and make sure it's valid
|
my $iBlockSize;
|
||||||
my $strBlockHeader = $self->read_line($hIn);
|
|
||||||
|
|
||||||
if ($strBlockHeader !~ /^block -{0,1}[0-9]+$/)
|
if ($bProtocol)
|
||||||
{
|
{
|
||||||
$self->wait_pid();
|
# Read the block header and make sure it's valid
|
||||||
confess "unable to read block header ${strBlockHeader}";
|
my $strBlockHeader = $self->read_line($hIn);
|
||||||
}
|
|
||||||
|
|
||||||
# Get block size from the header
|
if ($strBlockHeader !~ /^block -{0,1}[0-9]+$/)
|
||||||
my $iBlockSize = trim(substr($strBlockHeader, index($strBlockHeader, ' ') + 1));
|
{
|
||||||
|
$self->wait_pid();
|
||||||
|
confess "unable to read block header ${strBlockHeader}";
|
||||||
|
}
|
||||||
|
|
||||||
# If block size is 0 or an error code then undef the buffer
|
# Get block size from the header
|
||||||
if ($iBlockSize <= 0)
|
$iBlockSize = trim(substr($strBlockHeader, index($strBlockHeader, ' ') + 1));
|
||||||
{
|
|
||||||
undef($$strBlockRef);
|
# If block size is 0 or an error code then undef the buffer
|
||||||
|
if ($iBlockSize <= 0)
|
||||||
|
{
|
||||||
|
undef($$strBlockRef);
|
||||||
|
}
|
||||||
|
# Else read the block
|
||||||
|
else
|
||||||
|
{
|
||||||
|
my $iBlockRead = 0;
|
||||||
|
my $iBlockIn = 0;
|
||||||
|
my $iOffset = defined($$strBlockRef) ? length($$strBlockRef) : 0;
|
||||||
|
|
||||||
|
# !!! Would be nice to modify this with a non-blocking read
|
||||||
|
# http://docstore.mik.ua/orelly/perl/cookbook/ch07_15.htm
|
||||||
|
|
||||||
|
# Read as many chunks as it takes to get the full block
|
||||||
|
while ($iBlockRead != $iBlockSize)
|
||||||
|
{
|
||||||
|
$iBlockIn = sysread($hIn, $$strBlockRef, $iBlockSize - $iBlockRead, $iBlockRead + $iOffset);
|
||||||
|
|
||||||
|
if (!defined($iBlockIn))
|
||||||
|
{
|
||||||
|
my $strError = $!;
|
||||||
|
|
||||||
|
$self->wait_pid();
|
||||||
|
confess "only read ${iBlockRead}/${iBlockSize} block bytes from remote" .
|
||||||
|
(defined($strError) ? ": ${strError}" : '');
|
||||||
|
}
|
||||||
|
|
||||||
|
$iBlockRead += $iBlockIn;
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
# Else read the block
|
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
my $iBlockRead = 0;
|
$iBlockSize = $self->stream_read($hIn, $strBlockRef, $self->{iBlockSize},
|
||||||
my $iBlockIn = 0;
|
defined($$strBlockRef) ? length($$strBlockRef) : 0);
|
||||||
my $iOffset = defined($$strBlockRef) ? length($$strBlockRef) : 0;
|
|
||||||
|
|
||||||
# !!! Would be nice to modify this with a non-blocking read
|
|
||||||
# http://docstore.mik.ua/orelly/perl/cookbook/ch07_15.htm
|
|
||||||
|
|
||||||
# Read as many chunks as it takes to get the full block
|
|
||||||
while ($iBlockRead != $iBlockSize)
|
|
||||||
{
|
|
||||||
$iBlockIn = sysread($hIn, $$strBlockRef, $iBlockSize - $iBlockRead, $iBlockRead + $iOffset);
|
|
||||||
|
|
||||||
if (!defined($iBlockIn))
|
|
||||||
{
|
|
||||||
my $strError = $!;
|
|
||||||
|
|
||||||
$self->wait_pid();
|
|
||||||
confess "only read ${iBlockRead}/${iBlockSize} block bytes from remote" .
|
|
||||||
(defined($strError) ? ": ${strError}" : '');
|
|
||||||
}
|
|
||||||
|
|
||||||
$iBlockRead += $iBlockIn;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
# Return the block size
|
# Return the block size
|
||||||
@@ -418,13 +430,16 @@ sub block_write
|
|||||||
my $hOut = shift;
|
my $hOut = shift;
|
||||||
my $tBlockRef = shift;
|
my $tBlockRef = shift;
|
||||||
my $iBlockSize = shift;
|
my $iBlockSize = shift;
|
||||||
|
my $bProtocol = shift;
|
||||||
|
|
||||||
# If block size is not defined, get it from buffer length
|
# If block size is not defined, get it from buffer length
|
||||||
$iBlockSize = defined($iBlockSize) ? $iBlockSize : length($$tBlockRef);
|
$iBlockSize = defined($iBlockSize) ? $iBlockSize : length($$tBlockRef);
|
||||||
|
|
||||||
# Write block header to the protocol stream
|
# Write block header to the protocol stream
|
||||||
$self->write_line($hOut, "block ${iBlockSize}");
|
if ($bProtocol)
|
||||||
# &log(INFO, "block ${iBlockSize}");
|
{
|
||||||
|
$self->write_line($hOut, "block ${iBlockSize}");
|
||||||
|
}
|
||||||
|
|
||||||
# Write block if size > 0
|
# Write block if size > 0
|
||||||
if ($iBlockSize > 0)
|
if ($iBlockSize > 0)
|
||||||
@@ -500,6 +515,13 @@ sub binary_xfer
|
|||||||
my $strRemote = shift;
|
my $strRemote = shift;
|
||||||
my $bSourceCompressed = shift;
|
my $bSourceCompressed = shift;
|
||||||
my $bDestinationCompress = shift;
|
my $bDestinationCompress = shift;
|
||||||
|
my $bProtocol = shift;
|
||||||
|
|
||||||
|
# The input stream must be defined (output is optional)
|
||||||
|
if (!defined($hIn))
|
||||||
|
{
|
||||||
|
confess &log(ASSERT, 'hIn is not defined');
|
||||||
|
}
|
||||||
|
|
||||||
# If no remote is defined then set to none
|
# If no remote is defined then set to none
|
||||||
if (!defined($strRemote))
|
if (!defined($strRemote))
|
||||||
@@ -513,27 +535,23 @@ sub binary_xfer
|
|||||||
$bDestinationCompress = defined($bDestinationCompress) ? $bDestinationCompress : false;
|
$bDestinationCompress = defined($bDestinationCompress) ? $bDestinationCompress : false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
# Default protocol to true
|
||||||
|
$bProtocol = defined($bProtocol) ? $bProtocol : true;
|
||||||
|
|
||||||
# Working variables
|
# Working variables
|
||||||
my $iBlockSize = $self->{iBlockSize};
|
my $iBlockSize = $self->{iBlockSize};
|
||||||
my $iBlockIn;
|
my $iBlockIn;
|
||||||
my $iBlockInTotal = $iBlockSize;
|
|
||||||
my $iBlockBufferIn;
|
my $iBlockBufferIn;
|
||||||
my $iBlockOut;
|
|
||||||
my $iBlockTotal = 0;
|
|
||||||
my $strBlockHeader;
|
|
||||||
my $strBlock;
|
my $strBlock;
|
||||||
my $strBlockBuffer;
|
my $strBlockBuffer;
|
||||||
my $oGzip = undef;
|
|
||||||
my $oSHA = undef;
|
|
||||||
my $iFileSize = undef;
|
my $iFileSize = undef;
|
||||||
|
|
||||||
my $bFirst = true;
|
my $oGzip = undef;
|
||||||
|
my $oZLib = undef;
|
||||||
|
my $iZLibStatus;
|
||||||
|
my $oSHA = undef;
|
||||||
|
|
||||||
# Both the in and out streams must be defined
|
my $bFirst = true;
|
||||||
if (!defined($hIn) || !defined($hOut))
|
|
||||||
{
|
|
||||||
confess &log(ASSERT, 'hIn or hOut is not defined');
|
|
||||||
}
|
|
||||||
|
|
||||||
while (1)
|
while (1)
|
||||||
{
|
{
|
||||||
@@ -544,9 +562,9 @@ sub binary_xfer
|
|||||||
if (!$bDestinationCompress)
|
if (!$bDestinationCompress)
|
||||||
{
|
{
|
||||||
# Read a block from the protocol stream
|
# Read a block from the protocol stream
|
||||||
$iBlockSize = $self->block_read($hIn, \$strBlockBuffer);
|
$iBlockSize = $self->block_read($hIn, \$strBlockBuffer, $bProtocol);
|
||||||
|
|
||||||
# If block size = -1 it means an error happened on the remote we need to exit so it can be returned.
|
# If block size = -1 it means an error happened on the remote and we need to exit so it can be returned.
|
||||||
if ($iBlockSize == -1)
|
if ($iBlockSize == -1)
|
||||||
{
|
{
|
||||||
last;
|
last;
|
||||||
@@ -558,22 +576,30 @@ sub binary_xfer
|
|||||||
$oSHA = Digest::SHA->new('sha1');
|
$oSHA = Digest::SHA->new('sha1');
|
||||||
$iFileSize = 0;
|
$iFileSize = 0;
|
||||||
|
|
||||||
if ($iBlockSize == 0)
|
# if ($iBlockSize == 0)
|
||||||
{
|
# {
|
||||||
&log(ASSERT, 'first protocol block is zero');
|
# &log(ASSERT, 'first protocol block is zero');
|
||||||
}
|
# }
|
||||||
|
#
|
||||||
# Gunzip doesn't like to be initialized with just the header, so if the first block is 10 bytes then fetch
|
# # Gunzip doesn't like to be initialized with just the header, so if the first block is 10 bytes then fetch
|
||||||
# another another block to make sure so is at least some payload.
|
# # another another block to make sure so is at least some payload.
|
||||||
if ($iBlockSize <= 10)
|
# if ($iBlockSize <= 10)
|
||||||
{
|
# {
|
||||||
$iBlockSize = $self->block_read($hIn, \$strBlockBuffer);
|
# $iBlockSize = $self->block_read($hIn, \$strBlockBuffer, $bProtocol);
|
||||||
}
|
# }
|
||||||
|
|
||||||
# Initialize Gunzip
|
# Initialize Gunzip
|
||||||
$oGzip = new IO::Uncompress::Gunzip(\$strBlockBuffer, Append => 1, Transparent => 0,
|
($oZLib, $iZLibStatus) = new Compress::Raw::Zlib::Inflate(LimitOutput => 1, -WindowBits => WANT_GZIP,
|
||||||
BlockSize => $self->{iBlockSize})
|
-Bufsize => $self->{iBlockSize});
|
||||||
or confess "IO::Uncompress::Gunzip failed (${iBlockSize}): $GunzipError";
|
|
||||||
|
if ($iZLibStatus != Z_OK)
|
||||||
|
{
|
||||||
|
confess &log(ERROR, "unable create a inflation stream: ${iZLibStatus}");
|
||||||
|
}
|
||||||
|
|
||||||
|
# $oGzip = new IO::Uncompress::Gunzip(\$strBlockBuffer, Append => 1, Transparent => 0,
|
||||||
|
# BlockSize => $self->{iBlockSize})
|
||||||
|
# or confess "IO::Uncompress::Gunzip failed (${iBlockSize}): $GunzipError";
|
||||||
|
|
||||||
# Clear first block flag
|
# Clear first block flag
|
||||||
$bFirst = false;
|
$bFirst = false;
|
||||||
@@ -582,36 +608,67 @@ sub binary_xfer
|
|||||||
# If the block contains data, decompress it
|
# If the block contains data, decompress it
|
||||||
if ($iBlockSize > 0)
|
if ($iBlockSize > 0)
|
||||||
{
|
{
|
||||||
my $iUncompressedTotal = 0;
|
# my $iUncompressedTotal = 0;
|
||||||
|
|
||||||
# Loop while there is more data to uncompress
|
# # Loop while there is more data to uncompress
|
||||||
while (!$oGzip->eof())
|
# while (!$oGzip->eof())
|
||||||
|
# {
|
||||||
|
# # Decompress the block
|
||||||
|
# $iBlockIn = $oGzip->read($strBlock);
|
||||||
|
#
|
||||||
|
# if ($iBlockIn < 0)
|
||||||
|
# {
|
||||||
|
# confess &log(ERROR, "unable to decompress stream ($iBlockIn): ${GunzipError}");
|
||||||
|
# }
|
||||||
|
#
|
||||||
|
# $iUncompressedTotal += $iBlockIn;
|
||||||
|
# }
|
||||||
|
|
||||||
|
do
|
||||||
{
|
{
|
||||||
# Decompress the block
|
$iZLibStatus = $oZLib->inflate($strBlockBuffer, $strBlock);
|
||||||
$iBlockIn = $oGzip->read($strBlock);
|
|
||||||
|
|
||||||
if ($iBlockIn < 0)
|
if ($iZLibStatus == Z_OK || $iZLibStatus == Z_BUF_ERROR || $iZLibStatus == Z_STREAM_END)
|
||||||
{
|
{
|
||||||
confess &log(ERROR, "unable to decompress stream ($iBlockIn): ${GunzipError}");
|
$iFileSize += length($strBlock);
|
||||||
|
$oSHA->add($strBlock);
|
||||||
|
|
||||||
|
if (defined($hOut))
|
||||||
|
{
|
||||||
|
$self->stream_write($hOut, \$strBlock);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
$iBlockSize = 0;
|
||||||
|
last;
|
||||||
}
|
}
|
||||||
|
|
||||||
$iUncompressedTotal += $iBlockIn;
|
|
||||||
}
|
}
|
||||||
|
while ($iZLibStatus == Z_OK && length($strBlock));
|
||||||
|
|
||||||
# Write out the uncompressed bytes if there are any
|
# # Write out the uncompressed bytes if there are any
|
||||||
if ($iUncompressedTotal > 0)
|
# if ($iUncompressedTotal > 0)
|
||||||
{
|
# {
|
||||||
$oSHA->add($strBlock);
|
# $oSHA->add($strBlock);
|
||||||
$iFileSize += $iUncompressedTotal;
|
# $iFileSize += $iUncompressedTotal;
|
||||||
|
#
|
||||||
$self->stream_write($hOut, \$strBlock, $iUncompressedTotal);
|
# if (defined($hOut))
|
||||||
undef($strBlock);
|
# {
|
||||||
}
|
# $self->stream_write($hOut, \$strBlock, $iUncompressedTotal);
|
||||||
|
# }
|
||||||
|
#
|
||||||
|
# undef($strBlock);
|
||||||
|
# }
|
||||||
}
|
}
|
||||||
# Else close gzip
|
|
||||||
else
|
# Make sure the decompression succeeded
|
||||||
|
if ($iBlockSize == 0)
|
||||||
{
|
{
|
||||||
$iBlockIn = $oGzip->close();
|
if ($iZLibStatus != Z_STREAM_END)
|
||||||
|
{
|
||||||
|
confess &log(ERROR, "unable to inflate stream: gzip returned ${iZLibStatus}");
|
||||||
|
}
|
||||||
|
|
||||||
last;
|
last;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -619,7 +676,7 @@ sub binary_xfer
|
|||||||
else
|
else
|
||||||
{
|
{
|
||||||
# Read a block from the protocol stream
|
# Read a block from the protocol stream
|
||||||
$iBlockSize = $self->block_read($hIn, \$strBlock);
|
$iBlockSize = $self->block_read($hIn, \$strBlock, $bProtocol);
|
||||||
|
|
||||||
# If the block contains data, write it
|
# If the block contains data, write it
|
||||||
if ($iBlockSize > 0)
|
if ($iBlockSize > 0)
|
||||||
@@ -669,9 +726,9 @@ sub binary_xfer
|
|||||||
confess &log(ERROR, "IO::Compress::Gzip failed: $GzipError");
|
confess &log(ERROR, "IO::Compress::Gzip failed: $GzipError");
|
||||||
}
|
}
|
||||||
|
|
||||||
if (defined($strBlock) && length($strBlock) > $self->{iBlockSize})
|
if (defined($hOut) && defined($strBlock) && length($strBlock) > $self->{iBlockSize})
|
||||||
{
|
{
|
||||||
$self->block_write($hOut, \$strBlock);
|
$self->block_write($hOut, \$strBlock, undef, $bProtocol);
|
||||||
undef($strBlock);
|
undef($strBlock);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -680,8 +737,12 @@ sub binary_xfer
|
|||||||
{
|
{
|
||||||
$oGzip->close();
|
$oGzip->close();
|
||||||
|
|
||||||
$self->block_write($hOut, \$strBlock);
|
if (defined($hOut))
|
||||||
$self->block_write($hOut, undef, 0);
|
{
|
||||||
|
$self->block_write($hOut, \$strBlock, undef, $bProtocol);
|
||||||
|
$self->block_write($hOut, undef, 0, $bProtocol);
|
||||||
|
}
|
||||||
|
|
||||||
last;
|
last;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -692,11 +753,11 @@ sub binary_xfer
|
|||||||
|
|
||||||
if ($iBlockIn > 0)
|
if ($iBlockIn > 0)
|
||||||
{
|
{
|
||||||
$self->block_write($hOut, \$strBlock, $iBlockIn);
|
$self->block_write($hOut, \$strBlock, $iBlockIn, $bProtocol);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
$self->block_write($hOut, undef, 0);
|
$self->block_write($hOut, undef, 0, $bProtocol);
|
||||||
last;
|
last;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
Reference in New Issue
Block a user