Obtém a representação de fluxo de bits do elemento especificado. O analisador que está 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 originais, por exemplo, um fluxo de bits que é lido de uma fila do WebSphere MQ pelo nó MQInput e a mensagem não foi modificada desde o recebimento do fluxo de bits original, esse fluxo de bits original será copiado na 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 as 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 o fluxo de bits para o corpo da mensagem de entrada*/ /*a segunda mensagem possui o fluxo de bits para a entrada RFH2*/ /*a terceira mensagem possui o 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); /*Configure 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;