TAD Class

1. TAD Class とは

TAD Class は、ファイルやストリームから TAD を 読み書きするのを助ける C++ クラスライブラリです。 生の TAD を解析して、セグメント単位で読み込んだり 書き込んだりできます。

2. 対応プラットホーム

2.1. 対応システム(OS)

現在は C++ の iostream を対象にしていて、 iostream の使える環境(UNIX,Windows,その他)なら どこでも使えるはずです。

将来的には BTRON1,BTRON3 の 実身(BRealObjTADInputStream,BRealObjTADOutputStream)と トレー(BTrayTADInputStream,BTrayTADOutputStream)を 作成する予定です。

2.2. 対応コンパイラ

できるかぎりプラットホームに依存しないようにしたつもりです。 私は Linux 上で gcc(egcs-2.90.27) でコンパイルしています。 他の環境でも使えるはずですが、 内部で STL を使用しているため、 STL の使えるコンパイラが必要になります。

ちなみに、Visual C++ 4.0 ではコンパイルできませんでした。 最新バージョンは持っていないので、 コンパイルできるかどうか分からないです。

コンパイルできないコンパイラが多いようでしたら、 ソースのほうで対応するかもしれません。

3. TAD Class の構成

3.1. 利用者から見た TAD Class の構成

TAD Class を利用する場合、使用するクラスは

の2種類です。

それ以外には、プログラムで使用するセグメントを 登録するための、BSegMakerRegister,BSubIDSegMakerRegister を 使用しますが、これの使い方は毎回同じなので 決まり文句として使えば良いです。

その他のクラスは直接使うことはまずないでしょう。

3.1.1 BSegment

BSegment は TAD のセグメントに対応するものです。 全てのセグメントは BSegment を継承しています。

BSegment の主な機能は、

の3種類です。

セグメントはあくまでデータであり、 ストリームとの入出力以外の機能は持たせません。

セグメントにはサブID を持つものもありますが、 サブID が違うと、ほとんど別物と言って良いほど内容が異なるので、 サブID ごとに別クラスとしています。
また、サブID のための機能が BSegment に 入っているので、サブID を持たないセグメントでは 無駄になってしまいますが、まあこのくらいなら良いのでは、と 思っています。

セグメントのデータメンバの多くは public になっています。 これは"セグメントはデータである"という考えに基づくものです。 ただ、複雑なデータ構造の場合は非公開にして get,set 関数を 準備します。

特殊なセグメントとして、BUnknownSeg と BStringSeg があります。

BUnknownSeg はまだ作成されていないセグメントを 処理するためのクラスです。 データ部分を Byte列として扱います。

BStringSeg は、一続きに連続した文字(固定長セグメント)を ひとまとめにしたものです。 本来の TAD には文字列セグメントは存在しませんが、 他のセグメントと同列に扱うために、BStringSeg があります。

3.1.2. BTADInputStream, BTADOutputStream

BTADInputStream, BTADOutputStream は抽象クラスで、 セグメント(BSegment)単位で読み書きできるストリームです。

定義は次のようになっています。

class BTADInputStream
{
public:
    virtual BSegment* getSegment()=0;
};

class BTADOutputStream
{
public:
    virtual bool putSegment(const BSegment* asegment)=0;
};

つまり、BSegment を取り出し、書き込む機能だけです。

3.2. TAD Class の内部構造

3.2.1 Byte ストリーム

BTADInputStream,BTADOutputStream はセグメントの並びですが、 生の TAD である Byte列(Byte ストリーム)を表したものが BByteInputStream,BByteOutputStream です。

BByteInputStream では、データの読み込みだけではなく、 機能も付いています。 BByteInputStream,BByteOutputStream でマシンの エンディアンの違いを吸収しています。

BByteInputStream,BByteOutputStream を継承して 新しい Byte ストリームを作る場合、
BByteInputStream : read_inner(),skip_inner()
BByteOutputStream : write_inner()
をオーバーロードしてください。 他のメソッドはオーバーロードする必要はないです。

3.2.2 BTADInputStream,BTADOutputStream の実装

BTADInputStream を実装するには Byte ストリーム(BByteInputStream)を解析する必要があります。 iostream、実身、トレーごと別々に 解析プログラムを書くのは無駄ですので、 Byte ストリームの解析をしてくれる補助クラス BTADInputHelper を準備しました。

TAD 解析のほとんどを BTADInputHelper がやってくれるので、 BTADInputStream を継承したクラスでは、 それぞれの特有の機能のプログラムだけに専念できます。

実際、IstreamInputStream では istream 特有の機能は なにもないので、IstreamInputStream では ほとんどなにもやってません。 BRealObjTADInputStream やBTrayTADInputStream では 仮身の扱いを自分でする必要があります。

同様に、BTADOutputStream の実装を助けるために BTADOutputHelper があります。

3.2.3 セグメントメーカー

BTADInputStream では、BByteInputStream から セグメントID,サブID を読み出したところで、 ID に対応する BSegment のサブクラスを インスタンス化する必要があります。

ID を指定するとそれに合うセグメントを生成するクラスは BSegmentMaker と言います。

TAD Class では、グローバル変数 defaultSegMaker が 準備してあり、普通は defaultSegMaker に 使用するセグメントを登録します。

登録作業を楽するために、 BSegMakerRegister,BSubIDSegMakerRegister があります。

例えば、BInfoSeg (ID: TS_INFO, サブID: なし)を登録する場合、
BSegMakerRegister();
とします。

独自の BSegmentMaker を作っても良いです。 例えば、myMaker に登録したい場合、
BSegMakerRegister(myMaker);
とします。

実際には、セグメントを生成する作業は BTADInputStream ではなく BTADInputHelper で行なわれています。

3.3. TAD Class の現状

3.3.1 セグメントのインプリメント状況

現在作成されているセグメントは

だけです。 作成されていないセグメントは BUnknownSeg で処理されます。

画像セグメントや仮身セグメントのような やっかいそうなセグメントは、とりあえず後回しにしてます。

その他のセグメントは必要になったら作ります。 ですから、欲しいセグメントは自分で作成してください。 もしよろしければ、作ったセグメントを私まで送っていただけると ありがたいです。

3.3.2 ストリームのインプリメント状況

C++ の iostream を利用する IstreamTADInputStream と OstreamTADInputStream が 作成されています。

将来的には BTRON1,BTRON3 の 実身(BRealObjTADInputStream,BRealObjTADOutputStream)と トレー(BTrayTADInputStream,BTrayTADOutputStream)を 作成する予定です。

4. 使用例

TAD Class は次のように使います。

IstreamTADInputStream in(cin); // 標準入力を利用する TADInputStream

BSegment* seg=in.getSegment(); // セグメントを1つ読み込みます。

OstreamTADOutputStream out(cout); //標準出力を利用する TADOutputStream

out.putSegment(seg); // セグメントをストリームに書き込みます。

文書作成: 落合秀俊 1998年5月3日