File Coverage

blib/lib/Data/Session/Serialize/DataDumper.pm
Criterion Covered Total %
statement 54 69 78.2
branch 6 24 25.0
condition 4 10 40.0
subroutine 13 13 100.0
pod 1 3 33.3
total 78 119 65.5


line stmt bran cond sub pod time code
1             package Data::Session::Serialize::DataDumper;
2              
3 2     2   1470 use parent 'Data::Session::Base';
  2         4  
  2         7  
4 2     2   101 no autovivification;
  2         4  
  2         8  
5 2     2   70 use strict;
  2         3  
  2         30  
6 2     2   7 use warnings;
  2         3  
  2         37  
7              
8 2     2   714 use Data::Dumper;
  2         10774  
  2         110  
9              
10 2     2   577 use Safe;
  2         55568  
  2         121  
11              
12 2     2   19 use Scalar::Util qw(blessed reftype refaddr);
  2         3  
  2         152  
13              
14 2     2   11 use vars qw( %overloaded );
  2         4  
  2         1532  
15              
16             require overload;
17              
18             our $VERSION = '1.17';
19              
20             # -----------------------------------------------
21              
22             sub freeze
23             {
24 24     24 0 59 my($self, $data) = @_;
25 24         184 my($d) = Data::Dumper -> new([$data], ["D"]);
26              
27 24         838 $d -> Deepcopy(0);
28 24         192 $d -> Indent(0);
29 24         328 $d -> Purity(1);
30 24         168 $d -> Quotekeys(1);
31 24         172 $d -> Terse(0);
32 24         154 $d -> Useqq(0);
33              
34 24         151 return $d ->Dump;
35              
36             } # End of freeze.
37              
38             # -----------------------------------------------
39              
40             sub new
41             {
42 53     53 1 120 my($class) = @_;
43              
44 53         238 return bless({}, $class);
45              
46             } # End of new.
47              
48             # -----------------------------------------------
49             # We need to do this because the values we get back from the safe compartment
50             # will have packages defined from the safe compartment's *main instead of
51             # the one we use.
52              
53             sub _scan
54             {
55             # $_ gets aliased to each value from @_ which are aliases of the values in
56             # the current data structure.
57              
58 78     78   147 for (@_)
59             {
60 202 50       364 if (blessed $_)
61             {
62 0 0       0 if (overload::Overloaded($_) )
63             {
64 0         0 my($address) = refaddr $_;
65              
66             # If we already rebuilt and reblessed this item, use the cached
67             # copy so our ds is consistent with the one we serialized.
68              
69 0 0       0 if (exists $overloaded{$address})
70             {
71 0         0 $_ = $overloaded{$address};
72             }
73             else
74             {
75 0         0 my($reftype) = reftype $_;
76              
77 0 0 0     0 if ($reftype eq "HASH")
    0          
    0          
78             {
79 0         0 $_ = $overloaded{$address} = bless { %$_ }, ref $_;
80             }
81             elsif ($reftype eq "ARRAY")
82             {
83 0         0 $_ = $overloaded{$address} = bless [ @$_ ], ref $_;
84             }
85             elsif ($reftype eq "SCALAR" || $reftype eq "REF")
86             {
87 0         0 $_ = $overloaded{$address} = bless \do{my $o = $$_}, ref $_;
  0         0  
88             }
89             else
90             {
91 0         0 die __PACKAGE__ . ". Do not know how to reconstitute blessed object of base type $reftype";
92             }
93             }
94             }
95             else
96             {
97 0         0 bless $_, ref $_;
98             }
99             }
100             }
101              
102 78         199 return @_;
103              
104             } # End of _scan.
105              
106             # -----------------------------------------------
107              
108             sub thaw
109             {
110 26     26 0 57 my($self, $data) = @_;
111              
112             # To make -T happy.
113              
114 26         150 my($safe_string) = $data =~ m/^(.*)$/s;
115 26         167 my($rv) = Safe -> new -> reval($safe_string);
116              
117 26 50       39024 if ($@)
118             {
119 0         0 die __PACKAGE__ . ". Couldn't thaw. $@";
120             }
121              
122 26         2230 _walk($rv);
123              
124 26         87 return $rv;
125              
126             } # End of thaw.
127              
128             # -----------------------------------------------
129              
130             sub _walk
131             {
132 26     26   68 my(@filter) = _scan(shift);
133              
134 26         45 local %overloaded;
135              
136 26         40 my(%seen);
137              
138             # We allow the value assigned to a key to be undef.
139             # Hence the defined() test is not in the while().
140              
141 26         60 while (@filter)
142             {
143 202 50       379 defined(my $x = shift @filter) or next;
144              
145 202 100 100     643 $seen{refaddr $x || ''}++ and next;
146              
147             # The original syntax my($r) = reftype($x) or next led to if ($r...)
148             # issuing an uninit warning when $r was undef.
149              
150 78   100     197 my($r) = reftype($x) || next;
151              
152 52 50 0     99 if ($r eq "HASH")
    0          
    0          
153             {
154             # We use this form to make certain we have aliases
155             # to the values in %$x and not copies.
156              
157 52         129 push @filter, _scan(@{$x}{keys %$x});
  52         117  
158             }
159             elsif ($r eq "ARRAY")
160             {
161 0           push @filter, _scan(@$x);
162             }
163             elsif ($r eq "SCALAR" || $r eq "REF")
164             {
165 0           push @filter, _scan($$x);
166             }
167             }
168              
169             } # End of _walk.
170              
171             # -----------------------------------------------
172              
173             1;
174              
175             =pod
176              
177             =head1 NAME
178              
179             L - A persistent session manager
180              
181             =head1 Synopsis
182              
183             See L for details.
184              
185             =head1 Description
186              
187             L allows L to manipulate sessions with
188             L.
189              
190             To use this module do this:
191              
192             =over 4
193              
194             =item o Specify a driver of type DataDumper as
195             Data::Session -> new(type=> '... serialize:DataDumper')
196              
197             =back
198              
199             The Data::Dumper options used are:
200              
201             $d -> Deepcopy(0);
202             $d -> Indent(0);
203             $d -> Purity(1);
204             $d -> Quotekeys(1);
205             $d -> Terse(0);
206             $d -> Useqq(0);
207              
208             =head1 Case-sensitive Options
209              
210             See L for important information.
211              
212             =head1 Method: new()
213              
214             Creates a new object of type L.
215              
216             C takes a hash of key/value pairs, some of which might mandatory. Further, some combinations
217             might be mandatory.
218              
219             The keys are listed here in alphabetical order.
220              
221             They are lower-case because they are (also) method names, meaning they can be called to set or get
222             the value at any time.
223              
224             =over 4
225              
226             =item o verbose => $integer
227              
228             Print to STDERR more or less information.
229              
230             Typical values are 0, 1 and 2.
231              
232             This key is normally passed in as Data::Session -> new(verbose => $integer).
233              
234             This key is optional.
235              
236             =back
237              
238             =head1 Method: freeze($data)
239              
240             Returns $data frozen by L.
241              
242             =head1 Method: thaw($data)
243              
244             Returns $data thawed by L.
245              
246             =head1 Support
247              
248             Log a bug on RT: L.
249              
250             =head1 Author
251              
252             L was written by Ron Savage Iron@savage.net.auE> in 2010.
253              
254             Home page: L.
255              
256             =head1 Copyright
257              
258             Australian copyright (c) 2010, Ron Savage.
259              
260             All Programs of mine are 'OSI Certified Open Source Software';
261             you can redistribute them and/or modify them under the terms of
262             The Artistic License, a copy of which is available at:
263             http://www.opensource.org/licenses/index.html
264              
265             =cut