in reply to Re^2: Declaring Hash entries
in thread Declaring Hash entries
haha Re: Iteratively unpack structure from binary file ( ReadBytes, ReadFloat, ReadInt32 ), http://vitadevwiki.com/index.php?title=System_File_Object_%28SFO%29_%28PSF%29#Header_SFO
#!/usr/bin/perl -- use strict; use warnings; use Data::Dump qw/ dd /; Main( @ARGV ); exit( 0 ); sub ReadBytes { my( $fh, $bytes ) = @_; $bytes or Carp::croak 'Usage: ReadBytes( $filehandle, $bytes ) '; my $readed = read $fh, my($data) , $bytes; $readed == $bytes or Carp::carp "Only read($readed) but wanted($by +tes): $! ## $^E "; $data; } use constant CAN_PACK_QUADS => !! eval { my $f = pack 'q'; 1 }; sub Int8 { unpack 'c', $_[-1] } sub UInt8 { unpack 'C', $_[-1] } sub Int16 { unpack 's<', $_[-1] } sub UInt16 { unpack 'S<', $_[-1] } sub Int32 { unpack 'l<', $_[-1] } sub UInt32 { unpack 'L<', $_[-1] } sub Int64 { unpack( ( CAN_PACK_QUADS ? 'q<' : 'a8' ), $_[-1] ) } sub UInt64 { unpack( ( CAN_PACK_QUADS ? 'Q<' : 'a8' ), $_[-1] ) } sub ReadInt8 { Int8( ReadBytes( $_[-1], 8 /8 ) ); } sub ReadUInt8 { UInt8( ReadBytes( $_[-1], 8 /8 ) ); } sub ReadInt16 { Int16( ReadBytes( $_[-1], 16/8 ) ); } sub ReadUInt16 { UInt16( ReadBytes( $_[-1], 16/8 ) ); } sub ReadInt32 { Int32( ReadBytes( $_[-1], 32/8 ) ); } sub ReadUInt32 { UInt32( ReadBytes( $_[-1], 32/8 ) ); } sub ReadInt64 { Int64( ReadBytes( $_[-1], 64/8 ) ); } sub ReadUInt64 { UInt64( ReadBytes( $_[-1], 64/8 ) ); } sub Float { unpack 'f', $_[-1] } sub ReadFloat { Float( ReadBytes( $_[-1], 32/8 ) ); } #~ perlpacktut says #~ f A single-precision float in native format. #~ d A double-precision float in native format. #~ see perlport sub Double{ unpack 'd', $_[-1] } sub ReadDouble{ Float( ReadBytes( $_[-1], 32/8 ) ); } #~ sub Main { #~ my $file = shift; #~ use autodie qw/ open /; #~ open my($fh), '<:raw', $file; #~ seek $fh, 0x14, 0; #~ my %stuff; #~ $stuff{key_table_offset} = ReadBytes( $fh , 2); #~ #~ $stuff{key_table_offset} = ReadUInt16( $fh ); #~ dd( \%stuff ); #~ #~ } sub Main { for my $file ( @_ ){ Stuffing( $file ); } } sub Stuffing { my $file = shift; use autodie qw/ open /; open my( $fh ), '<:raw', $file; my %stuff; $stuff{header}{magic} = ReadBytes( $fh, 4 ); #~ $stuff{header}{version} = ReadInt64( $fh ); #~ $stuff{header}{key_table_start_offset} = ReadInt64( $fh ); #~ $stuff{header}{data_table_start_offset} = ReadInt64( $fh ); #~ $stuff{header}{number_entries} = ReadInt64( $fh ); $stuff{header}{version} = UInt32( ReadBytes( $fh, +4 ) ); $stuff{header}{key_table_start_offset} = UInt32( ReadBytes( $fh, +4 ) ); $stuff{header}{data_table_start_offset} = UInt32( ReadBytes( $fh, +4 ) ); $stuff{header}{number_entries} = UInt32( ReadBytes( $fh, +4 ) ); seek $fh, 0x14, 0; ## $stuff{index_table}{key_table_offset} = ReadUInt16( $fh ); $stuff{index_table}{param_fmt} = ReadUInt16( $fh ); #~ $stuff{index_table}{param_fmt} = ReadBytes( $fh, 2 ); $stuff{index_table}{param_format} = { 4 => 'utf-8-special', 516 => 'utf-8-charstring-nul', 1027 => 'uint32', }->{ $stuff{index_table}{param_fmt} }; #~ 04 00 Little Endian utf-8 Special Mode Used in contents + generated by the system (e.g.: save data) #~ 04 02 Little Endian utf-8 Character string, NULL finish +ed (0x00) #~ 04 04 Little Endian integer 32 bits unsigned #~ fail #~ perl -le " print pack qw/ L< /, $_ for qw/ 0400 0402 040 +4 /; " #~ fail #~ "\4\2", 516 #~ fail #~ perl -le" die pack 'H*', 516 " #~ #~ $ perl -le" binmode STDOUT; print qq/\4\0\4\2\4\4/ " |hexdump #~ 00000000: 04 00 04 02 04 04 0A - | + | #~ 00000007; #~ #~ { open my($fh), '<:raw', \qq/\4\0/; dd( ReadUInt16( $fh ) ); } + ## 4 #~ { open my($fh), '<:raw', \qq/\4\2/; dd( ReadUInt16( $fh ) ); } + ## 516 #~ { open my($fh), '<:raw', \qq/\4\4/; dd( ReadUInt16( $fh ) ); } + ## 1028 $stuff{index_table}{param_length} = ReadUInt32( $fh ); $stuff{index_table}{param_max_length} = ReadUInt32( $fh ); $stuff{index_table}{data_table_offset} = ReadUInt32( $fh ); #~ typedef struct{ #~ u16 keyOffset; //offset of keytable + keyOffset #~ u16 param_fmt; //enum (see below) #~ u32 paramLen; #~ u32 paramMaxLen; #~ u32 dataOffset; //offset of datatable + dataOffset #~ } indexTableEntry_t; dd( \%stuff ); } ## end sub Stuffing sub StuffingBytes { my $file = shift; use autodie qw/ open /; open my( $fh ), '<:raw', $file; my %stuff; $stuff{header}{magic} = ReadBytes( $fh, 4 ); $stuff{header}{version} = ReadBytes( $fh, 4 ); $stuff{header}{key_table_start_offset} = ReadBytes( $fh, 4 ); $stuff{header}{data_table_start_offset} = ReadBytes( $fh, 4 ); $stuff{header}{number_entries} = ReadBytes( $fh, 4 ); $stuff{index_table}{key_table_offset} = ReadBytes( $fh, 2 ); $stuff{index_table}{param_fmt} = ReadBytes( $fh, 2 ); $stuff{index_table}{param_length} = ReadBytes( $fh, 4 ); $stuff{index_table}{param_max_length} = ReadBytes( $fh, 4 ); $stuff{index_table}{data_table_offset} = ReadBytes( $fh, 4 ); dd( \%stuff ); } ## end sub StuffingBytes __END__ $ perl keytable.pl nonworking.file working.file { header => { data_table_start_offset => 684, key_table_start_offset => 404, magic => "\0PSF", number_entries => 24, version => 257, }, index_table => { data_table_offset => 0, key_table_offset => 0, param_fmt => 516, param_format => "utf-8-charstring-nul", param_length => 6, param_max_length => 8, }, } { header => { data_table_start_offset => 372, key_table_start_offset => 228, magic => "\0PSF", number_entries => 13, version => 257, }, index_table => { data_table_offset => 0, key_table_offset => 0, param_fmt => 516, param_format => "utf-8-charstring-nul", param_length => 6, param_max_length => 8, }, }
|
|---|
| Replies are listed 'Best First'. | |
|---|---|
|
Re^4: Declaring Hash entries
by james28909 (Deacon) on Jan 05, 2015 at 04:44 UTC | |
by Anonymous Monk on Jan 05, 2015 at 08:45 UTC | |
by james28909 (Deacon) on Jan 05, 2015 at 17:16 UTC | |
by Anonymous Monk on Jan 05, 2015 at 22:13 UTC | |
by james28909 (Deacon) on Jan 06, 2015 at 00:29 UTC | |
|