File Coverage

blib/lib/Cake/Utils/Serializer.pm
Criterion Covered Total %
statement 15 101 14.8
branch 0 32 0.0
condition 0 14 0.0
subroutine 5 16 31.2
pod 0 7 0.0
total 20 170 11.7


line stmt bran cond sub pod time code
1             package Cake::Utils::Serializer;
2 8     8   41 use strict;
  8         9  
  8         333  
3 8     8   38 use warnings;
  8         14  
  8         173  
4 8     8   36 use Carp;
  8         12  
  8         381  
5 8     8   38 use Data::Dumper;
  8         19  
  8         10194  
6            
7             sub new {
8 0     0 0   my $class = shift;
9 0           return bless({data => shift},$class);
10             }
11            
12 0     0 0   sub true {'true' }
13 0     0 0   sub false { undef }
14 0     0 0   sub null { 'null' }
15            
16             ##from json to perl
17             sub to_perl {
18 0     0 0   my $self = shift;
19             #remove comments
20 0           $self->{data} =~ s/\n+\s+/\n/g;
21 0           $self->{data} =~ s/[\n\s+]\/\*.*?\*\/|[\n\s+]\/\/.*?\n/\n/gs;
22 0           my $data = $self->{data};
23            
24 0 0         if ($data){
25 0           $data =~ s/(["'])(?:\s?)+:/$1=>/g;
26 0           $data =~ s/[^\\]([\@\$].*?\s*)/ \\$1/g;
27             }
28            
29 0           my $str = eval "$data";
30 0 0         croak "invalid json" if $@;
31            
32             #return bless($str,'Cake::Utils::Serializer::Base');
33            
34 0           return $str;
35 0           return _stringify($data);
36             }
37            
38             sub to_json {
39 0     0 0   my $self = shift;
40 0           my $trim = shift;
41 0           my $perl_object = $self->{data};
42 0           my $dumper = Data::Dumper->new([ _stringify($perl_object,'encode') ]);
43 0           $dumper->Purity(1)->Terse(1)->Indent(1)->Deparse(1)->Pair(' : ');
44 0           my $json = $dumper->Dump;
45 0 0         $json =~ s/(?:'((.*?)[^\\'])?')/$1 ? '"'.$1.'"' : '""'/ge;
  0            
46 0           $json =~ s/\\'/'/g;
47 0           $json =~ s/\\\\/\\/g;
48 0           $json =~ s/(\\x\{(.*?)\})/chr(hex($2))/ge;
  0            
49 0 0         if ($trim){
50 0           $json =~ s/\n//g;
51 0           $json =~ s/\s+//g;
52             }
53 0           return $json;
54             }
55            
56            
57             sub validate_json {
58            
59 0     0 0   my $self = shift;
60 0           my $data = $self->{data};
61 0           eval "$data";
62             ##fastest way to check valid json.. I guess!!
63 0           $data =~ s/"(\\.|[^"\\])*"//g;
64 0 0 0       if ( $data =~ m/[^,:{}\[\]0-9.\-+Eaeflnr-u \n\r\t]/g && $@){
65 0           croak('invalid json string');
66             }
67             }
68            
69            
70             sub _stringify {
71 0     0     my $hash = shift;
72 0   0       my $type = shift || 'decode';
73 0           my $action = {
74             decode => \&_decode_string,
75             encode => \&_encode_string,
76             };
77            
78 0 0         if (!ref $hash){
79 0           return $action->{$type}($hash);
80             }
81            
82 0           my $newhash = {};
83 0           my $array = 0;
84 0           my $loop;
85            
86             #ref $hash eq 'ARRAY' ? $loop->{array} = $hash : $loop = $hash;
87 0 0         if (ref $hash eq 'ARRAY') {
88 0           $loop->{array} = $hash;
89 0           $array = 1;
90             } else {
91 0           $loop = $hash
92             }
93            
94 0           while (my ($key,$value) = each (%{$loop}) ) {
  0            
95 0 0         if (ref $value eq 'HASH'){
    0          
96 0           $newhash->{$key} = _stringify($value,$type);
97             } elsif (ref $value eq 'ARRAY'){
98 0           push @{$newhash->{$key}}, map { _stringify($_,$type) } @{$value};
  0            
  0            
  0            
99             } else {
100 0           $newhash->{$key} = $action->{$type}->($value);
101             }
102             }
103 0 0         return !$array ? $newhash : $newhash->{array};
104             }
105            
106            
107             sub _decode_string {
108 0     0     my $str = shift;
109 0 0         return '' if !$str;
110 0           my @search = ('\\\\', '\\n', '\\t', '\\r', '\\b', '\\f', '\"');
111 0           my @replace = ('\\', "\n", "\t", "\r", "\b", "\f", '"');
112 0           map { $str =~ s/\Q$search[$_]/$replace[$_]/ } (0..$#search);
  0            
113 0           return $str;
114             }
115            
116            
117             sub _encode_string {
118 0     0     my $str = shift;
119 0 0 0       return 0 if $str && $str =~ /^\d$/ && $str == 0;
      0        
120 0 0         return '' if !$str;
121 0           my @search = ('\\', "\n", "\t", "\r", "\b", "\f", '"');
122 0           my @replace = ('\\\\', '\\n', '\\t', '\\r', '\\b', '\\f', '\"');
123 0           map { $str =~ s/\Q$search[$_]/$replace[$_]/g } (0..$#search);
  0            
124 0           return $str;
125             }
126            
127             package Cake::Utils::Serializer::Base;
128 8     8   60 use Data::Dumper;
  8         16  
  8         1572  
129             our $AUTOLOAD;
130             sub AUTOLOAD {
131 0     0     my $self = shift;
132 0           my $index = shift;
133 0           my $sub = $AUTOLOAD;
134            
135 0           $sub =~ s/.*:://;
136 0           my $val = $self->{$sub};
137            
138 0 0         return undef if (!defined $val);
139            
140 0 0 0       if ($index && ref $val eq 'ARRAY'){
141 0           $val = $val->[$index];
142             }
143            
144 0 0         if (ref $val){
145 0           return bless($val,__PACKAGE__);
146             } else {
147 0           return $val;
148             }
149             }
150            
151             1;
152            
153            
154             __END__