## ## このクラスについて ## 「メールヘッダのエンコードクラス」 ## ## バージョン ## 「1.11」 ## ## (C) 飛田 益夫丸 ## ## メモ:予め、jcode.plを要求してから使います。 ## package ap_mimeenc; #use strict "vars"; ## メールヘッダ用の名前に使う文字列を返す ## @param string 名前 ## @param string mail ## @return string sub get_name_and_mailaddr { my( $str, $mail ) = @_; my $ret = ap_mimeenc::getName( $str ); if( length( $ret ) > 0 ) { return $ret."<".$mail.">"; } return $mail; } ## メールヘッダ用の名前に使う文字列を返す ## @param string ## @return string sub get_name { my( $str ) = @_; my $ret = ap_mimeenc::_encode( $str ); #常にクォートで if( length( $ret ) > 0 ) { return "\"".$ret."\""; } return ""; } ## メールヘッダ用のSubjectに使う文字列を返す ## @param string ## @return string sub get_subject { my( $str ) = @_; return ap_mimeenc::_encode( $str ); } ## JISに変換したメールヘッダ用文字列を返す ## @param string ## @return string sub _encode { my( $str ) = @_; my $ret = ""; #jcodeで安全な文字へ変換 jcode::convert( \$str, 'euc' ); jcode::h2z_euc( \$str ); #メールヘッダに影響のある文字を置換 $str =~ s/\t/ /g; $str =~ s/\0/ /; $str =~ s/[\n\r\f\a\e]/ /g; #前後の空白を削除(ltrim風とrtrim風) while( substr( $str, 0, 1 ) =~ /\s/ ) { substr( $str, 0, 1, "" ); } while( substr( $str, -1 ) =~ /\s/ ) { chop( $str ); } my $char = ""; my $char2 = ""; my $off = 0; my $ret2 = ""; my $j_flag = 0; if ( ($str =~ /[\xA1-\xFE][\xA1-\xFE]/) || ($str =~ /\W/) ) { #漢字、記号あり while( length( $str ) > $off ) { $char = substr( $str, $off, 1 ); $off++; if( ($char =~ /\x8F$/) || ($char =~ tr/\x8E\xA1-\xFE// % 2 ) ) { $j_flag = 1; } else { $j_flag = 0; } if( ($j_flag == 0) && ( ($char =~ //) || ($char =~ /\@/) ) ) { #問題のある記号を読み込んだ #前の文字をエンコード if( $char2 ne "" ) { $ret2 = ""; jcode::convert( \$char2, 'jis' ); ap_mimeenc::encodeToBase64( \$char2, \$ret2, undef ); $ret .= "=?iso-2022-jp?B?".$ret2."?="; $char2 = ""; } #問題のある記号は、 #差出人名用にエンコードすると表示されないので、 #そのまま連結 $ret .= $char; #次へ next; } elsif( $j_flag == 1 ) { #日本語読みかけ開始 #日本語読みかけ開始の状態で、前が英数のみなら前をエンコード #(記号は即エンコードするので、ここでは英数のみ) if( ($char2 ne "") && ($char2 !~ /\W/) ) { #そのまま連結 $ret .= $char2; $char2 = ""; } $char2 .= $char; #次へ next(); } elsif( $char2 eq "" ) { #何らかの文字読みかけなし #英数の読込み開始 $char2 .= $char; #次へ next(); } else { #日本語、または英数の文字読みかけ続き $char2 .= $char; #次へ next(); } } if( length( $char2 ) > 0 ) { if( $char2 !~ /\W/ ) { #英数はそのまま連結 $ret .= $char2; } else { #日本語 $ret2 = ""; jcode::convert( \$char2, 'jis' ); ap_mimeenc::encodeToBase64( \$char2, \$ret2, undef ); $ret .= "=?iso-2022-jp?B?".$ret2."?="; } } } else { #漢字、記号なし(エンコードしなくても良い) #jcode::convert( \$str, 'jis' ); #ap_mimeenc::encodeToBase64( \$str, \$ret, undef ); #$ret = "=?iso-2022-jp?B?".$ret."?="; return $str; } #返す return $ret; } ## Base64エンコード ## @param string_ref 元のあれ ## @param string_ref 返すあれ ## @param boolean \nをラインの最後に付ける ## @return void sub encodeToBase64 { my( $in_ref, $out_ref, $eol ) = @_; ${$out_ref} = pack( "u", ${$in_ref} ); if( $eol ) { $eol = "\n"; } else { $eol = ""; } #影響のある文字を消す ${$out_ref} =~ s/^.//mg; ${$out_ref} =~ s/\n//g; ${$out_ref} =~ tr|` -_|AA-Za-z0-9+/|; my $padding = (3 - length($$in_ref) % 3) % 3; if( $padding >= 1 ) { $$out_ref =~ s/.{$padding}$/'=' x $padding/e; } if (length( $eol ) ) { ${$out_ref} =~ s/(.{1,76})/$1$eol/g; } return; } 1;