あるプロセスから別のプロセスにメッセージを送信する場合、メッセージ・データ用のバッファを割り当てておく必要があります。Oracle Tuxedo ATMIクライアントは、型付きバッファを使用してATMIサーバーにメッセージを送ります。型付きバッファとは、カテゴリ(タイプ)と、サブカテゴリ(サブタイプ)が定義されたメモリー領域です。型付きバッファは、Oracle Tuxedoシステムでサポートされる分散プログラミング環境の基本要素の1つです。
なぜ
型付きレコードを使用するのでしょうか。分散環境では、アプリケーションが異機種システムにインストールされ、異なるプロトコルを使用して複数のネットワーク間で通信が行われます。バッファ・タイプが異なると、初期化、メッセージの送受信、およびデータのエンコード/デコードにそれぞれ別のルーチンが必要になります。各バッファに特定のタイプが割り当てられていると、プログラマが介在しなくても、そのタイプに対応するルーチンを自動的に呼び出すことができます。
表2-1は、Oracle Tuxedoシステムでサポートされる型付きバッファと、そのバッファが次の条件を満たしているかどうかを示しています。
•
|
自己記述型であるかどうか。 つまり、バッファのデータ型と長さが、タイプとサブタイプ、およびそのデータからわかるかどうか。
|
•
|
型付きバッファのデータ依存型ルーティングがシステムでサポートされているかどうか。
|
•
|
型付きバッファのエンコード/デコードがシステムでサポートされているかどうか。
|
ルーティング関数が必要な場合は、アプリケーション・プログラマが用意します。
|
|
|
|
|
|
|
未定義の文字配列。NULL文字を含むことができます。Oracle Tuxedoシステムでは配列のセマンティクスは解釈されないので、この型付きバッファは曖昧なデータを処理する場合に使用します。CARRAYは自己記述型ではないので、転送時には長さを指定する必要があります。システムではバイトは解釈されないので、マシン間のメッセージ送信ではエンコード/デコードはサポートされません。
|
|
|
|
|
|
Oracle Tuxedoシステム固有の自己記述型バッファ・タイプ。このバッファでは、各データ・フィールドに対応する識別子、オカレンス番号、場合によっては長さを示す値が格納されています。データ操作はすべて、ネイティブなC言語の文ではなくFML関数を使用して行われます。このため、処理に多少のオーバーヘッドが生じてでも、FMLバッファを通じて、データの独立性と動作の柔軟性が確保されるようになっています。
FMLバッファでは、フィールド識別子とフィールド長に16ビットが使用されます。
FMLバッファの詳細は、 2-27ページの「FML型バッファの使用」を参照してください。
|
|
|
|
|
|
FMLと同じ。ただし、フィールド識別子とフィールド長に32ビットが使用されます。より長いフィールドを多数使用できるので、バッファ全体が大きくなります。
FML32バッファの詳細は、 2-27ページの「FML型バッファの使用」を参照してください。
|
|
|
|
|
|
最後がNULL文字で終了する文字配列。STRINGバッファは、自己記述型です。そのため、異なる文字セットを使用するマシン間でデータを交換する場合は、Oracle Tuxedoシステムによってデータが自動的に変換されます。
|
|
|
|
|
|
アプリケーションで定義されるC構造体。VIEW型には、個々のデータ構造体を示すサブタイプが必要です。 VIEW記述ファイル(データ構造体のフィールドとタイプが定義されたファイル)は、VIEW型バッファに定義されたデータ構造体を使用するクライアント・プロセスとサーバー・プロセスがアクセスできなければなりません。異なるタイプのマシン間でバッファがやり取りされる場合は、エンコード/デコードが自動的に行われます。
VIEWは、mbstring型バッファをサポートしていません。
VIEWバッファの詳細は、 2-19ページの「VIEW型バッファの使用」を参照してください。
|
|
|
|
|
|
VIEWと同じ。ただし、長さとカウントのフィールド長に32ビットが使用されます。より長いフィールドを多数使用できるので、バッファ全体が大きくなります。
VIEW32は、mbstring型バッファをサポートしており、carrayと同じ方法でmbstringデータを処理します。
VIEW32バッファの詳細は、 2-19ページの「VIEW型バッファの使用」を参照してください。
|
|
|
|
|
|
|
|
|
|
|
|
VIEWと同じ。ただし、このバッファ型はCOBOLとCプログラム間の互換性を取るために使用されます。フィールド・タイプとして使用できるのは、short、long、およびstringだけです。
|
|
|
|
|
|
•
|
ドキュメントの論理構造の記述と、その構造に関する情報
|
XML文書のルーティングは、要素の内容、または要素タイプと属性値に基づいて行われます。使用されている文字エンコードはXMLパーサーによって判別されます(Oracle Tuxedo 9.xでは、XMLパーサーとしてApache Xerces C++バージョン2.5パーサーが使用可能)。エンコードがOracle Tuxedoの構成ファイル( UBBCONFIG(5)と DMCONFIG(5))で使用されているネイティブな文字セット(US-ASCIIまたはEBCDIC)と異なる場合、要素と属性名はUS-ASCIIまたはEBCDICに変換されます。
|
|
|
|
|
|
|
|
|
|
|
|
Oracle Tuxedo 8.1で使用可能になったマルチバイト文字の文字配列。MBSTRINGバッファの詳細は、 2-45ページの「MBSTRING型バッファの使用」を参照してください。
|
|
|
|
|
|
アプリケーションで定義されるCOBOLコピーブック・レコード。RECORD型には、レコード構造体を示すサブタイプが必要です。レコード構造体のフィールドと型が定義されたRECORD記述ファイルは、RECORD型バッファに記述されたレコード構造体を使用するクライアント・プロセスとサーバー・プロセスで使用できる必要があります。RECORDバッファの詳細は、 「RECORD型バッファの使用」を参照してください。
|
|
|
|
|
すべてのバッファ・タイプは、
$TUXDIR/libディレクトリの
tmtypesw.cファイルに定義されています。クライアント・プログラムとサーバー・プログラムで認識されるバッファ・タイプは、
tmtypesw.cに定義されているものだけです。
tmtypesw.cファイルを編集して、バッファ・タイプを追加したり削除できます。また、
UBBCONFIGの
BUFTYPEパラメータを使用して、特定のサービスで処理できるタイプとサブタイプを制限できます。
tmtypesw.cファイルは、共有オブジェクトや動的リンク・ライブラリのビルドに使用されます。このオブジェクトは、Oracle Tuxedo管理サーバー、およびアプリケーション・クライアントとアプリケーション・サーバーによって動的にロードされます。
初期状態では、バッファはクライアント・プロセスに関連付けられていません。クライアント・プロセスでメッセージを送信する場合、サポートされているタイプのバッファを割り当てて、メッセージを格納できるようにします。型付きバッファを割り当てるには、次に示すように
tpacall(3c)関数を使用します。
char*
tpalloc(char *type, char *subtype, long size)
表2-2は、
tpalloc()関数の引数を示しています。
|
|
|
|
|
VIEW記述ファイルで VIEW、 VIEW32、 X_COMMONまたは RECORD型バッファに指定されているサブタイプの名前を指すポインタ。
subtypeがない場合、この引数にはNULL値が使用されます。
|
|
Oracle Tuxedoシステムにより、 CARRAY、 X_OCTET、および XMLを除くすべての型付きバッファに、自動的にデフォルトのバッファ・サイズが割り当てられます。自動的にバッファ・サイズが割り当てられないバッファ型には、バッファの終わりを識別できるようにサイズを指定する必要があります。
CARRAY、 X_OCTET、および XMLを除くすべての型付きバッファのサイズにゼロが指定されると、各型付きバッファに割り当てられているデフォルト値が使用されます。サイズが指定されている場合、指定されたサイズまたはそのバッファ型に割り当てられているデフォルト値のうちの大きい方が使用されます。
STRING、 CARRAY、 X_OCTET、および XMLを除くすべての型付きバッファのデフォルト・サイズは1024バイトです。 STRING型バッファのデフォルト・サイズは512バイトです。 CARRAY、 X_OCTET、および XMLにデフォルト値はありません。これらの型付きバッファには、 ゼロより大きな値を指定する必要があります。サイズが指定されていない場合、引数にはデフォルト値の0が使用されます。その結果、 tpalloc()関数はNULLポインタを返して、 tperrnoに TPEINVALを設定します。
|
リスト2-1で示すように、
VIEW、
VIEW32、
X_C_TYPEおよび
X_COMMON型バッファには
subtype引数が必要です。
struct aud *audv; /* pointer to aud view structure */
. . .
audv = (struct aud *) tpalloc("VIEW", "aud", sizeof(struct aud));
. . .
リスト2-2は、FML型バッファの割当て方法を示しています。
subtype引数にNULL値が指定されていることに注目してください。
FBFR *fbfr; /* pointer to an FML buffer structure */
. . .
fbfr = (FBFR *)tpalloc("FML", NULL, Fneeded(f, v))
. . .
リスト2-3は、
CARRAY型バッファの割当て方法を示しています(このバッファ型では、
size値を指定する必要があります)。
char *cptr;
long casize;
. . .
casize = 1024;
cptr = tpalloc("CARRAY", NULL, casize);
. . .
処理が正常に終了すると、
tpalloc()関数は
char型のポインタを返します。
STRINGと
CARRAY以外のタイプでは、ポインタを適切なC構造体またはFMLポインタにキャストする必要があります。
tpalloc()関数は、エラーを検出するとNULLポインタを返します。次は、エラー条件の例です。
•
|
CARRAY、 X_OCTET、または XML型バッファの size値が指定されていません。
|
•
|
type、または VIEWの場合に、 subtypeが指定されていません。
|
•
|
システムで認識されない値が typeに指定されています。
|
•
|
割当てを行う前に、アプリケーションに参加できませんでした。
|
全エラー・コードとその説明については、
『Oracle Tuxedo ATMI C言語関数リファレンス』の
「tpalloc(3c)」を参照してください。
リスト2-4は、
STRING型バッファの割当て方法を示しています。この例では、
tpalloc()の
size引数の値として、関連するデフォルト・サイズが使用されています。
char *cptr;
. . .
cptr = tpalloc("STRING", NULL, 0);
. . .
リスト2-5は、RECORD型バッファの割当て方法を示しています。この例では、サイズは
Frneeded()から取得されます。RECORD型バッファには、サブタイプ引数が必要です。
struct RECORD *rec; /* pointer to an RECORD buffer structure */
rec = (struct RECORD *)tpalloc("RECORD", "CUSTOMER", Frneeded("CUSTOMER"));
バッファを割り当てると、そこにデータを格納できるようになります。
リスト2-6では、3つのメンバー(フィールド)を持つ
VIEW型バッファ
audを作成しています。3つのメンバーは、コマンド行がある場合は、そこから取得される支店識別子の
b_id、照会された残高を戻す
balance、およびユーザーのステータス行にメッセージを戻す
ermsgです。
auditを使用して特定の支店の残高が照会されると、
b_idメンバーの値には照会の送信先の支店識別子、
balanceメンバーにはゼロ、
ermsgメンバーにはNULL文字列がそれぞれ設定されます。
リスト2-6
メッセージ・バッファへのデータの格納 - 例1
...
audv = (struct aud *)tpalloc("VIEW", "aud", sizeof(struct aud));
/* Prepare aud structure */
audv->b_id = q_branchid;
audv->balance = 0.0;
(void)strcpy(audv->ermsg, "");
...
auditを使用して銀行全体の残高が照会されると、
BALサーバーが呼び出されてサイトごとの残高合計が取得されます。個々のサイトで照会を行うには、代表支店識別子を指定します。代表支店IDは、配列
sitelist[]に格納されます。したがって、
aud構造体は、
リスト2-7のように設定されます。
リスト2-7
メッセージ・バッファへのデータの格納 - 例2
...
/* Prepare aud structure */
audv->b_id = sitelist[i];/* routing done on this field */
audv->balance = 0.0;
(void)strcpy(audv->ermsg, "");
...
•
|
『Oracle Tuxedo ATMI C言語関数リファレンス』の「tpalloc(3c)」
|
tpalloc()で割り当てられたバッファのサイズを変更するには、次のように
tprealloc(3c)関数を使用します。
char*
tprealloc(char *
ptr, long
size)
表2-3は、
tprealloc()関数の引数を示しています。
|
|
|
サイズを変更するバッファを指すポインタ。このポインタは、 tpalloc()の呼出しで設定されます。それ以外の方法で設定されている場合、呼出しは失敗し、 tperrno(5)が TPEINVALに設定されて、無効な引数がこの関数に渡されたことが示されます。
|
|
変更後のバッファ・サイズを指定する長精度型(long)。
|
tprealloc()が返すポインタは、元のバッファと同じタイプのバッファを指します。バッファの場所が変わっている場合があるので、返されたポインタを使用してサイズが変更されたバッファを参照します。
バッファのサイズを増やすために
tprealloc()関数を呼び出すと、バッファに新しい領域が割り当てられます。バッファのサイズを減らすために
tprealloc()関数を呼び出すと、実際にバッファのサイズが変更されるのでなく、指定されたサイズを超える領域が使用不能になります。型付きバッファの内容には影響しません。未使用領域を解放するには、必要なサイズを持つ別のバッファにデータをコピーし、
未使用領域を持つバッファを解放します。
tprealloc()関数は、エラーが発生するとNULLポインタを返し、
tperrnoに適切な値を設定します。エラー・コードについては、
『Oracle Tuxedo ATMI C言語関数リファレンス』の
「tpalloc(3c)」を参照してください。
警告:
|
tprealloc()関数がNULLポインタを返した場合、内容が変更されて有効ではなくなったバッファが渡された可能性があります。
|
リスト2-8は、
STRINGバッファの領域を再度割り当てる方法を示しています。
#include <stdio.h>
#include ���atmi.h���
char instr[100]; /* string to capture stdin input strings */
long s1len, s2len; /* string 1 and string 2 lengths */
char *s1ptr, *s2ptr; /* string 1 and string 2 pointers */
main
()
{
(void)gets(instr); /* get line from stdin */
s1len = (long)strlen(instr)+1; /* determine its length */
join application
if ((s1ptr = tpalloc(���STRING���, NULL, s1len)) == NULL) {
fprintf(stderr, ���tpalloc failed for echo of: %s\n���, instr);
leave application
exit(1);
}
(void)strcpy(s1ptr, instr);
make communication call with buffer pointed to by s1ptr
(void)gets(instr); /* get another line from stdin */
s2len = (long)strlen(instr)+1; /* determine its length */
if ((s2ptr = tprealloc(s1ptr, s2len)) == NULL) {
fprintf(stderr, ���tprealloc failed for echo of: %s\n���, instr);
free s1ptr's buffer
leave application
exit(1);
}
(void)strcpy(s2ptr, instr);
make communication call with buffer pointed to by s2ptr
. . .
}
リスト2-9は前述の例を拡張したもので、発生する可能性があるすべてのエラー・コードを確認する方法を示しています。
リスト2-9
tprealloc()のエラーの確認
. . .
if ((s2ptr=tprealloc(s1ptr, s2len)) == NULL)
switch(tperrno) {
case TPEINVAL:
fprintf(stderr, "given invalid arguments\n");
fprintf(stderr, "will do tpalloc instead\n");
tpfree(s1ptr);
if ((s2ptr=tpalloc("STRING", NULL, s2len)) == NULL) {
fprintf(stderr, "tpalloc failed for echo of: %s\n", instr);
leave application
exit(1);
}
break;
case TPEPROTO:
fprintf(stderr, "tried to tprealloc before tpinit;\n");
fprintf(stderr, "program error; contact product support\n");
leave application
exit(1);
case TPESYSTEM:
fprintf(stderr,
"BEA Tuxedo error occurred; consult today's userlog file\n");
leave application
exit(1);
case TPEOS:
fprintf(stderr, "Operating System error %d occurred\n",Uunixerr);
leave application
exit(1);
default:
fprintf(stderr,
"Error from tpalloc: %s\n", tpstrerror(tperrno));
break;
}
tptypes(3c)関数は、バッファのタイプとサブタイプ(指定されている場合)を返します。次は
tptypes()関数のシグネチャです。
long
tptypes(char *
ptr, char *
type, char *
subtype)
表2-4は、
tptypes()関数の引数を示しています。
|
|
|
データ・バッファを指すポインタ。このポインタは、 tpalloc()または tprealloc()の呼出しで設定されます。NULLは指定できません。また、文字型にキャストする必要があります。この2つの条件が満たされていない場合、 tptypes()関数は引数が無効であることを示すエラーを返します。
|
|
データ・バッファのタイプを指すポインタ。 typeは文字型の値です。
|
|
データ・バッファのサブタイプ(指定されている場合)を指すポインタ。 subtypeは文字型の値です。 VIEW、 VIEW32、 RECORD、 X_C_TYPE、および X_COMMON以外のタイプの場合、返された subtypeパラメータはNULL文字列を含む文字配列を指します。
注意:
|
RECORD型バッファの場合、レコード名の最大長( subtype)は32バイトです。レコード名の長さが16バイトより長い場合、 tptypes()ではサブタイプの最初の16バイトが移入されますが、 RECORD *ポインタはレコード名全体の先頭を指します。
|
|
処理が正常に終了した場合、
tptypes()関数は長精度型(long)でバッファの長さを返します。
エラーが発生した場合、
tptypes()は
-1を戻し、
tperrno(5)に対応するエラー・コードを設定します。エラー・コードのリストについては、
『Oracle Tuxedo ATMI C言語関数リファレンス』の
C言語アプリケーション・トランザクション・モニター・インタフェースの紹介および
tpalloc(3c)に関する項を参照してください。
リスト2-10に示すように、処理の正常終了時に
tptypes()から戻されたサイズ値を使用して、デフォルトのバッファ・サイズがデータを格納するのに十分な大きさかどうかを確認できます。
. . .
iptr = (FBFR *)tpalloc("FML", NULL, 0);
ilen = tptypes(iptr, NULL, NULL);
. . .
if (ilen < mydatasize)
iptr=tprealloc(iptr, mydatasize);
•
|
『Oracle Tuxedo ATMI C言語関数リファレンス』の 「tptypes(3c)」
|
tpfree()関数の引数は、
リスト2-5に示す
ptrだけです。
|
|
|
データ・バッファを指すポインタ。このポインタは、 tpalloc()または tprealloc()の呼出しで設定されます。NULLは指定できません。また、文字型にキャストする必要があります。この2つの条件が満たされていない場合、この関数は何も解放しないか、エラー条件を通知しないで制御を戻します。
|
tpfree()を使用して
FML32バッファを解放するとき、ルーチンは埋め込まれたバッファをすべて再帰的に解放して、メモリー・リークの発生を防ぎます。埋め込みバッファが解放されないようにするには、対応するポインタにNULLを指定してから
tpfree()ルーチンを発行します。
ptrがNULLの場合、何も処理は行われません。
リスト2-11は、
tpfree()関数を使用してバッファを解放する方法を示しています。
struct aud *audv; /* pointer to aud view structure */
. . .
audv = (struct aud *)tpalloc("VIEW", "aud", sizeof(struct aud));
. . .
tpfree((char *)audv);
•
|
『Oracle Tuxedo ATMI C言語関数リファレンス』の 「tpfree(3c)」
|
VIEW型バッファには2種類あります。1つは
FML VIEWで、
FMLバッファから生成されるC構造体です。もう1つは、単なる非依存型のC構造体です。
FMLバッファをC構造体に変換して再び元に戻す(
FML VIEW型バッファを使用する)のは、
FML型バッファでの処理にはオーバーヘッドが生じるからです。つまりFML型バッファには、データの独立性と操作の利便性がある一方で、
FML関数を呼び出すためのオーバーヘッドが発生します。C構造体は、柔軟性の点では劣りますが、バッファ・データの時間がかかる処理に適しています。大量のデータを操作する場合、フィールド化バッファのデータをC構造体に転送し、通常のC関数を使用してそのデータを処理し、格納やメッセージ転送を行うためにそのデータをFML型バッファに戻すと、パフォーマンスを向上させることができます。
FML型バッファと
FMLファイルの変換の詳細は、『Oracle Tuxedo ATMI FML関数リファレンス』を参照してください。
VIEW型バッファを使用するには、次の手順に従います。
アプリケーションで
VIEW型バッファを使用するには、
表2-6の環境変数を設定します。
|
|
|
FMLまたは FML32型バッファのフィールド表ファイル名のカンマ区切りのリスト。 FML VIEW型のみで必要です。
|
|
FMLまたは FML32型バッファのフィールド表ファイルが検索されるディレクトリのコロン区切りのリスト。Microsoft Windowsでは、セミコロンで区切られます。 FML VIEW型のみで必要です。
|
|
VIEWまたは VIEW32記述ファイルに使用されるファイル名 のカンマ区切りのリスト。
|
|
VIEWまたは VIEW32ファイルが検索されるディレクトリのコロン区切りのリスト。Microsoft Windowsでは、セミコロンで区切られます。
|
VIEW型バッファを使用するには、VIEW記述ファイルにC言語のレコードを定義する必要があります。VIEW記述ファイルには、各エントリのVIEW、およびC構造体のマッピングと
FML変換パターンを記述したVIEWが定義されています。VIEWの名前は、C言語の構造体の名前に対応します。
VIEW記述ファイルの各構造体は、次の形式で定義します。
$ /* VIEW構造体*/
VIEW viewname
type cname fbname count flag size null
表2-7は、VIEW記述ファイルに指定する必要がある各C構造体のフィールドを示しています。
|
|
|
フィールドのデータ型。 short、 long、 float、 double、 char、 string、または carrayを指定できます。
注意:
|
mbstringデータ型は、 VIEW32型付きバッファのみでサポートされます。
|
|
|
|
|
FMLから VIEW、または VIEWから FMLへの変換関数を使用する場合、対応する FML名をこのフィールドに指定する必要があります。このフィールド名は、FML フィールド表ファイルにも必要です。 FMLに依存しない VIEWには必要ありません。
|
|
|
|
•
|
S - フィールド化バッファから構造体に一方向のマッピングを行います。
|
•
|
F - 構造体からフィールド化バッファへの一方向マッピングを行います。
|
•
|
C - 連想カウント・メンバー(ACM)に追加フィールドを生成します。
|
•
|
L - STRING、 CARRAY、および MBSTRINGに転送されるバイト数を保持します。
|
注意:
|
view32コマンドは、 MBSTRING型バッファの Lオプション・フラグを自動的に追加します。
|
|
|
STRINGまたは CARRAY型レコードの最大長を指定します。それ以外のバッファ・タイプでは、このフィールドは無視されます。
|
|
ユーザー定義のNULL値、または -の場合はフィールドのデフォルト値。 VIEW型バッファで使用されるNULL値は、空のC構造体を示します。
数値型の場合、デフォルトのNULL値は0 ( dec_tの場合は0.0)になります。文字型の場合、デフォルトのNULL値は \0になります。 STRING型、 CARRAY型、および MBSTRING型の場合、デフォルトのNULL値は “ "になります。
エスケープ文字として使用されている定数も、NULL値の指定に使用できます。VIEWコンパイラで認識されるエスケープ定数は、 \ddd ( dは8進数)、 \0、 \n、 \t、 \v、 \r、 \f、 \\、 \'、および \"です。
STRING、 CARRAY、 MBSTRING、および char型のNULL値は、二重引用符または一重引用符で囲みます。VIEWコンパイラでは、ユーザー定義のNULL値でエスケープされていない引用符は使用できません。
VIEWメンバー記述のNULLフィールドにキーワードNONEを指定することもできます。このキーワードは、そのメンバーのNULL値がないことを示します。文字列および文字配列メンバーの最大サイズのデフォルト値は2660文字です。詳細については、『Oracle Tuxedo ATMI FML関数リファレンス』を参照してください。
|
行頭に#または$文字を付けてコメント行を挿入できます。行頭に$が挿入されたコード行は、
.hファイルに出力されます。
リスト2-12は、
FMLバッファに基づくVIEW記述サンプル・ファイルの一部です。この場合は、
fbnameフィールドを指定する必要があり、この値は対応する
フィールド表ファイルの値と一致している必要があります。
CARRAY1フィールドのオカレンス・カウントが
2に設定されていること、
Cフラグが設定されて追加のカウント要素の作成が定義されていることに注目してください。また、
Lフラグが設定され、アプリケーションが
CARRAY1フィールドを格納するときの文字数を示す長さ要素が定義されています。
リスト2-12
FML VIEWのVIEW記述ファイル
$ /* View structure */
VIEW MYVIEW
#type cname fbname count flag size null
float float1 FLOAT1 1 - - 0.0
double double1 DOUBLE1 1 - - 0.0
long long1 LONG1 1 - - 0
short short1 SHORT1 1 - - 0
int int1 INT1 1 - - 0
dec_t dec1 DEC1 1 - 9,16 0
char char1 CHAR1 1 - - '\0'
string string1 STRING1 1 - 20 '\0'
carray carray1 CARRAY1 2 CL 20 '\0'
bool bool1 BOOL1 1 - - 0
signedchar signedchar1 SIGNEDCHAR1 1 - - 0
unsignedchar unsignedchar1 UNSIGNEDCHAR1 1 - - 0
wchar_t wchar_t1 WCHAR_T1 1 - - 0
unsignedint unsignedint1 UNSIGNEDINT1 1 - - 0
unsignedlong unsignedlong1 UNSIGNEDLONG1 1 - - 0
longlong longlong1 LONGLONG1 1 - - 0
unsignedlonglong unsignedlonglong1 UNSIGNEDLONGLONG1 1 - - 0
longdouble longdouble1 LONGDOUBLE1 1 - - 0
struct struct1 STRUCT1 1 - - 0
END
リスト2-13は、同じVIEW記述ファイルで非依存型
VIEWのものを示しています。
リスト2-13
非依存型VIEWのVIEW記述ファイル
$ /* View data structure */
VIEW MYVIEW
#type cname fbname count flag size null
float float1 - 1 - - -
double double1 - 1 - - -
long long1 - 1 - - -
short short1 - 1 - - -
int int1 - 1 - - -
dec_t dec1 - 1 - 9,16 -
char char1 - 1 - - -
string string1 - 1 - 20 -
carray carray1 - 2 CL 20 -
bool bool1
signedchar signedchar1
unsignedchar unsignedchar1
wchar_t wchar_t1
unsignedint unsignedint1
unsignedlong unsignedlong1
longlong
longlong1
unsignedlonglong unsignedlonglong1
longdouble longdouble1
struct struct1
END
この形式は
FML依存型VIEWと同じであることに注意してください。ただし、
fbnameフィールドと
nullフィールドには意味がなく、
viewcコンパイラで無視されます。これらのフィールドには、プレースホルダーとしてダッシュ(-)などの値を挿入する必要があります。
VIEW型バッファをコンパイルするには、引数としてVIEW記述ファイルの名前を指定して
viewcコマンドを実行します。非依存型
VIEWを指定するには、
-nオプションを使用します。生成される出力ファイルを書き込むディレクトリを指定することもできます(オプション)。デフォルトでは、出力ファイルはカレント・ディレクトリに書き込まれます。
たとえば、
FML依存型
VIEWをコンパイルするには、次のようにコンパイラを実行します。
注意:
|
VIEW32型バッファをコンパイルするには、 viewc32コマンドを実行します。
|
非依存型
VIEWの場合、コマンド行で次のように
-nオプションを指定します。
•
|
MYVIEW.cblなど、1つ以上のCOBOLの COPYファイル
|
•
|
アプリケーション・プログラムで使用される構造体定義が記述されたヘッダー・ファイル
|
•
|
myview.Vなど、バイナリ・バージョンのソース記述ファイル
|
注意:
|
Microsoft Windowsなど、大文字と小文字が区別されないプラットフォームでは、バイナリ・バージョンのソース記述ファイル名には、拡張子 vv ( myview.vvなど)が使用されます。
|
リスト2-14は、
viewcによって作成されるヘッダー・ファイルの例を示しています。
リスト2-14
VIEWコンパイラによって生成されるヘッダー・ファイル
struct MYVIEW {
float float1;
double double1;
long long1;
short short1;
int int1;
dec_t dec1;
char char1;
char string1[20];
unsigned short L_carray1[2]; /* length array of carray1 */
short C_carray1; /* count of carray1 */
char carray1[2][20];
bool bool1
signedchar signedchar1
unsignedchar unsignedchar1
wchar_t wchar_t1
unsignedint unsignedint1
unsignedlong unsignedlong1
longlong
longlong1
unsignedlonglong unsignedlonglong1
longdouble longdouble1
struct struct1
};
FML依存型とFML非依存型VIEWにも、同じヘッダー・ファイルが生成されます。
クライアント・プログラムまたはサービス・サブルーチンで
VIEW型バッファを使用するには、アプリケーションの
#include文にヘッダー・ファイルを指定する必要があります。
RECORD型バッファを使用するには、次の手順に従います。
アプリケーションで
RECORD型バッファを使用するには、次の環境変数を設定します。
|
|
|
RECORDファイルに使用されるファイル名のカンマ区切りのリスト。
|
|
RECORDファイルの検索先ディレクトリのコロン区切りのリスト。Microsoft Windowsでは、セミコロンで区切られます。
|
RECORD型バッファを使用するには、COBOLコピーブック・ファイルにレコードを定義する必要があります。コピーブック・ファイルには各エントリの
RECORDが含まれます。
RECORDの名前は、COBOL言語フィールドの名前に対応します。詳細は、COBOL言語リファレンスを参照してください。
COBOLコピーブック・ファイルの例の一部を次に示します。
02 BALANCE PIC S9(9) COMP-5.
RECORD記述ファイルを生成するには、
copybookファイルの名前を引数として指定して、
cpy2recordコマンドを実行します。生成される出力ファイルを書き込むディレクトリを指定することもできます(オプション)。デフォルトでは、出力ファイルはカレント・ディレクトリに書き込まれます。
cpy2recordコマンドの出力は、
abc.Rなどの
RECORD記述ファイルのバイナリ・バージョンになります。
FML型バッファを使用するには、次の手順に従います。
•
|
FMLヘッダー・ファイルを作成して、アプリケーションの #include文に指定します。
|
FML関数は、フィールド化バッファからC構造体への変換、またその逆の変換など、型付きバッファを操作する場合に使用します。これらの関数を使用すると、データ構造やデータの格納状態がわからなくても、データ値にアクセスしたり更新できます。
FML関数の詳細は、『Oracle Tuxedo ATMI FML関数リファレンス』
を参照してください。
アプリケーション・プログラムで
FML型バッファを使用するには、
表2-9の環境変数を設定します。
|
|
|
FMLまたは FML32型 バッファのフィールド表ファイル名のカンマ区切りのリスト。
|
|
FMLまたは FML32型バッファのフィールド表ファイルが検索されるディレクトリのコロン区切りのリスト。Microsoft Windowsでは、セミコロンで区切られます。
|
FML型バッファや
FML依存型
VIEWを使用する場合は、常にフィールド表ファイルが必要です。フィールド表ファイルは、
FML型バッファのフィールドの論理名をそのフィールドをユニークに識別する文字列にマッピングします。
FMLフィールド表の各フィールドは、次の形式で定義します。
$ /* FML structure */
*base
value
name number type flags comments
表2-10は、
FMLフィールド表ファイルに指定する必要がある
FMLフィールドを示しています。
|
|
|
後続のフィールド番号をオフセットするためのベース値。関連するフィールドのセットを簡単にグループ分けし、番号を付け直すことができるようになります。 *baseオプションを使用すると、フィールド番号を再利用できます。16ビットのバッファの場合、ベース値とそれに関連する番号を加算した値が、100以上8191未満でなければなりません。このフィールドは省略可能です。
注意:
|
Oracle Tuxedoシステムでは、フィールド番号1 - 100と6000 - 7000は、内部使用のために予約されています。 FMLではフィールド番号101 - 8191、 FML32ではフィールド番号101 - 33、554、および431がアプリケーション定義のフィールド用に使用できます。
|
|
|
フィールドの識別子。この値は256文字以下の文字列で、英数字と下線文字だけを指定できます。
|
|
フィールドの相対数値。現在のベース値が指定されている場合、この値は現在のベース値に加算されて、フィールド番号が計算されます。
|
|
フィールドのタイプ。指定できるのは、 char、 string、 short、 long、 float、 double、または carrayです。
|
|
将来使用するために予約されたフィールド。プレースホルダーとしてダッシュ(-)を挿入します。
|
|
|
すべてのフィールドは省略可能です。また、複数個使用できます。
リスト2-15は、
FML依存型VIEWの例で使用されるフィールド表ファイルを示しています。
リスト2-15
FML VIEWのフィールド表ファイル
# name number type flags comments
FLOAT1 110 float - -
DOUBLE1 111 double - -
LONG1 112 long - -
SHORT1 113 short - -
INT1 114 long - -
DEC1 115 string - -
CHAR1 116 char - -
STRING1 117 string - -
CARRAY1 118 carray - -
BOOL1
SIGNEDCHAR
1
UNSIGNEDCHAR
1
WCHAR_T1
UNSIGNEDINT1
UNSIGNEDLONG1
LONGLONG1
UNSIGNEDLONGLONG1
LONGDOUBLE
1
STRUCT1
クライアント・プログラムやサービス・サブルーチンで
FML型バッファを使用するには、
FMLヘッダー・ファイルを作成して、アプリケーションの
#include文にそのヘッダー・ファイルを指定する必要があります。
フィールド表ファイルから
FMLヘッダー・ファイルを作成するには、
mkfldhdr(1)コマンドを使用します。たとえば、
myview.flds.hというファイルを作成するには、次のコマンドを入力します。
FML32型バッファの場合は、
mkfldhdr32コマンドを使用します。
リスト2-16は、
mkfldhdrコマンドによって作成される
myview.flds.hヘッダー・ファイルを示しています。
リスト2-16
myview.flds.hヘッダー・ファイル
/* fname fldid */
/* ----- ----- */
#define FLOAT1 ((FLDID)24686) /* number: 110 type: float */
#define DOUBLE1 ((FLDID)32879) /* number: 111 type: double */
#define LONG1 ((FLDID)8304) /* number: 112 type: long */
#define SHORT1 ((FLDID)113) /* number: 113 type: short */
#define INT1 ((FLDID)8306) /* number: 114 type: long */
#define DEC1 ((FLDID)41075) /* number: 115 type: string */
#define CHAR1 ((FLDID)16500) /* number: 116 type: char */
#define STRING1 ((FLDID)41077) /* number: 117 type: string */
#define CARRAY1 ((FLDID)49270) /* number: 118 type: carray */
#define BOOL1
#define SIGNEDCHAR
1
#define UNSIGNEDCHAR
1
#define
WCHAR_T1
#define
UNSIGNEDINT1
#define
UNSIGNEDLONG1
#define
LONGLONG1
#define
UNSIGNEDLONGLONG1
#define LONGDOUBLE
1
#define STRUCT1
アプリケーションの
#include文に新しいヘッダー・ファイルを指定します。ヘッダー・ファイルがインクルードされると、シンボリック名でフィールドを参照できるようになります。
XML型バッファとApache Xerces C++パーサーの使用
XMLがデータ標準として受け入れられるに伴い、アプリケーションでXML型付きバッファを使用するOracle Tuxedoユーザーが増加しています。この動きを後押しするため、Oracle TuxedoソフトウェアではApache Xerces C++バージョン2.5パーサーが統合されました。
XMLバッファを使用すると、Oracle TuxedoアプリケーションでXMLを使用して、アプリケーション内やアプリケーション間でデータを交換できるようになります。Oracle Tuxedoアプリケーションでは、単純XML型バッファの送受信や、それらのバッファを適切なサーバーにルーティングできます。解析など、XMLドキュメントのすべての処理ロジックはアプリケーション側にあります。
•
|
ドキュメントの論理構造の記述と、その構造に関する情報
|
XML型バッファのプログラミング・モデルは、
CARRAY型バッファのモデルと類似しています。
tpalloc()関数を使用して、バッファの長さを指定する必要があります。最大4 GBのXML文書がサポートされます。
イベント処理で行われるフォーマット処理とフィルタリングは、STRING型バッファが使用されている場合はサポートされますが、XML型バッファではサポートされません。そのため、XML型バッファのバッファ・タイプ・スイッチ内の
_tmfilter関数と
_tmformat関数のポインタは、NULLに設定されます。
Oracle TuxedoシステムのXMLパーサーは、次の操作を行います。
XML型バッファでは、データ依存型ルーティングがサポートされています。XML文書のルーティングは、要素の内容、または要素タイプと属性値に基づいて行われます。使用される文字エンコードはXMLパーサーによって判別されます。エンコードがOracle Tuxedoの構成ファイル(
UBBCONFIGと
DMCONFIG)で使用されているネイティブな文字セット(US-ASCIIまたはEBCDIC)と異なる場合、要素と属性名はUS-ASCIIまたはEBCDICに変換されます。
XMLドキュメントには、ルーティング用に構成する属性を含めなければなりません。属性がルーティング基準として構成されていてもXMLドキュメントに含まれていない場合、ルーティング処理は失敗します。
要素の内容と属性値は、ルーティング・フィールド値の構文とセマンティクスに従っていることが必要です。また、ルーティング・フィールド値のタイプも指定しなければなりません。XMLでサポートされるのは文字データだけです。範囲フィールドが数値の場合、そのフィールドの内容や値はルーティング処理時に数値に変換されます。
Apache Xerces C++パーサーについて
Xerces-C++ 2.5.0パーサーは、移植可能なC++サブセットで記述され、XML文書を解析、生成、操作、および検証するための共有ライブラリを備えています。これは、XML 1.0勧告および関連する規格に準拠します: DOM 1.0、DOM 2.0、SAX 1.0、SAX 2.0、ネームスペースおよびW3CのXMLスキーマ勧告バージョン1.0。
Xerces-C++ 1.7パーサーは、検証が必要なときに文書型定義(DTD)とXMLスキーマ・ファイルをキャッシュせず、DTDで使用される外部エンティティ・ファイルもキャッシュしません。Oracle Tuxedo 8.1では、Webで繰り返し取得される外部DTD、スキーマ、およびエンティティ・ファイルをキャッシュするオプションを追加することによってXerces-C++ 1.7パーサーのパフォーマンスが向上ました。この変更の継続的なサポートは、Tuxedo 9.xおよびXerces C++ 2.5.0で使用可能です。
Xerces-C++パーサーのキャッシュ機能を有効または無効にする方法は次の2通りです。
•
|
URLENTITYCACHINGと URLENTITYCACHEDIRという2つの環境変数を使用して管理的に制御します。
|
•
|
特定のXercesパーサー・クラス・メソッドを指定する4つのATMI関数を使用してプログラム的に制御します。
|
注意:
|
これらの4つのメソッドは、Apache Xerces-C++パーサーに加えられたOracle Tuxedoの拡張機能です。以下の2つのXercesオブジェクトと組み合わせて排他的に使用されます。
|
Oracle Tuxedo配布キットには、様々なプラットフォーム上で200種類を超えるエンコード文字セット(エンコード形式)をサポートするC/C++ライブラリ、International Components for Unicode (ICU) 3.0ライブラリが付属しています。Xerces-C++ 2.5.0パーサーは、ICU 3.0ライブラリと共に構築されます。
Xerces-C++パーサーATMI関数を使用するためのサンプル・アプリケーションは、Oracle Tuxedoユーザー・ドキュメントに記載されています。このサンプルには、Xerces-C++パーサーのラッパーを記述して、Cで記述されたTuxedoクライアントおよびサーバーからXerces-C++ ATMI関数を呼び出せるようにするための方法が示されています。
XercesパーサーでXMLスキーマを使用するためのサンプル・アプリケーションは、Oracle Tuxedoのドキュメントに記載されています。
『Oracle Tuxedo ATMIアプリケーション開発のためのチュートリアル』の
「xmlfmlapp (完全なC XML/FML32変換アプリケーション)のチュートリアル」を参照してください。
入力/出力形式として、XMLデータは、現在のアプリケーション開発で幅広く使用されています。一方、ほとんどのTuxedoカスタマは、望ましいデータ・トランスポートとしてTuxedo FML/FML32バッファを使用する既存の定義済サービスに多額の投資を行っています。
Oracle Tuxedoは、XMLとFML/FML32バッファ間のデータ変換が可能な機能を追加して、この問題に対処します。この変換は、次のいずれかの方法で開始できます。
プログラマ用に、XMLデータとFML/FML32バッファ間のオンデマンド変換では、手動変換用に新しいATMI関数が4つ用意されています。詳細は、
「オンデマンド変換の使い方」を参照してください。
アプリケーション開発者用に
、XMLとFML/FML32バッファ間の自動変換では、
UBBCONFIG構成ファイルの
SERVICESセクションに新しい
BUFTYPECONVパラメータが用意されています。自動変換では、サーバーの起動時に変換が開始されます。詳細については、
「自動変換の使い方」を参照してください。
注意:
|
XMLとFML/FML32間の変換では、サイズが大きくなる可能性があるサード・パーティ・ライブラリ(libticudata.soなど)を使用します。
|
共有ライブラリのサイズが大きくなると、そのライブラリに直接または間接的に依存する、Tuxedoアプリケーションで実行中のプロセスが多くのメモリーを消費し、その結果、パフォーマンスが低下する可能性があります。
XMLとFML/FML32間の変換機能は、Tuxedoシステム・プロセスでは使用しないでください。
Xercesパーサーを使用したXMLとFML/FML32バッファ間の変換の制限に関するその他の既知の問題については、
「変換の制限事項」を参照してください。
オンデマンド変換では、XMLデータからFML/FML32バッファまたはFML/FML32バッファからXMLデータへの変換を手動で実行できます。
次の4つのATMI関数では、オンデマンド変換を実行できます。
•
|
tpxmltofml() - XMLをFMLに変換
|
•
|
tpfmltoxml() - FMLをXMLに変換
|
•
|
tpxmltofml32() - XMLをFML32に変換
|
•
|
tpfml32toxml() - FML32をXMLに変換
|
これらの関数と引数の詳細な説明については、
『Oracle Tuxedo ATMI C言語関数リファレンス』を参照してください。
XMLデータとFML/FML32バッファ間のオンデマンド変換を実行するには、次の手順に従います。
•
|
rtag引数を使用して、関数呼出しでバッファ型変換の入力/出力XMLルート・タグを指定します(オプション)。
|
•
|
Xercesパーサー・オプションを選択するように flag引数を設定します(オプション)。
|
ATMI関数を使用してXMLとFML/FML32バッファ間の変換を開始する場合は、次のいずれかの方法でパーサー検証が決定されます。
•
|
ATMI関数でflag引数を使用して検証オプションを指定する
|
ATMI関数とそのXercesパーサーのflag引数の詳細な説明については、
『Oracle Tuxedo ATMI C言語関数リファレンス』を参照してください。
自動変換では、最初の形式も最後の形式もXMLになります。つまり、XMLバッファがFML/FML32バッファに入力、変換、および処理され、最後にXMLに再変換されます。
XMLとFML/FML32バッファ間の変換を開始するには、
UBBCONFIGファイルの
SERVICESセクションの
BUFTYPECONVパラメータを指定する必要があります。このパラメータは、
XML2FMLまたは
XML2FML32のどちらかの値のオプションのみを受け付けます。
このパラメータを使用してサーバーを起動した場合、クライアント
tpcall()、
tpacall()、
tpconnect()、または
tpsend()によって入力バッファがXMLバッファからFML/FML32バッファに変換されてからサービスに送られます。
tpreturn()または
tpsend()が呼び出されると、FML/FML32バッファがXMLバッファに変換されてから返されます。
BUFTYPECONVパラメータを使用しているサービスでは、クライアントまたはその他のサービスは、既存のサービスがFML/FML32バッファを処理する方法を変更することなく、XMLバッファを送受信できます。
注意:
|
BUFTYPECONVパラメータを使用する場合は、以下の項目に注意してください。
|
•
|
サービスが BUFTYPECONVパラメータを使用している場合、出力された すべてのFML/FML32バッファはXMLに変換されます。 BUFTYPECONVパラメータを使用して新しいサービス名を作成すると、XMLを出力し、FML/FML32バッファに対する元のサービス名を保持することができます。
|
•
|
XMLとFML/FML32バッファ間の自動変換は、入力されたXMLデータに対してのみ処理を行います。その他のすべての入力バッファは、 BUFTYPECONVで指定されている場合でも変換されません。
|
•
|
XML、FMLおよびFML32の入力/出力サービス・データが変換されるのは、サービスが サーバーとして機能する場合のみです。つまり、クライアントまたは他のサービスが、 BUFTYPECONVパラメータを使用してサービスにリクエストを行う場合です。
|
•
|
BUFTYPECONVパラメータを使用しているサービスがクライアントとして動作している場合、変換は実行されません。たとえば、別のサービスに対して tpcall()を使用している BUFTYPECONVパラメータが指定されたサービスなどが挙げられます。
|
•
|
/Qメッセージング・モードでは、 TMQFORWARDはサービスの呼出しに tpcall()を使用します。呼び出されたサービスが BUFTYPECONVパラメータを使用している場合、自動変換が実行されます。
|
自動変換の際に、入力XMLルート要素名を保存することはできないため、出力XMLルート・タグ
は、デフォルト・ルート・タグ
<FML Type="FML">または
<FML Type="FML32">を使用します。
XMLデータとFML/FML32バッファ間の自動変換を実行するには、次の手順に従います。
•
|
状況に応じて XML2FMLまたは XML2FML32を指定している BUFTYPECONVパラメータを追加します。
|
•
|
TPXPARSFILE環境変数を使用して、Xercesパーサーの属性および設定を制御します(オプション)。
|
•
|
tmloadcf -yを使用して UBBCONFIGファイルをコンパイルおよびロードします。
|
•
|
tmboot -yを使用してサーバーを起動します。
|
Xercesパーサーは、デフォルトの属性設定を使用して、自動変換時のXML検証を制御します。ただし、Tuxedoでは14個の固有のXerces DOMParserクラス属性をサポートしており、これらを使用することで自動変換を多少柔軟にカスタマイズできます。
自動変換メソッドを使用している場合、パーサー検証は以下のいずれかの方法で決定されます。
•
|
TPXPARSFILE環境変数で検証オプションを指定する
|
TPXPARSFILE環境変数は、変更したいXercesDOMParserクラス属性設定を含むテキスト・ファイルへの完全修飾パスを示します。
テキスト・ファイルの各属性は、次の形式で別の行に記述されます。
<parser attribute>=<setting>
<parser attribute>には、次の表の14個のパーサー属性の一部または全部を指定できます((D)はデフォルト設定を示します)。
注意:
|
これらの属性の詳細は、 Xercesパーサー2.5.0のドキュメントを参照してください。
|
|
|
|
|
|
|
|
|
|
|
|
|
IncludeIgnorableWhiteSpace
|
|
|
|
NoNamespaceSchemaLocation
|
|
|
|
|
|
|
|
ValidationConstraintFatal
|
|
|
Val_Never、Val_Always、またはVal_Auto (D)
|
ValidationSchemaFullChecking
|
|
リスト2-17は、
TPXPARSFILE環境変数のサンプル入力プレーン・テキスト・ファイルです。
リスト2-17
TXPARSFILE環境変数のサンプル入力
CacheGrammarFromParse=True
DoNameSpaces=True
DoSchema=True
ExternalSchemaLocation= http://www.xml.org/sch.xsd
ExitOnFirstFatalError=c:\xml\example.xsd
IncludeIgnorableWhiteSpace=True
LoadGrammar=
NoNamespaceSchemaLocation=
StandardUriConformant=True
UseCachedGrammarInParse=True
UseScanner=WF
ValidationConstraintFatal=True
ValidationScheme=Val_Auto
ValidationSchemaFullChecking=True
XMLとFML/FML32フィールド型のマッピング
XML形式とFML/FML32フィールド間の関係では、XML要素名はFML/FML32フィールド名と同じですが、XML値は対応するフィールド型をもとに解釈されます。
開始および終了タグは、フィールドの名前を使用します。属性は、必要に応じて
FLD_FML32、FLD_MBSTRINGと
FLD_VIEW32で提供されます。フィールド名と属性の大文字と小文字は区別されます。
フィールド値は文字列として読み取られ、以下のフィールド型に変換されます。
<FIELDNAME Attribute="Attribute Value"> FIELDVALUE </FIELDNAME>
FML/FML32フィールド型は、次のようにXMLバッファ型にマッピングされます。
|
|
|
SHORT LONG CHAR FLOAT DOUBLE STRING
|
FLD_SHORT、 FLD_LONG、FLD_CHAR、 FLD_FLOAT, FLD_DOUBLE、および FLD_STRINGフィールドとXML文字列値間の変換は単純です。
型の値の形式は、 Ftypcvt()で使用されているスタイルに従います。
|
FML:AMOUNT=10.00 XML:<AMOUNT>10.00</AMOUNT>
|
|
FLD_CARRAYフィールドの変換時に、Tuxedoでは、XMLバイト・ストリーム値はXMLの2文字から1バイト値に変換されます。つまり、文字の各XMLペアは16バイト値を表します。
|
FML: BEA=TUXEDO XML:<BEA>54555845444F</BEA>
|
|
XMLへの変換時に、 FLD_PTRフィールド名は、 STRING、 MBSTRING、 CARRAY、 FML、 FML32、および VIEW32のうち、有効なTuxedoバッファ型を示し、無効なバッファ型を無視します。バッファの内容がXMLに変換された場合、 BUFTYPE属性はバッファ型タグに含まれます(例1を参照)。
FML32への変換時に、 BUFTYPE属性をバッファ型タグに含める必要があります。有効な唯一の値は、 STRING、 MBSTRING、 CARRAY、 FML、 FML32、および VIEW32のTuxedoバッファ型です。 BUFTYPE属性を指定していない場合、または無効な値を使用している場合、要素はFML32で無視されます。
|
<stringptr BUFTYPE=”STRING”>teststringptr</stringptr>
<fml32ptr BUFTYPE=”FML32”><id>2323</id> </fml32ptr>
|
|
FLD_FML32フィールド名は、FMLフィールド名に基づいて開始および終了タグでサポートされます。このXMLドキュメントには、バッファに含まれるフィールドごとに <fieldname>value</fieldname>の複数の説明が含まれます。
埋め込みFML32は許可されるので、XMLの階層記述は受け付けられます。
注意:
|
省略可能な属性Tpmbenc,は、XMLとFML32間の変換時にFML32バッファのMBSTRING フィールド全体のエンコードを指定するために使用します。
|
|
下記の最初の例には、エンコード属性が含まれます。2番目の例は、IDという埋め込みFML32フィールドを含むBANKフィールドに対するFML32定義です。
例1: <ACCT Tpmbenc="EUC"><NM>Smith</NM><TRAN>OPEN</TRAN></ACCT>
例2: <BANK><BID>001</BID><ID><NM>Jones</NM><AC>001</AC></ID> </BANK>
|
|
FLD_VIEW32フィールド名がサポートされているので、 FLD_INTフィールドと FLD_DECIMALフィールドも認識されます。 FLD_INTは、 FLD_LONGと同様に処理されます。
開始および終了タグは、 FLD_VIEW32フィールド名を基づいています。使用するVIEW名を指定するために Vname属性が取られます。このXMLドキュメントには、次の記述が複数含まれています。
fbnameは、VIEWメンバー・フィールドのバッファ名です。
|
<CURR Vname="Myview"> <FB1>001</FB1><FB1>002</FB1><FB2>7.50</FB2><FB3>Y</FB3> </CURR>
|
|
FLD_MBSTRINGフィールド変換は、 Encoding属性、およびFML32フィールドを記述するためのフィールド・データを使用します。この変換は、 Fmbpack32を使用した場合と同じです。次の条件に注意してください。
1.
|
Encoding属性があり、値が指定されている場合、データ値を基に FLD_MBSTRING値が作成されます。
|
2.
|
Encoding属性がなく、 Tpmbencが完全なFML32バッファ用に設定されている場合、 FLD_MBSTRINGは Tpmbenc値を適用します。
|
3.
|
Encoding属性がなく、 Tpmbencも指定されていない場合、プロセス環境 TPMBENC (すべて大文字 )の取得が試みられ、属性定義のかわりに FLD_MBSTRING値としてそのエンコードが使用されます。
|
4.
|
上記の3つの条件のいずれにも当てはまらない場合、それらの要素は無視され、変換は実行されません。
|
データは、 FLD_CARRAYフィールドと同じ方法で処理されます。
|
<MBIN Encoding="SJIS">C7E8D9CAB3</MBIN>
|
Tuxedoで提供されているXerces 2.5.0パーサーを使用したXMLデータとFML/FML32バッファ間の変換には、次の制限事項があります。
•
|
XMLドキュメントは、柔軟なXML文法としてではなく、制限されたXMLメッセージ・セットとして処理されます。この制限は、FML/FML32ヘッダー・ファイルで指定されている定義に基づいています。
|
•
|
デジタル署名されたXML、FML、FML32バッファは、自動変換時に署名のチェックに失敗します。デジタル署名用の tpenvelope()関数は、オンデマンド変換時にのみ使用できます。
|
•
|
解析の制限は、Xercesライブラリから継承されています。
|
•
|
Xercesパーサーは、出力XML DTD/スキーマ検証をサポートしていません。
|
•
|
XMLとFML/FML32バッファ間の変換によって、開始したときとまったく同一のXMLドキュメントが 必ずしも作成されるわけではありません。Tuxedo FML/FML32バッファは、バッファ内の 同じフィールド型をグループ化し、そのグループを基に出力順序を決めるため、入力XMLに基づく個々の要素の順序は失われます。Xercesパーサーは、FML/FML32フィールド入力順序を追跡したり、FML/FML32フィールド 出力順序を制御したりすることはできません。
|
•
|
view32メンバーの部分リストをXMLに入力できますが、XMLがFML32に変換される際に、FML32の出力には、VIEW定義ファイルで定義されたすべてのview32メンバーが含まれます。
|
•
|
自動変換の際に、入力XMLルート・タグ名は保存されず、デフォルトの出力XMLルート・タグ <FML Type="FML">または <FML Type="FML32">が使用されます。
|
中国語、日本語、韓国語、およびその他のアジア太平洋言語で必要とされるマルチバイト・エンコード文字セットをサポートするために、Oracle Tuxedoには、マルチバイト文字のユーザー・データをトランスポートするためのMBSTRING型付きバッファが用意されています。中国語、日本語、韓国語、およびその他のアジア太平洋言語では、文字を表現するために複数バイトを使用するエンコード文字セットが使用されます。
MBSTRING型付きバッファおよびマルチバイト文字エンコード機能を使用すると、Oracle Tuxedoシステムは、プロセス間でMBSTRINGバッファ(またはFML32バッファの
FLD_MBSTRINGフィールド)が転送されるときに、ユーザー・データを別のエンコード表現に変換できます。
図2-1は、エンコード変換がどのように行われるかを例示しています。
上図の例に示すように、MBSTRING型付きバッファは、ユーザー・データのコード・セット
文字エンコード(または単に
エンコード)を識別する情報を保持できます。この例では、クライアントのリクエストのMBSTRINGバッファは、Shift-JIS (SJIS)エンコードで表される日本語ユーザー・データを保持し、サーバーの応答のMBSTRINGバッファは、Extended UNIX Code (EUC)エンコードで表される日本語ユーザー・データを保持しています。マルチバイト文字エンコード機能では、環境変数
TPMBENCと
TPMBACONVを読み込んで、ソースのエンコード、ターゲットのエンコード、および自動エンコード変換の状態(有効または無効)を判別します。
エンコードの変換機能により、基底のTuxedoシステム・ソフトウェアでは、着信メッセージのエンコード表現を、受信プロセスが実行されているマシンでサポートされているエンコード表現に変換できます。この変換は文字コード・セット間の変換でも言語の翻訳でもなく、同じ言語の異なる文字エンコード間の変換です。
文字エンコード変換は、次の2とおりの方法で制御できます。
•
|
環境変数 TPMBENCと TPMBACONVを使用して管理的に制御します。
|
•
|
ATMI関数を使用してプログラマティックに制御します。
|
次の2つのフローチャートでは、MBSTRINGバッファの割り当て、送信、受信、および変換時に環境変数およびATMIがどのように使用されるかを示します。
sendlenがゼロに設定されている場合、MBSTRINGを自己記述型にすることができます。一部のTuxedoバッファでは、ユーザーがバッファの長さを指定していない場合、バッファが長さを自己決定できます。この自己記述型の動作は、アプリケーションが、Tuxedo関数呼出し(
tpcall()など)の
sendlen引数をゼロに設定したときにトリガーされます。
この自己記述型の動作を実装するには、以下の操作を行います。
•
|
_mbspresend()関数を MBSTRINGタイプ・スイッチ関数リストに追加します。
|
•
|
機能とともに使用するのは安全でないとみなされるコードセットのエンコード名を含む保護ファイル $TUXDIR/udataobj/sendlen0_unsafe_tpmbencを追加します。
|
_mbspresend()を追加するには、Tuxedoバッファをカスタマイズするユーザーがアプリケーションを再ビルドする必要があります。
TPMBENCで指定する安全または危険なエンコード名という考えは、これらのエンコードのマルチバイト文字データにNULLが埋め込まれているかどうかで決まります。
_mbspresend()関数は
strlen()を使用してデータの長さを決めるので、NULLが埋め込まれていると、データの長さが不適切になり、誤ったデータ・バイト数が送られてしまいます。
sendlen0_unsafe_tpmbencのデフォルト・リストには、NULLが埋め込まれている可能性がある(便宜上、大文字および小文字の)マルチバイトUnicodeエンコード名があります。アプリケーション管理またはパフォーマンスを考慮すると、このリストを変更する必要があります。
•
|
ファイルがあっても空の場合は、 MBSTRING自己記述処理ですべてのエンコード名が安全なものとみなされます。
|
•
|
ファイルがない場合は、 MBSTRING自己記述処理ですべてのエンコード名が危険なものとみなされます( tperrnoは TPEINVALになります)。
|
•
|
ファイルがあり、名前のリストを格納している場合は、このファイルが( _mbsinit()で)一度読み取られ、Tuxedoの内部にリストが格納されます。 mbsinit()の実行中に、格納されているリストと TPMBENC名が比較され、バッファが安全または危険に設定されます。 _mbspresend()が呼び出され( sendlen引数がゼロに設定されている状態)、バッファが安全とマークされると、データの長さはTuxedoの内部で設定されます。
|
Oracle Tuxedoのマルチバイト文字サポートには、以下の制限が存在します。
•
|
UBBCONFIGパラメータおよびDMCONFIGパラメータにはASCII文字以外を使用しないでください。
|
•
|
データ依存型ルーティングのフィールド・データにはASCII文字以外を使用しないでください。
|
•
|
マルチバイト文字機能は、Oracle Joltではサポートされていません。
|
•
|
マルチバイト文字機能は、リリース8.x以前のOracle WebLogic Tuxedo Connector (WTC)ではサポートされていません。
|
•
|
マルチバイト文字機能は、Tuxedo VIEWバッファ・タイプではサポートされていません。
|
•
|
MBSTRINGと FLD_MBSTRINGをサポートするTuxedo APIに相当するCOBOL APIは存在しません。
|
マルチバイト文字エンコードでのlibiconvのサポート
Oracle Tuxedo 8.1以降のソフトウェア配布キットには、多くのエンコード文字セットとエンコードをサポートするエンコード変換ライブラリであるlibiconvが付属しています。マルチバイト文字エンコードの機能では、このライブラリの文字変換関数を使用して、サポートされている任意の文字エンコードから別の文字エンコードにUnicode変換を通じて変換できます。
libiconvでは、次のエンコードをサポートします。
•
|
ASCII、ISO-8859-{1,2,3,4,5,7,9,10,13,14,15,16},
|
•
|
CP{1250,1251,1252,1253,1254,1257}, CP{850,866},
|
•
|
Mac{Roman,CentralEurope,Iceland,Croatian,Romania}
|
•
|
Mac{Cyrillic,Ukraine,Greek,Turkish}
|
•
|
ISO-8859-{6,8}、CP{1255,1256}、CP862、Mac{Hebrew,Arabic}
|
•
|
EUC-JP、SHIFT-JIS、CP932、ISO-2022-JP、ISO-2022-JP-2、ISO-2022-JP-1
|
•
|
EUC-CN、HZ、GBK、GB18030、EUC-TW、BIG5、CP950、BIG5-HKSCS
|
•
|
ISO-2022-CN、ISO-2022-CN-EXT
|
•
|
EUC-KR、CP949、ISO-2022-KR、JOHAB
|
•
|
Georgian-Academy、Georgian-PS
|
•
|
`uint16_t'または`uint32_t' (マシン依存のエンディアンと配置)による正規のUnicode
|
•
|
UCS-2-INTERNAL、UCS-4-INTERNAL
|
•
|
`char'または`wchar_t' (マシン依存のエンディアンと配置、およびOSとロケール依存のセマンティクス)によるロケール依存のエンコード
|
マルチバイト文字エンコードの詳細は、次のドキュメントを参照してください。
Oracle Tuxedoシステムで提供されるバッファ・タイプでは、アプリケーションのニーズが満たされない場合があります。たとえば、アプリケーションがフラットではないデータ構造体、つまりSQLデータベースの問合せのための解析ツリーなど、ほかのデータ構造体へのポインタを持つデータ構造を扱う場合があります。アプリケーション固有の要件に対応するために、Oracle Tuxedoシステムではカスタム・バッファがサポートされています。
バッファをカスタマイズするには、
表2-11の特性を理解しておく必要があります。
|
|
|
バッファ・タイプの名前。8文字以内の文字列で指定します。
|
|
バッファ・サブタイプの名前。16文字以内の文字列で指定します。サブタイプは、特定のタイプのバッファに必要となる処理の違いを示すために使用されます。サブタイプ値としてワイルドカード文字(*)を指定すると、同じ汎用ルーチンを使用して、指定されたタイプのすべてのバッファが処理されます。サブタイプが定義されているバッファは、リスト内でワイルドカードより前に置く必要があります。置かないと、処理が正常に行われません。
|
|
対応するバッファ・タイプが割り当てまたは再割り当てされるときの最小サイズ。バッファ・タイプにゼロより大きい適切な値が設定されている場合、バッファを割り当てや再割り当てする際に、バッファ・サイズにゼロを指定できます。
|
表2-12は、各バッファ・タイプに指定する必要があるルーチンを示しています。特定のルーチンが必要ない場合は、NULLポインタを指定します。必要に応じて、Oracle Tuxedoシステムでデフォルトの処理が行われます。
|
|
|
新しく割り当てられた型付きバッファを初期化します。
|
|
型付きバッファを再初期化します。このルーチンは、バッファが新しいサイズで再割り当てされたときに呼び出されます。
|
|
型付きバッファを非初期化します。このルーチンは、型付きバッファが解放される直前に呼び出されます。
|
|
型付きバッファを送るための前処理を行います。このルーチンは、メッセージとして型付きバッファを別のクライアントやサーバーに送信する前に呼び出されます。転送されるデータの長さが返されます。
|
|
型付きバッファを元の状態に戻します。このルーチンは、メッセージの送信後に呼び出されます。
|
|
アプリケーションで受信された型付きバッファを準備します。アプリケーション・データの長さが返されます。
|
|
バッファ・タイプで必要なすべてのエンコードとデコードを行います。入力バッファと出力バッファ、およびその長さと共に、エンコードやデコードのリクエストがルーチンに渡されます。エンコードに使用される形式はアプリケーションで決定され、ほかのルーチンと同じように、バッファ・タイプによって異なる場合があります。
|
|
ルーティング情報を指定します。このルーチンは、型付きバッファ、バッファのデータ長、管理者が構成した論理的なルーティング名、およびターゲット・サービスを指定して呼び出されます。この情報に基づいて、アプリケーションでメッセージの送信先サーバー・グループが選択されるか、またはメッセージが不要であることが決定されます。
|
|
フィルタ情報を指定します。このルーチンは、型付きバッファに対する式の評価するときに呼び出され、合致したかどうかを返します。型付きバッファが VIEWまたは FMLの場合、 FMLブール式が使用されます。イベント・ブローカは、このルーチンを使用してイベントが合致しているかどうかを評価します。
|
|
|
領域の割当てと解放、メッセージの送受信など、バッファを操作するコードを記述するのはアプリケーション・プログラマです。デフォルトのバッファ・タイプではアプリケーションのニーズを満たすことができない場合、ほかのバッファ・タイプを定義し、新しいルーチンを記述してバッファ・タイプ・スイッチに組み込むことができます。
ほかのバッファ・タイプを定義するには、次の手順に従います。
2.
|
tm_typeswに、新しいタイプとバッファ管理モジュールの名前を追加します。
|
3.
|
新しい共有オブジェクトまたはDLLをビルドします。共有オブジェクトまたはDLLには、更新されたバッファ・タイプ・スイッチとそれに対応する関数が含まれていなければなりません。
|
4.
|
新しい共有オブジェクトまたはDLLをインストールして、すべてのサーバー、クライアント、およびOracle Tuxedoシステムで提供される実行可能ファイルが実行時に動的にロードされるようにします。
|
静的ライブラリが使用されるアプリケーションで、カスタム・バッファ・タイプ・スイッチを使う場合は、カスタム・サーバーをビルドして、新しいタイプ・スイッチにリンクする必要があります。詳細は、
buildwsh (1)、
TMQUEUE (5)、
TMQFORWARD (5)を参照してください。
ここでは、前述の手順に従って、共有オブジェクトまたはDLL環境で新しいバッファ・タイプを定義します。最初に、Oracle Tuxedoシステム・ソフトウェアに提供されているバッファ・スイッチを参照してみます。
リスト2-18は、システムに提供されているスイッチです。
リスト2-18
デフォルトのバッファ・タイプ・スイッチ
#include <stdio.h>
#include <tmtypes.h>
/*
* Initialization of the buffer type switch.
*/
struct tmtype_sw_t tm_typesw[] = {
{
"CARRAY", /* type */
"*", /* subtype */
0 /* dfltsize */
NULL, /* initbuf */
NULL, /* reinitbuf */
NULL, /* uninitbuf */
NULL, /* presend */
NULL, /* postsend */
NULL, /* postrecv */
NULL, /* encdec */
NULL, /* route */
NULL, /* filter */
NULL, /* format */
NULL, /* presend2 */
NULL /* multibyte code-set encoding conversion */
},
{
"STRING", /* type */
"*", /* subtype */
512, /* dfltsize */
NULL, /* initbuf */
NULL, /* reinitbuf */
NULL, /* uninitbuf */
_strpresend, /* presend */
NULL, /* postsend */
NULL, /* postrecv */
_strencdec, /* encdec */
NULL, /* route */
_sfilter, /* filter */
_sformat, /* format */
NULL, /* presend2 */
NULL /* multibyte code-set encoding conversion */
},
{
"FML", /* type */
"*", /* subtype */
1024, /* dfltsize */
_finit, /* initbuf */
_freinit, /* reinitbuf */
_funinit, /* uninitbuf */
_fpresend, /* presend */
_fpostsend, /* postsend */
_fpostrecv, /* postrecv */
_fencdec, /* encdec */
_froute, /* route */
_ffilter, /* filter */
_fformat, /* format */
NULL, /* presend2 */
NULL /* multibyte code-set encoding conversion */
},
{
"VIEW", /* type */
"*", /* subtype */
1024, /* dfltsize */
_vinit, /* initbuf */
_vreinit, /* reinitbuf */
NULL, /* uninitbuf */
_vpresend, /* presend */
NULL, /* postsend */
NULL, /* postrecv */
_vencdec, /* encdec */
_vroute, /* route */
_vfilter, /* filter */
_vformat, /* format */
NULL, /* presend2 */
NULL /* multibyte code-set encoding conversion */
},
{
/* XATMI - identical to CARRAY */
"X_OCTET", /* type */
"*", /* subtype */
0 /* dfltsize */
},
{ /* XATMI - identical to VIEW */
{'X','_','C','_','T','Y','P','E'}, /* type */
"*", /* subtype */
1024, /* dfltsize */
_vinit, /* initbuf */
_vreinit, /* reinitbuf */
NULL, /* uninitbuf */
_vpresend, /* presend */
NULL, /* postsend */
NULL, /* postrecv */
_vencdec, /* encdec */
_vroute, /* route */
_vfilter, /* filter */
_vformat, /* format */
NULL, /* presend2 */
NULL /* multibyte code-set encoding conversion */
},
{
/* XATMI - identical to VIEW */
{'X','_','C','O','M','M','O','N'}, /* type */
"*", /* subtype */
1024, /* dfltsize */
_vinit, /* initbuf */
_vreinit, /* reinitbuf */
NULL, /* uninitbuf */
_vpresend, /* presend */
NULL, /* postsend */
NULL, /* postrecv */
_vencdec, /* encdec */
_vroute, /* route */
_vfilter, /* filter */
_vformat, /* format */
NULL, /* presend2 */
NULL /* multibyte code-set encoding conversion */
},
{
"FML32", /* type */
"*", /* subtype */
1024, /* dfltsize */
_finit32, /* initbuf */
_freinit32, /* reinitbuf */
_funinit32, /* uninitbuf */
_fpresend32, /* presend */
_fpostsend32, /* postsend */
_fpostrecv32, /* postrecv */
_fencdec32, /* encdec */
_froute32, /* route */
_ffilter32, /* filter */
_fformat32, /* format */
_fpresend232, /* presend2 */
_fmbconv32 /* multibyte code-set encoding conversion */
},
{
"VIEW32", /* type */
"*", /* subtype */
1024, /* dfltsize */
_vinit32, /* initbuf */
_vreinit32, /* reinitbuf */
NULL, /* uninitbuf */
_vpresend32, /* presend */
NULL, /* postsend */
NULL, /* postrecv */
_vencdec32, /* encdec */
_vroute32, /* route */
_vfilter32, /* filter */
_vformat32, /* format */
NULL, /* presend2 */
_vmbconv32, /* multibyte code-set encoding conversion */
},
{
"XML", /* type */
"*", /* subtype */
0, /* dfltsize */
NULL, /* initbuf */
NULL, /* reinitbuf */
NULL, /* uninitbuf */
NULL, /* presend */
NULL, /* postsend */
NULL, /* postrecv */
NULL, /* encdec */
_xroute, /* route */
NULL, /* filter */
NULL, /* format */
NULL, /* presend2 */
NULL /* multibyte code-set encoding conversion */
},
{
"MBSTRING", /* type */
"*", /* subtype */
0, /* dfltsize */
_mbsinit, /* initbuf */
NULL, /* reinitbuf */
NULL, /* uninitbuf */
_mbspresend, /* presend */
NULL, /* postsend */
NULL, /* postrecv */
NULL, /* encdec */
NULL, /* route */
NULL, /* filter */
NULL, /* format */
NULL, /* presend2 */
_mbsconv /* multibyte code-set encoding conversion */
},
_rreinit, /* reinitbuf */
_runinit, /* uninitbuf */
struct tmtype_sw_t _TM_FAR *
_TMDLLENTRY
_tmtypeswaddr(void)
{
return(tm_typesw);
}
この例をよく理解できるように、
リスト2-19に示すバッファ・タイプ構造体の宣言を参照してください。
/*
* The following definitions are in $TUXDIR/include/tmtypes.h
*/
#define TMTYPELEN ED_TYPELEN
#define TMSTYPELEN ED_STYPELEN
struct tmtype_sw_t {
char type[TMTYPELEN]; /* type of buffer */
char subtype[TMSTYPELEN]; /* subtype of buffer */
long dfltsize; /* default size of buffer */
/* buffer initialization function pointer */
int (_TMDLLENTRY *initbuf) _((char _TM_FAR *, long));
/* buffer reinitialization function pointer */
int (_TMDLLENTRY *reinitbuf) _((char _TM_FAR *, long));
/* buffer un-initialization function pointer */
int (_TMDLLENTRY *uninitbuf) _((char _TM_FAR *, long));
/* pre-send buffer manipulation func pointer */
long (_TMDLLENTRY *presend) _((char _TM_FAR *, long, long));
/* post-send buffer manipulation func pointer */
void (_TMDLLENTRY *postsend) _((char _TM_FAR *, long, long));
/* post-receive buffer manipulation func pointer*/
long (_TMDLLENTRY *postrecv) _((char _TM_FAR *, long, long));
/* XDR encode/decode function pointer */
long (_TMDLLENTRY *encdec) _((int, char _TM_FAR *, long, char _TM_FAR *, long));
/* routing function pointer */
int (_TMDLLENTRY *route) _((char _TM_FAR *, char _TM_FAR *, char _TM_FAR *,
long, char _TM_FAR *));
/* buffer filtering function pointer */
int (_TMDLLENTRY *filter) _((char _TM_FAR *, long, char _TM_FAR *, long));
/* buffer formatting function pointer */
int (_TMDLLENTRY *format) _((char _TM_FAR *, long, char _TM_FAR *,
char _TM_FAR *, long));
/* process buffer before sending, possibly generating copy */
long (_TMDLLENTRY *presend2) _((char _TM_FAR *, long,
long, char _TM_FAR *, long, long _TM_FAR *));
/* Multibyte code-set encoding conversion function pointer*/
long (_TMDLLENTRY *mbconv) _((char _TM_FAR *, long,
char _TM_FAR *, char _TM_FAR *, long, long _TM_FAR *));
/* this space reserved for future expansion */
void (_TMDLLENTRY *reserved[8]) _((void));
};
/*
* application types switch pointer
* always use this pointer when accessing the table
*/
extern struct tmtype_sw_t *tm_typeswp;
前述のデフォルト・バッファ・タイプ・スイッチの例は、バッファ・タイプ・スイッチの初期化を示しています。9つのデフォルト・バッファ・タイプの後に、サブタイプの名前を指定するフィールドがあります。
VIEW (
X_C_TYPEと
X_COMMON)型を除き、サブタイプはNULLです。
VIEWのサブタイプは``*''として指定されています。これは、デフォルトの
VIEW型のサブタイプに制約がないことを示します。つまり、
VIEW型のすべてのサブタイプは同じ方法で処理されます。
次のフィールドには、バッファのデフォルト(最小)サイズが指定されています。
CARRAY (
X_OCTET)型の場合、このフィールドに0が指定されています。これは、
CARRAY型バッファを使用するルーチンでは、
CARRAY型に必要な領域を
tpalloc()で割り当てなければならないことを示します。
それ以外のバッファ・タイプの場合、
tpalloc()が呼び出されて、
dfltsizeフィールドに指定されている領域がOracle Tuxedoシステムによって割り当てられます。ただし、
tpalloc()のサイズを示す引数にこれより大きな値が設定されていない場合にかぎります。
バッファ・タイプ・スイッチのエントリで、残りの8つのフィールドには、スイッチ要素ルーチンの名前が指定されています。これらのルーチンの詳細は、
『Oracle Tuxedo C言語関数リファレンス』の
buffer(3c)を参照してください。ルーチン名からそのルーチンの処理内容がわかります。たとえば、
FML型の
_fpresendは、送信前にバッファを操作するルーチンを指すポインタです。送信前処理が必要ない場合は、NULLポインタを指定します。NULLは、特に処理が必要ないことを示し、その結果デフォルトの処理が行われます。詳細は、
buffer(3c)を参照してください。
スイッチの最後にNULLエントリがあることに注目してください。変更時には、配列の終わりに必ずNULLエントリを置いてください。
アプリケーションで新しいバッファ・タイプを定義するのは、特別な処理を行うためです。たとえば、アプリケーションで、次のプロセスにバッファを送信する前に、データ圧縮を何度か行うとします。このようなアプリケーションでは、送信前処理ルーチンを記述します。
リスト2-20は、送信前処理ルーチンの宣言を示しています。
リスト2-20
送信前処理スイッチ要素のセマンティクス
long
presend(ptr, dlen, mdlen)
char *ptr;
long dlen, mdlen;
•
|
ptrは、アプリケーション・データ・バッファを指すポインタです。
|
•
|
mdlenは、データが格納されたバッファのサイズです。
|
送信前処理ルーチンで行うデータ圧縮は、アプリケーションのシステム・プログラマが行います。
ルーチンの処理が正常に終了した場合、同じバッファ内にある圧縮後の送信データの長さが返されます。処理が失敗した場合は、
-1が返されます。
プログラマが記述した送信前処理ルーチンには、Cコンパイラが使用できる任意の識別子を付けることができます。たとえば、
_mypresendという名前を付けます。
_mypresend圧縮ルーチンを使用する場合、受信側にはそのデータの圧縮を解除する
_mypostrecvルーチンが必要です。『Oracle Tuxedo C言語関数リファレンス』の
buffer(3c)に示すテンプレートを使用してください。
tm_typeswへの新しいバッファ・タイプの追加
新しいスイッチ要素ルーチンを記述し、そのコンパイルに成功したら、そのバッファ・タイプ・スイッチに新しいバッファ・タイプを追加する必要があります。その場合、
$TUXDIR/lib/tmtypesw.c(デフォルトのバッファ・タイプ・スイッチのソース・コード)をコピーします。コピーしたファイル名に、
mytypesw.cなど、拡張子として
.cを付けます。コピーしたファイルに新しいタイプを追加します。タイプ名は8文字以内で指定します。サブタイプには、NULL(
"")または16文字以内の文字列を指定できます。新しいスイッチ要素ルーチンの名前は、
extern宣言も含めて適切な場所に入力します。
リスト2-21は、その例を示しています。
リスト2-21
新しいタイプのバッファ・スイッチへの追加
#include <stdio.h>
#include <tmtypes.h>
/* Customized the buffer type switch */
static struct tmtype_sw_t tm_typesw[] = {
{
"SOUND", /* type */
���", /* subtype */
50000, /* dfltsize */
snd_init, /* initbuf */
snd_init, /* reinitbuf */
NULL, /* uninitbuf */
snd_cmprs, /* presend */
snd_uncmprs, /* postsend */
snd_uncmprs /* postrecv */
},
{
"FML", /* type */
"", /* subtype */
1024, /* dfltsize */
_finit, /* initbuf */
_freinit, /* reinitbuf */
_funinit, /* uninitbuf */
_fpresend, /* presend */
_fpostsend, /* postsend */
_fpostrecv, /* postrecv */
_fencdec, /* encdec */
_froute, /* route */
_ffilter, /* filter */
_fformat /* format */
},
{
""
}
};
この例では、
SOUNDという新しいタイプを追加しています。また、
VIEW、
X_OCTET、
X_COMMON、および
X_C_TYPEのエントリを削除して、デフォルト・スイッチで不要なエントリを削除できることを示しています。配列の最後にNULLがあることに注目してください。
新しいバッファ・タイプを定義する別の方法は、既存のタイプを再定義することです。バッファ・タイプ
MYTYPEに定義したデータ圧縮が文字列に対して実行されたとします。その場合、
STRING型の2つの
_dfltblenのかわりに、新しいスイッチ要素ルーチン
_mypresendと
_mypostrecvを使用できます。
インストールを簡単に行うには、バッファ・タイプ・スイッチを共有オブジェクトに格納します。
注意:
|
一部のプラットフォームでは、「共有オブジェクト」ではなく「共有ライブラリ」という言葉が使用されています。Windows 2003プラットフォームでは、「共有オブジェクト」ではなく「動的リンク・ライブラリ」と呼ばれています。この3つの用語が示す機能は同じなので、ここでは「共有オブジェクト」を使用します。
|
ここでは、アプリケーション内のすべてのOracle Tuxedoプロセスに、変更後のバッファ・タイプ・スイッチを認識させる方法について説明します。これらのプロセスには、Oracle Tuxedoシステムで提供されるサーバーとユーティリティのほかに、アプリケーション・サーバーおよびアプリケーション・クライアントも含まれています。
2.
|
共有オブジェクトに必要なフラグを設定し、 tmtypesw.cをコンパイルします。
|
3.
|
すべてのオブジェクト・ファイルをリンクして、共有オブジェクトを生成します。
|
4.
|
libbuft.so.71をカレント・ディレクトリから別のディレクトリにコピーします。コピー先のディレクトリとしては、アプリケーションがlibbuft.so.71を認識でき、Oracle Tuxedoシステムで提供されるデフォルトの共有オブジェクトより先にlibbuft.so.71が処理されるディレクトリを選択します。 $APPDIRまたは $TUXDIR/libディレクトリ、または $TUXDIR/bin (Windows 2003プラットフォームの場合)のいずれかを使用することをお薦めします。
|
オペレーティング・システムの規則に従うために、プラットフォームが異なる場合は、バッファ・タイプ・スイッチ共有オブジェクトには異なる名前が使用されます。
表2-13
バッファ・タイプ・スイッチ共有オブジェクトのOS別の名前
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
共有オブジェクト・ライブラリのビルド方法については、お使いのプラットフォームのソフトウェア開発ドキュメントを参照してください。
別の方法として、すべてのクライアント・プロセスとサーバー・プロセスで新しいバッファ・タイプ・スイッチを静的にリンクすることもできます。ただし、この方法ではエラーが発生しやすくなり、効率も共有オブジェクト・ライブラリをビルドするより劣ります。
16ビットWindowsプラットフォーム用の新しいtm_typeswのコンパイルとリンク
リスト2-22
Microsoft Visual C++のリスト
CL -AL -I..\e\|sysinclu -I..\e\|include -Aw -G2swx -Zp -D_TM_WIN
-D_TMDLL -Od -c TMTYPESW.C
LINK /CO /ALIGN:16 TMTYPESW.OBJ, WBUFT.DLL, NUL, WTUXWS /SE:250 /NOD
/NOE LIBW LDLLCEW, WBUFT.DEF
RC /30 /T /K WBUFT.DLL
構成ファイルの
MACHINESセクションにある
TYPEパラメータは、データ表現と使用するコンパイラが同じであるマシンをグループ化して、
TYPEが異なるマシン間でやり取りされるメッセージのデータが変換されるようにします。デフォルトのバッファ・タイプの場合、異なるマシン間でのデータ変換はユーザー、管理者、プログラマに対して透過的です。
アプリケーションで新しいバッファ・タイプを定義して、データ表現スキームが異なるマシン間でメッセージを交換する場合、新しいエンコード/デコード・ルーチンを記述して、バッファ・タイプ・スイッチに組み込む必要があります。独自のデータ変換ルーチンを記述する場合は、次のガイドラインに従ってください。
•
|
『Oracle Tuxedo ATMI C言語関数リファレンス』のリファレンス・ページ 「buffer(3c)」に示してある _tmencdecルーチンのセマンティクスを使用します。つまり、同じ引数を使用し、処理が成功した場合や失敗した場合に _tmencdecと同じ値が返されるようにルーチンをコーディングします。新しいバッファ・タイプを定義する場合は、 2-56ページの「独自のバッファ・タイプの定義」の手順に従って、新しいバッファ・タイプを使用するサービスを提供するサーバーをビルドします。
|
エンコード/デコード・ルーチンが呼び出されるのは、データをやり取りする2つのマシンの
TYPEが異なることがOracle Tuxedoシステムによって検出された場合だけです。