Changeset 3413 for lang/perl/Archive-Lha
- Timestamp:
- 12/21/07 18:32:34 (12 months ago)
- Location:
- lang/perl/Archive-Lha/trunk
- Files:
-
- 3 added
- 7 removed
- 8 modified
-
Changes (modified) (1 diff)
-
Lha.h (added)
-
Lha.xs (added)
-
MANIFEST (modified) (2 diffs)
-
Makefile.PL (modified) (1 diff)
-
lib/Archive/Lha.pm (modified) (2 diffs)
-
lib/Archive/Lha/Bitstream.pm (deleted)
-
lib/Archive/Lha/CRC.pm (deleted)
-
lib/Archive/Lha/Decode/Base.pm (modified) (3 diffs)
-
lib/Archive/Lha/Decode/LH0.pm (modified) (3 diffs)
-
lib/Archive/Lha/Header/Level0.pm (modified) (1 diff)
-
lib/Archive/Lha/Queue.pm (deleted)
-
lib/Archive/Lha/Table.pm (deleted)
-
lib/Archive/Lha/TableSet.pm (deleted)
-
lib/Archive/Lha/Tree.pm (deleted)
-
ppport.h (added)
-
t/10_bitstream.t (deleted)
-
t/20_decode.t (modified) (1 diff)
Legend:
- Unmodified
- Added
- Removed
-
lang/perl/Archive-Lha/trunk/Changes
r3270 r3413 1 1 Revision history for Archive-Lha 2 2 3 0.01 2007/12/1 84 - initial CodeReposrelease3 0.01 2007/12/10 4 - initial release -
lang/perl/Archive-Lha/trunk/MANIFEST
r3270 r3413 1 1 Changes 2 Lha.h 3 Lha.xs 2 4 lib/Archive/Lha.pm 3 lib/Archive/Lha/Bitstream.pm4 5 lib/Archive/Lha/Constants.pm 5 lib/Archive/Lha/CRC.pm6 6 lib/Archive/Lha/Debug.pm 7 7 lib/Archive/Lha/Decode.pm … … 16 16 lib/Archive/Lha/Header/Level2.pm 17 17 lib/Archive/Lha/Header/Utils.pm 18 lib/Archive/Lha/Queue.pm19 18 lib/Archive/Lha/Stream.pm 20 19 lib/Archive/Lha/Stream/File.pm 21 20 lib/Archive/Lha/Stream/Hex.pm 22 21 lib/Archive/Lha/Stream/String.pm 23 lib/Archive/Lha/Table.pm24 lib/Archive/Lha/TableSet.pm25 lib/Archive/Lha/Tree.pm26 22 Makefile.PL 27 23 MANIFEST This list of files 24 ppport.h 28 25 README 29 26 t/00_load.t -
lang/perl/Archive-Lha/trunk/Makefile.PL
r3270 r3413 16 16 'List::Util' => 0, 17 17 'Log::Dispatch' => 0, 18 'Test::UseAllModules' => 0, 18 19 'Test::More' => 0.47, 19 'Test::UseAllModules' => 0,20 20 'Time::Piece' => 0, 21 21 }, -
lang/perl/Archive-Lha/trunk/lib/Archive/Lha.pm
r3270 r3413 5 5 6 6 our $VERSION = '0.01'; 7 8 require XSLoader; 9 XSLoader::load('Archive::Lha', $VERSION); 7 10 8 11 1; … … 20 23 =head1 ACKNOWLEDGMENT 21 24 22 The decoding algorithm used here is based on the one of LHa for UNIX version 1.14i-ac20050924p1. Though largely modified, you may find that some parts of this perl port are still similar, or almost literal translations of the original, especially where I've not fully understood yet.25 The decoding (XS) part is based on the C sources of LHa for UNIX version 1.14i-ac20050924p1. Though I modified a lot not only to XSify but aslo to make it (comparatively) thread-safe and easy to understand, I'm not fair if I omit the names of the original authors/contributors. If you find this port valuable, kudos be to them. If you find something wrong, most probably that'd be my fault. 23 26 24 Well, as a whole, they are different, in terms of file layout, object-orientedness and thread safety, not to mention the language used.27 According to the original C sources, those parts of LHa for UNIX version 1.14i-ac20050924p1 are copyrighted by Nobutaka Watazaki (1993-1995), Tsugio Okamoto (1996-2000?), and Koji Arai (2002-). I'm grateful to them, and also to all the people who involved in the development of LHa and its descendants/relatives including Masaru Oki, Yoichi Tagawa, Haruhiko Okumura, Haruyasu Yoshizaki, Kazuhiko Miki and others. 25 28 26 However, I'm not fair if I omit the names of the original authors/contributors. If you find this port valuable, kudos be to them. If you find something wrong, most probably that'd be my fault. 27 28 According to the C sources, those parts of LHa for UNIX version 1.14i-ac20050924p1 are copyrighted by Nobutaka Watazaki (1993-1995), Tsugio Okamoto (1996-2000?), and Koji Arai (2002-). I'm grateful to them, and also to all the people who involved in the development of LHa and its descendants/relatives including Masaru Oki, Yoichi Tagawa, Haruhiko Okumura, Haruyasu Yoshizaki, Kazuhiko Miki and others. 29 Other parts including headers file and perl sources are mine or of contributors to this perl port. See appropriate POD sections for details. 29 30 30 31 =head1 SEE ALSO -
lang/perl/Archive-Lha/trunk/lib/Archive/Lha/Decode/Base.pm
r3270 r3413 6 6 use List::Util qw( min ); 7 7 use Archive::Lha::Constants; 8 use Archive::Lha::Bitstream; 9 use Archive::Lha::Queue; 10 use Archive::Lha::TableSet; 11 use Archive::Lha::Tree; 8 use base qw( Archive::Lha ); 12 9 13 10 sub import { … … 18 15 no strict 'refs'; no warnings 'redefine'; 19 16 20 my $dicbit = $options{dicbit} ;17 my $dicbit = $options{dicbit} || 13; 21 18 22 19 # these should be configurable, probably? … … 68 65 my $header = $options{header}; 69 66 70 my $bitstream = Archive::Lha::Bitstream->new(71 callback => $options{read},72 length => $header->{packed_size},73 );74 75 my $pt_table = Archive::Lha::TableSet->new(76 bit => $class->PT_TABLE_BIT, length => $class->NPT77 );78 my $c_table = Archive::Lha::TableSet->new(79 bit => $class->C_TABLE_BIT, length => $class->NC80 );81 my $tree = Archive::Lha::Tree->new( size => 2 * $class->NC - 1 );82 83 67 my $self = bless { 84 68 blocksize => 0, 85 pt => $pt_table, 86 c => $c_table, 87 tree => $tree, 88 bit => $bitstream, 69 read => $options{read}, 89 70 write => $options{write}, 71 packed => $header->{packed_size}, 90 72 original => $header->{original_size}, 91 crc16 => $header->{crc16}, 73 crc16 => $header->{crc16} || 0, 74 DICSIZE => $class->DICSIZE, 75 MAXMATCH => $class->MAXMATCH, 76 THRESHOLD => $class->THRESHOLD, 77 NPT => $class->NPT, 78 NP => $class->NP, 79 NT => $class->NT, 80 NC => $class->NC, 81 PBIT => $class->PBIT, 82 TBIT => $class->TBIT, 83 CBIT => $class->CBIT, 84 PT_TABLE_BIT => $class->PT_TABLE_BIT, 85 PT_TABLE_SIZE => $class->PT_TABLE_SIZE, 86 C_TABLE_BIT => $class->C_TABLE_BIT, 87 C_TABLE_SIZE => $class->C_TABLE_SIZE, 92 88 }, $class; 93 89 94 90 $self; 95 }96 97 sub decode { # modified from slide.c:decode98 my $self = shift;99 100 my $queue = Archive::Lha::Queue->new(101 size => $self->DICSIZE,102 callback => $self->{write},103 );104 my $adjust = ( 1 << UCHAR_BIT ) - $self->THRESHOLD;105 my $total = 0;106 my $original = $self->{original};107 108 while ( $total < $original ) {109 my $char = $self->_decode_c;110 if ( $char <= UCHAR_MAX ) {111 $queue->set( $char );112 $total++;113 }114 else {115 my $length = $char - $adjust;116 my $offset = $self->_decode_p + 1;117 118 $queue->copy( $offset, $length );119 $total += $length;120 }121 }122 $queue->output;123 croak "CRC mismatch" if $queue->crc16 != $self->{crc16};124 }125 126 sub _decode_c { # modified from huf.c:decode_c127 my $self = shift;128 129 if ( $self->{blocksize} == 0 ) {130 $self->{blocksize} = $self->bit->read( USHORT_BIT );131 $self->_read_pt( $self->NT, $self->TBIT, 3 );132 $self->_read_c;133 $self->_read_pt( $self->NP, $self->PBIT, -1 );134 }135 $self->{blocksize}--;136 137 my $char = $self->c->value( $self->bit->peek( $self->c->bit ) );138 139 if ( $char < $self->c->length_size ) {140 $self->bit->cut( $self->c->length( $char ) );141 }142 else {143 $self->bit->cut( $self->c->bit );144 $char = $self->tree->_follow(145 from => $char,146 bits => $self->bit->peek( USHORT_BIT ),147 limit => $self->c->length_size,148 );149 $self->bit->cut( $self->c->length( $char ) - $self->c->bit );150 }151 return $char;152 }153 154 sub _decode_p { # modified from huf.c:decode_p155 my $self = shift;156 157 my $pt = $self->pt->value( $self->bit->peek( $self->pt->bit ) );158 159 if ( $pt < $self->NP ) {160 $self->bit->cut( $self->pt->length( $pt ) );161 }162 else {163 $self->bit->cut( $self->pt->bit );164 $pt = $self->tree->_follow(165 from => $pt,166 bits => $self->bit->peek( USHORT_BIT ),167 limit => $self->NP,168 );169 $self->bit->cut( $self->pt->length( $pt ) - $self->pt->bit );170 }171 if ( $pt ) {172 $pt = ( 1 << ( $pt - 1 ) ) + $self->bit->read( $pt - 1 );173 }174 return $pt;175 }176 177 sub _read_pt { # modified from huf.c:read_pt_len178 my ($self, $nn, $nbit, $threshold) = @_;179 180 my $n = $self->bit->read( $nbit );181 if ( $n == 0 ) {182 $self->pt->fill_value( with => $self->bit->read( $nbit ) );183 $self->pt->fill_length( with => 0, to => $nn );184 }185 else {186 my $i = 0;187 while ( $i < min( $n, $self->pt->length_size ) ) {188 my $c = $self->bit->peek(3);189 if ( $c == 7 ) {190 my $mask = _ushort( 1 << ( ( USHORT_BIT - 1 ) - 3 ) );191 while ( $self->bit->check( $mask ) ) {192 $mask >>= 1;193 $c++;194 }195 $self->bit->cut( $c - 3 );196 }197 else {198 $self->bit->cut(3);199 }200 201 $self->pt->length( $i++ => $c );202 if ( $i == $threshold ) {203 $c = $self->bit->read(2);204 while( --$c >= 0 && $i < $self->pt->length_size ) {205 $self->pt->length( $i++ => 0 );206 }207 }208 }209 $self->pt->fill_length( with => 0, from => $i, to => $nn );210 $self->_make_table( $self->pt, $nn );211 }212 }213 214 sub _read_c { # modified from huf.c:read_c_len215 my $self = shift;216 217 my $n = $self->bit->read( $self->CBIT );218 if ( $n == 0 ) {219 $self->c->fill_value( with => $self->bit->read( $self->CBIT ) );220 $self->c->fill_length( with => 0 );221 }222 else {223 my $i = 0;224 while ( $i < min( $n, $self->c->length_size ) ) {225 my $c = $self->pt->value( $self->bit->peek( $self->pt->bit ) );226 if ( $c >= $self->NT ) {227 $c = $self->tree->_follow(228 from => $c,229 bits => $self->bit->peek( USHORT_BIT ),230 mask_shift => $self->pt->bit,231 limit => $self->NT,232 );233 }234 $self->bit->cut( $self->pt->length( $c ) );235 if ( $c <= 2 ) {236 if ( $c == 0 ) {237 $c = 1;238 }239 elsif ( $c == 1 ) {240 $c = $self->bit->read(4) + 3;241 }242 else {243 $c = $self->bit->read( $self->CBIT ) + 20;244 }245 while ( --$c >= 0 ) {246 $self->c->length( $i++ => 0 );247 }248 }249 else {250 $self->c->length( $i++ => $c - 2 );251 }252 }253 $self->c->fill_length( with => 0, from => $i );254 $self->_make_table( $self->c, $self->c->length_size );255 }256 }257 258 sub _make_table { # modified from maketbl.c:make_table259 my ($self, $table, $nchar) = @_;260 261 my (@count, @weight, @start);262 263 for( my $i = 1; $i <= USHORT_BIT; $i++ ) {264 $count[$i] = 0;265 $weight[$i] = _ushort( 1 << ( USHORT_BIT - $i ) );266 }267 268 for( my $i = 0; $i < $nchar; $i++ ) {269 if ( $table->length( $i ) > USHORT_BIT ) {270 croak "Table is broken: ".$table->stringify;271 }272 $count[ $table->length( $i ) ]++;273 }274 275 my $total = 0;276 for( my $i = 1; $i <= USHORT_BIT; $i++ ) {277 $start[$i] = $total;278 $total += $weight[$i] * $count[$i];279 }280 281 if ( $total & USHORT_MAX ) {282 croak "Table is broken: ".$table->stringify;283 }284 285 my $m = USHORT_BIT - $table->bit;286 287 for( my $i = 1; $i <= $table->bit; $i++ ) {288 $start[$i] = _ushort( $start[$i] >> $m );289 $weight[$i] = _ushort( $weight[$i] >> $m );290 }291 292 my $j = $start[ $table->bit + 1 ] >> $m;293 my $k = min( 1 << $table->bit, $table->size );294 295 if ( $j ) {296 $table->fill_value( with => 0, from => $j, to => $k );297 }298 299 my $avail = $nchar;300 for( my $j = 0; $j < $nchar; $j++ ) {301 my $k = $table->length( $j ) or next;302 my $l = $start[$k] + $weight[$k];303 304 if ( $k <= $table->bit ) {305 $l = min( $l, $table->size );306 $table->fill_value( with => $j, from => $start[$k], to => $l );307 }308 else {309 my $i = $start[$k];310 if ( ( $i >> $m ) > $table->size ) {311 croak "Table is broken: ".$table->stringify;312 }313 314 my $p_addr = $i >> $m;315 my $p_type = 'table';316 my $p = $table->value( $p_addr );317 my $n = $k - $table->bit;318 $i = _ushort( $i << $table->bit );319 320 while ( --$n >= 0 ) {321 if ( $p == 0 ) {322 $self->tree->right( $avail => 0 );323 $self->tree->left( $avail => 0 );324 $p = $avail++;325 if ( $p_type eq 'table' ) {326 $table->value( $p_addr => $p );327 }328 elsif ( $p_type eq 'right' ) {329 $self->tree->right( $p_addr => $p );330 }331 elsif ( $p_type eq 'left' ) {332 $self->tree->left( $p_addr => $p );333 }334 }335 if ( $i >= USHORT_CENTER ) {336 $p_type = 'right';337 $p_addr = $p;338 $p = $self->tree->right( $p_addr );339 }340 else {341 $p_type = 'left';342 $p_addr = $p;343 $p = $self->tree->left( $p_addr );344 }345 $i = _ushort( $i << 1 );346 }347 if ( $p_type eq 'table' ) {348 $table->value( $p_addr => $j );349 }350 elsif ( $p_type eq 'right' ) {351 $self->tree->right( $p_addr => $j );352 }353 elsif ( $p_type eq 'left' ) {354 $self->tree->left( $p_addr => $j );355 }356 }357 $start[$k] = $l;358 }359 91 } 360 92 -
lang/perl/Archive-Lha/trunk/lib/Archive/Lha/Decode/LH0.pm
r3270 r3413 4 4 use warnings; 5 5 use Carp; 6 use bytes; 6 7 use Archive::Lha::Constants; 7 use Archive::Lha ::CRC;8 use Archive::Lha; 8 9 9 10 sub new { … … 26 27 my $self = shift; 27 28 29 my $crc = 0; 28 30 my $total = 0; 29 31 my $size = $self->{size}; 30 my $crc = Archive::Lha::CRC->new;31 32 32 while ( $total < $size ) { 33 33 my $left = $size - $total; … … 35 35 my $str = $self->{read}->( $length ); 36 36 $self->{write}->( $str ); 37 $crc ->add( $str);37 $crc = Archive::Lha::crc16( $crc, $str, length($str) ); 38 38 $total += $length; 39 39 } 40 croak "CRC mismatch" if $crc->value != $self->{crc16}; 40 croak "CRC mismatch" if $crc != $self->{crc16}; 41 return $crc; 41 42 } 42 43 -
lang/perl/Archive-Lha/trunk/lib/Archive/Lha/Header/Level0.pm
r3270 r3413 22 22 my $checksum = ord( $bits[1] ); 23 23 my $checksum1 = ( sum( map { ord } @bits[2..$#bits] ) ) & CHAR_MAX; 24 croak "Header is broken: checksum $checksum/$checksum1"24 croak "Header is broken: start:$start checksum $checksum/$checksum1" 25 25 unless $checksum == $checksum1; 26 26 -
lang/perl/Archive-Lha/trunk/t/20_decode.t
r3270 r3413 27 27 write => sub { $decoded .= join '', @_ }, 28 28 ); 29 $decoder->decode; 29 my $crc = $decoder->decode; 30 if ( $header->{crc16} ) { 31 ok $crc == $header->{crc16}, "CRC: $crc / $$header{crc16}"; 32 } 30 33 31 34 if ( defined $value ) {
![(please configure the [header_logo] section in trac.ini)](/share/chrome/site/your_project_logo.png)