cniElementAsBitstream

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.

O algoritmo utilizado para gerar o fluxo de bits depende do analisador sendo utilizado e das opções especificadas. Todos os analisadores suportam os seguintes modos:
  • RootBitStream, no qual o algoritmo de geração do fluxo de bits é igual ao utilizado por um nó de saída. Neste modo, um resultado significativo é obtido apenas se o elemento apontado estiver no topo de uma subárvore com uma estrutura apropriada.
  • EmbeddedBitStream, o qual não é apenas o algoritmo de geração de fluxo de bits igual ao utilizado por um nó de saída, mas também os seguintes são determinados, se não explicitamente especificados, da mesma forma que o nó de saída, que significa que eles são determinados pela procura dos irmãos anteriores do elemento na hipótese de que estes representam os cabeçalhos:
    • Codificação
    • CCSID
    • Conjunto de Mensagens
    • Tipo de Mensagem
    • Formato de 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.

Sintaxe

CciSize cniElementAsBitstream(
    int*            returnCode,
    CciElement*      element,
    const struct CciByteArray* value,
    CciChar*                   messageType,
    CciChar*                   messageSet,
    CciChar*                   messageFormat,
    int            encoding,
    int            ccsid,
    int                        options);

Parâmetros

returnCode
O código de retorno da função (saída). Especificar um ponteiro NULL significa que o nó não deseja lidar com erros. Se a entrada não for NULL, a saída significa o status de êxito da chamada. Quaisquer exceções lançadas durante a execução desta chamada serão lançadas novamente para o próximo nó acima no fluxo. Chame cciGetLastExceptionData para obter detalhes da exceção.Os possíveis códigos de retorno são:
  • CCI_SUCCESS
  • CCI_EXCEPTION
  • CCI_INV_ELEMENT_OBJECT
  • CCI_INV_DATA_POINTER
  • CCI_INV_DATA_BUFLEN
  • CCI_INV_BUFFER_TOO_SMALL
elemento
O elemento de sintaxe a ser serializado (entrada).
O elemento de sintaxe a ser serializado (entrada). Deve ser o último filho da raiz da mensagem.
value
Um ponteiro para uma estrutura CciByteArray contendo um ponteiro para uma região de memória alocada pelo responsável pela chamada, e o tamanho em CciBytes dessa memória (saída).
messageType
A definição de tipo de mensagem utilizada para criar o fluxo de bits a partir da árvore de elementos (entrada). Um ponteiro NULL significa que este parâmetro é ignorado. Além disso, se o analisador associado ao elemento não tiver interesse neste valor, por exemplo, se ele for um analisador XML genérico, o parâmetro é ignorado.
messageSet
A definição de conjunto de mensagem utilizada para criar o fluxo de bits a partir da árvore de elementos (entrada). Um ponteiro NULL significa que este parâmetro é ignorado. Além disso, se o analisador associado ao elemento não tiver interesse neste valor, por exemplo, se ele for um analisador XML genérico, o parâmetro também é ignorado.
messageFormat
O formato utilizado para criar o fluxo de bits a partir da árvore de elementos (entrada). Um ponteiro NULL significa que este parâmetro é ignorado. Além disso, se o analisador associado ao elemento não tiver interesse neste valor, por exemplo, se ele for um analisador XML genérico, o parâmetro é ignorado.
encoding
A codificação a ser utilizada ao gravar o fluxo de bits (entrada). Esse parâmetro é obrigatório. Você pode especificar um valor de 0 para indicar que a codificação do gerenciador de filas deve ser utilizada.
ccsid
O identificador do conjunto de caracteres codificado a ser utilizado ao gravar o fluxo de bits (entrada). Esse parâmetro é obrigatório. Você pode especificar um valor de 0 para indicar que o ccsid do gerenciador de filas deve ser utilizado. Um ccsid de -1 indica que o fluxo de bits deve ser gerado, utilizando informações de ccsid contidas na subárvore, consistindo no campo apontado pelo elemento e seus filhos. Atualmente nenhum analisador suporta essa função.
options
O valor inteiro que especifica o modo de geração de fluxo de bits deve ser utilizado. Ele pode ter um dos seguinte valores:
  • CCI_BITSTREAM_OPTIONS_ROOT
  • CCI_BITSTREAM_OPTIONS_EMBEDDED
  • CCI_BITSTREAM_OPTIONS_FOLDER

Valores de Retorno

  • Se bem-sucedida, o tamanho correto de memória necessária para conter o fluxo de bits é retornado.
  • Se a memória alocada pelo responsável pela chamada era insuficiente, returnCode é definido como CCI_BUFFER_TOO_SMALL.
  • Se uma exceção ocorrer durante a execução, returnCode é definido como CCI_EXCEPTION.

Exemplo

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.

Esse código pode ser copiado na função _evaluate do nó Transform de amostra. Para uma mensagem de entrada tal como:
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;
Avisos | Marcas Registradas | Downloads | Biblioteca | Suporte | Feedback
Direitos Autorais IBM Corporation 1999, 2005 Última Atualização: 04/11/2005
as07885_