入力ストリームの基底クラスです。このクラスを実体化することはできません。
[詳解]
#include "nn/nlib/InputStream.h"
入力ストリームの基底クラスです。このクラスを実体化することはできません。
- 説明
- 同期かつシーケンシャルなアクセスI/Fを持つ入力ストリームの基底となります。 実際のデータの読み込み先は、派生クラスによって定義されます。
- 1バイトずつデータを読む処理は以下のようにコーディングすることができます。
int c;
while ((c = is.Read()) >= 0) {
}
}
- バッファを用意していて、特定のバイト数をまとめて読み込みたい場合は、以下のようにコーディングすることができます。
uint8_t* buf = ... N bytesのメモリ ...;
size n = is.Read(buf, N);
}
- テキストデータ(UTF-8)を読み込みたい場合は、
TextReader
オブジェクトを利用します。 改行を正規化し、UTF-8をチェックしてUTF-32に変換してからユーザーに渡します。 TextReader r;
int c;
while ((c = is.Read()) >= 0) {
}
}
派生クラスの実装のための情報
InputStream
クラスの仕様は予告なしに変更される可能性があるので、出来るだけ派生クラスを独自に実装しない方がリスクは低いですが、必要な場合、派生クラスは以下の仮想関数をオーバーライドすることで定義できます。
- size_t FillBuffer_(void* p, size_t nbytes)
- 引数
p
は設定されるデータへのポインタで、nbytes
はサイズです。 ユーザーがデータを読み込もうとして、InputStream
内のバッファにデータがなかった場合に呼ばれます。 p
には内部バッファ、又はユーザーが指定したバッファのポインタが入ります。
- 戻り値は実際に設定されたデータのサイズで
nbytes
以下の値です。 エラーかデータの末尾の場合、かつその場合のみに0を返すことができます。 データがまだ届いていない、というような場合は内部でブロックする必要があります。
- エラーケースの対応として以下を例として挙げます。
-
対応デバイスがない場合(ハンドルが無効等)は、
EBADF
を設定し0を返します。
-
途中で読み込み失敗が確定した場合はエラー(ex.
EIO
)を設定し0を返します。
- エラー場合、データを途中まで読むことができた場合も0を返さなくてはならないことに注意してください。
- 注意
- 2018-05-08版より、引数に
nullptr, 0
が渡された場合はResetBuffer()
をコールしてInputStream
の内部バッファをセットしてからデータを設定する必要があります。
- bool Close_()
- 内部のハンドル等をクローズします。 どのような場合でも内部で保持する関連リソース全てを解放する実装になっている必要があります。 また、基底クラスのデストラクタからは
Close_()
が呼ばれないことに注意してください。
- エラーケースの対応として以下を例として挙げます。
-
対応デバイスがない場合(ハンドルが無効等)は、
EBADF
を設定しfalse
を返します。
-
クローズの際の動作等で失敗した場合、何らかのエラー(ex.
EIO
)を設定しfalse
を返します。
- エラーの場合でも、ハンドル等の内部リソースの解放を確実に行うことが必要であることに注意してください。
- void* GetWorkBuffer_(size_t* nbytes)
- 注意
- 2018-05-08版より削除されています。
InputStreamの設計に関するメモ
InputStream
でデータを読むと必ずデータがバッファがキャッシュされます。 このキャッシュはデバイスからの読み込みをまとめて行うことが目的なのではなく、仮想関数の呼び出しを抑制するためのものです。
InputStream
の設計にあたり、以下のようなインターフェイスクラスを基底に置く設計はシンプルなものになります。 しかしながら、1バイトずつデータを呼び出した場合の仮想関数のオーバーヘッドが大きく、現実的な利用には適しません。
InputStream.h の 29 行目に定義があります。
◆ Close()
nn::nlib::InputStream::Close |
( |
| ) |
|
|
noexcept |
ストリームを閉じます。成功した場合にはtrue
を返します。
- 戻り値
- 成功した場合は
true
- 説明
false
の場合は、途中で何らかの処理が失敗しています。もし失敗した場合も再度クローズする必要はありません。
◆ GetErrorValue()
nn::nlib::InputStream::GetErrorValue |
( |
| ) |
const |
|
inlinenoexcept |
エラー値を取得します。
- 戻り値
- エラー値
- 説明
- 0以外の場合はエラーです。エラー値は一般には実装依存になります。
InputStream.h の 57 行目に定義があります。
◆ GoBackToMark()
nn::nlib::InputStream::GoBackToMark |
( |
| ) |
|
|
noexcept |
最後にMark()
を実行した読み込み位置に戻ります。
- 戻り値
- マークした読み込み位置に戻ることができた場合には
true
を返します。
- 説明
Mark()
が呼ばれてからreadlimit
バイト以内の位置でこの関数を呼び出した場合にマークした読み込み位置に戻ることができます。
false
を返すのは以下の場合です。
-
このストリームが
Mark()
とGoBackToMark()
をサポートしていない場合。この場合はストリームにENOTSUP
エラーを設定します。
-
readlimit
バイトより多くのデータを読んだ後にこの関数を実行した場合。この場合はストリームにERANGE
エラーを設定します。
◆ IsEos()
nn::nlib::InputStream::IsEos |
( |
| ) |
|
|
inlinenoexcept |
ストリームを最後まで読み終えている場合true
を返します。最後まで読み終えていない場合やエラーが発生している場合はfalse
を返します。
- 戻り値
true
の場合ストリームの最後に到達しています。
InputStream.h の 61 行目に定義があります。
◆ Mark()
nn::nlib::InputStream::Mark |
( |
size_t |
readlimit | ) |
|
|
noexcept |
現在の読み込み位置にGoBackToMark()
で戻ることができるように設定します。
- 引数
-
- 戻り値
- 成功した場合に
true
を返します。
- 説明
- ストリーム上の現在位置から
readlimit
バイトのデータがGoBackToMark()
の実行で再読込できるようになります。 readlimit
には、GoBackToMark()
を呼び出すまでに読み込む可能性のある最大バイト数を指定します。 Mark()
を繰り返し実行した場合は、最後の実行結果のみが有効になります。 また、readlimit
は1024以下の値である必要があります。
false
を返すのは以下の場合です。
-
このストリームが
Mark()
とGoBackToMark()
をサポートしていない場合。この場合はストリームにENOTSUP
エラーを設定します。
-
readlimit
が1024より大きい場合。この場合はストリームにEINVAL
エラーを設定します。
-
その他I/Oに起因するエラーが発生した場合。この場合はストリームに
EIO
エラーを設定します。
◆ Peek()
nn::nlib::InputStream::Peek |
( |
| ) |
|
|
inlinenoexcept |
ストリームを消費せずに次の1バイトを読み込みます。
- 戻り値
- 読み込んだデータ、又は-1
- 説明
- 読み込んだデータを返します。 失敗した場合やストリームの最後まで読み終えた場合は-1を返します。
InputStream.h の 77 行目に定義があります。
◆ Pos()
nn::nlib::InputStream::Pos |
( |
| ) |
const |
|
inlinenoexcept |
ストリーム上の現在位置を返します。
- 戻り値
- ストリーム上の現在位置(読み込んだバイト数)
- 説明
- ストリームを閉じた後にこのメソッドを利用しても正しい値は得られない点に注意してください。
InputStream.h の 59 行目に定義があります。
◆ Pos64()
nn::nlib::InputStream::Pos64 |
( |
| ) |
const |
|
inlinenoexcept |
ストリーム上の現在位置を64bit値で返します。
- 戻り値
- ストリーム上の現在位置(読み込んだバイト数)
InputStream.h の 60 行目に定義があります。
◆ Read() [1/2]
nn::nlib::InputStream::Read |
( |
| ) |
|
|
inlinenoexcept |
ストリームから1バイトを読み込みます。
- 戻り値
- 読み込んだデータ、又は-1
- 説明
- 読み込んだデータを返します。 失敗した場合やストリームの最後まで読み終えた場合は-1を返します。
- 従って-1を読み込んだ場合にはエラーであるかストリームの末端であるかを判定する必要があります。
c = is.Read();
if (c < 0) {
} else {
}
}
InputStream.h の 69 行目に定義があります。
◆ Read() [2/2]
nn::nlib::InputStream::Read |
( |
void * |
ptr, |
|
|
size_t |
nbytes |
|
) |
| |
|
inlinenoexcept |
ptr
で示されるメモリにnbytes
読み込みます。
- 引数
-
[in,out] | ptr | 読み込んだデータを格納するメモリ |
[in] | nbytes | 読み込むバイト数 |
- 戻り値
- 実際に読み込んだバイト数
- 説明
- 読み込んだバイト数が0の場合はストリームの終わりかエラーです。 それ以外の場合は、
nbytes
より小さい値が戻ってきた場合でもストリームの終わりではないかもしれません。
InputStream.h の 86 行目に定義があります。
◆ SetBuffer()
nn::nlib::InputStream::SetBuffer |
( |
void * |
p, |
|
|
size_t |
nbytes, |
|
|
bool |
is_mark_supported, |
|
|
bool |
is_buf_readonly |
|
) |
| |
|
inlineprotectednoexcept |
InputStream
が持つバッファを設定します。
- 引数
-
[in] | p | バッファへのポインタ |
[in] | nbytes | バッファ・サイズ |
[in] | is_mark_supported | Mark() がサポートされていればtrue |
[in] | is_buf_readonly | バッファが上書き禁止ならtrue |
InputStream.h の 116 行目に定義があります。
◆ SetError()
nn::nlib::InputStream::SetError |
( |
errno_t |
e | ) |
const |
|
inlineprotectednoexcept |
◆ Skip()
nn::nlib::InputStream::Skip |
( |
size_t |
nbytes | ) |
|
|
noexcept |
nbytes
を読み飛ばします。
- 引数
-
- 戻り値
- 実際に読み飛ばしたバイト数
- 説明
- データを読み飛ばす場合、
Read()
でデータを読み捨てるより効率がよい場合があります。
このクラス詳解は次のファイルから抽出されました: