cniElementAsBitstream

Obtiene la representación de corriente de bits del elemento especificado. El analizador asociado con el elemento serializa el elemento y todos los hijos. El resultado de copia en la memoria asignada por el canal de llamada. En el caso especial donde todas las opciones especificadas coinciden con las de la corriente de bits original, por ejemplo una corriente de bits leída desde una cola de WebSphere MQ por el nodo MQInput, y el mensaje no se ha modificado desde que se ha recibido la corriente de bits original, esta corriente de bits original se copia en la memoria asignada por el usuario. En este caso, no es necesario que el analizador analice y vuelva a serializar el mensaje.

El algoritmo utilizado para generar la corriente de bits depende del analizador que se utilice y de las opciones especificadas. Todos los analizadores dan soporte a las modalidades siguientes:
  • RootBitStream, en el que el algoritmo de generación de corriente de bits es el mismo que utiliza un nodo de salida. En esta modalidad, se obtiene un resultado significativo solamente si el elemento al que se apunta está a la cabeza de un subárbol con una estructura adecuada.
  • EmbeddedBitStream, en la que el algoritmo de generación de corriente de bits no sólo es el mismo que el que utiliza un nodo de salida sino que también se determinan los campos, si no especificados explícitamente, de la misma manera que el nodo de salida, lo que significa que se determinan buscando los elementos hermanos anteriores del elemento, suponiendo que estos representan cabeceras:
    • Codificación
    • CCSID
    • Conjunto de mensajes
    • Tipo de mensaje
    • Formato del mensaje

    De este modo, el algoritmo para determinar estas propiedades es esencialmente el mismo que se utiliza para la función BITSTREAM.

Algunos analizadores también dan soporte a otra modalidad, FolderBitStream, que genera una corriente de bits significativos para cualquier subárbol, siempre que el campo apuntado represente una carpeta.

Sintaxis

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
Código de retorno de la función (salida). La especificación de un puntero NULL significa que el nodo no desea tratar los errores. Si la entrada no es NULL, la salida significa el estado de éxito de la llamada. Las excepciones emitidas durante la ejecución de esta llamada se vuelven a emitir en el nodo ascendente siguiente del flujo. Invoque cciGetLastExceptionData para obtener información detallada de la excepción.
Los códigos de retorno posibles son:
  • CCI_SUCCESS
  • CCI_EXCEPTION
  • CCI_INV_ELEMENT_OBJECT
  • CCI_INV_DATA_POINTER
  • CCI_INV_DATA_BUFLEN
  • CCI_INV_BUFFER_TOO_SMALL
element
Elemento de sintaxis que se debe serializar (entrada).
Elemento de sintaxis que se debe serializar (entrada). Debe ser el último hijo de la raíz de mensaje.
value
Puntero a una estructura CciByteArray que contiene un puntero a una región de memoria asignada por el canal de llamada y el tamaño en CciBytes de esta memoria (salida).
messageType
Definición de tipo de mensaje utilizada para crear la corriente de bits desde el árbol de elementos (entrada. Un puntero NULL significa que se ignora este parámetro. Asimismo, si el analizador asociado con el elemento no tiene ningún interés en este valor, por ejemplo si es un analizador XML genérico, se ignora el parámetro.
messageSet
Definición de conjunto de mensajes utilizada para crear la corriente de bits desde el árbol de elementos (entrada). Un puntero NULL significa que se ignora este parámetro. Asimismo, si el analizador asociado con el elemento no tiene ningún interés en este valor, por ejemplo si es un analizador XML genérico, también se ignora el parámetro.
messageFormat
Formato utilizado para crear la corriente de bits desde el árbol de elementos (entrada). Un puntero NULL significa que se ignora este parámetro. Asimismo, si el analizador asociado con el elemento no tiene ningún interés en este valor, por ejemplo si es un analizador XML genérico, se ignora el parámetro.
encoding
Codificación a utilizar cuando se analiza la corriente de bits (entrada). Este parámetro es obligatorio. Puede especificar un valor de 0 para indicar que se debe utilizar la codificación del gestor de colas.
ccsid
Identificador de juego de caracteres codificado a utilizar cuando se graba la corriente de bits (entrada). Este parámetro es obligatorio. Puede especificar un valor de 0 para indicar que se debe utilizar el ccsid del gestor de colas. Un ccsid de -1 indica que la corriente de bits se debe generar utilizando la información de ccsid contenida en el subárbol que consta del campo apuntado por el elemento y sus hijos. Actualmente ningún analizador soporta esta opción.
options
Valor entero que especifica la modalidad de generación de corriente de bits que debe utilizarse. Puede tener uno de los siguientes valores:
  • CCI_BITSTREAM_OPTIONS_ROOT
  • CCI_BITSTREAM_OPTIONS_EMBEDDED
  • CCI_BITSTREAM_OPTIONS_FOLDER

Valores de retorno

  • Si la ejecución se realiza satisfactoriamente, se devuelve el tamaño correcto de memoria necesaria para contener la corriente de bits.
  • Si la memoria asignada por el canal de llamada no ha sido suficiente, returnCode se establece en CCI_BUFFER_TOO_SMALL.
  • Si se produce una excepción durante la ejecución, returnCode se establece en CCI_EXCEPTION.

Ejemplo

El ejemplo siguiente muestra cómo debe utilizarse el parámetro de opciones para generar la corriente de bits para distintas partes del árbol de mensaje.

Este código puede copiarse en la función _evaluate del nodo Transform de ejemplo. Para un mensaje de entrada como:
MQMD
RFH2
<test><data><stuff>things</stuff></data></test>
el nodo propagará 3 mensajes, uno con una copia del mensaje de entrada en el dominio BLOB. Otro con una copia del RFH2 de entrada como el cuerpo del mensaje en el dominio BLOB. Otro con la carpeta <data></data> como el cuerpo del mensaje en el dominio 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);

  /*crear y propagar mensajes de salida*/
  /*primer mensaje con corriente de bits para el cuerpo del mensaje de entrada*/
  /*segundo mensaje con corriente de bits para RFH2 de entrada*/
  /*tercer mensaje con corriente de bits para subelemento del mensaje de entrada*/

  /* Obtener el elemento raíz del mensaje de entrada */
  inRootElement=cniRootElement(&rc, message);
  /*CCI_CHECK_RC();*/
  checkRC(rc);

  /*establecer la matriz de opciones de corriente de bits y elementos origen*/

  /*cuerpo del mensaje*/
  inSourceElement[0] =  cniLastChild(&rc,inRootElement);
  checkRC(rc);

  /*Esta es la raíz del mensaje, por lo que se usa la modalidad RootBitStream*/
  bitstreamOptions[0] = CCI_BITSTREAM_OPTIONS_ROOT;

  
  /*última cabecera*/
  inSourceElement[1] = cniPreviousSibling(&rc,inSourceElement[0]);
  checkRC(rc);

  /*Esta es la raíz de RFH2, por lo que se usa la modalidad RootBitStream*/
  bitstreamOptions[1] = CCI_BITSTREAM_OPTIONS_ROOT;

  
  /*body.FIRST(primer hijo del cuerpo del mensaje) */
  inSourceElement[2] = cniFirstChild(&rc,inSourceElement[0]);
  checkRC(rc);
  
  /*body.FIRST.FIRST */
  inSourceElement[2] = cniFirstChild(&rc,inSourceElement[2]);
  checkRC(rc);

  /*Es un subárbol dentro del cuerpo del mensaje, se usa la modalidad FolderBitStream*/
  bitstreamOptions[2] = CCI_BITSTREAM_OPTIONS_FOLDER;

  
  for (loopCount=0;loopCount<3;loopCount++) {
    int bufLength;

    /* Crear nuevo mensaje para salida */
    outMsg[loopCount] = cniCreateMessage(&rc, cniGetMessageContext(&rc, message));
    checkRC(rc);

    /* Obtener el elemento raíz del mensaje de salida */
    outRootElement = cniRootElement(&rc, outMsg[loopCount]);
    checkRC(rc);

    /* Copiar el contenido del mensaje de entrada en el mensaje de salida */
    cniCopyElementTree(&rc, inRootElement, outRootElement);
    checkRC(rc);

    /* Obtener el último hijo del elemento raíz (por ej., el cuerpo)  */
    bodyChild = cniLastChild(&rc, outRootElement);
    checkRC(rc);

    /*desechar el cuerpo del mensaje que se ha copiado del mensaje de entrada*/
    cniDetach(&rc,
              bodyChild);
    checkRC(rc);

    /*crear el nuevo cuerpo del mensaje de salida en el dominio BLOB*/
    outBody = cniCreateElementAsLastChildUsingParser(&rc,
                                           outRootElement,
                                           constBLOBParserName);
    checkRC(rc);

    /*crear el elemento BLOB*/
    outBlobElement = cniCreateElementAsLastChild(&rc,
                                outBody);
    checkRC(rc);

    cniSetElementName(&rc,
                      outBlobElement,
                      constBLOBElementName);
    checkRC(rc);
    
    /*Establecer el valor del elemento blob obteniendo la corriente de bits para
    el elemento */
    bitstream[loopCount].size=512;
    bitstream[loopCount].pointer=(CciByte*)malloc(sizeof(CciByte) * 512);
    
    bufLength = cniElementAsBitstream(&rc,
                          inSourceElement[loopCount],
                          &bitstream[loopCount],
                          constEmptyString,/*suponemos mensaje XML, por lo que*/
                          constEmptyString,/*no interesa tipo, conjunto o formato*/
                          constEmptyString,
                          0,/*Usar CCSID & codificación de gestor de colas*/
                          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,/*suponemos mensaje XML, por lo que*/
                          constEmptyString,/*no interesa tipo, conjunto o formato*/
                          constEmptyString,
                          0,/*Usar CCSID & codificación de gestor de colas*/
                          0,
                          bitstreamOptions[loopCount]);      
    }
    checkRC(rc);
    bitstream[loopCount].size=bufLength;
    
    cniSetElementByteArrayValue(&rc,
                                outBlobElement,
                                &bitstream[loopCount]);
    checkRC(rc);
  }

  /* Obtener manejador de terminal de salida */
  terminalObject = getOutputTerminalHandle( (NODE_CONTEXT_ST *)context,
                                            (CciChar*)constOut);

  /* Si el terminal existe y se adjunta, propagar al mismo */
  if (terminalObject) {
    if (cniIsTerminalAttached(&rc, terminalObject)) {
      /* Al ser un mensaje nuevo y cambiado, debe finalizarse... */
      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) {
          			/* Obtener detalles de la excepción */
          memset(&exception_st, 0, sizeof(exception_st));
          cciGetLastExceptionData(&rc, &exception_st);

          /* Aquí puede ir cualquier manejo de errores locales */

          /* Asegúrese de que se suprime el mensaje antes de devolver/generar */
          cniDeleteMessage(0, outMsg[0]);
          cniDeleteMessage(0, outMsg[1]);
          cniDeleteMessage(0, outMsg[2]);

          /* Se debe volver a generar la excepción; observe que no regresa */
          cciRethrowLastException(&rc);
        }
        else {

          /* Algún otro error... el plugin puede elegir anotarlo utilizando la función */
          /* de programa de utilidad CciLog()                                          */

        }
      }
      else {
      }
    }
  }
  else {
    /* El terminal no existía... error interno grave. Es posible que el plugin */
    /* quiera anotar un error aquí utilizando la función de utilidad cciLog().                 */
  }

  /* Suprimir los mensajes que hemos creado; hemos terminado con ellos. */
  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 | Descargas | Biblioteca | Soporte | Su opinión
Copyright IBM Corporation 1999, 2006 Última actualización: 22/08/2006
as07885_