Skip to content

Commit

Permalink
fixed offset bug in Mojo::Asset::File
Browse files Browse the repository at this point in the history
  • Loading branch information
kraih committed Nov 9, 2012
1 parent b513934 commit 6075ec1
Show file tree
Hide file tree
Showing 3 changed files with 38 additions and 16 deletions.
1 change: 1 addition & 0 deletions Changes
Expand Up @@ -4,6 +4,7 @@
significantly.
- Improved documentation.
- Improved tests.
- Fixed offset bug in Mojo::Asset::File.

3.55 2012-11-08
- Added gzip compression support to Mojo::UserAgent.
Expand Down
24 changes: 15 additions & 9 deletions lib/Mojo/Asset/File.pm
Expand Up @@ -63,23 +63,29 @@ sub contains {
my $handle = $self->handle;
$handle->sysseek($self->start_range, SEEK_SET);

# Calculate window
# Calculate window size
my $end = $self->end_range // $self->size;
my $size = length($pattern) * 2;
$size = $size > 131072 ? $size : 131072;
$size = $end - $self->start_range if $size > $end - $self->start_range;
my $offset = $handle->sysread(my $window, $size);
my $range = $self->end_range;

# Sliding window search
while ($offset <= $end) {
return -1 if defined $range && ($size = $end + 1 - $offset) <= 0;
my $read = $handle->sysread(my $buffer, $size);
$offset += $read;
my $offset = 0;
$handle->sysread(my $window, $size);
while ($offset < $end) {

# Read as much as possible
my $diff = $end - $offset;
my $read = $handle->sysread(my $buffer, $diff < $size ? $diff : $size);
$window .= $buffer;

# Search window
my $pos = index $window, $pattern;
return $pos if $pos >= 0;
return -1 if $read == 0;
return $offset + $pos if $pos >= 0;
$offset += $read;
return -1 if $read == 0 || $offset == $end;

# Resize window
substr $window, 0, $read, '';
}

Expand Down
29 changes: 22 additions & 7 deletions t/mojo/asset.t
Expand Up @@ -7,7 +7,6 @@ use Mojo::Asset::Memory;
# File asset
my $file = Mojo::Asset::File->new;
$file->add_chunk('abc');
is $file->contains(''), 0, 'empty string at position 0';
is $file->contains('abc'), 0, '"abc" at position 0';
is $file->contains('bc'), 1, '"bc" at position 1';
is $file->contains('db'), -1, 'does not contain "db"';
Expand All @@ -21,18 +20,17 @@ ok !-e $path, 'temporary file has been cleaned up';
# Memory asset
my $mem = Mojo::Asset::Memory->new;
$mem->add_chunk('abc');
is $mem->contains(''), 0, 'empty string at position 0';
is $mem->contains('abc'), 0, '"abc" at position 0';
is $mem->contains('bc'), 1, '"bc" at position 1';
is $mem->contains('db'), -1, 'does not contain "db"';

# Empty file asset
$file = Mojo::Asset::File->new;
is $file->contains(''), 0, 'empty string at position 0';
is $file->contains('a'), -1, 'does not contain "a"';

# Empty memory asset
$mem = Mojo::Asset::File->new;
is $mem->contains(''), 0, 'empty string at position 0';
$mem = Mojo::Asset::Memory->new;
is $mem->contains('a'), -1, 'does not contain "a"';

# File asset range support (a[bcdef])
$file = Mojo::Asset::File->new(start_range => 1);
Expand Down Expand Up @@ -87,17 +85,34 @@ $file = Mojo::Asset::File->new;
$file->add_chunk('a' x 131072);
$file->add_chunk('b');
$file->add_chunk('c' x 131072);
$file->add_chunk('ddd');
is $file->contains(''), 0, 'empty string at position 0';
is $file->contains('a'), 0, '"a" at position 0';
is $file->contains('b'), 131072, '"b" at position 131072';
is $file->contains('c'), 131073, '"c" at position 131073';
is $file->contains('abc'), 131071, '"abc" at position 131071';
is $file->contains('d'), -1, 'does not contain "d"';
is $file->contains('ddd'), 262145, '"ddd" at position 262145';
is $file->contains('e'), -1, 'does not contain "e"';
is $file->contains('a' x 131072), 0, '"a" x 131072 at position 0';
is $file->contains('c' x 131072), 131073, '"c" x 131072 at position 131073';
is $file->contains('b' . ('c' x 131072)), 131072,
is $file->contains('b' . ('c' x 131072) . "ddd"), 131072,
'"b" . ("c" x 131072) at position 131072';

# Huge file asset with range
$file = Mojo::Asset::File->new(start_range => 1, end_range => 131073);
$file->add_chunk('a' x 131072);
$file->add_chunk('b');
$file->add_chunk('c' x 131072);
$file->add_chunk('ddd');
is $file->contains(''), 0, 'empty string at position 0';
is $file->contains('a'), 0, '"a" at position 0';
is $file->contains('b'), 131071, '"b" at position 131071';
is $file->contains('c'), 131072, '"c" at position 131072';
is $file->contains('abc'), 131070, '"abc" at position 131070';
is $file->contains('ddd'), -1, 'does not contain "ddd"';
is $file->contains('b' . ('c' x 131072) . 'ddd'), -1,
'does not contain "b" . ("c" x 131072) . "ddd"';

# Move memory asset to file
$mem = Mojo::Asset::Memory->new->add_chunk('abc');
my $tmp = Mojo::Asset::File->new->add_chunk('x');
Expand Down

0 comments on commit 6075ec1

Please sign in to comment.