| File-Format-RIFF documentation | Contained in the File-Format-RIFF distribution. |
File::Format::RIFF::Chunk - a single RIFF chunk
use File::Format::RIFF; my ( $chunk ) = new File::Format::RIFF::Chunk; $chunk->id( 'stuf' ); $chunk->data( 'here is some stuff' ); ... some $container ... $container->push( $chunk );
A File::Format::RIFF::Chunk is a single chunk of data in a RIFF file. It
has an identifier and one piece of scalar data. The id must be a
four character code, and the data can be any piece of scalar data you wish
to store, in any format (it is treated as opaque binary data, so you must
interpret it yourself).
Creates a new File::Format::RIFF::Chunk object. $id is a four character
code that identifies the type of data. If $id is not specified, it
defaults to ' ' (four spaces). $data is a scalar, treated as
opaque binary data. If $data is undef or not specified, it defaults
to ''.
Returns the id of $chunk.
Sets the id of $chunk. $id must be a four character code that
identifies the type of data.
Returns the data of $chunk.
Sets the data of $chunk. $data is treated as a piece of opaque
binary data, not modified or interpreted in any way.
Returns the size (in bytes) of $chunk's data.
Returns the total size (in bytes) that $chunk will take up when written
out to a file. Total size is the size of the data, plus 8 bytes for the
header, plus 1 alignment byte if the data has an odd number of bytes (so that
the RIFF chunks will be word-aligned on disk).
Prints a string representation of $chunk to STDOUT. If the data is
larger than $max bytes, prints '[...]' instead of the actual data. If
$max is not specified or undef, it defaults to 64.
A RIFF chunk is rendered as:
id: <id> size: <size> (<total size>): <data>
Paul Sturm <sturm@branewave.com>
| File-Format-RIFF documentation | Contained in the File-Format-RIFF distribution. |
package File::Format::RIFF::Chunk; our $VERSION = '0.09'; use bytes; use Carp; use vars qw/ $PACKFMT /; BEGIN { $PACKFMT = 'V' } sub new { my ( $proto, $id, $data ) = @_; my ( $self ) = $proto->_new; $self->id( defined $id ? $id : ' ' ); $self->data( $data ); return $self; } sub _new { my ( $proto ) = @_; my ( $class ) = ref( $proto ) || $proto; return bless { }, $class; } sub write { my ( $self, $fh ) = @_; $self->_write_header( $fh ); $self->_write_data( $fh ); } sub id { my ( $self ) = shift; return $self->{id} unless ( @_ ); my ( $id ) = shift; croak "Length of id must be 4" unless ( length( $id ) == 4 ); $self->{id} = $id; } sub data { my ( $self ) = shift; return $self->{data} unless ( @_ ); my ( $data ) = shift; $data = '' unless ( defined $data ); $self->{size} = length( $self->{data} = $data ); } sub size { my ( $self ) = @_; return $self->{size}; } sub total_size { my ( $self ) = @_; my ( $sz ) = $self->size; return 8 + $sz + ( $sz % 2 ); } sub _read_header { my ( $self, $fh ) = @_; $self->{size} = $self->_read_size( $fh ); } sub _write_header { my ( $self, $fh ) = @_; $self->_write_fourcc( $fh, $self->{id} ); $self->_write_size( $fh, $self->{size} ); } sub _read_data { my ( $self, $fh ) = @_; my ( $sz ) = $self->size; $self->_file_read( $fh, \$self->{data}, $sz ); return unless ( $sz % 2 ); my ( $x ); $self->_file_read( $fh, \$x, 1 ); } sub _write_data { my ( $self, $fh ) = @_; $self->_file_write( $fh, $self->{data} ); $self->_file_write( $fh, "\0" ) if ( $self->{size} % 2 ); } sub _file_read { my ( $proto, $fh, $ref, $expect ) = @_; my ( $got ) = read( $fh, $$ref, $expect ); croak "File read error: $!" unless ( defined $got ); croak "File read error: expected $expect bytes, got $got" unless ( $got == $expect ); } sub _file_write { my ( $proto, $fh, @data ) = @_; print { $fh } @data or croak 'Could not write to file'; } sub _read_fourcc { my ( $proto, $fh ) = @_; my ( $fourcc ); $proto->_file_read( $fh, \$fourcc, 4 ); return $fourcc; } sub _write_fourcc { my ( $self, $fh, $fourcc ) = @_; $self->_file_write( $fh, $fourcc ); } sub _read_size { my ( $proto, $fh ) = @_; my ( $size ); $proto->_file_read( $fh, \$size, 4 ); return unpack( $PACKFMT, $size ); } sub _write_size { my ( $self, $fh, $size ) = @_; $self->_file_write( $fh, pack( $PACKFMT, $size ) ); } sub dump { my ( $self, $max, $indent ) = @_; $max = 64 unless ( defined $max ); $indent = 0 unless ( defined $indent and $indent > 0 ); print join( '', "\t" x $indent ), 'id: ', $self->id, ' size: ', $self->size, ' (', $self->total_size, '): '; ( $max and $self->size > $max ) ? print '[...]' : print $self->{data}; print "\n"; } sub read { my ( $proto, $id, $fh ) = @_; my ( $self ) = ref( $proto ) ? $proto : $proto->_new; $self->id( $id ); $self->_read_header( $fh ); $self->_read_data( $fh ); return $self; } 1;