cniElementAsBitstream

Fornisce la rappresentazione flusso di bit dell'elemento specificato. Il programma di analisi associato all'elemento serializza l'elemento e tutti i relativi child. Il risultato viene copiato nella memoria assegnata da chi esegue la chiamata. Nel caso in cui tutte le opzioni specificate corrispondano a quelle del flusso di bit di origine, ad esempio un flusso di bit letto da una coda WebSphere MQ dal nodo MQInput e il messaggio non è stato modificato da quando è stato ricevuto il flusso di bit di origine, tale flusso viene copiato nella memoria assegnata dall'utente. In tale caso, non è richiesto al programma di analisi di analizzare e serializzare di nuovo il messaggio.

L'algoritmo utilizzato per creare il flusso di bit dipende dal programma di analisi utilizzato e dalle opzioni specificate. Tutti i programmi di analisi supportano le seguenti modalità:
  • RootBitStream, in cui l'algoritmo di creazione del flusso di bit è lo stesso di quello utilizzato da un nodo di output. In tale modalità, si ottiene un risultato significativo solo se l'elemento a cui si esegue il puntamento è in testa ad una struttura ad albero secondaria con una struttura appropriata.
  • EmbeddedBitStream, in cui non solo l'algoritmo di creazione del flusso di bit è lo stesso di quello utilizzato da un nodo di output, ma anche i seguenti sono determinati, se non specificato esplicitamente, nello stesso modo del nodo di output; ciò significa che sono determinati dalla ricerca degli elementi associati precedenti di element presupponendo che questi rappresentano le intestazioni:
    • Codifica
    • CCSID
    • Serie di messaggi
    • Tipo di messaggio
    • Formato del messaggio

    In questo modo, l'algoritmo per la determinazione di tali proprietà è essenzialmente lo stesso di quello utilizzato per la funzione ESQL BITSTREAM.

Alcuni programmi di analisi supportano anche la modalità FolderBitStream, che genera un flusso di bit valido per qualsiasi struttura ad albero secondaria, purché il campo indicato rappresenti una cartella.

Sintassi

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

Parametri

returnCode
Il codice di ritorno dalla funzione (output). Se si specifica un puntatore NULL significa che il nodo non intende gestire gli errori. Se l'input è diverso da NULL, l'output indica lo stato positivo della chiamata. Eventuali eccezioni generate durante l'esecuzione di questa chiamata, vengono generate nuovamente nel nodo successivo a monte del flusso. Per informazioni dettagliate relative all'eccezione, richiamare cciGetLastExceptionData.
I codici di ritorno possibili sono:
  • CCI_SUCCESS
  • CCI_EXCEPTION
  • CCI_INV_ELEMENT_OBJECT
  • CCI_INV_DATA_POINTER
  • CCI_INV_DATA_BUFLEN
  • CCI_INV_BUFFER_TOO_SMALL
element
L'elemento di sintassi di cui deve essere eseguita la serializzazione (input.)
L'elemento di sintassi di cui deve essere eseguita la serializzazione (input.) Deve essere l'ultimo child del root del messaggio.
value
Un puntatore su uno struct CciByteArray contenente un puntatore ad una parte di memoria assegnata da chi esegue la chiamata e la dimensione in CciBytes di tale memoria (output).
messageType
La definizione del tipo di messaggio utilizzata per creare il flusso di bit dalla struttura ad albero dell'elemento (input). Un puntatore NULL indica che questo parametro viene ignorato. Inoltre, se il programma di analisi associato all'elemento non è interessato a questo valore, ad esempio, se è un programma di analisi XML generico, il parametro viene ignorato.
messageSet
La definizione della serie di messaggi utilizzata per creare il flusso di bit dalla struttura ad albero dell'elemento (input). Un puntatore NULL indica che questo parametro viene ignorato. Inoltre, se il programma di analisi associato all'elemento non è interessato a questo valore, ad esempio, se è un programma di analisi XML generico, il parametro viene ignorato.
messageFormat
Il formato utilizzato per creare il flusso di bit dalla struttura ad albero dell'elemento (input). Un puntatore NULL indica che questo parametro viene ignorato. Inoltre, se il programma di analisi associato all'elemento non è interessato a questo valore, ad esempio, se è un programma di analisi XML generico, il parametro viene ignorato.
encoding
La codifica da utilizzare quando viene scritto il flusso di bit (input). Questo parametro è obbligatorio. E' possibile specificare un valore 0 per indicare che deve essere utilizzata la codifica del gestore code.
ccsid
Il CCSID (Coded Character Set Identifier) da utilizzare quando viene scritto il flusso di bit (input). Questo parametro è obbligatorio. E' possibile specificare un valore 0 per indicare che deve essere utilizzato il ccsid del gestore code. Un ccsid corrispondente a -1 indica che il flusso di bit deve essere creato utilizzando le informazioni ccsid contenute nella struttura ad albero secondaria consistente nel campo in cui l'elemento esegue il puntamento e nei relativi child. Attualmente nessun programma di analisi supporta questa opzione.
options
Valore intero che specifica quale modalità di creazione del flusso di bit deve essere utilizzata. Può assumere uno dei seguenti valori:
  • CCI_BITSTREAM_OPTIONS_ROOT
  • CCI_BITSTREAM_OPTIONS_EMBEDDED
  • CCI_BITSTREAM_OPTIONS_FOLDER

Valori di restituzione

  • Con un esito positivo, viene restituita la dimensione esatta di memoria necessaria a contenere il flusso di bit.
  • Se la memoria assegnata da chi esegue la chiamata non era sufficiente, returnCode è impostato su CCI_BUFFER_TOO_SMALL.
  • Se durante l'esecuzione si verifica un'eccezione, returnCode è impostato su CCI_EXCEPTION.

Esempio

Nell'esempio riportato di seguito viene indicato come utilizzare il parametro delle opzioni per creare il flusso di bit per parti diverse della struttura ad albero del messaggio.

Tale codice può essere copiato nella funzione _evaluate del nodo Transform di esempio. Relativamente ad un messaggio di input quale:
MQMD
RFH2
<test><data><stuff>things</stuff></data></test>
il nodo eseguirà l'invio di 3 messaggi, uno contenente una copia del messaggio di input nel dominio BLOB. Uno contenente una copia di RFH2 di input come contenuto del messaggio nel dominio BLOB. Uno contenente la cartella <data></data> come contenuto del messaggio nel 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);

  /*crea e invia 3 messaggi di output*/
  /*il primo messaggio ha un flusso di bit per il contenuto del messaggio di input*/
  /*il secondo messaggio ha un flusso di bit per RFH2 di input*/
  /*il terzo messaggio ha un flusso di bit per l'elemento secondario del messaggio di input*/

  /* Fornisce l'elemento root del messaggio di input */
  inRootElement = cniRootElement(&rc, message);
  /*CCI_CHECK_RC();*/
  checkRC(rc);

  /*imposta l'array degli elementi di origine e le opzioni del flusso di bit*/

  /*message body*/
  inSourceElement[0] =  cniLastChild(&rc,inRootElement);
  checkRC(rc);

  /*Questo è il root del contenuto del messaggio viene quindi usata la modalità RootBitStream*/
  bitstreamOptions[0] = CCI_BITSTREAM_OPTIONS_ROOT;

  
  /*ultima intestazione*/
  inSourceElement[1] = cniPreviousSibling(&rc,inSourceElement[0]);
  checkRC(rc);

  /*Questo è il root di RFH2 viene quindi usata la modalità RootBitStream*/
  bitstreamOptions[1] = CCI_BITSTREAM_OPTIONS_ROOT;

  
  /*body.FIRST(primo child del contenuto del messaggio) */
  inSourceElement[2] = cniFirstChild(&rc,inSourceElement[0]);
  checkRC(rc);
  
  /*body.FIRST.FIRST */
  inSourceElement[2] = cniFirstChild(&rc,inSourceElement[2]);
  checkRC(rc);

  /*Questa è una struttura ad albero secondaria dentro il contenuto del messaggio viene quindi usata la modalità FolderBitStream*/
  bitstreamOptions[2] = CCI_BITSTREAM_OPTIONS_FOLDER;

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

    /* Crea un nuovo messaggio per output */
    outMsg[loopCount] = cniCreateMessage(&rc, cniGetMessageContext(&rc, message));
    checkRC(rc);

    /* Fornisce l'elemento root del messaggio di output */
    outRootElement = cniRootElement(&rc, outMsg[loopCount]);
    checkRC(rc);

    /* Copia il contenuto del messaggio di input nel messaggio di output */
    cniCopyElementTree(&rc, inRootElement, outRootElement);
    checkRC(rc);

    /* Fornisce l'ultimo child di root (ad esempio il contenuto)  */
    bodyChild = cniLastChild(&rc, outRootElement);
    checkRC(rc);

    /*elimina il contenuto del messaggio copiato dal messaggio di input*/
    cniDetach(&rc,
              bodyChild);
    checkRC(rc);

    /*crea il nuovo contenuto del messaggio di output nel dominio BLOB*/
    outBody = cniCreateElementAsLastChildUsingParser(&rc,
                                           outRootElement,
                                           constBLOBParserName);
    checkRC(rc);

    /*crea l'elemento BLOB*/
    outBlobElement = cniCreateElementAsLastChild(&rc,
                                outBody);
    checkRC(rc);

    cniSetElementName(&rc,
                      outBlobElement,
                      constBLOBElementName);
    checkRC(rc);
    
    /*Imposta il valore dell'elemento blob ottenendo il flusso di bit per
    l'elemento */
    bitstream[loopCount].size=512;
    bitstream[loopCount].pointer=(CciByte*)malloc(sizeof(CciByte) * 512);
    
    bufLength = cniElementAsBitstream(&rc,
                          inSourceElement[loopCount],
                          &bitstream[loopCount],
                          constEmptyString,/*assume messaggio XML quindi nessun interesse in*/
                          constEmptyString,/* tipo, serie o formato*/
                          constEmptyString,
                          0,/*Utilizza la codifica e il CCSID del gestore code*/
                          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,/*assume messaggio XML quindi nessun interesse in*/
                          constEmptyString,/* tipo, serie o formato*/
                          constEmptyString,
                          0,/*Utilizza la codifica e il CCSID del gestore code*/
                          0,
                          bitstreamOptions[loopCount]);      
    }
    checkRC(rc);
    bitstream[loopCount].size=bufLength;
    
    cniSetElementByteArrayValue(&rc,
                                outBlobElement,
                                &bitstream[loopCount]);
    checkRC(rc);
  }

  /* Fornisce l'handle del terminale di output */
  terminalObject = getOutputTerminalHandle( (NODE_CONTEXT_ST *)context,
                                            (CciChar*)constOut);

  /* Se il terminale esiste ed è collegato, ne esegue la distribuzione */
  if (terminalObject) {
    if (cniIsTerminalAttached(&rc, terminalObject)) {
      /* Poiché questo è un messaggio nuovo e modificato, deve essere finalizzato... */
      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) {
          /* Fornisce i dettagli dell'eccezione */
          memset(&exception_st, 0, sizeof(exception_st));
          cciGetLastExceptionData(&rc, &exception_st);

          /* L'eventuale gestione errori locale può essere inserita qui */

          /* Accerta che il messaggio venga eliminato prima di restituire/generare */
          cniDeleteMessage(0, outMsg[0]);
          cniDeleteMessage(0, outMsg[1]);
          cniDeleteMessage(0, outMsg[2]);

          /* E' necessario "generare nuovamente" l'eccezione; verificare che questo non restituisca */
          cciRethrowLastException(&rc);
        }
        else {

          /* Qualche altro errore...il plugin potrebbe decidere di registrarlo utilizzando la funzione di */
          /* utilità  CciLog()                                                       */

        }
      }
      else {
      }
    }
  }
  else {
    /* Terminale non esistente...errore interno grave. Il plugin potrebbe voler */
    /* registrare un errore qui utilizzando la funzione di utilità cciLog()                 */
  }

  /* Elimina i messaggi creati concludendo così il loro uso    */
  cniDeleteMessage(0, outMsg[0]);
  cniDeleteMessage(0, outMsg[1]);
  cniDeleteMessage(0, outMsg[2]);

  free((void*) constBLOBParserName);
  free((void*) constBLOBElementName);
  free((void*) constEmptyString);
  return;
Informazioni particolari | Marchi | Download | Libreria | Supporto | Commenti
Copyright IBM Corporation 1999, 2006 Ultimo aggiornamento: ago 17, 2006
as07885_