![]() ![]() ![]() ![]() |
この章では、「フィールドの定義と使用」で説明した実行時のマッピング関数を除く、すべての FML 関数および FML VIEWS 関数について説明します。
COBOL プログラムでは、FML 関数を直接使用できません。まず、FINIT
というプロシージャを使用して、FML データを受信するためにレコードを初期化し、次に FVSTOF
および FVFTOS
のプロシージャを使用して COBOL レコードと FML バッファ間の変換を行います。これらのプロシージャの詳細については、『COBOL を使用した Oracle Tuxedo アプリケーションのプログラミング』を参照してください。ここでは、COBOL インタフェースについては説明しません。
FML は、2 種類あります。従来の FML インタフェースは、フィールド長に 16 ビットの値を使用し、フィールドを識別する情報を格納します。したがって、FML16 と呼ばれます。FML16 では、ユニークなフィールド数は 8191、個々のフィールド長は最大 64K バイト、フィールド化バッファの総容量は 64K に制限されます。このインタフェースの定義、型、および関数のプロトタイプは fml.h
に定義され、FML16 インタフェースを使用するアプリケーション プログラムは、このファイルをインクルードする必要があります。各関数は、-lfml
にあります。
FML32 は、フィールド長と識別子に 32 ビットの値を使用します。FML32 では、約 3000 万個のフィールドを含むことができ、フィールド長およびバッファ長は約 20 GB まで使用できます。FML32 の定義、型、および関数のプロトタイプは、fml32.h
内にあります。各関数は、-lfml32
にあります。FML32 の定義、型、および関数名には、すべて接尾辞「32」が付きます (MAXFBLEN32
、FBFR32
、FLDID32
、FLDLEN32
、F_OVHD32
、Fchg32
、エラー コード Ferror32
など)。また、環境変数にも接頭辞 “32” が付きます (FLDTBLDIR32
、FIELDTBLS32
、VIEWFILES32
、VIEWDIR32
など)。FML32 では、フィールド化バッファのポインタは「FBFR32 *
」型、フィールド長は FLDLEN32
型、フィールドのオカレンス数は FLDOCC32
型です。FML32 バッファには、デフォルトで 4 バイトの調整が必要です。
正しく記述された FML16 アプリケーションは、簡単に FML32 インタフェースに変更できます。FML 関数の呼び出しに使用する変数は、すべて適切な typedef (FLDID
、FLDLEN
、および FLDOCC
) により定義されている必要があります。FML の型付きバッファに対して tpalloc(3c) を呼び出すときは、FML の代わりに FMLTYPE
で定義する必要があります。アプリケーションのソース コードに、fml.h
の代わりに fml32.h
を指定し、fml1632.h
を組み込むことで 32 ビットの関数を使用できるようになります。fml1632.h
には、すべての 16 ビットの型定義を 32 ビット版に変換したり、16 ビットの関数やマクロを 32 ビット版に変換するマクロが含まれています。
FML32 のフィールド化バッファを FML16 のフィールド化バッファに変換する関数や、その逆の変換を行う関数も提供されています。
#include “fml.h”
#include “fml32.h”
int
F32to16(FBFR *dest, FBFR32 *src)
int
F16to32(FBFR32 *dest, FBFR *src)
F32to16
は、32 ビットの FML バッファを 16 ビットの FML バッファに変換します。これは、フィールド対フィールドのバッファの変換を行い、フィールド化バッファのインデックスを作成することによって行ないます。FLDID32 から FLDID を生成し、フィールド値 (string
型および carray
型フィールドではフィールド長も含む) をコピーすると、フィールドは変換されます。
dest
は、変換後のフィールド化バッファを示すポインタ (宛先バッファ) であり、src
は、変換元のフィールド化バッファを示すポインタ (ソース バッファ) です。ソース バッファは変更されません。
これらの関数は、領域の不足により失敗する可能性があります。操作を完了するには、十分な追加領域を割り当ててから関数を再度発行します。F16to32
は、16 ビットの FML バッファを 32 ビットの FML バッファに変換します。この関数は、fml32
ライブラリまたは共有オブジェクトに格納されており、エラーが発生すると Ferror32
が設定されます。F32to16
は、fml
ライブラリまたは共有オブジェクトに格納されており、エラーが発生すると Ferror
が設定されます。これらの関数を使用するためには、fml.h
および fml32.h
の両方をインクルードする必要があることに注意してください。同じファイルに、fml1632.h
をインクルードする必要はありません。
埋め込み型バッファのフィールド型 (FLD_PTR
、FLD_FML32
、および FLD_VIEW32
) は、FML32 でのみサポートされています。FLD_PTR
型、FLD_FML32
型、FLD_MBSTRING
型、または FLD_VIEW32
型のフィールドを含むバッファを使用すると、F32to16
が失敗し、FBADFLD
エラーが返されます。これらの関数に対して F16to32
を呼び出しても、何も起こりません。
注意 : | 以降の節では、16 ビットの関数のみ説明し、対応する FML32 および VIEW32 関数は説明しません。 |
FML 関数のパラメータ仕様をわかりやすくするため、パラメータは、規則的な順序で指定されます。FML のパラメータは、次の順序で指定されます。
FBFR
) を必要とする関数の場合は、このポインタを最初に指定します。フィールド化バッファに対するポインタが 2 つ必要な関数 (転送関数など) の場合は、最初に宛先バッファに対するポインタを指定し、次にソース バッファに対するポインタを指定します。フィールド化バッファに対するポインタは、short 型の境界に調整した領域を指す必要があります (そうでない場合は、Ferror
に FALIGNERR
が設定されたエラーが返されます)。また、領域はフィールド化バッファでなければなりません (そうでない場合は、Ferror
に FNOTFLD
が設定されたエラーが返されます)。FLDID
型) を指定します (Fnext
の場合は、次にフィールド識別子に対するポインタを指定します)。FLDOCC
型) を必要とする関数の場合は、次にフィールド オカレンスを指定します (Fnext
の場合は、次にオカレンス番号に対するポインタを指定します)。carray
、mbstring
) 型フィールドを処理する関数にフィールド値を渡す場合は、次にフィールドの長さを決定するパラメータ (FLDLEN
型) を指定します。フィールド値を検索する関数の場合は、検索対象のバッファの長さに対するポインタを関数に渡す必要があります。このパラメータは、検索対象の値の長さに設定されます。
以下の関数を使用すると、プログラムの実行時にフィールド テーブルまたはフィールド識別子を照会し、フィールドに関する情報を取得できます。
Fldid
は、指定された有効なフィールド名のフィールド識別子を返し、フィールド名/フィールド識別子のマッピング テーブルがない場合は、そのテーブルをフィールド テーブル ファイルからロードします。
FLDID
Fldid(char *name
)
マッピング テーブルが使用するメモリ領域は、Fnmid_unload、Fnmid_unload32(3fml) 関数を使用して解放することができます。ただし、これらのテーブルは、Fname
関数でロードされ、使用されるテーブルとは異なります。
詳細については、『Oracle Tuxedo FML リファレンス』の「Fldid、Fldid32(3fml)」を参照してください。
Fname
は、指定された有効なフィールド識別子のフィールド名を返し、フィールド識別子/フィールド名のマッピング テーブルがない場合は、そのテーブルをフィールド テーブル ファイルからロードします。
char *
Fname(FLDIDfieldid
)
マッピング テーブルが使用するメモリ領域は、Fnmid_unload、Fnmid_unload32(3fml) 関数を使用して解放することができます。ただし、これらのテーブルは、Fldid
関数によってロードおよび使用されるテーブルとは別のテーブルです。詳細については、『Oracle Tuxedo FML リファレンス』を参照してください。
詳細については、『Oracle Tuxedo FML リファレンス』の「Fname、Fname32(3fml)」を参照してください。
Fldno
は、指定されたフィールド識別子からフィールド番号を抽出します。
FLDOCC
Fldno(FLDIDfieldid
)
詳細については、『Oracle Tuxedo FML リファレンス』の「Fldno、Fldno32(3fml)」を参照してください。
Fldtype
は、指定されたフィールド識別子からフィールドの型 (fml.h
で定義された整数) を抽出します。
int
Fldtype(FLDIDfieldid
)
詳細については、『Oracle Tuxedo FML リファレンス』の「Fldtype、Fldtype32(3fml)」を参照してください。
Ftype
は、フィールド識別子で指定されたフィールドの型名を含む文字列に対するポインタを返します。
char *
Ftype(FLDIDfieldid
)
fieldid
は、有効なフィールド識別子です。たとえば、次のコードは、short
型、long
型、char
型、float
型、double
型、string
型、carray
型、mbstring
型、FLD_PTR
型、FLD_FML32
型、FLD_VIEW32
型のいずれか 1 つの文字列に対するポインタを返します。
char *typename
.. .
typename = Ftype(fieldid);
詳細については、『Oracle Tuxedo FML リファレンス』の「Ftype、Ftype32(3fml)」を参照してください。
アプリケーションの作成機能の一部として、またはフィールド識別子を再作成するため、型の種類とフィールド番号からフィールド識別子を作成しておくと便利です。Fmkfldid
は、この機能を提供します。
FLDID
Fmkfldid(inttype
, FLDIDnum
)
type
は、有効な型、つまり整数です。詳細については、「Fldtype」を参照してください。num
は、フィールド番号です。既存のフィールドとの混同を避けるため、未使用のフィールド番号を指定する必要があります。
詳細については、『Oracle Tuxedo FML リファレンス』の「Fmkfldid、Fmkfldid32(3fml)」を参照してください。
ここでは、スタンドアロンの FML プログラムをコーディングするための関数を説明します。Oracle Tuxedo の ATMI 関数を使用している場合に、メッセージ バッファを割り当てたり、割り当てを解除するには、Falloc、Falloc32(3fml)、Frealloc、Frealloc32(3fml)、Ffree、Ffree32(3fml) などの FML 関数の代わりに、tpalloc(3c)、tprealloc(3c)、tpfree(3c) などの ATMI 関数を呼び出さなければなりません。
大半の FML 関数では、引数としてフィールド化バッファに対するポインタが必要です。このようなポインタを宣言するには、次の例のように、typedef
宣言をした FBFR
を使用できます。
FBFR *fbfr
;
この節では、変数 fbfr
をフィールド化バッファに対するポインタとして使用します。フィールド化バッファ自体は宣言できません。宣言できるのは、フィールド化バッファに対するポインタだけです。
サーバは、FML バッファを含む要求を受け取ると、受け取った FML バッファと埋め込み型の VIEW または FLD_PTR
フィールドが参照するバッファに対して領域を割り当てます。新しい FML バッファに対するポインタが、ユーザ記述コードに渡されます。サーバの処理が終了したら、メッセージ受信時に割り当てたバッファはすべて破棄しなければなりません。Oracle Tuxedo システムによって FML バッファとすべての補助バッファが調べられ、参照が見つかったバッファはすべて削除されます。サーバ コードをコーディングする場合は、以下の状況を認識しておく必要があります。
tpreturn()
に渡された FML バッファは解放されますが、FLD_PTR
フィールドまたは FLD_VIEW32
フィールドによって参照されるバッファは解放されません。
この節では、フィールド化バッファの領域を確保するための関数について説明します。まず、指定されたバッファがフィールド化バッファであるかどうかを判別するための関数を説明します。
Fielded
(または Fielded32
) を使用すると、指定されたバッファがフィールド化されているかどうかをテストできます。
int
Fielded(FBFR *fbfr
)
Fielded32
は 32 ビットの FML と共に使用します。
Fielded
を使用すると、バッファがフィールド化されている場合は true (1
) が返されます。バッファがフィールド化されていない場合は false (0
) が返されます。この場合、Ferror
は設定されません。
詳細については、『Oracle Tuxedo FML リファレンス』の「Fielded、Fielded32(3fml)」を参照してください。
フィールド化バッファに割り当てるメモリ領域のサイズは、フィールド化バッファに指定できるフィールドの最大数と、すべてのフィールド値に必要な領域の合計サイズによって異なります。Fneeded
を使用すると、フィールド化バッファに必要な領域 (バイト単位) を判別できます。この関数には引数として、フィールド数とすべてのフィールド値に必要な領域 (バイト単位) を指定します。
long
Fneeded(FLDOCCF
, FLDLENV
)
フィールド値に必要な領域は、各フィールド値が標準的な構造で格納された場合の領域を見積もることにより、算出できます。たとえば、long
型の値が long
型として格納されると、4 バイトの領域が必要です。可変長フィールドの場合は、フィールドに必要な領域の平均値を見積もります。Fneeded
で算出される領域には、フィールドごとの固定オーバーヘッドが含まれます。つまり、フィールド値に必要な領域には、オーバーヘッド分が加算されます。
Fneeded
を使用して必要な領域を見積もったら、malloc
(3) を使用して必要なバイト数を割り当て、割り当てたメモリ領域に対するポインタを設定できます。たとえば、次のコードでは、フィールド化バッファに対し、25 個のフィールドと 300 バイトの値を格納できるだけの領域を割り当てています。
#define NF 25
#define NV 300
extern char *malloc;
.. .
if((fbfr = (FBFR *)malloc(Fneeded(NF, NV))) == NULL)
F_error("pgm_name"); /* バッファを割り当てる領域がない */
ただし、このコードで割り当てられたメモリ領域は、まだフィールド化バッファではありません。この領域は、Finit
を使用して初期化する必要があります。
詳細については、『Oracle Tuxedo FML リファレンス』の「Fneeded、Fneeded32(3fml)」を参照してください。
Fvneeded
関数を使用すると、VIEW
バッファに必要な領域 (バイト単位) を判別できます。この関数には、引数として VIEW
の名前に対するポインタを指定します。
long
Fvneeded(char *subtype
)
Fvneeded
関数は、VIEW
のサイズをバイト数で返します。
詳細については、『Oracle Tuxedo FML リファレンス』の「Fvneeded、Fvneeded32(3fml)」を参照してください。
Finit
は、割り当てられたメモリ領域をフィールド化バッファとして初期化します。
int
Finit(FBFR *fbfr
, FLDLENbuflen
)
Fneeded の例で割り当てたメモリ領域を初期化するために Finit
を呼び出す場合は、以下の形式を使用します。
Finit(fbfr, Fneeded(NF, NV));
この呼び出しの結果、fbfr
は、初期化された空のフィールド化バッファを指します。Fneeded
(NF, NV)
によって割り当てられた最大バイト数から、fml.h
で定義された F_OVHD
分を差し引いたバイト数を、バッファのフィールド領域として使用できます。
注意 : | ただし、malloc (3) (前の節を参照) への呼び出しと Finit への呼び出しでは、同じ値を使用する必要があります。 |
詳細については、『Oracle Tuxedo FML リファレンス』の「Finit、Finit32(3fml)」を参照してください。
Fneeded
、malloc
(3)、および Finit
に対する呼び出しは、Falloc
に対する 1 回の呼び出しで置き換えることができます。この関数を使用すると、必要な領域を割り当て、バッファを初期化できます。
FBFR *
Falloc(FLDOCCF
, FLDLEN
V
)
前の 3 つの節で説明した、Fneeded
、malloc()
、および Finit
と同じ機能を実行する Falloc
への呼び出しは、次のようにコーディングします。
extern FBFR *Falloc;
. . .
if((fbfr = Falloc(NF, NV)) == NULL)
F_error(“pgm_name”); /* バッファを割り当てることができなかった */
Falloc
(または、Fneeded
、malloc
(3) および Finit
) によって割り当てられたストレージを解放するには、Ffree
を使用します。『Oracle Tuxedo FML リファレンス』の「Ffree、Ffree32(3fml)」を参照してください。
詳細については、『Oracle Tuxedo FML リファレンス』の「Falloc、Falloc32(3fml)」を参照してください。
Ffree
は、フィールド化バッファとして割り当てられたメモリ領域を解放します。Ffree32
は、FLD_PTR
フィールドのポインタによって参照されるメモリ領域を解放しません。
int
Ffree(FBFR *fbfr
)
fbfr
は、フィールド化バッファに対するポインタです。次の例を参照してください。
#include <fml.h>
. . .
if(Ffree(fbfr) < 0)
F_error("pgm_name"); /* フィールド化バッファではない */
free
(3) より Ffree
の使用をお勧めします。free
(3) ではフィールド化バッファを無効にできませんが、Ffree
を使用するとフィールド化バッファを無効にできます。フィールド化バッファの無効化が必要なのは、malloc
(3) が解放されたメモリをクリアせずに再利用するためです。free
(3) を使用すると、malloc
が無効化されていないフィールド化バッファを返す可能性があります。
フィールド化バッファの領域を直接確保することもできます。フィールド化バッファは、short
型境界に調整させて開始する必要があります。バッファには、少なくとも F_OVHD
分のバイト (fml.h
で定義) を割り当てる必要があります。割り当てないと、Finit
からエラーが返されます。
以下のコードは、前の節の例と似ていますが、Fneeded
はマクロではないため、静的バッファのサイズ指定には使用できません。
/* 最初の行でバッファを調整している */
static short buffer[500/sizeof(short)];
FBFR *fbfr=(FBFR *)buffer;
. . .
Finit(fbfr, 500);
FBFR badfbfr;
. . .
Finit(&badfbfr, Fneeded(NF, NV));
このコードは間違いです。FBFR
の構造体がユーザのヘッダ ファイルで定義されていません。したがって、コンパイル時にエラーが発生します。
詳細については、『Oracle Tuxedo FML リファレンス』の「Ffree、Ffree32(3fml)」を参照してください。
Fsizeof
は、バイト単位でフィールド化バッファのサイズを返します。
long
Fsizeof(FBFR *fbfr
)
fbfr
は、フィールド化バッファに対するポインタです。たとえば、次のコードでは、Fsizeof
は、フィールド化バッファの当初の割り当て時に Fneeded
が返した数と同じ数を返します。
long bytes;
. . .
bytes = Fsizeof(fbfr);
詳細については、『Oracle Tuxedo FML リファレンス』の「Fsizeof、Fsizeof32(3fml)」を参照してください。
Funused
を使用すると、フィールド化バッファの領域のうち、追加データを格納するために使用できる領域を判別できます。
long
Funused(FBFR *fbfr
)
fbfr
は、フィールド化バッファに対するポインタです。次の例を参照してください。
long unused;
. . .
unused = Funused(fbfr);
Funused
は、空き領域のバイト数のみを示し、バッファ内での空き領域の位置は示しません。
詳細については、『Oracle Tuxedo FML リファレンス』の「Funused、Funused32(3fml)」を参照してください。
Fused
を使用すると、フィールド化バッファ内でデータおよびオーバーヘッド用に使用されている領域を判別できます。
long
Fused(FBFR *fbfr
)
fbfr
は、フィールド化バッファに対するポインタです。次の例を参照してください。
long used;
. . .
used = Fused(fbfr);
Fused
は、使用済み領域のバイト数のみを示し、バッファ内での位置は示しません。
詳細については、『Oracle Tuxedo FML リファレンス』の「Fused、Fused32(3fml)」を参照してください。
この関数を使用すると、Falloc
を呼び出して既に領域を割り当てたバッファのサイズを変更できます。
tpalloc(3c) で領域を割り当てた場合は、tprealloc(3c) を呼び出して領域を再び割り当てます。バッファのサイズ変更機能は、新しいフィールド値を追加したために空き領域が不足した場合などに役立ちます。このような場合は、単に Frealloc
を呼び出すだけでバッファのサイズを増やすことができます。また、Frealloc
を呼び出してバッファのサイズを小さくすることもできます。
FBFR *
Frealloc(FBFR *fbfr
, FLDOCCnf
, FLDLENnv
)
FBFR *newfbfr;
. . .
if((newfbfr = Frealloc(fbfr, NF+5, NV+300)) == NULL)
F_error(“pgm_name”); /* 領域を再割り当てできなかった */
else
fbfr = newfbfr; /* 新しいポインタを設定する */
この例では、アプリケーション側で、既に割り当てられたフィールド数と値の領域のバイト数を認識している必要があります。Frealloc
の引数 (および対応する realloc
(3)) は絶対値であり、インクリメント値ではありません。領域の割り当てを複数回行う必要がある場合、このサンプル コードは正しく動作しません。
以下の例では、割り当てられた領域をインクリメントする別の方法を示します。
/* バッファがなくなった時にサイズを増やす */
#define INCR 400
FBFR *newfbfr;
. . .
if((newfbfr = Frealloc(fbfr, 0, Fsizeof(fbfr)+INCR)) == NULL)
F_error(“pgm_name”); /* 領域を再割り当てできなかった */
else
fbfr = newfbfr; /* 新しいポインタを設定する */
この例では、バッファが最後に初期化されたときのフィールド数や値の領域のサイズを知っておく必要はありません。したがって、サイズを増やす最も簡単な方法は、現在のサイズにインクリメント値を加えたサイズを値の領域として使用することです。上の例は、必要に応じて何回でも実行することができます。過去の実行内容や値を覚えておく必要はありません。Frealloc
を呼び出した後で Finit
を呼び出す必要はありません。
Frealloc
に対する呼び出しで要求した追加の領域が古いバッファと隣接している場合は、上の例の newfbfr
と fbfr
は同一になります。ただし、プログラムが正しく実行されるようにするため、newfbfr
を宣言しておき、新しい値または NULL 値が返されるのを防ぐ必要があります。Frealloc
が失敗した場合、fbfr
は再使用しないでください。
注意 : | バッファ サイズは、バッファ内で現在使用中のバイト数までしか縮小できません。 |
詳細については、『Oracle Tuxedo FML リファレンス』の「Frealloc、Frealloc32(3fml)」を参照してください。
フィールド化バッファの位置に関する唯一の制約は、フィールド化バッファを short
型境界に調整しなければならないことです。この制約がなければ、フィールド化バッファをメモリ内で自由に移動できます。
src
がフィールド化バッファを指し、dest
がフィールド化バッファを保持できるサイズのストレージ領域を指す場合は、以下のコードを使用してフィールド化バッファを移動できます。
FBFR *src
;
char *dest
;
. . .
memcpy(dest, src, Fsizeof(src));
C の実行時メモリ管理関数の 1 つである memcpy
は、指定したバイト数のバッファ (3 つ目の引数で指定) を、指定した領域 (2 つ目の引数で指定) から別の領域 (1 つ目の引数で指定) に移動します。
memcpy
を使用するとフィールド化バッファをコピーできますが、コピー先のバッファは、コピー元と同じになります。たとえば、コピー先の空き領域のバイト数は、コピー元の空き領域のバイト数と同じです。
Fmove
は、memcpy
と同じように動作します。ただし、明示的に長さを指定する必要はありません (自動的に算出されます)。
int
Fmove(char *dest
, FBFR *src
)
たとえば、次のコードでは、Fmove
は、ソース バッファがフィールド化バッファかどうかを確認しますが、このバッファの変更は行いません。
FBFR *src;
char *dest;
. . .
if(Fmove(dest,src) < 0)
F_error("pgm_name");
宛先バッファは、フィールド化バッファ (Falloc
で割り当てられたバッファ) でなくてもかまいませんが、short
型境界に調整されている必要があります (FML32 では 4 バイト)。したがって、Fmove
は、フィールド化バッファをフィールド化バッファ以外のバッファにコピーする必要がある時に、Fcpy
の代替関数として機能します。ただし Fmove
は、宛先バッファに十分な領域があるかどうかの確認は行いません。
値が FLD_PTR
型の場合、Fmove32
はバッファ ポインタを転送します。アプリケーション プログラマは、対応するポインタの移動に応じてバッファの再割り当て、および解放を管理する必要があります。FLD_PTR
フィールドが指すバッファは、tpalloc(3c) を呼び出して割り当てます。
詳細については、『Oracle Tuxedo FML リファレンス』の「Fmove、Fmove32(3fml)」を参照してください。
Fcpy
は、あるフィールド化バッファを別のフィールド化バッファで上書きするために使用します。
int
Fcpy(FBFR *dest
, FBFR *src
)
Fcpy
は、上書きされたフィールド化バッファの全体の長さを保持するため、フィールド化バッファのサイズを拡大または縮小する場合に便利です。次の例を参照してください。
FBFR *src, *dest;
. . .
if(Fcpy(dest, src) < 0)
F_error(“pgm_name”);
Fmove
の dest
は、初期化されていない領域を指す場合があります。しかし、Fcpy
の dest
には、初期化されたフィールド化バッファ (Falloc
で割り当てられる) を指定する必要があります。さらに、Fcpy
は、dest
に指定されたバッファが十分な大きさであるかどうかも検証します。
注意 : | フィールド化バッファのサイズを、現在格納されているデータの領域より小さくすることはできません。 |
Fmove
と同じく、Fcpy
は、ソース バッファを変更しません。
値が FLD_PTR
型の場合、Fcpy32
はバッファ ポインタをコピーします。アプリケーション プログラマは、対応するポインタがコピーされたときのバッファの再割り当ておよび解放を管理する必要があります。FLD_PTR
フィールドが指すバッファは、tpalloc(3c) を呼び出して割り当てます。
詳細については、『Oracle Tuxedo FML リファレンス』の「Fcpy、Fcpy32(3fml)」を参照してください。
この節では、変換処理を行わずにフィールド型を使用して、フィールド化バッファにアクセスしたり、更新する方法を説明します。フィールド化バッファから、またはフィールド化バッファへのデータ転送時に、データ型を変換する関数の一覧については、「変換を行う関数」を参照してください。
Fadd
は、フィールド化バッファに新しいフィールド値を追加します。
int
Fadd(FBFR *fbfr
, FLDIDfieldid
, char *value
, FLDLENlen
)
バッファ内にフィールド オカレンスがない場合は、フィールドが追加されます。1 つまたは複数のフィールド オカレンスが既に存在する場合は、新しいフィールド オカレンスとして値が追加され、現在指定されている最も大きい番号より 1 つ大きい番号が割り当てられます。特定のオカレンスを追加するには、Fchg
を使用します。
Fadd
には、フィールド値に対するポインタを指定し、フィールド値自体は指定しません。これは、フィールド値を取得したり、フィールド値を返すその他の関数でも同じです。
フィールド長が固定されているフィールド型 (short
型、long
型、char
型、float
型、double
型)、またはフィールド長を指定できるフィールド型 (string
型) の場合、フィールド長を指定する必要ありません。フィールド長は無視されます。フィールド型が文字配列 (FLD_CARRAY
または FLD_MBSTRING
) の場合は、フィールド長を指定する必要があります。フィールド長は FLDLEN
型で定義されます。たとえば、次のコードは、目的のフィールドのフィールド識別子を取得し、フィールド値をバッファに追加します。
FLDID fieldid, Fldid;
FBFR *fbfr;
. . .
fieldid = Fldid("fieldname");
if(Fadd(fbfr, fieldid, "new value", (FLDLEN)9) < 0)
F_error("pgm_name");
デフォルトでは、文字配列型がネイティブなフィールド型と見なされます。したがって、関数には値の長さを渡す必要があります。追加する値が文字配列以外の場合、value
の型は、ポインタが指す値の型に応じて変わります。たとえば、次のコードは、long 型のフィールド値を追加します。
long lval;
. . .
lval = 123456789;
if(Fadd(fbfr, fieldid, &lval, (FLDLEN)0) < 0)
F_error("pgm_name");
文字配列フィールドの場合、NULL フィールドは、長さ 0 で表します。文字列フィールドでは、フィールド値の一部として NULL 終了バイトが格納されるので、NULL 文字列を格納できます。つまり、NULL 終了バイトだけで構成される文字列は、長さ 1 であると見なされます。これ以外の型 (固定長の型) では、アプリケーション プログラムで NULL と解釈される特殊な値を使用できますが、値のサイズは、実際に渡される値とは関係なく、フィールド型で指定されます (たとえば、long
型の場合は長さ 4)。NULL 値のアドレスを渡すとエラー (FEINVAL
) が発生します。
ポインタ フィールドの場合、Fadd32
はポインタ値を格納します。FLD_PTR
フィールドが指すバッファは、tpalloc(3c) を呼び出して割り当てます。埋め込み型の FML32 バッファの場合、Fadd32
はインデックスを除くすべての FLD_FML32
フィールド値を格納します。
埋め込み型の VIEW32 バッファの場合、Fadd32
は FVIEWFLD
型の構造体に対するポインタを格納します。FVIEWFLD 型の構造体には、vflags (現在未使用で 0
に設定されているフラグ フィールド)、vname
(VIEW 名を含む文字配列)、および data
(C 構造体として格納される VIEW データに対するポインタ) が含まれています。アプリケーションは、Fadd32
に vname
と data
を提供します。FVIEWFLD
構造体は、次のとおりです。
typedef struct {
TM32U vflags; /* フラグ - 現在未使用 */
char vname[FVIEWNAMESIZE+1]; /* VIEW の名前 */
char *data; /* VIEW 構造体に対するポインタ */
} FVIEWFLD;
詳細については、『Oracle Tuxedo FML リファレンス』の「Fadd、Fadd32(3fml)」を参照してください。
Fappend
は、フィールド化バッファに新しいフィールド値を付加します。
int
Fappend(FBFR *fbfr
, FLDIDfieldid
, char *value
, FLDLENlen
)
Fappend
は、value
で定義された値を指定した、新しい fieldid
のフィールド オカレンスを付加し、バッファを付加モードにします。付加モードでは、同じフィールド セットを含む多数の行で構成された、サイズの大きいバッファが最適化されます。
バッファを付加モードにすると、バッファに対する操作が制限されます。付加モードで呼び出せる FML ルーチンは、Fappend
、Findex
、Funindex
、Ffree
、Fused
、Funused
、および Fsizeof
です。Findex
または Funindex
を呼び出すと、付加モードは終了します。
次の例では、Fappend
を使用して、各行に 5 つのフィールドがある 500 行のバッファを作成します。
for (i=0; i 500 ;i++) {
if ((Fappend(fbfr, LONGFLD1, &lval1[i], (FLDLEN)0) < 0) ||
(Fappend(fbfr, LONGFLD2, &lval2[i], (FLDLEN)0) < 0) ||
(Fappend(fbfr, STRFLD1, &str1[i], (FLDLEN)0) < 0) ||
(Fappend(fbfr, STRFLD2, &str2[i], (FLDLEN)0) < 0) ||
(Fappend(fbfr, LONGFLD3, &lval3[i], (FLDLEN)0) < 0)) {
F_error("pgm_name");
break;
}
}
Findex(fbfr, 0);
Fappend
には、フィールド値に対するポインタを指定し、フィールド値自体は指定しません。これは、フィールド値を取得したり、フィールド値を返すその他の関数でも同じです。
フィールド長が固定されているフィールド型 (short
型、long
型、char
型、float
型、double
型)、またはフィールド長を指定できるフィールド型 (string
型) の場合、フィールド長を指定する必要ありません。フィールド長は無視されます。フィールド型が文字配列 (FLD_CARRAY
または FLD_MBSTRING
) の場合は、フィールド長を指定する必要があります。フィールド長は FLDLEN
型で定義されます。
デフォルトでは、文字配列型がネイティブなフィールド型と見なされます。したがって、関数には値の長さを渡す必要があります。付加する値が文字配列以外の場合、value
の型は、ポインタが指す値の型に応じて変わります。
文字配列フィールドの場合、NULL フィールドは、長さ 0 で表します。文字列フィールドでは、フィールド値の一部として NULL 終了バイトが格納されるので、NULL 文字列を格納できます。つまり、NULL 終了バイトだけで構成される文字列は、長さ 1 であると見なされます。これ以外の型 (固定長の型) では、アプリケーション プログラムで NULL と解釈される特殊な値を使用できますが、値のサイズは、実際に渡される値とは関係なく、フィールド型で指定されます (たとえば、long
型の場合は長さ 4)。NULL 値のアドレスを渡すとエラー (FEINVAL
) が発生します。
詳細については、『Oracle Tuxedo FML リファレンス』の「Fappend、Fappend32(3fml)」を参照してください。
int
Fchg(FBFR *fbfr
, FLDIDfieldid
, FLDOCCoc
, char *value
, FLDLENlen
)
fbfr
は、フィールド化バッファを指すポインタです。fieldid
は、フィールド識別子です。oc
は、フィールドのオカレンス番号です。value
は、新しい値に対するポインタです。上の例は char *
型を示していますが、実際に使用するときは、追加する値と同じ型を指定します (「Fadd」を参照)。FLD_CARRAY
型または FLD_MBSTRING
型の場合、len
は値の長さです。
たとえば、次のコードは、carray
型のフィールドを value
に格納された新しい値に変更します。
FBFR *fbfr;
FLDID fieldid;
FLDOCC oc;
FLDLEN len;
char value[50];
.. .
strcpy(value, "new value");
flen = strlen(value);
if(Fchg(fbfr, fieldid, oc, value, len) < 0)
F_error("pgm_name");
oc
が -1 の場合、フィールド値が新しいオカレンスとしてバッファに追加されます。oc
が 0 以上であり、フィールドが見つかった場合、フィールド値は指定された新しい値に変更されます。oc
が 0 以上であり、フィールドがない場合は、指定されたオカレンスとして値を追加できるまで、NULL オカレンスがバッファに追加されます。たとえば、バッファ上に存在しないフィールドのフィールド オカレンス 3 を変更しようとすると、3 つの NULL オカレンス (オカレンス 0、1 および 2) が追加され、続いて、フィールド値が指定されたオカレンス 3 が追加されます。NULL 値については、文字列型と文字型の値の場合は NULL 文字列「\0
」(長さ 1 バイト)、long 型と short 型のフィールドの場合は 0
、float 型と double 型の値の場合は 0.0
、文字配列の場合は 0 長の文字列が使用されます。
新しい値または変更された値は、value
に格納されます。文字配列 (FLD_CARRAY
または FLD_MBSTRING
) の場合、長さは len
で指定されます。その他のフィールド型では、len
は無視されます。値のポインタが NULL であり、フィールドが見つかった場合、そのフィールドは削除されます。削除対象のフィールド オカレンスが見つからないと、エラー (FNOTPRES
) と見なされます。
ポインタ フィールドの場合、Fchg32
にポインタ値が格納されます。FLD_PTR
フィールドが指すバッファは、tpalloc(3c) を呼び出して割り当てます。埋め込み型の FML32 バッファの場合、Fchg32
は、インデックスを除くすべての FLD_FML32
フィールドの値を格納します。
埋め込み型の VIEW32 バッファの場合、Fchg32
は FVIEWFLD
型の構造体に対するポインタを格納します。FVIEWFLD 型の構造体には、vflags
(現在未使用で 0
に設定されているフラグ フィールド)、vname
(VIEW 名を含む文字配列)、および data
(C 構造体として格納される VIEW データに対するポインタ) が含まれています。アプリケーションは、vname
と data
を Fchg32
に提供します。FVIEWFLD
構造体は、次のとおりです。
typedef struct {
TM32U vflags; /* フラグ - 現在未使用 */
char vname[FVIEWNAMESIZE+1]; /* VIEW の名前 */
char *data; /* VIEW 構造体に対するポインタ */
} FVIEWFLD;
バッファには、変更または追加されたフィールド値を格納できる領域が必要です。空き領域不足の場合、エラー (FNOSPACE
) が返されます。
詳細については、『Oracle Tuxedo FML リファレンス』の「Fchg、Fchg32(3fml)」を参照してください。
Fcmp
は、2 つのフィールド化バッファのフィールド識別子とフィールド値を比較します。
int
Fcmp(FBFR *fbfr1
, FBFR *fbfr2
)
fbfr1
および fbfr2
は、フィールド化バッファに対するポインタです。
この関数は、2 つのバッファが同一の場合は 0
を返し、以下の条件のいずれかが成立する場合は -1
を返します。
ポインタと埋め込み型のバッファが同一かどうかは、以下の条件によって決まります。
Fcmp
は、上記のいずれかの条件の逆が true である場合に 1
を返します。たとえば、fbfr2
フィールドのフィールド識別子が fbfr1
フィールドの対応するフィールド識別子より小さい場合、Fcmp
は 1
を返します。
詳細については、『Oracle Tuxedo FML リファレンス』の「Fcmp、Fcmp32(3fml)」を参照してください。
Fdel
は、指定されたフィールド オカレンスを削除します。
int
Fdel(FBFR *fbfr
, FLDIDfieldid
, FLDOCCoc
)
たとえば、次のコードは、指定されたフィールド識別子が示すフィールドの最初のオカレンスを削除します。
FLDOCC occurrence;
. . .
occurrence=0;
if(Fdel(fbfr, fieldid, occurrence) < 0)
F_error("pgm_name");
指定されたフィールドが存在しない場合は -1
が返され、Ferror
が FNOTPRES
に設定されます。
ポインタ フィールドの場合、Fdel32
は、参照されるバッファを変更したり、ポインタを解放しないで、FLD_PTR
フィールド オカレンスを削除します。データ バッファは、オペークなポインタとして扱われます。
詳細については、『Oracle Tuxedo FML リファレンス』の「Fdel、Fdel32(3fml)」を参照してください。
Fdelall
は、指定されたフィールドのすべてのオカレンスをバッファから削除します。
int
Fdelall(FBFR *fbfr
, FLDIDfieldid
)
if(Fdelall(fbfr, fieldid) < 0)
F_error("pgm_name"); /* フィールドが存在しない */
フィールドが見つからないと、-1
が返され、Ferror
が FNOTPRES
に設定されます。
ポインタ フィールドの場合、Fdelall32
は、参照されるバッファを変更したり、ポインタを解放しないで、FLD_PTR
フィールド オカレンスを削除します。データ バッファは、オペークなポインタとして扱われます。
詳細については、『Oracle Tuxedo FML リファレンス』の「Fdelall、Fdelall32(3fml)」を参照してください。
Fdelete
は、フィールド識別子の配列 (fieldid[]
) にリストされているすべてのフィールドのすべてのオカレンスを削除します。
int
Fdelete(FBFR *fbfr
, FLDID *fieldid
)
更新は、フィールド化バッファに対して直接行われます。フィールド識別子の配列内のエントリを特定の順序で並べる必要はありませんが、配列の最後のエントリは、フィールド識別子 0 (BADFLDID
) でなければなりません。次の例を参照してください。
#include "fldtbl.h"
FBFR *dest;
FLDID fieldid[20];
. . .
fieldid[0] = A; /* フィールド A のフィールド識別子 */
fieldid[1] = D; /* フィールド D のフィールド識別子 */
fieldid[2] = BADFLDID; /* 標識値 */
if(Fdelete(dest, fieldid) < 0)
F_error("pgm_name");
宛先バッファに、A、B、C、D という 4 つのフィールドがある場合、上記の例では、フィールド B およびフィールド C のオカレンスのみを含むバッファが生成されます。
Fdelete
を使用すると、Fdelall
を数回呼び出す場合より効率的にバッファから複数のフィールドを削除できます。
ポインタ フィールドの場合、Fdelete
は、参照されるバッファを変更したり、ポインタを解放しないで、FLD_PTR
フィールド オカレンスを削除します。データ バッファは、オペークなポインタとして扱われます。
詳細については、『Oracle Tuxedo FML リファレンス』の「Fdelete、Fdelete32(3fml)」を参照してください。
Ffind
は、バッファ内の指定されたフィールド オカレンスの値を検索します。
char *
Ffind(FBFR *fbfr
, FLDIDfieldid
, FLDOCCoc
, FLDLEN *len
)
上の例では、Ffind
の戻り値として、文字ポインタのデータ型 (C の char*
) が示されています。実際に返されるポインタの型は、ポインタが指す値の型と同じです。
#include "fldtbl.h"
FBFR *fbfr;
FLDLEN len;
char* Ffind, *value;
. . .
if((value=Ffind(fbfr,ZIP,0, &len)) == NULL)
F_error("pgm_name");
フィールドが見つかると、フィールドの長さが len
内に返され (len
が NULL の場合は、長さは返されない)、フィールドの位置が関数の値として返されます。フィールドが見つからないと、NULL が返され、Ferror
が FNOTPRES
に設定されます。
Ffind
は、フィールドに対して読み取り専用でアクセスするために使用します。Ffind
からの戻り値でバッファを変更することはできません。フィールド値を変更できるのは、Fadd
または Fchg
関数のみです。この関数は、埋め込み型のバッファにある指定されたフィールドのオカレンスは調べません。
Ffind
からの戻り値は、バッファが変更されない限り有効です。この値は、short 型境界では確実に調整されますが、long 型または double 型の境界では、フィールド型が long 型または double 型でも、調整されない場合があります値の調整については、この章の後の説明を参照してください。変数を正しく境界に調整する必要があるプロセッサでは、正しく調整されていない値を参照すると、システム エラーが発生します。次は、その例です。
long *l1,l2;
FLDLEN length;
char *Ffind;
. . .
if((l1=(long *)Ffind(fbfr, ZIP, 0, &length)) == NULL)
F_error("pgm_name");
else
l2 = *l1;
if((l1==(long *)Ffind(fbfr, ZIP, 0, &length)) == NULL)
F_error("pgm_name");
else
memcpy(&l2,l1,sizeof(long));
詳細については、『Oracle Tuxedo FML リファレンス』の「Ffind、Ffind32(3fml)」を参照してください。
この関数は、フィールド化バッファ内のフィールドの最後のオカレンスを検索し、そのフィールドに対するポインタと、最後のフィールド オカレンスのオカレンス番号と長さを返します。
char *
Ffindlast(FBFR *fbfr
, FLDIDfieldid
, FLDOCC *oc
, FLDLEN *len
)
上の例では、Ffindlast
の戻り値として、文字ポインタのデータ型 (C の char*
) が示されています。実際に返されるポインタの型は、ポインタが指す値の型と同じです。
Ffindlast
は、Ffind
と同様に動作します。ただし、フィールド オカレンスを指定する必要はなく、関数の戻り値として、最後のフィールド オカレンスのオカレンス番号と値が返されます。関数の呼び出し時にオカレンスに NULL を指定すると、オカレンス番号は返されません。この関数は、埋め込み型のバッファにある指定されたフィールドのオカレンスは調べません。
Ffindlast
が返す値は、バッファが変更されない限り有効です。
詳細については、『Oracle Tuxedo FML リファレンス』の「Ffindlast、Ffindlast32(3fml)」を参照してください。
Ffindocc
は、バッファ内の指定したフィールドのオカレンスを調べ、ユーザ指定のフィールド値と一致する最初のフィールド オカレンスのオカレンス番号を返します。
FLDOCC
Ffindocc(FBFR *fbfr,
FLDIDfieldid
, char *value
, FLDLENlen
;)
fbfr
は、フィールド化バッファを指すポインタです。fieldid
は、フィールド識別子です。value
は、新しい値に対するポインタです。上の例は char *
型を示していますが、実際に使用するときは、追加する値と同じ型を指定します (「Fadd」を参照)。FLD_CARRAY
型または FLD_MBSTRING
型の場合、len
は値の長さです。
たとえば、次のコードは、oc
を、指定された郵便番号のオカレンスに設定します。
#include "fldtbl.h"
FBFR *fbfr;
FLDOCC oc;
long zipvalue;
. . .
zipvalue = 123456;
if((oc=Ffindocc(fbfr,ZIP,&zipvalue, 0)) < 0)
F_error("pgm_name");
文字列フィールドでは、正規表現がサポートされています。たとえば、次のコードは、oc
を「J」で始まる NAME
のオカレンスに設定します。
#include "fldtbl.h"
FBFR *fbfr;
FLDOCC oc;
char *name;
. . .
name = "J.*"
if ((oc = Ffindocc(fbfr, NAME, name, 1)) < 0)
F_error("pgm_name");
注意 : | ただし、文字列上でのパターン照合を可能にするには、Ffindocc の 4 番目の引数を 0 以外にする必要があります。この引数が 0 の場合、単純な文字列比較が実行されます。フィールド値が見つからない場合は、-1 が返されます。 |
上位互換性のため、接頭辞としてアクセント記号 (^
)、また接尾辞としてドル記号 ($
) が正規表現に暗黙的に追加されます。したがって、前の例にある正規表現は、実際には「^(J.*)$
」として解釈されます。正規表現は、フィールド内の文字列値全体と一致しなければなりません。
詳細については、『Oracle Tuxedo FML リファレンス』の「Ffindocc、Ffindocc32(3fml)」を参照してください。
Fget
は、値が変更されたときに、フィールド化バッファのフィールドを検索するために使用されます。
int
Fget(FBFR *fbfr
, FLDIDfieldid
, FLDOCCoc
, char *loc
, FLDLEN *maxlen)
呼び出し側プログラムは、Fget
にプライベート バッファに対するポインタとプライベート バッファの長さを提供します。maxlen
を NULL として指定すると、宛先バッファはフィールド値を格納できるだけのサイズを持つと想定され、バッファの長さは返されません。
Fget
は、目的のフィールドがバッファにない場合 (FNOTPRES
) または宛先バッファが小さすぎる場合 (FNOSPACE
) にはエラーを返します。たとえば、次のコードは、郵便番号が文字配列または文字列として格納されている場合は、その郵便番号を検索します。
FLDLEN len;
char value[100];
. . .
len=sizeof(value);
if(Fget(fbfr, ZIP, 0, value, &len) < 0)
F_error("pgm_name");
郵便番号が long
型として格納されている場合は、次のコードで郵便番号を取得できます。
FLDLEN len;
long value;
. . .
len = sizeof(value);
if(Fget(fbfr, ZIP, 0, value, &len) < 0)
F_error("pgm_name");
詳細については、『Oracle Tuxedo FML リファレンス』の「Fget、Fget32(3fml)」を参照してください。
Fgetalloc
は、Fget
と同じく、バッファ フィールドを検索し、そのコピーを作成します。ただし、フィールドの領域は、malloc
(3) への呼び出しによって取得します。
char *
Fgetalloc(FBFR *fbfr
, FLDIDfieldid
, FLDOCCoc
, FLDLEN *extralen
)
上記の例では、Fgetalloc
の戻り値として、文字ポインタのデータ型 (C の char*
) が示されています。実際に返されるポインタの型は、ポインタが指す値の型と同じです。
Fgetalloc
が成功すると、正しく境界に調整されたバッファ フィールドのコピーに対する有効なポインタが返されます。失敗すると、NULL が返されます。malloc
(3) が失敗すると、Fgetalloc
からエラーが返され、Ferror
が FMALLOC
に設定されます。
Fgetalloc
の最後のパラメータには、予備の領域を指定します。たとえば、空き領域が不足した場合に、フィールド化バッファに値を再度指定する代わりに、取得済みの領域を拡張する場合に取得する領域です。成功すると、割り当てられたバッファの長さが extralen
に返されます。次の例を参照してください。
FLDLEN extralen;
FBFR *fieldbfr
char *Fgetalloc;
. . .
extralen = 0;
if (fieldbfr = (FBFR *)Fgetalloc(fbfr, ZIP, 0, &extralen) == NULL)
F_error("pgm_name");
Fgetalloc
で取得した領域を free
で解放する処理は、呼び出し側プログラムの役割です。
詳細については、『Oracle Tuxedo FML リファレンス』の「Fgetalloc、Fgetalloc32(3fml)」を参照してください。
Fgetlast
は、値の変更時にフィールド化バッファからフィールドの最後のオカレンスを検索するために使用します。
int
Fgetlast(FBFR *fbfr
, FLDIDfieldid
, FLDOCC *oc
, char *loc
, FLDLEN *maxlen
)
呼び出し側プログラムは、Fgetlast
にプライベート バッファに対するポインタとブライペート バッファの長さを提供します。Fgetlast
は、Fget
と同様に動作します。ただし、フィールド オカレンスを指定する必要はなく、関数の戻り値として、最後のフィールド オカレンスのオカレンス番号と値が返されます。ただし、occ
に NULL を指定して関数を呼び出すと、オカレンス番号は返されません。
詳細については、『Oracle Tuxedo FML リファレンス』の「Fgetlast、Fgetlast32(3fml)」を参照してください。
Fnext
は、指定されたフィールド オカレンスの次のバッファ フィールドを検索します。
int
Fnext(FBFR *fbfr
, FLDID *fieldid
, FLDOCC *oc
, char *value
, FLDLEN *len
)
バッファ内の最初のフィールドを取得するには、fieldid
に FIRSTFLDID
を代入します。フィールド識別子と最初のフィールド オカレンスのオカレンス番号が対応するパラメータ内に返されます。フィールドが NULL でない場合は、フィールド値が value
ポインタでアドレス指定されたメモリ位置にコピーされます。
len
パラメータを使用すると、フィールド値を格納できるだけの領域が value
に割り当てられているかどうかを判別できます。十分な領域が割り当てられていない場合は、Ferror
が FNOSPACE
に設定されます。値の長さが len
パラメータ内に返されます。ただし、フィールドの値が NULL でない場合、len
パラメータは、value
に現在割り当てられている領域の長さも含んでいると見なします。
取り出されるフィールドが埋め込み型の VIEW32 バッファのときは、value
パラメータは FVIEWFLD
構造体を指します。Fnext
関数は、構造体の vname
フィールドと data
フィールドを設定します。FVIEWFLD
構造体は、次のとおりです。
typedef struct {
TM32U vflags; /* フラグ - 現在未使用 */
char vname[FVIEWNAMESIZE+1]; /* VIEW の名前 */
char *data; /* VIEW 構造体に対するポインタ */
} FVIEWFLD;
フィールド値が NULL の場合は、value
パラメータと length
パラメータは変更されません。
フィールドがそれ以上見つからない場合は、Fnext
は 0
を返し (バッファの終わり)、fieldid
、occurrence
、value
は変更されません。
value
パラメータが NULL でない場合は、length
パラメータも NULL でないと想定されます。
以下の例は、バッファ内のすべてのフィールド オカレンスを読み取ります。
FLDID fieldid;
FLDOCC occurrence;
char *value[100];
FLDLEN len;
. . .
for(fieldid=FIRSTFLDID,len=sizeof(value);
Fnext(fbfr,&fieldid,&occurrence,value,&len) > 0;
len=sizeof(value)) {
/* 各フィールド オカレンス用のコード */
}
詳細については、『Oracle Tuxedo FML リファレンス』の「Fnext、Fnext32(3fml)」を参照してください。
Fnum
は、指定されたバッファに含まれているフィールド数を返します。エラーの場合は -1
を返します。
FLDOCC
Fnum(FBFR *fbfr
)
fbfr
は、フィールド化バッファに対するポインタです。たとえば、次のコードは、指定されたバッファ内のフィールド数を出力します。
if((cnt=Fnum(fbfr)) < 0)
F_error("pgm_name");
else
fprintf(stdout,"%d fields in buffer\n",cnt);
FLD_FML32
および FLD_VIEW32
フィールドは、格納するフィールド数に関係なく、単一フィールドとしてカウントされます。
詳細については、『Oracle Tuxedo FML リファレンス』の「Fnum、Fnum32(3fml)」を参照してください。
Foccur
は、バッファ内の指定されたフィールドのオカレンス数を返します。
FLDOCC
Foccur(FBFR *fbfr
, FLDIDfieldid
)
埋め込み型の FML32 バッファ内でのフィールドのオカレンスはカウントされません。
フィールド オカレンスがバッファ内にない場合は 0 が返され、エラーの場合は -1
が返されます。たとえば、次のコードは、指定されたバッファ内のフィールド ZIP
のオカレンス数を出力します。
FLDOCC cnt;
. . .
if((cnt=Foccur(fbfr,ZIP)) < 0)
F_error("pgm_name");
else
fprintf(stdout,"Field ZIP occurs %d times in buffer\n",cnt);
詳細については、『Oracle Tuxedo FML リファレンス』の「Foccur、Foccur32(3fml)」を参照してください。
Fpres
、指定されたフィールド オカレンスが存在する場合は true (1) を返し、存在しない場合は false (0) を返します。
int
Fpres(FBFR *fbfr
, FLDIDfieldid
, FLDOCCoc
)
たとえば、次のコードは、fbfr
が指すフィールド化バッファ内にフィールド ZIP
が存在する場合、true を返します。
Fpres(fbfr,ZIP,0)
Fpres
は、埋め込み型のバッファにある指定されたフィールドのオカレンスは確認しません。
詳細については、『Oracle Tuxedo FML リファレンス』の「Fpres、Fpres32(3fml)」を参照してください。
Fvals
は、string
値の場合は Ffind
と同じように動作しますが、値に対するポインタを必ず返します。Fvall
は、long
型および short
型の値の場合は、Ffind
と同じように動作しますが、実際のフィールド値を、値に対するポインタの代わりに long
型で返します。
char
*Fvals(FBFR *
fbfr
,FLDID
fieldid
,FLDOCC
oc)
char*Fvall(FBFR *
fbfr
,FLDID
fieldid
,FLDOCC
oc)
Fvals
の場合、指定されたフィールド オカレンスが見つからないと、NULL 文字列 \0
を返します。この関数は、戻り値をチェックせずにフィールドの値を別の関数に渡すのに役立ちます。ただし、この関数は、string
型のフィールドの場合のみ有効であり、ほかのフィールド型の場合は、自動的に NULL 文字列を返します (つまり、変換は行われません)。
Fvall
の場合、指定されたフィールド オカレンスが見つからないと、0 を返します。この関数は、戻り値をチェックせずにフィールドの値を別の関数に渡すのに役立ちます。ただし、この関数は、long
型と short
型のフィールドの場合のみ有効であり、ほかのフィールド型の場合は、自動的に 0 を返します (つまり、変換は行われません)。
詳細については、『Oracle Tuxedo FML リファレンス』の「Fvals、Fvals32(3fml)」および「Fvall、Fvall32(3fml)」を参照してください。
この節では、バッファ内の個々のフィールドではなく、フィールド化バッファ全体にアクセスし、内容を更新する関数を説明します。これらの関数では、最大 3 つのパラメータしか使用されません。
Fconcat
は、ソース バッファのフィールドを、既存の宛先バッファのフィールドに追加します。
int
Fconcat(FBFR *dest
, FBFR *src
)
宛先バッファ内のオカレンスは保持されます。つまり、このオカレンスは変更されません。新しいオカレンス、つまり、ソース バッファから取得されたオカレンスには、宛先フィールドの既存のオカレンス番号より大きい番号が設定され、宛先バッファに追加されます。フィールドは、フィールド識別子の順序で保持されます。
FBFR *src, *dest;
. . .
if(Fconcat(dest,src) < 0)
F_error("pgm_name");
dest
に 2 つのフィールド (A、B) と 2 つのオカレンスを持つフィールド C があり、src
に 3 つのフィールド (A、C、D) があるとします。この結果、dest
には、2 つのオカレンスを持つフィールド A (宛先のフィールド A とソースのフィールド A)、フィールド B、3 つのオカレンスを持つフィールド C (dest
の 2 つのオカレンスと src
のオカレンス)、およびフィールド D が設定されます。
新しいフィールドを格納できるだけの領域がない場合 (FNOSPACE
が返された場合)、この処理は失敗し、宛先バッファは変更されません。
詳細については、『Oracle Tuxedo FML リファレンス』の「Fconcat、Fconcat32(3fml)」を参照してください。
Fjoin
は、フィールド識別子とオカレンスの組み合わせに基づき、2 つのフィールド化バッファを結合します。
int
Fjoin(FBFR *dest
, FBFR *src
)
フィールド識別子とオカレンスの組み合わせが一致するフィールド間では、宛先バッファの値がソース バッファの値で更新されます。ソース バッファ内に、対応するフィールド識別子とオカレンスの組み合わせがない場合、宛先バッファのフィールドは削除されます。宛先バッファ内に、対応するフィールド識別子とオカレンスの組み合わせがない場合、ソース バッファ内のフィールドは、宛先バッファに追加されません。次の例を参照してください。
if(Fjoin(dest,src) < 0)
F_error("pgm_name");
Fconcat の例で使用した入力バッファを使用すると、ソース フィールド値 A とソース フィールド値 C を持つ宛先バッファが生成されます。新しい値が古い値より大きい場合は、この関数は領域の不足のために失敗することがあります (FNOSPACE
)。その場合、宛先バッファは変更されていると予測されます。ただし、この事態が発生した場合、Frealloc
関数と Fjoin
関数を繰り返し使用すると、宛先バッファを再割り当てできます (宛先バッファが部分的に更新されてしまった場合でも、これらの関数を繰り返し使用すると、正しい結果が得られます)。
バッファの結合によってポインタ フィールド (FLD_PTR
) が削除されると、ポインタが参照するメモリ領域は、変更も解放もされません。
詳細については、『Oracle Tuxedo FML リファレンス』の「Fjoin、Fjoin32(3fml)」を参照してください。
Fojoin
は、Fjoin
と似ていますが、ソース バッファ内に対応するフィールド識別子とオカレンスの組み合わせがない宛先バッファのフィールドの削除は行いません。
int
Fojoin(FBFR *dest
, FBFR *src
)
宛先バッファ内に対応するフィールド識別子とオカレンスの組み合わせがないソース バッファ内のフィールドは、宛先バッファに追加されません。次の例を参照してください。
if(Fojoin(dest,src) < 0)
F_error("pgm_name");
Fjoin の例で使用した入力バッファを使用すると、この呼び出しの結果の dest
には、ソース フィールド値 A、宛先フィールド値 B、ソース フィールド値 C が含まれます。Fjoin
の場合のように、Fojoin 関数は、領域の不足のために失敗する場合があり (FNOSPACE
)、その場合は、領域をさらに割り当てた後で関数を再発行すると、処理を完了できます。
バッファの結合によってポインタ フィールド (FLD_PTR
) が削除されると、ポインタが参照するメモリ領域は、変更も解放もされません。
詳細については、『Oracle Tuxedo FML リファレンス』の「Fojoin、Fojoin32(3fml)」を参照してください。
Fproj
は、目的のフィールドのみが保存されるように、バッファの適切な箇所を更新します (つまり、結果として、指定されたフィールドのプロジェクションが行われます)。バッファの更新によってポインタ フィールド (FLD_PTR
) が削除されると、ポインタが参照するメモリ領域は、変更も解放もされません。
int
Fproj(FBFR *fbfr
, FLDID *fieldid
)
これらのフィールドは、この関数に渡されるフィールド識別子の配列で指定されます。更新は、フィールド化バッファ内で直接実行されます。次の例を参照してください。
#include "fldtbl.h"
FBFR *fbfr;
FLDID fieldid[20];
. . .
fieldid[0] = A; /* フィールド A のフィールド識別子 */
fieldid[1] = D; /* フィールド D のフィールド識別子 */
fieldid[2] = BADFLDID; /* 標識値 */
if(Fproj(fbfr, fieldid) < 0)
F_error("pgm_name");
バッファに A、B、C の各フィールドがある場合は、上記の例の結果として、フィールド A とフィールド D のオカレンスのみを含むバッファが生成されます。ただし、フィールド識別子の配列内のエントリは、特定の順序で並べる必要はありませんが、フィールド識別子 0 (BADFLDID
) がフィールド識別子の配列の最後の値でなければなりません。
詳細については、『Oracle Tuxedo FML リファレンス』の「Fproj、Fproj32(3fml)」を参照してください。
Fprojcpy
は Fproj
と似ていますが、目的のフィールドは宛先バッファに配置されます。バッファの更新によってポインタ フィールド (FLD_PTR
) が削除されると、ポインタが参照するメモリ領域は、変更も解放もされません。
int
Fprojcpy(FBFR *dest
, FBFR *src
, FLDID *fieldid
)
まず、宛先バッファ内のすべてのフィールドが削除され、ソース バッファでのプロジェクションの結果が宛先バッファにコピーされます。上記の例を使って、次のコードではプロジェクションの結果が宛先バッファに格納されます。
if(Fprojcpy(dest, src, fieldid) < 0)
F_error("pgm_name");
フィールド識別子の配列内のエントリは、再配置される場合があります。つまり、フィールド識別子の配列は、それらのエントリが番号順になっていないとソートされます。
詳細については、『Oracle Tuxedo FML リファレンス』の「Fprojcpy、Fprojcpy32(3fml)」を参照してください。
Fupdate
は、ソース バッファ内のフィールド値で宛先バッファを更新します。
int
Fupdate(FBFR *dest
, FBFR *src
)
フィールド識別子とオカレンスの組み合わせが一致するフィールドの場合、フィールド値は、ソース バッファ内の値によって宛先バッファ内で更新されます (Fjoin
と同じ)。ソース バッファに対応するフィールドがない宛先バッファのフィールドは、変更されません (Fojoin
と同じ)。宛先バッファに対応するフィールドのないソース バッファのフィールドは、宛先バッファに追加されます (Fconcat
と同じ)。次の例を参照してください。
if(Fupdate(dest,src) < 0)
F_error("pgm_name");
src
バッファにフィールド A、C、D という 3 つのフィールドがあり、dest
バッファにフィールド A、B という 2 つのフィールドと、フィールド C の 2 つのオカレンスがある場合、結果はソース フィールド A、宛先フィールド B、ソース フィールド C、2 つ目の宛先フィールド C、およびソース フィールド D になります。
ポインタの場合、Fupdate32
はポインタ値を格納します。FLD_PTR
フィールドが指すバッファは、tpalloc(3c) を呼び出して割り当てます。埋め込み型の FML32 バッファの場合、Fupdate32
は、インデックスを除くすべての FLD_FML32
フィールド値を格納します。
埋め込み型の VIEW32 バッファの場合、Fupdate32
は FVIEWFLD
型の構造体に対するポインタを格納します。FVIEWFLD 型の構造体には、vflags
(現在未使用で 0
に設定されているフラグ フィールド)、vname
(VIEW 名を含む文字配列)、および data
(C 構造体として格納される VIEW データに対するポインタ) が含まれています。アプリケーションは、Fupdate32
に vname
および data
を提供します。FVIEWFLD
構造体は、次のとおりです。
typedef struct {
TM32U vflags; /* フラグ - 現在未使用 */
char vname[FVIEWNAMESIZE+1]; /* VIEW の名前 */
char *data; /* VIEW 構造体に対するポインタ */
} FVIEWFLD;
詳細については、『Oracle Tuxedo FML リファレンス』の「Fupdate、Fupdate32(3fml)」を参照してください。
Fvftos は、指定された VIEW 記述を使用して、フィールド化バッファから C 構造体へデータを転送します。
int
Fvftos(FBFR *fbfr
, char *cstruct
, char *view
)
指定された VIEW が見つからない場合、Fvftos
から -1
が返され、Ferror
が FBADVIEW
に設定されます。
フィールド化バッファから C 構造体へのデータ転送時には、以下の規則が適用されます。
string
型または carray
型のデータを含む場合は、最大でマッピング先の構造体メンバーのサイズまで文字がコピーされます (それ以上のマッピング元の値は切り捨てられます)。マッピング元の値がマッピング先の構造体メンバーよりも短い場合は、メンバー値の残りに NULL 文字 (0) が埋め込まれます。string 型の値は、値を切り捨てても、必ず NULL 文字で終了します。
たとえば、次のコードは、string1
を cust.action[0]
に格納し、abc
を cust.bug[0]
に格納します。cust
構造体内のほかのすべてのメンバーには NULL 値を格納します。
#include <stdio.h>
#include "fml.h"
#include "custdb.flds.h"
#include "custdb.h"
struct custdb cust;
FBFR *fbfr;
. . .
fbfr = Falloc(800,1000);
Fvinit((char *)&cust,"custdb"); /* cust 構造体を初期化 */
str = "string1";
Fadd(fbfr,ACTION,str,(FLDLEN)8);
str = "abc";
Fadd(fbfr,BUG_CURS,str,(FLDLEN)4);
Fvftos(fbfr,(char *)&cust,"custdb");
. . .
VIEW 記述 custdb
の定義については、「VIEWS の使用例」を参照してください。
詳細については、『Oracle Tuxedo FML リファレンス』の「Fvftos、Fvftos32(3fml)」を参照してください。
Fvstof は、指定された VIEW 記述を使用して、C 構造体からフィールド化バッファへデータを転送します。
int
Fvstof(FBFR *fbfr
, char *cstruct
, intmode
, char *view
)
転送プロセスは、mode
パラメータに対応する FML 関数、Fupdate
、Fjoin
、Fojoin
、または Fconcat
の項目で説明されている規則に従います。
指定された VIEW が見つからない場合、Fvstof
から -1
が返され、Ferror
が FBADVIEW
に設定されます。
注意 : | NULL 値は、構造体メンバーからフィールド化バッファに転送されません。つまり、構造体からフィールドへの転送時には、構造体メンバーに対して定義されたデフォルト設定またはユーザ指定の NULL 値が構造体メンバーに含まれていると、そのメンバーは無視されます。 |
詳細については、『Oracle Tuxedo FML リファレンス』の「Fvftos、Fvftos32(3fml)」を参照してください。
Fvnull
は、C 構造体内のオカレンスにそのフィールド用の NULL 値が含まれているかどうかを判別します。
int
Fvnull(char *cstruct
, char *cname
, FLDOCCoc
, char *view
)
詳細については、『Oracle Tuxedo FML リファレンス』の「Fvnull、Fvnull32(3fml)」を参照してください。
Fvsinit は、適切な NULL 値で C 構造体内のすべての要素を初期化します。
int
Fvsinit(char *cstruct
, char *view
)
詳細については、『Oracle Tuxedo FML リファレンス』の「Fvsinit、Fvsinit32(3fml)」を参照してください。
int
Fvopt(char *cname,
intoption,
char *view
)
F_FTOS
F_STOF
F_BOTH
F_OFF
VIEW 記述への変更は永久に保持されるわけではありません。変更内容の有効期間は、別の VIEW 記述に対してアクセスが行われるときまでです。
詳細については、『Oracle Tuxedo FML リファレンス』の「Fvopt、Fvopt32(3fml)」を参照してください。
Fvselinit は、C 構造体の個々のメンバーを、適切な NULL 値に初期化します。この関数は、viewfile 内で C
フラグが使用されていると、要素の ACM を 0 に設定します。viewfile 内で L
フラグが使用されていると、要素の ALM を対応する NULL 値の長さに設定します。
int
Fvselinit(char *cstruct
, char *cname
, char *view
)
詳細については、『Oracle Tuxedo FML リファレンス』の「Fvselinit、Fvselinit32(3fml)」を参照してください。
FML には、フィールド化バッファの読み取りまたは書き込み時にデータを変換する一連のルーチンが用意されています。
一般に、これらのルーチンは、対応する非変換関数と同じように動作します。ただし、バッファへの書き込み時にはユーザ型からネイティブ型へ変換を行い、バッファからの読み取り時にはネイティブ型からユーザ型への変換を行います。
フィールドのネイティブ型は、そのフィールド テーブル エントリ内でそのフィールドに対して指定され、そのフィールド識別子内でエンコードされたデータ型です。ただし、上記の規則に対する唯一の例外として CFfindocc
があります。この関数は、読み取り操作を行いますが、ユーザ型からネイティブ型に変換を行ってから Ffindocc
を呼び出します。これらの関数の名前は、接頭辞「C」が付いた、対応する非変換 FML 関数と同じです。
変換を行う関数では、ポインタ (FLD_PTR
)、埋め込み型の FML32 バッファ (FLD_FML32
)、および埋め込み型の VIEW32 バッファ (FLD_VIEW32
) はサポートされていません。FML32 変換関数の実行中にこれらのフィールド型が使用されていた場合、Ferror
が FEBADOP
に設定されます。
CFadd
は、バッファにユーザ指定の項目を追加して、バッファ内に新しいフィールド オカレンスを生成します。
int
CFadd(FBFR *fbfr
, FLDIDfieldid
, char *value
, FLDLENlen
, inttype
)
フィールドを追加する前に、データ項目は、ユーザ指定の型からフィールドをフィールド化バッファに格納される型としてフィールド テーブル内で指定された型に変換されます。ソースが FLD_CARRAY
型 (文字配列) である場合は、len 引数を配列の長さに設定する必要があります。次の例を参照してください。
if(CFadd(fbfr,ZIP,"12345",(FLDLEN)0,FLD_STRING) < 0)
F_error("pgm_name");
上記の例では、ZIP
(郵便番号) フィールドが long 型整数としてフィールド化バッファ内に格納されている場合は、「12345」が long 型整数の表現に変換されてから、その表現が fbfr
の指すフィールド化バッファに追加されます (ただし、フィールド値の長さは、関数が決定できるので 0 に指定されています。この長さは、FLD_CARRAY
型の場合のみ必要です)。以下の例は、同じ値をフィールド化バッファに格納しますが、その値を string 型としてではなく long 型として表現して格納します。
long zipval;
. . .
zipval = 12345;
if(CFadd(fbfr,ZIP,&zipval,(FLDLEN)0,FLD_LONG) < 0)
F_error("pgm_name");
ただし、C では構造体 &12345L を使用できないので、まず、値を変数に格納する必要があります。CFadd
は、成功すると 1
を返し、エラーになると -1
を返します (Ferror
は、適宜に設定されます)。
詳細については、『Oracle Tuxedo FML リファレンス』の「CFadd、CFadd32(3fml)」を参照してください。
CFchg
は、CFadd
と同じように動作しますが、指定された値の変換後、フィールド値を変更します。
int
CFchg(FBFR *fbfr
, FLDIDfieldid
, FLDOCCoc
, char *value
, FLDLENlen
, inttype
)
たとえば、次のコードは、フィールド ZIP
の最初のオカレンス (オカレンス 0) を指定された値に変更し、必要に応じて変換を行います。
FLDOCC occurrence;
long zipval;
. . .
zipval = 12345;
occurrence = 0;
if(CFchg(fbfr,ZIP,occurrence,&zipval,(FLDLEN)0,FLD_LONG) < 0)
F_error("pgm_name");
指定されたオカレンスが見つからないと、指定されたオカレンスとして値を追加できるまで、NULL オカレンスがバッファに追加されます。
詳細については、『Oracle Tuxedo FML リファレンス』の「CFchg、CFchg32(3fml)」を参照してください。
CFget
は、Fget
に似た変換関数です。ただし、CFget は変換した値をユーザ指定のバッファにコピーします。
int
CFget(FBFR *fbfr
, FLDIDfieldid
, FLDOCCoc
, char *buf
, FLDLEN *len
, inttype
)
前の例を使って、次のコードは、バッファに格納されたばかりの値 (どのような形式の値でも可) にアクセスして、その値を元の long 型整数に戻します。
FLDLEN len;
. . .
len=sizeof(zipval);
if(CFget(fbfr,ZIP,occurrence,&zipval,&len,FLD_LONG) < 0)
F_error("pgm_name");
長さのポインタが NULL の場合は、検索および変換した値の長さは返されません。
詳細については、『Oracle Tuxedo FML リファレンス』の「CFget、CFget32(3fml)」を参照してください。
CFgetalloc
は、Fgetalloc
と同じように動作します。ただし、戻り値 (変換後の値) に対して malloc
を使用して割り当てた領域は、free
を使用して解放する必要があります。
char *
CFgetalloc(FBFR *fbfr
, FLDIDfieldid
, FLDOCCoc
, inttype
, FLDLEN *extralen
)
上記の例では、CFgetalloc
の戻り値として文字ポインタのデータ型 (C の char*
) が示されています。実際に返されるポインタの型は、ポインタが指す値の型と同じです。
以下のコードを使用すると、既に格納されている値を自動的に割り当てられた領域に取り込むことができます。
char *value;
FLDLEN extra;
. . .
extra = 25;
if((value=CFgetalloc(fbfr,ZIP,0,FLD_LONG,&extra)) == NULL)
F_error("pgm_name");
関数呼び出しに値 extra
を指定した場合、関数は、取り出した値に十分な領域に加えて、さらに 25 バイトを割り当てます。割り当てられた領域の総量が、この変数に返されます。
詳細については、『Oracle Tuxedo FML リファレンス』の「CFgetalloc、CFgetalloc32(3fml)」を参照してください。
CFfind
は、検索対象のフィールドの値を変換し、その値に対するポインタを返します。
char *
CFfind(FBFR *fbfr
, FLDIDfieldid
, FLDOCCoc
, FLDLENlen
, inttype
)
上記の例では、CFfind
の戻り値として、文字ポインタのデータ型 (C の char*
) が示されています。実際に返されるポインタの型は、ポインタが指す値の型と同じです。
この関数が返すポインタは、Ffind
の場合と同じく、読み取り専用と見なされます。たとえば、次のコードは、ZIP
フィールドの最初のオカレンスの値を含む long
型に対するポインタを返します。
char *CFfind;
FLDLEN len;
long *value;
. . .
if((value=(long *)CFfind(fbfr,ZIP,occurrence,&len,FLD_LONG))== NULL)
F_error("pgm_name");
長さに対するポインタが NULL の場合、検出された値の長さは返されません。この関数の戻り値は、Ffind
の場合と異なり、対応するユーザ指定の型の境界に正しく調整されます。
注意 : | CFfind が返すポインタは、次のバッファ操作 (破壊的でない操作も含む) が実行されるまで有効です。これは、変換後の値が 1 つのプライベート バッファに保存されているためです。一方、Ffind の戻り値の場合は、次にバッファが変更されるまで有効です。 |
詳細については、『Oracle Tuxedo FML リファレンス』の「CFfind、CFfind32(3fml)」を参照してください。
CFfindocc
は、バッファの指定されたフィールドのオカレンスを調べ、フィールド識別子の型に変換されたユーザ指定のフィールド値と一致する最初のフィールド オカレンスのオカレンス番号を返します。
FLDOCC
CFfindocc(FBFR *fbfr
, FLDIDfieldid
, char *value
, FLDLENlen
, inttype
)
たとえば、次のコードは、文字列を fieldid
ZIP
の型 (おそらく long
型) に変換し、oc
を指定された郵便番号のオカレンスに設定します。
#include "fldtbl.h"
FBFR *fbfr;
FLDOCC oc;
char zipvalue[20];
. . .
strcpy(zipvalue,"123456");
if((oc=CFfindocc(fbfr,ZIP,zipvalue,0,FLD_STRING)) < 0)
F_error("pgm_name");
注意 : | CFfindocc は、ユーザ指定の値をネイティブ フィールド型に変換してから、フィールド値を検証するため、正規表現は、ユーザ指定の型とネイティブ フィールド型が両方とも FLD_STRING である場合のみ機能します。したがって、CFfindocc には、正規表現に関するユーティリティがありません。 |
詳細については、『Oracle Tuxedo FML リファレンス』の「CFfindocc、CFfindocc32(3fml)」を参照してください。
ユーザ指定の型 FLD_STRING
への変換および FLD_STRING からの変換を処理するために、以下の関数が提供されています。
これらの関数は、対応する非文字列用の関数を呼び出し、FLD_STRING
型と len
0 を提供します。ただし、
Ffinds
が返すポインタの有効期間は、CFfind
の場合と同じです。
これらの関数の説明については、『Oracle Tuxedo FML リファレンス』を参照してください。
CFadd
、CFchg
、CFget
、CFgetalloc
、CFfind
の各関数は、Ftypcvt
を使用して、適切なデータ変換を行います。Ftypcvt32
関数は、フィールド型 FLD_PTR
、FLD_FML32
、および FLD_VIEW32
では失敗します。Ftypcvt
を使用する場合の形式は、次のとおりです。この形式は、パラメータの順序に関する規則に準拠しません。
char *
Ftypcvt(FLDLEN *tolen
, inttotype
, char *fromval
, intfromtype
, FLDLENfromlen
)
Ftypcvt
は、fromlen
で指定された長さの fromtype
型の *fromval
の値 (fromtype
が FLD_CARRAY
の場合。それ以外の場合、fromlen
は fromtype
から算出される。) を、totype
型の値に変換します。Ftypcvt
が成功すると、変換後の値に対するポインタが返され、*tolen
に変換後の長さが設定されます。失敗すると、Ftypcvt
から NULL が返されます。CFchg
関数を使用した次の例を参照してください。
CFchg(fbfr,fieldid,oc,value,len,type)
FBFR *fbfr; /* フィールド化バッファ */
FLDID fieldid; /* 変更されるべきフィールド */
FLDOCC oc; /* 変更されるべきフィールドのオカレンス */
char *value; /* 新しい値に対するポインタ */
FLDLEN len; /* 新しい値の長さ */
int type; /* 新しい値のタイプ */
{
char *convloc; /* 変換された値に対するポインタ */
FLDLEN convlen; /* 変換された値の長さ */
extern char *Ftypcvt;
/* 値をフィールド化バッファ タイプに変換 */
if((convloc = Ftypcvt(&convlen,FLDTYPE(fieldid),value,type,len)) == NULL)
return(-1);
if(Fchg(fbfr,fieldid,oc,convloc,convlen) < 0)
return(-1);
return(1);
}
Ftypcvt
を直接呼び出して、フィールド化バッファを変更せずにフィールド値を変換することができます。
詳細については、『Oracle Tuxedo FML リファレンス』の「Ftypcvt、Ftypcvt32(3fml)」を参照してください。
以下は、変換時の規則の一覧です。oldval
は、変換対象のデータ項目に対するポインタを表し、newval
は変換後の値に対するポインタを表します。
*newval
と *oldval
は同一です。long
型、short
型、float
型、または double
型) である場合は、C の代入演算子で正しい型変換を行います。たとえば、次のコードによって short
型は float
型に変換されます。 *((float *)newval) = *((short *) oldval)
sprintf
を使用します。たとえば、次のコードによって short
型は string
型に変換されます。sprintf(newval,"%d",*((short *)oldval))
atof
、atol
) を使用し、その結果を型変換のために代入します。たとえば、次のように指定します。*((float *)newval) = atof(oldval)
char
型から任意の数値型へ変換するか、または数値型から char
型へ変換する場合、char
型は、「短い short
型」と見なされます。たとえば、次のコードによって char
型は float
型に変換されます。*((float *)newval) = *((char *)oldval)
short
型から char
型へ変換するには、次の例に示す方法を使用します。
*((char *)newval) = *((short *)oldval)
char
型は、NULL 文字を追加することによって string
型に変換されます。この場合の char
型は、「短い short
型」ではありません。char 型が short
型である場合は、char 型を short
型に変換してから sprintf
で short 型を string
型に変換します。同様に、string
の最初の文字を代入すると、string
型は、char
型に変換されます。carray
型は、任意のシーケンスのバイトを格納するために使用されます。このため、carray 型は、任意のユーザ データ型をエンコードできます。ただし、carray
型の場合は、以下の規則に従います。carray
型は、carray
型に NULL バイトを付加することによって string
型に変換されます。このため、string
から後続の NULL のオーバーヘッドを差し引いたものを格納したい場合は、carray
型を使用できます (ただし、フィールドは、フィールド化バッファ内で short 型の範囲内に調整されるので、必ず領域を節約できるとは限りません)。string
は、その終了 NULL バイトを削除することによって carray
型に変換されます。carray
型を任意の数値型に変換する場合は、まず、string
型に変換し、その string
型を数値型に変換します。同様に、数値型を carray
型に変換する場合は、まず、数値型を string
型に変換してから、string
型を carray
型に変換します。char
に代入すると、carray
型は char
型に変換されます。同様に、char
型を carray
型に変換する場合は、文字を配列の最初のバイトとして代入し、配列の長さを 1 に設定します。
ただし、長さ 1 の carray
型と char
型は、以下の点で異なります。
char
型には、関連する fieldid
のオーバーヘッド分が含まれますが、carray
型には、関連する fieldid
のほか、長さコードが含まれます。carray
型を数値型に変換する場合は、string
型にしてから atoi
を呼び出します。char
を型変換すると、数値になります。たとえば、ASCII 値「1」 (10 進数では 49) の char
型は、値 49 の short
型に変換されます。長さ 1 の carray
型 (単一バイトの ASCII 値「1」を持つ) は、値 1 の short
型に変換されます。同様に、char
型の「a」 (10 進数では 97) は、値 97 の short
型に変換されます。carray
型の「a」は、atoi
(「a
」) が 0 を生成するので、値 0 の short
型に変換されます。dec_t
型を別の型に変換したり、またはその逆処理を行う場合、decimal
(3c) で説明されている変換関数 (_gp_deccvasc
、_gp_deccvdbl
、_gp_deccvflt
、_gp_deccvint
、_gp_deccvlong
、_gp_dectoasc
、_gp_dectodbl
、_gp_dectoflt
、_gp_dectoint
、および _gp_dectolong
) を使用します。
ユーザ指定の型 FLD_MBSTRING
のデータのコード セットのエンコーディング変換を処理するために、以下の関数が提供されています。
これらの関数では、FLD_MBSTRING
フィールドのエンコーディング名とマルチバイト データ情報の準備、FLD_MBSTRING
フィールドからのエンコーディング名とマルチバイト データ情報の抽出、および FLD_MBSTRING
フィールドにあるマルチバイト文字から対象の名前付きのエンコーディングへの変換を行います。次の図は、エンコーディング変換がどのように行われるかを例示しています。
上図の例に示すように、FLD_MBSTRING
フィールドは、ユーザ データのコード セット文字エンコーディング (または単にエンコーディング) を識別する情報を保持できます。この例では、クライアントの要求の FLD_MBSTRING
フィールドは、Shift-JIS (SJIS) エンコーディングで表される日本語ユーザ データを保持し、サーバの応答の FLD_MBSTRING
フィールドは、Extended UNIX Code (EUC) エンコーディングで表される日本語ユーザ データを保持しています。マルチバイト文字エンコーディング機能では、環境変数 TPMBENC
と TPMBACONV
を読み込んで、ソースのエンコーディング、対象のエンコーディング、および自動エンコーディング変換の状態 (有効または無効) を判別します。
次の図に示すように、FML32 型付きバッファは、それ自体でユーザ データの文字エンコーディングを識別する情報を保持できます。
FML32 型付きバッファで保持する FLD_MBSTRING
フィールド数が多い場合、グローバル エンコーディングを使用すると、FLD_MBSTRING
フィールドごとに文字エンコーディング名を追加するよりも、FML32 バッファによるマルチバイト ユーザ データの転送効率が向上します。Fmbpack32()
関数を使用すると、アプリケーション開発者は、Fmbpack32()
で作成された FLD_MBSTRING
フィールドごとに、グローバル エンコーディングを行うか個別のエンコーディングを行うかを選択できます。グローバル エンコーディングで使用できる名前は、各 FML32 バッファにつき 1 つだけです。
エンコーディングの変換機能により、基底の Tuxedo システム ソフトウェアでは、着信 FLD_MBSTRING
フィールドのエンコーディング表現を、受信プロセスが実行されているマシンでサポートされているエンコーディング表現に変換できます。この変換は文字コード セット間の変換でも言語の翻訳でもなく、同じ言語の異なる文字エンコーディング間の変換です。
この関数は、FML32 型付きバッファに入力された FLD_MBSTRING
フィールドのエンコーディング名およびマルチバイト データ情報を準備します。Fmbpack32()
は、FLD_MBSTRING
フィールドが FML32 API で FML32 バッファに追加される前に使用します。
この関数の詳細については、『Oracle Tuxedo FML リファレンス』の「Fmbpack32(3fml)」を参照してください。
この関数は、FML32 型付きバッファ内の FLD_MBSTRING
フィールドからエンコーディング名およびマルチバイト データ情報を抽出します。Fmbunpack32()
は、FLD_MBSTRING
フィールドが FML32 API (Ffind32()
、Fget32()
、など) で FML32 バッファから抽出された後に使用します。
この関数の詳細については、『Oracle Tuxedo FML リファレンス』の「Fmbunpack32(3fml)」を参照してください。
この関数は、FML32 型付きバッファにある FLD_MBSTRING
フィールドのマルチバイト文字を、対象の名前付きのエンコーディングに変換します。具体的には、tpconvfmb32()
は、FLD_MBSTRING
フィールドで指定されたソースのエンコーディング名と target_encoding
で定義された対象のエンコーディング名を比較し、エンコーディング名が異なる場合に tpconvfmb32()
は、FLD_MBSTRING
フィールドのデータを対象のエンコーディングに変換します。
この関数の詳細については、『Oracle Tuxedo FML リファレンス』の「tpconvfmb32(3fml)」を参照してください。
この関数は、VIEW32 型付きバッファにある MBSTRING
フィールドのマルチバイト文字を、対象の名前付きのエンコーディングに変換します。具体的には、tpconvvmb32()
は、MBSTRING
フィールドで指定されたソースのエンコーディング名と target_encoding
で定義された対象のエンコーディング名を比較し、エンコーディング名が異なる場合に tpconvvmb32()
は、MBSTRING
フィールドのデータを対象のエンコーディングに変換します。
この関数の詳細については、『Oracle Tuxedo FML リファレンス』の「tpconvvmb32(3fml)」を参照してください。
フィールド化バッファを Finit
または Falloc
で初期化すると、自動的にインデックスが設定されます。このインデックスにより、フィールド化バッファへのアクセスが促進されますが、プログラマ側からはインデックス処理が見えません。フィールド化バッファにフィールドを追加したり、削除すると、インデックスが自動的に更新されます。
ただし、記憶装置に長期に渡ってフィールド化バッファを格納したり、協調動作するプロセス間でフィールド化バッファを転送する場合は、フィールド化バッファの受信時に、インデックスを削除したり、再生成して領域を節約できます。ここで説明する関数は、このようなインデックス操作を実行します。
Fidxused は、バッファのインデックスが占有する領域を返します。
long
Fidxused(FBFR *fbfr
)
この関数を使用すると、バッファのインデックスのサイズを判別し、インデックスを削除した方が時間や領域を節約できるかどうかを判別できます。
詳細については、『Oracle Tuxedo FML リファレンス』の「Fidxused、Fidxused32(3fml)」を参照してください。
Findex
を使用すると、インデックスが設定されていないフィールド化バッファにインデックスを設定できます。
int
Findex(FBFR *fbfr
.FLDOCCintvl
)
Findex
の 2 つ目の引数は、バッファのインデックス付けの間隔を指定します。0 を指定すると、FSTDXINT
値 (fml.h
で定義) が使用されます。間隔 1 を指定すると、すべてのフィールドにインデックスが設定されます。
インデックス付けの間隔を増やしてバッファのインデックスを再設定すると、ユーザ データ用のバッファの空き領域を増やすことができます。ただし、処理時間の高速化と空き領域の確保を一度に両方実現することはできません。一般的に、インデックスの数を減らす、つまりインデックスの間隔を大きくすると、フィールドの検索に時間がかかります。ほとんどの操作では、空き領域が少なくなると、まず、すべてのインデックスが削除されます。それができない場合は、エラー メッセージが返されます。
詳細については、『Oracle Tuxedo FML リファレンス』の「Findex、Findex32(3fml)」を参照してください。
インデックスの削除後に、フィールド バッファを変更していない場合は、この関数を Findex
の代わりに使用できます。
int
Frstrindex(FBFR *fbfr
, FLDOCCnumidx
)
詳細については、『Oracle Tuxedo FML リファレンス』の「Frstrindex、Frstrindex32(3fml)」を参照してください。
Funindex
は、フィールド化バッファのインデックスを削除し、削除前のバッファ内のインデックス数を返します。
FLDOCC
Funindex(FBFR *fbfr
)
詳細については、『Oracle Tuxedo FML リファレンス』の「Funindex、Funindex32(3fml)」を参照してください。
インデックスを設定しないでフィールド化バッファを送信するには、次の手順に従います。
Findex(fbfr);
インデックスの削除は受信側のプロセス以外で行われ、さらにファイルで送信されなかったため、受信側のプロセスは Frstrindex
を呼び出せません。
注意 : | Funindex を呼び出しても、インデックスが占有していたメモリ領域は解放されません。Funindex は、ディスク上の領域を節約したり、バッファを別プロセスに送信するときに領域を節約するだけです。フィールド化バッファとインデックスを別プロセスに送信し、これらの関数を使用しないこともできます。 |
この節では、標準入出力またはファイルのストリームに対して、フィールド化バッファの入力や出力を行うための関数を説明します。
I/O 関数の Fread
および Fwrite
は、標準 I/O ライブラリを操作します。
int Fread(FBFR *fbfr, FILE *iop)
int Fwrite(FBFR *fbfr, FILE *iop)
入出力先のストリームは、FILE
型のポインタ引数によって決定されます。この引数は、通常の標準 I/O ライブラリ関数を使用して設定しなければなりません。
以下のように Fwrite
を使用すると、フィールド化バッファを標準 I/O ストリームに書き込むことができます。
if (Fwrite(fbfr, iop) < 0)
F_error("pgm_name");
以下のように Fread
を使用すると、Fwrite
を書き込んだバッファを読み取ることができます。
if(Fread(fbfr, iop) < 0)
F_error("pgm_name");
fbfr
が指すフィールド化バッファの内容は、読み込まれたフィールド化バッファの内容で置き換えられますが、フィールド化バッファの容量 (バッファ サイズ) は変更されません。
Fwrite
は、バッファのインデックスを削除し、Fused
から返されたフィールド化バッファの使用済みの部分のみを書き込みます。
Fread
は、Findex
を呼び出すことによってバッファのインデックスを復元します。バッファのインデックス付けには、Fwrite
で書き込まれた時と同じインデックス付けの間隔が使用されます。Fread32
は、FLD_PTR
型のフィールドを無視します。
詳細については、『Oracle Tuxedo FML リファレンス』の「Fread、Fread32(3fml)」および「Fwrite、Fwrite32(3fml)」を参照してください。
以下のようにチェックサムを算出して、I/O の妥当性をチェックできます。
long chk;
. . .
chk = Fchksum(fbfr);
Fchksum
を呼び出し、フィールド化バッファと共にチェックサムの値を書き出し、入力時にその値をチェックする処置は、ユーザの責任です。Fwrite は、チェックサムの自動的な書き込みは行いません。ポインタ フィールド (FLD_PTR
) の場合は、ポインタまたはポインタが参照するポインタではなく、チェックサムの計算に使用するポインタ フィールド名が含まれます。
詳細については、『Oracle Tuxedo FML リファレンス』の「Fchksum、Fchksum32(3fml)」を参照してください。
Fprint
は、フィールド化バッファをテキスト形式で標準出力に出力します。
Fprint(FBFR *fbfr)
Ffprint
は、Fprint
とよく似ていますが、次の例のように、テキストを指定された出力ストリームに出力します。
Ffprint(FBFR *fbfr
, FILE *iop
)
これらの各出力関数は、フィールド オカレンスごとに、フィールド名とフィールド値をタブで区切って出力し、改行文字を追加します。Fname
は、フィールド名の判別に使用しますが、フィールド名を判別できないと、フィールド識別子を出力します。文字列または文字配列のフィールド値内の表示不能な文字は、バックスラッシュとその後に続く 2 文字からなる 16 進値で表現されます。テキスト内に現れるバックスラッシュは、もう 1 つバックスラッシュを使用するとエスケープされます。バッファの出力が完了すると空白行が出力されます。
値が FLD_PTR
型の場合、Fprint32
はフィールド名またはフィールド識別子と 16 進法のポインタ値を出力します。この関数はポインタ情報を出力しますが、Fextread32
関数はフィールド型 FLD_PTR
を無視します。値が FLD_FML32
型の場合、Fprint32
は、ネストの各レベルの先頭にタブを付けて FML32 バッファを再帰的に出力します。値が FLD_VIEW32
型の場合、この関数は、VIEW32 フィールド名と構造体メンバー名/値の対を出力します。
詳細については、『Oracle Tuxedo FML リファレンス』の「Fprint、Fprint32(3fml)」を参照してください。
Fextread
を使用すると、フィールド化バッファを、その出力形式、つまり Fprint
の出力から作成できます (Fprint
で出力された 16 進値が正しく解釈されます)。
int
Fextread(FBFR *fbfr
, FILE *iop
)
Fextread
は、Fprint
の出力形式で、フィールド名とフィールド識別子の組み合わせの前指定する、次のオプション フラグを受け付けます。
フラグが指定されていない場合、デフォルトでは、Fadd
によりフィールドが追加されます。
複数行にわたってフィールド値を指定するには、2 行目以降の行頭にタブを入力します。このタブは無視されます。単一の空白行は、バッファの終了を示します。連続した複数の空白行を指定すると、NULL バッファが生成されます。埋め込み型のバッファに対して Fextread
を実行すると、ネスト状の FML32 バッファ (FLD_FML32
) と VIEW32 フィールド (FLD_VIEW32
) が生成されます。Fextread32
は、FLD_PTR
型のフィールドを無視します。
エラーが発生すると、-1
が返され、Ferror
が適宜設定されます。ファイルの終わりに達しても空白行が現れないと、Ferror
に FSYNTAX
が設定されます。
詳細については、『Oracle Tuxedo FML リファレンス』の「Fextread、Fextread32(3fml)」を参照してください。
この節では、式の「変数」にフィールド化バッファまたは VIEW のフィールドの値であるような論理式を評価する関数について説明します。これらの関数を使用すると、以下の処理を行うことができます。
ここでは、論理式をコンパクトな形式にコンパイルして効率的に評価するための関数と、コンパイル済みの論理式をフィールド化バッファと照合させ、true または false を返す関数を説明します。
ここでは、論理式のコンパイル用関数で受け付ける式と、式の評価方法を詳しく説明します。
論理式で許可される変数は、フィールド参照のみです。フィールド名の指定方法には、いくつかの規則があります。たとえば、フィールド名は、英字と数字で構成し、先頭には英字を指定しなければなりません。アンダースコア (_
) は、英字と見なされます。長い変数名をアンダースコアで区切り、読みやすい名前に変えることができます。フィールド名には、最大 30 文字を指定できます。予約語はありません。
フィールド化バッファを評価するため、論理式で参照されるフィールドは、フィールド テーブルに存在していなければなりません。したがって、「FML および VIEWS の環境設定」で説明したように、環境変数の FLDTBLDIR
と FIELDTBLS
を設定してから、論理式をコンパイルする関数を使用してください。論理式で使用できるフィールド型は、FML フィールドで使用できる型と同じです。つまり、short
型、long
型、float
型、double
型、char
型、string
型、および carray
型を使用できます。フィールド型は、フィールド名と共にフィールド テーブルに格納されています。したがって、フィールド型は常に判別できます。
VIEW を評価するため、論理式で参照されるフィールドは、対応するフィールド化バッファ名ではなく、C 構造体の要素名として VIEW に存在していなければなりません。したがって、「FML および VIEWS の環境設定」で説明したように、環境変数の VIEWDIR
と VIEWFILES
を設定してから、論理式をコンパイルする関数を使用してください。論理式で使用できるフィールド型は、FML VIEWS で使用できる型と同じです。つまり、short
型、long
型、float
型、double
型、char
型、string
型、carray
型のほか、int
型および dec_t
型を使用できます。フィールド型は、フィールド名と共に VIEW 定義に格納されています。したがって、フィールド型は常に判別できます。
文字列は、一重引用符で囲まれた文字の集まりです。エスケープ シーケンスでエスケープした文字は、その文字の ASCII コードで置き換えることができます。エスケープ シーケンスは、バックスラッシュと 2 桁の 16 進数で構成されます。この規則は、\x
で始める 16 進のエスケープ シーケンスを使用する C 言語規則とは異なります。
たとえば、`hello'
と `hell\\6f'
の場合、「o
」の 16 進数は 6f
なので、これらの文字列は同一と見なされます。
8 進のエスケープ シーケンスや \n
などのエスケープ シーケンスはサポートされていません。
定数として、C 言語の場合と同じく、整数と浮動小数点値が受け付けられます。8 進および 16 進の定数は認識されません。整数は、long
型として処理され、浮動小数点値は、double
型として処理されます。(dec_t
型の 10 進定数はサポートされていません。)
論理式を評価するため、論理式のコンパイラによって以下の変換が行われます。
フィールド名またはフィールド名と後続の添字は、基本式です。添字は、参照対象のフィールド オカレンスを指定します。添字としては、整定数または ?
(任意のオカレンスを示す) のいずれかを使用します。添字は、式と見なされません。フィールド名に添字が付いていないと、フィールド オカレンスは 0 と見なされます。
フィールド名参照が、算術演算子、単項演算子、代入演算子、または関係演算子なしで示されると、フィールドが存在する場合は long 型整数の 1、フィールドが存在しない場合は 0 となります。この方法を使用して、フィールド型に関係なく、フィールド化バッファ内にフィールドが存在するかどうかをテストできます。間接演算子 (*
) は存在しません。
定数は基本式です。定数の型は、long
型、double
型、carray
型のいずれかです。型変換の説明を参照してください。
かっこで囲んだ式は、型と値が、かっこで囲まない場合の式の型と値に等しい基本式です。かっこを使用すると、演算子の優先順位を変更できます。次の節を参照してください。
次の表は、論理式の演算子を優先順位の高いものから順に示しています。
同じ演算子型に分類される演算子は、優先順位が同じです。次の節では、各演算子を詳しく説明します。C 言語では、かっこを使用して、演算子の優先順位をオーバーライドできます。
+expression
-expression
~expression
!expression
単項プラス演算子は、オペランドに有効ではありません。認識はされても、無視されます。単項マイナス演算子の結果は、そのオペランドの否定です。通常の算術変換が実行されます。符号なしのものは、FML には存在しないので、この演算子には問題がありません。
論理否定演算子の結果は、オペランドの値が 0 の場合は 1 であり、オペランドの値が 0 以外の場合は 0 となります。結果は long
型になります。
補数演算子の結果は、オペランドの補数です。結果は long
型になります。
倍数に関する演算子の *
、/
、%
は、左から右にグループ化されます。通常の算術変換が実行されます。
expression
*expression
/
expressionexpression
%
expressionexpression
2 項演算子 *
は、乗算を示します。*
演算子は、連想型であり、同一レベルで数回の乗算を行う式は、コンパイラで再配置できます。
2 項演算子 /
は、除算を示します。正の整数が除算されると、切り捨ては 0 に向かって行われますが、オペランドのいずれかが負の場合は、切り捨ての形式は、マシンによって異なります。
2 項演算子 %
は、最初の式を次の式で除算した結果の剰余を返します。通常の算術変換が実行されます。オペランドには、float
型や double
型を使用してはなりません。
加法に関する演算子の +
と -
は、左から右にグループ化されます。通常の算術変換が実行されます。
expression
+expression
-
expressionexpression
+
演算子は、オペランドの和を返します。+
演算子は連想型であり、同一レベルで数回の加算を行う式は、コンパイラで再配置できます。オペランドが両方とも string
である必要はありません。一方のオペランドが string
文字列の場合、そのオペランドはもう一方のオペランドの算術型に変換されます。
-
演算子は、オペランドの差を返します。通常の算術変換が実行されます。オペランドが両方とも string
である必要はありません。一方のオペランドが string
文字列の場合、そのオペランドはもう一方のオペランドの算術型に変換されます。
expression
==expression
!=
expressionexpression
%%
expressionexpression
!%
expressionexpression
==
(等価)、!=
(非等価) の各演算子は、指定された関係が false の場合は 0 を返し、true の場合は 1 を返します。結果は long
型になります。通常の算術変換が実行されます。
%%
演算子の場合は、2 つ目の式は、最初の式と照合するために使用する正規表現です。2 つ目の式 (正規表現) は、引用符で囲まれた文字列でなければなりません。最初の式は、FML フィールド名であっても、引用符で囲まれた文字列であってもかまいません。この演算子は、最初の式が 2 つ目の式 (正規表現) と完全に一致する場合は、1 を返し、それ以外は 0 を返します。
!%
演算子は、正規表現との不一致を検出する演算子です。この演算子は、%%
演算子と同じオペランドをとりますが、まったく反対の結果を生じます。%%
と !%
の関係は、==
と !=
の関係と同じです。
使用可能な正規表現については、『Oracle Tuxedo C リファレンス』の「tpsubscribe(3c)」リファレンス ページを参照してください。
expression
<expression
>
expressionexpression
<=
expressionexpression
>=
expressionexpression
<
(より小さい)、>
(より大きい)、<=
(以下)、>=
(以上) の各演算子は、指定された関係が false であれば 0 を返し、true であれば 1 を返します。結果は long
型になります。通常の算術変換が実行されます。
expression
^expression
ビット単位の排他論理和が返されます。結果は、必ず long
型です。
expression
&&expression
&&
演算子は、左から右にグループ化されます。この演算子は、両方のオペランドが 0 でない場合は 1 を返し、どちらかが 0 の場合は 0 を返します。&&
演算子は、必ず左から右へ評価を行います。ただし、最初のオペランドが 0 の場合、2 つ目のオペランドを評価しないということはなく、この点で C 言語とは異なります。オペランドの型は同一でなくてもかまいません。結果は、必ず long
型です。
expression
||expression
どちらかのオペランドが 0 でない場合は 1
を返し、両方とも 0 の場合は 0
を返します。||
演算子は、必ず左から右へ評価を行います。ただし、最初のオペランドが 0 でない場合、2 つ目のオペランドを評価しないということはなく、この点で C 言語と異なります。オペランドの型は同一でなくてもかまいません。結果は、必ず long
型です。
以下のフィールド テーブルは、論理式のサンプルで使用するフィールドを定義しています。
EMPID 200 carray
SEX 201 char
AGE 202 short
DEPT 203 long
SALARY 204 float
NAME 205 string
論理式は、必ず true か false に評価されることに注意してください。次の例では、条件が両方とも true の場合、true になります。
この例では、EMPID
の添字として整定数を使用しています。以下の例では、?
添字を使用しています。
"PETS[?] == 'dog'"
この式は、PETS
が存在し、その任意のオカレンスが文字「dog」を含む場合は、true となります。
ここでは、引数として論理式をとる各種の関数について説明します。
Fboolco
は、論理式をコンパイルし、評価ツリーに対するポインタを返します。
char *
Fboolco(char *expression)
*expression
はコンパイル対象の式に対するポインタです。FLD_PTR
、FLD_FML32
、または FLD_VIEW32
のフィールド タイプが使用されると、この関数は異常終了します。これらのフィールド タイプの 1 つが指定されると、Ferror
に FEBADOP
が設定されます。
Fvboolco
は、VIEW の論理式をコンパイルし、評価ツリーに対するポインタを返します。
char *
Fvboolco(char *expression, char *viewname)
*expression
はコンパイル対象の式に対するポインタで、*viewname
はフィールドを評価する VIEW 名に対するポインタです。
評価ツリーを保持するには、malloc
(3) を使用して領域を割り当てます。たとえば、次の例は、「J」で始まり「n」で終了する FIRSTNAME
フィールド (たとえば、「John」、「Joan」など) がバッファ内に存在し、かつ、SEX
(性別) フィールドが「M」に設定されているかどうかをチェックする論理式をコンパイルします。
#include "<stdio.h>"
#include "fml.h"
extern char *Fboolco;
char *tree;
. . .
if((tree=Fboolco("FIRSTNAME %% 'J.*n' && SEX == 'M'")) == NULL)
F_error("pgm_name");
tree 配列の最初の文字は、最下位バイトを形成します。次の文字は、最上位バイトを形成します。それぞれ、全体の配列の長さをバイト数で指定する unsigned 型 (16 ビット) です。この値は、複写あるいは配列の操作に役立ちます。
Fboolco
が生成する評価ツリーは、次の節で説明する論理式関数で使用されます。したがって、絶えず式の再コンパイルをする必要はありません。
論理式を使用する必要がなくなった時に評価ツリーに割り当てられた領域を解放するには、free
(3) を使用してください。必要がなくなった評価ツリーを解放せずに多くの論理式をコンパイルすると、プログラムのデータ領域がなくなってしまう恐れがあります。
詳細については、『Oracle Tuxedo FML リファレンス』の「Fboolco、Fboolco32、Fvboolco、Fvboolco32(3fml)」を参照してください。
Fboolpr
は、指定されたファイルにコンパイルされた式を出力します。コンパイルされた式は、構文解析された (評価ツリーで示された) ようにコンパイルされ、全体にかっこが付きます。
void
Fboolpr(char *tree, FILE *iop)
Fvboolpr
は、指定されたファイルにコンパイルされた式を出力します。
void
Fvboolpr(char *tree, FILE *iop, char *viewname)
Fboolco
の例でコンパイルされた式を Fboolpr にかけると、以下の結果が出力されます。
(((FIRSTNAME[0]) %% ('J.*n')) && ((SEX[0]) == ('M')))
詳細については、『Oracle Tuxedo FML リファレンス』の「Fboolpr、Fboolpr32、Fvboolpr、Fvboolpr32(3fml)」を参照してください。
これらの関数は、両方とも、フィールド化バッファと照合して論理式を評価します。
int Fboolev(FBFR *
fbfr
,char *
tree
)
double Ffloatev(FBFR *fbfr
,char *
tree
)
int
Fvboolev(FBFR *fbfr
,char *tree
,char *viewname
)
double
Fvfloatev(FBFR *fbfr
,char *tree
,char *viewname
)
Fboolev
は、フィールド化バッファが評価ツリーで指定された論理式の条件と一致する場合は true (1) を返します。この関数は、フィールド化バッファあるいは評価ツリーのいずれも変更しません。上記の例のコンパイルされた評価ツリーを使用すると、「Buffer selected」と出力されます。
#include <stdio.h>
#include "fml.h"
#include "fldtbl.h"
FBFR *fbfr;
. . .
Fchg(fbfr,FIRSTNAME,0,"John",0);
Fchg(fbfr,SEX,0,"M",0);
if(Fboolev(fbfr,tree) > 0)
fprintf(stderr,"Buffer selected\n");
else
fprintf(stderr,"Buffer not selected\n");
Ffloatev
および Ffloatev32
は、Fboolev
と同様に動作しますが、式の値を double
型として返します。たとえば、次のコードでは、「6.6」と出力されます。
#include <stdio.h>
#include "fml.h"
FBFR *fbfr;
. . .
main() {
char *Fboolco;
char *tree;
double Ffloatev;
if (tree=Fboolco("3.3+3.3")) {
printf("%lf",Ffloatev(fbfr,tree));
}
}
Fboolev
を上記の例の Ffloatev
の位置で使用した場合、1 が出力されます。
詳細については、『Oracle Tuxedo FML リファレンス』の「Fboolev、Fboolev32、Fvboolev、Fvboolev32(3fml)」および「Ffloatev、Ffloatev32、Fvfloatev、Fvfloatev32(3fml)」を参照してください。
VIEW を、指定したレコード形式に変換したり、その逆の処理を行うことができます。デフォルトでは、IBM System/370 COBOL レコード形式に変換されます。
long
Fvstot(char *cstruct, char *trecord, long treclen, char *viewname)
long
Fvttos(char *cstruct, char *trecord, char *viewname)
int
Fcodeset(char *translation_table)
Fvstot
関数は、C 構造体のデータを、指定したレコードの形式に転送します。Fvttos
関数は、指定レコード形式のデータを C 構造体に転送します。trecord
は指定したレコードに対するポインタです。cstruct
は C 構造体に対するポインタです。viewname
は、コンパイルされた VIEW 記述名に対するポインタです。VIEWDIR
環境変数および VIEWFILES
環境変数を使用してコンパイルされた VIEW 記述があるディレクトリとファイルが検索されます。
FML バッファを、指定したレコードに変換するには、次の手順に従います。
指定レコードを、FML バッファに変換するには、次の手順に従います。
デフォルトは、IBM/370 COBOL レコードの形式です。デフォルトのデータ変換は、以下の表に基づいて行われます。
IBM/370 のレコードでは、フィールド間のフィルタ バイトはありません。ビューに対応するデータ構造の一部をなすデータ項目に対しては、COBOL SYNC 節は指定することはできません。整数フィールドは、変換を実行するマシン上の整数のサイズに応じて 4 バイトまたは 2 バイトの整数に変換されます。IBM/370 フォーマットへの変換、または IBM/370 フォーマットからの変換を行う場合、ビューの文字列フィールドは NULL で終了している必要があります。carray
フィールドのデータは変更されずに渡されます。データの変換は行われません。
パック 10 進数は、IBM/370 環境では 1 バイトにパッキングされた 2 桁の 10 進数として存在し、下位の 1/2 バイトは符号を格納するために使用されます。パッキングされた 10 進数の長さは 1 ~ 16 バイトで、1 ~ 31 桁の数字と 1 つの符号のストレージ領域があります。パッキングされた 10 進数は、C の構造体では dec_t
というフィールド タイプを利用することによってサポートされます。dec_t
フィールドは、カンマで区切られた 2 つの数字で構成されたサイズに定義されています。カンマの左側の数字は、10 進数が占有する総バイト数です。右側の数値は、小数点以下の桁数です。変換には、次の公式が使用されます。
dec_t(m, n) <=> S9(2*m-(n+1))V9(n)COMP-3
10 進数とほかのデータ型 (int
型、long
型、string
型、double
型、float
型) 間の変換には、decimal(3c) で説明されている関数を使用できます。
ASCII から EBCDIC へ、また EBCDIC から ASCII へのデフォルトの文字変換の詳細については、「Fvstof、Fvstof32(3fml)」の項を参照してください。
Fcodeset
を呼び出すと、実行時に代替文字変換テーブルを使用することができます。translation_table
は、512 バイトのバイナリ データを指している必要があります。最初の 256 バイトのデータは、ASCII から EBCDIC への変換テーブルとして解釈されます。次の 256 バイトのデータは、EBCDIC から ASCII へのテーブルとして解釈されます。512 バイトより後ろのデータは無視されます。ポインタが NULL のときは、デフォルトの変換テーブルが使用されます。
詳細については、『Oracle Tuxedo FML リファレンス』の「Fvstot、Fvttos(3fml)」を参照してください。
![]() ![]() ![]() |