FML を使用した Tuxedo アプリケーションのプログラミング

     前  次    新しいウィンドウで目次を開く     
ここから内容の開始

フィールド操作関数

ここでは、以下の内容について説明します。

 


この章について

この章では、「フィールドの定義と使用」で説明した実行時のマッピング関数を除く、すべての FML 関数および FML VIEWS 関数について説明します。

COBOL プログラムでは、FML 関数を直接使用できません。まず、FINIT というプロシージャを使用して、FML データを受信するためにレコードを初期化し、次に FVSTOF および FVFTOS のプロシージャを使用して COBOL レコードと FML バッファ間の変換を行います。これらのプロシージャの詳細については、『COBOL を使用した Oracle Tuxedo アプリケーションのプログラミング』を参照してください。ここでは、COBOL インタフェースについては説明しません。

 


FML と VIEWS: 16 ビット インタフェースと 32 ビット インタフェース

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」が付きます (MAXFBLEN32FBFR32FLDID32FLDLEN32F_OVHD32Fchg32、エラー コード Ferror32 など)。また、環境変数にも接頭辞 “32” が付きます (FLDTBLDIR32FIELDTBLS32VIEWFILES32VIEWDIR32 など)。FML32 では、フィールド化バッファのポインタは「FBFR32 *」型、フィールド長は FLDLEN32 型、フィールドのオカレンス数は FLDOCC32 型です。FML32 バッファには、デフォルトで 4 バイトの調整が必要です。

正しく記述された FML16 アプリケーションは、簡単に FML32 インタフェースに変更できます。FML 関数の呼び出しに使用する変数は、すべて適切な typedef (FLDIDFLDLEN、および 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_PTRFLD_FML32、および FLD_VIEW32) は、FML32 でのみサポートされています。FLD_PTR 型、FLD_FML32 型、FLD_MBSTRING 型、または FLD_VIEW32 型のフィールドを含むバッファを使用すると、F32to16 が失敗し、FBADFLD エラーが返されます。これらの関数に対して F16to32 を呼び出しても、何も起こりません。

注意 : 以降の節では、16 ビットの関数のみ説明し、対応する FML32 および VIEW32 関数は説明しません。

 


FML 関数のパラメータの定義

FML 関数のパラメータ仕様をわかりやすくするため、パラメータは、規則的な順序で指定されます。FML のパラメータは、次の順序で指定されます。

  1. フィールド化バッファに対するポインタ (FBFR) を必要とする関数の場合は、このポインタを最初に指定します。フィールド化バッファに対するポインタが 2 つ必要な関数 (転送関数など) の場合は、最初に宛先バッファに対するポインタを指定し、次にソース バッファに対するポインタを指定します。フィールド化バッファに対するポインタは、short 型の境界に調整した領域を指す必要があります (そうでない場合は、FerrorFALIGNERR が設定されたエラーが返されます)。また、領域はフィールド化バッファでなければなりません (そうでない場合は、FerrorFNOTFLD が設定されたエラーが返されます)。
  2. 入出力関数の場合は、最初にストリームに対するポインタを指定し、次にフィールド化バッファに対するポインタを指定します。
  3. フィールド識別子を必要とする関数の場合は、次にフィールド識別子 (FLDID 型) を指定します (Fnext の場合は、次にフィールド識別子に対するポインタを指定します)。
  4. フィールド オカレンス (FLDOCC 型) を必要とする関数の場合は、次にフィールド オカレンスを指定します (Fnext の場合は、次にオカレンス番号に対するポインタを指定します)。
  5. フィールド値を受け渡す関数の場合は、次にフィールド値の先頭に対するポインタを指定します (このポインタは、文字ポインタとして定義しますが、別の型のポインタからキャストすることもできます)。
  6. 文字配列 (carraymbstring) 型フィールドを処理する関数にフィールド値を渡す場合は、次にフィールドの長さを決定するパラメータ (FLDLEN 型) を指定します。フィールド値を検索する関数の場合は、検索対象のバッファの長さに対するポインタを関数に渡す必要があります。このパラメータは、検索対象の値の長さに設定されます。
  7. いくつかの関数では、上記の規則には当てはまらない特別なパラメータが必要です。これらの特別なパラメータは、上記のパラメータの後に指定します。詳細については、各関数の説明部分を参照してください。
  8. 以下は、フィールドの型ごとに定義されている NULL 値です。
    • short 型と long 型の場合は 0
    • float 型と double 型の場合は 0.0
    • string 型の場合は \0 (長さ 1 バイト)
    • carray 型または mbstring 型の場合は長さ 0 の文字列

 


フィールド識別子をマッピングする関数

以下の関数を使用すると、プログラムの実行時にフィールド テーブルまたはフィールド識別子を照会し、フィールドに関する情報を取得できます。

Fldid

Fldid は、指定された有効なフィールド名のフィールド識別子を返し、フィールド名/フィールド識別子のマッピング テーブルがない場合は、そのテーブルをフィールド テーブル ファイルからロードします。

FLDID
Fldid(char *name)

name は有効なフィールド名です。

マッピング テーブルが使用するメモリ領域は、Fnmid_unload、Fnmid_unload32(3fml) 関数を使用して解放することができます。ただし、これらのテーブルは、Fname 関数でロードされ、使用されるテーブルとは異なります。

詳細については、『Oracle Tuxedo FML リファレンス』の「Fldid、Fldid32(3fml)」を参照してください。

Fname

Fname は、指定された有効なフィールド識別子のフィールド名を返し、フィールド識別子/フィールド名のマッピング テーブルがない場合は、そのテーブルをフィールド テーブル ファイルからロードします。

char *
Fname(FLDID fieldid)

fieldid は、有効なフィールド識別子です。

マッピング テーブルが使用するメモリ領域は、Fnmid_unload、Fnmid_unload32(3fml) 関数を使用して解放することができます。ただし、これらのテーブルは、Fldid 関数によってロードおよび使用されるテーブルとは別のテーブルです。詳細については、『Oracle Tuxedo FML リファレンス』を参照してください。

詳細については、『Oracle Tuxedo FML リファレンス』の「Fname、Fname32(3fml)」を参照してください。

Fldno

Fldno は、指定されたフィールド識別子からフィールド番号を抽出します。

FLDOCC
Fldno(FLDID fieldid)

fieldid は、有効なフィールド識別子です。

詳細については、『Oracle Tuxedo FML リファレンス』の「Fldno、Fldno32(3fml)」を参照してください。

Fldtype

Fldtype は、指定されたフィールド識別子からフィールドの型 (fml.h で定義された整数) を抽出します。

int
Fldtype(FLDID fieldid)

fieldid は、有効なフィールド識別子です。

次の表は、Fldtype が返す値とその意味です。

表 5-1 Fldtype が返すフィールド型
戻り値
説明
fml.h または fml32.h でのフィールド型名
0
short 型整数
FLD_SHORT
1
long 型整数
FLD_LONG
2
文字
FLD_CHAR
3
単精度浮動小数点
FLD_FLOAT
4
倍精度浮動小数点
FLD_DOUBLE
5
NULL 終了文字列
FLD_STRING
6
文字配列
FLD_CARRAY
9
ポインタ
FLD_PTR
10
埋め込み型の FML32 バッファ
FLD_FML32
11
埋め込み型の VIEW32 バッファ
FLD_VIEW32
12
マルチバイト文字配列
FLD_MBSTRING

詳細については、『Oracle Tuxedo FML リファレンス』の「Fldtype、Fldtype32(3fml)」を参照してください。

Ftype

Ftype は、フィールド識別子で指定されたフィールドの型名を含む文字列に対するポインタを返します。

char *
Ftype(FLDID fieldid)

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

アプリケーションの作成機能の一部として、またはフィールド識別子を再作成するため、型の種類とフィールド番号からフィールド識別子を作成しておくと便利です。Fmkfldid は、この機能を提供します。

FLDID
Fmkfldid(int type, FLDID 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 バッファとすべての補助バッファが調べられ、参照が見つかったバッファはすべて削除されます。サーバ コードをコーディングする場合は、以下の状況を認識しておく必要があります。

この節では、フィールド化バッファの領域を確保するための関数について説明します。まず、指定されたバッファがフィールド化バッファであるかどうかを判別するための関数を説明します。

Fielded

Fielded (または Fielded32) を使用すると、指定されたバッファがフィールド化されているかどうかをテストできます。

int
Fielded(FBFR *fbfr)

Fielded32 は 32 ビットの FML と共に使用します。

Fielded を使用すると、バッファがフィールド化されている場合は true (1) が返されます。バッファがフィールド化されていない場合は false (0) が返されます。この場合、Ferror は設定されません。

詳細については、『Oracle Tuxedo FML リファレンス』の「Fielded、Fielded32(3fml)」を参照してください。

Fneeded

フィールド化バッファに割り当てるメモリ領域のサイズは、フィールド化バッファに指定できるフィールドの最大数と、すべてのフィールド値に必要な領域の合計サイズによって異なります。Fneeded を使用すると、フィールド化バッファに必要な領域 (バイト単位) を判別できます。この関数には引数として、フィールド数とすべてのフィールド値に必要な領域 (バイト単位) を指定します。

long
Fneeded(FLDOCC F, FLDLEN V)

以下はパラメータの説明です。

フィールド値に必要な領域は、各フィールド値が標準的な構造で格納された場合の領域を見積もることにより、算出できます。たとえば、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

Fvneeded 関数を使用すると、VIEW バッファに必要な領域 (バイト単位) を判別できます。この関数には、引数として VIEW の名前に対するポインタを指定します。

long
Fvneeded(char *subtype)

Fvneeded 関数は、VIEW のサイズをバイト数で返します。

詳細については、『Oracle Tuxedo FML リファレンス』の「Fvneeded、Fvneeded32(3fml)」を参照してください。

Finit

Finit は、割り当てられたメモリ領域をフィールド化バッファとして初期化します。

int
Finit(FBFR *fbfr, FLDLEN buflen)

以下はパラメータの説明です。

Fneeded の例で割り当てたメモリ領域を初期化するために Finit を呼び出す場合は、以下の形式を使用します。

Finit(fbfr, Fneeded(NF, NV));

この呼び出しの結果、fbfr は、初期化された空のフィールド化バッファを指します。Fneeded(NF, NV) によって割り当てられた最大バイト数から、fml.h で定義された F_OVHD 分を差し引いたバイト数を、バッファのフィールド領域として使用できます。

注意 : ただし、malloc(3) (前の節を参照) への呼び出しと Finit への呼び出しでは、同じ値を使用する必要があります。

詳細については、『Oracle Tuxedo FML リファレンス』の「Finit、Finit32(3fml)」を参照してください。

Falloc

Fneededmalloc(3)、および Finit に対する呼び出しは、Falloc に対する 1 回の呼び出しで置き換えることができます。この関数を使用すると、必要な領域を割り当て、バッファを初期化できます。

FBFR *
Falloc(FLDOCC
F, FLDLEN V)

以下はパラメータの説明です。

前の 3 つの節で説明した、Fneededmalloc()、および Finit と同じ機能を実行する Falloc への呼び出しは、次のようにコーディングします。

extern FBFR *Falloc;
. . .
if((fbfr = Falloc(NF, NV)) == NULL)
F_error(“pgm_name”); /* バッファを割り当てることができなかった */

Falloc (または、Fneededmalloc(3) および Finit) によって割り当てられたストレージを解放するには、Ffree を使用します。『Oracle Tuxedo FML リファレンス』の「Ffree、Ffree32(3fml)」を参照してください。

詳細については、『Oracle Tuxedo FML リファレンス』の「Falloc、Falloc32(3fml)」を参照してください。

Ffree

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

Fsizeof は、バイト単位でフィールド化バッファのサイズを返します。

long
Fsizeof(FBFR *fbfr)

fbfr は、フィールド化バッファに対するポインタです。たとえば、次のコードでは、Fsizeof は、フィールド化バッファの当初の割り当て時に Fneeded が返した数と同じ数を返します。

long bytes;
. . .
bytes = Fsizeof(fbfr);

詳細については、『Oracle Tuxedo FML リファレンス』の「Fsizeof、Fsizeof32(3fml)」を参照してください。

Funused

Funused を使用すると、フィールド化バッファの領域のうち、追加データを格納するために使用できる領域を判別できます。

long
Funused(FBFR *fbfr)

fbfr は、フィールド化バッファに対するポインタです。次の例を参照してください。

long unused;
. . .
unused = Funused(fbfr);

Funused は、空き領域のバイト数のみを示し、バッファ内での空き領域の位置は示しません。

詳細については、『Oracle Tuxedo FML リファレンス』の「Funused、Funused32(3fml)」を参照してください。

Fused

Fused を使用すると、フィールド化バッファ内でデータおよびオーバーヘッド用に使用されている領域を判別できます。

long
Fused(FBFR *fbfr)

fbfr は、フィールド化バッファに対するポインタです。次の例を参照してください。

long used;
. . .
used = Fused(fbfr);

Fused は、使用済み領域のバイト数のみを示し、バッファ内での位置は示しません。

詳細については、『Oracle Tuxedo FML リファレンス』の「Fused、Fused32(3fml)」を参照してください。

Frealloc

この関数を使用すると、Falloc を呼び出して既に領域を割り当てたバッファのサイズを変更できます。

tpalloc(3c) で領域を割り当てた場合は、tprealloc(3c) を呼び出して領域を再び割り当てます。バッファのサイズ変更機能は、新しいフィールド値を追加したために空き領域が不足した場合などに役立ちます。このような場合は、単に Frealloc を呼び出すだけでバッファのサイズを増やすことができます。また、Frealloc を呼び出してバッファのサイズを小さくすることもできます。

FBFR *
Frealloc(FBFR *fbfr, FLDOCC nf, FLDLEN nv)

以下はパラメータの説明です。

次の例を参照してください。

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 に対する呼び出しで要求した追加の領域が古いバッファと隣接している場合は、上の例の newfbfrfbfr は同一になります。ただし、プログラムが正しく実行されるようにするため、newfbfr を宣言しておき、新しい値または NULL 値が返されるのを防ぐ必要があります。Frealloc が失敗した場合、fbfr は再使用しないでください。

注意 : バッファ サイズは、バッファ内で現在使用中のバイト数までしか縮小できません。

詳細については、『Oracle Tuxedo FML リファレンス』の「Frealloc、Frealloc32(3fml)」を参照してください。

 


フィールド化バッファを移動する関数

フィールド化バッファの位置に関する唯一の制約は、フィールド化バッファを short 型境界に調整しなければならないことです。この制約がなければ、フィールド化バッファをメモリ内で自由に移動できます。

Fmove

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

Fcpy は、あるフィールド化バッファを別のフィールド化バッファで上書きするために使用します。

int
Fcpy(FBFR *dest, FBFR *src)

以下はパラメータの説明です。

Fcpy は、上書きされたフィールド化バッファの全体の長さを保持するため、フィールド化バッファのサイズを拡大または縮小する場合に便利です。次の例を参照してください。

FBFR *src, *dest;
. . .
if(Fcpy(dest, src) < 0)
F_error(“pgm_name”);

Fmovedest は、初期化されていない領域を指す場合があります。しかし、Fcpydest には、初期化されたフィールド化バッファ (Falloc で割り当てられる) を指定する必要があります。さらに、Fcpy は、dest に指定されたバッファが十分な大きさであるかどうかも検証します。

注意 : フィールド化バッファのサイズを、現在格納されているデータの領域より小さくすることはできません。

Fmove と同じく、Fcpy は、ソース バッファを変更しません。

値が FLD_PTR 型の場合、Fcpy32 はバッファ ポインタをコピーします。アプリケーション プログラマは、対応するポインタがコピーされたときのバッファの再割り当ておよび解放を管理する必要があります。FLD_PTR フィールドが指すバッファは、tpalloc(3c) を呼び出して割り当てます。

詳細については、『Oracle Tuxedo FML リファレンス』の「Fcpy、Fcpy32(3fml)」を参照してください。

 


フィールドへのアクセスおよびフィールドの変更を行う関数

この節では、変換処理を行わずにフィールド型を使用して、フィールド化バッファにアクセスしたり、更新する方法を説明します。フィールド化バッファから、またはフィールド化バッファへのデータ転送時に、データ型を変換する関数の一覧については、「変換を行う関数」を参照してください。

Fadd

Fadd は、フィールド化バッファに新しいフィールド値を追加します。

int
Fadd(FBFR *fbfr, FLDID fieldid, char *value, FLDLEN len)

以下はパラメータの説明です。

バッファ内にフィールド オカレンスがない場合は、フィールドが追加されます。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 バッファの場合、Fadd32FVIEWFLD 型の構造体に対するポインタを格納します。FVIEWFLD 型の構造体には、vflags (現在未使用で 0 に設定されているフラグ フィールド)、vname (VIEW 名を含む文字配列)、および data (C 構造体として格納される VIEW データに対するポインタ) が含まれています。アプリケーションは、Fadd32vnamedata を提供します。FVIEWFLD 構造体は、次のとおりです。

typedef struct { 
TM32U vflags; /* フラグ - 現在未使用 */
char vname[FVIEWNAMESIZE+1]; /* VIEW の名前 */
char *data; /* VIEW 構造体に対するポインタ */
} FVIEWFLD;

詳細については、『Oracle Tuxedo FML リファレンス』の「Fadd、Fadd32(3fml)」を参照してください。

Fappend

Fappend は、フィールド化バッファに新しいフィールド値を付加します。

int
Fappend(FBFR *fbfr, FLDID fieldid, char *value, FLDLEN len)

以下はパラメータの説明です。

Fappend は、value で定義された値を指定した、新しい fieldid のフィールド オカレンスを付加し、バッファを付加モードにします。付加モードでは、同じフィールド セットを含む多数の行で構成された、サイズの大きいバッファが最適化されます。

バッファを付加モードにすると、バッファに対する操作が制限されます。付加モードで呼び出せる FML ルーチンは、FappendFindexFunindexFfreeFusedFunused、および 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)」を参照してください。

Fchg

Fchg は、バッファ内のフィールド値を変更します。

int
Fchg(FBFR *fbfr, FLDID fieldid, FLDOCC oc, char *value, FLDLEN 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 バッファの場合、Fchg32FVIEWFLD 型の構造体に対するポインタを格納します。FVIEWFLD 型の構造体には、vflags (現在未使用で 0 に設定されているフラグ フィールド)、vname (VIEW 名を含む文字配列)、および data (C 構造体として格納される VIEW データに対するポインタ) が含まれています。アプリケーションは、vnamedataFchg32 に提供します。FVIEWFLD 構造体は、次のとおりです。

typedef struct { 
TM32U vflags; /* フラグ - 現在未使用 */
char vname[FVIEWNAMESIZE+1]; /* VIEW の名前 */
char *data; /* VIEW 構造体に対するポインタ */
} FVIEWFLD;

バッファには、変更または追加されたフィールド値を格納できる領域が必要です。空き領域不足の場合、エラー (FNOSPACE) が返されます。

詳細については、『Oracle Tuxedo FML リファレンス』の「Fchg、Fchg32(3fml)」を参照してください。

Fcmp

Fcmp は、2 つのフィールド化バッファのフィールド識別子とフィールド値を比較します。

int
Fcmp(FBFR *fbfr1, FBFR *fbfr2)

fbfr1 および fbfr2 は、フィールド化バッファに対するポインタです。

この関数は、2 つのバッファが同一の場合は 0 を返し、以下の条件のいずれかが成立する場合は -1 を返します。

ポインタと埋め込み型のバッファが同一かどうかは、以下の条件によって決まります。

Fcmp は、上記のいずれかの条件の逆が true である場合に 1 を返します。たとえば、fbfr2 フィールドのフィールド識別子が fbfr1 フィールドの対応するフィールド識別子より小さい場合、Fcmp1 を返します。

詳細については、『Oracle Tuxedo FML リファレンス』の「Fcmp、Fcmp32(3fml)」を参照してください。

Fdel

Fdel は、指定されたフィールド オカレンスを削除します。

int
Fdel(FBFR *fbfr, FLDID fieldid, FLDOCC oc)

以下はパラメータの説明です。

たとえば、次のコードは、指定されたフィールド識別子が示すフィールドの最初のオカレンスを削除します。

FLDOCC occurrence;
. . .
occurrence=0;
if(Fdel(fbfr, fieldid, occurrence) < 0)
F_error("pgm_name");

指定されたフィールドが存在しない場合は -1 が返され、FerrorFNOTPRES に設定されます。

ポインタ フィールドの場合、Fdel32 は、参照されるバッファを変更したり、ポインタを解放しないで、FLD_PTR フィールド オカレンスを削除します。データ バッファは、オペークなポインタとして扱われます。

詳細については、『Oracle Tuxedo FML リファレンス』の「Fdel、Fdel32(3fml)」を参照してください。

Fdelall

Fdelall は、指定されたフィールドのすべてのオカレンスをバッファから削除します。

int
Fdelall(FBFR *fbfr, FLDID fieldid)

以下はパラメータの説明です。

次の例を参照してください。

if(Fdelall(fbfr, fieldid) < 0)
F_error("pgm_name"); /* フィールドが存在しない */

フィールドが見つからないと、-1 が返され、FerrorFNOTPRES に設定されます。

ポインタ フィールドの場合、Fdelall32 は、参照されるバッファを変更したり、ポインタを解放しないで、FLD_PTR フィールド オカレンスを削除します。データ バッファは、オペークなポインタとして扱われます。

詳細については、『Oracle Tuxedo FML リファレンス』の「Fdelall、Fdelall32(3fml)」を参照してください。

Fdelete

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

Ffind は、バッファ内の指定されたフィールド オカレンスの値を検索します。

char *
Ffind(FBFR *fbfr, FLDID fieldid, FLDOCC oc, 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 が返され、FerrorFNOTPRES に設定されます。

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)」を参照してください。

Ffindlast

この関数は、フィールド化バッファ内のフィールドの最後のオカレンスを検索し、そのフィールドに対するポインタと、最後のフィールド オカレンスのオカレンス番号と長さを返します。

char *
Ffindlast(FBFR *fbfr, FLDID fieldid, FLDOCC *oc, FLDLEN *len)

以下はパラメータの説明です。

上の例では、Ffindlast の戻り値として、文字ポインタのデータ型 (C の char*) が示されています。実際に返されるポインタの型は、ポインタが指す値の型と同じです。

Ffindlast は、Ffind と同様に動作します。ただし、フィールド オカレンスを指定する必要はなく、関数の戻り値として、最後のフィールド オカレンスのオカレンス番号と値が返されます。関数の呼び出し時にオカレンスに NULL を指定すると、オカレンス番号は返されません。この関数は、埋め込み型のバッファにある指定されたフィールドのオカレンスは調べません。

Ffindlast が返す値は、バッファが変更されない限り有効です。

詳細については、『Oracle Tuxedo FML リファレンス』の「Ffindlast、Ffindlast32(3fml)」を参照してください。

Ffindocc

Ffindocc は、バッファ内の指定したフィールドのオカレンスを調べ、ユーザ指定のフィールド値と一致する最初のフィールド オカレンスのオカレンス番号を返します。

FLDOCC
Ffindocc(FBFR *fbfr, FLDID fieldid, char *value, FLDLEN 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

Fget は、値が変更されたときに、フィールド化バッファのフィールドを検索するために使用されます。

int
Fget(FBFR *fbfr, FLDID fieldid, FLDOCC oc, 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

Fgetalloc は、Fget と同じく、バッファ フィールドを検索し、そのコピーを作成します。ただし、フィールドの領域は、malloc(3) への呼び出しによって取得します。

char *
Fgetalloc(FBFR *fbfr, FLDID fieldid, FLDOCC oc, FLDLEN *extralen)

以下はパラメータの説明です。

上記の例では、Fgetalloc の戻り値として、文字ポインタのデータ型 (C の char*) が示されています。実際に返されるポインタの型は、ポインタが指す値の型と同じです。

Fgetalloc が成功すると、正しく境界に調整されたバッファ フィールドのコピーに対する有効なポインタが返されます。失敗すると、NULL が返されます。malloc(3) が失敗すると、Fgetalloc からエラーが返され、FerrorFMALLOC に設定されます。

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

Fgetlast は、値の変更時にフィールド化バッファからフィールドの最後のオカレンスを検索するために使用します。

int
Fgetlast(FBFR *fbfr, FLDID fieldid, FLDOCC *oc, char *loc, FLDLEN *maxlen)

以下はパラメータの説明です。

呼び出し側プログラムは、Fgetlast にプライベート バッファに対するポインタとブライペート バッファの長さを提供します。Fgetlast は、Fget と同様に動作します。ただし、フィールド オカレンスを指定する必要はなく、関数の戻り値として、最後のフィールド オカレンスのオカレンス番号と値が返されます。ただし、occ に NULL を指定して関数を呼び出すと、オカレンス番号は返されません。

詳細については、『Oracle Tuxedo FML リファレンス』の「Fgetlast、Fgetlast32(3fml)」を参照してください。

Fnext

Fnext は、指定されたフィールド オカレンスの次のバッファ フィールドを検索します。

int
Fnext(FBFR *fbfr, FLDID *fieldid, FLDOCC *oc, char *value, FLDLEN *len)

以下はパラメータの説明です。

バッファ内の最初のフィールドを取得するには、fieldidFIRSTFLDID を代入します。フィールド識別子と最初のフィールド オカレンスのオカレンス番号が対応するパラメータ内に返されます。フィールドが NULL でない場合は、フィールド値が value ポインタでアドレス指定されたメモリ位置にコピーされます。

len パラメータを使用すると、フィールド値を格納できるだけの領域が value に割り当てられているかどうかを判別できます。十分な領域が割り当てられていない場合は、FerrorFNOSPACE に設定されます。値の長さが 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 パラメータは変更されません。

フィールドがそれ以上見つからない場合は、Fnext0 を返し (バッファの終わり)、fieldidoccurrencevalue は変更されません。

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

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

Foccur は、バッファ内の指定されたフィールドのオカレンス数を返します。

FLDOCC
Foccur(FBFR *fbfr, FLDID fieldid)

以下はパラメータの説明です。

埋め込み型の 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

Fpres、指定されたフィールド オカレンスが存在する場合は true (1) を返し、存在しない場合は false (0) を返します。

int
Fpres(FBFR *fbfr, FLDID fieldid, FLDOCC oc)

以下はパラメータの説明です。

たとえば、次のコードは、fbfr が指すフィールド化バッファ内にフィールド ZIP が存在する場合、true を返します。

Fpres(fbfr,ZIP,0)

Fpres は、埋め込み型のバッファにある指定されたフィールドのオカレンスは確認しません。

詳細については、『Oracle Tuxedo FML リファレンス』の「Fpres、Fpres32(3fml)」を参照してください。

Fvals および Fvall

Fvals は、string 値の場合は Ffind と同じように動作しますが、値に対するポインタを必ず返します。Fvall は、long 型および short 型の値の場合は、Ffind と同じように動作しますが、実際のフィールド値を、値に対するポインタの代わりに long 型で返します。

char* 
Fvals(FBFR *fbfr,FLDID fieldid,FLDOCC oc)
char*
Fvall(FBFR *fbfr,FLDID fieldid,FLDOCC oc)

2 つの関数に共通するパラメータは、以下のとおりです。

Fvals の場合、指定されたフィールド オカレンスが見つからないと、NULL 文字列 \0 を返します。この関数は、戻り値をチェックせずにフィールドの値を別の関数に渡すのに役立ちます。ただし、この関数は、string 型のフィールドの場合のみ有効であり、ほかのフィールド型の場合は、自動的に NULL 文字列を返します (つまり、変換は行われません)。

Fvall の場合、指定されたフィールド オカレンスが見つからないと、0 を返します。この関数は、戻り値をチェックせずにフィールドの値を別の関数に渡すのに役立ちます。ただし、この関数は、long 型と short 型のフィールドの場合のみ有効であり、ほかのフィールド型の場合は、自動的に 0 を返します (つまり、変換は行われません)。

詳細については、『Oracle Tuxedo FML リファレンス』の「Fvals、Fvals32(3fml)」および「Fvall、Fvall32(3fml)」を参照してください。

 


バッファを更新する関数

この節では、バッファ内の個々のフィールドではなく、フィールド化バッファ全体にアクセスし、内容を更新する関数を説明します。これらの関数では、最大 3 つのパラメータしか使用されません。

Fconcat

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

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

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

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

FprojcpyFproj と似ていますが、目的のフィールドは宛先バッファに配置されます。バッファの更新によってポインタ フィールド (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

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 バッファの場合、Fupdate32FVIEWFLD 型の構造体に対するポインタを格納します。FVIEWFLD 型の構造体には、vflags (現在未使用で 0 に設定されているフラグ フィールド)、vname (VIEW 名を含む文字配列)、および data (C 構造体として格納される VIEW データに対するポインタ) が含まれています。アプリケーションは、Fupdate32vname および data を提供します。FVIEWFLD 構造体は、次のとおりです。

typedef struct { 
TM32U vflags; /* フラグ - 現在未使用 */
char vname[FVIEWNAMESIZE+1]; /* VIEW の名前 */
char *data; /* VIEW 構造体に対するポインタ */
} FVIEWFLD;

詳細については、『Oracle Tuxedo FML リファレンス』の「Fupdate、Fupdate32(3fml)」を参照してください。

 


VIEWS 関数

Fvftos

Fvftos は、指定された VIEW 記述を使用して、フィールド化バッファから C 構造体へデータを転送します。

int
Fvftos(FBFR *fbfr, char *cstruct, char *view)

以下はパラメータの説明です。

指定された VIEW が見つからない場合、Fvftos から -1 が返され、FerrorFBADVIEW に設定されます。

フィールド化バッファから C 構造体へのデータ転送時には、以下の規則が適用されます。

たとえば、次のコードは、string1cust.action[0] に格納し、abccust.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

Fvstof は、指定された VIEW 記述を使用して、C 構造体からフィールド化バッファへデータを転送します。

int
Fvstof(FBFR *fbfr, char *cstruct, int mode, char *view)

以下はパラメータの説明です。

転送プロセスは、mode パラメータに対応する FML 関数、FupdateFjoinFojoin、または Fconcat の項目で説明されている規則に従います。

指定された VIEW が見つからない場合、Fvstof から -1 が返され、FerrorFBADVIEW に設定されます。

注意 : NULL 値は、構造体メンバーからフィールド化バッファに転送されません。つまり、構造体からフィールドへの転送時には、構造体メンバーに対して定義されたデフォルト設定またはユーザ指定の NULL 値が構造体メンバーに含まれていると、そのメンバーは無視されます。

詳細については、『Oracle Tuxedo FML リファレンス』の「Fvftos、Fvftos32(3fml)」を参照してください。

Fvnull

Fvnull は、C 構造体内のオカレンスにそのフィールド用の NULL 値が含まれているかどうかを判別します。

int
Fvnull(char *cstruct, char *cname, FLDOCC oc, char *view)

以下はパラメータの説明です。

以下は、Fvnull の戻り値です。

詳細については、『Oracle Tuxedo FML リファレンス』の「Fvnull、Fvnull32(3fml)」を参照してください。

Fvsinit

Fvsinit は、適切な NULL 値で C 構造体内のすべての要素を初期化します。

int
Fvsinit(char *cstruct, char *view)

以下はパラメータの説明です。

詳細については、『Oracle Tuxedo FML リファレンス』の「Fvsinit、Fvsinit32(3fml)」を参照してください。

Fvopt

Fvopt は、実行時にフラグ オプションを変更します。

int
Fvopt(char *cname, int option, char *view)

以下はパラメータの説明です。

以下は、option パラメータに指定できる値の一覧です。

F_FTOS

フィールド化バッファから C 構造体への一方向マッピングを指定します。VIEW 記述の S オプションと同じように機能します。

F_STOF

C 構造体からフィールド化バッファへの一方向マッピングを指定します。VIEW 記述の F オプションと同じように機能します。

F_BOTH

C 構造体とフィールド化バッファの間の双方向マッピングを指定します。

F_OFF

指定されたメンバーのマッピングを無効にします。VIEW 記述の N オプションと同じように機能します。

VIEW 記述への変更は永久に保持されるわけではありません。変更内容の有効期間は、別の VIEW 記述に対してアクセスが行われるときまでです。

詳細については、『Oracle Tuxedo FML リファレンス』の「Fvopt、Fvopt32(3fml)」を参照してください。

Fvselinit

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 変換関数の実行中にこれらのフィールド型が使用されていた場合、FerrorFEBADOP に設定されます。

CFadd

CFadd は、バッファにユーザ指定の項目を追加して、バッファ内に新しいフィールド オカレンスを生成します。

int
CFadd(FBFR *fbfr, FLDID fieldid, char *value, FLDLEN len, int type)

以下はパラメータの説明です。

フィールドを追加する前に、データ項目は、ユーザ指定の型からフィールドをフィールド化バッファに格納される型としてフィールド テーブル内で指定された型に変換されます。ソースが 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

CFchg は、CFadd と同じように動作しますが、指定された値の変換後、フィールド値を変更します。

int
CFchg(FBFR *fbfr, FLDID fieldid, FLDOCC oc, char *value, FLDLEN len, int type)

以下はパラメータの説明です。

たとえば、次のコードは、フィールド 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

CFget は、Fget に似た変換関数です。ただし、CFget は変換した値をユーザ指定のバッファにコピーします。

int
CFget(FBFR *fbfr, FLDID fieldid, FLDOCC oc, char *buf, FLDLEN *len, int type)

以下はパラメータの説明です。

前の例を使って、次のコードは、バッファに格納されたばかりの値 (どのような形式の値でも可) にアクセスして、その値を元の 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

CFgetalloc は、Fgetalloc と同じように動作します。ただし、戻り値 (変換後の値) に対して malloc を使用して割り当てた領域は、free を使用して解放する必要があります。

char *
CFgetalloc(FBFR *fbfr, FLDID fieldid, FLDOCC oc, int type, 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

CFfind は、検索対象のフィールドの値を変換し、その値に対するポインタを返します。

char *
CFfind(FBFR *fbfr, FLDID fieldid, FLDOCC oc, FLDLEN len, int type)

以下はパラメータの説明です。

上記の例では、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

CFfindocc は、バッファの指定されたフィールドのオカレンスを調べ、フィールド識別子の型に変換されたユーザ指定のフィールド値と一致する最初のフィールド オカレンスのオカレンス番号を返します。

FLDOCC
CFfindocc(FBFR *fbfr, FLDID fieldid, char *value, FLDLEN len, int type)

以下はパラメータの説明です。

たとえば、次のコードは、文字列を 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");

フィールド値が見つからない場合は、-1 が返されます。

注意 : CFfindocc は、ユーザ指定の値をネイティブ フィールド型に変換してから、フィールド値を検証するため、正規表現は、ユーザ指定の型とネイティブ フィールド型が両方とも FLD_STRING である場合のみ機能します。したがって、CFfindocc には、正規表現に関するユーティリティがありません。

詳細については、『Oracle Tuxedo FML リファレンス』の「CFfindocc、CFfindocc32(3fml)」を参照してください。

 


文字列を変換する関数

ユーザ指定の型 FLD_STRING への変換および FLD_STRING からの変換を処理するために、以下の関数が提供されています。

これらの関数は、対応する非文字列用の関数を呼び出し、FLD_STRING 型と len 0 を提供します。ただし、Ffinds が返すポインタの有効期間は、CFfind の場合と同じです。

これらの関数の説明については、『Oracle Tuxedo FML リファレンス』を参照してください。

Ftypcvt

CFaddCFchgCFgetCFgetallocCFfind の各関数は、Ftypcvt を使用して、適切なデータ変換を行います。Ftypcvt32 関数は、フィールド型 FLD_PTRFLD_FML32、および FLD_VIEW32 では失敗します。Ftypcvt を使用する場合の形式は、次のとおりです。この形式は、パラメータの順序に関する規則に準拠しません。

char *
Ftypcvt(FLDLEN *tolen, int totype, char *fromval, int fromtype, FLDLEN fromlen)

以下はパラメータの説明です。

Ftypcvt は、fromlen で指定された長さの fromtype 型の *fromval の値 (fromtypeFLD_CARRAY の場合。それ以外の場合、fromlenfromtype から算出される。) を、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 は変換後の値に対するポインタを表します。

次の表は、この節で示した変換規則をまとめたものです。

表 5-2 変換規則のまとめ
変換前の型
変換後の型
-
char
short
long
float
double
string
carray
dec_t
char
-
cast
cast
cast
cast
st[0]=c
array[0]=c
d
short
cast
-
cast
cast
cast
sprintf
sprintf
d
long
cast
cast
-
cast
cast
sprintf
sprintf
d
float
cast
cast
cast
-
cast
sprintf
sprintf
d
double
cast
cast
cast
cast
-
sprintf
sprintf
d
string
c=st[0]
atoi
atol
atof
atof
-
drop 0
d
carray
c=array[0]
atoi
atol
atof
atof
add 0
-
d
dec_t
d
d
d
d
d
d
d
-

次の表は、前の表で使用されているエントリの説明です。

表 5-3 エントリの説明
エントリ
説明
-
srcdest が同じ型です。変換の必要はありません。
cast
C の代入演算子を使用した型変換によって、変換が行われます。
sprintf
sprintf 関数によって変換が行われます。
atoi
atoi 関数によって変換が行われます。
atof
atof 関数によって変換が行われます。
atol
atol 関数によって変換が行われます。
add 0
NULL バイトの連結によって変換が行われます。
drop 0
NULL 終了バイトを削除することによって変換が行われます。
c=array[0]
文字が配列の最初のバイトに設定されます。
array[0]=c
配列の最初のバイトが文字に設定されます。
c=st[0]
文字が文字列の最初のバイトに設定されます。
st[0]=c
文字列の最初のバイトが文字に設定されます。
d
decimal(3c) 変換関数

 


FLD_MBSTRING フィールドの変換

ユーザ指定の型 FLD_MBSTRING のデータのコード セットのエンコーディング変換を処理するために、以下の関数が提供されています。

これらの関数では、FLD_MBSTRING フィールドのエンコーディング名とマルチバイト データ情報の準備、FLD_MBSTRING フィールドからのエンコーディング名とマルチバイト データ情報の抽出、および FLD_MBSTRING フィールドにあるマルチバイト文字から対象の名前付きのエンコーディングへの変換を行います。次の図は、エンコーディング変換がどのように行われるかを例示しています。

図 5-1 FML32 バッファによるエンコーディング変換の例

FML32 バッファによるエンコーディング変換の例

上図の例に示すように、FLD_MBSTRING フィールドは、ユーザ データのコード セット文字エンコーディング (または単にエンコーディング) を識別する情報を保持できます。この例では、クライアントの要求の FLD_MBSTRING フィールドは、Shift-JIS (SJIS) エンコーディングで表される日本語ユーザ データを保持し、サーバの応答の FLD_MBSTRING フィールドは、Extended UNIX Code (EUC) エンコーディングで表される日本語ユーザ データを保持しています。マルチバイト文字エンコーディング機能では、環境変数 TPMBENCTPMBACONV を読み込んで、ソースのエンコーディング、対象のエンコーディング、および自動エンコーディング変換の状態 (有効または無効) を判別します。

次の図に示すように、FML32 型付きバッファは、それ自体でユーザ データの文字エンコーディングを識別する情報を保持できます。

図 5-2 グローバル エンコーディングの使用

グローバル エンコーディングの使用

FML32 型付きバッファで保持する FLD_MBSTRING フィールド数が多い場合、グローバル エンコーディングを使用すると、FLD_MBSTRING フィールドごとに文字エンコーディング名を追加するよりも、FML32 バッファによるマルチバイト ユーザ データの転送効率が向上します。Fmbpack32() 関数を使用すると、アプリケーション開発者は、Fmbpack32() で作成された FLD_MBSTRING フィールドごとに、グローバル エンコーディングを行うか個別のエンコーディングを行うかを選択できます。グローバル エンコーディングで使用できる名前は、各 FML32 バッファにつき 1 つだけです。

エンコーディングの変換機能により、基底の Tuxedo システム ソフトウェアでは、着信 FLD_MBSTRING フィールドのエンコーディング表現を、受信プロセスが実行されているマシンでサポートされているエンコーディング表現に変換できます。この変換は文字コード セット間の変換でも言語の翻訳でもなく、同じ言語の異なる文字エンコーディング間の変換です。

Fmbpack32

この関数は、FML32 型付きバッファに入力された FLD_MBSTRING フィールドのエンコーディング名およびマルチバイト データ情報を準備します。Fmbpack32() は、FLD_MBSTRING フィールドが FML32 API で FML32 バッファに追加される前に使用します。

この関数の詳細については、『Oracle Tuxedo FML リファレンス』の「Fmbpack32(3fml)」を参照してください。

Fmbunpack32

この関数は、FML32 型付きバッファ内の FLD_MBSTRING フィールドからエンコーディング名およびマルチバイト データ情報を抽出します。Fmbunpack32() は、FLD_MBSTRING フィールドが FML32 API (Ffind32()Fget32()、など) で FML32 バッファから抽出された後に使用します。

この関数の詳細については、『Oracle Tuxedo FML リファレンス』の「Fmbunpack32(3fml)」を参照してください。

tpconvfmb32

この関数は、FML32 型付きバッファにある FLD_MBSTRING フィールドのマルチバイト文字を、対象の名前付きのエンコーディングに変換します。具体的には、tpconvfmb32() は、FLD_MBSTRING フィールドで指定されたソースのエンコーディング名と target_encoding で定義された対象のエンコーディング名を比較し、エンコーディング名が異なる場合に tpconvfmb32() は、FLD_MBSTRING フィールドのデータを対象のエンコーディングに変換します。

この関数の詳細については、『Oracle Tuxedo FML リファレンス』の「tpconvfmb32(3fml)」を参照してください。

tpconvvmb32

この関数は、VIEW32 型付きバッファにある MBSTRING フィールドのマルチバイト文字を、対象の名前付きのエンコーディングに変換します。具体的には、tpconvvmb32() は、MBSTRING フィールドで指定されたソースのエンコーディング名と target_encoding で定義された対象のエンコーディング名を比較し、エンコーディング名が異なる場合に tpconvvmb32() は、MBSTRING フィールドのデータを対象のエンコーディングに変換します。

この関数の詳細については、『Oracle Tuxedo FML リファレンス』の「tpconvvmb32(3fml)」を参照してください。

 


インデックスを操作する関数

フィールド化バッファを Finit または Falloc で初期化すると、自動的にインデックスが設定されます。このインデックスにより、フィールド化バッファへのアクセスが促進されますが、プログラマ側からはインデックス処理が見えません。フィールド化バッファにフィールドを追加したり、削除すると、インデックスが自動的に更新されます。

ただし、記憶装置に長期に渡ってフィールド化バッファを格納したり、協調動作するプロセス間でフィールド化バッファを転送する場合は、フィールド化バッファの受信時に、インデックスを削除したり、再生成して領域を節約できます。ここで説明する関数は、このようなインデックス操作を実行します。

Fidxused

Fidxused は、バッファのインデックスが占有する領域を返します。

long
Fidxused(FBFR *fbfr)

fbfr は、フィールド化バッファに対するポインタです。

この関数を使用すると、バッファのインデックスのサイズを判別し、インデックスを削除した方が時間や領域を節約できるかどうかを判別できます。

詳細については、『Oracle Tuxedo FML リファレンス』の「Fidxused、Fidxused32(3fml)」を参照してください。

Findex

Findex を使用すると、インデックスが設定されていないフィールド化バッファにインデックスを設定できます。

int
Findex(FBFR *fbfr.FLDOCC intvl)

以下はパラメータの説明です。

Findex の 2 つ目の引数は、バッファのインデックス付けの間隔を指定します。0 を指定すると、FSTDXINT 値 (fml.h で定義) が使用されます。間隔 1 を指定すると、すべてのフィールドにインデックスが設定されます。

インデックス付けの間隔を増やしてバッファのインデックスを再設定すると、ユーザ データ用のバッファの空き領域を増やすことができます。ただし、処理時間の高速化と空き領域の確保を一度に両方実現することはできません。一般的に、インデックスの数を減らす、つまりインデックスの間隔を大きくすると、フィールドの検索に時間がかかります。ほとんどの操作では、空き領域が少なくなると、まず、すべてのインデックスが削除されます。それができない場合は、エラー メッセージが返されます。

詳細については、『Oracle Tuxedo FML リファレンス』の「Findex、Findex32(3fml)」を参照してください。

Frstrindex

インデックスの削除後に、フィールド バッファを変更していない場合は、この関数を Findex の代わりに使用できます。

int
Frstrindex(FBFR *fbfr, FLDOCC numidx)

以下はパラメータの説明です。

詳細については、『Oracle Tuxedo FML リファレンス』の「Frstrindex、Frstrindex32(3fml)」を参照してください。

Funindex

Funindex は、フィールド化バッファのインデックスを削除し、削除前のバッファ内のインデックス数を返します。

FLDOCC
Funindex(FBFR *fbfr)

fbfr は、フィールド化バッファに対するポインタです。

詳細については、『Oracle Tuxedo FML リファレンス』の「Funindex、Funindex32(3fml)」を参照してください。

インデックスを設定しないでフィールド化バッファを送信する例

インデックスを設定しないでフィールド化バッファを送信するには、次の手順に従います。

  1. インデックスを削除します。
  2. save = Funindex(fbfr);
  3. 送信するバイト数 (バッファの先頭の最上位バイトの数) を取得します。
  4. num_to_send = Fused(fbfr);
  5. インデックスが設定されていないバッファを送信します。
  6. transmit(fbfr,num_to_send);
  7. バッファのインデックスを復元します。
  8. Frstrindex(fbfr,save);

インデックスは、次の文を使用して受信側で再生成できます。

Findex(fbfr);

インデックスの削除は受信側のプロセス以外で行われ、さらにファイルで送信されなかったため、受信側のプロセスは Frstrindex を呼び出せません。

注意 : Funindex を呼び出しても、インデックスが占有していたメモリ領域は解放されません。Funindex は、ディスク上の領域を節約したり、バッファを別プロセスに送信するときに領域を節約するだけです。フィールド化バッファとインデックスを別プロセスに送信し、これらの関数を使用しないこともできます。

 


入出力を操作する関数

この節では、標準入出力またはファイルのストリームに対して、フィールド化バッファの入力や出力を行うための関数を説明します。

Fread および Fwrite

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)」を参照してください。

Fchksum

以下のようにチェックサムを算出して、I/O の妥当性をチェックできます。

long chk;
. . .
chk = Fchksum(fbfr);

Fchksum を呼び出し、フィールド化バッファと共にチェックサムの値を書き出し、入力時にその値をチェックする処置は、ユーザの責任です。Fwrite は、チェックサムの自動的な書き込みは行いません。ポインタ フィールド (FLD_PTR) の場合は、ポインタまたはポインタが参照するポインタではなく、チェックサムの計算に使用するポインタ フィールド名が含まれます。

詳細については、『Oracle Tuxedo FML リファレンス』の「Fchksum、Fchksum32(3fml)」を参照してください。

Fprint および Ffprint

Fprint は、フィールド化バッファをテキスト形式で標準出力に出力します。

Fprint(FBFR *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

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 が適宜設定されます。ファイルの終わりに達しても空白行が現れないと、FerrorFSYNTAX が設定されます。

詳細については、『Oracle Tuxedo FML リファレンス』の「Fextread、Fextread32(3fml)」を参照してください。

 


フィールド化バッファの論理式

ここでは、以下の内容について説明します。

この節では、式の「変数」にフィールド化バッファまたは VIEW のフィールドの値であるような論理式を評価する関数について説明します。これらの関数を使用すると、以下の処理を行うことができます。

ここでは、論理式をコンパクトな形式にコンパイルして効率的に評価するための関数と、コンパイル済みの論理式をフィールド化バッファと照合させ、true または false を返す関数を説明します。

 


論理式の定義

ここでは、論理式のコンパイル用関数で受け付ける式と、式の評価方法を詳しく説明します。

以下の C 言語の標準演算子はサポートされていません。

次の表は、論理式で受け付けられる BNF 記法の一覧です。

表 5-5 BNF 記法による論理式の定義
定義
<boolean>
<boolean> || <logical and> | <logical and>
<logical and>
<logical and> && <xor expr> | <xor expr>
<xor expr>
<xor expr> ^ <equality expr> | <equality expr>
<equality expr>
<equality expr> <eq op> <relational expr> | <relational expr>
<eq op>
== | != | %% | !%
<relational expr>
<relational expr> <rel op> <additive expr> | <additive expr>
<rel op>
< | <= | >= | > |
<additive expr>
<additive expr> <add op> <multiplicative expr> | <multiplicative expr>
<add op>
+ | -
<multiplicative expr>
<multiplicative expr> <mult op> <unary expr> | <unary expr>
<mult op>
* | / | %
<unary expr>
<unary op> <primary expr> | <primary expr>
<unary op>
+ | - | ~ | !
<primary expr>
( <boolean> ) | <unsigned constant> | <field ref>
<unsigned constant>
<unsigned number> | <string>
<unsigned number>
<unsigned float> | <unsigned int>
<string>
' <character> {<character>. . .} '
<field ref>
<field name> | <field name>[<field occurrence>]
<field occurrence>
<unsigned int> | <meta>
<meta>
?

以降の節では、論理式についてさらに詳しく説明します。

 


フィールド名とフィールド型

論理式で許可される変数は、フィールド参照のみです。フィールド名の指定方法には、いくつかの規則があります。たとえば、フィールド名は、英字と数字で構成し、先頭には英字を指定しなければなりません。アンダースコア (_) は、英字と見なされます。長い変数名をアンダースコアで区切り、読みやすい名前に変えることができます。フィールド名には、最大 30 文字を指定できます。予約語はありません。

フィールド化バッファを評価するため、論理式で参照されるフィールドは、フィールド テーブルに存在していなければなりません。したがって、「FML および VIEWS の環境設定」で説明したように、環境変数の FLDTBLDIRFIELDTBLS を設定してから、論理式をコンパイルする関数を使用してください。論理式で使用できるフィールド型は、FML フィールドで使用できる型と同じです。つまり、short 型、long 型、float 型、double 型、char 型、string 型、および carray 型を使用できます。フィールド型は、フィールド名と共にフィールド テーブルに格納されています。したがって、フィールド型は常に判別できます。

VIEW を評価するため、論理式で参照されるフィールドは、対応するフィールド化バッファ名ではなく、C 構造体の要素名として VIEW に存在していなければなりません。したがって、「FML および VIEWS の環境設定」で説明したように、環境変数の VIEWDIRVIEWFILES を設定してから、論理式をコンパイルする関数を使用してください。論理式で使用できるフィールド型は、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 型のいずれかです。型変換の説明を参照してください。

かっこで囲んだ式は、型と値が、かっこで囲まない場合の式の型と値に等しい基本式です。かっこを使用すると、演算子の優先順位を変更できます。次の節を参照してください。

論理式の演算子

次の表は、論理式の演算子を優先順位の高いものから順に示しています。

表 5-6 論理式の演算子
演算子
単項
+, -, !, ~
倍数
*, /, %
加法
+, -
比較
< , >, <=, >=, ==, !=
等価、一致
==, !=, %%, !%
排他論理和
^
論理積
&&
論理和
||

同じ演算子型に分類される演算子は、優先順位が同じです。次の節では、各演算子を詳しく説明します。C 言語では、かっこを使用して、演算子の優先順位をオーバーライドできます。

論理式で使用される単項演算子

以下の単項演算子が認識されます。

単項演算子を含む式は、右から左にグループ化されます。

+ expression
- expression
~ expression
! expression

単項プラス演算子は、オペランドに有効ではありません。認識はされても、無視されます。単項マイナス演算子の結果は、そのオペランドの否定です。通常の算術変換が実行されます。符号なしのものは、FML には存在しないので、この演算子には問題がありません。

論理否定演算子の結果は、オペランドの値が 0 の場合は 1 であり、オペランドの値が 0 以外の場合は 0 となります。結果は long 型になります。

補数演算子の結果は、オペランドの補数です。結果は long 型になります。

論理式で使用される倍数演算子

倍数に関する演算子の */% は、左から右にグループ化されます。通常の算術変換が実行されます。

expression * expression
expression
/ expression
expression
% expression

2 項演算子 * は、乗算を示します。* 演算子は、連想型であり、同一レベルで数回の乗算を行う式は、コンパイラで再配置できます。

2 項演算子 / は、除算を示します。正の整数が除算されると、切り捨ては 0 に向かって行われますが、オペランドのいずれかが負の場合は、切り捨ての形式は、マシンによって異なります。

2 項演算子 % は、最初の式を次の式で除算した結果の剰余を返します。通常の算術変換が実行されます。オペランドには、float 型や double 型を使用してはなりません。

論理式で使用される加法演算子

加法に関する演算子の +- は、左から右にグループ化されます。通常の算術変換が実行されます。

expression + expression
expression
- expression

+ 演算子は、オペランドの和を返します。+ 演算子は連想型であり、同一レベルで数回の加算を行う式は、コンパイラで再配置できます。オペランドが両方とも string である必要はありません。一方のオペランドが string 文字列の場合、そのオペランドはもう一方のオペランドの算術型に変換されます。

- 演算子は、オペランドの差を返します。通常の算術変換が実行されます。オペランドが両方とも string である必要はありません。一方のオペランドが string 文字列の場合、そのオペランドはもう一方のオペランドの算術型に変換されます。

論理式で使用される等価、一致に関する演算子

この型の演算子は、左から右にグループ化されます。

expression == expression
expression
!= expression
expression
%% expression
expression
!% expression

== (等価)、!= (非等価) の各演算子は、指定された関係が false の場合は 0 を返し、true の場合は 1 を返します。結果は long 型になります。通常の算術変換が実行されます。

%% 演算子の場合は、2 つ目の式は、最初の式と照合するために使用する正規表現です。2 つ目の式 (正規表現) は、引用符で囲まれた文字列でなければなりません。最初の式は、FML フィールド名であっても、引用符で囲まれた文字列であってもかまいません。この演算子は、最初の式が 2 つ目の式 (正規表現) と完全に一致する場合は、1 を返し、それ以外は 0 を返します。

!% 演算子は、正規表現との不一致を検出する演算子です。この演算子は、%% 演算子と同じオペランドをとりますが、まったく反対の結果を生じます。%%!% の関係は、==!= の関係と同じです。

使用可能な正規表現については、『Oracle Tuxedo C リファレンス』の「tpsubscribe(3c)」リファレンス ページを参照してください。

論理式で使用される関係演算子

この型の演算子は、左から右にグループ化されます。

expression < expression
expression
> expression
expression
<= expression
expression
>= expression

< (より小さい)、> (より大きい)、<= (以下)、>= (以上) の各演算子は、指定された関係が 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 および Fvboolco

Fboolco は、論理式をコンパイルし、評価ツリーに対するポインタを返します。

char *
Fboolco(char *expression)

*expression はコンパイル対象の式に対するポインタです。FLD_PTRFLD_FML32、または FLD_VIEW32 のフィールド タイプが使用されると、この関数は異常終了します。これらのフィールド タイプの 1 つが指定されると、FerrorFEBADOP が設定されます。

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 および Fvboolpr

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)」を参照してください。

Fboolev と Ffloatev、および Fvboolev と Fvfloatev

これらの関数は、両方とも、フィールド化バッファと照合して論理式を評価します。

int Fboolev(FBFR *fbfr,char *tree)
double Ffloatev(FBFR *
fbfr,char *tree)

以下はパラメータの説明です。

同等の VIEW の関数を以下に示します。

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 の変換

VIEW を、指定したレコード形式に変換したり、その逆の処理を行うことができます。デフォルトでは、IBM System/370 COBOL レコード形式に変換されます。

Fvstot、Fvftos、および Fcodeset

以下の関数は、指定した形式に VIEW を変換します。

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 バッファを、指定したレコードに変換するには、次の手順に従います。

  1. Fvftos を呼び出して FML バッファを C 構造体に変換します。
  2. Fvstot を呼び出して指定レコードに変換します。

指定レコードを、FML バッファに変換するには、次の手順に従います。

  1. Fvttos を呼び出して C 構造体に変換します。
  2. Fvstof を呼び出してその構造体を 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)」を参照してください。


  ページの先頭       前  次