IStream
COM公式ドキュメント
IStream インターフェイスを使用すると、ストリームオブジェクトに対してデータの読み取りと書き込みを行うことができます。
メソッド 9
vtbl = vtable インデックス(0始まり)。HSP等からCOMメソッドをインデックス指定で呼ぶ際に使用します。0〜2 は IUnknown。
シークポインターを新しい位置に変更します。新しい位置は、ストリームの先頭、ストリームの末尾、または現在のシークポインターのいずれかを基準とします。
| dlibMove | LONGLONG | in | dwOrigin パラメーターで示される位置に加算する変位量です。dwOrigin が STREAM_SEEK_SET の場合、この値は符号付き値ではなく符号なし値として解釈されます。 |
| dwOrigin | STREAM_SEEK | in | dlibMove で指定された変位量の基点です。基点には、ファイルの先頭 (STREAM_SEEK_SET)、現在のシークポインター (STREAM_SEEK_CUR)、またはファイルの末尾 (STREAM_SEEK_END) を指定できます。値の詳細については、STREAM_SEEK 列挙型を参照してください。 |
| plibNewPosition | ULONGLONG* | outoptional | このメソッドがストリームの先頭からの新しいシークポインターの値を書き込む位置へのポインターです。 このポインターには NULL を設定できます。その場合、このメソッドは新しいシークポインターを返しません。 |
戻り値
このメソッドは、次のいずれかの値を返すことがあります。
| Return code | Description |
|---|---|
| S_OK | シークポインターが正常に調整されました。 |
| E_PENDING | 非同期ストレージのみ: ストリームデータの一部またはすべてが現在利用できません。 |
| STG_E_INVALIDPOINTER | plibNewPosition が無効なメモリを指していることを示します。plibNewPosition が読み取り可能でないためです。 |
| STG_E_INVALIDFUNCTION | dwOrigin パラメーターに無効な値が含まれているか、dlibMove パラメーターに不正なオフセット値が含まれています。たとえば、シークポインターの結果が負のオフセット値になる場合などです。 |
| STG_E_REVERTED | トランザクションツリー内の上位にある元に戻す (revert) 操作によって、オブジェクトが無効になりました。 |
解説(Remarks)
IStream::Seek はシークポインターを変更し、以降の読み取りおよび書き込み操作をストリームオブジェクト内の別の位置で実行できるようにします。ストリームの先頭より前にシークするのはエラーです。ただし、ストリームの末尾を超えてシークするのはエラーではありません。ストリームの末尾を超えてシークすることは、以降の書き込み操作に役立ちます。書き込みが完了する直前に、ストリームのバイト範囲が新しいシーク位置まで拡張されるためです。
また、このメソッドを使用してシークポインターの現在の値を取得することもできます。dwOrigin パラメーターを STREAM_SEEK_CUR に、dlibMove パラメーターを 0 に設定してこのメソッドを呼び出すと、シークポインターは変更されません。現在のシークポインターは plibNewPosition パラメーターに返されます。
ストリームオブジェクトのサイズを変更します。
| libNewSize | ULONGLONG | in | ストリームの新しいサイズをバイト単位で指定します。 |
戻り値
このメソッドは、次のいずれかの値を返すことがあります。
| Return code | Description |
|---|---|
| S_OK | ストリームオブジェクトのサイズが正常に変更されました。 |
| E_PENDING | 非同期ストレージのみ: ストリームデータの一部またはすべてが現在利用できません。 |
| STG_E_MEDIUMFULL | ストレージデバイスに空き領域がないため、ストリームサイズは変更されませんでした。 |
| STG_E_INVALIDFUNCTION | libNewSize パラメーターの値が実装でサポートされていません。すべてのストリームが 232 バイトを超えるサイズをサポートするわけではありません。ストリームが 232 バイトを超えるサイズをサポートしない場合、libNewSize の上位 DWORD データ型は 0 でなければなりません。0 以外の場合、実装は STG_E_INVALIDFUNCTION を返すことがあります。一般に、COM ベースの IStream インターフェイスの実装は 232 バイトを超えるストリームをサポートしません。 |
| STG_E_REVERTED | トランザクションツリー内の上位にある元に戻す (revert) 操作によって、オブジェクトが無効になりました。 |
解説(Remarks)
IStream::SetSize はストリームオブジェクトのサイズを変更します。ストリーム用の領域を事前に割り当てるには、このメソッドを呼び出します。libNewSize パラメーターが現在のストリームサイズよりも大きい場合、ストリームは指定されたサイズまで拡張され、その間の領域は未定義の値のバイトで埋められます。この操作は、シークポインターが現在のストリームの末尾を超えている場合の ISequentialStream::Write メソッドに似ています。
libNewSize パラメーターが現在のストリームよりも小さい場合、ストリームは指定されたサイズに切り詰められます。
シークポインターはストリームサイズの変更による影響を受けません。
IStream::SetSize を呼び出すことは、連続した大きな領域を確保する効果的な方法となります。
ストリーム内の現在のシークポインターから、別のストリームの現在のシークポインターへ、指定したバイト数をコピーします。
| pstm | IStream* | in | コピー先ストリームへのポインターです。pstm が指すストリームは、新しいストリームでも、コピー元ストリームのクローンでもかまいません。 |
| cb | ULONGLONG | in | コピー元ストリームからコピーするバイト数です。 |
| pcbRead | ULONGLONG* | outoptional | このメソッドがコピー元から実際に読み取ったバイト数を書き込む位置へのポインターです。このポインターには NULL を設定できます。その場合、このメソッドは実際に読み取ったバイト数を返しません。 |
| pcbWritten | ULONGLONG* | outoptional | このメソッドがコピー先へ実際に書き込んだバイト数を書き込む位置へのポインターです。このポインターには NULL を設定できます。その場合、このメソッドは実際に書き込んだバイト数を返しません。 |
戻り値
このメソッドは、次のいずれかの値を返すことがあります。
| Return code | Description |
|---|---|
| S_OK | ストリームオブジェクトが正常にコピーされました。 |
| E_PENDING | 非同期ストレージのみ: コピーするデータの一部またはすべてが現在利用できません。 |
| STG_E_INVALIDPOINTER | ポインターパラメーターのいずれかの値が無効です。 |
| STG_E_MEDIUMFULL | ストレージデバイスに空き領域がないため、ストリームはコピーされませんでした。 |
| STG_E_REVERTED | トランザクションツリー内の上位にある元に戻す (revert) 操作によって、オブジェクトが無効になりました。 |
解説(Remarks)
CopyTo メソッドは、指定したバイトをあるストリームから別のストリームへコピーします。ストリームを自分自身へコピーすることもできます。各ストリームインスタンスのシークポインターは、読み取りまたは書き込みが行われたバイト数に応じて調整されます。このメソッドは、 ISequentialStream::Read を使用して cb バイトをメモリに読み込み、その後すぐに ISequentialStream::Write を使用してコピー先ストリームへ書き込むことと同等ですが、IStream::CopyTo の方が効率的です。
コピー先ストリームには、 IStream::Clone メソッドを呼び出して作成した、コピー元ストリームのクローンを指定できます。
IStream::CopyTo がエラーを返した場合、コピー元とコピー先のいずれについても、シークポインターが有効であるとは想定できません。さらに、pcbRead と pcbWritten の値は返されはしますが、意味を持ちません。
IStream::CopyTo が正常に返った場合、実際に読み取られたバイト数と書き込まれたバイト数は同じです。
現在のシークポインターからコピー元の残り全体をコピーするには、cb パラメーターに符号付き大整数の最大値を指定します。シークポインターがストリームの先頭にある場合、この操作はストリーム全体をコピーします。
Commit メソッドは、トランザクションモードで開かれているストリームオブジェクトに加えられた変更が、親ストレージに確実に反映されるようにします。
| grfCommitFlags | DWORD | in | ストリームオブジェクトの変更をどのようにコミットするかを制御します。これらの値の定義については、 STGC 列挙型を参照してください。 |
戻り値
このメソッドは、次のいずれかの値を返すことがあります。
| Return code | Description |
|---|---|
| S_OK | ストリームオブジェクトへの変更が親レベルに正常にコミットされました。 |
| E_PENDING | 非同期ストレージのみ: ストリームデータの一部またはすべてが現在利用できません。 |
| STG_E_MEDIUMFULL | ストレージデバイスの領域不足のため、コミット操作が失敗しました。 |
| STG_E_REVERTED | トランザクションツリー内の上位にある元に戻す (revert) 操作によって、オブジェクトが無効になりました。 |
解説(Remarks)
Commit メソッドは、トランザクションモードで開かれたストリームオブジェクトに加えられた変更が、親ストレージに確実に反映されるようにします。ストリームが開かれてから、または最後にコミットされてから加えられた変更が、親ストレージオブジェクトに反映されます。親がトランザクションモードで開かれている場合、親は後で元に戻され、このストリームオブジェクトへの変更がロールバックされる可能性があります。複合ファイルの実装ではトランザクションモードでのストリームのオープンをサポートしていないため、このメソッドはメモリバッファーをフラッシュする以外にはほとんど効果がありません。詳細については、 IStream - Compound File Implementation を参照してください。
ストリームがダイレクトモードで開かれている場合、このメソッドは、メモリバッファーが基になるストレージオブジェクトへ確実にフラッシュされるようにします。これは従来のファイルシステムにおけるフラッシュとよく似ています。
IStream::Commit メソッドは、 IStream インターフェイスの実装が基になるファイルシステム API のラッパーである場合に、ダイレクトモードのストリームで役立ちます。この場合、IStream::Commit はファイルシステムのフラッシュ呼び出しに接続されます。
Revert メソッドは、最後の IStream::Commit 呼び出し以降にトランザクションストリームに加えられたすべての変更を破棄します。ダイレクトモードで開かれたストリーム、および IStream::Revert の COM 複合ファイル実装を使用するストリームでは、このメソッドは効果を持ちません。
戻り値
このメソッドは、次のいずれかの値を返すことがあります。
| Return code | Description |
|---|---|
| S_OK | ストリームが正常に以前のバージョンに戻されました。 |
| E_PENDING | 非同期ストレージのみ: ストリームデータの一部またはすべてが現在利用できません。 |
解説(Remarks)
Revert メソッドは、最後のコミット操作以降にトランザクションストリームに加えられた変更を破棄します。
LockRegion メソッドは、ストリーム内の指定したバイト範囲へのアクセスを制限します。
| libOffset | ULONGLONG | in | 範囲の先頭のバイトオフセットを指定する整数です。 |
| cb | ULONGLONG | in | 制限する範囲の長さをバイト単位で指定する整数です。 |
| dwLockType | DWORD | in | 範囲へのアクセスに対して要求する制限を指定します。 |
戻り値
このメソッドは、次のいずれかの値を返すことがあります。
| Return code | Description |
|---|---|
| S_OK | 指定したバイト範囲がロックされました。 |
| E_PENDING | 非同期ストレージのみ: ストリームデータの一部またはすべてが現在利用できません。 |
| STG_E_INVALIDFUNCTION | ロックがまったくサポートされていないか、要求された特定の種類のロックがサポートされていません。 |
| STG_E_LOCKVIOLATION | 要求されたロックはサポートされていますが、既存のロックがあるため許可できません。 |
| STG_E_REVERTED | トランザクションツリー内の上位にある元に戻す (revert) 操作によって、オブジェクトが無効になりました。 |
解説(Remarks)
ストリームのバイト範囲は拡張できます。ストリームの拡張された範囲をロックすることは、実際にストリームの一部となっているデータを変更することなく、ストリームの異なるインスタンス間で通信を行う方法として役立ちます。
3 種類のロックをサポートできます。他の書き込み側を排除するロック、他の読み取り側または書き込み側を排除するロック、および指定した範囲に対して 1 つの要求側のみがロックを取得できるロックです。最後のロックは通常、他の 2 つのロック種別のいずれかのエイリアスです。特定のストリームインスタンスは、最初の 2 つの種別のいずれか、または両方をサポートする場合があります。ロック種別は dwLockType で、 LOCKTYPE 列挙型の値を使用して指定します。
IStream::LockRegion でロックした範囲は、後で libOffset、cb、dwLockType の各パラメーターにまったく同じ値を指定して IStream::UnlockRegion を呼び出し、明示的にロックを解除する必要があります。ストリームを解放する前に、範囲のロックを解除しておく必要があります。隣接する 2 つの範囲を別々にロックし、それらを 1 回のロック解除呼び出しでまとめて解除することはできません。
呼び出し側への注意
サポートされるロックの種類は任意であり、 IStream の実装によって異なる場合があるため、STG_E_INVALIDFUNCTION エラーを処理するコードを用意する必要があります。LockRegion メソッドは、範囲ロックをサポートしていないため、複合ファイルの実装では効果を持ちません。
実装者への注意
このメソッドのサポートは、基になるファイルシステムでサポートされていない可能性があるため、ストリームオブジェクトの実装では任意です。サポートされるロックの種類も任意です。要求された種類のロックがサポートされていない場合は、STG_E_INVALIDFUNCTION エラーが返されます。UnlockRegion メソッドは、IStream::LockRegion によって以前に制限したバイト範囲に対するアクセス制限を解除します。
| libOffset | ULONGLONG | in | 範囲の先頭のバイトオフセットを指定します。 |
| cb | ULONGLONG | in | 制限する範囲の長さをバイト単位で指定します。 |
| dwLockType | DWORD | in | 範囲に以前設定したアクセス制限を指定します。 |
戻り値
このメソッドは、次のいずれかの値を返すことがあります。
| Return code | Description |
|---|---|
| S_OK | バイト範囲のロックが解除されました。 |
| E_PENDING | 非同期ストレージのみ: ストリームデータの一部またはすべてが現在利用できません。 |
| STG_E_INVALIDFUNCTION | ロックがまったくサポートされていないか、要求された特定の種類のロックがサポートされていません。 |
| STG_E_LOCKVIOLATION | 要求されたロック解除操作を許可できません。 |
| STG_E_REVERTED | トランザクションツリー内の上位にある元に戻す (revert) 操作によって、オブジェクトが無効になりました。 |
解説(Remarks)
IStream::UnlockRegion は、 IStream::LockRegion メソッドによって以前にロックした範囲のロックを解除します。ロックした範囲は、後で libOffset、cb、dwLockType の各パラメーターにまったく同じ値を指定して IStream::UnlockRegion を呼び出し、明示的にロックを解除する必要があります。ストリームを解放する前に、範囲のロックを解除しておく必要があります。隣接する 2 つの範囲を別々にロックし、それらを 1 回のロック解除呼び出しでまとめて解除することはできません。
Stat メソッドは、このストリームの STATSTG 構造体を取得します。
| pstatstg | STATSTG* | out | このメソッドがこのストリームオブジェクトに関する情報を格納する STATSTG 構造体へのポインターです。 |
| grfStatFlag | DWORD | in | このメソッドが STATSTG 構造体の一部のメンバーを返さないように指定し、メモリ割り当て操作を省略します。値は STATFLAG 列挙型から取得します。 |
戻り値
このメソッドは、次のいずれかの値を返すことがあります。
| Return code | Description |
|---|---|
| S_OK | 指定した位置に STATSTG 構造体が正常に返されました。 |
| E_PENDING | 非同期ストレージのみ: ストリームデータの一部またはすべてが現在利用できません。 |
| STG_E_ACCESSDENIED | 呼び出し側は、このストレージオブジェクトの統計情報にアクセスするための十分な権限を持っていません。 |
| STG_E_INSUFFICIENTMEMORY | メモリ不足のため、STATSTG 構造体は返されませんでした。 |
| STG_E_INVALIDFLAG | grfStateFlag パラメーターの値が無効です。 |
| STG_E_INVALIDPOINTER | pStatStg ポインターが無効です。 |
| STG_E_REVERTED | トランザクションツリー内の上位にある元に戻す (revert) 操作によって、オブジェクトが無効になりました。 |
解説(Remarks)
IStream::Stat は、この開いているストリームに関する情報を含む STATSTG 構造体へのポインターを取得します。このストリームが構造化ストレージ内にあり、 IStorage::EnumElements が呼び出されると、その上に IEnumSTATSTG インターフェイスを持つ列挙子オブジェクトが作成されます。この列挙子を呼び出すことで、各ストレージおよびストリームに関連付けられた STATSTG 構造体を通じて、それらを列挙できます。
Clone メソッドは、元のストリームと同じバイトを参照しながら、独自のシークポインターを持つ新しいストリームオブジェクトを作成します。
| ppstm | IStream** | out | 成功した場合、新しいストリームオブジェクトへの IStream ポインターの位置へのポインターです。エラーが発生した場合、このパラメーターは NULL になります。 |
戻り値
このメソッドは、次のいずれかの値を返すことがあります。
| Return code | Description |
|---|---|
| S_OK | ストリームが正常にクローンされました。 |
| E_PENDING | 非同期ストレージのみ: ストリームデータの一部またはすべてが現在利用できません。 |
| STG_E_INSUFFICIENTMEMORY | メモリ不足のため、ストリームはクローンされませんでした。 |
| STG_E_INVALIDPOINTER | ppStm ポインターが無効です。 |
| STG_E_REVERTED | トランザクションツリー内の上位にある元に戻す (revert) 操作によって、オブジェクトが無効になりました。 |
解説(Remarks)
Clone メソッドは、同じバイトにアクセスしながら別個のシークポインターを使用する新しいストリームオブジェクトを作成します。新しいストリームオブジェクトは、コピー元ストリームオブジェクトと同じデータを参照します。一方のオブジェクトに書き込まれた変更は、すぐにもう一方のオブジェクトにも反映されます。範囲ロックはストリームオブジェクト間で共有されます。
クローンされたストリームインスタンスのシークポインターの初期設定は、クローン操作時点での元のストリームのシークポインターの現在の設定と同じです。
Microsoft 公式リファレンス: 英語 (en-us) · 日本語 (ja-jp) · 原文ソース (GitHub)
HSP用 COM定義
#usecom / #comfunc によるHSPのCOM呼び出し定義。数字は vtbl インデックス(0始まり)。クラスIDが無い場合 #usecom の末尾は "{}"、ある場合は "{CLSID}"。
#define global IID_IStream "{0000000C-0000-0000-C000-000000000046}" #usecom global IStream IID_IStream "{}" #comfunc global IStream_Seek 5 int64,int,var #comfunc global IStream_SetSize 6 int64 #comfunc global IStream_CopyTo 7 sptr,int64,var,var #comfunc global IStream_Commit 8 int #comfunc global IStream_Revert 9 #comfunc global IStream_LockRegion 10 int64,int64,int #comfunc global IStream_UnlockRegion 11 int64,int64,int #comfunc global IStream_Stat 12 var,int #comfunc global IStream_Clone 13 sptr ; ※数字は vtbl インデックス(0始まり)。0/1/2 は IUnknown(QueryInterface/AddRef/Release)。 ; ※このインターフェースは直接 CoCreateInstance するクラスIDが無いため "{}"(他メソッド/アクティベーションで取得)。 ; ※出力/バッファ引数は var(変数直渡し)。varptr 方式にも切替可。 ; ※ハンドル/void*等の不透明ポインタは IronHSP では intptr 指定が可能。#define global IID_IStream "{0000000C-0000-0000-C000-000000000046}" #usecom global IStream IID_IStream "{}" #comfunc global IStream_Seek 5 int64,int,sptr #comfunc global IStream_SetSize 6 int64 #comfunc global IStream_CopyTo 7 sptr,int64,sptr,sptr #comfunc global IStream_Commit 8 int #comfunc global IStream_Revert 9 #comfunc global IStream_LockRegion 10 int64,int64,int #comfunc global IStream_UnlockRegion 11 int64,int64,int #comfunc global IStream_Stat 12 sptr,int #comfunc global IStream_Clone 13 sptr ; ※数字は vtbl インデックス(0始まり)。0/1/2 は IUnknown(QueryInterface/AddRef/Release)。 ; ※このインターフェースは直接 CoCreateInstance するクラスIDが無いため "{}"(他メソッド/アクティベーションで取得)。 ; ※出力/バッファ引数はポインタ方式(token=sptr / 呼び出しは varptr(変数))。 ; ※ハンドル/void*等の不透明ポインタは IronHSP では intptr 指定が可能。