File Coverage

blib/lib/XML/ExtOn/TieAttrs.pm
Criterion Covered Total %
statement 116 116 100.0
branch 18 22 81.8
condition 11 13 84.6
subroutine 20 20 100.0
pod 1 5 20.0
total 166 176 94.3


line stmt bran cond sub pod time code
1             package XML::ExtOn::TieAttrs;
2              
3             =head1 NAME
4              
5             XML::ExtOn::TieAttrs
6              
7             =head1 SYNOPSIS
8              
9             use XML::ExtOn::TieAttrs;
10             tie %hasha, 'XML::ExtOn::TieAttrs', \%hash1, default=>;
11              
12             =head1 DESCRIPTION
13              
14            
15            
16             =cut
17              
18 9     9   88275 use strict;
  9         18  
  9         297  
19 9     9   43 use warnings;
  9         19  
  9         205  
20 9     9   45 use strict;
  9         18  
  9         260  
21 9     9   53 use Carp;
  9         26  
  9         520  
22 9     9   47 use Data::Dumper;
  9         20  
  9         2149  
23             require Tie::Hash;
24             @XML::ExtOn::TieAttrs::ISA = qw(Tie::StdHash);
25             $XML::ExtOn::TieAttrs::VERSION = '0.01';
26              
27             sub attr_from_sax2 {
28 6   50 6 0 16 my $sax_attr = shift || {};
29 6         11 my %res = ();
30 6         28 while ( my ( $key, $value ) = each %$sax_attr ) {
31 6         21 my ( $prefix, $name, $ns_uri ) =
32 6         10 @{$value}{qw/ Prefix LocalName NamespaceURI/};
33 6 100       16 $prefix = '' unless defined $prefix;
34 6 50       14 $ns_uri = '' unless defined $ns_uri;
35 6         49 $res{qq/{$ns_uri}$name/} = {%$value};
36             }
37 6         15 return \%res;
38             }
39              
40             my $attrs = {
41             __temp_array => [],
42             _orig_hash => {},
43             _default => undef,
44             _template => {},
45              
46             };
47              
48             ### install get/set accessors for this object.
49             for my $key ( keys %$attrs ) {
50 9     9   47 no strict 'refs';
  9         16  
  9         10615  
51             *{ __PACKAGE__ . "::$key" } = sub {
52 233     233   594 my $self = shift;
53 233 100       430 $self->{$key} = $_[0] if @_;
54 233         524 return $self->{$key};
55             }
56             }
57              
58             =head2 new
59              
60             tie %hasha, 'XML::ExtOn::TieAttrs', \%hash1, default=>;
61              
62             =cut
63              
64             sub new {
65 5     5 1 8 my $class = shift;
66 5 50       14 $class = ref $class if ref $class;
67 5   50     13 my $orig_hash = shift || {};
68 5         25 my %props = @_;
69 5         14 my $self = bless( \%props, $class );
70 5         16 $self->_orig_hash($orig_hash);
71              
72             #set filters by
73 5   100     15 my $field_name = $props{by} || 'Name';
74 5   100     60 my $value = $props{value} || '';
75 5         21 $self->_default( [ $field_name, $value ] );
76              
77             #setup template
78 5   100     36 $self->_template( $props{template} || {} );
79 5         19 return $self;
80             }
81              
82             sub get_by_filter {
83 42     42 0 50 my $self = shift;
84 42         47 my $flocal_name = shift;
85 42         104 my $ahash = $self->_orig_hash;
86 42         61 my %res = ();
87 42         40 my ( $field_name, $value ) = @{ $self->_default() };
  42         105  
88 42         51 my $i = -1;
89 42         56 foreach my $val (@$ahash) {
90 145         140 $i++;
91 145 100       293 next unless defined( $val->{$field_name} );
92 125 100       233 next unless $val->{$field_name} eq $value;
93 87 100 100     327 next if defined $flocal_name && $val->{LocalName} ne $flocal_name;
94 44         112 $res{$i} = $val;
95             }
96 42         142 return \%res;
97             }
98              
99             sub create_attr {
100 5     5 0 7 my $self = shift;
101 5         9 my $key = shift;
102 5         9 my %template =
103 5         4 ( %{ $self->_template() }, @{ $self->_default() }, LocalName => $key );
  5         10  
104 5         12 my $prefix = $template{Prefix};
105 5         6 my $local_name = $template{LocalName};
106 5 100       15 $template{Name} = $prefix ? "$prefix:$local_name" : $local_name;
107 5         26 return attr_from_sax2( { 1 => \%template } );
108             }
109              
110             sub DELETE {
111 5     5   377 my ( $self, $key ) = @_;
112 5         8 my ( $fkey, $fhash ) = %{ $self->get_by_filter($key) };
  5         21  
113 5 50       16 return unless $fhash;
114 5         7 my $val = $fhash->{Value};
115 5         10 my $ahash = $self->_orig_hash;
116 5         9 delete $ahash->[$fkey];
117 5         14 @{$ahash} = grep { defined } @{$ahash};
  5         18  
  19         30  
  5         10  
118 5         21 return $val;
119             }
120              
121             sub STORE {
122 12     12   820 my ( $self, $key, $val ) = @_;
123             # warn " store: $key, $val ";
124 12         15 my ( $pkey, $fhash ) = %{ $self->get_by_filter($key) };
  12         31  
125 12 100       30 if ($fhash) {
126 6         10 $fhash->{Value} = $val;
127             }
128             else {
129 6         16 my $new_add_to_hash = $self->create_attr($key);
130 6         23 my $ahash = $self->_orig_hash;
131 6         20 while ( my ( $pkey, $pval ) = each %$new_add_to_hash ) {
132 6         6 push @{$ahash}, $pval;
  6         22  
133             }
134 6         19 $self->STORE( $key, $val );
135             }
136 12         29 return $val;
137             }
138              
139             sub FETCH {
140 23     23   111 my ( $self, $key ) = @_;
141 23         22 my $res;
142 23         25 my ( $pkey, $pval ) = %{ $self->get_by_filter($key) };
  23         41  
143 23 50       72 $res = $pval->{Value} if $pval;
144 23         57 return $res;
145             }
146              
147             sub GetKeys {
148 8     8 0 17 my $self = shift;
149 8         9 return [ map { $_->{LocalName} } values %{ $self->get_by_filter } ];
  15         53  
  8         15  
150             }
151              
152             sub TIEHASH { #shift;
153 5     5   1768 return &new(@_);
154             }
155              
156             sub FIRSTKEY {
157 10     10   1799 my ($self) = @_;
158 10         13 $self->__temp_array( [ sort { $a cmp $b } @{ $self->GetKeys() } ] );
  24         46  
  10         26  
159 10         23 shift( @{ $self->__temp_array() } );
  10         19  
160             }
161              
162             sub NEXTKEY {
163 25     25   36 my ( $self, $key ) = @_;
164 25         25 shift( @{ $self->__temp_array() } );
  25         37  
165             }
166              
167             sub EXISTS {
168 23     23   247 my ( $self, $key ) = @_;
169 23         23 my ( $pkey, $pval ) = %{ $self->get_by_filter($key) };
  23         46  
170 23         81 return defined $pval;
171             }
172              
173             sub CLEAR {
174 1     1   428 my $self = shift;
175 1         3 foreach my $key ( @{ $self->GetKeys } ) {
  1         4  
176 3         8 $self->DELETE($key);
177             }
178             }
179              
180             1;
181             __END__