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