.NET Framework required BOM

デフォルトの search.ini や lng 読み込みで文字化けする理由が判明。
BOM が付いていない UTF-8 文書は UTF-16 文字列に変換読み込みしてくれないということ…

何を今更 BOM での判別といい UNICODE と cp932 の混在といい…
もうイヤだこの変態 OS は、全てが UTF-8 である最近の Linux を見習ってくれ!

Python 組み込みの open() では読み込んだ後に変換しかできないわけだから、方法ある?
System.IO.StreamReader と System.Text.Encoding.UTF8 を普通に使うのが一番だよな。
StreamReader オブジェクトは for ループに…やっぱり無理か。

import os

# 略

class Inifile(InifileBase):
    def __init__(self, filename):
        InifileBase.__init__(self, filename)
        self.header = ""
        self.ini = []
        if os.path.exists(filename):
            f = open(filename)
            x = f.read()
            f.close()
            lines = x.split("\n")
            section = ""
            for line in lines:
                if line == "":
                    continue
                if len(line) > 2 and line[0] =="[" and line[-1] == "]":
                    section = line[1:-1]
                elif section == "":
                    pass # 何もしない
                elif "=" in line:
                    pos = line.index("=")
                    self._add(section, line[:pos], line[pos+1:])

from System.IO import *
from System.Text import *

# 略

class Inifile(InifileBase):
    def __init__(self, filename):
        # ベースクラスでアトリビュートを利用する場合は IronPython でも必要
        InifileBase.__init__(self, filename)
        self.header = ""
        self.ini = []
        #if os.path.exists(filename):
        if File.Exists(self.filename):
            f = StreamReader(self.filename, Encoding.UTF8)
            try:
                section = ""
                while 1:
                    line = f.ReadLine()
                    if line == None:
                        break
                    if line == "":
                        continue
                    if len(line) > 2 and line[0] =="[" and line[-1] == "]":
                        section = line[1:-1]
                    elif section == "":
                        pass # 何もしない
                    elif "=" in line:
                        pos = line.index("=")
                        self._add(section, line[:pos], line[pos+1:])
            finally:
                f.Close()

utf8read

大体同じに仕上げたけど Linux 版とコード共有はもうあきらめるしかない。
組み込みの open とは違い StreamReader は Close 必須なので忘れないでね。
しかし私は無限ループを作って null で抜けるコードばかりだ、一番単純に書けるのよね。
if not line: だと空文字も拾ってしまうのは Python という言語の常識かな。

ついでに継承ベースクラスの __init__() が不要の IronPython も必要な場合があると解った。
ここではベースクラスで self.filename を定義しているだけなんだが、そういう場合に。
だから無意味に呼び出しても結果が同じなのか、ふむふむ。

これならコンストラクタ化されているというのに自由に __init__() を定義できる。
C++ の継承で頭を抱えた経験がある人にしか解らないだろうけど嬉しい仕様だ。

seeme_a405.zip

次はメニューの文字化けか、一部だけ化けるというのが理解に苦しむ。

こんなノロノロ作っている間に Opera 10 が RC になっているわ。
SeeMe for Windows v4 はもうしばらく C# つまり exe 形式のままね。
そのほうがいいという人のほうが多いと知っているけどシラネ!