|
Posted by Paul Marquess on April 29, 2008, 12:37 pm
Please log in for more thread options
hymie! wrote:
> Greetings.
>
> I'm using Compress::Zlib for the first time. I'm working with strings
> are are ZLib-compressed but not fully RFC1950 compliant. I'm getting
> some errors and, although I have it working, I know there has to be
> a better way.
>
> I started pretty simple:
>
> my ($inflate,$status);
> ($inflate,$status) = inflateInit();
> while ($i<3)
> {
> print "$i\n";
> # the strings are coming from an internet socket.
> # i can probably get some sample lines if needed
> read($socket,$line,$number);
> ($newline,$status) = $inflate->inflate($line);
> print "line -> $newline\n";
> print "status -> $status\n";
> print "msg -> " , $inflate->msg() , "\n";
> $i++;
> }
>
> and got these results
>
> 0
> line ->
> status -> data error
> msg -> incorrect header check
> 1
> line ->
> status -> data error
> msg -> incorrect header check
> 2
> line ->
> status -> data error
> msg -> incorrect header check
>
> So I did some research and found about adding the header to the string:
>
> my ($inflate,$status);
> ($inflate,$status) = inflateInit();
> while ($i<3)
> {
> print "$i\n";
> # the strings are coming from an internet socket.
> # i can probably get some sample lines if needed
> read($socket,$line,$number);
> $line = "\x78\x01$line"; # i added this line here
> ($newline,$status) = $inflate->inflate($line);
> print "line -> $newline\n";
> print "status -> $status\n";
> print "msg -> " , $inflate->msg() , "\n";
> $i++;
> }
>
> and did a little better
>
> 0
> line -> 06710002515770TradePAC USD17393883907^PDP.IV
> status ->
> msg ->
> 1
> line ->
> status -> data error
> msg -> incorrect data check
> 2
> line ->
> status -> data error
> msg -> incorrect data check
>
> So I adjusted the header thusly
>
> my ($inflate,$status);
> ($inflate,$status) = inflateInit();
> while ($i<3)
> {
> print "$i\n";
> # the strings are coming from an internet socket.
> # i can probably get some sample lines if needed
> read($socket,$line,$number);
> $line = "\x78\x01$line" if $i==0; # i altered this line here
> ($newline,$status) = $inflate->inflate($line);
> print "line -> $newline\n";
> print "status -> $status\n";
> print "msg -> " , $inflate->msg() , "\n";
> $i++;
> }
>
> but same results
>
> line -> 06710002515770TradePAC USD17393883907^PDP.IV
> status ->
> msg ->
> 1
> line ->
> status -> data error
> msg -> incorrect data check
> 2
> line ->
> status -> data error
> msg -> incorrect data check
>
> Now, here is what I finally got working:
>
> while ($i<3)
> {
> print "$i\n";
> my ($inflate,$status);
> ($inflate,$status) = inflateInit(); # moved inflateInit here
> # the strings are coming from an internet socket.
> # i can probably get some sample lines if needed
> read($socket,$line,$number);
> $line = "\x78\x01$line"; # always add header
> ($newline,$status) = $inflate->inflate($line);
> print "line -> $newline\n";
> print "status -> $status\n";
> print "msg -> " , $inflate->msg() , "\n";
> $i++;
> }
>
> but it has to be inefficient always running inflateInit.
>
> So can somebody help me figure out what I'm doing wrong?
Do you have any more info on the structure of the data in the socket. For
example, is there any significance toyou reading $number bytes at a time
from the socket?
If you can get it to work by prefixing every $number bytes with "\x78\x01"
it sounds like you are dealing with one or more RFC1951 data streams.
If you want Compress::Zlib to read an RFC1951 stream, add the WindowsBits
parameter like this when you create the inflation object
($inflate,$status) = inflateInit(WindowBits => -MAX_WBITS);
An alternative is to use one of the of IO::Uncompress modules that
Compress::Zlib now uses behind the scenes. So, for example, if you expect a
single RFC1951 compressed data stream from the socket, the code below will
read it, uncompress it, and write the result into $data
use IO::Uncompress::RawInflate qw(:all)
my $data ;
rawinflate $socket => $data
or die "Cannot uncompress: $RawInflateError\n";
Paul
|