#======================================================== # MailFileUTF8 #======================================================== package MailFileUTF8; use Common; @ISA = qw(Common); use strict; use Encode qw/encode decode from_to/; use utf8; use Jcode; use Mail::MailPart; #============================================================ # 変数 #============================================================ my $DefaultCode = 'utf8'; my @MonthName = ("Jan", "Feb", "Mar", "Apr", "May", "Jun", "Jul", "Aug", "Sep", "Oct", "Nov", "Dec"); my @WeekDayName = ("Sun", "Mon", "Tue", "Wed", "Thu", "Fri", "Sat"); my %ShortMonthName = ( Jan => '01', Feb => '02', Mar => '03', Apr => '04', May => '05', Jun => '06', Jul => '07', Aug => '08', Sep => '09', Oct => '10', Nov => '11', Dec => '12', ); #============================================================ # 静的関数 #============================================================ #============================================================ # コンストラクタ、デストラクタ #============================================================ BEGIN { } sub new { my ($module) = @_; my $this = {}; bless $this; return $this; } sub DESTROY { my $this = shift; } #============================================================ # 一般関数 #============================================================ sub AddHash { my ($this, @a) = @_; for(my $i = 0 ; $i < @a ; $i += 2) { $this->{$a[$i]} = $a[$i+1]; } } sub GetHeaderArray { my ($this) = @_; return $this->{pSourceHeader}; } sub GetHeader { my ($this) = @_; return join('', @{$this->{pSourceHeader}}); } sub GetFullContentArray { my ($this) = @_; return $this->{pSourceFullContent}; } sub GetFullContent { my ($this) = @_; return join('', @{$this->{pSourceFullContent}}); } #sub GetMailBodyArray #{ # my ($this) = @_; # return $this->{pSourceBody}; #} #sub GetMailBoy #{ # my ($this) = @_; # return join('', @{$this->{pSourceBody}}); #} sub GetContentArray { my ($this) = @_; return $this->{Content}; } sub GetContent { my ($this) = @_; return join('', @{$this->{Content}}); } sub GetMonthName { my ($this, $iDate) = @_; return $MonthName[$iDate]; } sub GetWeekDayName { my ($this, $iDate) = @_; return $WeekDayName[$iDate]; } sub GetMonthFromName { my ($this, $name) = @_; Utils::DelSpace($name); return $name+0 if($name =~ /^\d+$/); $name = lc $name; for(my $i = 0 ; $i < @MonthName ; $i++) { if($name eq lc $MonthName[$i]) { return $i+1; } } return 0; } sub ConvertDateString { my ($this, $Date, $format) = @_; #format: '{year04}/{month02}/{day02} {hour02}:{min02} {difftime}' my ($wday, $mday, $mon, $year, $time, $difftime) = Utils::Split("[,\\s]+", $Date); #Wed, 27 Apr 2011 15:56:23 +0900 if($wday =~ /^\d+$/) { ($mday, $mon, $year, $time, $difftime) = ($wday, $mday, $mon, $year, $time, $difftime); } my $imon = ($ShortMonthName{$mon})? $ShortMonthName{$mon} : $mon; my ($hour, $min, $sec) = Utils::Split("[\\s:]", $time); my $s = $format; my $s1 = sprintf('%04d', $year); $s =~ s/{year04}/$s1/g; $s1 = sprintf('%02d', $imon); $s =~ s/{month02}/$s1/g; $s1 = sprintf('%02d', $mday); $s =~ s/{day02}/$s1/g; $s1 = sprintf('%02d', $hour); $s =~ s/{hour02}/$s1/g; $s1 = sprintf('%02d', $min); $s =~ s/{min02}/$s1/g; $s1 = sprintf('%02d', $sec); $s =~ s/{sec02}/$s1/g; $s =~ s/{difftime}/$difftime/g; return "$s ($Date)" if(!defined $ShortMonthName{$mon}); return $s; } sub SplitDate { my ($this, $Date) = @_; my ($DayOfWeek, $DayOfMonth, $Month, $Year, $hour, $min, $sec, $TimeDifference) = ($Date =~ /^(\w+),\s*(\d+)\s+([\w\d]+)\s+(\d+)\s+(\d+):(\d+):(\d+)\s+([\+\-\d]*)/); return ($DayOfWeek, $DayOfMonth, $Month, $Year, $hour, $min, $sec, $TimeDifference); } sub SplitEMailAddress { my ($this, $address) = @_; my ($name, $email); if($address =~ /^\s*(.*)\<([^\>]+)\>\s*(.*)\s*$/) { $name = "$1 $3"; Utils::DelSpace($name); $email = $2; } if(!defined $email and $address =~ /^\s*(.*)\(([^\)]+)\)\s*(.*)\s*$/) { $name = $2; $email = "$1 $2"; Utils::DelSpace($email); } if(!defined $email) { $name = ""; $email = $address; Utils::DelSpace($email); } Utils::DelQuote($name); return ($email, $name); } sub GetContentFromContentType { my ($this, $ContentType) = @_; my $p = $this->GetPartInfFromContentType($ContentType); return '' if(!$p); return $p->{Content}; } sub GetPartInfFromContentType { my ($this, $ContentType) = @_; my $psp = $this->{pSerialPartsInf}; my $nParts = @$psp; for(my $i = 0 ; $i < $nParts ; $i++) { my $p = $psp->[$i]; if($p->{ContentType} =~ /$ContentType/i) { return $p; } } return ''; } sub DecodeSubject { my ($this, $str, $code, $UseEncodeModule) = @_; return '' if(!defined $str or $str eq ''); my $s = ''; my $prevtail = $str; for(my $i = 0 ; ; $i++) { Utils::DelSpace($prevtail); my ($head, $encode, $method, $line, $tail, $tail2) = (''); ($encode, $tail2) = ($prevtail =~ /=\?([^\?]+?)\?(.*)$/s); ($method, $tail2) = ($tail2 =~ /([^\?]+?)\?(.*)$/s) if($tail2); ($line, $tail) = ($tail2 =~ /^(.*?)\?=(.*)$/s) if($tail2); if(!defined $tail) { $line = $tail2; } # ($encode, $method, $line, $tail) = ($prevtail =~ /=\?([^\?]+?)\?([^\?]+?)\?(.*?)\?=(.*)$/); # ($head, $encode, $method, $line, $tail) = ($prevtail =~ /^([^=]*?)=\?([^\?]+?)\?([^\?]+?)\?(.*?)\?=(.*)$/); # $encode = lc $encode; $encode = '' if(!defined $encode); $code = '' if(!defined $code); $method = '' if(!defined $method); #print "prevtail[$i]: $prevtail
\n"; #print " encode: $encode => $code
\n"; #print " method: $method
\n"; #print " line: $line
\n\n"; last if(!defined $line); return $str if(!$encode); if($method =~ /^B/i) { #print " B [$line]
\n"; $line = Utils::Base64Decode($line); } elsif($method =~ /^Q/i) { $line = Utils::QPDecode($line); } else { print "Error in MailFile::DecodeSubject: Encode method [$method] is not supported.\n"; return undef; } if($UseEncodeModule) { # $line = decode($encode, $line); # $line = encode($code, $line); from_to($line, $$encode, $code); } else { Utils::convert(\$line, $code, $encode); } #if($code and $code ne 'ascii') { # if($encode) { ##print "encode from [$line] "; # Utils::convert(\$line, $code, $encode); ##print "to [$line]\n"; # } # else { # Utils::convert(\$line, $code); # } #} $s .= $head . $line; #print " s [$s]
\n"; $prevtail = $tail; } $s .= $prevtail if($prevtail); #print "S [$s]
\n"; #Utils::convert(\$s, 'utf-8'); return $s; } sub SaveDecodedContent { my ($this, $fname, $code, $RemoveHeader) = @_; my $DecodedContent = $this->DecodeContent($code, $RemoveHeader); $fname =~ s/\.\w+?$//; if($this->{ContentType} =~ /text\/html/i) { my $path = "$fname.html"; print "MailFile::SaveDecodedContent: Save to [$path].\n"; open(OUT, ">$path") or die $!; print OUT $DecodedContent; close(OUT); } elsif($this->{ContentType} =~ /text\//i) { my $path = "$fname.txt"; print "MailFile::SaveDecodedContent: Save to [$path].\n"; open(OUT, ">$path") or die $!; print OUT $DecodedContent; close(OUT); } elsif($this->{FileName}) { my $path = ($fname)? $fname : $this->{FileName}; print "MailFile::SaveDecodedContent: Save to [$path].\n"; open(OUT, ">$path") or die $!; binmode(OUT); print OUT $DecodedContent; close(OUT); } else { print "Error in MailFile::SaveDecodedContent: Invalid type [$this->{ContentType}].\n"; } } sub GetNextHeader { my ($this, $c, $code, $KeepCRLF, $pStrArray) = @_; return undef if($c < 0); my $key; my $s; while(1) { my $line = $pStrArray->[$c++]; #print "line1 [$c] $line"; if(!defined $line or $line !~ /^\S+:/) { return undef; } ($key, $s) = ($line =~ /^(.*?):\s*(\S.*?)\s*$/); $s .= "\n" if($KeepCRLF); while(1) { my $line2 = $pStrArray->[$c++]; if(!defined $line2 or $line2 =~ /^\s*$/) { #print "line2 [$c] $line2"; return ($key, $s, -1); } if($line2 =~ /^\S+:/) { $c--; return ($key, $s, $c); } if($KeepCRLF) { $s .= $line2; } else { Utils::DelSpace($line2); $s .= $line2; } } } return ($key, $s, $c); } sub ReadHeader { my ($this, $code, $KeepCRLF, $pStrArray) = @_; return if(!defined $pStrArray and !defined $this->{pSourceHeader}); $code = $DefaultCode if(!$code); $KeepCRLF = 0 if(!defined $KeepCRLF); #なぜか$this->{pSourceHeader}にアクセスすると$this->{pSourceHeader}がクリアーされる my @SH = ($this->{pSourceHeader})? @{$this->{pSourceHeader}} : (); # $pStrArray = $this->{pSourceHeader} if(!defined $pStrArray); # $pStrArray = $this->{Content} if(!defined $pStrArray); # my $pStrArray2 = (defined $pStrArray)? $pStrArray : $this->{pSourceHeader}; my $pStrArray2 = (defined $pStrArray)? $pStrArray : \@SH; #print "ReadHeader: p2=$this->{pSourceHeader}, $this->{Content}\n"; #print "ReadHeader: Header[$pStrArray2]\n"; #print "ReadHeader: Header[[@$pStrArray2]]\n"; my $c = 0; my ($key, $s); while(1) { ($key, $s, $c) = $this->GetNextHeader($c, $code, $KeepCRLF, $pStrArray2); last if(!defined $key); #print "Header: $key [$c]: $s\n"; $this->{$key} = $s; } } sub Parse { my ($this, $code) = @_; #print "SCF: ", @{$this->{pSourceFullContent}}, "

\n"; my ($pHeader, $pContent) = $this->SplitHeaderFromString($this->{pSourceFullContent}); # $this->{pSourceHeader}= $pHeader; # $this->{Content} = $pContent; #print "Parse: p1=$pHeader, $pContent\n"; #print "Parse: p2=$this->{pSourceHeader}, $this->{Content}\n"; #print "Parse: HD: ", @$pHeader, "

\n"; $this->ReadHeader($code, 0); my $ContentType = $this->GetHeaderFromString("Content-Type", $code, 0); my $ContentTransferEncoding = $this->GetHeaderFromString("Content-Transfer-encoding", $code, 0); my $ContentDisposition = $this->GetHeaderFromString("Content-Disposition", $code, 0); my $Boundary = $this->GetBoundaryFromContentType($ContentType); my $CharSet = $this->GetCharSetFromContentType($ContentType); my $AttachFileName = $this->GetAttachFileNameFromContentType($ContentType, $ContentDisposition); $this->AddHash( Content => $this->{pSourceFullContent}, ContentType => $ContentType, ContentTransferEncoding => $ContentTransferEncoding, ContentDisposition => $ContentDisposition, CharSet => $CharSet, Boundary => $Boundary, FileName => $AttachFileName, ); # my ($Boundary, $type, $pPartsInf) = $this->GetMultipartInfoFromString(); # $this->{SourceBoundary} = $Boundary; # $this->{SourcepPartsInf} = $pPartsInf; $this->{pSerialPartsInf} = []; my $count = 0; my $iLevel = 0; $this->AddPartsInf($this->{pSourceFullContent}, $count, $iLevel); } sub AddPartsInf { my ($this, $Content, $count, $iLevel) = @_; my ($Boundary, $type, $pPartsInf) = $this->GetMultipartInfoFromString($DefaultCode, $Content); my $nParts = @$pPartsInf; #print "c=$count: l=$iLevel: n=$nParts\n"; for(my $i = 0 ; $i < $nParts ; $i++) { my $p = $pPartsInf->[$i]; my $type = $p->{ContentType}; #print " c=$count: i=$i: type=", substr($type, 0, 30), "\n"; if($type =~ /multipart\//i) { #print "multipart: present count=$count [i=$i] [l=$iLevel] [p=$p]\n"; $count = $this->AddPartsInf($p->{Content}, $count, $iLevel+1); #print " out count=$count [i=$i]\n"; } else { #print "present count=$count [i=$i] [l=$iLevel] [p=$p]\n"; $p->{iLevel} = $iLevel; $this->{pSerialPartsInf}->[$count++] = $p; } } return $count; } sub GetBoundaryFromContentType { my ($this, $ContentType) = @_; my ($Boundary) = ($ContentType =~ /boundary\s*=\s*"([^"]*)"/i); if(!$Boundary) { ($Boundary) = ($ContentType =~ /boundary\s*=\s*(.*);?/i); } return $Boundary; } sub GetCharSetFromContentType { my ($this, $ContentType) = @_; my ($CharSet) = ($ContentType =~ /charset\s*=\s*"([^"]*)"/); if(!$CharSet) { ($CharSet) = ($ContentType =~ /charset\s*=\s*(.*);?/); } return $CharSet; } sub GetAttachFileNameFromContentType { my ($this, $ContentType, $ContentDisposition, $code) = @_; $code = $DefaultCode if(!defined $code); my $FileName; if($ContentType) { ($FileName) = ($ContentType =~ /name\s*=\s*"(.*)"$/i); if(!$FileName) { ($FileName) = ($ContentType =~ /name\s*=\s*(.*?)\s*$/i); } } #$FileName = undef; if(!$FileName and $ContentDisposition) { ($FileName) = ($ContentDisposition =~ /filename\s*=\s*"([^"]*)"/i); if(!$FileName) { ($FileName) = ($ContentDisposition =~ /filename\s*=\s*(.*?)\s*/i); } if(!$FileName) { #print "CD: $ContentDisposition\n"; ($FileName) = ($ContentDisposition =~ /filename\*0\*=\s*(.*?)\s*$/i); #print "f=$FileName\n"; if(defined $FileName and $FileName =~ s/^iso-?2022-?jp''//i) { #print " f1=$FileName\n"; $FileName =~ s/;filename[^=]*?=//g; #print " f2=$FileName\n"; $FileName = Utils::URLDecode($FileName); Utils::convert(\$FileName, $code, "jis"); #print " f3=$FileName\n"; } #exit; } } return $FileName; } sub GetMultipartInfoFromString { my ($this, $code, $pStrArray) = @_; $code = $DefaultCode if(!$code); $pStrArray = $this->{pSourceFullContent} if(!defined $pStrArray); my $ContentType = $this->GetHeaderFromString("Content-Type", $code, 0, $pStrArray); #print "CT: $ContentType\n"; my $Boundary = $this->GetBoundaryFromContentType($ContentType); #print "BD: $Boundary\n"; #return undef if(!defined $Boundary); $Boundary = "nqler0tg89xcl;rejt3j" if(!defined $Boundary); $this->{SourceBoundary} = $Boundary; my ($type) = ($ContentType =~ /(\w+\/\w+);/); my $HeadBoundary = "--$Boundary"; my $LastBoundary = "$Boundary--"; #print "HeadB: [$HeadBoundary]\n"; #print "LastB: [$LastBoundary]\n"; my $iPart = 0; my @Parts; my $c = 0; while(1) { my $line = $pStrArray->[$c++]; last if(!$line); Utils::DelSpace($line); last if($line eq $HeadBoundary); } while(defined $pStrArray->[$c]) { my @s; my $cs = 0; while(1) { my $line = $pStrArray->[$c++]; last if(!defined $line); #print "$c-$iPart-$cs: $line"; my $l = $line; Utils::DelSpace($l); last if($l eq $HeadBoundary or $l eq $LastBoundary); $s[$cs++] = $line; } $Parts[$iPart] = \@s; $iPart++; } my $nPart = @Parts; #print "nPart=$nPart\n"; my @PartsInf; for(my $i = 0 ; $i < $nPart ; $i++) { #print "$i: ", @{$Parts[$i]}, "\n"; my $ContentType = $this->GetHeaderFromString("Content-Type", $code, 0, $Parts[$i]); my $ContentTransferEncoding = $this->GetHeaderFromString( "Content-Transfer-encoding", $code, 0, $Parts[$i]); my $ContentDisposition = $this->GetHeaderFromString( "Content-Disposition", $code, 0, $Parts[$i]); my $Boundary2 = $this->GetBoundaryFromContentType($ContentType); my $CharSet = $this->GetCharSetFromContentType($ContentType); my $AttachFileName = $this->GetAttachFileNameFromContentType($ContentType, $ContentDisposition); #print "$i: CT: $ContentType\n"; #print "$i: E : $ContentTransferEncoding\n"; #print "$i: CD: $ContentDisposition\n"; my $pInf = new MailPart; $pInf->ReadHeader($code, 0); my $From = $pInf->GetHeaderFromString("From", $DefaultCode, 0); #, $p->{Content}); my $To = $pInf->GetHeaderFromString("To", $DefaultCode, 0); #, $p->{Content}); my $Cc = $pInf->GetHeaderFromString("Cc", $DefaultCode, 0); #, $p->{Content}); my $Bcc = $pInf->GetHeaderFromString("Bcc", $DefaultCode, 0); #, $p->{Content}); $pInf->AddHash( Content => $Parts[$i], From => $From, To => $To, Cc => $Cc, Bcc => $Bcc, ContentType => $ContentType, ContentTransferEncoding => $ContentTransferEncoding, ContentDisposition => $ContentDisposition, CharSet => $CharSet, Boundary => $Boundary2, FileName => $AttachFileName, ); $PartsInf[$i] = $pInf; } return ($Boundary, $type, \@PartsInf); } sub GetHeaders { my ($this, $pKeys, $Decode, $def, $code) = @_; $Decode = 0 if(!defined $Decode); my %hash; foreach my $key (@$pKeys) { #print "key=$key\n"; $hash{$key} = $this->GetHeaderFromString($key); #print "header:$hash{$key}\n"; my ($encode) = ($hash{$key} =~ /=\?(.*?)\?/); #print "encode=$encode\n"; $hash{$key} = $this->DecodeSubject($hash{$key}, $code); $hash{$key} = $def if(defined $def and $hash{$key} eq ''); if($code and $code ne 'ascii') { if($encode) { Utils::convert(\$hash{$key}, $code, $encode); } else { Utils::convert(\$hash{$key}, $code); } } } return %hash; } sub GetHeaderFromString { my ($this, $key, $code, $KeepCRLF, $pStrArray) = @_; $code = $DefaultCode if(!$code); $KeepCRLF = 0 if(!defined $KeepCRLF); #print "pSA: [$pStrArray]
\n"; $pStrArray = $this->{pSourceHeader} if(!defined $pStrArray); #print "pSA2: [$pStrArray]
\n"; $pStrArray = $this->{Content} if(!defined $pStrArray); #print "pSA3: [$pStrArray]
\n"; #print join('
', @$pStrArray), "
\n"; my $c = 0; my $header = ''; while(1) { my $s = $pStrArray->[$c++]; return $header if(!defined $s); if($s =~ /^$key:\s+(.*)$/i) { $header = $1; Utils::DelSpace($header); if($KeepCRLF) { $header .= "\n"; } last; } } while(1) { my $line = $pStrArray->[$c++]; return $header if(!defined $line); last if(!defined $line or $line !~ /^\s/); if(!$KeepCRLF) { Utils::DelSpace($line); } $header .= $line; } Utils::convert(\$header, $code); return $header; } sub SplitHeaderFromString { my ($this, $pStrArray, $code, $HeaderOnly) = @_; $code = $DefaultCode if(!$code); $HeaderOnly = 0 if(!defined $HeaderOnly); $pStrArray = $this->{pSourceHeader} if(!defined $pStrArray); $pStrArray = $this->{Content} if(!defined $pStrArray); #print "SCF2: ", @$pStrArray, "

\n"; my @header; my $ch = 0; my @content; my $cc = 0; my $c = 0; while(1) { my $line = $pStrArray->[$c++]; #print "l[$c]: $line
\n"; return ('', '') if(!defined $line); last if(!defined $line or $line =~ /^\s*$/); if($c == 1 and $line =~ /^From\s/) { next; } if($c == 1 and $line !~ /^\S+:/) { $c = 0; last; } $header[$ch++] = $line; } $this->{pSourceHeader} = \@header; return (\@header, undef) if($HeaderOnly); while(1) { my $line = $pStrArray->[$c++]; last if(!defined $line); # last if($line =~ /^\s*$/); $content[$cc++] = $line; } $this->{Content} = \@content; return (\@header, \@content); } sub GetAttachedFileName { my ($this, $pHeader, $charcode) = @_; my $ContentType = $this->GetHeaderFromString("Content-Type", $charcode, 0, $pHeader); my $ContentDisposition = $this->GetHeaderFromString("Content-Disposition", $charcode, 0, $pHeader); my ($filename) = ($ContentType =~ /name\s*=\s*\"(.*)\"/si); if($filename eq '') { ($filename) = ($ContentDisposition =~ /filename\s*=\s*\"(.*)\"/si); } # if($filename eq '') { # ($filename) = ($Header =~ /filename\s*=\s*\"(.*)\"/); # } Utils::convert(\$filename, $charcode) if($charcode ne ''); return $filename; } sub Read { my ($this, $path, $HeaderOnly, $code, $UseEncodeModule) = @_; delete $this->{SourcePath}; my $in = new JFile($path, "r"); return undef if(!$in); $this->{SourcePath} = $path; my @text; my $c = 0; while(1) { my $line = $in->ReadLine(0, $code, $UseEncodeModule); last if(!defined $line); last if($HeaderOnly and $line =~ /^\s*$/); #if($code and $UseEncodeModule) { # $line = decode($code, $line); #} $text[$c] = $line; $c++; } $in->Close(); $this->{pSourceFullContent} = \@text; #print "SCF0: ", @{$this->{pSourceFullContent}}, "

\n"; $this->Parse(); return \@text; } sub DecodeContent { my ($this, $code, $RemoveHeader, $UseEncodeModule, $content, $encode) = @_; $RemoveHeader = 1 if(!defined $RemoveHeader); $UseEncodeModule = 0 if(!defined $UseEncodeModule); $encode = $this->{ContentTransferEncoding} if(!defined $encode); # my $pContent = $this->{Content}; my ($pHeader, $pContent); my $DecodedContent; if(defined $content) { $DecodedContent = $content; } else { ($pHeader, $pContent) = $this->SplitHeaderFromString($this->{Content}); # if(!$RemoveHeader) { # $pContent = $this->{Content}; # } $DecodedContent = join('', @$pContent); } #print "Decode [$encode]\n"; if($encode =~ /base64/i) { #print "=====\n$DecodedContent=====\n"; $DecodedContent = Utils::Base64Decode($DecodedContent); #$DecodedContent = encode($DefaultCode, $DecodedContent); #print "=====\n$DecodedContent=====\n"; # for(my $k = 0 ; $k < @$pContent ; $k++) { # $DecodedContent .= Utils::Base64Decode($pContent->[$k]); # } } elsif($encode =~ /quoted-printable/i) { $DecodedContent = Utils::QPDecode($DecodedContent); # for(my $k = 0 ; $k < @$pContent ; $k++) { # $DecodedContent .= Utils::QPDecode($pContent->[$k]); # } } else { # for(my $k = 0 ; $k < @$pContent ; $k++) { # $DecodedContent .= $pContent->[$k]; # } } my $ContentType = $this->{ContentType}; my $CharSet = $this->{CharSet}; if($CharSet and $code) { # if($ContentType !~ /html/i and $CharSet and $code) { $CharSet = 'jis' if($CharSet =~ /iso-?2022-?jp/i); $CharSet = 'utf8' if($CharSet =~ /UTF-8/i); #print "code=$code: CharSet=$CharSet\n"; #$UseEncodeModule=1; if($code ne '' and $code ne 'ascii') { if($UseEncodeModule) { #print "Decode:$DecodedContent\n"; # $DecodedContent = encode($code, $DecodedContent); from_to($DecodedContent, $CharSet, $code); } else { #print "CS:$CharSet to $code\n"; ## if($CharSet =~ /sjis/i) { ## Utils::convert(\$DecodedContent, $code, $CharSet); ## } ## else { if($CharSet) { Utils::convert(\$DecodedContent, $code, $CharSet); } else { Utils::convert(\$DecodedContent, $code); } ## } } } } if(!$RemoveHeader) { $DecodedContent = join('', @$pHeader) . $DecodedContent if(defined $pHeader); } return $DecodedContent; } 1;