HTMLDocument と Numeric character references
Java で HTML を読み込み、その内容を元に別の HTML を出力するちょっとしたプログラムを書こうとしています。こんな時、Java には HTMLEditorKit という便利なクラスがあります。これを使うと HTML を解析して HTMLDocument という HTML の内容を表すドキュメントクラスのインスタンスを生成してくれます。これがどんなに便利かは古い記事ですが、この記事等を読むとわかります。
さて逆に HTMLDocument の内容 HTML として出力しようとする時は HTMLWriter を使うことができます。ところがこれを使って日本語の HTMLDocument を出力しようとすると "このとこ" のような内容で出力されてしまいます。一瞬「また、文字化け??」と思ってしまいましたが、これはれっきとした HTML の書式で"Numeric character references (NCR)"と呼ばれるものだそうです。日本語では数値文字参照というようです。
「うーん、何で EUC や シフト JIS で出してくれないの??」と思い、Web 検索するもこのあたりの情報は乏しいです。仕方がないのでクラスのソースを見てみると、HTMLWriter クラスで思いっきり次のように書かれていました。
acscii でなけりゃ問答無用で NCR だということです。作った人はそれで済む国の人なのでしょう。日本でエディタ等を使って HTML を書くような人はシフト JIS や EUC で出力されないと困りますよね。
今回は EUC で出力したいのでどうしたものかと考えました。 HTMLWriter のサブクラスを作って該当の output 関数のみ override して HTMLWriter.output の丸コピーのチョイ直しという手も考えました。しかしそうすると HTMLWriter クラスの replaceEntities という重要なフラグが private なので参照することができません。本来 HTMLWriter が NCR で出力するかネイティブな文字コードで出力するか動作を選択できるようになっているべきなのでしょう。
そこで今回は使い捨てのプログラムだからと割り切り、出力する Writer の方にサブクラスをつくって"数字;" が来たらいつも使っているダブルバイトの文字に直すようにすることにしました。
で書いてみたのが、下のクラスです。このクラスのインスタンスを使って HTMLWriter を生成します。先に参照したソースの部分の output 呼び出し3連発に依存する書き方です。使い捨てなのでいいのです。
public class NCR2NativeWriter extends java.io.OutputStreamWriter {
private int count;
private String tempString; // NCR format string
public NCR2NativeWriter(OutputStream out, String s)
throws java.io.UnsupportedEncodingException {
super(out, s);
count = 0;
}
public void write(char cbuf, int off, int len)
throws java.io.IOException {
if (off != 0) {
super .write (cbuf, off, len);
return;
}
if (count == 0 && len == 2 && cbuf[0] == '&' && cbuf[1] == '#') {
count = 1;
return;
} else if (count == 1) {
int i = 0;
for (; i < len; i++) {
if (cbuf[i] > '9' || cbuf[i] < '0') {
break;
}
}
if (i >= len) {
tempString = new String(cbuf, 0, len);
count = 2;
return;
} else {
super .write ("");
}
} else if (count == 2) {
if (len == 1 && cbuf[0] == ';') {
char c[] = new char[1];
c[0] = (char)new Integer(tempString).intValue();
super .write (c, 0, 1);
count = 0;
return;
} else {
super .write ("");
super .write (tempString);
}
}
super .write (cbuf, 0, len);
count = 0;
}
}
private int count;
private String tempString; // NCR format string
public NCR2NativeWriter(OutputStream out, String s)
throws java.io.UnsupportedEncodingException {
super(out, s);
count = 0;
}
public void write(char cbuf, int off, int len)
throws java.io.IOException {
if (off != 0) {
super .write (cbuf, off, len);
return;
}
if (count == 0 && len == 2 && cbuf[0] == '&' && cbuf[1] == '#') {
count = 1;
return;
} else if (count == 1) {
int i = 0;
for (; i < len; i++) {
if (cbuf[i] > '9' || cbuf[i] < '0') {
break;
}
}
if (i >= len) {
tempString = new String(cbuf, 0, len);
count = 2;
return;
} else {
super .write ("");
}
} else if (count == 2) {
if (len == 1 && cbuf[0] == ';') {
char c[] = new char[1];
c[0] = (char)new Integer(tempString).intValue();
super .write (c, 0, 1);
count = 0;
return;
} else {
super .write ("");
super .write (tempString);
}
}
super .write (cbuf, 0, len);
count = 0;
}
}
Java のまとまったプログラムってほとんど書いたことないのでアレですが、いつか誰か(含自分)の参考になればということで。
*1:int)chars[counter]
Tomix 鉄道模型システムガイド
Tomix の鉄道模型システムガイドというものを模型店で見つけました。「システムガイド」ということなので役に立つ情報がいろいろあるかと思い、安価なこともあって反射的に買ってしまいました。しかし、カタログ持っている人には特に必要のない内容でした。カタログに比べて増えている情報といったらレールセットの組み合わせとビギナー用情報(車両の連結方法やパワーパックの扱い等々)なので、今年のカタログを持っている人には不要でしょう。最近のカタログを買ってなくて、「最近自動運転やら新しいポイントやらいろいろ増えてるけどよくわかんなーい」という人には良いと思います。
Cisco PIX/ASA の transparent mode
このところ触る機会が多い Cisco PIX/ASA の話です。Cisco ASA 5500 シリーズ (software version 7.0) の transparent mode を利用する機会がありました。transparent mode は通常の L3 IP forwarding でなく L2 で bridging をする動作モードです。このモードで動作している ASA を Spanning Tree Protocol (STP) が通過するように設定しなければならなかったのですが、これにハマってしまいました。
以下のコマンドで transparent mode での動作となります。
firewall transparent
デフォルトの設定では STP のフレーム (BPDU) は通過しないので ethertype を指定した ACL を inside/outside の両方のインターフェイスに明示的に適用しなければなりません。今回は特に ethertype は制限せず、全て通過するよう any を用いて ACL を作りました。
これでうまくいくと思ったのですが、何故かツリーが構成されず、内側と外側で別々の root bridge ができてしまいます。
で結局何が悪かったかというと、物理インターフェイスをそのまま使っていたのがまずかったのです。うまく行かないときは次のように設定していました。
interface Ethernet0/0
speed 100
duplex full
nameif inside
security-level 100
!
interface Ethernet0/1
speed 100
duplex full
nameif outside
security-level 0
speed 100
duplex full
nameif inside
security-level 100
!
interface Ethernet0/1
speed 100
duplex full
nameif outside
security-level 0
実は transparent mode ではサブインターフェイスを使わなければならないのです。次のように設定し直すとうまくいきました。
interface Ethernet0/0
speed 100
duplex full
no nameif
no security-level
!
interface Ethernet0/0.1
vlan 100
nameif inside
security-level 100
!
interface Ethernet0/1
speed 100
duplex full
no nameif
no security-level
!
interface Ethernet0/1.1
vlan 101
nameif outside
security-level 0
speed 100
duplex full
no nameif
no security-level
!
interface Ethernet0/0.1
vlan 100
nameif inside
security-level 100
!
interface Ethernet0/1
speed 100
duplex full
no nameif
no security-level
!
interface Ethernet0/1.1
vlan 101
nameif outside
security-level 0
inside/outside で別々の VLAN 番号を振らなければなりません。このとき 802.1Q が使われるので、ASA が接続する inside 側のスイッチのインターフェイスは次のような設定になります。
(Catalyst 3550 の例)
interface GigabitEthernet0/1
switchport trunk encapsulation dot1q
switchport trunk allowed vlan 100
switchport mode trunk
no ip address
no cdp enable
interface GigabitEthernet0/1
switchport trunk encapsulation dot1q
switchport trunk allowed vlan 100
switchport mode trunk
no ip address
no cdp enable
Microsoft Money 2000 からのアップグレード
そろそろヤバいか (?) と思い Microsoft Money 2000 から 2007 へアップグレードすることにしました。システム要件 を見ると「その他」のところで「Money 2000 以降のデータ ファイルが読み込み可能」とあるので、アップグレードは全然問題なさそうです。
ところが実際にアップグレードして既存の Money 2000 ファイルを読み込もうとすると、
○○ファイルを見つけられません、または開けません。読み取り専用ファイルであるか、書き込みの権限がないか、ディスクドライブが書き込み禁止である可能性があります。
というエラーが表示され Money 2000 で作ったファイルを読み込んでくれません。
困って情報を探すと、
に行き当たり、これをを見ると英語版 Money 98/99 で作ったファイルは Money 2006 以降で自動的に変換してくれないようです。ひょっとしてと思い Money 2002 体験版をダウンロードしていったん Money 2002 用のファイルに変換すると、見事 Money 2007 で読み込んで変換することができるではないですか!
Money 2002 の体験版はデータを読み込んだとたん、
コンピュータのシステムの日付が 2001 年または 2002 年に設定されている必要があります
と言って終了してしまいますが、ファイルの変換はできていました。このファイルを使えば Money 2007 に既存データを読み込むことができます。
推測するに英語版と日本語版で差があって英語版では 99 と 2000 が境目だけれど、日本語版では 2000 と 2001 の間が境界になっているのではないでしょうか。Microsoft のオンラインサポートには Money 日本語版の情報は十分でなく、しかも機械翻訳情報ばかりなので今ひとつです。
なお、実際には 2007 の体験版を用いて上の通りエラーが発生すること&それを解決できることを確認してから購入しています。(体験版だけでなく製品版でも先のエラーが起こります)
何か余分なものをインストールさせられるかと身構えましたが、結局製品インストール用の ZIP ファイルをダウンロードするだけで、「ダウンローダー」なるものは不要でした。
久しぶりのアップグレードで税込み \7,140 ならばまあいいかという感じです。ただし機能については経過した年数を考えるとあまり進化を感じないですね。
GyaO による Super GT ライブ中継
EF70-300mm F4-5.6 IS USM の修理完了
そういえば EF70-300mm F4-5.6 IS USM 不具合の修理が済みました。9月の中旬に頼んで2週間半程度かかりました。
修理に出す際に「今回の不具合は縦位置の 300mm ならばいつも症状が出るものなのですか?」と聞いたところボディの機種を聞かれ、「Kiss Digital N だとわからないかも知れないです」とのことでした。APS-C サイズのセンサーでは気にならない程度の「撮影画像の周辺の一部」の問題というところでしょうか。ちなみに QR センターに持ち込んで修理後宅配してもらいました。
どうでもよいですが、最近このレンズはこの問題もあってか運動会シーズンだったのに品薄だったようですね。入手するのに苦労されている方も多いようです。私はもちろん子供の運動会の日程をにらみながら修理に出しました。これ位の大きさのレンズをつけて子供を撮影しているとお友達のお父さん/お母さんに冷やかされてしまいます...