関数リファレンス

SER実行時ライブラリのリファレンスは、include/SER.hを見て下さい... と言いたいところですが、一応ちょっとだけ。

SER.h

SERの通常の機能を使用するには、SER.hを#includeする必要があります (ただし、AP向けヘッダファイルを#includeすると付いてくるので、 通常は明示的に#includeする必要はありません)。

初期化

void SER_initialize(void);

SERを初期化します。SERを使用するアプリケーションは、 最初に一度だけこの関数をコールする必要があります。

ストレージの生成

SER_Storage SER_create_storage(SER_Schema schema);

ストレージを生成します。 この関数により作成したストレージを、以後、 SERのほとんどの関数の第1引数として使用することになります。

引数のschemaには、AP向けヘッダファイル内でexternされている グローバル変数を渡します。スキーマ名がhogeの時、schemaの変数名は SER_hoge_schemaとなります。

スキーマとストレージは、1:nの関係ですので、 ひとつのスキーマで複数のストレージを生成することが可能です。

ルートオブジェクトの設定

void SER_set_root_object(SER_Storage storage, SER_Object root);

そのストレージのルートオブジェクトを設定します。

SERは、ルートオブジェクトから(ポインタを経由して)辿れるオブジェクトを、 「生きている」オブジェクトとして扱います。

ルートオブジェクトの取得

SER_Object SER_get_root_object(SER_Storage storage);

ストレージのルートオブジェクトのポインタを返します。

ルートオブジェクト(に限らず全てのオブジェクト)のアドレスは、 コンパクションの際変更される可能性があるので、アプリケーションが グローバル変数やローカル変数で継続的に保持すべきではありません。 必ず SER_get_root_object()を使用してルートオブジェクトを取得し、 そこから辿るようにしてください。

オブジェクトの確保

SER_Object SER_malloc(SER_Storage storage, SER_Type const *type);

オブジェクトの領域を確保します。確保した領域は、 そのオブジェクトの型の初期値で初期化されています。

型の指定は、SER_Type型(実際にはint型)の配列で行ないます。

SER_Type型の取り得る値は、SER.hとAP向けヘッダファイルにまたがって 定義されています。

SER.hで定義されている分:
#define	SER_TYPE_CHAR		(1)
#define	SER_TYPE_SHORT		(2)
#define	SER_TYPE_INT		(3)
#define	SER_TYPE_LONG		(4)
#define	SER_TYPE_UCHAR		(5)
#define	SER_TYPE_USHORT		(6)
#define	SER_TYPE_UINT		(7)
#define	SER_TYPE_ULONG		(8)
#define	SER_TYPE_FLOAT		(9)
#define	SER_TYPE_DOUBLE		(10)
#define	SER_TYPE_ENUM		(11)
#define	SER_TYPE_ARRAY		(12)
#define	SER_TYPE_V_ARRAY	(13)
#define	SER_TYPE_POINTER	(14)
#define	SER_TYPE_STRUCT		(15)
#define	SER_TYPE_UNION		(16)

SER.hには、Cの基本型と派生型が定義されています。 このうち、SER_TYPE_ENUM, SER_TYPE_V_ARRAY, SER_TYPE_STRUCT, SER_TYPE_UNIONは、SER_malloc()の引数として使用することはありません。

AP向けヘッダファイルで定義されている分(サンプルプログラム"draw"の例):
#define	SER_TYPE_Polyline	(17)
#define	SER_TYPE_Box	(18)
#define	SER_TYPE_Circle	(19)
#define	SER_TYPE_ShapeType	(20)
#define	SER_TYPE_Shape	(21)
#define	SER_TYPE_Point	(22)
#define	SER_TYPE_NUM_shape	(22)

AP向けヘッダファイルでは、 スキーマファイルで新たに定義した型が定義されています。

SER_malloc()では、これらの#defineを用いて、以下のように型を指定します。

基本型、またはスキーマファイルで定義した型の場合
確保する型をそのまま指定します。
static const SER_Type type[] = {SER_TYPE_INT};
配列の場合
SER_TYPE_ARRAYの後に、要素数と基底型を指定します。
static const SER_Type type[] = {SER_TYPE_ARRAY, 10, SER_TYPE_INT};
ポインタの場合
SER_TYPE_POINTERの後に、基底型を指定します。
static const SER_Type type[] = {SER_TYPE_POINTER, SER_TYPE_INT};

配列・ポインタは、再帰的に(繰り返して)適用可能です。

intのポインタの配列(要素数10)の配列(要素数20)の場合:
static const SER_Type type[] = {
    SER_TYPE_ARRAY, 20,
    SER_TYPE_ARRAY, 10,
    SER_TYPE_POINTER,
    SER_TYPE_INT
};

SER_malloc()は、効率向上のため、オブジェクト毎に データ型のための領域を確保するようなことは行ないません。 よって、SER_malloc()に渡すtypeの指定にstatic を付けないと、 関数を抜けた時点で領域が解放されてしまい、後のガベージコレクトや シリアライズの際に必要な情報が取得できなくなってしまいます。

可変長配列の確保

SER_Object SER_malloc_array(SER_Storage storage, SER_Type const *type,
			    int num);

SER_malloc_array()では、可変長配列を確保します。

typeには、SER_malloc()と同一の形式で、 可変長配列の基底型となる型を指定します。

numには、要素数を指定します。

可変長配列の要素数取得

int SER_get_array_size(SER_Storage storage, SER_Object ptr);

可変長配列の要素数(バイト単位のサイズではない)を取得します。

可変長配列のリサイズ

SER_Object SER_resize(SER_Storage storage, SER_Object ptr, int num);

可変長配列をリサイズします。numには、 要素数(バイト単位のサイズではない)を指定します。

リサイズにより配列を縮めた場合、要素が後ろから単純に捨てられます。

逆に、伸ばした場合、後ろの要素は、 そのデータ型のデフォルト値で初期化されています。

オブジェクトの解放

void SER_free(SER_Storage storage, SER_Object ptr);

ガベージコレクタを使用せず、明示的にオブジェクトの領域を解放する場合は、 SER_free()を使用します。

ガベージコレクト

void SER_garbage_collect(SER_Storage storage);

ルートオブジェクトから 必要な全てのオブジェクトを辿ることができる状態のとき、 アプリケーションプログラムは「ガベージコレクト」を行うことができます。

ガベージコレクトでは、以下の処理を行ないます。

  1. ルートオブジェクトから到達不能な全てのオブジェクトを解放する。
  2. コンパクションを行なう。

コンパクションの際、オブジェクトのアドレスは変更される可能性があります。 SERの管理下にあるオブジェクト内にポインタが格納されている場合、 そのポインタは自動的に更新されますが、 アプリケーションが独自に(自動(ローカル)変数やグローバル変数で) オブジェクトへのポインタを保持していた場合、整合性が崩れてしまいます。

ストレージの破棄

void SER_dispose_storage(SER_Storage storage);

ストレージが不要になった場合、SER_dispose_storage()により破棄します。

シリアライズ

SER_CallStatus SER_serialize(SER_Storage storage, char *encode_type_name,
			     SER_Stream dest);

ルートオブジェクトから 必要な全てのオブジェクトを辿ることができる状態のとき(つまり ガベージコレクトと同じ条件)、 アプリケーションプログラムは「シリアライズ」を行なうことができます。

シリアライズにより、指定したストレージの全オブジェクトがシリアライズされ、 指定したストリーム(大抵はファイルポインタ)に出力されます。

SER_Stream型は、実際には単なるvoid*であり、そのままの形で エンコーダに渡されます。よって、destは、 大抵はファイルポインタですが、エンコーダとの合意次第で、 何を渡しても構いません。

デシリアライズ

SER_CallStatus SER_deserialize(SER_Schema schema, char *encode_type_name,
			       SER_Stream src, SER_Storage *storage);

SER_deserialize()により、 シリアライズしたデータを復元(デシリアライズ)できます。

オブジェクトのデータ型の取得

SER_Type const *SER_get_type(SER_Object p);

SER_malloc()の際に渡したオブジェクトのデータ型を取得します。


SER_encode.h

SER_encode.hで宣言されている関数は、 エンコーダ・デコーダを自作する人が使用します。

エンコードタイプの新規作成

SER_EncodeType SER_create_encode_type(char *name);

SER_create_encode_type()では、「エンコードタイプ」を新規作成します。

「エンコードタイプ」を新規作成しただけでは、 その時点のSERに対して何の影響もおよぼしません。 新規作成した「エンコードタイプ」に対し、エンコーダ・デコーダを指定し、 SERに対してaddした時点で初めてエンコードタイプとして 使用できるようになります。

エンコーダの設定

void SER_set_encoder(SER_EncodeType encode_type, SER_BuildInType type,
		     SER_EncodeProc func);

指定したエンコードタイプの指定した型に対して、エンコーダを設定します。

デコーダの設定

void SER_set_decoder(SER_EncodeType encode_type, SER_BuildInType type,
		     SER_DecodeProc func);

指定したエンコードタイプの指定した型に対して、デコーダを設定します。

エンコードタイプの追加

void SER_add_encode_type(SER_EncodeType encode_type);

エンコードタイプを、SER処理系に対して追加します。


ひとつ上のページに戻る | prev(サンプルプログラム"draw"について) | next(ディレクトリ構成)