プログラマのつれづれなるままにプログラマのつれづれなるままに音宮志久が思ったことなどをネタにします。プログラムネタ・数学ネタがメインです。[IStreamを実装してみよう(3)]コメントを残す残りは実装だけです。実装しないものはE_NOTIMPLを返して終わらせちゃおうCOMの関数の中には「関数は用意されているけど機能がないんだよ~」的なものが意外とたくさんあります。いわゆる、拡張用ですね。今回のように「読み込み専用なので書き込みの機能は実装しないよ」という意味で実装しないものもあります。それらはあっさりと実装することができます。今回は読み込み専用なので書き込みに関する機能を全部無視します。現在のカーソル位置からデータを読み出すの4つだけなのでほかはさくっと未実装ということで終わらせます。本来ならもう一つCopyTo(対象のIStreamにデータをコピーする)も実装対象とすべきですが、面倒なので実装しません。実装するときには以下の点に注意して組むようにしてください。ポインタがNULLを許可しないときにはE_POINTERを返してポインタエラーであることを必ず通告すること。エラーコードは汎用のもの以外で指定があるときはそちらを使うようにする。Readの実装そのまんまです。ま、気をつけるべき点に気をつけていきます。S_OK;}そのまんまといっているくせにいろいろとやかましいコードがくっついていますね。IStreamのReadのヘルプには「pvはエラーでない限りNULLにはならない」とあるので、ポインタチェックが必要です。CheckPointerはポインタがNULLの時は第二引数を返すマクロで、NULLチェックにはぴったりです。DirectShowのマクロですが・・・。DirectShowなどでは「ポインタエラーはE_POINTERを返すように」となっていますが、IStreamではそれがSTG_E_INVALIDPOINTERになっていますのでそちらを使っています。どちらにしてもエラーなのは変わりないわけですが・・・。一つのポインタは「pcbReadはNULLに設定できる」とあるのでこれはNULLチェック対象ではないですね。これは念のために入れてありますが、ハンドルが無効の時はE_HANDLEを返してハンドルエラーであることを通知しています。ReadFileです。さっきの「pcbReadはNULLに設定できる」との記述があるのでそのままReadFileには渡せなくなるので中間変数を挟んでいます。後は終了処理なのでわかりやすいと思います。最後に成功したときはS_OKで読み込み成功を返して完了です。Seekの実装Seekもそのまんま実装します。S_OK;}ポインタチェックは「plibNewPositionはNULLに設定できる」とのことなのでしなくてもいいですね。問題はdwOriginで、これは説明では三つの値をとる、とありますが、これはSetFilePointerの定数と互換があるかわからないので変換します。このときに三つの値のいずれでもないときはヘルプのreturn値に従ってSTG_E_INVALIDFUNCTIONを返します。あとはSetFilePointerを呼び出してSeekさせます。失敗したときはE_FAILで失敗したことにします。Cloneの実装そのまんまです。hr;}・・・そのまんまでもないか。コピーコンストラクタに近いコンストラクタを使えればいいんですが、DuplicateHandleだとファイルカーソルが共有してしまうでファイルを再度開かせる方法でコピーしています。再度正しく開ければファイルカーソルをコピーしてオブジェクトをアップキャスト(QueryInterface)して完了です。エラー処理がちょっと微妙ですが・・・。S_OK;}ファイル名のコピーがとても大変ですがこんな感じですね。ファイル名のバッファはCoTaskMemAllocで確保する、UNICODEである、という定義があるのでその定義に従っています。UNICODEかどうかでstringを分けてどうにかしています。VisualStudioでstd::stringというと勝手にcharの文字列になりますので注意してください。std::stringと宣言していますが、UNICODEの状態によって定義が変わるようになっていると仮定しています。*と仮定しています)それ以降のデータは構造体中の必要な部分にデータを書き込んでいるだけです。いうわけで実装してみました。試しに使ってみるといいかもしれません。IStreamの定義はいろんなもの(自作ライブラリのファイル処理にも)に転用できるのでこういうのを考えることはおもしろいと思います。次回からはしばらくこの系の記事はお休みして別の話をしてみたいと思います。コメントをキャンセルメールアドレスが公開されることはありません。志久プログラムネタや思いついたり世間で話題になっている数学ネタを解説したりしています。プログラマとしては今年度(つまり2020年3月)までの復帰となるか、完全復帰となるか、別の仕事に戻るかは運と実力次第。ちなみに教育系のプログラムでもOKです。アクセスカウンタアクセス数:スポンサーリンク。