入力ストリームの基底クラスです。このクラスを実体化することはできません。
[詳解]
#include "nn/nlib/InputStream.h"
|
errno_t | GetErrorValue () const noexcept |
| エラー値を取得します。 [詳解]
|
|
size_t | Pos () const noexcept |
| ストリーム上の現在位置を返します。 [詳解]
|
|
uint64_t | Pos64 () const noexcept |
| ストリーム上の現在位置を64bit値で返します。 [詳解]
|
|
bool | IsEos () noexcept |
| ストリームを最後まで読み終えている場合true を返します。最後まで読み終えていない場合やエラーが発生している場合はfalse を返します。 [詳解]
|
|
int | Read () noexcept |
| ストリームから1バイトを読み込みます。 [詳解]
|
|
NLIB_CHECK_RESULT int | Peek () noexcept |
| ストリームを消費せずに次の1バイトを読み込みます。 [詳解]
|
|
size_t | Skip (size_t nbytes) noexcept |
| nBytes を読み飛ばします。 [詳解]
|
|
size_t | Read (void *ptr, size_t nbytes) noexcept |
| ptr で示されるメモリにnBytes 読み込みます。 [詳解]
|
|
bool | Close () noexcept |
| ストリームを閉じます。成功した場合にはtrue を返します。 [詳解]
|
|
| operator bool () const |
| 内部でエラーが発生していなければtrue を返します。
|
|
|
constexpr | InputStream () noexcept |
| コンストラクタです。派生クラスから呼び出されます。
|
|
virtual | ~InputStream () noexcept |
| デストラクタです。派生クラスから呼び出されます。
|
|
入力ストリームの基底クラスです。このクラスを実体化することはできません。
- 説明
- 同期かつシーケンシャルなアクセス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を返すことができます。 データがまだ届いていない、というような場合は内部でブロックする必要があります。
- また、後述の
GetWorkBuffer_()
でバッファが設定されなかった場合は、p
にNULL
が入ってコールされることがあります。 その場合はResetBuffer()
をコールしてInputStream
の内部バッファをセットする必要があります。
- エラーケースの対応として以下を例として挙げます。
-
対応デバイスがない場合(ハンドルが無効等)は、
EBADF
を設定し0を返します。
-
途中で読み込み失敗が確定した場合はエラー(ex.
EIO
)を設定し0を返します。
- エラー場合、データを途中まで読めた場合も0を返さなくてはならないことに注意してください。
- bool Close_()
- 内部のハンドル等をクローズします。 どのような場合でも内部で保持する関連リソース全てを解放する実装になっている必要があります。 また、基底クラスのデストラクタからは
Close_()
が呼ばれないことに注意してください。
- エラーケースの対応として以下を例として挙げます。
-
対応デバイスがない場合(ハンドルが無効等)は、
EBADF
を設定しfalse
を返します。
-
クローズの際の動作等で失敗した場合、何らかのエラー(ex.
EIO
)を設定しfalse
を返します。
- エラーの場合でも、ハンドル等の内部リソースの解放を確実に行うことが必要であることに注意してください。
- void* GetWorkBuffer_(size_t* nbytes)
is_buf_
がNULL
の場合、InputStream
はまずこの関数を呼び出してバッファを獲得しようとします。 戻り値がバッファへのポインタで、nBytes
にサイズが設定されます。 バッファ自体の所有権は派生クラス側にあるので、バッファの解放は派生クラスのコードで行う必要があります。
- メモリの確保等に失敗してバッファを渡せない場合は、
NULL
を返しnBytes
に0を設定する必要があります。
- この関数をオーバーライドしない場合は
NULL
を返し、nBytes
には-1が代入されます。 この場合、InputStream
はFillBuffer_()
においてバッファを獲得しようとします。
InputStreamの設計に関するメモ
InputStream
でデータを読むと必ずデータがバッファがキャッシュされます。 このキャッシュはデバイスからの読み込みをまとめて行うことが目的なのではなく、仮想関数の呼び出しを抑制するためのものです。
InputStream
の設計にあたり、以下のようなインターフェイスクラスを基底に置く設計はシンプルなものになります。 しかしながら、1バイトずつデータを呼び出した場合の仮想関数のオーバーヘッドが大きく、現実的な利用には適しません。
InputStream.h の 16 行目に定義があります。
§ Close()
nn::nlib::InputStream::Close |
( |
| ) |
|
|
noexcept |
ストリームを閉じます。成功した場合にはtrue
を返します。
- 戻り値
- 成功した場合は
true
- 説明
false
の場合は、途中で何らかの処理が失敗しています。もし失敗した場合も再度クローズする必要はありません。
§ GetErrorValue()
nn::nlib::InputStream::GetErrorValue |
( |
| ) |
const |
|
inlinenoexcept |
エラー値を取得します。
- 戻り値
- エラー値
- 説明
- 0以外の場合はエラーです。エラー値は一般には実装依存になります。
InputStream.h の 31 行目に定義があります。
§ IsEos()
nn::nlib::InputStream::IsEos |
( |
| ) |
|
|
inlinenoexcept |
ストリームを最後まで読み終えている場合true
を返します。最後まで読み終えていない場合やエラーが発生している場合はfalse
を返します。
- 戻り値
true
の場合ストリームの最後に到達しています。
InputStream.h の 35 行目に定義があります。
§ Peek()
nn::nlib::InputStream::Peek |
( |
| ) |
|
|
inlinenoexcept |
ストリームを消費せずに次の1バイトを読み込みます。
- 戻り値
- 読み込んだデータ、又は-1
- 説明
- 読み込んだデータを返します。 失敗した場合やストリームの最後まで読み終えた場合は-1を返します。
InputStream.h の 51 行目に定義があります。
§ Pos()
nn::nlib::InputStream::Pos |
( |
| ) |
const |
|
inlinenoexcept |
ストリーム上の現在位置を返します。
- 戻り値
- ストリーム上の現在位置(読み込んだバイト数)
- 説明
- ストリームを閉じた後にこのメソッドを利用しても正しい値は得られない点に注意してください。
InputStream.h の 33 行目に定義があります。
§ Pos64()
nn::nlib::InputStream::Pos64 |
( |
| ) |
const |
|
inlinenoexcept |
ストリーム上の現在位置を64bit値で返します。
- 戻り値
- ストリーム上の現在位置(読み込んだバイト数)
InputStream.h の 34 行目に定義があります。
§ Read() [1/2]
nn::nlib::InputStream::Read |
( |
| ) |
|
|
inlinenoexcept |
ストリームから1バイトを読み込みます。
- 戻り値
- 読み込んだデータ、又は-1
- 説明
- 読み込んだデータを返します。 失敗した場合やストリームの最後まで読み終えた場合は-1を返します。
- 従って-1を読み込んだ場合にはエラーであるかストリームの末端であるかを判定する必要があります。
c = is.Read();
if (c < 0) {
} else {
}
}
InputStream.h の 43 行目に定義があります。
§ Read() [2/2]
nn::nlib::InputStream::Read |
( |
void * |
ptr, |
|
|
size_t |
nbytes |
|
) |
| |
|
inlinenoexcept |
ptr
で示されるメモリにnBytes
読み込みます。
- 引数
-
[in,out] | ptr | 読み込んだデータを格納するメモリ |
[in] | nbytes | 読み込むバイト数 |
- 戻り値
- 実際に読み込んだバイト数
- 説明
- 読み込んだバイト数が0の場合はストリームの終わりかエラーです。 それ以外の場合は、
nBytes
より小さい値が戻ってきた場合でもストリームの終わりではないかもしれません。
InputStream.h の 60 行目に定義があります。
§ ResetBuffer()
nn::nlib::InputStream::ResetBuffer |
( |
void * |
p, |
|
|
size_t |
nbytes |
|
) |
| |
|
inlineprotectednoexcept |
§ SetError()
nn::nlib::InputStream::SetError |
( |
errno_t |
e | ) |
const |
|
inlineprotectednoexcept |
§ Skip()
nn::nlib::InputStream::Skip |
( |
size_t |
nbytes | ) |
|
|
noexcept |
nBytes
を読み飛ばします。
- 引数
-
- 戻り値
- 実際に読み飛ばしたバイト数
- 説明
- データを読み飛ばす場合、
Read()
でデータを読み捨てるより効率がよい場合があります。
このクラス詳解は次のファイルから抽出されました: