cniElementAsBitstream

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

ビット・ストリームを生成するために使用されるアルゴリズムは、使用中のパーサー、および指定されたオプションに応じて異なります。 すべてのパーサーは、以下のモードをサポートしています。
  • RootBitStream。 このモードでは、出力ノードで使用されているものと同じビット・ストリーム生成アルゴリズムが使用されます。 ただし、このモードでは、指示されているエレメントが適切な構造を持つサブツリーの始めにある場合にのみ、有効な結果が得られます。
  • EmbeddedBitStream。 このモードでは、出力ノードで使用されているものと同じビット・ストリーム生成アルゴリズムが判別されるだけではなく、以下のアルゴリズムも判別されます。この場合、明示的に指定されていなければ出力ノードと同様に判別されます。つまりアルゴリズムは、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
RFH2
<test><data><stuff>things</stuff></data></test>
ノードは、3 つのメッセージを伝搬します。そのうち 1 つのメッセージでは、BLOB ドメインに入力メッセージのコピーが入っています。 別のメッセージでは、BLOB ドメインに入力 RFH2 のコピーがメッセージ本体として入っています。 さらに別のメッセージでは、BLOB ドメインに <data></data> フォルダーがメッセージ本体として入っています。
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 RFH2*/
  /*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 RFH2 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, destinationList, exceptionList, outMsg[0]);
      retvalue = cniPropagate(&rc, terminalObject, destinationList, exceptionList, outMsg[1]);
      retvalue = cniPropagate(&rc, terminalObject, destinationList, 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, 2006 最終更新: 08/21/2006
as07885_