MS

 view release on metacpan or  search on metacpan

lib/MS/Reader.pm  view on Meta::CPAN

package MS::Reader;

use strict;
use warnings;

use Carp;
use Digest::MD5;
use File::stat;
use Storable qw/nstore_fd retrieve_fd/;
use Scalar::Util qw/blessed/;
use PerlIO::gzip;
use MS; # because we need access to the package version

use constant BGZF_MAGIC => pack 'H*', '1f8b0804';

sub new {

    my ($class, $fn, %args) = @_;

    my $self = bless {} => $class;

    $self->{__use_cache} = $args{use_cache} ? 1 : 0; # remember accessed records
    $self->{__paranoid}  = $args{paranoid}  ? 1 : 0; # calc MD5 each time
    $self->{__fn}        = undef; # to allow dunlock even if not loaded
    $self->{__fh}        = undef; # to allow dunlock even if not loaded
    $self->{__version}   = $MS::VERSION;
    $self->{__lock}      = $args{lock} // 0;
    $self->{__app_data}  = {};

    $self->load($fn) if (defined $fn);

    # check expected methods in subclasses
    $self->_check_interface;

    return $self;

}

# to be defined by subclass
sub _check_interface { return }

sub _read_element {

    my ($self, $offset, $to_read) = @_;

    seek $self->{__fh}, $offset, 0;
    my $r = read($self->{__fh}, my $el, $to_read);
    croak "returned unexpected byte count" if ($r != $to_read);

    return $el;

}

sub load {

    my ($self, $fn) = @_;

    my $use_cache = $self->{__use_cache};

    croak "input file not found" if (! -e $fn);
    $self->{__fn} = $fn;
    open my $fh, '<', $fn;
    my $old_layers = join '', map {":$_"} PerlIO::get_layers($fh);
    binmode $fh;

    # check for BGZIP compression
    read($fh, my $magic, 4);
    binmode($fh, $old_layers);
    if ($magic eq BGZF_MAGIC) {
        require Compress::BGZF::Reader
            or croak "Compress::BGZF::Reader required to handle BGZF files";
        close $fh;
        $fh = Compress::BGZF::Reader->new_filehandle($fn);
    }
    
    $self->{__fh} = $fh;
    seek $fh, 0, 0;
    
    # Use a simple/fast file check (file size + mod time)
    my $st = stat($fn);



( run in 0.964 second using v1.01-cache-2.11-cpan-99c4e6809bf )