CGI:IRC

IRCチャットをWWWブラウザから使えるようにするCGIシステム CGI:IRC をUTMCのサーバにインストールした.
http://cgiirc.sourceforge.net/
海外で作られたものなのでそのままでは日本語が通らない*1Jcode.pmjcode.plという漢字コード変換モジュール*2を使った日本語化パッチがmya氏により作られている.
http://ijc.ne.jp/~mya/index.cgi/net?page=CGIIRC%A4%F2%C6%FC%CB%DC%B8%EC%A4%C7%BB%C8%A4%AA%A4%A6
ところがパッチの最新版はcgiirc 0.5.3向けで,本家の最新版0.5.4ではうまく機能しない.そこで今日はしばらく頭をひねって0.5.3向けパッチを参考に0.5.4向けパッチを書いてみた.
辛かったよ... Perlなんてまともに使ったことないのに.文字コード問題ってそもそも複雑なんだよね.日本語IRCサーバは普通ISO-2022-JPに対応しているが,ブラウザが送るユーザのメッセージ文字列は「ASCII文字はそのまま,マルチバイト文字はUCS-2を基準に %u30fa 等とASCII文字でエンコード」という訳の分からん方式*3.Jcode.pmはUnicode系のうちではUTF-8UCS-2にしか対応してないので,どっちかにしなければならない.エンコードされたマルチバイト文字を正規表現で見つけ出し,関数packを使って元の2byteに戻す.そこにJcodeを使ってUCS-2からEUC-JPに変換(EUC-JPにおいてはASCII文字列は変換の必要がない).つーことで次のようになる((4回繰り返しには |4| が使えるとも聞くが...)).

$line =~ s/%u([\da-f][\da-f][\da-f][\da-f])/Jcode->new(pack('H4', $1), 'ucs2')->euc/egi 

このEUC-JP文字列がブラウザで表示される.んで,IRCサーバに送る方は送る関数を見つけてISO-2022-JPに変換.その関数はmya氏のパッチを参考にして判別できたんだけど,どのエンコーディング方法を基本にするかで大変困った.あーするとブラウザではちゃんと読めるがみんなが普通のIRCクライアントから見ると化ける,こーするとみんなは読めるがブラウザで読めない,今度はどっちも化ける... サーバがISO-2022-JPを基準にするなら全部それに変えればいいじゃん,と言うかも知れないが,ISO-2022-JPはマルチバイト文字列の前後にエスケープシーケンスを埋めるので,1文字ずつ変換している↑の方式では無駄なエスケープシーケンスが生じたり,色々嬉しくない.
慣れてる人には簡単なことなのかも知れないけど,私はこういうのは... むしろ慣れたくもないこんなの.もう二度とごめんだ*4

*1:1byte=char型=1文字というぬるま湯で育った毛唐どもめが! C/C++にbyte型を新設し,数年後にそっとchar型を(UCS-4の入る)4byteに広げねばアジアは救われない! 最近はプログラミング言語/環境の方では次第にUnicode対応が進んでいるが,まだまだ心理面では遅れている.

*2:繰り返すようだけど,Perl5では大変充実したUnicodeサポートが実現されている.Perlはキモいので使う気はないが豊富な機能は確かに魅力だ...

*3:Unicodeエンコーディング方法のうち,ASCII文字を不変に保つのはUTF-8.しかしこれは1文字を表すbyte数が1から3までの場合があり,2byte固定のUCS-2とはかなり異質.あ,UTF-8では規格上6byte文字も存在するらしいがあまり縁はなさそう.それとUCS-2と書いたが,実はUTF-16かも知れない...

*4:UTMCの1年生がもっと気軽にIRCチャットに参加してくれればいいと思って CGI:IRC を整備したのだった.