File Coverage

blib/lib/Storable/AMF0.pm
Criterion Covered Total %
statement 77 79 97.4
branch 24 32 75.0
condition 4 4 100.0
subroutine 15 15 100.0
pod 6 6 100.0
total 126 136 92.6


line stmt bran cond sub pod time code
1             package Storable::AMF0;
2             # vim: ts=8 sw=4 sts=4 et
3 52     52   127732 use strict;
  52         66  
  52         1210  
4 52     52   166 use warnings;
  52         66  
  52         1148  
5 52     52   225 use Fcntl qw(:flock);
  52         57  
  52         5449  
6             our $VERSION = '1.21';
7 52     52   18961 use subs qw(freeze thaw);
  52         983  
  52         199  
8 52     52   1967 use Exporter 'import';
  52         73  
  52         1387  
9 52     52   202 use Carp qw(croak);
  52         51  
  52         24338  
10             { our @Bool = (bless( do{\(my $o = 0)},'JSON::PP::Boolean'), bless( do{\(my $o = 1)},'JSON::PP::Boolean'));
11             local $@;
12             eval {
13             require Types::Serialiser;
14             @Bool = (Types::Serialiser::false(), Types::Serialiser::true());
15             1
16             } or
17             eval {
18             require JSON::XS;
19             @Bool = (JSON::XS::false(), JSON::XS::true());
20             1
21             };
22             };
23              
24             # Items to export into callers namespace by default. Note: do not export
25             # names by default without a very good reason. Use EXPORT_OK instead.
26             # Do not simply export all your public functions/methods/constants.
27              
28             our @EXPORT_TAGS_ALL = qw(
29             freeze thaw dclone
30             retrieve lock_retrieve lock_store lock_nstore store nstore
31             ref_lost_memory ref_clear
32             deparse_amf new_amfdate perl_date
33             new_date
34             parse_option
35             parse_serializator_option
36             );
37              
38             our %EXPORT_TAGS = ( 'all' => \@EXPORT_TAGS_ALL);
39             our @EXPORT_OK = ( @EXPORT_TAGS_ALL );
40              
41             sub retrieve($) {
42 32     32 1 53 my $file = shift;
43 32         35 my $lock = shift;
44              
45 32 50       893 open my $fh, "<:raw", $file or croak "Can't open file \"$file\" for read.";
46 32 100       86 flock $fh, LOCK_SH if $lock;
47 32         34 my $buf;
48 32         192 sysread $fh, $buf, (( sysseek $fh, 0, 2 ), sysseek $fh, 0,0)[0] ;
49 32         499 return thaw($buf);
50             }
51              
52             sub lock_retrieve($) {
53 6     6 1 12 $_[1] = 1;
54 6         15 goto &retrieve;
55             }
56              
57             sub store($$) {
58 15     15 1 41573 my ( $object, $file, $lock ) = @_;
59              
60 15         309 my $freeze = \freeze($object);
61 15 50       51 unless (defined $$freeze ){
62 0         0 croak "Bad object";
63             }
64             else {
65 15         14 my $fh;
66 15 100       21 if ($lock){
67 7 50       337 open $fh, ">>:raw", $file or croak "Can't open file \"$file\" for write.";
68 7 50       251303 flock $fh, LOCK_EX if $lock;
69 7         194 truncate $fh, 0;
70 7         22 seek $fh,0,0;
71             }
72             else {
73 8 50       567 open $fh, ">:raw", $file or croak "Can't open file \"$file\" for write.";
74             }
75 15 50       161 print $fh $$freeze if defined $$freeze;
76 15         496 close $fh;
77             };
78             }
79              
80             sub lock_store($$) {
81 7     7 1 14 $_[2] = 1;
82 7         28 goto &store;
83             }
84             sub ref_lost_memory($);
85             sub ref_clear($);
86             {{
87             require XSLoader;
88             XSLoader::load( 'Storable::AMF', $VERSION );
89 52     52   270 no warnings 'once';
  52         70  
  52         2814  
90             *nstore = \&store;
91             *lock_nstore = \&lock_store;
92              
93 52     52   204 no strict 'refs';
  52         51  
  52         24167  
94              
95             my $my_package = __PACKAGE__ . "::";
96             for my $other_package ( "Storable::AMF::", "Storable::AMF3::" ){
97             # print STDERR "*{ $other_package$_ } = *{ $my_package$_}\n" for qw(ref_clear ref_lost_memory);
98             *{ $other_package . $_ } = *{ $my_package . $_} for qw(ref_clear ref_lost_memory VERSION);
99             }
100             *{"Storable::AMF::$_"} = *{"Storable::AMF0::$_"} for grep m/retrieve|store/, @EXPORT_OK;
101             }};
102              
103             *refaddr = \&Scalar::Util::refaddr;
104             *reftype = \&Scalar::Util::reftype;
105              
106             sub _ref_selfref($$);
107             sub _ref_selfref($$){
108 1462     1462   2997 require Scalar::Util;
109 1462         904 my $obj_addr = shift;
110 1462         991 my $value = shift;
111 1462         1443 my $addr = refaddr($value);
112 1462 100       2600 return unless defined $addr;
113 686 100       1236 if ( reftype($value) eq 'ARRAY' ) {
    50          
114              
115 374 100       724 return $$obj_addr{$addr} if exists $$obj_addr{$addr};
116 275         316 $$obj_addr{$addr} = 1;
117 275   100     407 _ref_selfref( $obj_addr, $_ ) && return 1 for @$value;
118 221         174 $$obj_addr{$addr} = 0;
119             }
120             elsif ( reftype($value) eq 'HASH' ) {
121              
122 312 100       552 return $$obj_addr{$addr} if exists $$obj_addr{$addr};
123 234         250 $$obj_addr{$addr} = 1;
124 234   100     468 _ref_selfref( $obj_addr, $_ ) && return 1 for values %$value;
125 216         171 $$obj_addr{$addr} = 0;
126             }
127             else {
128 0         0 return;
129             }
130              
131 437         767 return;
132             }
133              
134             sub ref_clear($) {
135 1581     1581 1 654930 my $ref = shift;
136 1581         1259 my %addr;
137 1581         4590 require Scalar::Util;
138 1581 100       4190 return unless ( refaddr($ref));
139 726         541 my @r;
140 726 100       1805 if ( reftype($ref) eq 'ARRAY' ) {
    50          
141 399         612 @r = @$ref;
142 399         399 @$ref = ();
143 399         910 ref_clear($_) for @r;
144             }
145             elsif ( reftype($ref) eq 'HASH' ) {
146 327         671 @r = values %$ref;
147 327         455 %$ref = ();
148 327         770 ref_clear($_) for @r;
149             }
150             }
151              
152             sub ref_lost_memory($) {
153 533     533 1 166439 my $ref = shift;
154 533         351 my %obj_addr;
155 533         591 return _ref_selfref( \%obj_addr, $ref );
156             }
157              
158             1;
159             __END__