File Coverage

blib/lib/Encoding/HandleUtf8.pm
Criterion Covered Total %
statement 54 58 93.1
branch 20 26 76.9
condition 10 17 58.8
subroutine 10 10 100.0
pod 2 2 100.0
total 96 113 84.9


line stmt bran cond sub pod time code
1             package Encoding::HandleUtf8;
2             # ABSTRACT: Fix the encoding for Perl value store (input) and general output (output) to a console or the web.
3             #
4             # This file is part of Encoding-HandleUtf8
5             #
6             # This software is Copyright (c) 2014 by BURNERSK .
7             #
8             # This is free software, licensed under:
9             #
10             # The MIT (X11) License
11             #
12 3     3   108238 use strict;
  3         8  
  3         141  
13 3     3   18 use warnings FATAL => 'all';
  3         4  
  3         173  
14              
15             BEGIN {
16 3     3   86 our $VERSION = '0.003'; # VERSION: generated by Dist::Zilla
17             }
18              
19 3     3   23 use Carp qw( carp croak );
  3         4  
  3         265  
20 3     3   4385 use Encoding::FixLatin qw( fix_latin );
  3         52670  
  3         194  
21 3     3   15250 use Clone 'clone';
  3         9576  
  3         372  
22              
23             ############################################################################
24             # Prototype definition - required for the recursion, otherwise it will not
25             # find itself because it is not already in the internal symbol list.
26              
27             sub fix_encoding ($\[$@%];$);
28             sub fix_encoding_return ($$;$);
29              
30             ############################################################################
31             # Setup exporter.
32              
33             our @EXPORT_OK;
34              
35             BEGIN {
36 3     3   27 use base 'Exporter';
  3         4  
  3         359  
37 3     3   1401 @EXPORT_OK = qw( &fix_encoding &fix_encoding_return );
38             }
39              
40             ############################################################################
41             # Utility function to fix the encoding for Perl value store (input) and
42             # general output (output) to a console or the web.
43             # Second parameter is the object indended which should be fixed. Due to
44             # prototypes it automatically turns into an reference.
45             sub fix_encoding ($\[$@%];$) {
46 138     138 1 36482 my ( $direction, $obj, $skip_latin ) = @_;
47              
48 138         222 my $ref = ref $obj;
49 138 100       284 my $obj_ref = $ref eq 'REF' ? ref ${$obj} : $ref;
  41         77  
50              
51             # Check encoding direction.
52 138 50 66     654 croak sprintf q{invalid direction '%s' (input or output)}, $direction
      33        
53             if !$direction || ( $direction ne 'input' && $direction ne 'output' );
54              
55             # If $obj is just a string everything is very basic.
56 138 100       437 if ( $ref eq 'SCALAR' ) {
    50          
    100          
    50          
57              
58             # Fix possible mixed encodings.
59 96 50       197 ${$obj} = fix_latin ${$obj} unless $skip_latin;
  96         10418  
  96         317  
60              
61             # Final encoding it to UTF-8 (output) or Unicode (input).
62 96 100       239 if ( $direction eq 'output' ) {
63 46 50 33     153 utf8::encode ${$obj} if defined ${$obj} && utf8::is_utf8 ${$obj};
  46         105  
  46         124  
  46         188  
64             }
65             else {
66 50 100 66     58 utf8::decode ${$obj} if defined ${$obj} && !utf8::is_utf8 ${$obj};
  2         12  
  50         139  
  50         314  
67             }
68             }
69              
70             # Iterate over an array reference.
71             elsif ( $ref eq 'ARRAY' ) {
72 0         0 fix_encoding $direction, $_ for ( @{$obj} );
  0         0  
73             }
74              
75             # Iterate over the keys of a hash reference.
76             elsif ( $ref eq 'HASH' ) {
77 1         2 fix_encoding $direction, $obj->{$_} for ( keys %{$obj} );
  1         10  
78             }
79              
80             # Otherwise if $obj is a reference we have to use some recursive magic.
81             elsif ( $ref eq 'REF' ) {
82              
83             # Iterate over an array reference.
84 41 100       95 if ( $obj_ref eq 'ARRAY' ) {
    50          
85 12         18 fix_encoding $direction, $_ for ( @{ ${$obj} } );
  12         14  
  12         42  
86             }
87              
88             # Iterate over the keys of a hash reference.
89             elsif ( $obj_ref eq 'HASH' ) {
90 29         36 fix_encoding $direction, ${$obj}->{$_} for ( keys %{ ${$obj} } );
  29         29  
  29         96  
  57         152  
91             }
92              
93             # Everything else is not supported.
94             else {
95 0         0 carp sprintf q{unsupported reference '%s'}, $obj_ref;
96             }
97              
98             }
99              
100             # w00t - this shouldn't ever happen!
101             else {
102 0         0 carp sprintf q{unknown object reference '%s'}, $ref;
103             }
104              
105 138 100 100     609 return $ref eq 'REF' || $ref eq 'SCALAR' ? ${$obj} : $obj;
  137         414  
106             }
107              
108              
109             ############################################################################
110             # Does the same like fix_encoding but do not touches original reference.
111             sub fix_encoding_return ($$;$) {
112 27     27 1 29598 my ( $direction, $obj, $skip_latin ) = @_;
113 27         218 my $obj_cloned = clone $obj;
114 27   50     150 fix_encoding $direction, $obj_cloned, $skip_latin // 0;
115 27         120 return $obj_cloned;
116             }
117              
118              
119              
120             ############################################################################
121             1;
122             ############################################################################
123              
124             __END__