始める前に
ロード可能インプリメンテーション・ライブラリー、または LIL、 は C パーサー (またはノード) のインプリメンテーション・モジュールです。 LIL は、ファイル拡張子が .dll ではなく .lil である、UNIX 共有オブジェクトまたは Windows ダイナミック・リンク・ライブラリー (DLL) です。
開発者が作成する必要のあるインプリメンテーション関数は、パーサー・インプリメンテーション関数でリストしています。このプロセスに役立てるために WebSphere Business Integration Message Broker によって提供されるユーティリティー関数は、パーサー・ユーティリティー関数でリストしています。
WebSphere Business Integration Message Broker には、 BipSampPluginParser.c というサンプル・ユーザー定義パーサーのソースが備えられています。これは、単純な擬似 XML パーサーで、現状のまま使用することもできますし、変更を加えることもできます。
input 関数 (たとえば、cpiParseBuffer) は、 パーサーが入力メッセージを解析する必要があるときにブローカーによって呼び出されます。パーサーはブローカーに、所有する必要のある入力ビット・ストリーム・バッファーの量を知らせる必要があります。 固定サイズ・ヘッダーの場合、パーサーはヘッダーのサイズを要求します。 パーサーがメッセージ全体を処理する場合、バッファーの残りの部分を要求します。
int cpiParseBufferEncoded( CciParser* parser, CciContext* context, int encoding, int ccsid ){ PARSER_CONTEXT_ST* pc = (PARSER_CONTEXT_ST *)context ; int rc;
pc->iBuffer = (void *)cpiBufferPointer(&rc, parser); pc->iIndex = 0;
pc->iEncoding = encoding; pc->iCcsid = ccsid;
pc->iSize = cpiBufferSize(&rc, parser);
pc->iCurrentCharacter = cpiBufferByte(&rc, parser, pc->iIndex);
pc->iCurrentElement = cpiRootElement(&rc, parser);
pc->iInTag = 0;
return(pc->iSize); }
汎用解析関数 (たとえば、cpiParseFirstChild) は、 ESQL 式を評価するために構文エレメント・ツリーを作成する必要がある場合に、 ブローカーが呼び出す関数です。たとえば、filter ノードは ESQL 式の ESQL フィールド参照を使用します。 式を評価するには、このフィールド参照を解決しなければなりません。 要求されたエレメントが作成されるか、またはそれが存在しないことをパーサーが認識するまで、 パーサーの汎用解析関数が、おそらく繰り返し呼び出されます。
void cpiParseFirstChild( CciParser* parser, CciContext* context, CciElement* element ){ PARSER_CONTEXT_ST* pc = (PARSER_CONTEXT_ST *)context ; int rc; if ((!cpiElementCompleteNext(&rc, element)) && (cpiElementType(&rc, element) == CCI_ELEMENT_TYPE_NAME)) { while ((!cpiElementCompleteNext(&rc, element)) && (!cpiFirstChild(&rc, element)) && (pc->iCurrentElement)) { pc->iCurrentElement = parseNextItem(parser, context, pc->iCurrentElement); } } return; }
output 関数 (たとえば、cpiWriteBuffer) は、 パーサーが構文エレメント・ツリーを出力ビット・ストリームに直列化する必要があるときにブローカーによって呼び出されます。 たとえば、Compute ノードはご使用のユーザー定義パーサーのドメイン内にツリーを作成したとします。 このツリーが、たとえば MQOutput ノードによる出力でなければならない場合、 パーサーが出力ビット・ストリーム・バッファーを、作成されたツリーを表すデータに付加します。
int cpiWriteBufferEncoded( CciParser* parser, CciContext* context, int encoding, int ccsid ){ PARSER_CONTEXT_ST* pc = (PARSER_CONTEXT_ST *)context ; int initialSize = 0; int rc = 0; const void* a; CciByte b; initialSize = cpiBufferSize(&rc, parser); a = cpiBufferPointer(&rc, parser); b = cpiBufferByte(&rc, parser, 0); cpiAppendToBuffer(&rc, parser, (char *)"Some test data", 14); return cpiBufferSize(0, parser) - initialSize; }
通常、 着信メッセージ・データは単一メッセージ形式なので、 1 つのパーサーがメッセージの内容全体の構文解析を担当します。 必要なパーサーのクラス名は、入力メッセージの MQMD または MQRFH2 ヘッダーにある、 Format フィールドで定義されます。
しかし、 メッセージは複数のフォーマットで構成される場合もあります。たとえば、 あるフォーマットのヘッダーに続くデータは、別のフォーマットである場合などです。 この場合、最初のパーサーが、 チェーン内の次のフォーマットを構文解析するパーサーのクラス名を識別する必要があり、 これが順に続きます。 ユーザー定義パーサーでは、インプリメンテーション関数 cpiNextParserClassName が、 複数のメッセージ形式から構成されるメッセージ用に、 パーサー・クラスのチェーンをナビゲートする必要がある場合、 そのブローカーによって呼び出されます。
ご使用のユーザー定義パーサーが、 複数のメッセージ形式の一部であるメッセージ形式の構文解析をサポートする場合、 ユーザー定義パーサーは、cpiNextParserClassName 関数をインプリメントする必要があります。
void cpiNextParserClassName( CciParser* parser, CciContext* context, CciChar* buffer, int size ){ PARSER_CONTEXT_ST* pc = (PARSER_CONTEXT_ST *)context ; int rc = 0;
CciCharNCpy(buffer, pc->iNextParserClassName, size); return; }
ユーザー定義パーサーをインプリメントするそれぞれの LIL は、 bipGetParserFactory と呼ばれる関数を、その初期化関数としてエクスポートする必要があります。 初期化関数は、ユーザー定義パーサーがサポートするファクトリーの名前、 およびファクトリーがサポートするオブジェクトのクラスまたは共用オブジェクトを定義します。
初期化関数はまた、ファクトリー・オブジェクトを作成し、 LIL がサポートするすべてのパーサーの名前を定義する必要があります。 ファクトリーは、任意の数のオブジェクト・クラス (パーサー) をサポートできます。 パーサーの定義時には、そのパーサー用のインプリメンテーション関数へのポインターのリストが、 ブローカーに渡されます。 同じ名前のパーサーがすでに存在する場合、要求は拒否されます。
void LilFactoryExportPrefix * LilFactoryExportSuffix bipGetParserFactory() {
CciFactory* factoryObject; int rc; static CPI_VFT vftable = {CPI_VFT_DEFAULT};
initParserConstants();
vftable.iFpCreateContext = cpiCreateContext; vftable.iFpParseBufferEncoded = cpiParseBufferEncoded; vftable.iFpParseFirstChild = cpiParseFirstChild; vftable.iFpParseLastChild = cpiParseLastChild; vftable.iFpParsePreviousSibling = cpiParsePreviousSibling; vftable.iFpParseNextSibling = cpiParseNextSibling; vftable.iFpWriteBufferEncoded = cpiWriteBufferEncoded; vftable.iFpDeleteContext = cpiDeleteContext; vftable.iFpSetElementValue = cpiSetElementValue; vftable.iFpElementValue = cpiElementValue; vftable.iFpNextParserClassName = cpiNextParserClassName; vftable.iFpSetNextParserClassName = cpiSetNextParserClassName; vftable.iFpNextParserEncoding = cpiNextParserEncoding; vftable.iFpNextParserCodedCharSetId = cpiNextParserCodedCharSetId;
初期化関数は、cpiCreateParserFactory を呼び出すことによってパーサー・ファクトリーを作成する必要があります。 ファクトリーがサポートするパーサー・クラスは、cpiDefineParserClass を呼び出すことによって定義されます。ファクトリー・オブジェクトのアドレス (cpiCreateParserFactory によって戻される) は、 初期化関数からの戻り値としてブローカーに戻される必要があります。
factoryObject = cpiCreateParserFactory(&rc, constParserFactory);
if (factoryObject) { cpiDefineParserClass(&rc, factoryObject, constPXML, &vftable); } else { /* Error: Unable to create parser factory */ }
return(factoryObject); }
ユーザー定義パーサー・オブジェクトのインスタンスが作成されるときはいつでも、 コンテキスト作成インプリメンテーション関数 cpiCreateContext が、 メッセージ・ブローカーによって呼び出されます。 これによって、ユーザー定義パーサーは、属性用のデータ域など、 パーサーと関連付けられたインスタンス・データを割り振ることができます。
CciContext* cpiCreateContext( CciParser* parser ){ PARSER_CONTEXT_ST *p;
p = (PARSER_CONTEXT_ST *)malloc(sizeof(PARSER_CONTEXT_ST));
if (p) { memset(p, 0, sizeof(PARSER_CONTEXT_ST)); } else { /* Error: Unable to allocate memory */ }
return((CciContext*)p); }
以下では、各関数タイプについて説明します。
void cpiDeleteContext( CciParser* parser, CciContext* context ){ PARSER_CONTEXT_ST* pc = (PARSER_CONTEXT_ST *)context ; int rc = 0; return; }
注意 |
商標 |
ダウンロード |
ライブラリー |
技術サポート |
フィードバック
![]() ![]() |
as10010_ |