SER実行時ライブラリのリファレンスは、include/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を用いて、以下のように型を指定します。
配列・ポインタは、再帰的に(繰り返して)適用可能です。
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);
ルートオブジェクトから 必要な全てのオブジェクトを辿ることができる状態のとき、 アプリケーションプログラムは「ガベージコレクト」を行うことができます。
ガベージコレクトでは、以下の処理を行ないます。
コンパクションの際、オブジェクトのアドレスは変更される可能性があります。 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_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処理系に対して追加します。