C パーサーの機能の拡張

始める前に

以下のトピックを読み、理解していることを確認してください。

パーサー機能のインプリメント

パーサーは、以下のタイプのインプリメンテーション関数をインプリメントする必要があります。
  1. input 関数
  2. parse 関数
  3. output 関数

以下では、各関数タイプについて説明します。

input 関数のインプリメント

以下の 3 つの入力関数があります。 パーサーは、これらの入力関数のいずれか 1つだけをインプリメントする必要があります。

ユーザー定義パーサーが入力メッセージを構文解析する必要がある場合に、ブローカーは 入力関数を起動します。 パーサーは、所有する必要があるものとして要求する入力ビット・ストリーム・バッファーの量を、ブローカーに対して知らせなければなりません。固定サイズ・ヘッダーの場合、パーサーはヘッダーのサイズを要求します。 パーサーがメッセージ全体を処理する場合、バッファーの残りの部分を要求します。

以下に例を示します。
  1. ブローカーは、以下の cpiParseBufferEncoded 入力関数を起動します。
    int cpiParseBufferEncoded(
      CciParser*     parser,
      CciContext* context,
      int            encoding,
      int         ccsid
    ){
      PARSER_CONTEXT_ST* pc = (PARSER_CONTEXT_ST *)context ;
      int             rc;
  2. 以下の cpiBufferPointer ユーティリティー関数を使用してメッセージ・バッファーへのポインターを取得し、オフセットを設定します。
      pc->iBuffer = (void *)cpiBufferPointer(&rc, parser);
      pc->iIndex = 0;
  3. バッファーのフォーマットを保管します。
      pc->iEncoding = encoding;
      pc->iCcsid = ccsid;
  4. cpiBufferSize ユーティリティー関数を使用して、バッファーのサイズを保管します。
      pc->iSize = cpiBufferSize(&rc, parser);
  5. cpiBufferByte ユーティリティー関数を使用して、ストリーム内の先頭バイトの事前準備をします。
      pc->iCurrentCharacter = cpiBufferByte(&rc, parser, pc->iIndex);
  6. cpiRootElement ユーティリティー関数を使用して、 現行エレメントをルート・エレメントに設定します。
      pc->iCurrentElement = cpiRootElement(&rc, parser);
  7. フラグをリセットして、構文解析が正しくリセットされるようにします。
      pc->iInTag = 0;
  8. 残りのバッファーの所有権を請求します。
      return(pc->iSize);
    }

parse 関数のインプリメント

汎用解析関数 (例えば、cpiParseFirstChild) は、 ESQL 式または Java 式を評価するために構文エレメント・ツリーを作成する必要がある場合に、 ブローカーが呼び出す関数です。例えば、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 関数のインプリメント

以下の 3 つの出力関数があります。 パーサーは、これらの出力関数のいずれか 1 つだけをインプリメントする必要があります。

ユーザー定義パーサーが構文エレメント・ツリーを出力ビット・ストリームに逐次化する必要がある場合に、ブローカーは出力関数を起動します。 例えば、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 関数をインプリメントする必要があります

以下に例を示します。
  1. cpiNextParserClassName 関数を呼び出します。
    void cpiNextParserClassName(
      CciParser*     parser,
      CciContext* context,
      CciChar*     buffer,
      int         size
    ){
      PARSER_CONTEXT_ST* pc = (PARSER_CONTEXT_ST *)context ;
      int rc = 0;
  2. 次のパーサー・クラスの名前をブローカーにコピーします。
      CciCharNCpy(buffer, pc->iNextParserClassName, size);
    
      return;
    }
特記事項 | 商標 | ダウンロード | ライブラリー | サポート | フィードバック
Copyright IBM Corporation 1999, 2006 最終更新: 08/21/2006
as24980_