コンテンツへスキップ
ものがたり
戻る

2007-05-23

System.Resources関係のメモ

infocardなんてちっとも流行っていないものは放置して、.net 2.0の穴埋めの仕事をやっつけている。で、ここ2,3日mscorlibのSystem.Resourcesを眺めていたのだけど、1.xとはずいぶん違う物になっているみたいだし、微妙に内部動作に依存したAPI設計になっていて困ったりする。今日はそんなSystem.Resourcesについてちょこっと書いてみたい。役に立つ話ではないけど。

…役に立たない話なので続きを読むモードにしておこう。

ランタイム上存在しない型のデータ処理

ResourceWriter.AddResourceData(string name, string typeName, byte data) は、型の指定まで型名で指定してデータを追加する。ResourceReader.GetResourceData(string name, out string typeName, out byte data)はこの逆だ。

ResourceReader.GetEnumerator()で列挙されるオブジェクトの値を取得しようとすると、リソースに含まれるデータのうち、ランタイム型として存在しない(例えば、シリアライズした側にあって、こちら側にない)場合にはエラーになるがこれは誤りのようだ。nullになる、GetResourceData()を使えば、デシリアライズできなくてもリソースを読み込む処理が、出来なくもない。そしてそのようにして読み込んだデータを、AddResourceData()で書き戻すこともできる。

安全なデータ列挙を求めるのであれば、GetEnumerator()で取得したIDictionaryEnumeratorから、Valueを取得しようとしてはいけない。ただしどのリソースがどの型になるかは、事前に判別のしようがないので、Valueがnullだった場合にGetResourceData()をtry-catchで括るようなダメなやり方で処理するしかなさそうだ。

ResourceManager.GetStream()

ResourceManager.GetStream(string name)は、GetObject(string)やGetString(string)と同じで、指定されたリソースアイテムの内容をStreamの状態で返す。といっても(2.0で追加された)Streamオブジェクトとしてシリアライズされたオブジェクト(というかMemoryStreamしか思いつかないけど)のみが、これで取得できる。

で、その内容はUnmanagedMemoryStreamになっていて、僕が実装する時はMemoryStreamにでもして返したいのだけど(何しろresourcesファイルはStreamを開いているだけなので)、MemoryStreamはUnmanagedMemoryStreamではないので、UnmanagedMemoryStream「にして」返さないといけない。めんどくさい。というか効率が悪い。実装に依存した悪いAPIだ。

データフォーマット

v1とv2では違う。見た感じ↓のようになっているようだ。

BEはbig endian, LEはlittle endian。ちなみにBinaryWriter/BinaryReaderのフォーマットを利用している部分がいくつかあるといえる。文字列ハッシュはDJBっぽいが(既存のソースの定数でぐぐった)、演算には+ではなく^が使用されている部分がある。

data sectionやtypesの内容も違う。typesも、2.0ではstringやintなどの基本的な型の情報は入っていない。data sectionは型情報も含むようになった。

…これ以上の説明は不毛なのでそのうちコミットするResourceReader/ResourceWriterのソースを見てちょうだいということで。

Firefox Developers Conference

http://www.mozilla-japan.org/events/fxdevcon/summer2007/

に仲間が西海岸からやってくるかもしれないというので、見てみたら、今年はshaverまでやってくるじゃないですか。これはちょっと楽しみだ。って、例によって英語ようしゃべらんのだけど。


この記事を共有:

前の記事
Firefox Developers Conference
次の記事
System.Resources関係のメモ