cniElementAsBitstream

指定したエレメントのビット・ストリーム表現を取得します。 エレメントに関連付けられたパーサーは、このエレメントとそのすべての子を逐次化します。 結果は、呼び出し側によって割り振られたメモリーにコピーされます。 指定されたすべてのオプションがオリジナルのビット・ストリーム (例えば、MQInput ノードによって WebSphere® MQ キューから読み取られたビット・ストリーム) のオプションと一致しており、オリジナルのビット・ストリームを受け取った後でメッセージが変更されていない特殊なケースでは、このオリジナルのビット・ストリームは割り振られたメモリーにコピーされます。 この場合、パーサーは構文解析を行ってメッセージを再び逐次化する必要はありません。

ビット・ストリームを生成するために使用されるアルゴリズムは、使用されるパーサー、および指定されたオプションに応じて異なります。 すべてのパーサーは、以下のモードをサポートしています。
  • RootBitStream。このモードでは、出力ノードで使用されているものと同じビット・ストリーム生成アルゴリズムが使用されます。ただし、このモードでは、指示されているエレメントが適切な構造を持つサブツリーの始めにある場合にのみ、有効な結果が得られます。
  • このモードでは、出力ノードで使用されているものと同じビット・ストリーム生成アルゴリズムが判別されるだけではなく、以下のエレメントも判別されます。この場合、明示的に指定されていなければ出力ノードと同様に判別されます。 そのため、element の直前の兄弟がヘッダーを表すと想定して、これらのエレメントを検索することによって判別されます。
    • Encoding
    • CCSID
    • Message set
    • Message type
    • Message format

    このように、これらのプロパティーを判別するアルゴリズムは ESQL BITSTREAM 関数で使用されるものと実質的に同じです。

パーサーの中には、FolderBitStream という別のモードをサポートしているものもあります。このモードでは、指示されているフィールドがフォルダーを表していれば、どのようなサブツリーでも有効なビット・ストリームが生成されます。

構文

CciSize cniElementAsBitstream(
  int*                       returnCode,
  CciElement*                element,
  const struct CciByteArray* value,
  CciChar*                   messageType,
  CciChar*                   messageSet,
  CciChar*                   messageFormat,
  int                        encoding,
  int                        ccsid,
  int                        options);

パラメーター

returnCode
関数からの戻りコード (出力)。入力に NULL ポインターを指定すると、その値はノードがエラーを処理しないことを示します。入力が NULL でない場合、出力は呼び出しの成功状況を示します。 この呼び出しの実行時にスローされた例外は、フロー内の次のアップストリーム・ノードに対して再度スローされます。 この例外の詳細については、cciGetLastExceptionData を呼び出してください。
考えられる戻りコードは以下のとおりです。
  • CCI_SUCCESS
  • CCI_EXCEPTION
  • CCI_INV_ELEMENT_OBJECT
  • CCI_INV_DATA_POINTER
  • CCI_INV_DATA_BUFLEN
  • CCI_INV_BUFFER_TOO_SMALL
element
逐次化される構文エレメント (入力)。
value
呼び出し側によって割り振られたメモリー領域へのポインターを含む CciByteArray 構造へのポインター。 このメモリーの CciBytes 単位のサイズでもあります (出力)。
messageType
エレメント・ツリーからビット・ストリームを作成するために使用されるメッセージ・タイプ定義 (入力)。NULL ポインターを指定すると、パラメーターは無視されます。また、エレメントに関連したパーサーが値と関連がない場合 (例えば、汎用 XML パーサーの場合) にも、このパラメーターは無視されます。
messageSet
エレメント・ツリーからビット・ストリームを作成するために使用されるメッセージ・セット定義 (入力)。NULL ポインターを指定すると、パラメーターは無視されます。また、エレメントに関連したパーサーが値と関連がない場合 (例えば、汎用 XML パーサーの場合) にも、このパラメーターは無視されます。
messageFormat
エレメント・ツリーからビット・ストリームを作成するために使用される形式 (入力)。 NULL ポインターを指定すると、パラメーターは無視されます。また、エレメントに関連したパーサーが値と関連がない場合 (例えば、汎用 XML パーサーの場合) にも、このパラメーターは無視されます。
encoding
ビット・ストリームを作成する際に使用するエンコード方式 (入力)。このパラメーターは必須です。 値 0 を指定して、キュー・マネージャーのエンコード方式を使用するように指示することができます。
ccsid
ビット・ストリームを作成する際に使用する コード化文字セット ID (入力)。このパラメーターは必須です。 0 の値を指定すると、キュー・マネージャーの ccsid が使用されます。ccsid が -1 の場合は、エレメントによって指し示されるフィールドとその子で構成されるサブツリー内の CCSID 情報を使用して、ビット・ストリームが生成されることを示します。 このオプションをサポートするパーサーはありません。
options
どのビット・ストリーム生成モードを使用するかを指定する整数値。 以下のいずれかの値を設定します。
  • CCI_BITSTREAM_OPTIONS_ROOT
  • CCI_BITSTREAM_OPTIONS_EMBEDDED
  • CCI_BITSTREAM_OPTIONS_FOLDER

戻り値

  • 成功した場合、ビット・ストリームを保持するために必要なメモリーの正しいサイズが戻されます。
  • 呼び出し側によって割り振られたメモリーが不十分な場合、returnCode は CCI_BUFFER_TOO_SMALL です。
  • 実行時に例外が発生する場合、returnCode は CCI_EXCEPTION です。

以下の例は、オプション・パラメーターを使用してメッセージ・ツリーのさまざまな部分のビット・ストリームを生成する方法を示しています。

このコードは、サンプルの Transform ノードの _evaluate 関数にコピーできます。 次のような入力メッセージの場合:
MQMD
MQRFH2
<test><data><foo>text</foo></data></test>
ノードは 3 つのメッセージを伝搬します。BLOB ドメインにある入力メッセージのコピーを含むメッセージ、BLOB ドメインにあるメッセージ本体としての入力 MQRFH2 のコピーを含むメッセージ、および BLOB ドメインにあるメッセージ本体としての <data></data> フォルダーを含むメッセージの 3 種類です。
CciMessage* outMsg[3];
  CciTerminal* terminalObject;
  CciElement* bodyChild;
  CciElement* inRootElement;
  CciElement* inSourceElement[3];
  CciElement* outRootElement;
  CciElement* outBlobElement;
  CciElement* outBody;
  struct CciByteArray bitstream[3];
  int bitstreamOptions[3];
  int retvalue;
  int rc = 0;
  int loopCount;
  CCI_EXCEPTION_ST exception_st = {CCI_EXCEPTION_ST_DEFAULT};
  const CciChar* constBLOBParserName =
                 cciString("NONE",BIP_DEF_COMP_CCSID);
  const CciChar* constBLOBElementName =
                 cciString("BLOB",BIP_DEF_COMP_CCSID);
  const CciChar* constEmptyString =
                 cciString("",BIP_DEF_COMP_CCSID);

  /*build up and propagate 3 output messages*/
  /*first message has bit stream for input message body*/
  /*second message has bit stream for input MQRFH2*/
  /*third message has bit stream for sub element from input message*/

  /* Get the root element of the input message */
  inRootElement = cniRootElement(&rc, message);
  /*CCI_CHECK_RC();*/
  checkRC(rc);

  /*set up the array of source elements and bitstream options*/

  /*message body*/
  inSourceElement[0] = cniLastChild(&rc,inRootElement);
  checkRC(rc);

  /*This is the root of the message body so we use RootBitStream mode*/
  bitstreamOptions[0] = CCI_BITSTREAM_OPTIONS_ROOT;

  
  /*last header*/
  inSourceElement[1] = cniPreviousSibling(&rc,inSourceElement[0]);
  checkRC(rc);

  /*This is the root of the MQRFH2 so we use RootBitStream mode*/
  bitstreamOptions[1] = CCI_BITSTREAM_OPTIONS_ROOT;

  
  /*body.FIRST(first child of message body) */
  inSourceElement[2] = cniFirstChild(&rc,inSourceElement[0]);
  checkRC(rc);
  
  /*body.FIRST.FIRST */
  inSourceElement[2] = cniFirstChild(&rc,inSourceElement[2]);
  checkRC(rc);

  /*This is a sub tree within the message body so we use FolderBitStream mode*/
  bitstreamOptions[2] = CCI_BITSTREAM_OPTIONS_FOLDER;

  
  for (loopCount=0;loopCount<3;loopCount++) {
    int bufLength;

    /* Create new message for output */
    outMsg[loopCount] = cniCreateMessage(&rc, cniGetMessageContext(&rc, message));
    checkRC(rc);

    /* Get the root element of the output message */
    outRootElement = cniRootElement(&rc, outMsg[loopCount]);
    checkRC(rc);

    /* Copy the contents of the input message to the output message */
    cniCopyElementTree(&rc, inRootElement, outRootElement);
    checkRC(rc);

    /* Get the last child of root (ie the body) */
    bodyChild = cniLastChild(&rc, outRootElement);
    checkRC(rc);

    /*throw away the message body which was copied from the input message*/
    cniDetach(&rc,
              bodyChild);
    checkRC(rc);

    /*create the new output message body in the BLOB domain*/
    outBody = cniCreateElementAsLastChildUsingParser(&rc,
                                           outRootElement,
                                           constBLOBParserName);
    checkRC(rc);

    /*create the BLOB element*/
    outBlobElement = cniCreateElementAsLastChild(&rc,
                                outBody);
    checkRC(rc);

    cniSetElementName(&rc,
                      outBlobElement,
                      constBLOBElementName);
    checkRC(rc);
    
    /*Set the value of the blob element by obtaining the bit stream for the
    element */
    bitstream[loopCount].size=512;
    bitstream[loopCount].pointer=(CciByte*)malloc(sizeof(CciByte) * 512);
    
    bufLength = cniElementAsBitstream(&rc,
                          inSourceElement[loopCount],
                          &bitstream[loopCount],
                          constEmptyString,/*assume XML message so no interest in*/
                          constEmptyString,/* type, set or format*/
                          constEmptyString,
                          0,/*Use Queue Manager CCSID & Encoding*/
                          0,
                          bitstreamOptions[loopCount]);
    

    if (rc==CCI_BUFFER_TOO_SMALL)
    {
        free(bitstream[loopCount].pointer);
        bitstream[loopCount].size=bufLength;
        bitstream[loopCount].pointer=(CciByte*)malloc(sizeof(CciByte) * bitstream[loopCount].size);

        bufLength = cniElementAsBitstream(&rc,
                          inSourceElement[loopCount],
                          &bitstream[loopCount],
                          constEmptyString,/*assume XML message so no interest in*/
                          constEmptyString,/* type, set or format*/
                          constEmptyString,
                          0,/*Use Queue Manager CCSID & Encoding*/
                          0,
                          bitstreamOptions[loopCount]);
    }
    checkRC(rc);
    bitstream[loopCount].size=bufLength;
    
    cniSetElementByteArrayValue(&rc,
                                outBlobElement,
                                &bitstream[loopCount]);
    checkRC(rc);
  }

  /* Get handle of output terminal */
  terminalObject = getOutputTerminalHandle( (NODE_CONTEXT_ST *)context,
                                            (CciChar*)constOut);

  /* If the terminal exists and is attached, propagate to it */
  if (terminalObject) {
    if (cniIsTerminalAttached(&rc, terminalObject)) {
      /* As this is a new, and changed message, it should be finalized... */
      cniFinalize(&rc, outMsg[0], CCI_FINALIZE_NONE);
      cniFinalize(&rc, outMsg[1], CCI_FINALIZE_NONE);
      cniFinalize(&rc, outMsg[2], CCI_FINALIZE_NONE);
      retvalue = cniPropagate(&rc, terminalObject, localEnvironment, exceptionList, outMsg[0]);
      retvalue = cniPropagate(&rc, terminalObject, localEnvironment, exceptionList, outMsg[1]);
      retvalue = cniPropagate(&rc, terminalObject, localEnvironment, exceptionList, outMsg[2]);
      if (retvalue == CCI_FAILURE) {
        if (rc == CCI_EXCEPTION) {
          /* Get details of the exception */
          memset(&exception_st, 0, sizeof(exception_st));
          cciGetLastExceptionData(&rc, &exception_st);

          /* Any local error handling may go here */

          /* Ensure message is deleted prior to return/throw */
          cniDeleteMessage(0, outMsg[0]);
          cniDeleteMessage(0, outMsg[1]);
          cniDeleteMessage(0, outMsg[2]);

          /* We must "rethrow" the exception; note this does not return */
          cciRethrowLastException(&rc);
        }
        else {

          /* Some other error...the plugin might choose to log it using the CciLog() */
          /* utility function */

        }
      }
      else {
      }
    }
  }
  else {
    /* Terminal did not exist...severe internal error. The plugin may wish to */
    /* log an error here using the cciLog() utility function.                 */
  }

  /* Delete the messages we created now we have finished with them */
  cniDeleteMessage(0, outMsg[0]);
  cniDeleteMessage(0, outMsg[1]);
  cniDeleteMessage(0, outMsg[2]);

  free((void*) constBLOBParserName);
  free((void*) constBLOBElementName);
  free((void*) constEmptyString);
  return;
特記事項 | 商標 | ダウンロード | ライブラリー | サポート | フィードバック

Copyright IBM Corporation 1999, 2009Copyright IBM Corporation 1999, 2009.
最終更新 : 2009-02-20 12:44:36

as07885_