FC2ブログ
上記の広告は1ヶ月以上更新のないブログに表示されています。
新しい記事を書く事で広告が消せます。
Thunderbirdでならもう少し簡単にデコードする方法がある、という情報をコメントでいただきました。
情報を元に組んだコードはこちら


前回から1ヶ月も空いてしまった。
今回は文字コードの変換について分かったことを書きます。

日本でメールのやりとりをするとき、ヘッダ部分は
ISO-2022-JPという文字コードとbase64でエンコードされている
ことが大半です。

しかし、アドオンでロジック部分を担当するJavaScriptは
内部的な文字コードがUnicodeですので、これらの文字列を扱う
(文字列検索したり、alert()で表示させたりする)ためには、
文字コードの変換が必要になります。

具体的には、たとえばメールの件名として


"古い複合機について"


という文字列は、メールの内部的には


"=?ISO-2022-JP?B?GyRCOEUkJEojOWc1ISRLJEQkJCRGGyhC?="


という文字列で表現されているので、アドオンの内部でいろいろ
使うにはこいつを変換してやらねばならないのです。

変換の詳しいことは以下のサイトに書いてあります。
すばらしい。
メールヘッダの日本語SubjectをISO-2022-JPに変換する方法(MIME(Base64))

で、このサイトを参考にして以下を実行したら変換できた。


①"=?ISO-2022-JP?B?" と "?=" で囲まれる部分を、
  base64方式でデコード

②デコードしてできた文字列を、いったんISO-2022-JP方式で
 エスケープ

③最後にその文字列をアンエスケープすると、元の日本語が見える


ISO-2022-JPのエンコード・デコード方法については
Escape Codec Library: ecl.js
base64のデコード方法については
高度な JavaScript 技集base64.js
を参考にしました。感謝。

日本語についてはこれでいけますが、ASCII文字(Aとかbとかc)については、
"=?ISO-2022-JP?B?" と "?=" で囲まれることなく
平文で書いてあるので、そこらへんうまいことロジックで
よけておかねばなりません。他にも、件名が長くなると
"=?ISO-2022-JP?B?"が何回も現れたりしますので注意してください。

具体的なソースコードについては、技術調査レベルのコードしかないので
載せません。あんまり変なのを載せると弾さんに怒られるし

なんでエスケープしてからアンエスケープしないといけないのか
理由が分からなくて気持ち悪いのですが、いろいろいじってたら
できてしまいました。なので、上記はその程度のものだという認識でお願いします。
勉強が足りなくてすみません。

次回はメールの中身を取得する方法について書くと思います。



以下雑感。

Base64では?に相当するコードは無いけど、ヘッダで使うのは別に
構わないみたいだ。
ヘッダでの非US-ASCII 文字の扱い
?は使わないことになってるくせに、文字コードを指定するために
?を使うとはこれ如何に。納得いかねぇ。

文字コードって複雑ですね。これを解決するだけでも普通に
2日3日掛かってしまいました。Joel Spolskyさんが
著書:Joel on Softwareで言っていることが
分かった気がします。

関連記事
スポンサーサイト

コメント

Thunderbird内部で使われている機能を流用する方法もありますよ。これを使うとBase64以外のエンコード形式にも対応できるというメリットもあります。
実際に以下のもので使用しています。
http://www.clear-code.com/software/tb/#normalizequotes
http://www.clear-code.com/repos/svn/thunderbird-extensions/normalize_quotes_in_addresses/trunk/content/normalizequotes/globalOverlay.js
この中で定義されているwindow.RFC2822AddressesParser.decode()の実装がそれです。
珍しくコメントが・・・と思ったら以前トラックバックさせていただいたoutsider reflex の方ですか?
コメントありがとうございます。

そんな簡単にできるんですか…他の人が真似したらいけないので、
この投稿は大幅に訂正します。
ありがとうございました_(._.)_
どもです。
言うほど簡単というわけでもない(これはこれでおまじない的な記述が必要)ので、どうなんだろう、という感じもしますけどね……

ちなみに、「To」「Cc」「Bcc」あたりのフィールドからメールアドレスを取り出すということだけであれば、以下でいけます。
http://mxr.mozilla.org/mozilla1.8/source/mailnews/mime/public/nsIMsgHeaderParser.idl

var parser = Components.classes['@mozilla.org/messenger/headerparser;1'].getService(Components.interfaces.nsIMsgHeaderParser);
var addresses = {};
var names = {};
var fullnames = {};
var count = {};
parser.parseHeadersWithArray('元の文字列', addresses, names, fullnames, count);
// addresses.value, name.value, fullnames.valueはデコード後の文字列の配列

上のコメントで示した物は、nsIMsgHeaderParserのparseHeadersWithArrayの実装からコードを抜き出して、他の場面でも無理矢理流用してみよう、という物です。

コメントの投稿

  • URL
  • コメント
  • パスワード
  • 秘密
  • 管理者にだけ表示を許可する

トラックバック

トラックバックURL:http://remotehost.blog54.fc2.com/tb.php/20-05517c42
上記広告は1ヶ月以上更新のないブログに表示されています。新しい記事を書くことで広告を消せます。