File: Sysreader.pm

package info (click to toggle)
libmaxmind-db-reader-perl 1.000014-1
  • links: PTS, VCS
  • area: main
  • in suites: bullseye
  • size: 2,040 kB
  • sloc: perl: 1,668; makefile: 10
file content (82 lines) | stat: -rw-r--r-- 1,842 bytes parent folder | download | duplicates (2)
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;