You are viewing a plain text version of this content. The canonical link for it is here.
Posted to modperl@perl.apache.org by Robert Landrum <rl...@capitoladvantage.com> on 2001/04/04 21:47:47 UTC

Compress::Zlib problem

One of my developers is looking for a way to take records output from 
a database and compress them into a gzip file on the fly, without 
using a file on disk.

To do this, he's using Compress::Zlib and passing \*STDOUT as the 
output file.  Since this is mod_perl, STDOUT is blessed to Apache, 
and appears to be missing Apache::TELL.

# $fh is \*STDOUT
my $gz = gzopen($fh, 'wb');

$gz->gzwrite($line);  # $line is from db.

He's also played with deflating the content on his own, but is unable 
to get the checksum correct on the output.

Has anyone ever compressed something like this on the fly with 
Compress::Zlib.  As I understand it, Apache::Compress creates 
seperate files, which is not acceptable in this case.

Thanks,

Robert Landrum

--
As soon as you make something foolproof, someone will create a better fool.

Re: Compress::Zlib problem

Posted by Jens-Uwe Mager <ju...@helios.de>.
On Wed, Apr 04, 2001 at 03:47:47PM -0400, Robert Landrum wrote:
> One of my developers is looking for a way to take records output from 
> a database and compress them into a gzip file on the fly, without 
> using a file on disk.
> 
> To do this, he's using Compress::Zlib and passing \*STDOUT as the 
> output file.  Since this is mod_perl, STDOUT is blessed to Apache, 
> and appears to be missing Apache::TELL.
> 
> # $fh is \*STDOUT
> my $gz = gzopen($fh, 'wb');
> 
> $gz->gzwrite($line);  # $line is from db.
> 
> He's also played with deflating the content on his own, but is unable 
> to get the checksum correct on the output.
> 
> Has anyone ever compressed something like this on the fly with 
> Compress::Zlib.  As I understand it, Apache::Compress creates 
> seperate files, which is not acceptable in this case.

I used I logic like the following in one of my packages:

# implement a gzipped file handle via the Compress:Zlib compression
# library.

sub MAGIC1() { 0x1f }
sub MAGIC2() { 0x8b }
sub OSCODE() { 3    }

sub TIEHANDLE {
	my ($class, $out) = @_;
	my ($d) = Compress::Zlib::deflateInit(-Level => Compress::Zlib::Z_BEST_COMPRESSION(),
		-WindowBits => -Compress::Zlib::MAX_WBITS()) or return undef;
	my ($o) = {
		handle => $out,
		dh => $d,
		crc => 0,
		len => 0,
	};
	my ($header) = pack("c10", MAGIC1, MAGIC2, Compress::Zlib::Z_DEFLATED(), 0,0,0,0,0,0, OSCODE);
	print {$o->{handle}} $header;
	return bless($o, $class);
}

sub PRINT {
	my ($o) = shift;
	my ($buf) = join(defined $, ? $, : "",@_);
	my ($len) = length($buf);
	my ($compressed, $status) = $o->{dh}->deflate($buf);
	print {$o->{handle}} $compressed if defined($compressed);
	$o->{crc} = Compress::Zlib::crc32($buf, $o->{crc});
	$o->{len} += $len;
	return $len;
}

sub PRINTF {
	my ($o) = shift;
	my ($fmt) = shift;
	my ($buf) = sprintf($fmt, @_);
	my ($len) = length($buf);
	my ($compressed, $status) = $o->{dh}->deflate($buf);
	print {$o->{handle}} $compressed if defined($compressed);
	$o->{crc} = Compress::Zlib::crc32($buf, $o->{crc});
	$o->{len} += $len;
	return $len;
}

sub WRITE {
	my ($o, $buf, $len, $off) = @_;
	my ($compressed, $status) = $o->{dh}->deflate(substr($buf, 0, $len));
	print {$o->{handle}} $compressed if defined($compressed);
	$o->{crc} = Compress::Zlib::crc32(substr($buf, 0, $len), $o->{crc});
	$o->{len} += $len;
	return $len;
}

sub CLOSE {
	my ($o) = @_;
	return if !defined( $o->{dh});
	my ($buf) = $o->{dh}->flush();
	$buf .= pack("V V", $o->{crc}, $o->{len});
	print {$o->{handle}} $buf;
	undef $o->{dh};
}

sub DESTROY {
	my ($o) = @_;
	CLOSE($o);
}

-- 
Jens-Uwe Mager

HELIOS Software GmbH
Steinriede 3
30827 Garbsen
Germany

Phone:		+49 5131 709320
FAX:		+49 5131 709325
Internet:	jum@helios.de