Re: Streamについて

投稿ツリー


このトピックの投稿一覧へ

なし Re: Streamについて

msg# 1.6.1
depth:
2
前の投稿 - 次の投稿 | 親投稿 - 子投稿.1 .2 | 投稿日時 2010/7/25 2:27
SHOO  管理人   投稿数: 658
Handleを定義するためのモジュールを試作してみました。
まだ色々と足りない部分が多いのですが、ご参考までに御覧ください。


http://www.ideone.com/BDA0Q


他に、I/Oならこれが欲しいよ!とか、これ使いにくそう!等の相談は、是非是非是非、気軽に発言してください。私自身、何を実装したら良いのか今イチ分かっていないので…

コードの方は、行数こそ長い((1500行程度))ものの、とりたてて難しい技術は使っていませんので、テンプレートメタプログラミングが出来るのであれば、読み下せるのではないかと思います。

以下説明です。

----

ハンドルは大きく分けて2種類あります。InputHandleとOutputHandleです。
また、オプションによって
バッファ機能付き入力ハンドル(BufferedInputHandle)
バッファ機能付き出力ハンドル(BufferedOutputHandle)
シーク可能ハンドル(Seekable)
の属性が付属する可能性があります。
以下にこれらを判定するためのテンプレートを示します

- isInputHandle
入力ハンドルかどうかを判定します。
入力ハンドルの場合
-- size_t read(ubyte[] dst);
引数により渡されたdstバッファへと入力します。
戻り値は入力したバイト数が返ります。
-- @property const bool eoh();
End Of Handle
ハンドルの終端にたどり着き、これ以上読み込めない場合にはtrueが返る
-- void close();
ハンドルを閉じ、他の場所でオープン可能な状態にします。
上記3つのメソッドが利用可能です。

- isOutputHandle
出力ハンドルかどうかを判定します
出力ハンドルの場合
-- size_t write(in ubyte[] src);
引数により渡されたsrcのバイト列をハンドルへと出力します。
戻り値は出力したバイト数が返ります。
-- @property const bool eoh();
End Of Handle
ハンドルの終端にたどり着き、これ以上読み込めない場合にはtrueが返る
-- void close();
ハンドルを閉じ、他の場所でオープン可能な状態にします。
上記3つのメソッドが利用可能です。

- isBufferedInputHandle
入力ハンドルで、かつバッファ機能が付いているかを判定します。
バッファ機能付き入力ハンドルの場合
-- void fill();
バッファをハンドルからの入力情報で埋め尽くします。
readメソッドから自動的に呼ばれます。
-- @property const const(ubyte)[] buffer();
現在のバッファの中身を返します。
上記2つのメソッドが利用可能です。


- isBufferedOutputHandle
出力ハンドルで、かつバッファ機能が付いているかを判定します。
バッファ機能付き出力ハンドルの場合
-- void flush();
バッファに溜まっているデータを全てHandleへと出力します。

上記1つのメソッドが利用可能です。

- isSeekable
シーク可能なハンドルかどうかを判定します。
シーク可能ハンドルの場合
-- void seek(long pos, bool relative = false);
posの位置へとシークします。 relativeがtrueになっている場合は
現在のシーク位置からの移動量です。falseになっている場合はHandle先頭
位置からの移動量です。
-- @property const ulong size();
Handleで入出力可能な全体のサイズを返す
-- @property const ulong position();
現在のシーク位置を返します。

上記3つのメソッドが利用可能です。

どうしてもインターフェースを使いたい場合のため、各種interfaceとwrap関数を
用意しました。
- InputHandle
- OutputHandle
- BufferedInputHandle
- BufferedOutputHandle
- Seekable
- AnyHandle!Handle wrap(Handle)(Handle handle);
インターフェースを使う場合については、以下のような場合が挙げられます。
#code(d){{{
interface X
{
InputHandle input();
}
class Y: X
{
InputHandle input(){ return wrap(FileHandle("test.dat", "wb")); }
}
class Z: X
{
InputHandle input(){ return wrap(MemoryHandle()); }
}

void foo()
{
X[] x;
x ~= new Y;
x ~= new Z;
}
}}}

汎用バッファ機能付きハンドルとして、入力用と出力用をそれぞれ用意しました
- InputBuffer!Handle
- OutputBuffer!Handle

入出力を指定バイト確実に行うための関数を用意しました。
- void readExact(ubyte[] dst);
- void writeExact(in ubyte[] src);
なお、この関数は元々Handleに実装してある場合
- hasReadExact
- hasWriteExact
のテンプレートがtrueを示し、そちらを利用します。

汎用のByChunkを用意しました
- ChunkReaderRange!Handle
- ChunkReaderRange!Handle byChunk(Handle)(Handle handle, ubyte[] data);
- ChunkReaderRange!Handle byChunk(Handle)(Handle handle, size_t size);
指定バイトづつ読み込みます。

ファイル用、メモリ用のハンドルとして、ハンドルを用意しました
- FileHandle
-- this(string filename);
-- this(string filename, string attrib);
- MemoryHandle
-- this(ref ubyte[] buf);

エンディアンを考慮した出力のために、Rangeを用意しました
- EndianOutBuffer!(Range, Endian)
- EndianOutBuffer!(Range, LittleEndian) leoutbuf(Range)(Range r);
- EndianOutBuffer!(Range, BigEndian) beoutbuf(Range)(Range r);
- EndianOutBuffer!(Range, LittleEndian) byLittleEndian(Handle)(Handle h);
- EndianOutBuffer!(Range, BigEndian) byBigEndian(Handle)(Handle h);
投票数:52 平均点:3.85
返信する

この投稿に返信する

題名
ゲスト名
投稿本文

  条件検索へ


メインメニュー

ログイン

ユーザー名:


パスワード:





パスワード紛失  |新規登録

Menu