Skip to content

Instantly share code, notes, and snippets.

@kazeburo
Created May 30, 2011 06:23
Show Gist options
  • Select an option

  • Save kazeburo/998515 to your computer and use it in GitHub Desktop.

Select an option

Save kazeburo/998515 to your computer and use it in GitHub Desktop.
#!/usr/bin/env perl
package RangeFile;
use strict;
use warnings;
use 5.10.0;
use Fcntl qw/:seek/;
use parent qw/Exporter/;
our @EXPORT = qw/rangefile/;
sub rangefile {
my ($fh, $count, $offset) = @_;
my $self = bless {
fh => $fh,
_count => $count,
_offset => $offset,
}, __PACKAGE__;
if ( ! defined $offset ) {
seek( $fh, 0, SEEK_CUR) or die $!;
my $cur = tell($fh);
die $! if $cur < 0;
$self->{_offset} = $cur;
}
if ( ! $count ) {
seek( $fh, 0, SEEK_END) or die $!;
my $end = tell($fh);
die $! if $end < -1;
$self->{_count} = $end - $offset;
}
seek( $fh, $self->{_offset}, SEEK_SET) or die $!;
$self;
}
sub getline {
my $self = shift;
return if defined $self->{_read} && $self->{_read} >= $self->{_count};
$self->{_read} = 0 if ! exists $self->{_read};
my $len = ref $/ ? ${$/} : 65536;
$len = $self->{_count} - $self->{_read} if $len > $self->{_count} - $self->{_read};
my $read = read( $self->{fh}, my $buf, $len);
die $! if ! defined $read;
$self->{_read} += $read;
$self->{_offset} = $self->{_offset} + $self->{_read};
return $buf;
}
sub close { 1 };
1;
package main;
use strict;
use warnings;
use 5.10.0;
use Plack::Builder;
builder {
sub {
my $env = shift;
open( my $fh, __FILE__) or die $!;
my $range = RangeFile::rangefile( $fh, 30, 100);
return [200, ['Content-Type'=>'text/plain'], $range];
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment