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.
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.
CciSize cniElementAsBitstream( int* returnCode, CciElement* element, const struct CciByteArray* value, CciChar* messageType, CciChar* messageSet, CciChar* messageFormat, int encoding, int ccsid, int options);
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.
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;