この章では、「フィールドの定義と使用」で説明した実行時のマッピング関数を除く、すべてのFML関数およびFML VIEWS関数について説明します。
COBOLプログラムでは、FML関数を直接使用できません。まず、FINIT
というプロシージャを使用して、FMLデータを受信するためにレコードを初期化し、次にFVSTOF
およびFVFTOS
のプロシージャを使用してCOBOLレコードとFMLバッファ間の変換を行います。これらのプロシージャの詳細は、『COBOLを使用したOracle Tuxedo ATMIアプリケーションのプログラミング』を参照してください。ここでは、COBOLインタフェースについては説明しません。
FMLは、2種類あります。従来のFMLインタフェースは、フィールド長に16ビットの値を使用し、フィールドを識別する情報を格納します。したがって、FML16と呼ばれます。FML16では、一意のフィールド数は8191、個々のフィールド長は最大64Kバイト、フィールド化バッファの総容量は64Kに制限されます。このインタフェースの定義、型、および関数のプロトタイプはfml.h
に定義され、FML16インタフェースを使用するアプリケーション・プログラムは、このファイルをインクルードする必要があります。各関数は、-lfml
にあります。
FML32は、フィールド長と識別子に32ビットの値を使用します。約3千万のフィールド、約20億バイトのフィールド長およびバッファ長が使用できます。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バッファおよびFLD_PTR
フィールドによって参照される埋込みVIEWまたはバッファ用に領域が割り当てられます。新しいFMLバッファへのポインタがユーザー作成コードに渡されます。サーバー処理の完了時には、メッセージの受信時に割り当てられたすべてのバッファを破棄する必要があります。Oracle Tuxedoでは、FMLバッファおよびすべての従属バッファがチェックされ、参照が検出されるとバッファが削除されます。サーバー・コードを作成するプログラマは、次の状況を認識しておく必要があります。
tpreturn()
に渡されたFMLバッファは解放されますが、FLD_PTR
フィールドまたはFLD_VIEW32
フィールドによって参照されるバッファは解放されません。この項では、フィールド化バッファの領域を確保するための関数について説明します。まず、指定されたバッファがフィールド化バッファであるかどうかを判別するための関数を説明します。
Fielded
(またはFielded32
)を使用すると、指定されたバッファがフィールド化されているかどうかをテストできます。
int
Fielded(FBFR *fbfr
)
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"); /* no space to allocate buffer */
ただし、このコードで割り当てられたメモリー領域は、まだフィールド化バッファではありません。この領域は、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
)
前述の例で割り当てたメモリー領域を初期化するために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”); /* couldn't allocate buffer */
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"); /* not fielded buffer */
free
(3)よりFfree
の使用をお勧めします。free
(3)ではフィールド化バッファを無効にできませんが、Ffree
を使用するとフィールド化バッファを無効にできます。フィールド化バッファの無効化が必要なのは、malloc
(3)が解放されたメモリーをクリアせずに再利用するためです。free
(3)を使用すると、malloc
が無効化されていないフィールド化バッファを戻す可能性があります。
フィールド化バッファの領域を直接確保することもできます。フィールド化バッファは、short
型境界に調整させて開始する必要があります。バッファには、少なくともF_OVHD
分のバイト(fml.h
で定義)を割り当てる必要があります。割り当てないと、Finit
からエラーが返されます。
以下のコードは、前の項の例と似ていますが、Fneeded
はマクロではないため、静的バッファのサイズ指定には使用できません。
/* the first line aligns the buffer */
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”); /* couldn't re-allocate space */
else
fbfr = newfbfr; /* assign new pointer to old */
この例では、アプリケーション側で、すでに割り当てられたフィールド数と値の領域のバイト数を認識している必要があります。Frealloc
の引数(および対応するrealloc
(3))は絶対値であり、インクリメント値ではありません。領域の割当てを複数回行う必要がある場合、このサンプル・コードは正しく動作しません。
以下の例では、割り当てられた領域をインクリメントする別の方法を示します。
/* define the increment size when buffer out of space */
#define INCR 400
FBFR *newfbfr;
. . .
if((newfbfr = Frealloc(fbfr, 0, Fsizeof(fbfr)+INCR)) == NULL)
F_error(“pgm_name”); /* couldn't re-allocate space */
else
fbfr = newfbfr; /* assign new pointer to old */
この例では、バッファが最後に初期化されたときのフィールド数や値の領域のサイズを知っておく必要はありません。したがって、サイズを増やす最も簡単な方法は、現在のサイズにインクリメント値を加えたサイズを値の領域として使用することです。上の例は、必要に応じて何回でも実行することができます。過去の実行内容や値を覚えておく必要はありません。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; /* flags - currently unused */
char vname[FVIEWNAMESIZE+1]; /* name of view */
char *data; /* pointer to view structure */
} 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; /* flags - currently unused */
char vname[FVIEWNAMESIZE+1]; /* name of view */
char *data; /* pointer to view structure */
} 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)」を参照してください。
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"); /* field not present */
フィールドが検出されなかった場合は-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; /* field id for field A */
fieldid[1] = D; /* field id for field D */
fieldid[2] = BADFLDID; /* sentinel value */
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; /* flags - currently unused */
char vname[FVIEWNAMESIZE+1]; /* name of view */
char *data; /* pointer to view structure */
} 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)) {
/* code for each field occurrence */
}
詳細は、『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");
前述の例で使用した入力バッファを使用すると、ソース・フィールド値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
の場合のように、この関数は、領域の不足のために失敗する場合があり(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; /* field id for field A */
fieldid[1] = D; /* field id for field D */
fieldid[2] = BADFLDID; /* sentinel value */
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; /* flags - currently unused */
char vname[FVIEWNAMESIZE+1]; /* name of view */
char *data; /* pointer to view structure */
} FVIEWFLD;
詳細は、『Oracle Tuxedo FMLリファレンス』のFupdate、Fupdate32(3fml)に関する項を参照してください。
この関数は、指定された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"); /* initialize 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)」を参照してください。
この関数は、指定された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)」を参照してください。
この関数は、適切な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)」を参照してください。
この関数は、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
と同様に変換を行います。異なる点は、変換された値がユーザー提供のバッファにコピーされることです。
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
の型
と0のlen
を提供します。ただし、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; /* fielded buffer */
FLDID fieldid; /* field to be changed */
FLDOCC oc; /* occurrence of field to be changed */
char *value; /* location of new value */
FLDLEN len; /* length of new value */
int type; /* type of new value */
{
char *convloc; /* location of post-conversion value */
FLDLEN convlen; /* length of post-conversion value */
extern char *Ftypcvt;
/* convert value to fielded buffer type */
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)
*((char *)newval) = *((short *)oldval)
char
は、NULL文字を追加することによってstring
に変換されます。この場合のchar
は、「より短いshort
」ではありません。もしそうであれば、それをshort
に変換し、次にsprintf
を介してshort
をstring
に変換することで、割当てが行われます。同じ意味で、string
は、string
の最初の文字をその文字に割り当てることにより、char
に変換されます。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
で初期化すると、自動的に索引が設定されます。この索引により、フィールド化バッファへのアクセスが促進されますが、プログラマ側からは索引処理が見えません。フィールド化バッファにフィールドを追加したり、削除すると、索引が自動的に更新されます。
ただし、記憶装置に長期に渡ってフィールド化バッファを格納したり、協調動作するプロセス間でフィールド化バッファを転送する場合は、フィールド化バッファの受信時に、索引を削除したり、再生成して領域を節約できます。ここで説明する関数は、このような索引操作を実行します。
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のフィールドの値であるようなブール式を評価する関数について説明します。これらの関数を使用すると、以下の処理を行うことができます。
式を効率的な評価に適した簡潔な形式にコンパイルする関数が使用されます。2番目の関数により、コンパイルされた形式がフィールド化バッファと照合して評価され、trueまたはfalseの結果が返されます。
ここでは、ブール式のコンパイル用関数で受け付ける式と、式の評価方法を詳しく説明します。
論理式で許可される変数は、フィールド参照のみです。フィールド名の指定方法には、いくつかの規則があります。たとえば、フィールド名は、英字と数字で構成し、先頭には英字を指定しなければなりません。アンダースコア(_
)は、英字と見なされます。長い変数名をアンダースコアで区切り、読みやすい名前に変えることができます。フィールド名には、最大30文字を指定できます。予約語はありません。
フィールド化バッファを評価するため、論理式で参照されるフィールドは、フィールド表に存在していなければなりません。したがって、「FMLおよびVIEWSの環境設定」
で説明したように、環境変数のFLDTBLDIR
とFIELDTBLSを設定してから、論理式をコンパイルする関数を使用してください。論理式で使用できるフィールド型は、FMLフィールドで使用できる型と同じです。つまり、short
型、long
型、float
型、double
型、char
型、string
型、およびcarray
型を使用できます。フィールド型は、フィールド名と共にフィールド表に格納されています。したがって、フィールド型は常に判別できます。
VIEWを評価するため、ブール式で参照されるフィールドは、関連付けられたフィールド化バッファ名ではなく、VIEW内にC構造体要素名として存在していなければなりません。したがって、「FMLおよびVIEWSの環境設定」で説明したように、環境変数のVIEWDIR
とVIEWFILES
を設定してから、ブール式をコンパイルする関数を使用してください。ブール式で使用できるフィールド型は、FMLフィールドで使用できる型と同じで、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でない場合、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配列の最初の文字は、最下位バイトを形成します。次の文字は、最上位バイトを形成します。それぞれ、全体の配列の長さをバイト数で指定する符号なし型(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)
上記でコンパイルされた式で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)」を参照してください。