File Coverage

blib/lib/XML/Smart/Data.pm
Criterion Covered Total %
statement 314 427 73.5
branch 223 348 64.0
condition 75 110 68.1
subroutine 12 13 92.3
pod 0 2 0.0
total 624 900 69.3


line stmt bran cond sub pod time code
1             #############################################################################
2             ## Name: Data.pm
3             ## Purpose: XML::Smart::Data - Generate XML data.
4             ## Author: Graciliano M. P.
5             ## Modified by: Harish Madabushi
6             ## Created: 28/09/2003
7             ## RCS-ID:
8             ## Copyright: (c) 2003 Graciliano M. P.
9             ## Licence: This program is free software; you can redistribute it and/or
10             ## modify it under the same terms as Perl itself
11             #############################################################################
12              
13             package XML::Smart::Data ;
14              
15              
16 7     7   40 use strict ;
  7         12  
  7         271  
17 7     7   36 use warnings ;
  7         13  
  7         306  
18              
19             require Exporter ;
20              
21 7     7   35 use XML::Smart::Entity qw(_add_basic_entity) ;
  7         9  
  7         388  
22 7     7   36 use XML::Smart::Shared qw( _unset_sig_warn _reset_sig_warn ) ;
  7         21  
  7         45462  
23              
24             our ($VERSION , @ISA) ;
25             $VERSION = '0.06' ;
26              
27             @ISA = qw(Exporter) ;
28              
29             our @EXPORT = qw(data) ;
30             our @EXPORT_OK = @EXPORT ;
31              
32             ########
33             # DATA #
34             ########
35              
36             sub data {
37              
38 251     251 0 9238 _unset_sig_warn() ;
39 251         496 my $this = shift ;
40            
41 251         795 my ( %args ) = @_ ;
42 251         373 my $tree ;
43 251 50       749 if( $args{tree} ) {
44 0         0 $tree = $args{ tree } ;
45             } else {
46 251         940 $tree = $this->tree ;
47             }
48            
49             {
50 251         468 my $addroot ;
  251         347  
51 251 50 33     1807 if ( $args{root} || ref $tree ne 'HASH' ) { $addroot = 1 ; }
  0         0  
52             else {
53            
54 251         479 my $ks = keys %$tree ; ## WARNING ON ORDER ( Mostly harmless )!
55              
56 251         384 my $n = 1 ;
57 251 100       803 if (ref $$tree{'/nodes'} eq 'HASH') { ++$n ;}
  175         431  
58 251 100       729 if (ref $$tree{'/order'} eq 'ARRAY') { ++$n ;}
  151         186  
59             #if (ref $$tree{'/nodes'} eq 'HASH') { ++$n if (keys %{$$tree{'/nodes'}}) ;}
60             #if (ref $$tree{'/order'} eq 'ARRAY') { ++$n if @{$$tree{'/order'}} ;}
61            
62 251 100       535 if ($ks > $n) { $addroot = 1 ; }
  3         8  
63             else {
64             # Fix hash randomization bug Id:84929
65 248         1381 my %tmp = %$tree ;
66 248         527 delete $tmp{ '/nodes' } ;
67 248         392 delete $tmp{ '/order' } ;
68 248         556 my $k = (keys %tmp)[0] ;
69 248 100 66     2718 if (ref $$tree{$k} eq 'ARRAY' && $#{$$tree{$k}} > 0) {
  9 50       40  
70 9         13 my ($c,$ok) ;
71 9         15 foreach my $i ( @{$$tree{$k}} ) {
  9         22  
72 18 100 66     68 if ( $i && &is_valid_tree($i) ) { $c++ ; $ok = $i ;}
  15         18  
  15         19  
73 18 100       75 if ($c > 1) { $addroot = 1 ; last ;}
  6         10  
  6         12  
74             }
75 9 100 66     50 if (!$addroot && $ok) { $$tree{$k} = $ok ;}
  3         10  
76             }
77 0         0 elsif (ref $$tree{$k} =~ /^(?:HASH|)$/) { $addroot = 1 ;}
78             }
79             }
80            
81 251 100       789 if ($addroot) {
82 9   50     50 my $root = $args{root} || 'root' ;
83 9         32 $tree = {$root => $tree} ;
84             }
85             }
86            
87 251 100       701 if ( $args{lowtag} ) { $args{lowtag} = 1 ;}
  3         7  
88 251 100       654 if ( $args{upertag} ) { $args{lowtag} = 2 ;}
  3         8  
89            
90 251 50       796 if ( $args{lowarg} ) { $args{lowarg} = 1 ;}
  0         0  
91 251 100       666 if ( $args{uperarg} ) { $args{lowarg} = 2 ;}
  3         9  
92              
93 251         438 my ($data,$unicode) ;
94             {
95 251         308 my $parsed = {} ;
  251         419  
96 251         2293 &_data( $args{decode}, \$data , $tree , '' , -1 , {} , $parsed , undef , undef , $args{noident} , $args{nospace} , $args{lowtag} , $args{lowarg} , $args{wild} , $args{sortall} ) ;
97 251 100       1520 $data .= "\n" if !$args{nospace} ;
98 251 100       710 if ( &_is_unicode($data) ) { $unicode = 1 ;}
  14         78  
99             }
100              
101 251         487 my $enc = 'iso-8859-1' ;
102 251 100       533 if ($unicode) { $enc = 'UTF-8' ;}
  14         27  
103            
104 251         304 my $meta ;
105 251 50       606 if ( $args{meta} ) {
106 0         0 my @metas ;
107 0 0       0 if (ref($args{meta}) eq 'ARRAY') { @metas = @{$args{meta}} ;}
  0 0       0  
  0         0  
108 0         0 elsif (ref($args{meta}) eq 'HASH') { @metas = $args{meta} ;}
109 0         0 else { @metas = $args{meta} ;}
110            
111 0         0 foreach my $metas_i ( @metas ) {
112 0 0       0 if (ref($metas_i) eq 'HASH') {
113 0         0 my $meta ;
114 0         0 foreach my $Key (sort keys %$metas_i ) {
115 0         0 $meta .= " $Key=" . &_add_quote($$metas_i{$Key}) ;
116             }
117 0         0 $metas_i = $meta ;
118             }
119             }
120            
121 0         0 foreach my $meta ( @metas ) {
122 0         0 $meta =~ s/^[<\?\s*]//s ;
123 0         0 $meta =~ s/[\s\?>]*$//s ;
124 0         0 $meta =~ s/^meta\s+//s ;
125 0         0 $meta = "" ;
126             }
127            
128 0         0 $meta = "\n" . join ("\n", @metas) ;
129             }
130            
131 251 100       737 my $wild = $args{wild} ? ' [format: wild]' : '' ;
132            
133 251         1682 my $metagen = qq`\n` ;
134 251 100       643 if ( $args{nometagen} ) { $metagen = '' ;}
  6         15  
135            
136 251         313 my $length ;
137 251 100       627 if ( $args{length} ) {
138 3         27 $length = ' length="' . (length($metagen) + length($meta) + length($data)) . '"' ;
139             }
140            
141 251         2307 my $xml = qq`` ;
142            
143 251 50       842 if ( $args{noheader} ) { $xml = '' ; $metagen = '' if $args{nometagen} eq '' ;}
  227 100       357  
  227         2851  
144            
145 251         457 my $dtd ;
146            
147 251 100 100     1890 if ( !$args{nodtd} && $$this->{DTD} ) {
148 4 50       46 $dtd = ref $$this->{DTD} ? $$this->{DTD}->CutDTD : $$this->{DTD} ;
149 4         173 $dtd =~ s/\s*$// ;
150 4 100 66     32 $dtd = "\n$dtd" if $dtd ne '' && !$args{nospace} ;
151             }
152              
153            
154 251         2046 $data = $xml . $metagen . $meta . $dtd . $data ;
155            
156 251 100       906 if ($xml eq '') { $data =~ s/^\s+//gs ;}
  227         1966  
157            
158 251 50       732 if (wantarray) {
159 0         0 _reset_sig_warn() ;
160 0         0 return($data , $unicode) ;
161             }
162 251         703 _reset_sig_warn() ;
163 251         1292 return($data) ;
164             }
165              
166              
167              
168             ##################################################
169             ## UNUSED - DEPRECATED. ##
170             ##################################################
171              
172              
173             sub _replace_data_with_lt {
174              
175 0     0   0 my $data = shift ;
176              
177 0         0 while( my $index_of_smart_html_encode = index( $data, 'smart_html_encode( < )' ) ) {
178 0 0       0 last if( $index_of_smart_html_encode == -1 ) ;
179 0         0 my $tmp = substr( $data ,
180             $index_of_smart_html_encode ,
181             length( 'smart_html_encode( < )' ) ,
182             '<'
183             ) ;
184             }
185              
186 0         0 while( my $index_of_multiple_smart_html_encode = index( $data, 'multiple_smart_html_encode(' ) ) {
187 0 0       0 last if( $index_of_multiple_smart_html_encode == -1 ) ;
188 0         0 my $check_string = substr( $data, $index_of_multiple_smart_html_encode ) ;
189 0 0       0 if( $check_string =~ /multiple_smart_html_encode\((.*?)\).*/ ) {
190 0         0 my $params = $1 ;
191 0         0 my $len = length( $params ) ;
192 0         0 $params =~ s/^\s+//g;
193 0         0 $params =~ s/\s+$//g;
194 0         0 my ( $from, $to ) = split( /\s/, $params ) ;
195 0         0 my $number_of_lt = $from - $to ;
196 0         0 my $tmp = substr( $data,
197             $index_of_multiple_smart_html_encode,
198             length( 'multiple_smart_html_encode(' ) + $len + 1 ,
199             '<' x $number_of_lt );
200             }
201              
202             }
203              
204 0         0 return $data ;
205            
206             }
207            
208              
209              
210             #################
211             # IS_VALID_TREE #
212             #################
213              
214             sub is_valid_tree {
215 33     33 0 88 _unset_sig_warn() ;
216 33         53 my ( $tree ) = @_ ;
217 33         39 my $found ;
218 33 100 0     87 if (ref($tree) eq 'HASH') {
    50          
    0          
219 30         109 foreach my $Key (sort keys %$tree ) {
220 42 100 66     247 if ($Key eq '' || $Key eq '/order' || $Key eq '/nodes') { next ;}
  15   100     28  
221 27 100       95 if (ref($$tree{$Key})) { $found = &is_valid_tree($$tree{$Key}) ;}
  12 50       43  
222 15         21 elsif ($$tree{$Key} ne '') { $found = 1 ;}
223 27 50       58 if ($found) { last ;}
  27         39  
224             }
225             }
226             elsif (ref($tree) eq 'ARRAY') {
227 3         12 foreach my $value (@$tree) {
228 3 50       13 if (ref($value)) { $found = &is_valid_tree($value) ;}
  3 0       18  
229 0         0 elsif ($value ne '') { $found = 1 ;}
230 3 50       12 if ($found) { last ;}
  3         5  
231             }
232             }
233 0         0 elsif (ref($tree) eq 'SCALAR' && $$tree ne '') { $found = 1 ;}
234            
235 33         90 _reset_sig_warn() ;
236 33         121 return $found ;
237              
238             }
239              
240             ###############
241             # _IS_UNICODE #
242             ###############
243              
244             sub _is_unicode {
245 251     251   779 _unset_sig_warn() ;
246 251 50       786 if ($] >= 5.008001) {
    0          
    0          
247 251 100       1037 if ( utf8::is_utf8($_[0])) {
248 14         43 _reset_sig_warn() ;
249 14         74 return 1 ;
250             }
251             }
252             elsif ($] >= 5.008) {
253 0         0 require Encode ;
254 0 0       0 if ( Encode::is_utf8($_[0])) {
255 0         0 _reset_sig_warn() ;
256 0         0 return 1 ;
257             }
258             }
259             elsif ( $] >= 5.007 ) {
260 0         0 _reset_sig_warn() ;
261 0         0 my $is = eval(q`
262             if ( $_[0] =~ /[\x{100}-\x{10FFFF}]/s) { return 1 ;}
263             return undef ;
264             `);
265 0         0 $@ = undef ;
266 0 0       0 return 1 if $is ;
267             }
268             else {
269             ## No Perl internal support for UTF-8! ;-/
270             ## Is better to handle as Latin1.
271 0         0 _reset_sig_warn() ;
272 0         0 return undef ;
273             }
274              
275 237         648 _reset_sig_warn() ;
276 237         1042 return undef ;
277             }
278              
279             #########
280             # _DATA #
281             #########
282              
283             sub _data {
284              
285 1482     1482   3755 _unset_sig_warn() ;
286 1482         5726 my ( $decode, $data , $tree , $tag , $level , $prev_tree , $parsed , $ar_i , $node_type , @stat ) = @_ ;
287              
288 1482 0       3569 if (ref($tree) eq 'XML::Smart') { $tree = defined $$tree->{content} ? $$tree->{content} : $$tree->{point} ;}
  0 50       0  
289            
290 1482 50       3168 if ( ref($tree) ) {
291 1482 50       4383 if ($$parsed{"$tree"}) {
292 0         0 _reset_sig_warn() ;
293 0         0 return ;
294             }
295 1482         4838 ++$$parsed{"$tree"} ;
296             }
297            
298 1482         2096 my $ident = "\n" ;
299 1482 100       3470 $ident .= ' ' x $level if !$stat[0] ;
300              
301 1482 100       2583 if ($stat[1]) { $ident = '' ;}
  477         592  
302 1482 100       9084 $stat[1] -= 2 if $stat[1] > 1 ;
303            
304 1482         3169 my $tag_org = $tag ;
305              
306 1482 100       3758 $tag = $stat[4] ? $tag : &_check_tag($tag) ;
307 1482 50       11443 if ($stat[2] == 1) { $tag = "\L$tag\E" ;}
  0 100       0  
308 56         82 elsif ($stat[2] == 2) { $tag = "\U$tag\E" ;}
309              
310 1482 100       4436 if (ref($tree) eq 'HASH') {
    50          
    0          
    0          
311 1110         1385 my ($args,$args_end,$tags,$cont,$stat_1) ;
312            
313 0         0 my (@all_keys , %multi_keys) ;
314            
315 1110 100 66     4597 if ( !$stat[5] && $tree->{'/order'} ) {
316 524         614 my %keys ;
317 524         629 foreach my $keys_i ( @{$tree->{'/order'}} ) {
  524         1286  
318 1361 50 66     13176 if ( exists $$tree{$keys_i} && (!ref($$tree{$keys_i}) || ref($$tree{$keys_i}) eq 'HASH' || ref($$tree{$keys_i}) eq 'XML::Smart' || (ref($$tree{$keys_i}) eq 'ARRAY' && exists $$tree{$keys_i}[ $keys{$keys_i} ] ) ) ) {
      66        
319 1336         1913 push(@all_keys , $keys_i) ;
320            
321 1336 100 66     5166 if ( ++$keys{$keys_i} == 2 && ref $$tree{$keys_i} eq 'ARRAY' ) {
322 127 100       185 my @val = map { ( $_ ne '' ? 1 : () ) } @{ $$tree{$keys_i} } ;
  327         952  
  127         277  
323 127 100       548 $multi_keys{$keys_i} = 1 if $#val > 0 ;
324             }
325             }
326             }
327 524         2618 foreach my $keys_i ( sort keys %$tree ) {
328 2047 100 66     7234 if ( !$keys{$keys_i} && exists $$tree{$keys_i} ) { push(@all_keys , $keys_i) ;}
  907         1640  
329             }
330             }
331 586         2197 else { @all_keys = sort keys %$tree ;}
332            
333 1110         1767 my %array_i ;
334              
335 1110         1631 foreach my $Key ( @all_keys ) {
336 3006 100 66     16657 if ($Key eq '' || $Key eq '/order' || $Key eq '/nodes') { next ;}
  1034   100     1959  
337              
338 1972 100 33     11718 if ( $Key eq '!--' && (!ref($$tree{$Key}) || ( ref($$tree{$Key}) eq 'HASH' && (keys %{$$tree{$Key}}) == 1 && (defined $$tree{$Key}{CONTENT} || defined $$tree{$Key}{content}) ) ) ) {
    100 66        
    100 100        
    100          
    100          
    100          
339 10         20 my $ct = $$tree{$Key} ;
340 10 50       33 if (ref $$tree{$Key}) { $ct = defined $$tree{$Key}{CONTENT} ? $$tree{$Key}{CONTENT} : $$tree{$Key}{content} ;} ;
  10 50       37  
341 10 50       27 if ( $ct ne '' ) { $tags .= "$ident" ;}
  10         30  
342             }
343             elsif (ref($$tree{$Key})) {
344 904         1363 my $k = $$tree{$Key} ;
345 904         903 my $i ;
346 904 100 100     4379 if (ref $k eq 'XML::Smart') {
    100          
347 1 50       2 $k = defined ${$$tree{$Key}}->{content} ? ${$$tree{$Key}}->{content} : ${$$tree{$Key}}->{point} ;
  1         7  
  0         0  
  1         4  
348             }
349             elsif ( ref $k eq 'ARRAY' && $multi_keys{$Key} ) {
350 317 50       325 $i = $array_i{$Key}++ if $#{$k} > 0 ;
  317         1068  
351             }
352 904 100       6651 $args .= &_data($decode, \$tags,$k,$Key, $level+1 , $tree , $parsed , $i , $$tree{'/nodes'}{$Key} , @stat) if $array_i{$Key} ne 'ok' ;
353 904 100 100     5659 $array_i{$Key} = 'ok' if $i eq '' && ref $k eq 'ARRAY' ;
354             }
355             elsif ( $$tree{'/nodes'}{$Key} ) {
356 7         26 my $k = [$$tree{$Key}] ;
357 7         40 $args .= &_data($decode, \$tags,$k,$Key, $level+1 , $tree , $parsed , undef , $$tree{'/nodes'}{$Key} , @stat) ;
358             }
359             elsif (lc($Key) eq 'content') {
360 324 100 66     1144 if ( tied($$tree{$Key}) && $$tree{$Key} =~ /\S/s ) {
361 8         13 $ident = '' ; $stat[1] += 2 ;
  8         15  
362             }
363 324 100       656 next if tied($$tree{$Key}) ;
364            
365 316 100       737 if ( $$tree{$Key} ne '' ) {
366 304         400 my $p0 = length($tags) ;
367 304         670 $tags .= $$tree{$Key} ;
368 304         3142 $cont = [$p0, length($tags) - $p0] ;
369             }
370             }
371 20         44 elsif ($Key =~ /^\/\.CONTENT\/\d+$/) { $tags .= $$tree{$Key} ;}
372 6         17 elsif ( $stat[4] && $$tree{$Key} eq '') { $args_end .= " $Key" ;}
373             else {
374 701         1752 my $tp = _data_type($$tree{$Key}) ;
375 701 100       1471 if ($tp == 1) {
376 692 100       1669 my $k = $stat[4] ? $Key : &_check_key($Key) ;
377 692 50       10684 if ($stat[3] == 1) { $k = "\L$Key\E" ;}
  0 100       0  
378 40         67 elsif ($stat[3] == 2) { $k = "\U$Key\E" ;}
379 692         2877 $args .= " $k=" . &_add_quote($$tree{$Key}) ;
380             }
381             else {
382 9 50       44 my $k = $stat[4] ? $Key : &_check_key($Key) ;
383 9 50       89 if ($stat[2] == 1) { $k = "\L$Key\E" ;}
  0 50       0  
384 0         0 elsif ($stat[2] == 2) { $k = "\U$Key\E" ;}
385              
386 9 50       60 if ($tp == 2) {
    100          
    50          
387 0         0 my $cont = $$tree{$Key} ; &_add_basic_entity($cont) ;
  0         0  
388 0         0 $tags .= qq`$ident<$k>$cont` ;
389             }
390 6         33 elsif ($tp == 3) { $tags .= qq`$ident<$k>`;}
391             elsif ($tp == 4) {
392 3         21 require XML::Smart::Base64 ;
393 3         18 my $base64 = &XML::Smart::Base64::encode_base64($$tree{$Key}) ;
394 3         16 $base64 =~ s/\s$//s ;
395 3         23 $tags .= qq`$ident<$k dt:dt="binary.base64">$base64`;
396             }
397             }
398             }
399             } # foreach my $Key ( @all_keys ) { -- Contains if ($Key eq '' || $Key eq '/order' || $Key eq '/nodes') { next ;}
400            
401 1110         2778 foreach my $Key ( keys %array_i ) {
402 168 100 100     590 if ( $array_i{$Key} ne 'ok' && $#{ $$tree{$Key} } >= $array_i{$Key} ) {
  124         588  
403 4         11 for my $i ( $array_i{$Key} .. $#{ $$tree{$Key} } ) {
  4         14  
404 4         22 $args .= &_data($decode, \$tags, $$tree{$Key} ,$Key, $level+1 , $tree , $parsed , $i , $$tree{'/nodes'}{$Key} , @stat) ;
405             }
406             }
407             }
408            
409 1110 100       6520 if ( $cont ne '' ) {
410 304         624 my ( $po , $p1 ) = @$cont ;
411 304         2274 my $cont = substr($tags , $po , $p1) ;
412            
413 304         780 my $tp = _data_type($cont) ;
414            
415 304 100       1750 if ( $node_type =~ /^(\w+),(\d+),(\d*)$/ ) {
416 11         86 my ( $node_tp , $node_set ) = ($1,$2) ;
417              
418 11 100       38 if ( !$node_set ) {
419 2 100 66     23 if ( $tp == 3 && $node_tp eq 'cdata' ) { $tp = 0 ;}
  1 50 33     4  
420 1         4 elsif ( $tp == 4 && $node_tp eq 'binary' ) { $tp = 0 ;}
421             }
422             else {
423 9 100       52 if ( $node_tp eq 'cdata' ) { $tp = 3 ;}
  3 50       9  
424 6         14 elsif ( $node_tp eq 'binary' ) { $tp = 4 ;}
425             }
426             }
427            
428 304 100       943 if ( $tp == 3 ) { $cont = "" ;}
  5 100       23  
429             elsif ( $tp == 4 ) {
430 25         3474 require XML::Smart::Base64 ;
431 25         117 $cont = &XML::Smart::Base64::encode_base64($cont) ;
432 25         123 $cont =~ s/\s$//s ;
433 25         75 $args .= ' dt:dt="binary.base64"' ;
434             }
435 274         720 else { &_add_basic_entity($cont) ;}
436            
437 304         2481 my $pe = $po + $p1 ;
438 304         574 my $px = $pe ;
439 304         1123 while( substr($tags , $px , 1) =~ /\s/ ) { ++$px ;}
  39         122  
440              
441 304 100       664 if ( $px > $pe ) { substr($tags , $pe , $px-$pe) = '' ;}
  15         40  
442            
443 304         1974 substr($tags , $po , $p1) = $cont ;
444             }
445            
446             ## print STDERR "***$tag>> $args,$args_end,$tags,$cont,$stat_1 [@all_keys]\n" ;
447              
448 1110 100       7332 if ($args_end ne '') {
449 6         10 $args .= $args_end ;
450 6         12 $args_end = undef ;
451             }
452              
453 1110 100 100     7119 if (!@all_keys) {
    100          
    100          
    100          
454 40 100       181 $$data .= qq`$ident<$tag/>` if $tag ne '' ;
455             }
456             elsif ($args ne '' && $tags ne '') {
457 187 100 100     746 if( $args =~ /dt\:dt="binary.base64"/ and $decode ) {
458 10 50       68 $$data .= qq`$ident<$tag>` if $tag ne '' ;
459 10         75 require XML::Smart::Base64 ;
460 10         50 $$data .= &XML::Smart::Base64::decode_base64( $tags ) ;
461             } else {
462 177 50       622 $$data .= qq`$ident<$tag$args>` if $tag ne '' ;
463 177         264 $$data .= $tags ;
464             }
465 187 100       400 $$data .= $ident if !$cont ;
466 187 50       946 $$data .= qq`` if $tag ne '' ;
467             }
468             elsif ($args ne '') {
469 178         739 $$data .= qq`$ident<$tag$args/>`;
470             }
471             elsif ($tags ne '') {
472 690 100       1986 $$data .= qq`$ident<$tag>` if $tag ne '' ;
473 690         2643 $$data .= $tags ;
474 690 100       1368 $$data .= $ident if !$cont ;
475 690 100       2778 $$data .= qq`` if $tag ne '' ;
476             }
477             else {
478 15 50       90 $$data .= qq`$ident<$tag>` if $tag ne '' ;
479             }
480              
481             }
482             elsif (ref($tree) eq 'ARRAY') {
483 372         488 my ($c,$v,$tags) ;
484              
485 372 100       1190 foreach my $value_i ( ($ar_i ne '' ? $$tree[$ar_i] : @$tree) ) {
486            
487 414         609 my $value = $value_i ;
488 414 50       785 if (ref $value_i eq 'XML::Smart') { $value = $$value_i->{point} ;}
  0         0  
489            
490 414         450 my $do_val = 1 ;
491 414 50 0     1459 if ( $tag_org eq '!--' && ( !ref($value) || ( ref($value) eq 'HASH' && keys %{$value} == 1 && (defined $$value{CONTENT} || defined $$value{content}) ) ) ) {
    100 33        
492 0         0 $c++ ;
493 0         0 my $ct = $value ;
494 0 0       0 if (ref $value) { $ct = defined $$value{CONTENT} ? $$value{CONTENT} : $$value{content} ;} ;
  0 0       0  
495 0         0 $tags .= $ident . '' ;
496 0 0       0 $v = $ct if $c == 1 ;
497 0         0 $do_val = 0 ;
498             }
499             elsif (ref($value)) {
500 319 50       554 if (ref($value) eq 'HASH') {
    0          
    0          
501 319         373 $c = 2 ;
502 319         995 &_data($decode, \$tags,$value,$tag,$level, $tree , $parsed , undef , undef , @stat) ;
503 319         595 $do_val = 0 ;
504             }
505 0         0 elsif (ref($value) eq 'SCALAR') { $value = $$value ;}
506 0         0 elsif (ref($value) ne 'ARRAY') { $value = "$value" ;}
507             }
508 414 100 100     1519 if ( $do_val && $value ne '') {
509 92         221 my $tp = _data_type($value) ;
510            
511 92 100       1950 if ( $node_type =~ /^(\w+),(\d+),(\d*)$/ ) {
512 7         30 my ( $node_tp , $node_set ) = ($1,$2) ;
513 7 50       23 if ( !$node_set ) {
514 7 100 66     53 if ( $tp == 3 && $node_tp eq 'cdata' ) { $tp = 0 ;}
  5 50 33     11  
515 2         4 elsif ( $tp == 4 && $node_tp eq 'binary' ) { $tp = 0 ;}
516             }
517             else {
518 0 0       0 if ( $node_tp eq 'cdata' ) { $tp = 3 ;}
  0 0       0  
519 0         0 elsif ( $node_tp eq 'binary' ) { $tp = 4 ;}
520             }
521             }
522            
523 92 100       270 if ($tp <= 2) {
    50          
    50          
524 82         111 $c++ ;
525 82         144 my $cont = $value ; &_add_basic_entity($value) ;
  82         276  
526 82         199 &_add_basic_entity($cont) ;
527 82         339 $tags .= qq`$ident<$tag>$cont`;
528 82 100       341 $v = $cont if $c == 1 ;
529             }
530             elsif ($tp == 3) {
531 0         0 $c++ ;
532 0         0 $tags .= qq`$ident<$tag>`;
533 0 0       0 $v = $value if $c == 1 ;
534             }
535             elsif ($tp == 4) {
536 10         14 $c++ ;
537 10         846 require XML::Smart::Base64 ;
538 10         57 my $base64 = &XML::Smart::Base64::encode_base64($value) ;
539 10         49 $base64 =~ s/\s$//s ;
540 10         1314 $tags .= qq`$ident<$tag dt:dt="binary.base64">$base64`;
541 10 50       50 $v = $value if $c == 1 ;
542             }
543             }
544             }
545              
546 372 100 100     1444 if ( $ar_i eq '' && $c <= 1 && ! $$prev_tree{'/nodes'}{$tag}) {
      100        
547 3 50       16 my $k = $stat[4] ? $tag : &_check_key($tag) ;
548 3 50       24 if ($stat[3] == 1) { $k = "\L$k\E" ;}
  0 100       0  
549 2         9 elsif ($stat[3] == 2) { $k = "\U$k\E" ;}
550 3 50       18 delete $$parsed{"$tree"} if ref($tree) ;
551 3         16 my $return_val = " $k=" . &_add_quote($v) ;
552 3         14 _reset_sig_warn() ;
553 3         14 return $return_val ;
554             }
555 369         1322 else { $$data .= $tags ;}
556             }
557             elsif (ref($tree) eq 'SCALAR') {
558 0 0       0 my $k = $stat[4] ? $tag : &_check_key($tag) ;
559 0 0       0 if ($stat[3] == 1) { $k = "\L$k\E" ;}
  0 0       0  
560 0         0 elsif ($stat[3] == 2) { $k = "\U$k\E" ;}
561 0 0       0 delete $$parsed{"$tree"} if ref($tree) ;
562 0         0 my $return_val = " $k=" . &_add_quote($$tree) ;
563 0         0 _reset_sig_warn() ;
564 0         0 return $return_val ;
565             }
566             elsif (ref($tree)) {
567 0 0       0 my $k = $stat[4] ? $tag : &_check_key($tag) ;
568 0 0       0 if ($stat[3] == 1) { $k = "\L$k\E" ;}
  0 0       0  
569 0         0 elsif ($stat[3] == 2) { $k = "\U$k\E" ;}
570 0 0       0 delete $$parsed{"$tree"} if ref($tree) ;
571 0         0 my $return_val = " $k=" . &_add_quote("$tree") ;
572 0         0 _reset_sig_warn() ;
573 0         0 return $return_val ;
574             }
575             else {
576 0 0       0 my $k = $stat[4] ? $tag : &_check_key($tag) ;
577 0 0       0 if ($stat[3] == 1) { $k = "\L$k\E" ;}
  0 0       0  
578 0         0 elsif ($stat[3] == 2) { $k = "\U$k\E" ;}
579 0 0       0 delete $$parsed{"$tree"} if ref($tree) ;
580 0         0 my $return_val = " $k=" . &_add_quote($tree) ;
581 0         0 _reset_sig_warn() ;
582 0         0 return $return_val ;
583             }
584              
585              
586 1479 50       5366 delete $$parsed{"$tree"} if ref($tree) ;
587 1479         3816 _reset_sig_warn() ;
588 1479         9315 return ;
589             }
590              
591             ##############
592             # _DATA_TYPE #
593             ##############
594              
595             ## 4 binary
596             ## 3 CDATA
597             ## 2 content
598             ## 1 value
599              
600 1097     1097   2734 sub _data_type { &XML::Smart::_data_type ;}
601              
602             ##############
603             # _CHECK_TAG #
604             ##############
605              
606 1448     1448   2231 sub _check_tag { &_check_key ;}
607              
608             ##############
609             # _CHECK_KEY #
610             ##############
611              
612             sub _check_key {
613 2137     2137   4921 _unset_sig_warn() ;
614 2137 100       8593 if ($_[0] =~ /(?:^[.:-]|[^\w\:\.\-])/s) {
615 4         5 my $k = $_[0] ;
616 4         12 $k =~ s/^[.:-]+//s ;
617 4         12 $k =~ s/[^\w\:\.\-]+/_/gs ;
618 4         11 _reset_sig_warn() ;
619 4         14 return( $k ) ;
620             }
621 2133         3112 my $return_val = $_[0] ;
622 2133         5050 _reset_sig_warn() ;
623 2133         6725 return( $return_val ) ;
624             }
625              
626             ##############
627             # _ADD_QUOTE #
628             ##############
629              
630             sub _add_quote {
631 695     695   1619 _unset_sig_warn() ;
632 695         1335 my ($data) = @_ ;
633 695         1105 $data =~ s/\\$/\\\\/s ;
634            
635 695         1801 &_add_basic_entity($data) ;
636            
637 695 100       1523 my $q1 = ($data =~ /"/s) ? 1 : undef ;
638 695 50       1250 my $q2 = ($data =~ /'/s) ? 1 : undef ;
639            
640 695 50 66     2087 if (!$q1 && !$q2) {
641 691         1513 _reset_sig_warn() ;
642 691         3472 return( qq`"$data"` ) ;
643             }
644            
645 4 50 33     30 if ($q1 && $q2) {
646 0         0 $data =~ s/"/"/gs ;
647 0         0 _reset_sig_warn() ;
648 0         0 return( qq`"$data"` ) ;
649             }
650            
651 4 50       15 if ($q1) {
652 4         13 _reset_sig_warn() ;
653 4         26 return( qq`'$data'` ) ;
654             }
655 0 0         if ($q2) {
656 0           _reset_sig_warn() ;
657 0           return( qq`"$data"` ) ;
658             }
659              
660 0           _reset_sig_warn() ;
661 0           return( qq`"$data"` ) ;
662              
663             }
664              
665             #######
666             # END #
667             #######
668              
669             1;
670              
671