use Carp qw/croak verbose/;
use Encode;
+use Compress::Raw::Lzma;
+
+our %UNCOMPRESS = (
+ '' => sub { $_[0] },
+ 'lzma2' => sub {
+ my ($input) = @_;
+ my ($lzma2, $code, $output);
+ ($lzma2, $code) = Compress::Raw::Lzma::RawDecoder->new(Filter => Lzma::Filter::Lzma2());
+ die "Error creating LZMA2 decoder: $code\n" unless $code == LZMA_OK;
+ $code = $lzma2->code($input, $output);
+ die "Did not reach end of stream" if $code == LZMA_OK;
+ die "Error decoding LZMA2: $code" if $code != LZMA_STREAM_END;
+ $output
+ }
+);
+
sub new {
my ($class, $path) = @_;
- my $fh =
- ref $path eq 'IO'
- ? $path
- : open my $fh, '<', $path or croak "Cannot open \"$path\": $!";
+ my $fh;
+ if (ref $path eq 'IO') {
+ $fh = $path
+ } else {
+ open $fh, '<', $path or croak "Cannot open \"$path\": $!"
+ }
my $self = bless {path => $path, fh => $fh}, $class;
$self->{header} = $self->read_header;
$self
sub uncompress {
my ($self, $data) = @_;
- $data
+ $UNCOMPRESS{$self->{header}{compression}}->($data)
}
sub read_header {
$self->{encoding} = $encoding;
my $compression = $self->read_tiny_text;
- die "Compression not yet supported" if $compression;
+ die "Compression '$compression' not yet supported" unless exists $UNCOMPRESS{$compression};
my %tags = $self->read_tags;
my @content_types = $self->read_content_types;
my $blob_count = $self->read_int;
use strict;
use warnings;
-use Test::More tests => 7;
+use Test::More tests => 13;
BEGIN { use_ok('Slob') };
-my $slob = Slob->new('t/freedict-01.slob');
+for my $path (qw/freedict-uncompressed.slob freedict-lzma2.slob/) {
+ my $slob = Slob->new("t/$path");
-my $nr_of_entries = $slob->ref_count;
+ my $nr_of_entries = $slob->ref_count;
-my $second_ref = $slob->seek_and_read_ref(4);
-my $bin = $slob->seek_and_read_storage_bin($second_ref->{bin_index});
+ my $second_ref = $slob->seek_and_read_ref(4);
+ my $bin = $slob->seek_and_read_storage_bin($second_ref->{bin_index});
-is $second_ref->{key}, 'abacus';
-is $second_ref->{bin_index}, 0;
-is $second_ref->{item_index}, 161;
-my $count = scalar @{$bin->{positions}};
-is $count, 637;
+ is $second_ref->{key}, 'abacus';
+ is $second_ref->{bin_index}, 0;
+ is $second_ref->{item_index}, 161;
+ my $count = scalar @{$bin->{positions}};
+ is $count, 637;
-my $expected = <<'EOF';
+ my $expected = <<'EOF';
<html><head><link href="~/css/default.css" rel="stylesheet" type="text/css"><link href="~/css/night.css" rel="alternate stylesheet" title="Night" type="text/css"></head><script src="~/js/styleswitcher.js"></script><body><div class="form">
<div class="orth">abacus</div><div class="pron">æbəkəs</div></div><ol class="sense single"><li class="sense">
<ol class="cit single"><li class="cit trans">
<ol class="quote single"><li class="quote">Rechenbrett</li></ol><div class="gramGrp">
<div class="gen">m</div></div></li></ol></li></ol></body></html>
EOF
-chomp $expected;
-is $slob->get_entry_of_storage_bin($bin, $second_ref->{item_index}), $expected;
+ chomp $expected;
+ is $slob->get_entry_of_storage_bin($bin, $second_ref->{item_index}), $expected;
-is $slob->seek_and_read_ref_and_data(4)->{data}, $expected;
+ is $slob->seek_and_read_ref_and_data(4)->{data}, $expected;
+}