Use esta função para obter a representação de fluxo de bits do elemento especificado.
O analisador que está associado ao elemento serializa o elemento e todos os seus elementos filhos. O resultado é copiado para a memória alocada pelo responsável pela chamada. No caso especial em que todas as opções que foram especificadas correspondem àquelas do fluxo de bits original, por exemplo, um fluxo de bits que é lido a partir de uma fila do WebSphere MQ pelo nó do MQInput, e a mensagem não foi modificada desde o recebimento do fluxo de bits original, este fluxo de bits original é copiado na memória alocada. Neste caso, o analisador não é necessário para analisar e resserializar 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 é possível usar o parâmetro de opções para gerar o fluxo de bits para diferentes partes da árvore de mensagens.
MQMD
MQRFH2
<test><data><aaa>text</aaa></data></test>
o nó propaga três mensagens: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 MQRFH2*/
/*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 de MQRFH2, 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, 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) {
/* Obter detalhes da exceção */
memset(&exception_st, 0, sizeof(exception_st));
cciGetLastExceptionData(&rc, &exception_st);
/* Qualquer tratamento de erro 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 plugin talvez precise fazer */
/* registro de um erro aqui usando a função do 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;