Obtém a representação de fluxo de bits do elemento especificado. O analisador associado ao elemento serializa o elemento e todos os seus filhos. O resultado é copiado para a memória alocada pelo responsável pela chamada. No caso especial em que todas as opções especificadas correspondem às do fluxo de bits original, por exemplo, um fluxo de bits lido de uma fila do WebSphere MQ pelo nó MQInput, e a mensagem não foi modificada desde que recebeu o fluxo de bits original, esse fluxo de bits original é copiado para a memória alocada pelo usuário. Nesse caso, o analisador não precisa analisar e serializar novamente a mensagem.
Dessa forma, o algoritmo para determinar estas propriedades é essencialmente igual ao utilizado para a função ESQL BITSTREAM.
Alguns analisadores também suportam outro modo, FolderBitStream, que gera um fluxo de bits significativo para qualquer sub-árvore, desde que o campo apontado represente uma pasta.
CciSize cniElementAsBitstream( int* returnCode, CciElement* element, const struct CciByteArray* value, CciChar* messageType, CciChar* messageSet, CciChar* messageFormat, int encoding, int ccsid, int options);
O exemplo a seguir demonstra como o parâmetro de opções deve ser utilizado para gerar o fluxo de bits para diferentes partes da árvore de mensagens.
MQMDRFH2 <test><data><stuff>things</stuff></data></test>o nó propagará 3 mensagens, uma contendo uma cópia da mensagem de entrada no domínio BLOB. Uma contendo uma cópia da entrada RFH2 como o corpo da mensagem no domínio BLOB. Uma contendo a pasta <data></data> como o corpo da mensagem no domínio BLOB.
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); /*construir e propagar 3 mensagens de saída*/ /*a primeira mensagem possui fluxo de bits para o corpo da mensagem de entrada*/ /*a segunda mensagem possui fluxo de bits para a entrada RFH2*/ /*a terceira mensagem possui fluxo de bits para o subelemento da mensagem de entrada*/ /* Obter o elemento raiz da mensagem de entrada */ inRootElement=cniRootElement(&rc, message); /*CCI_CHECK_RC();*/ checkRC(rc); /*configurar a matriz de elementos de origem e opções de fluxos de bits*/ /*corpo da mensagem*/ inSourceElement[0] = cniLastChild(&rc,inRootElement); checkRC(rc); /*Essa é a raiz do corpo da mensagem, portanto, é utilizado o modo RootBitStream*/ bitstreamOptions[0] = CCI_BITSTREAM_OPTIONS_ROOT; /*último cabeçalho*/ inSourceElement[1] = cniPreviousSibling(&rc,inSourceElement[0]); checkRC(rc); /*Essa é a raiz do RFH2, portanto, é utilizado o modo RootBitStream*/ bitstreamOptions[1] = CCI_BITSTREAM_OPTIONS_ROOT; /*body.FIRST(primeiro filho do corpo da mensagem) */ inSourceElement[2] = cniFirstChild(&rc,inSourceElement[0]); checkRC(rc); /*body.FIRST.FIRST */ inSourceElement[2] = cniFirstChild(&rc,inSourceElement[2]); checkRC(rc); /*Essa é uma subárvore dentro do corpo da mensagem, portanto, é utilizado o modo FolderBitStream*/ bitstreamOptions[2] = CCI_BITSTREAM_OPTIONS_FOLDER; for (loopCount=0;loopCount<3;loopCount++) { int bufLength; /* Criar nova mensagem para saída */ outMsg[loopCount] = cniCreateMessage(&rc, cniGetMessageContext(&rc, message)); checkRC(rc); /* Obter o elemento raiz da mensagem de saída */ outRootElement = cniRootElement(&rc, outMsg[loopCount]); checkRC(rc); /* Copiar conteúdo da mensagem de entrada para a mensagem de saída */ cniCopyElementTree(&rc, inRootElement, outRootElement); checkRC(rc); /* Obter o último filho da raiz (ou seja, o corpo) */ bodyChild = cniLastChild(&rc, outRootElement); checkRC(rc); /*remover o corpo da mensagem que foi copiado da mensagem de entrada*/ cniDetach(&rc, bodyChild); checkRC(rc); /*criar o novo corpo da mensagem de saída no domínio BLOB*/ outBody = cniCreateElementAsLastChildUsingParser(&rc, outRootElement, constBLOBParserName); checkRC(rc); /*criar o elemento BLOB*/ outBlobElement = cniCreateElementAsLastChild(&rc, outBody); checkRC(rc); cniSetElementName(&rc, outBlobElement, constBLOBElementName); checkRC(rc); /*Configurar o valor do elemento blob obtendo o fluxo de bits para o elemento */ bitstream[loopCount].size=512; bitstream[loopCount].pointer=(CciByte*)malloc(sizeof(CciByte) * 512); bufLength = cniElementAsBitstream(&rc, inSourceElement[loopCount], &bitstream[loopCount], constEmptyString,/*assumir a mensagem XML sem nenhum interesse*/ constEmptyString,/* tipo, conjunto ou formato*/ constEmptyString, 0,/*Utilizar o CCSID do Gerenciador de Filas & Codificação*/ 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,/*assumir a mensagem XML sem nenhum interesse*/ constEmptyString,/* tipo, conjunto ou formato*/ constEmptyString, 0,/*Utilizar o CCSID do Gerenciador de Filas & Codificação*/ 0, bitstreamOptions[loopCount]); } checkRC(rc); bitstream[loopCount].size=bufLength; cniSetElementByteArrayValue(&rc, outBlobElement, &bitstream[loopCount]); checkRC(rc); } /* Obter manuseio do terminal de saída */ terminalObject = getOutputTerminalHandle( (NODE_CONTEXT_ST *)context, (CciChar*)constOut); /* Se o terminal existir e for anexado, propague-o */ if (terminalObject) { if (cniIsTerminalAttached(&rc, terminalObject)) { /* Como esta é uma mensagem nova e alterada, ela deve ser finalizada... */ 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) { /* Obter detalhes da exceção */ memset(&exception_st, 0, sizeof(exception_st)); cciGetLastExceptionData(&rc, &exception_st); /* Qualquer identificação de erros local pode ir aqui */ /* Assegurar-se de que a mensagem será excluída antes de retornar/emitir */ cniDeleteMessage(0, outMsg[0]); cniDeleteMessage(0, outMsg[1]); cniDeleteMessage(0, outMsg[2]); /* É necessário "reemitir" a exceção; observe que não há retorno */ cciRethrowLastException(&rc); } else { /* Algum outro erro...o plug-in pode escolher para registrá-lo utilizando a função de utilitário */ /* CciLog() } } else { } } } else { /* O terminal não existe...vários erros internos. O plug-in pode querer */ /* registrar um erro aqui, utilizando a função de utilitário cciLog(). */ } /* Excluir as mensagens criadas agora e finalizadas */ cniDeleteMessage(0, outMsg[0]); cniDeleteMessage(0, outMsg[1]); cniDeleteMessage(0, outMsg[2]); free((void*) constBLOBParserName); free((void*) constBLOBElementName); free((void*) constEmptyString); return;