2006/03/31(Fri)
○ iconv ``RAW'' conversion
ところでGNU libiconvは
JIS_X0201-1976 JIS_X0208-1983 JIS_X0212-1990 KSC5601 GB2312-80
のような符号化文字集合の「生」変換をサポートしている。
compound text + X11を介さずにbdf fontを操作する場合なんかに使うんだろうかね。
以下実行結果。
$ echo -n "あ" | /usr/pkg/bin/iconv -f EUC-JP -t JIS_X0208-1983 | od -c
0000000 $ "
0000002
NetBSD/Citrusでとりあえず実装するならlibISO2022.soのパラメタに
NAME "JISX0208-RAW"
ENCODING "ISO2022"
VARIABLE "INIT0=94$B"
DEFCSID "JISX0208:1990" 0x42007F00
INVALID 0x4200222E # GETA
とセットすればよいはず。
多分libEUC.so のように性能向上の為に専用モジュール書いたほうがいいんだろうけど。
$ echo -n "あ" | iconv -f EUC-JP -t JISX0208-RAW | od -c
0000000 $ " 033 ( B
0000005
うーん余計なエスケープシーケンスがついてしまうがな。
1034 if (iscntl(wc & 0xff)) {
1035 /* go back to ASCII on control chars */
1036 cs.type = CS94;
1037 cs.final = 'B';
1038 cs.interm = '\0';
1039 } else if (!(wc & ~0xff)) {
ここは制御文字がきたらASCIIに強制的に戻すんじゃなくて
static const _ISO2022Charset ascii = { CS94, 'B', '\0', '\0' };
static const _ISO2022Charset iso88591 = { CS94, 'A', '\0', '\0' };
...
if (isc0(wc & 0xff))
/* go back to INIT0 on C0 chars */
cs = (ei->initg[0].final) ? ei->initg[0] : ascii;
else if (isc1(wc & 0xff))
/* go back to INIT1 on C1 chars */
cs = (ei->initg[1].final) ? ei->initg[1] : ascii;
else if (!(wc & ~0xff)) {
こんな感じでC0ならINIT0、C1ならINIT1に戻すが正解?、とりあえず上の対応をして再実行。
0000000 $ " \0
0000003
まだゴミがついてくるね。
put_state_reset内でmbstate_tを初期化するために喰わせるL'\0'が変なことになってる。
1155 switch (cs.type) {
1156 case CS94:
1157 case CS96:
1158 i = 1;
1159 break;
1160 case CS94MULTI:
1161 case CS96MULTI:
1162 i = isthree(cs.final) ? 3 : 2;
1163 break;
1164 }
1165 while (i-- > 0)
1166 *p++ = ((wc >> (i << 3)) & 0x7f) | mask;
ここだね。
ワイド文字が制御文字にも関わらず2バイトに水増しされてしまう、ここも修正すれば多分OK。