File Coverage

blib/lib/WDDX/Struct.pm
Criterion Covered Total %
statement 6 107 5.6
branch 0 44 0.0
condition 0 15 0.0
subroutine 2 22 9.0
pod n/a
total 8 188 4.2


line stmt bran cond sub pod time code
1             #!/usr/bin/perl -w
2             #
3             # $Id: Struct.pm,v 1.2 2003/10/28 16:41:12 andy Exp $
4             #
5             # This code is copyright 1999-2000 by Scott Guelich
6             # and is distributed according to the same conditions as Perl itself
7             # Please visit http://www.scripted.com/wddx/ for more information
8             #
9              
10             package WDDX::Struct;
11              
12             # Auto-inserted by build scripts
13             $VERSION = "1.01";
14              
15 1     1   1872 use strict;
  1         2  
  1         32  
16 1     1   5 use Carp;
  1         2  
  1         1535  
17              
18             require WDDX;
19              
20             { my $i_hate_the_w_flag_sometimes = [
21             $WDDX::PACKET_HEADER,
22             $WDDX::PACKET_FOOTER,
23             $WDDX::Struct::VERSION
24             ] }
25              
26             1;
27              
28              
29             #/-----------------------------------------------------------------------
30             # Public Methods
31             #
32              
33             sub new {
34 0     0     my( $class, $hashref ) = @_;
35            
36             croak "You must supply a hash ref when creating a new $class object.\n"
37 0 0         unless eval { %$hashref || 1 };
  0 0          
38            
39 0           foreach ( values %$hashref ) {
40             croak "Each element of the supplied hash must be a WDDX data object.\n"
41 0 0         unless eval { $_->can( "_serialize" ) };
  0            
42             }
43            
44 0           my $self = {
45             value => $hashref,
46             };
47            
48 0           bless $self, $class;
49 0           return $self;
50             }
51              
52             sub type {
53 0     0     return "hash";
54             }
55              
56             sub as_packet {
57 0     0     my( $self ) = @_;
58 0           my $output = $WDDX::PACKET_HEADER .
59             $self->_serialize .
60             $WDDX::PACKET_FOOTER;
61             }
62              
63              
64             sub as_hashref {
65 0     0     my( $self ) = @_;
66 0           return $self->_deserialize;
67             }
68              
69              
70             sub as_javascript {
71 0     0     my( $self, $js_var ) = @_;
72 0           my $hashref = $self->{value};
73 0           my $output = "$js_var=new Object;";
74            
75 0           while ( my( $key, $val ) = each %$hashref ) {
76 0           $output .= $val->as_javascript( $js_var . "[\"$key\"]" );
77             }
78 0           return $output;
79             }
80              
81              
82             #/-----------------------------------------------------------------------
83             # Other Public Methods
84             #
85              
86              
87             sub get_element {
88 0     0     my( $self, $key ) = @_;
89 0           return $self->{value}{$key};
90             }
91              
92              
93             # Method alias
94             *get = *get = \&get_element;
95              
96              
97             sub set {
98 0     0     my( $self, %pairs ) = @_;
99 0           my( $key, $value );
100 0           while ( ( $key, $value ) = each %pairs ) {
101             croak "The value of each pair must be a WDDX data object.\n"
102 0 0         unless eval { $value->can( "_serialize" ) };
  0            
103 0           $self->{value}{$key} = $value;
104             }
105             }
106              
107              
108             sub delete {
109 0     0     my( $self, $key ) = @_;
110 0           delete $self->{value}{$key};
111             }
112              
113              
114             sub keys {
115 0     0     my( $self ) = @_;
116             return wantarray ?
117 0           ( keys %{ $self->{value} } ) :
  0            
118 0 0         scalar keys %{ $self->{value} };
119             }
120              
121              
122             sub values {
123 0     0     my( $self ) = @_;
124             return wantarray ?
125 0           ( values %{ $self->{value} } ) :
  0            
126 0 0         scalar values %{ $self->{value} };
127             }
128              
129              
130             #/-----------------------------------------------------------------------
131             # Private Methods
132             #
133              
134             sub is_parser {
135 0     0     return 0;
136             }
137              
138              
139             sub _serialize {
140 0     0     my( $self ) = @_;
141 0           my $hashref = $self->{value};
142 0           my $output = "";
143            
144 0           foreach ( CORE::keys %$hashref ) {
145 0           $output .= "";
146 0           $output .= $hashref->{$_}->_serialize;
147 0           $output .= "";
148             }
149            
150 0           $output .= "";
151 0           return $output;
152             }
153              
154              
155             sub _deserialize {
156 0     0     my( $self ) = @_;
157 0           my $wddx_hashref = $self->{value};
158 0           my %hash;
159            
160 0           foreach ( CORE::keys %$wddx_hashref ) {
161 0           $hash{$_} = $wddx_hashref->{$_}->_deserialize;
162             }
163 0           return \%hash;
164             }
165              
166             #/-----------------------------------------------------------------------
167             # Parsing Code
168             #
169              
170             package WDDX::Struct::Parser;
171              
172              
173             sub new {
174 0     0     my $class = shift;
175            
176 0           my $self = {
177             value => {},
178             curr_key => undef,
179             seen_structs => 0,
180             };
181 0           return bless $self, $class;
182             }
183              
184              
185             sub start_tag {
186 0     0     my( $self, $element, $attribs ) = @_;
187 0           my $parse_var = $self->parse_var;
188            
189 0 0 0       unless ( $element eq "struct" and not $self->{seen_structs}++ ) {
190 0 0 0       if ( $element eq "var" and $self->{seen_structs} == 1 ) {
191 0           $self->add( $attribs->{name} );
192             }
193             else {
194 0 0         unless ( $parse_var ) {
195 0 0         $parse_var = WDDX::Parser->create_var( $element ) or
196             die "Expecting some data element (e.g., ), " .
197             "found: <$element>\n";
198 0           $self->parse_var( $parse_var );
199             }
200 0           $parse_var->start_tag( $element, $attribs );
201             }
202             }
203            
204 0           return $self;
205             }
206              
207              
208             sub end_tag {
209 0     0     my( $self, $element ) = @_;
210 0           my $parse_var = $self->parse_var;
211            
212 0 0 0       if ( $element eq "struct" and not --$self->{seen_structs} ) {
    0 0        
213             # Clean up non-object pairs used for case-insensitive checks
214 0           foreach ( keys %{ $self->{value} } ) {
  0            
215 0 0         delete $self->{value}{$_} unless ref $self->{value}{$_};
216             }
217 0           $self = new WDDX::Struct( $self->{value} );
218             }
219             elsif ( $element eq "var" and $self->{seen_structs} == 1 ) {
220 0           $self->{curr_key} = undef;
221             }
222             else {
223 0 0         unless ( $parse_var ) {
224             # XML::Parser should actually catch this
225 0           die "Found before <$element>\n";
226             }
227 0           $self->parse_var( $parse_var->end_tag( $element ) );
228             }
229            
230 0           return $self;
231             }
232              
233              
234             sub append_data {
235 0     0     my( $self, $data ) = @_;
236 0           my $parse_var = $self->parse_var;
237            
238 0 0         if ( $parse_var ) {
    0          
239 0           $parse_var->append_data( $data );
240             }
241             elsif ( $data =~ /\S/ ) {
242 0           die "No data is allowed within elements outside of " .
243             "other elements\n";
244             }
245             }
246              
247              
248             sub is_parser {
249 0     0     return 1;
250             }
251              
252              
253             sub parse_var {
254 0     0     my( $self, $var ) = @_;
255 0           my $curr_key = $self->{curr_key};
256            
257 0 0         unless ( defined $curr_key ) {
258 0           return undef;
259             }
260            
261 0 0         if ( defined $var ) {
262 0 0         die "Missing element in \n" unless defined $curr_key;
263 0           $self->{value}{$curr_key} = $var;
264             }
265 0           my $curr_var = $self->{value}{$curr_key};
266 0 0 0       return ( ref $curr_var && $curr_var->is_parser ) ? $curr_var : undef;
267             }
268              
269              
270             sub add {
271 0     0     my( $self, $name ) = @_;
272 0           my $hash = $self->{value};
273            
274 0           $self->{curr_key} = $name;
275            
276             # Duplicates should be replaced by later values; case-insensitive
277 0 0         if ( exists $hash->{lc $name} ) {
278 0           delete $hash->{ $hash->{lc $name} };
279             }
280            
281 0 0         $hash->{lc $name} = $name unless $name eq lc $name;
282 0           $hash->{$name} = undef;
283             }