/
XS.pm
151 lines (103 loc) · 3.29 KB
/
XS.pm
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
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
package MaxMind::DB::Reader::XS;
use strict;
use warnings;
use namespace::autoclean;
our $VERSION = '1.000003';
use 5.010000;
use Math::Int128 qw( uint128 );
use MaxMind::DB::Metadata 0.040001;
use MaxMind::DB::Reader 1.000012;
use MaxMind::DB::Types qw( Int );
use Moo;
with 'MaxMind::DB::Reader::Role::Reader',
'MaxMind::DB::Reader::Role::HasMetadata';
use XSLoader;
## no critic (Subroutines::ProhibitCallsToUnexportedSubs)
XSLoader::load( __PACKAGE__, $VERSION );
## use critic
has _mmdb => (
is => 'ro',
init_arg => undef,
lazy => 1,
builder => '_build_mmdb',
predicate => '_has_mmdb',
);
# XXX - making this private & hard coding this is obviously wrong - eventually
# we need to expose the flag constants in Perl
has _flags => (
is => 'ro',
isa => Int,
init_arg => undef,
default => 0,
);
sub BUILD { $_[0]->_mmdb }
## no critic (Subroutines::ProhibitUnusedPrivateSubroutines)
sub _data_for_address {
my $self = shift;
return $self->__data_for_address( $self->_mmdb(), @_ );
}
sub iterate_search_tree {
my $self = shift;
my $data_callback = shift;
my $node_callback = shift;
return $self->_iterate_search_tree(
$self->_mmdb, $data_callback,
$node_callback
);
}
sub _build_mmdb {
my $self = shift;
return $self->_open_mmdb( $self->file(), $self->_flags() );
}
sub _build_metadata {
my $self = shift;
my $raw = $self->_raw_metadata( $self->_mmdb() );
return MaxMind::DB::Metadata->new($raw);
}
sub _decode_bigint {
my $buffer = shift;
my $int = uint128(0);
my @unpacked = unpack( 'NNNN', _zero_pad_left( $buffer, 16 ) );
for my $piece (@unpacked) {
$int = ( $int << 32 ) | $piece;
}
return $int;
}
## use critic
# Copied from MaxMind::DB::Reader::Decoder
sub _zero_pad_left {
my $content = shift;
my $desired_length = shift;
return ( "\x00" x ( $desired_length - length($content) ) ) . $content;
}
sub DEMOLISH {
my $self = shift;
$self->_close_mmdb( $self->_mmdb() )
if $self->_has_mmdb();
return;
}
__PACKAGE__->meta()->make_immutable();
1;
# ABSTRACT: Fast XS implementation of MaxMind DB reader
__END__
=for Pod::Coverage BUILD DEMOLISH
=head1 SYNOPSIS
my $reader = MaxMind::DB::Reader->new( file => 'path/to/database.mmdb' );
my $record = $reader->record_for_address('1.2.3.4');
=head1 DESCRIPTION
Simply installing this module causes L<MaxMind::DB::Reader> to use the XS
implementation, which is much faster than the Perl implementation.
The XS implementation links against the
L<libmaxminddb|http://maxmind.github.io/libmaxminddb/> library.
See L<MaxMind::DB::Reader> for API details.
=head1 VERSIONING POLICY
This module uses semantic versioning as described by
L<http://semver.org/>. Version numbers can be read as X.YYYZZZ, where X is the
major number, YYY is the minor number, and ZZZ is the patch number.
=head1 MAC OS X SUPPORT
If you're running into install errors under Mac OS X, you may need to force a
build of the 64 bit binary. For example, if you're installing via C<cpanm>:
ARCHFLAGS="-arch x86_64" cpanm MaxMind::DB::Reader::XS
=head1 SUPPORT
Please report all issues with this code using the GitHub issue tracker at
L<https://github.com/maxmind/MaxMind-DB-Reader-XS/issues>.