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:       [EMAIL PROTECTED]

Reply via email to