1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82
|
package MaxMind::DB::Reader::Role::Sysreader;
use strict;
use warnings;
use namespace::autoclean;
use autodie;
our $VERSION = '1.000014';
use Carp qw( confess );
use MaxMind::DB::Types qw( FileHandle Int );
use Moo::Role;
has data_source => (
is => 'ro',
isa => FileHandle,
lazy => 1,
builder => '_build_data_source',
);
has _data_source_size => (
is => 'ro',
isa => Int,
lazy => 1,
builder => '_build_data_source_size',
);
## no critic (Subroutines::ProhibitUnusedPrivateSubroutines)
sub _read {
my $self = shift;
my $buffer = shift;
my $offset = shift;
my $wanted_size = shift;
my $seek_from_end = shift;
my $source = $self->data_source;
seek $source, $offset, $seek_from_end ? 2 : 0;
my $read_offset = 0;
while (1) {
my $read_size = read(
$source,
${$buffer},
$wanted_size,
$read_offset,
);
confess $! unless defined $read_size;
# This error message doesn't provide much context, but it should only
# be thrown because of a fundamental logic error in the reader code,
# _or_ because the writer generated a database with broken pointers
# and/or broken data elements.
confess 'Attempted to read past the end of a file/memory buffer'
if $read_size == 0;
return if $wanted_size == $read_size;
$wanted_size -= $read_size;
$read_offset += $read_size;
}
return;
}
## use critic
sub _build_data_source {
my $class = ref shift;
die
"You must provide a data_source parameter to the constructor for $class";
}
sub _build_data_source_size {
my $self = shift;
my @stat = stat( $self->data_source ) or die $!;
return $stat[7];
}
1;
|