File Coverage

blib/lib/PeekPoke/FFI.pm
Criterion Covered Total %
statement 30 30 100.0
branch 2 2 100.0
condition 6 7 85.7
subroutine 9 9 100.0
pod 3 3 100.0
total 50 51 98.0


line stmt bran cond sub pod time code
1             package PeekPoke::FFI;
2              
3 1     1   225554 use strict;
  1         6  
  1         28  
4 1     1   5 use warnings;
  1         2  
  1         26  
5 1     1   21 use 5.008001;
  1         4  
6 1     1   693 use FFI::Platypus 1.00;
  1         6583  
  1         31  
7 1     1   6 use base qw( Exporter );
  1         3  
  1         431  
8              
9             our @EXPORT_OK = qw( peek poke );
10              
11             # ABSTRACT: Perl extension for reading and writing to arbitrary memory locations
12             our $VERSION = '0.02'; # VERSION
13              
14              
15             my $ffi = FFI::Platypus->new( api => 1, lib => [undef], lang => 'C' );
16              
17              
18             sub new
19             {
20 2     2 1 4753 my($class, %opts) = @_;
21              
22 2   100     10 my $base = $opts{base} || 0;
23 2   100     8 my $type = $opts{type} || 'uint8';
24 2         8 my $size = $ffi->sizeof($type);
25 2         86 my $memcpy = $ffi->function( memcpy => [ 'opaque', "${type}[1]", 'size_t' ] => 'opaque' );
26              
27 2         433 bless {
28             base => $base,
29             type => $type,
30             size => $size,
31             memcpy => $memcpy,
32             }, $class;
33              
34             }
35              
36             my $default;
37              
38             sub _self
39             {
40 5     5   9 my $args = shift;
41 5 100       14 if(ref $args->[0])
42             {
43 3         24 return shift @$args;
44             }
45             else
46             {
47 2   66     16 return $default ||= __PACKAGE__->new;
48             }
49             }
50              
51              
52             sub peek
53             {
54 3     3 1 16332 my $self = _self(\@_);
55 3         7 my($offset) = @_;
56 3         17 $ffi->cast('opaque' => $self->{type} . '[1]', $self->{base} + ($offset * $self->{size}))->[0];
57             }
58              
59              
60             sub poke
61             {
62 2     2 1 1233 my $self = _self(\@_);
63 2         5 my($offset, $value) = @_;
64 2         21 $self->{memcpy}->call($self->{base} + ($offset * $self->{size}), [$value], $self->{size});
65             }
66              
67             1;
68              
69             __END__