指定したエレメントのビット・ストリーム表現を取得します。 エレメントに関連付けられたパーサーは、このエレメントとそのすべての子を逐次化します。 結果は、呼び出し側によって割り振られたメモリーにコピーされます。 指定されたすべてのオプションがオリジナルのビット・ストリーム (例えば、MQInput ノードによって WebSphere MQ キューから読み取られたビット・ストリーム) のオプションと一致しており、オリジナルのビット・ストリームを受け取った後でメッセージが変更されていない特殊なケースでは、このオリジナルのビット・ストリームはユーザーによって割り振られたメモリーにコピーされます。 この場合、パーサーは構文解析を行ってメッセージを再び逐次化する必要はありません。
このように、これらのプロパティーを判別するアルゴリズムは 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);
以下の例は、オプション・パラメーターを使用してメッセージ・ツリーのさまざまな部分のビット・ストリームを生成する方法を示しています。
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;