File Coverage

blib/lib/UUID/FFI.pm
Criterion Covered Total %
statement 67 68 98.5
branch 5 8 62.5
condition n/a
subroutine 22 23 95.6
pod 11 11 100.0
total 105 110 95.4


line stmt bran cond sub pod time code
1             package UUID::FFI;
2              
3 1     1   219816 use strict;
  1         6  
  1         29  
4 1     1   6 use warnings;
  1         1  
  1         21  
5 1     1   23 use 5.008001;
  1         4  
6 1     1   749 use FFI::Platypus 1.00;
  1         7495  
  1         28  
7 1     1   499 use FFI::Platypus::Memory ();
  1         12899  
  1         27  
8 1     1   509 use FFI::CheckLib ();
  1         6902  
  1         31  
9 1     1   7 use Carp qw( croak );
  1         2  
  1         97  
10 24     24   68 use overload '<=>' => sub { $_[0]->compare($_[1]) },
11 1     1   393 '""' => sub { shift->as_hex },
12 1     1   7 bool => sub { 1 }, fallback => 1;
  1     0   2  
  1         10  
  0         0  
13              
14             # TODO: as_bin or similar
15              
16             # ABSTRACT: Universally Unique Identifiers FFI style
17             our $VERSION = '0.11'; # VERSION
18              
19              
20             my $ffi = FFI::Platypus->new( api => 1 );
21              
22             $ffi->lib(sub {
23             my @lib = eval {
24             require Alien::libuuid;
25             Alien::libuuid->VERSION('0.05');
26             Alien::libuuid->dynamic_libs;
27             };
28             return @lib if @lib;
29             @lib = FFI::CheckLib::find_lib(
30             lib => 'uuid',
31             symbol => [
32             'uuid_generate_random',
33             'uuid_generate_time',
34             'uuid_unparse',
35             'uuid_parse',
36             'uuid_copy',
37             'uuid_clear',
38             'uuid_type',
39             'uuid_variant',
40             'uuid_time',
41             'uuid_is_null',
42             'uuid_compare',
43             ]
44             );
45             die "Unable to find system libuuid with required symbols. Try installing or upgrading Alien::libuuid"
46             unless @lib;
47             return @lib;
48             });
49              
50             $ffi->mangler(sub { "uuid$_[0]" });
51              
52             $ffi->attach( _generate_random => ['opaque'] => 'void' );
53             $ffi->attach( _generate_time => ['opaque'] => 'void' );
54             $ffi->attach( _unparse => ['opaque', 'opaque'] => 'void' );
55             $ffi->attach( _parse => ['string', 'opaque'] => 'int' );
56             $ffi->attach( _copy => ['opaque', 'opaque'] => 'void' );
57             $ffi->attach( _clear => ['opaque'] => 'void' );
58             $ffi->attach( _type => ['opaque'] => 'int' );
59             $ffi->attach( _variant => ['opaque'] => 'int' );
60             $ffi->attach( _time => ['opaque', 'opaque'] => 'time_t' );
61             $ffi->attach( _is_null => ['opaque'] => 'int' );
62             $ffi->attach( _compare => ['opaque', 'opaque'] => 'int' );
63              
64              
65             sub new
66             {
67 14     14 1 5572 my($class, $hex) = @_;
68 14 50       27 croak "usage: UUID::FFI->new($hex)" unless $hex;
69 14         50 my $self = bless \FFI::Platypus::Memory::malloc(16), $class;
70 14         61 my $r = _parse($hex, $$self);
71 14 100       193 croak "$hex is not a valid hex UUID" if $r != 0;
72 13         26 $self;
73             }
74              
75              
76             sub new_random
77             {
78 7     7 1 13362 my($class) = @_;
79 7         44 my $self = bless \FFI::Platypus::Memory::malloc(16), $class;
80 7         352 _generate_random->($$self);
81 7         39 $self;
82             }
83              
84              
85             sub new_time
86             {
87 2     2 1 1611 my($class) = @_;
88 2         12 my $self = bless \FFI::Platypus::Memory::malloc(16), $class;
89 2         250 _generate_time($$self);
90 2         11 $self;
91             }
92              
93              
94             sub new_null
95             {
96 2     2 1 3349 my($class) = @_;
97 2         13 my $self = bless \FFI::Platypus::Memory::malloc(16), $class;
98 2         14 _clear($$self);
99 2         6 $self;
100             }
101              
102              
103 3     3 1 7 sub is_null { _is_null(${$_[0]}) }
  3         22  
104              
105              
106             sub clone
107             {
108 1     1 1 434 my($self) = @_;
109 1         6 my $other = bless \FFI::Platypus::Memory::malloc(16), ref $self;
110 1         6 _copy($$other, $$self);
111 1         3 $other;
112             }
113              
114              
115             sub as_hex
116             {
117 35     35 1 2164 my($self) = @_;
118 35         54 my $data = "x" x 36;
119 35         95 my $ptr = unpack 'L!', pack 'P', $data;
120 35         239 _unparse($$self, $ptr);
121 35         134 $data;
122             }
123              
124              
125 49     49 1 108 sub compare { _compare( ${$_[0]}, ${$_[1]} ) }
  49         63  
  49         130  
126              
127             my %type_map = (
128             1 => 'time',
129             4 => 'random',
130             );
131              
132              
133             sub type
134             {
135 4     4 1 9 my($self) = @_;
136 4         15 my $r = _type($$self);
137 4 50       30 $type_map{$r} || croak "illegal type: $r";
138             }
139              
140             my @variant = qw( ncs dce microsoft other );
141              
142              
143             sub variant
144             {
145 2     2 1 11 my($self) = @_;
146 2         9 my $r = _variant($$self);
147 2 50       15 $variant[$r] || croak "illegal varient: $r";
148             }
149              
150              
151             sub time
152             {
153 1     1 1 10 my($self) = @_;
154 1         8 _time($$self, undef);
155             }
156              
157             sub DESTROY
158             {
159 26     26   7164 my($self) = @_;
160 26         112 FFI::Platypus::Memory::free($$self);
161             }
162              
163             1;
164              
165             __END__