[PATCH 1/3] Return offsets instead of chunk objects from chunkers
Michael Hanselmann
public at hansmi.ch
Wed Aug 13 21:18:12 UTC 2008
This patch removes duplicate code (instantiation of
Brackup::PositionedChunk) and is needed for further changes.
---
lib/Brackup/Chunker/Default.pm | 22 ++++++++-----------
lib/Brackup/Chunker/MP3.pm | 35 +++++++++---------------------
lib/Brackup/File.pm | 45 +++++++++++++++++++++++++++++++++++++++-
3 files changed, 64 insertions(+), 38 deletions(-)
diff --git a/lib/Brackup/Chunker/Default.pm b/lib/Brackup/Chunker/Default.pm
index 9b1f29b..a661f21 100644
--- a/lib/Brackup/Chunker/Default.pm
+++ b/lib/Brackup/Chunker/Default.pm
@@ -1,26 +1,22 @@
package Brackup::Chunker::Default;
use strict;
+use warnings;
-sub chunks {
- my ($class, $file) = @_;
- my @chunk_list;
+sub get_offsets {
+ my ($class, $file, $cb) = @_;
- my $root = $file->root;
+ my $root = $file->root;
my $chunk_size = $root->chunk_size;
- my $size = $file->size;
-
+ my $size = $file->size;
my $offset = 0;
+
while ($offset < $size) {
my $len = _min($chunk_size, $size - $offset);
- my $chunk = Brackup::PositionedChunk->new(
- file => $file,
- offset => $offset,
- length => $len,
- );
- push @chunk_list, $chunk;
+
+ $cb->($offset, $len);
+
$offset += $len;
}
- return @chunk_list;
}
sub _min {
diff --git a/lib/Brackup/Chunker/MP3.pm b/lib/Brackup/Chunker/MP3.pm
index 5bf5b7f..fe5cf46 100644
--- a/lib/Brackup/Chunker/MP3.pm
+++ b/lib/Brackup/Chunker/MP3.pm
@@ -1,15 +1,16 @@
package Brackup::Chunker::MP3;
use strict;
+use warnings;
my $HAVE_MP3_INFO;
BEGIN {
$HAVE_MP3_INFO = eval "use MP3::Info (); 1;";
}
-sub chunks {
- my ($class, $file) = @_;
- my @chunk_list;
- die "Required module MP3::Info not found. Needed by the MP3 file chunker.\n"
+sub get_offsets {
+ my ($class, $file, $cb) = @_;
+
+ die "Required module MP3::Info not found. Needed by the MP3 file chunker.\n"
unless $HAVE_MP3_INFO;
my $file_path = $file->path;
@@ -19,40 +20,26 @@ sub chunks {
return () unless -e $file_path;
my ($music_offset, $music_size) = main_music_range($file_path);
- my $size = $file->size;
+ my $size = $file->size;
# add the ID3v2 header, if necessary:
if ($music_offset != 0) {
- push @chunk_list, Brackup::PositionedChunk->new(
- file => $file,
- offset => 0,
- length => $music_offset,
- );
+ $cb->(0, $music_offset);
}
# add the music chunk (one big chunk, at least for now)
- push @chunk_list, Brackup::PositionedChunk->new(
- file => $file,
- offset => $music_offset,
- length => $music_size,
- );
+ $cb->($music_offset, $music_size);
# add the ID3v1 header chunk, if necessary:
my $music_end = $music_offset + $music_size;
if ($music_end != $size) {
- push @chunk_list, Brackup::PositionedChunk->new(
- file => $file,
- offset => $music_end,
- length => $size - $music_end,
- );
+ $cb->($music_end, $size - $music_end);
}
-
- return @chunk_list;
}
sub main_music_range {
- my $file = shift;
- my $size = -s $file;
+ my ($file) = @_;
+ my $size = $file->size;
# if not an mp3, include the whole file
unless ($file =~ /\.mp3$/i) {
diff --git a/lib/Brackup/File.pm b/lib/Brackup/File.pm
index 13c0b24..8dc2ee9 100644
--- a/lib/Brackup/File.pm
+++ b/lib/Brackup/File.pm
@@ -120,7 +120,50 @@ sub chunks {
# Get the appropriate FileChunker for this file type,
# then pass ourselves to it to get our chunks.
- my @chunk_list = $self->file_chunker->chunks($self);
+ my @chunk_list;
+
+ my $size = $self->size;
+ my $last_offset = undef;
+ my $last_len = undef;
+
+ $self->file_chunker->get_offsets($self, sub {
+ my ($offset, $len) = @_;
+
+ # Lots of verification on offset and length
+ if ($offset + $len > $size) {
+ die "Chunker seeks behind file";
+
+ } elsif ($len <= 0) {
+ die "Chunker returned invalid length";
+
+ }
+
+ if (defined($last_offset)) {
+ if ($offset <= $last_offset) {
+ die "Chunker didn't advance";
+ }
+
+ if (defined($last_len) and $offset != ($last_offset + $last_len)) {
+ die "Chunker jumped";
+ }
+
+ } elsif ($offset != 0) {
+ die "Chunker didn't start at offset 0";
+ }
+
+ push @chunk_list, new Brackup::PositionedChunk(
+ file => $self,
+ offset => $offset,
+ length => $len,
+ );
+
+ $last_offset = $offset;
+ $last_len = $len;
+ });
+
+ unless (($last_offset + $last_len) == $size) {
+ die "Chunker didn't return complete file";
+ }
$self->{chunks} = \@chunk_list;
return @chunk_list;
--
1.5.5.3
More information about the brackup
mailing list