アーカイブ

2006年 4月 5日 のアーカイブ

今回は開発環境のアップデート込みだから、Delphiの仕様変更にともなって、
あたしがソースを改変してない部分でのバグが追加されているかもだ。
それにしても今回のDelphi 2006はまだ一度も落ちていない。2005より超マシ。
TNotePadのドキュメント等を2006専用ということに変更しておいた。

もう一つ大きな変更は、正規表現での検索結果も色分けするようにし、
そうするととんでもなく遅くなるのだが、鬼車という速い正規表現に乗り換えてカバー。
鬼車のDLLはVS2003でビルドした。
このDLLをUPXで圧縮すると自宅のPCで動作しない。
事務所のPCと、嫁のVAIOではUPX圧縮しても平気で動く。
真魚本体ならUPXしても動くのに、DLLが動かなくなるのは不思議。
AMDだからか?他にぜんぜん心当たりがない。
結局UPX圧縮前の224KBのままで添付することにした。
コレまで使っていたTRegExprを除去しても本体サイズはほとんど変ってないので、
今までより全体でのサイズは増えてしまった。
サイズについては、配布ZIPサイズで1MB以内を想定しているのでまだ余裕。
以前は、解凍時でフロッピーに入ることを考えていたんだがね。

一応、バージョン情報ダイアログで鬼車のバージョンも出すようにした。
鬼車のバージョンアップに追従している人は、
真魚に添付のバージョンを確認して、自前で新しいものに差し替えられるようにと。
その際、DLLのバージョン情報はリソースになってないので、
実行ファイルからじゃなきゃ確認できないって事で、コピーライトと共に取得。

あとは細々と。
Shift + Deleteの見落としとか、ひらがな含まないUTF-8への配慮とか、
デバッグ中にCPUウィンドウ見て、最適化されてないところを自前でやったり。

つい最近作った部分で、もう判定に失敗することもないんだろうと思っていたが、
先ほど真魚で判定に失敗して文字化けさせてしまった。
そのファイルが、なぜ判定失敗したかは既にわかったので、それについての話。

とりあえず、今やってる文字コード判定のソースに書いたコメントを転載。
//実際の所この関数はどう動くのか
//lenの長さかValueの長さか、小さい方をゴールとする。
//Resultの初期値はASCIIにする。
//アルファベットなどのASCII文字しか使ってない場合は、
//どの文字コードで読み込んでも同じなんだからASCIIとなる。
//途中にUTF7だと断定出来る部分が複数あれば即終了。1個くらいは偶然あるかもなので。
//途中にJISだと断定できる部分が1カ所あれば即終了。
//途中でASCII以外の文字があればJISとUTF7の判定をやめる。
//これでJISとUTF7の判定は完璧に出来る。(たぶん)
//残り三つの判定は同時進行し、断定できた時点で即終了。
//どれとも断定できなかった場合、正当なマルチバイトの数で比較する。
//ひらがなを使ったSJISは、UTF8にもEUCにも間違えない。
//ひらがなを2文字連続で使ったUTF8は、SJISにもEUCにも間違えない。
//ひらがなを使ったEUCファイルは、SJISとして変換すると半カナが多くなるので、
//正当なマルチバイトの数を比較すればEUCだと断定できる。
//よって、ひらがなを使っている日本語ファイルなら判別は完璧。(たぶん)
//別にひらがながなくても正当なマルチバイト文字数比較で精度十分なはず。
要するに、普通の日本語ファイルでは、ひらがなを使っているのが当然であり、
2文字以上連続したひらがなを使ったファイルなら判定は完璧だろうということね。
一応、ひらがなが入ってないファイルでも十分な精度になると予想していた。

で、先ほど文字化けしたファイルは、ひらがなを含まないUTF-8のファイルだ。
小原駐車場 弘前市駅前町
って感じなんだが、正当なマルチバイトの数は、UTF-8が11、S-JISが14となった。
このファイルは、SJISとして読み込むことも出来るし、UTF-8として読み込むことも出来るし、
UTF-8だとすれば11文字分の漢字などを含むし、
S-JISだとすれば14文字分の漢字などを含んでいるから、
きっとS-JISのファイルだろうなと、内部では判断したということだった。
そりゃ、S-JISは2バイトで漢字を表すが、UTF-8では2バイト以上なので、
ひらがなを含まないUTF-8はS-JISとして判定するより文字数少なくなるさね。
こりゃぁ失敗だ。

でも、これでアイデアが浮かんだ。
正当な「マルチバイトの文字数」ではなく、「正当なマルチバイトのバイト数」にすればよかった。
それで平等な比較が出来るはずだな。

B000301Z1K
B000301Z1K