epic-s6ts
[kivitendo-erp.git] / SL / Iconv.pm
1 package SL::Iconv;
2
3 use Encode;
4 use English qw(-no_match_vars);
5 use Text::Iconv;
6
7 use SL::Common;
8
9 my %converters;
10
11 use strict;
12
13 sub new {
14   my $class = shift;
15   my $self  = bless { }, $class;
16
17   $self->_init(@_);
18
19   return $self;
20 }
21
22 sub _get_converter {
23   my ($from_charset, $to_charset) = @_;
24
25   my $index             = join $SUBSCRIPT_SEPARATOR, $from_charset, $to_charset;
26   $converters{$index} ||= Text::Iconv->new($from_charset, $to_charset) || die;
27
28   return $converters{$index};
29 }
30
31 sub convert {
32   return _convert(@_) if ref $_[0];
33
34   my ($from_charset, $to_charset, $text) = @_;
35
36   $from_charset ||= 'UTF-8';
37   $to_charset   ||= 'UTF-8';
38
39   my $converter = _get_converter($from_charset, $to_charset);
40   $text         = $converter->convert($text);
41   $text         = decode("utf-8-strict", $text) if ($to_charset =~ m/^utf-?8$/i) && !Encode::is_utf8($text);
42
43   return $text;
44 }
45
46 sub _convert {
47   my $self = shift;
48   my $text = shift;
49
50   $text    = convert($self->{from}, $self->{to}, $text) if !$self->{to_is_utf8} || !Encode::is_utf8($text);
51   $text    = decode("utf-8-strict", $text)              if  $self->{to_is_utf8} && !Encode::is_utf8($text);
52
53   return $text;
54 }
55
56 sub _init {
57   my $self = shift;
58   $self->{from}       = shift;
59   $self->{to}         = shift;
60   $self->{to}         = 'UTF-8' if lc $self->{to} eq 'unicode';
61   $self->{to_is_utf8} = $self->{to} =~ m/^utf-?8$/i;
62
63   return $self;
64 }
65
66 sub is_utf8 {
67   return shift->{to_is_utf8};
68 }
69
70 1;
71
72 __END__
73
74 =head1 NAME
75
76 SL::Iconv -- Thin layer on top of Text::Iconv including decode_utf8 usage
77
78 =head1 SYNOPSIS
79
80 Usage:
81
82   use SL::Iconv;
83
84   # Conversion without creating objects:
85   my $text_utf8 = SL::Iconv::convert("ISO-8859-15", "UTF-8", $text_iso);
86
87   # Conversion with an object:
88   my $converter = SL::Iconv->new("ISO-8859-15", "UTF-8");
89   my $text_utf8 = $converter->convert($text_iso);
90
91 =head1 DESCRIPTION
92
93 A thin layer on top of L<Text::Iconv>. Special handling is implemented
94 if the target charset is UTF-8: The resulting string has its UTF8 flag
95 set via a call to C<Encode::decode("utf-8-strict", ...)>.
96
97 =head1 CLASS FUNCTIONS
98
99 =over 4
100
101 =item C<new $from_charset, $to_charset>
102
103 Create a new object for conversion from C<$from_charset> to
104 C<$to_charset>.
105
106 =item C<convert $from_charset, $to_charset, $text>
107
108 Converts the string C<$text> from charset C<$from_charset> to charset
109 C<$to_charset>. See the instance method C<convert> for further
110 discussion.
111
112 The object used for this conversion is cached. Therefore multiple
113 calls to C<convert> do not result in multiple initializations of the
114 iconv library.
115
116 =back
117
118 =head1 INSTANCE FUNCTIONS
119
120 =over 4
121
122 =item C<convert $text>
123
124 Converts the string C<$text> from one charset to another (see C<new>).
125
126 Special handling is implemented if the target charset is UTF-8: The
127 resulting string has its UTF8 flag set via a call to
128 C<Encode::decode("utf-8-strict", ...)>. It is also safe to call
129 C<convert> multiple times for the same string in such cases as the
130 conversion is only done if the UTF8 flag hasn't been set yet.
131
132 =item C<is_utf8>
133
134 Returns true if the handle converts into UTF8.
135
136 =back
137
138 =head1 MODULE AUTHORS
139
140 Moritz Bunkus E<lt>m.bunkus@linet-services.deE<gt>
141
142 L<http://linet-services.de>