File Coverage

lib/App/Serializer/Ini.pm
Criterion Covered Total %
statement 42 67 62.6
branch 17 40 42.5
condition 2 6 33.3
subroutine 7 8 87.5
pod 2 3 66.6
total 70 124 56.4


line stmt bran cond sub pod time code
1              
2             #############################################################################
3             ## $Id: Ini.pm 6783 2006-08-11 17:43:28Z spadkins $
4             #############################################################################
5              
6             package App::Serializer::Ini;
7             $VERSION = (q$Revision: 6783 $ =~ /(\d[\d\.]*)/)[0]; # VERSION numbers generated by svn
8              
9 1     1   6 use App;
  1         2  
  1         23  
10 1     1   579 use App::Serializer;
  1         6  
  1         140  
11              
12             @ISA = ( "App::Serializer" );
13              
14 1     1   6 use App::Reference;
  1         3  
  1         20  
15              
16 1     1   5 use strict;
  1         2  
  1         951  
17              
18             =head1 NAME
19              
20             App::Serializer::Ini - Interface for serialization and deserialization
21              
22             =head1 SYNOPSIS
23              
24             use App;
25              
26             $context = App->context();
27             $serializer = $context->service("Serializer"); # or ...
28             $serializer = $context->serializer();
29             $data = {
30             an => 'arbitrary',
31             collection => [ 'of', 'data', ],
32             of => {
33             arbitrary => 'depth',
34             },
35             };
36             $inidata = $serializer->serialize($data);
37             $data = $serializer->deserialize($inidata);
38             print $serializer->dump($data), "\n";
39              
40             =head1 DESCRIPTION
41              
42             A Serializer allows you to serialize a structure of data
43             of arbitrary depth to a scalar and deserialize it back to the
44             structure.
45              
46             The Ini serializer reads and writes data which conforms to
47             the standards of Windows INI files.
48              
49             =cut
50              
51             #############################################################################
52             # CLASS
53             #############################################################################
54              
55             =head1 Class: App::Serializer::Ini
56              
57             * Throws: App::Exception::Serializer
58             * Since: 0.01
59              
60             =head2 Design
61              
62             The class is entirely made up of static (class) methods.
63             However, they are each intended to be
64             called as methods on the instance itself.
65              
66             =cut
67              
68             #############################################################################
69             # CONSTRUCTOR METHODS
70             #############################################################################
71              
72             =head1 Constructor Methods:
73              
74             =cut
75              
76             #############################################################################
77             # new()
78             #############################################################################
79              
80             =head2 new()
81              
82             The constructor is inherited from
83             L|App::Service/"new()">.
84              
85             =cut
86              
87             #############################################################################
88             # PUBLIC METHODS
89             #############################################################################
90              
91             =head1 Public Methods:
92              
93             =cut
94              
95             #############################################################################
96             # serialize()
97             #############################################################################
98              
99             =head2 serialize()
100              
101             * Signature: $inidata = $serializer->serialize($data);
102             * Param: $data ref
103             * Return: $inidata text
104             * Throws: App::Exception::Serializer
105             * Since: 0.01
106              
107             Sample Usage:
108              
109             $context = App->context();
110             $serializer = $context->service("Serializer"); # or ...
111             $serializer = $context->serializer();
112             $data = {
113             an => 'arbitrary',
114             collection => [ 'of', 'data', ],
115             of => {
116             arbitrary => 'depth',
117             },
118             };
119             $inidata = $serializer->serialize($data);
120              
121             =cut
122              
123             sub serialize {
124 1     1 1 8 my ($self, $data) = @_;
125 1         6 $self->_serialize($data, "");
126             }
127              
128             sub _serialize {
129 18     18   33 my ($self, $data, $section) = @_;
130 18         20 my ($section_data, $idx, $key, $elem);
131 18 50       46 if (ref($data) eq "ARRAY") {
    50          
132 0         0 for ($idx = 0; $idx <= $#$data; $idx++) {
133 0         0 $elem = $data->[$idx];
134 0 0       0 if (!ref($elem)) {
135 0 0 0     0 $section_data .= "[$section]\n" if (!$section_data && $section);
136 0         0 $section_data .= "$idx = $elem\n";
137             }
138             }
139 0         0 for ($idx = 0; $idx <= $#$data; $idx++) {
140 0         0 $elem = $data->[$idx];
141 0 0       0 if (ref($elem)) {
142 0 0       0 $section_data .= $self->_serialize($elem, $section ? "$section.$idx" : $idx);
143             }
144             }
145             }
146             elsif (ref($data)) {
147 18         67 foreach $key (sort keys %$data) {
148 38         50 $elem = $data->{$key};
149 38 100       72 if (!ref($elem)) {
150 21 100 66     74 $section_data .= "[$section]\n" if (!$section_data && $section);
151 21         47 $section_data .= "$key = $elem\n";
152             }
153             }
154 18         50 foreach $key (sort keys %$data) {
155 38         54 $elem = $data->{$key};
156 38 100       82 if (ref($elem)) {
157 17 100       57 $section_data .= $self->_serialize($elem, $section ? "$section.$key" : $key);
158             }
159             }
160             }
161              
162 18         59 return $section_data;
163             }
164              
165             #############################################################################
166             # deserialize()
167             #############################################################################
168              
169             =head2 deserialize()
170              
171             * Signature: $data = $serializer->deserialize($inidata);
172             * Signature: $data = App::Serializer->deserialize($inidata);
173             * Param: $data ref
174             * Return: $inidata text
175             * Throws: App::Exception::Serializer
176             * Since: 0.01
177              
178             Sample Usage:
179              
180             $context = App->context();
181             $serializer = $context->service("Serializer"); # or ...
182             $serializer = $context->serializer();
183             $data = $serializer->deserialize($inidata);
184             print $serializer->dump($data), "\n";
185              
186             =cut
187              
188             sub deserializex {
189 0     0 0 0 my ($self, $inidata) = @_;
190 0         0 my ($data, $r, @inidata, $line, $branch_name, $branch, $attrib, $value, $idx);
191              
192 0         0 $r = App::Reference->new(); # dummy ref (shorthand for static calls)
193 0         0 $data = {};
194              
195 0         0 foreach $line (split(/\n/, $inidata)) {
196 0 0       0 next if ($line =~ /^;/); # ignore comments
197 0 0       0 next if ($line =~ /^#/); # ignore comments
198 0 0       0 if ($line =~ /^\[([^\[\]]+)\] *$/) { # i.e. [Repository.default]
    0          
199 0         0 $branch_name = $1;
200 0         0 $branch = $r->get_branch($branch_name,1,$data);
201             }
202             elsif ($line =~ /^ *([^ =]+) *= *(.*)$/) {
203 0         0 $attrib = $1;
204 0         0 $value = $2;
205 0 0       0 if ($branch) {
206 0         0 $r->set($attrib, $value, $branch);
207             }
208             else {
209 0         0 $r->set($attrib, $value, $data);
210             }
211             }
212             }
213              
214 0         0 return $data;
215             }
216              
217             sub deserialize {
218 2     2 1 2332 my ($self, $inidata) = @_;
219 2         3 my ($data, $r, $line, $attrib_base, $attrib, $value);
220              
221 2         14 $r = App::Reference->new(); # dummy ref (shorthand for static calls)
222 2         6 $data = {};
223              
224 2         4 $attrib_base = "";
225 2         35 foreach $line (split(/\n/, $inidata)) {
226 78 50       171 next if ($line =~ /^;/); # ignore comments
227 78 50       138 next if ($line =~ /^#/); # ignore comments
228 78 100       211 if ($line =~ /^\[([^\[\]]+)\] *$/) { # i.e. [Repository.default]
229 24         44 $attrib_base = $1;
230             }
231 78 100       290 if ($line =~ /^ *([^ =]+) *= *(.*)$/) {
232 42 50       130 $attrib = $attrib_base ? "$attrib_base.$1" : $1;
233 42         66 $value = $2;
234 42         116 $r->set($attrib, $value, $data);
235             }
236             }
237              
238 2         18 return $data;
239             }
240              
241             #############################################################################
242             # dump()
243             #############################################################################
244              
245             =head2 dump()
246              
247             The constructor is inherited from
248             L|App::Serializer/"dump()">.
249              
250             =head1 ACKNOWLEDGEMENTS
251              
252             * Author: Stephen Adkins
253             * License: This is free software. It is licensed under the same terms as Perl itself.
254              
255             =head1 SEE ALSO
256              
257             L|App::Context>,
258             L|App::Service>
259              
260             =cut
261              
262             1;
263