| line | stmt | bran | cond | sub | pod | time | code | 
| 1 |  |  |  |  |  |  | package Data::Serializer; | 
| 2 |  |  |  |  |  |  |  | 
| 3 | 27 |  |  | 27 |  | 52994 | use warnings; | 
|  | 27 |  |  |  |  | 226 |  | 
|  | 27 |  |  |  |  | 1132 |  | 
| 4 | 27 |  |  | 27 |  | 145 | use strict; | 
|  | 27 |  |  |  |  | 53 |  | 
|  | 27 |  |  |  |  | 927 |  | 
| 5 | 27 |  |  | 27 |  | 210 | use vars qw($VERSION); | 
|  | 27 |  |  |  |  | 54 |  | 
|  | 27 |  |  |  |  | 1920 |  | 
| 6 |  |  |  |  |  |  |  | 
| 7 | 27 |  |  | 27 |  | 207 | use Carp; | 
|  | 27 |  |  |  |  | 57 |  | 
|  | 27 |  |  |  |  | 87984 |  | 
| 8 |  |  |  |  |  |  | require 5.004 ; | 
| 9 |  |  |  |  |  |  |  | 
| 10 |  |  |  |  |  |  | $VERSION = '0.65'; | 
| 11 |  |  |  |  |  |  |  | 
| 12 |  |  |  |  |  |  | #Global cache of modules we've loaded | 
| 13 |  |  |  |  |  |  | my %_MODULES; | 
| 14 |  |  |  |  |  |  |  | 
| 15 |  |  |  |  |  |  | my %_fields = ( | 
| 16 |  |  |  |  |  |  | serializer => 'Data::Dumper', | 
| 17 |  |  |  |  |  |  | digester   => 'SHA-256', | 
| 18 |  |  |  |  |  |  | cipher     => 'Blowfish', | 
| 19 |  |  |  |  |  |  | encoding   => 'hex', | 
| 20 |  |  |  |  |  |  | compressor => 'Compress::Zlib', | 
| 21 |  |  |  |  |  |  | secret     => undef, | 
| 22 |  |  |  |  |  |  | portable   => '1', | 
| 23 |  |  |  |  |  |  | compress   => '0', | 
| 24 |  |  |  |  |  |  | raw        => '0', | 
| 25 |  |  |  |  |  |  | options    => {}, | 
| 26 |  |  |  |  |  |  | serializer_token => '1', | 
| 27 |  |  |  |  |  |  | ); | 
| 28 |  |  |  |  |  |  | sub new { | 
| 29 | 2524 |  |  | 2524 | 1 | 4137703 | my ($class, %args) = @_; | 
| 30 | 2524 |  |  |  |  | 23420 | my $dataref = {%_fields}; | 
| 31 | 2524 |  |  |  |  | 10889 | foreach my $field (keys %_fields) { | 
| 32 | 27764 | 100 |  |  |  | 54393 | $dataref->{$field} = $args{$field} if exists $args{$field}; | 
| 33 |  |  |  |  |  |  | } | 
| 34 | 2524 |  |  |  |  | 5613 | my $self = $dataref; | 
| 35 | 2524 |  |  |  |  | 5173 | bless $self, $class; | 
| 36 |  |  |  |  |  |  |  | 
| 37 |  |  |  |  |  |  | #preintitialize serializer object | 
| 38 | 2524 |  |  |  |  | 7266 | $self->_serializer_obj(); | 
| 39 | 2524 |  |  |  |  | 7550 | return $self; | 
| 40 |  |  |  |  |  |  | } | 
| 41 |  |  |  |  |  |  |  | 
| 42 |  |  |  |  |  |  | sub _serializer_obj { | 
| 43 | 7576 |  |  | 7576 |  | 12896 | my $self = (shift); | 
| 44 | 7576 |  |  |  |  | 11512 | my $method = (shift); | 
| 45 | 7576 |  |  |  |  | 11693 | my $reset = (shift); | 
| 46 |  |  |  |  |  |  |  | 
| 47 | 7576 |  |  |  |  | 13059 | my $serializer = $self->{serializer}; | 
| 48 |  |  |  |  |  |  |  | 
| 49 |  |  |  |  |  |  | #remove cache if asked to | 
| 50 | 7576 | 100 |  |  |  | 14853 | if ($reset) { | 
| 51 | 4 |  |  |  |  | 10 | delete $self->{serializer_obj}; | 
| 52 |  |  |  |  |  |  | } | 
| 53 |  |  |  |  |  |  |  | 
| 54 |  |  |  |  |  |  | #If we're given the same method that we are already using, nothing to change | 
| 55 | 7576 | 50 | 66 |  |  | 28576 | if (defined $method && $method ne $serializer) { | 
| 56 | 0 |  |  |  |  | 0 | $serializer = $method; | 
| 57 |  |  |  |  |  |  | } else { | 
| 58 |  |  |  |  |  |  | #safe to return our cached object if we have it | 
| 59 | 7576 | 100 |  |  |  | 21143 | return $self->{serializer_obj} if (exists $self->{serializer_obj}); | 
| 60 |  |  |  |  |  |  | } | 
| 61 |  |  |  |  |  |  |  | 
| 62 | 2528 |  |  |  |  | 7088 | $self->_module_loader($serializer,"Data::Serializer");    #load in serializer module if necessary | 
| 63 | 2528 |  |  |  |  | 5036 | my $serializer_obj = {}; | 
| 64 | 2528 |  |  |  |  | 6252 | $serializer_obj->{options} = $self->{options}; | 
| 65 | 2528 |  |  |  |  | 7718 | bless $serializer_obj, "Data::Serializer::$serializer"; | 
| 66 |  |  |  |  |  |  |  | 
| 67 |  |  |  |  |  |  | #Cache it for later retrieval only if this is the default serializer for the object | 
| 68 |  |  |  |  |  |  | #ugly logic to support legacy token method that would allow the base to have a different serializer | 
| 69 |  |  |  |  |  |  | #than what it is reading | 
| 70 |  |  |  |  |  |  |  | 
| 71 | 2528 | 50 |  |  |  | 6855 | if ($serializer eq $self->{serializer}) { | 
| 72 | 2528 |  |  |  |  | 4790 | $self->{serializer_obj} = $serializer_obj; | 
| 73 |  |  |  |  |  |  | } | 
| 74 | 2528 |  |  |  |  | 4481 | return $serializer_obj; | 
| 75 |  |  |  |  |  |  |  | 
| 76 |  |  |  |  |  |  | } | 
| 77 |  |  |  |  |  |  |  | 
| 78 |  |  |  |  |  |  | sub _persistent_obj { | 
| 79 | 1260 |  |  | 1260 |  | 2032 | my $self = (shift); | 
| 80 | 1260 | 100 |  |  |  | 3932 | return $self->{persistent_obj} if (exists $self->{persistent_obj}); | 
| 81 | 630 |  |  |  |  | 1646 | $self->_module_loader('Data::Serializer::Persistent'); | 
| 82 | 630 |  |  |  |  | 1992 | my $persistent_obj = { parent => $self }; | 
| 83 | 630 |  |  |  |  | 2417 | bless $persistent_obj, "Data::Serializer::Persistent"; | 
| 84 | 630 |  |  |  |  | 1304 | $self->{persistent_obj} = $persistent_obj; | 
| 85 | 630 |  |  |  |  | 1128 | return $persistent_obj; | 
| 86 |  |  |  |  |  |  |  | 
| 87 |  |  |  |  |  |  | } | 
| 88 |  |  |  |  |  |  |  | 
| 89 |  |  |  |  |  |  |  | 
| 90 |  |  |  |  |  |  |  | 
| 91 |  |  |  |  |  |  | sub serializer { | 
| 92 | 2650 |  |  | 2650 | 1 | 4169 | my $self = (shift); | 
| 93 | 2650 |  |  |  |  | 4878 | my $return = $self->{serializer}; | 
| 94 | 2650 | 50 |  |  |  | 5339 | if (@_) { | 
| 95 | 0 |  |  |  |  | 0 | $self->{serializer} = (shift); | 
| 96 |  |  |  |  |  |  | #Reinitialize object | 
| 97 | 0 |  |  |  |  | 0 | $self->_serializer_obj($self->{serializer}, 1); | 
| 98 |  |  |  |  |  |  | } | 
| 99 | 2650 |  |  |  |  | 5526 | return $return; | 
| 100 |  |  |  |  |  |  | } | 
| 101 |  |  |  |  |  |  |  | 
| 102 |  |  |  |  |  |  | sub digester { | 
| 103 | 1260 |  |  | 1260 | 1 | 2792 | my $self = (shift); | 
| 104 | 1260 |  |  |  |  | 2327 | my $return = $self->{digester}; | 
| 105 | 1260 | 100 |  |  |  | 2839 | if (@_) { | 
| 106 | 252 |  |  |  |  | 383 | my $value = (shift); | 
| 107 | 252 |  |  |  |  | 508 | $self->{digester} = $value; | 
| 108 |  |  |  |  |  |  | } | 
| 109 | 1260 |  |  |  |  | 2580 | return $return; | 
| 110 |  |  |  |  |  |  | } | 
| 111 |  |  |  |  |  |  |  | 
| 112 |  |  |  |  |  |  | sub cipher { | 
| 113 | 1008 |  |  | 1008 | 1 | 1736 | my $self = (shift); | 
| 114 | 1008 |  |  |  |  | 1970 | my $return = $self->{cipher}; | 
| 115 | 1008 | 50 |  |  |  | 2392 | if (@_) { | 
| 116 | 0 |  |  |  |  | 0 | $self->{cipher} = (shift); | 
| 117 |  |  |  |  |  |  | } | 
| 118 | 1008 |  |  |  |  | 2071 | return $return; | 
| 119 |  |  |  |  |  |  | } | 
| 120 |  |  |  |  |  |  |  | 
| 121 |  |  |  |  |  |  | sub compressor { | 
| 122 | 5292 |  |  | 5292 | 1 | 9200 | my $self = (shift); | 
| 123 | 5292 |  |  |  |  | 9012 | my $return = $self->{compressor}; | 
| 124 | 5292 | 100 |  |  |  | 10178 | if (@_) { | 
| 125 | 882 |  |  |  |  | 1676 | $self->{compressor} = (shift); | 
| 126 |  |  |  |  |  |  | } | 
| 127 | 5292 |  |  |  |  | 13301 | return $return; | 
| 128 |  |  |  |  |  |  | } | 
| 129 |  |  |  |  |  |  |  | 
| 130 |  |  |  |  |  |  | sub secret { | 
| 131 | 7820 |  |  | 7820 | 1 | 17381 | my $self = (shift); | 
| 132 | 7820 |  |  |  |  | 19990 | my $return = $self->{secret}; | 
| 133 | 7820 | 100 |  |  |  | 16442 | if (@_) { | 
| 134 | 1008 |  |  |  |  | 2050 | $self->{secret} = (shift); | 
| 135 |  |  |  |  |  |  | } | 
| 136 | 7820 |  |  |  |  | 17454 | return $return; | 
| 137 |  |  |  |  |  |  | } | 
| 138 |  |  |  |  |  |  |  | 
| 139 |  |  |  |  |  |  | sub encoding { | 
| 140 | 4292 |  |  | 4292 | 1 | 10755 | my $self = (shift); | 
| 141 | 4292 |  |  |  |  | 7023 | my $return = $self->{encoding}; | 
| 142 | 4292 | 100 |  |  |  | 8460 | if (@_) { | 
| 143 | 504 |  |  |  |  | 946 | $self->{encoding} = (shift); | 
| 144 |  |  |  |  |  |  | } | 
| 145 | 4292 |  |  |  |  | 8043 | return $return; | 
| 146 |  |  |  |  |  |  | } | 
| 147 |  |  |  |  |  |  |  | 
| 148 |  |  |  |  |  |  | sub portable { | 
| 149 | 2902 |  |  | 2902 | 1 | 8417 | my $self = (shift); | 
| 150 | 2902 |  |  |  |  | 5456 | my $return = $self->{portable}; | 
| 151 | 2902 | 100 |  |  |  | 7244 | if (@_) { | 
| 152 | 504 |  |  |  |  | 1061 | $self->{portable} = (shift); | 
| 153 |  |  |  |  |  |  | } | 
| 154 | 2902 |  |  |  |  | 7379 | return $return; | 
| 155 |  |  |  |  |  |  | } | 
| 156 |  |  |  |  |  |  |  | 
| 157 |  |  |  |  |  |  | sub options { | 
| 158 | 4 |  |  | 4 | 1 | 65 | my $self = (shift); | 
| 159 | 4 |  |  |  |  | 9 | my $return = $self->{options}; | 
| 160 | 4 | 50 |  |  |  | 14 | if (@_) { | 
| 161 | 4 |  |  |  |  | 7 | $self->{options} = (shift); | 
| 162 |  |  |  |  |  |  | #Reinitialize object | 
| 163 | 4 |  |  |  |  | 12 | $self->_serializer_obj($self->{serializer}, 1); | 
| 164 |  |  |  |  |  |  | } | 
| 165 | 4 |  |  |  |  | 9 | return $return; | 
| 166 |  |  |  |  |  |  | } | 
| 167 |  |  |  |  |  |  |  | 
| 168 |  |  |  |  |  |  | sub compress { | 
| 169 | 5678 |  |  | 5678 | 1 | 14682 | my $self = (shift); | 
| 170 | 5678 |  |  |  |  | 10291 | my $return = $self->{compress}; | 
| 171 | 5678 | 100 |  |  |  | 12849 | if (@_) { | 
| 172 | 882 |  |  |  |  | 2004 | $self->{compress} = (shift); | 
| 173 |  |  |  |  |  |  | } | 
| 174 | 5678 |  |  |  |  | 12295 | return $return; | 
| 175 |  |  |  |  |  |  | } | 
| 176 |  |  |  |  |  |  |  | 
| 177 |  |  |  |  |  |  | sub raw { | 
| 178 | 4796 |  |  | 4796 | 1 | 7506 | my $self = (shift); | 
| 179 | 4796 |  |  |  |  | 8189 | my $return = $self->{raw}; | 
| 180 | 4796 | 50 |  |  |  | 10725 | if (@_) { | 
| 181 | 0 |  |  |  |  | 0 | $self->{raw} = (shift); | 
| 182 |  |  |  |  |  |  | } | 
| 183 | 4796 |  |  |  |  | 12281 | return $return; | 
| 184 |  |  |  |  |  |  | } | 
| 185 |  |  |  |  |  |  |  | 
| 186 |  |  |  |  |  |  | sub serializer_token { | 
| 187 | 2398 |  |  | 2398 | 1 | 4187 | my $self = (shift); | 
| 188 | 2398 |  |  |  |  | 4481 | my $return = $self->{serializer_token}; | 
| 189 | 2398 | 50 |  |  |  | 5437 | if (@_) { | 
| 190 | 0 |  |  |  |  | 0 | $self->{serializer_token} = (shift); | 
| 191 |  |  |  |  |  |  | } | 
| 192 | 2398 |  |  |  |  | 6008 | return $return; | 
| 193 |  |  |  |  |  |  | } | 
| 194 |  |  |  |  |  |  |  | 
| 195 |  |  |  |  |  |  | sub _module_loader { | 
| 196 | 15010 |  |  | 15010 |  | 22364 | my $self = (shift); | 
| 197 | 15010 |  |  |  |  | 23834 | my $module_name = (shift); | 
| 198 | 15010 | 50 |  |  |  | 31135 | unless (defined $module_name) { | 
| 199 | 0 |  |  |  |  | 0 | confess "Something wrong - module not defined! $! $@\n"; | 
| 200 |  |  |  |  |  |  | } | 
| 201 | 15010 | 100 |  |  |  | 36342 | return if (exists $_MODULES{$module_name}); | 
| 202 | 7590 | 100 |  |  |  | 15587 | if (@_) { | 
| 203 | 7576 |  |  |  |  | 19454 | $module_name = (shift) . "::$module_name"; | 
| 204 |  |  |  |  |  |  | } | 
| 205 | 7590 |  |  |  |  | 12829 | my $package = $module_name; | 
| 206 | 7590 |  |  |  |  | 30280 | $package =~ s|::|/|g; | 
| 207 | 7590 |  |  |  |  | 14767 | $package .= ".pm"; | 
| 208 | 7590 |  |  |  |  | 12140 | eval { require $package }; | 
|  | 7590 |  |  |  |  | 136492 |  | 
| 209 | 7590 | 50 |  |  |  | 20273 | if ($@) { | 
| 210 | 0 |  |  |  |  | 0 | carp "Data::Serializer error: " . | 
| 211 |  |  |  |  |  |  | "Please make sure $package is a properly installed package.\n"; | 
| 212 | 0 |  |  |  |  | 0 | return undef; | 
| 213 |  |  |  |  |  |  | } | 
| 214 | 7590 |  |  |  |  | 16567 | $_MODULES{$module_name} = 1; | 
| 215 |  |  |  |  |  |  | } | 
| 216 |  |  |  |  |  |  |  | 
| 217 |  |  |  |  |  |  |  | 
| 218 |  |  |  |  |  |  |  | 
| 219 |  |  |  |  |  |  |  | 
| 220 |  |  |  |  |  |  |  | 
| 221 |  |  |  |  |  |  | sub _serialize { | 
| 222 | 2524 |  |  | 2524 |  | 3823 | my $self = (shift); | 
| 223 | 2524 |  |  |  |  | 4264 | my @input = @{(shift)};#original @_ | 
|  | 2524 |  |  |  |  | 5935 |  | 
| 224 | 2524 |  |  |  |  | 4285 | my $method = (shift); | 
| 225 | 2524 |  |  |  |  | 6577 | $self->_module_loader($method,"Data::Serializer");	#load in serializer module if necessary | 
| 226 | 2524 |  |  |  |  | 5678 | my $serializer_obj = $self->_serializer_obj($method); | 
| 227 | 2524 |  |  |  |  | 8696 | return $serializer_obj->serialize(@input); | 
| 228 |  |  |  |  |  |  | } | 
| 229 |  |  |  |  |  |  |  | 
| 230 |  |  |  |  |  |  | sub _compress { | 
| 231 | 882 |  |  | 882 |  | 1482 | my $self = (shift); | 
| 232 | 882 |  |  |  |  | 1791 | $self->_module_loader($self->compressor); | 
| 233 | 882 | 50 |  |  |  | 1973 | if ($self->compressor eq 'Compress::Zlib') { | 
|  |  | 0 |  |  |  |  |  | 
| 234 | 882 |  |  |  |  | 3696 | return Compress::Zlib::compress((shift)); | 
| 235 |  |  |  |  |  |  | } elsif ($self->compressor eq 'Compress::PPMd') { | 
| 236 | 0 |  |  |  |  | 0 | my $compressor = Compress::PPMd::Encoder->new(); | 
| 237 | 0 |  |  |  |  | 0 | return $compressor->encode((shift)); | 
| 238 |  |  |  |  |  |  | } | 
| 239 |  |  |  |  |  |  | } | 
| 240 |  |  |  |  |  |  | sub _decompress { | 
| 241 | 882 |  |  | 882 |  | 1724 | my $self = (shift); | 
| 242 | 882 |  |  |  |  | 2333 | $self->_module_loader($self->compressor); | 
| 243 | 882 | 50 |  |  |  | 1863 | if ($self->compressor eq 'Compress::Zlib') { | 
|  |  | 0 |  |  |  |  |  | 
| 244 | 882 |  |  |  |  | 3331 | return Compress::Zlib::uncompress((shift)); | 
| 245 |  |  |  |  |  |  | } elsif ($self->compressor eq 'Compress::PPMd') { | 
| 246 | 0 |  |  |  |  | 0 | my $compressor = Compress::PPMd::Decoder->new(); | 
| 247 | 0 |  |  |  |  | 0 | return $compressor->decode((shift)); | 
| 248 |  |  |  |  |  |  | } | 
| 249 |  |  |  |  |  |  | } | 
| 250 |  |  |  |  |  |  |  | 
| 251 |  |  |  |  |  |  | sub _create_token { | 
| 252 | 2398 |  |  | 2398 |  | 3816 | my $self = (shift); | 
| 253 | 2398 |  |  |  |  | 9187 | return '^' . join('|', @_) . '^'; | 
| 254 |  |  |  |  |  |  | } | 
| 255 |  |  |  |  |  |  | sub _get_token { | 
| 256 | 2398 |  |  | 2398 |  | 3731 | my $self = (shift); | 
| 257 | 2398 |  |  |  |  | 4113 | my $line = (shift); | 
| 258 |  |  |  |  |  |  | #Should be anchored to beginning | 
| 259 |  |  |  |  |  |  | #my ($token) =  $line =~ /\^([^\^]+?)\^/; | 
| 260 | 2398 |  |  |  |  | 15739 | my ($token) =  $line =~ /^\^([^\^]{1,120}?)\^/; | 
| 261 | 2398 |  |  |  |  | 5812 | return $token; | 
| 262 |  |  |  |  |  |  | } | 
| 263 |  |  |  |  |  |  | sub _extract_token { | 
| 264 | 2398 |  |  | 2398 |  | 3933 | my $self = (shift); | 
| 265 | 2398 |  |  |  |  | 4043 | my $token = (shift); | 
| 266 | 2398 |  |  |  |  | 12105 | return split('\|',$token); | 
| 267 |  |  |  |  |  |  | } | 
| 268 |  |  |  |  |  |  | sub _remove_token { | 
| 269 | 2398 |  |  | 2398 |  | 3961 | my $self = (shift); | 
| 270 | 2398 |  |  |  |  | 3899 | my $line = (shift); | 
| 271 | 2398 |  |  |  |  | 11949 | $line =~ s/^\^[^\^]{1,120}?\^//; | 
| 272 | 2398 |  |  |  |  | 6527 | return $line; | 
| 273 |  |  |  |  |  |  | } | 
| 274 |  |  |  |  |  |  | sub _deserialize { | 
| 275 | 2524 |  |  | 2524 |  | 4283 | my $self = (shift); | 
| 276 | 2524 |  |  |  |  | 4310 | my $input = (shift); | 
| 277 | 2524 |  |  |  |  | 4102 | my $method = (shift); | 
| 278 | 2524 |  |  |  |  | 6519 | $self->_module_loader($method,"Data::Serializer");	#load in serializer module if necessary | 
| 279 | 2524 |  |  |  |  | 6200 | my $serializer_obj = $self->_serializer_obj($method); | 
| 280 | 2524 |  |  |  |  | 8831 | $serializer_obj->deserialize($input); | 
| 281 |  |  |  |  |  |  | } | 
| 282 |  |  |  |  |  |  |  | 
| 283 |  |  |  |  |  |  | sub _encrypt { | 
| 284 | 1008 |  |  | 1008 |  | 1778 | my $self = (shift); | 
| 285 | 1008 |  |  |  |  | 1857 | my $value = (shift); | 
| 286 | 1008 |  |  |  |  | 1735 | my $cipher = (shift); | 
| 287 | 1008 |  |  |  |  | 1607 | my $digester = (shift); | 
| 288 | 1008 |  |  |  |  | 2211 | my $secret = $self->secret; | 
| 289 | 1008 | 50 |  |  |  | 2613 | croak "Cannot encrypt: No secret provided!" unless defined $secret; | 
| 290 | 1008 |  |  |  |  | 3006 | $self->_module_loader('Crypt::CBC'); | 
| 291 | 1008 |  |  |  |  | 2815 | my $digest = $self->_endigest($value,$digester); | 
| 292 | 1008 |  |  |  |  | 5605 | my $cipher_obj = Crypt::CBC->new($secret,$cipher); | 
| 293 | 1008 |  |  |  |  | 252207 | return $cipher_obj->encrypt($digest); | 
| 294 |  |  |  |  |  |  | } | 
| 295 |  |  |  |  |  |  | sub _decrypt { | 
| 296 | 1008 |  |  | 1008 |  | 1997 | my $self = (shift); | 
| 297 | 1008 |  |  |  |  | 1794 | my $input = (shift); | 
| 298 | 1008 |  |  |  |  | 1680 | my $cipher = (shift); | 
| 299 | 1008 |  |  |  |  | 1664 | my $digester = (shift); | 
| 300 | 1008 |  |  |  |  | 2619 | my $secret = $self->secret; | 
| 301 | 1008 | 50 |  |  |  | 2508 | croak "Cannot encrypt: No secret provided!" unless defined $secret; | 
| 302 | 1008 |  |  |  |  | 3018 | $self->_module_loader('Crypt::CBC'); | 
| 303 | 1008 |  |  |  |  | 4383 | my $cipher_obj = Crypt::CBC->new($secret,$cipher); | 
| 304 | 1008 |  |  |  |  | 233286 | my $digest = $cipher_obj->decrypt($input); | 
| 305 | 1008 |  |  |  |  | 643854 | return $self->_dedigest($digest,$digester); | 
| 306 |  |  |  |  |  |  | } | 
| 307 |  |  |  |  |  |  | sub _endigest { | 
| 308 | 1008 |  |  | 1008 |  | 1805 | my $self = (shift); | 
| 309 | 1008 |  |  |  |  | 1854 | my $input = (shift); | 
| 310 | 1008 |  |  |  |  | 1614 | my $digester = (shift); | 
| 311 | 1008 |  |  |  |  | 2426 | $self->_module_loader('Digest'); | 
| 312 | 1008 |  |  |  |  | 2764 | my $digest = $self->_get_digest($input,$digester); | 
| 313 | 1008 |  |  |  |  | 4670 | return "$digest=$input"; | 
| 314 |  |  |  |  |  |  | } | 
| 315 |  |  |  |  |  |  | sub _dedigest { | 
| 316 | 1008 |  |  | 1008 |  | 2223 | my $self = (shift); | 
| 317 | 1008 |  |  |  |  | 1961 | my $input = (shift); | 
| 318 | 1008 |  |  |  |  | 1873 | my $digester = (shift); | 
| 319 | 1008 |  |  |  |  | 3323 | $self->_module_loader('Digest'); | 
| 320 |  |  |  |  |  |  | #my ($old_digest) = $input =~ /^([^=]+?)=/; | 
| 321 | 1008 |  |  |  |  | 6713 | $input =~ s/^([^=]+?)=//; | 
| 322 | 1008 |  |  |  |  | 3369 | my $old_digest = $1; | 
| 323 | 1008 | 50 |  |  |  | 2752 | return undef unless (defined $old_digest); | 
| 324 | 1008 |  |  |  |  | 3059 | my $new_digest = $self->_get_digest($input,$digester); | 
| 325 | 1008 | 50 |  |  |  | 3744 | return undef unless ($new_digest eq $old_digest); | 
| 326 | 1008 |  |  |  |  | 8656 | return $input; | 
| 327 |  |  |  |  |  |  | } | 
| 328 |  |  |  |  |  |  | sub _get_digest { | 
| 329 | 2016 |  |  | 2016 |  | 4256 | my $self = (shift); | 
| 330 | 2016 |  |  |  |  | 3556 | my $input = (shift); | 
| 331 | 2016 |  |  |  |  | 3425 | my $digester = (shift); | 
| 332 | 2016 |  |  |  |  | 9508 | my $ctx = Digest->new($digester); | 
| 333 | 2016 |  |  |  |  | 93420 | $ctx->add($input); | 
| 334 | 2016 |  |  |  |  | 20850 | return $ctx->hexdigest; | 
| 335 |  |  |  |  |  |  | } | 
| 336 |  |  |  |  |  |  | sub _enhex { | 
| 337 | 1390 |  |  | 1390 |  | 2250 | my $self = (shift); | 
| 338 | 1390 |  |  |  |  | 9111 | return join('',unpack 'H*',(shift)); | 
| 339 |  |  |  |  |  |  | } | 
| 340 |  |  |  |  |  |  | sub _dehex { | 
| 341 | 1390 |  |  | 1390 |  | 2149 | my $self = (shift); | 
| 342 | 1390 |  |  |  |  | 9469 | return (pack'H*',(shift)); | 
| 343 |  |  |  |  |  |  | } | 
| 344 |  |  |  |  |  |  |  | 
| 345 |  |  |  |  |  |  | sub _enb64 { | 
| 346 | 504 |  |  | 504 |  | 897 | my $self = (shift); | 
| 347 | 504 |  |  |  |  | 1471 | $self->_module_loader('MIME::Base64'); | 
| 348 | 504 |  |  |  |  | 2689 | my $b64 = MIME::Base64::encode_base64( (shift), '' ); | 
| 349 | 504 |  |  |  |  | 1636 | return $b64; | 
| 350 |  |  |  |  |  |  | } | 
| 351 |  |  |  |  |  |  |  | 
| 352 |  |  |  |  |  |  |  | 
| 353 |  |  |  |  |  |  | sub _deb64 { | 
| 354 | 504 |  |  | 504 |  | 927 | my $self = (shift); | 
| 355 | 504 |  |  |  |  | 1421 | $self->_module_loader('MIME::Base64'); | 
| 356 | 504 |  |  |  |  | 2832 | return MIME::Base64::decode_base64( (shift) ); | 
| 357 |  |  |  |  |  |  | } | 
| 358 |  |  |  |  |  |  |  | 
| 359 |  |  |  |  |  |  | # do all 3 stages | 
| 360 | 0 |  |  | 0 | 1 | 0 | sub freeze { (shift)->serialize(@_); } | 
| 361 | 0 |  |  | 0 | 1 | 0 | sub thaw { (shift)->deserialize(@_); } | 
| 362 |  |  |  |  |  |  |  | 
| 363 |  |  |  |  |  |  | sub serialize { | 
| 364 | 2398 |  |  | 2398 | 1 | 51871 | my $self = (shift); | 
| 365 | 2398 |  |  |  |  | 6522 | my ($serializer,$cipher,$digester,$encoding,$compressor) = ('','','','',''); | 
| 366 |  |  |  |  |  |  |  | 
| 367 | 2398 | 50 |  |  |  | 5466 | if ($self->raw) { | 
| 368 | 0 |  |  |  |  | 0 | return $self->raw_serialize(@_); | 
| 369 |  |  |  |  |  |  | } | 
| 370 |  |  |  |  |  |  |  | 
| 371 |  |  |  |  |  |  | #we always serialize no matter what. | 
| 372 |  |  |  |  |  |  |  | 
| 373 |  |  |  |  |  |  | #define serializer for token | 
| 374 | 2398 |  |  |  |  | 5641 | $serializer = $self->serializer; | 
| 375 | 2398 |  |  |  |  | 7067 | my $value = $self->_serialize(\@_,$serializer); | 
| 376 |  |  |  |  |  |  |  | 
| 377 | 2398 | 100 |  |  |  | 763564 | if ($self->compress) { | 
| 378 | 882 |  |  |  |  | 2238 | $compressor = $self->compressor; | 
| 379 | 882 |  |  |  |  | 2356 | $value = $self->_compress($value); | 
| 380 |  |  |  |  |  |  | } | 
| 381 |  |  |  |  |  |  |  | 
| 382 | 2398 | 100 |  |  |  | 248543 | if (defined $self->secret) { | 
| 383 |  |  |  |  |  |  | #define digester for token | 
| 384 | 1008 |  |  |  |  | 2645 | $digester = $self->digester; | 
| 385 |  |  |  |  |  |  | #define cipher for token | 
| 386 | 1008 |  |  |  |  | 2647 | $cipher = $self->cipher; | 
| 387 | 1008 |  |  |  |  | 3010 | $value = $self->_encrypt($value,$cipher,$digester); | 
| 388 |  |  |  |  |  |  | } | 
| 389 | 2398 | 100 |  |  |  | 1756713 | if ($self->portable) { | 
| 390 | 1894 |  |  |  |  | 4365 | $encoding = $self->encoding; | 
| 391 | 1894 |  |  |  |  | 5129 | $value = $self->_encode($value); | 
| 392 |  |  |  |  |  |  | } | 
| 393 | 2398 | 50 |  |  |  | 6343 | if ($self->serializer_token) { | 
| 394 | 2398 |  |  |  |  | 6811 | my $token = $self->_create_token($serializer,$cipher, $digester,$encoding,$compressor); | 
| 395 | 2398 |  |  |  |  | 8284 | $value = $token . $value; | 
| 396 |  |  |  |  |  |  | } | 
| 397 | 2398 |  |  |  |  | 13728 | return $value; | 
| 398 |  |  |  |  |  |  | } | 
| 399 |  |  |  |  |  |  |  | 
| 400 |  |  |  |  |  |  | sub store { | 
| 401 | 630 |  |  | 630 | 1 | 35270 | my $self = (shift); | 
| 402 | 630 |  |  |  |  | 1592 | my $persistent = $self->_persistent_obj(); | 
| 403 | 630 |  |  |  |  | 2421 | $persistent->_store(@_); | 
| 404 |  |  |  |  |  |  | } | 
| 405 |  |  |  |  |  |  |  | 
| 406 |  |  |  |  |  |  | sub retrieve { | 
| 407 | 630 |  |  | 630 | 1 | 79754 | my $self = (shift); | 
| 408 | 630 |  |  |  |  | 1782 | my $persistent = $self->_persistent_obj(); | 
| 409 | 630 |  |  |  |  | 2820 | $persistent->_retrieve(@_); | 
| 410 |  |  |  |  |  |  | } | 
| 411 |  |  |  |  |  |  |  | 
| 412 |  |  |  |  |  |  | sub raw_serialize { | 
| 413 | 126 |  |  | 126 | 1 | 2260 | my $self = (shift); | 
| 414 | 126 |  |  |  |  | 242 | my $serializer = $self->serializer; | 
| 415 | 126 |  |  |  |  | 332 | return $self->_serialize(\@_,$serializer); | 
| 416 |  |  |  |  |  |  | } | 
| 417 |  |  |  |  |  |  |  | 
| 418 |  |  |  |  |  |  | sub _encode { | 
| 419 | 1894 |  |  | 1894 |  | 3109 | my $self = (shift); | 
| 420 | 1894 |  |  |  |  | 3177 | my $value = (shift); | 
| 421 | 1894 |  |  |  |  | 3728 | my $encoding = $self->encoding; | 
| 422 | 1894 | 100 |  |  |  | 5677 | if ($encoding eq 'hex') { | 
|  |  | 50 |  |  |  |  |  | 
| 423 | 1390 |  |  |  |  | 3770 | return $self->_enhex($value); | 
| 424 |  |  |  |  |  |  | } elsif ($encoding eq 'b64') { | 
| 425 | 504 |  |  |  |  | 1856 | return $self->_enb64($value); | 
| 426 |  |  |  |  |  |  | } else { | 
| 427 | 0 |  |  |  |  | 0 | croak "Unknown encoding method $encoding\n"; | 
| 428 |  |  |  |  |  |  | } | 
| 429 |  |  |  |  |  |  | } | 
| 430 |  |  |  |  |  |  |  | 
| 431 |  |  |  |  |  |  | sub _decode { | 
| 432 | 2146 |  |  | 2146 |  | 3757 | my $self = (shift); | 
| 433 | 2146 |  |  |  |  | 3694 | my $value = (shift); | 
| 434 | 2146 |  |  |  |  | 3610 | my $encoding = (shift); | 
| 435 | 2146 | 100 |  |  |  | 6200 | if ($encoding eq 'hex') { | 
|  |  | 100 |  |  |  |  |  | 
|  |  | 50 |  |  |  |  |  | 
| 436 | 1390 |  |  |  |  | 3377 | return $self->_dehex($value); | 
| 437 |  |  |  |  |  |  | } elsif ($encoding eq 'b64') { | 
| 438 | 504 |  |  |  |  | 1338 | return $self->_deb64($value); | 
| 439 |  |  |  |  |  |  | } elsif ($encoding !~ /\S/) { | 
| 440 |  |  |  |  |  |  | #quietly ignore empty encoding | 
| 441 | 252 |  |  |  |  | 712 | return $value; | 
| 442 |  |  |  |  |  |  | } else { | 
| 443 | 0 |  |  |  |  | 0 | croak "Unknown encoding method $encoding\n"; | 
| 444 |  |  |  |  |  |  | } | 
| 445 |  |  |  |  |  |  | } | 
| 446 |  |  |  |  |  |  |  | 
| 447 |  |  |  |  |  |  | sub raw_deserialize { | 
| 448 | 126 |  |  | 126 | 1 | 44253 | my $self = (shift); | 
| 449 | 126 |  |  |  |  | 253 | my $serializer = $self->serializer; | 
| 450 | 126 |  |  |  |  | 306 | return $self->_deserialize((shift),$serializer); | 
| 451 |  |  |  |  |  |  | } | 
| 452 |  |  |  |  |  |  |  | 
| 453 |  |  |  |  |  |  | sub deserialize { | 
| 454 | 2398 |  |  | 2398 | 1 | 8455 | my $self = (shift); | 
| 455 |  |  |  |  |  |  |  | 
| 456 | 2398 | 50 |  |  |  | 6067 | if ($self->raw) { | 
| 457 | 0 |  |  |  |  | 0 | return $self->raw_deserialize(@_); | 
| 458 |  |  |  |  |  |  | } | 
| 459 |  |  |  |  |  |  |  | 
| 460 | 2398 |  |  |  |  | 4652 | my $value = (shift); | 
| 461 | 2398 |  |  |  |  | 5793 | my $token = $self->_get_token($value); | 
| 462 | 2398 |  |  |  |  | 5127 | my ($serializer,$cipher, $digester,$encoding, $compressor); | 
| 463 | 2398 |  |  |  |  | 5581 | my $compress = $self->compress; | 
| 464 | 2398 | 50 |  |  |  | 5833 | if (defined $token) { | 
| 465 | 2398 |  |  |  |  | 6016 | ($serializer,$cipher, $digester,$encoding, $compressor) = $self->_extract_token($token); | 
| 466 |  |  |  |  |  |  |  | 
| 467 |  |  |  |  |  |  | #if compressor is defined and has a value then we must decompress it | 
| 468 | 2398 | 100 |  |  |  | 6535 | $compress = 1 if ($compressor); | 
| 469 | 2398 |  |  |  |  | 5536 | $value = $self->_remove_token($value); | 
| 470 |  |  |  |  |  |  | } else { | 
| 471 | 0 |  |  |  |  | 0 | $serializer = $self->serializer; | 
| 472 | 0 |  |  |  |  | 0 | $cipher = $self->cipher; | 
| 473 | 0 |  |  |  |  | 0 | $digester = $self->digester; | 
| 474 | 0 |  |  |  |  | 0 | $compressor = $self->compressor; | 
| 475 | 0 | 0 |  |  |  | 0 | if ($self->portable) { | 
| 476 | 0 |  |  |  |  | 0 | $encoding = $self->encoding; | 
| 477 |  |  |  |  |  |  | } | 
| 478 |  |  |  |  |  |  | } | 
| 479 | 2398 | 100 |  |  |  | 6036 | if (defined $encoding) { | 
| 480 | 2146 |  |  |  |  | 5749 | $value = $self->_decode($value,$encoding); | 
| 481 |  |  |  |  |  |  | } | 
| 482 | 2398 | 100 |  |  |  | 5878 | if (defined $self->secret) { | 
| 483 | 1008 |  |  |  |  | 2872 | $value = $self->_decrypt($value,$cipher,$digester); | 
| 484 |  |  |  |  |  |  | } | 
| 485 | 2398 | 100 |  |  |  | 6084 | if ($compress) { | 
| 486 | 882 |  |  |  |  | 2958 | $value = $self->_decompress($value); | 
| 487 |  |  |  |  |  |  | } | 
| 488 |  |  |  |  |  |  | #we always deserialize no matter what. | 
| 489 | 2398 |  |  |  |  | 47249 | my @return = $self->_deserialize($value,$serializer); | 
| 490 | 2398 | 50 |  |  |  | 2208657 | return wantarray ? @return : $return[0]; | 
| 491 |  |  |  |  |  |  | } | 
| 492 |  |  |  |  |  |  |  | 
| 493 |  |  |  |  |  |  | 1; | 
| 494 |  |  |  |  |  |  | __END__ | 
| 495 |  |  |  |  |  |  |  | 
| 496 |  |  |  |  |  |  | #Documentation follows | 
| 497 |  |  |  |  |  |  |  | 
| 498 |  |  |  |  |  |  | =pod | 
| 499 |  |  |  |  |  |  |  | 
| 500 |  |  |  |  |  |  | =head1 NAME | 
| 501 |  |  |  |  |  |  |  | 
| 502 |  |  |  |  |  |  | Data::Serializer:: - Modules that serialize data structures | 
| 503 |  |  |  |  |  |  |  | 
| 504 |  |  |  |  |  |  | =head1 SYNOPSIS | 
| 505 |  |  |  |  |  |  |  | 
| 506 |  |  |  |  |  |  | use Data::Serializer; | 
| 507 |  |  |  |  |  |  |  | 
| 508 |  |  |  |  |  |  | $obj = Data::Serializer->new(); | 
| 509 |  |  |  |  |  |  |  | 
| 510 |  |  |  |  |  |  | $obj = Data::Serializer->new( | 
| 511 |  |  |  |  |  |  | serializer => 'Storable', | 
| 512 |  |  |  |  |  |  | digester   => 'MD5', | 
| 513 |  |  |  |  |  |  | cipher     => 'DES', | 
| 514 |  |  |  |  |  |  | secret     => 'my secret', | 
| 515 |  |  |  |  |  |  | compress   => 1, | 
| 516 |  |  |  |  |  |  | ); | 
| 517 |  |  |  |  |  |  |  | 
| 518 |  |  |  |  |  |  | $serialized = $obj->serialize({a => [1,2,3],b => 5}); | 
| 519 |  |  |  |  |  |  | $deserialized = $obj->deserialize($serialized); | 
| 520 |  |  |  |  |  |  | print "$deserialized->{b}\n"; | 
| 521 |  |  |  |  |  |  |  | 
| 522 |  |  |  |  |  |  | =head1 DESCRIPTION | 
| 523 |  |  |  |  |  |  |  | 
| 524 |  |  |  |  |  |  | Provides a unified interface to the various serializing modules | 
| 525 |  |  |  |  |  |  | currently available.  Adds the functionality of both compression | 
| 526 |  |  |  |  |  |  | and encryption. | 
| 527 |  |  |  |  |  |  |  | 
| 528 |  |  |  |  |  |  | By default L<Data::Serializer(3)> adds minor metadata and encodes serialized data | 
| 529 |  |  |  |  |  |  | structures in it's own format.  If you are looking for a simple unified | 
| 530 |  |  |  |  |  |  | pass through interface to the underlying serializers then look into L<Data::Serializer::Raw(3)> | 
| 531 |  |  |  |  |  |  | that comes bundled with L<Data::Serializer(3)>. | 
| 532 |  |  |  |  |  |  |  | 
| 533 |  |  |  |  |  |  | =head1 EXAMPLES | 
| 534 |  |  |  |  |  |  |  | 
| 535 |  |  |  |  |  |  | =over 4 | 
| 536 |  |  |  |  |  |  |  | 
| 537 |  |  |  |  |  |  | =item  Please see L<Data::Serializer::Cookbook(3)> | 
| 538 |  |  |  |  |  |  |  | 
| 539 |  |  |  |  |  |  | =back | 
| 540 |  |  |  |  |  |  |  | 
| 541 |  |  |  |  |  |  | =head1 METHODS | 
| 542 |  |  |  |  |  |  |  | 
| 543 |  |  |  |  |  |  | =over 4 | 
| 544 |  |  |  |  |  |  |  | 
| 545 |  |  |  |  |  |  | =item B<new> - constructor | 
| 546 |  |  |  |  |  |  |  | 
| 547 |  |  |  |  |  |  | $obj = Data::Serializer->new(); | 
| 548 |  |  |  |  |  |  |  | 
| 549 |  |  |  |  |  |  |  | 
| 550 |  |  |  |  |  |  | $obj = Data::Serializer->new( | 
| 551 |  |  |  |  |  |  | serializer => 'Data::Dumper', | 
| 552 |  |  |  |  |  |  | digester   => 'SHA-256', | 
| 553 |  |  |  |  |  |  | cipher     => 'Blowfish', | 
| 554 |  |  |  |  |  |  | secret     => undef, | 
| 555 |  |  |  |  |  |  | portable   => '1', | 
| 556 |  |  |  |  |  |  | compress   => '0', | 
| 557 |  |  |  |  |  |  | serializer_token => '1', | 
| 558 |  |  |  |  |  |  | options  => {}, | 
| 559 |  |  |  |  |  |  | ); | 
| 560 |  |  |  |  |  |  |  | 
| 561 |  |  |  |  |  |  |  | 
| 562 |  |  |  |  |  |  | B<new> is the constructor object for L<Data::Serializer(3)> objects. | 
| 563 |  |  |  |  |  |  |  | 
| 564 |  |  |  |  |  |  | =over 4 | 
| 565 |  |  |  |  |  |  |  | 
| 566 |  |  |  |  |  |  | =item | 
| 567 |  |  |  |  |  |  |  | 
| 568 |  |  |  |  |  |  | The default I<serializer> is C<Data::Dumper> | 
| 569 |  |  |  |  |  |  |  | 
| 570 |  |  |  |  |  |  | =item | 
| 571 |  |  |  |  |  |  |  | 
| 572 |  |  |  |  |  |  | The default I<digester> is C<SHA-256> | 
| 573 |  |  |  |  |  |  |  | 
| 574 |  |  |  |  |  |  | =item | 
| 575 |  |  |  |  |  |  |  | 
| 576 |  |  |  |  |  |  | The default I<cipher> is C<Blowfish> | 
| 577 |  |  |  |  |  |  |  | 
| 578 |  |  |  |  |  |  | =item | 
| 579 |  |  |  |  |  |  |  | 
| 580 |  |  |  |  |  |  | The default I<secret> is C<undef> | 
| 581 |  |  |  |  |  |  |  | 
| 582 |  |  |  |  |  |  | =item | 
| 583 |  |  |  |  |  |  |  | 
| 584 |  |  |  |  |  |  | The default I<portable> is C<1> | 
| 585 |  |  |  |  |  |  |  | 
| 586 |  |  |  |  |  |  | =item | 
| 587 |  |  |  |  |  |  |  | 
| 588 |  |  |  |  |  |  | The default I<encoding> is C<hex> | 
| 589 |  |  |  |  |  |  |  | 
| 590 |  |  |  |  |  |  | =item | 
| 591 |  |  |  |  |  |  |  | 
| 592 |  |  |  |  |  |  | The default I<compress> is C<0> | 
| 593 |  |  |  |  |  |  |  | 
| 594 |  |  |  |  |  |  | =item | 
| 595 |  |  |  |  |  |  |  | 
| 596 |  |  |  |  |  |  | The default I<compressor> is C<Compress::Zlib> | 
| 597 |  |  |  |  |  |  |  | 
| 598 |  |  |  |  |  |  | =item | 
| 599 |  |  |  |  |  |  |  | 
| 600 |  |  |  |  |  |  | The default I<serializer_token> is C<1> | 
| 601 |  |  |  |  |  |  |  | 
| 602 |  |  |  |  |  |  | =item | 
| 603 |  |  |  |  |  |  |  | 
| 604 |  |  |  |  |  |  | The default I<options> is C<{}> (pass nothing on to serializer) | 
| 605 |  |  |  |  |  |  |  | 
| 606 |  |  |  |  |  |  | =back | 
| 607 |  |  |  |  |  |  |  | 
| 608 |  |  |  |  |  |  | =item B<serialize> - serialize reference | 
| 609 |  |  |  |  |  |  |  | 
| 610 |  |  |  |  |  |  | $serialized = $obj->serialize({a => [1,2,3],b => 5}); | 
| 611 |  |  |  |  |  |  |  | 
| 612 |  |  |  |  |  |  | Serializes the reference specified. | 
| 613 |  |  |  |  |  |  |  | 
| 614 |  |  |  |  |  |  | Will compress if compress is a true value. | 
| 615 |  |  |  |  |  |  |  | 
| 616 |  |  |  |  |  |  | Will encrypt if secret is defined. | 
| 617 |  |  |  |  |  |  |  | 
| 618 |  |  |  |  |  |  | =item B<deserialize> - deserialize reference | 
| 619 |  |  |  |  |  |  |  | 
| 620 |  |  |  |  |  |  | $deserialized = $obj->deserialize($serialized); | 
| 621 |  |  |  |  |  |  |  | 
| 622 |  |  |  |  |  |  | Reverses the process of serialization and returns a copy | 
| 623 |  |  |  |  |  |  | of the original serialized reference. | 
| 624 |  |  |  |  |  |  |  | 
| 625 |  |  |  |  |  |  | =item B<freeze> - synonym for serialize | 
| 626 |  |  |  |  |  |  |  | 
| 627 |  |  |  |  |  |  | $serialized = $obj->freeze({a => [1,2,3],b => 5}); | 
| 628 |  |  |  |  |  |  |  | 
| 629 |  |  |  |  |  |  | =item B<thaw> - synonym for deserialize | 
| 630 |  |  |  |  |  |  |  | 
| 631 |  |  |  |  |  |  | $deserialized = $obj->thaw($serialized); | 
| 632 |  |  |  |  |  |  |  | 
| 633 |  |  |  |  |  |  | =item B<raw_serialize> - serialize reference in raw form | 
| 634 |  |  |  |  |  |  |  | 
| 635 |  |  |  |  |  |  | $serialized = $obj->raw_serialize({a => [1,2,3],b => 5}); | 
| 636 |  |  |  |  |  |  |  | 
| 637 |  |  |  |  |  |  | This is a straight pass through to the underlying serializer, | 
| 638 |  |  |  |  |  |  | nothing else is done. (no encoding, encryption, compression, etc) | 
| 639 |  |  |  |  |  |  |  | 
| 640 |  |  |  |  |  |  | If you desire this functionality you should look at L<Data::Serializer::Raw(3)> instead, it is | 
| 641 |  |  |  |  |  |  | faster and leaner. | 
| 642 |  |  |  |  |  |  |  | 
| 643 |  |  |  |  |  |  | =item B<raw_deserialize> - deserialize reference in raw form | 
| 644 |  |  |  |  |  |  |  | 
| 645 |  |  |  |  |  |  | $deserialized = $obj->raw_deserialize($serialized); | 
| 646 |  |  |  |  |  |  |  | 
| 647 |  |  |  |  |  |  | This is a straight pass through to the underlying serializer, | 
| 648 |  |  |  |  |  |  | nothing else is done. (no encoding, encryption, compression, etc) | 
| 649 |  |  |  |  |  |  |  | 
| 650 |  |  |  |  |  |  | If you desire this functionality you should look at L<Data::Serializer::Raw(3)> instead, it is | 
| 651 |  |  |  |  |  |  | faster and leaner. | 
| 652 |  |  |  |  |  |  |  | 
| 653 |  |  |  |  |  |  | =item B<secret> - specify secret for use with encryption | 
| 654 |  |  |  |  |  |  |  | 
| 655 |  |  |  |  |  |  | $obj->secret('mysecret'); | 
| 656 |  |  |  |  |  |  |  | 
| 657 |  |  |  |  |  |  | Changes setting of secret for the L<Data::Serializer(3)> object.  Can also be set | 
| 658 |  |  |  |  |  |  | in the constructor.  If specified than the object will utilize encryption. | 
| 659 |  |  |  |  |  |  |  | 
| 660 |  |  |  |  |  |  | =item B<portable> - encodes/decodes serialized data | 
| 661 |  |  |  |  |  |  |  | 
| 662 |  |  |  |  |  |  | Uses B<encoding> method to ascii armor serialized data | 
| 663 |  |  |  |  |  |  |  | 
| 664 |  |  |  |  |  |  | Aids in the portability of serialized data. | 
| 665 |  |  |  |  |  |  |  | 
| 666 |  |  |  |  |  |  | =item B<compress> - compression of data | 
| 667 |  |  |  |  |  |  |  | 
| 668 |  |  |  |  |  |  | Compresses serialized data.  Default is not to use it.  Will compress if set to a true value | 
| 669 |  |  |  |  |  |  | $obj->compress(1); | 
| 670 |  |  |  |  |  |  |  | 
| 671 |  |  |  |  |  |  | =item B<raw> - all calls to serializer and deserializer will automatically use raw mode | 
| 672 |  |  |  |  |  |  |  | 
| 673 |  |  |  |  |  |  | Setting this to a true value will force serializer and deserializer to work in raw mode | 
| 674 |  |  |  |  |  |  | (see raw_serializer and raw_deserializer).  The default is for this to be off. | 
| 675 |  |  |  |  |  |  |  | 
| 676 |  |  |  |  |  |  | If you desire this functionality you should look at L<Data::Serializer::Raw(3)> instead, it is | 
| 677 |  |  |  |  |  |  | faster and leaner. | 
| 678 |  |  |  |  |  |  |  | 
| 679 |  |  |  |  |  |  | =item B<serializer> - change the serializer | 
| 680 |  |  |  |  |  |  |  | 
| 681 |  |  |  |  |  |  | Currently supports the following serializers: | 
| 682 |  |  |  |  |  |  |  | 
| 683 |  |  |  |  |  |  | =over 4 | 
| 684 |  |  |  |  |  |  |  | 
| 685 |  |  |  |  |  |  | =item L<Bencode(3)> | 
| 686 |  |  |  |  |  |  |  | 
| 687 |  |  |  |  |  |  | =item L<Convert::Bencode(3)> | 
| 688 |  |  |  |  |  |  |  | 
| 689 |  |  |  |  |  |  | =item L<Convert::Bencode_XS(3)> | 
| 690 |  |  |  |  |  |  |  | 
| 691 |  |  |  |  |  |  | =item L<Config::General(3)> | 
| 692 |  |  |  |  |  |  |  | 
| 693 |  |  |  |  |  |  | =item L<Data::Denter(3)> | 
| 694 |  |  |  |  |  |  |  | 
| 695 |  |  |  |  |  |  | =item L<Data::Dumper(3)> | 
| 696 |  |  |  |  |  |  |  | 
| 697 |  |  |  |  |  |  | =item L<Data::Taxi(3)> | 
| 698 |  |  |  |  |  |  |  | 
| 699 |  |  |  |  |  |  | =item L<FreezeThaw(3)> | 
| 700 |  |  |  |  |  |  |  | 
| 701 |  |  |  |  |  |  | =item L<JSON(3)> | 
| 702 |  |  |  |  |  |  |  | 
| 703 |  |  |  |  |  |  | =item L<JSON::Syck(3)> | 
| 704 |  |  |  |  |  |  |  | 
| 705 |  |  |  |  |  |  | =item L<PHP::Serialization(3)> | 
| 706 |  |  |  |  |  |  |  | 
| 707 |  |  |  |  |  |  | =item L<Storable(3)> | 
| 708 |  |  |  |  |  |  |  | 
| 709 |  |  |  |  |  |  | =item L<XML::Dumper(3)> | 
| 710 |  |  |  |  |  |  |  | 
| 711 |  |  |  |  |  |  | =item L<XML::Simple(3)> | 
| 712 |  |  |  |  |  |  |  | 
| 713 |  |  |  |  |  |  | =item L<YAML(3)> | 
| 714 |  |  |  |  |  |  |  | 
| 715 |  |  |  |  |  |  | =item L<YAML::Syck(3)> | 
| 716 |  |  |  |  |  |  |  | 
| 717 |  |  |  |  |  |  | =back | 
| 718 |  |  |  |  |  |  |  | 
| 719 |  |  |  |  |  |  | Default is to use Data::Dumper. | 
| 720 |  |  |  |  |  |  |  | 
| 721 |  |  |  |  |  |  |  | 
| 722 |  |  |  |  |  |  |  | 
| 723 |  |  |  |  |  |  | Each serializer has its own caveat's about usage especially when dealing with | 
| 724 |  |  |  |  |  |  | cyclical data structures or CODE references.  Please see the appropriate | 
| 725 |  |  |  |  |  |  | documentation in those modules for further information. | 
| 726 |  |  |  |  |  |  |  | 
| 727 |  |  |  |  |  |  | =item B<cipher> - change the cipher method | 
| 728 |  |  |  |  |  |  |  | 
| 729 |  |  |  |  |  |  | Utilizes L<Crypt::CBC(3)> and can support any cipher method that it supports. | 
| 730 |  |  |  |  |  |  |  | 
| 731 |  |  |  |  |  |  | =item B<digester> - change digesting method | 
| 732 |  |  |  |  |  |  |  | 
| 733 |  |  |  |  |  |  | Uses L<Digest(3)> so can support any digesting method that it supports.  Digesting | 
| 734 |  |  |  |  |  |  | function is used internally by the encryption routine as part of data verification. | 
| 735 |  |  |  |  |  |  |  | 
| 736 |  |  |  |  |  |  | =item B<compressor> - changes compresing module | 
| 737 |  |  |  |  |  |  |  | 
| 738 |  |  |  |  |  |  | Currently L<Compress::Zlib(3)> and L<Compress::PPMd(3)> are the only options | 
| 739 |  |  |  |  |  |  |  | 
| 740 |  |  |  |  |  |  | =item B<encoding> - change encoding method | 
| 741 |  |  |  |  |  |  |  | 
| 742 |  |  |  |  |  |  | Encodes data structure in ascii friendly manner.  Currently the only valid options | 
| 743 |  |  |  |  |  |  | are hex, or b64. | 
| 744 |  |  |  |  |  |  |  | 
| 745 |  |  |  |  |  |  | The b64 option uses Base64 encoding provided by L<MIME::Base64(3)>, but strips out newlines. | 
| 746 |  |  |  |  |  |  |  | 
| 747 |  |  |  |  |  |  | =item B<serializer_token> - add usage hint to data | 
| 748 |  |  |  |  |  |  |  | 
| 749 |  |  |  |  |  |  | L<Data::Serializer(3)> prepends a token that identifies what was used to process its data. | 
| 750 |  |  |  |  |  |  | This is used internally to allow runtime determination of how to extract serialized | 
| 751 |  |  |  |  |  |  | data.  Disabling this feature is not recommended.   (Use L<Data::Serializer::Raw(3)> instead). | 
| 752 |  |  |  |  |  |  |  | 
| 753 |  |  |  |  |  |  | =item B<options> - pass options through to underlying serializer | 
| 754 |  |  |  |  |  |  |  | 
| 755 |  |  |  |  |  |  | Currently is only supported by L<Config::General(3)>, and L<XML::Dumper(3)>. | 
| 756 |  |  |  |  |  |  |  | 
| 757 |  |  |  |  |  |  | my $obj = Data::Serializer->new(serializer => 'Config::General', | 
| 758 |  |  |  |  |  |  | options    => { | 
| 759 |  |  |  |  |  |  | -LowerCaseNames       => 1, | 
| 760 |  |  |  |  |  |  | -UseApacheInclude     => 1, | 
| 761 |  |  |  |  |  |  | -MergeDuplicateBlocks => 1, | 
| 762 |  |  |  |  |  |  | -AutoTrue             => 1, | 
| 763 |  |  |  |  |  |  | -InterPolateVars      => 1 | 
| 764 |  |  |  |  |  |  | }, | 
| 765 |  |  |  |  |  |  | ) or die "$!\n"; | 
| 766 |  |  |  |  |  |  |  | 
| 767 |  |  |  |  |  |  | or | 
| 768 |  |  |  |  |  |  |  | 
| 769 |  |  |  |  |  |  | my $obj = Data::Serializer->new(serializer => 'XML::Dumper', | 
| 770 |  |  |  |  |  |  | options    => { dtd => 1, } | 
| 771 |  |  |  |  |  |  | ) or die "$!\n"; | 
| 772 |  |  |  |  |  |  |  | 
| 773 |  |  |  |  |  |  | =item B<store> - serialize data and write it to a file (or file handle) | 
| 774 |  |  |  |  |  |  |  | 
| 775 |  |  |  |  |  |  | $obj->store({a => [1,2,3],b => 5},$file, [$mode, $perm]); | 
| 776 |  |  |  |  |  |  |  | 
| 777 |  |  |  |  |  |  | or | 
| 778 |  |  |  |  |  |  |  | 
| 779 |  |  |  |  |  |  | $obj->store({a => [1,2,3],b => 5},$fh); | 
| 780 |  |  |  |  |  |  |  | 
| 781 |  |  |  |  |  |  |  | 
| 782 |  |  |  |  |  |  | Serializes the reference specified using the B<serialize> method | 
| 783 |  |  |  |  |  |  | and writes it out to the specified file or filehandle. | 
| 784 |  |  |  |  |  |  |  | 
| 785 |  |  |  |  |  |  | If a file path is specified you may specify an optional mode and permission as the | 
| 786 |  |  |  |  |  |  | next two arguments.  See L<IO::File> for examples. | 
| 787 |  |  |  |  |  |  |  | 
| 788 |  |  |  |  |  |  | Trips an exception if it is unable to write to the specified file. | 
| 789 |  |  |  |  |  |  |  | 
| 790 |  |  |  |  |  |  | =item B<retrieve> - read data from file (or file handle) and return it after deserialization | 
| 791 |  |  |  |  |  |  |  | 
| 792 |  |  |  |  |  |  | my $ref = $obj->retrieve($file); | 
| 793 |  |  |  |  |  |  |  | 
| 794 |  |  |  |  |  |  | or | 
| 795 |  |  |  |  |  |  |  | 
| 796 |  |  |  |  |  |  | my $ref = $obj->retrieve($fh); | 
| 797 |  |  |  |  |  |  |  | 
| 798 |  |  |  |  |  |  | Reads first line of supplied file or filehandle and returns it deserialized. | 
| 799 |  |  |  |  |  |  |  | 
| 800 |  |  |  |  |  |  | =back | 
| 801 |  |  |  |  |  |  |  | 
| 802 |  |  |  |  |  |  | =head1 AUTHOR | 
| 803 |  |  |  |  |  |  |  | 
| 804 |  |  |  |  |  |  | Neil Neely <F<neil@neely.cx>>. | 
| 805 |  |  |  |  |  |  |  | 
| 806 |  |  |  |  |  |  | Feature requests are certainly welcome. | 
| 807 |  |  |  |  |  |  |  | 
| 808 |  |  |  |  |  |  | http://neil-neely.blogspot.com/ | 
| 809 |  |  |  |  |  |  |  | 
| 810 |  |  |  |  |  |  | =head1 BUGS | 
| 811 |  |  |  |  |  |  |  | 
| 812 |  |  |  |  |  |  | Please report all bugs here: | 
| 813 |  |  |  |  |  |  |  | 
| 814 |  |  |  |  |  |  | http://rt.cpan.org/Public/Dist/Display.html?Name=Data-Serializer | 
| 815 |  |  |  |  |  |  |  | 
| 816 |  |  |  |  |  |  | =head1 TODO | 
| 817 |  |  |  |  |  |  |  | 
| 818 |  |  |  |  |  |  | Extend the persistent framework.  Perhaps  L<Persistent::Base(3)> framework | 
| 819 |  |  |  |  |  |  | would be useful to explore further.  Volunteers for putting this together | 
| 820 |  |  |  |  |  |  | would be welcome. | 
| 821 |  |  |  |  |  |  |  | 
| 822 |  |  |  |  |  |  |  | 
| 823 |  |  |  |  |  |  |  | 
| 824 |  |  |  |  |  |  | =head1 COPYRIGHT AND LICENSE | 
| 825 |  |  |  |  |  |  |  | 
| 826 |  |  |  |  |  |  | Copyright (c) 2001-2020 Neil Neely.  All rights reserved. | 
| 827 |  |  |  |  |  |  |  | 
| 828 |  |  |  |  |  |  | This library is free software; you can redistribute it and/or modify | 
| 829 |  |  |  |  |  |  | it under the same terms as Perl itself, either Perl version 5.8.2 or, | 
| 830 |  |  |  |  |  |  | at your option, any later version of Perl 5 you may have available. | 
| 831 |  |  |  |  |  |  |  | 
| 832 |  |  |  |  |  |  |  | 
| 833 |  |  |  |  |  |  | See http://www.perl.com/language/misc/Artistic.html | 
| 834 |  |  |  |  |  |  |  | 
| 835 |  |  |  |  |  |  | =head1 ACKNOWLEDGEMENTS | 
| 836 |  |  |  |  |  |  |  | 
| 837 |  |  |  |  |  |  | Gurusamy Sarathy and Raphael Manfredi for writing L<MLDBM(3)>, | 
| 838 |  |  |  |  |  |  | the module which inspired the creation of L<Data::Serializer(3)>. | 
| 839 |  |  |  |  |  |  |  | 
| 840 |  |  |  |  |  |  | And thanks to all of you who have provided the feedback | 
| 841 |  |  |  |  |  |  | that has improved this module over the years. | 
| 842 |  |  |  |  |  |  |  | 
| 843 |  |  |  |  |  |  | In particular I'd like to thank Florian Helmberger, for the | 
| 844 |  |  |  |  |  |  | numerous suggestions and bug fixes. | 
| 845 |  |  |  |  |  |  |  | 
| 846 |  |  |  |  |  |  | =head1 DEDICATION | 
| 847 |  |  |  |  |  |  |  | 
| 848 |  |  |  |  |  |  | This module is dedicated to my beautiful wife Erica. | 
| 849 |  |  |  |  |  |  |  | 
| 850 |  |  |  |  |  |  | =head1 REPOSITORY | 
| 851 |  |  |  |  |  |  |  | 
| 852 |  |  |  |  |  |  | L<http://github.com/neilneely/Data-Serializer/> | 
| 853 |  |  |  |  |  |  |  | 
| 854 |  |  |  |  |  |  | =head1 SEE ALSO | 
| 855 |  |  |  |  |  |  |  | 
| 856 |  |  |  |  |  |  | =over 4 | 
| 857 |  |  |  |  |  |  |  | 
| 858 |  |  |  |  |  |  | =item L<Bencode(3)> | 
| 859 |  |  |  |  |  |  |  | 
| 860 |  |  |  |  |  |  | =item L<Convert::Bencode(3)> | 
| 861 |  |  |  |  |  |  |  | 
| 862 |  |  |  |  |  |  | =item L<Convert::Bencode_XS(3)> | 
| 863 |  |  |  |  |  |  |  | 
| 864 |  |  |  |  |  |  | =item L<Config::General(3)> | 
| 865 |  |  |  |  |  |  |  | 
| 866 |  |  |  |  |  |  | =item L<Data::Denter(3)> | 
| 867 |  |  |  |  |  |  |  | 
| 868 |  |  |  |  |  |  | =item L<Data::Dumper(3)> | 
| 869 |  |  |  |  |  |  |  | 
| 870 |  |  |  |  |  |  | =item L<Data::Taxi(3)> | 
| 871 |  |  |  |  |  |  |  | 
| 872 |  |  |  |  |  |  | =item L<FreezeThaw(3)> | 
| 873 |  |  |  |  |  |  |  | 
| 874 |  |  |  |  |  |  | =item L<JSON(3)> | 
| 875 |  |  |  |  |  |  |  | 
| 876 |  |  |  |  |  |  | =item L<JSON::Syck(3)> | 
| 877 |  |  |  |  |  |  |  | 
| 878 |  |  |  |  |  |  | =item L<PHP::Serialization(3)> | 
| 879 |  |  |  |  |  |  |  | 
| 880 |  |  |  |  |  |  | =item L<Storable(3)> | 
| 881 |  |  |  |  |  |  |  | 
| 882 |  |  |  |  |  |  | =item L<XML::Dumper(3)> | 
| 883 |  |  |  |  |  |  |  | 
| 884 |  |  |  |  |  |  | =item L<XML::Simple(3)> | 
| 885 |  |  |  |  |  |  |  | 
| 886 |  |  |  |  |  |  | =item L<YAML(3)> | 
| 887 |  |  |  |  |  |  |  | 
| 888 |  |  |  |  |  |  | =item L<YAML::Syck(3)> | 
| 889 |  |  |  |  |  |  |  | 
| 890 |  |  |  |  |  |  | =item L<Compress::Zlib(3)> | 
| 891 |  |  |  |  |  |  |  | 
| 892 |  |  |  |  |  |  | =item L<Compress::PPMd(3)> | 
| 893 |  |  |  |  |  |  |  | 
| 894 |  |  |  |  |  |  | =item L<Digest(3)> | 
| 895 |  |  |  |  |  |  |  | 
| 896 |  |  |  |  |  |  | =item L<Digest::SHA(3)> | 
| 897 |  |  |  |  |  |  |  | 
| 898 |  |  |  |  |  |  | =item L<Crypt::CBC(3)> | 
| 899 |  |  |  |  |  |  |  | 
| 900 |  |  |  |  |  |  | =item L<MIME::Base64(3)> | 
| 901 |  |  |  |  |  |  |  | 
| 902 |  |  |  |  |  |  | =item L<IO::File(3)> | 
| 903 |  |  |  |  |  |  |  | 
| 904 |  |  |  |  |  |  | =item L<Data::Serializer::Config::Wrest(3)> - adds supports for L<Config::Wrest(3)> | 
| 905 |  |  |  |  |  |  |  | 
| 906 |  |  |  |  |  |  | =back | 
| 907 |  |  |  |  |  |  |  | 
| 908 |  |  |  |  |  |  | =cut |