File Coverage

blib/lib/CGI/Session/Serialize/default.pm
Criterion Covered Total %
statement 44 64 68.7
branch 3 26 11.5
condition 0 8 0.0
subroutine 11 11 100.0
pod 2 2 100.0
total 60 111 54.0


line stmt bran cond sub pod time code
1             package CGI::Session::Serialize::default;
2              
3             # $Id$
4              
5 21     21   120 use strict;
  21         44  
  21         845  
6 21     21   22675 use Safe;
  21         1087026  
  21         1633  
7 21     21   33597 use Data::Dumper;
  21         149708  
  21         2169  
8 21     21   505 use CGI::Session::ErrorHandler;
  21         44  
  21         618  
9 21     21   130 use Scalar::Util qw(blessed reftype refaddr);
  21         47  
  21         1516  
10 21     21   128 use Carp "croak";
  21         47  
  21         1141  
11 21     21   122 use vars qw( %overloaded );
  21         48  
  21         15801  
12             require overload;
13              
14             @CGI::Session::Serialize::default::ISA = ( "CGI::Session::ErrorHandler" );
15             $CGI::Session::Serialize::default::VERSION = '4.43';
16              
17              
18             sub freeze {
19 14     14 1 38 my ($class, $data) = @_;
20            
21 14         451 my $d =
22             new Data::Dumper([$data], ["D"]);
23 14         723 $d->Indent( 0 );
24 14         272 $d->Purity( 1 );
25 14         166 $d->Useqq( 0 );
26 14         123 $d->Deepcopy( 0 );
27 14         137 $d->Quotekeys( 1 );
28 14         147 $d->Terse( 0 );
29            
30             # ;$D added to make certain we get our data structure back when we thaw
31 14         119 return $d->Dump() . ';$D';
32             }
33              
34             sub thaw {
35 8     8 1 21 my ($class, $string) = @_;
36              
37             # To make -T happy
38 8         54 my ($safe_string) = $string =~ m/^(.*)$/s;
39 8         83 my $rv = Safe->new->reval( $safe_string );
40 8 50       29596 if ( $@ ) {
41 0         0 return $class->set_error("thaw(): couldn't thaw. $@");
42             }
43 8         1340 __walk($rv);
44 8         50 return $rv;
45             }
46              
47             sub __walk {
48 8     8   20 my %seen;
49 8         35 my @filter = __scan(shift);
50 8         20 local %overloaded;
51              
52             # We allow the value assigned to a key to be undef.
53             # Hence the defined() test is not in the while().
54              
55 8         32 while (@filter) {
56 8 50       63 defined(my $x = shift @filter) or next;
57 0 0 0     0 $seen{refaddr $x || ''}++ and next;
58            
59 0 0       0 my $r = reftype $x or next;
60 0 0 0     0 if ($r eq "HASH") {
    0          
    0          
61             # we use this form to make certain we have aliases
62             # to the values in %$x and not copies
63 0         0 push @filter, __scan(@{$x}{keys %$x});
  0         0  
64             } elsif ($r eq "ARRAY") {
65 0         0 push @filter, __scan(@$x);
66             } elsif ($r eq "SCALAR" || $r eq "REF") {
67 0         0 push @filter, __scan($$x);
68             }
69             }
70             }
71              
72             # we need to do this because the values we get back from the safe compartment
73             # will have packages defined from the safe compartment's *main instead of
74             # the one we use
75             sub __scan {
76             # $_ gets aliased to each value from @_ which are aliases of the values in
77             # the current data structure
78 8     8   26 for (@_) {
79 8 50       60 if (blessed $_) {
80 0 0       0 if (overload::Overloaded($_)) {
81 0         0 my $address = refaddr $_;
82              
83             # if we already rebuilt and reblessed this item, use the cached
84             # copy so our ds is consistent with the one we serialized
85 0 0       0 if (exists $overloaded{$address}) {
86 0         0 $_ = $overloaded{$address};
87             } else {
88 0         0 my $reftype = reftype $_;
89 0 0 0     0 if ($reftype eq "HASH") {
    0          
    0          
90 0         0 $_ = $overloaded{$address} = bless { %$_ }, ref $_;
91             } elsif ($reftype eq "ARRAY") {
92 0         0 $_ = $overloaded{$address} = bless [ @$_ ], ref $_;
93             } elsif ($reftype eq "SCALAR" || $reftype eq "REF") {
94 0         0 $_ = $overloaded{$address} = bless \do{my $o = $$_},ref $_;
  0         0  
95             } else {
96 0         0 croak "Do not know how to reconstitute blessed object of base type $reftype";
97             }
98             }
99             } else {
100 0         0 bless $_, ref $_;
101             }
102             }
103             }
104 8         104 return @_;
105             }
106              
107              
108             1;
109              
110             __END__;
111              
112             =pod
113              
114             =head1 NAME
115              
116             CGI::Session::Serialize::default - Default CGI::Session serializer
117              
118             =head1 DESCRIPTION
119              
120             This library is used by CGI::Session driver to serialize session data before storing it in disk.
121              
122             All the methods are called as class methods.
123              
124             =head1 METHODS
125              
126             =over 4
127              
128             =item freeze($class, \%hash)
129              
130             Receives two arguments. First is the class name, the second is the data to be serialized. Should return serialized string on success, undef on failure. Error message should be set using C<set_error()|CGI::Session::ErrorHandler/"set_error()">
131              
132             =item thaw($class, $string)
133              
134             Received two arguments. First is the class name, second is the I<frozen> data string. Should return thawed data structure on success, undef on failure. Error message should be set using C<set_error()|CGI::Session::ErrorHandler/"set_error()">
135              
136             =back
137              
138             =head1 LICENSING
139              
140             For support and licensing see L<CGI::Session|CGI::Session>
141              
142             =cut
143