Prima di iniziare
Ciascun tipo di funzione è descritto di seguito.
Il broker richiamerà la funzione di input quando è necessario che il programma di analisi definito dall'utente analizzi un messaggio di input. Tale programma deve indicare al broker la quantità di buffer del flusso di bit di input di cui dispone. In caso di intestazione a dimensione fissa, il programma di analisi indica la dimensione dell'intestazione. Se il programma di analisi gestisce l'intero messaggio, indica la parte rimanente del buffer.
int cpiParseBufferEncoded( CciParser* parser, CciContext* context, int encoding, int ccsid ){ PARSER_CONTEXT_ST* pc = (PARSER_CONTEXT_ST *)context ; int rc;
pc->iBuffer = (void *)cpiBufferPointer(&rc, parser); pc->iIndex = 0;
pc->iEncoding = encoding; pc->iCcsid = ccsid;
pc->iSize = cpiBufferSize(&rc, parser);
pc->iCurrentCharacter = cpiBufferByte(&rc, parser, pc->iIndex);
pc->iCurrentElement = cpiRootElement(&rc, parser);
pc->iInTag = 0;
return(pc->iSize); }
Le funzioni di analisi generale (ad esempio, cpiParseFirstChild) sono quelle richiamate dal broker quando, per valutare l'espressione SQL o Java, deve essere creata la struttura ad albero dell'elemento di sintassi. Ad esempio, un nodo Filter utilizza un riferimento di campo ESQL in un'espressione ESQL. Tale riferimento di campo deve essere risolto al fine di valutare l'espressione. La funzione di analisi generale del programma di analisi viene richiamata, probabilmente in modo ripetuto, finché l'elemento richiesto non viene creato o fino a quando il programma di analisi ne individua la non esistenza.
void cpiParseFirstChild( CciParser* parser, CciContext* context, CciElement* element ){ PARSER_CONTEXT_ST* pc = (PARSER_CONTEXT_ST *)context ; int rc; if ((!cpiElementCompleteNext(&rc, element)) && (cpiElementType(&rc, element) == CCI_ELEMENT_TYPE_NAME)) { while ((!cpiElementCompleteNext(&rc, element)) && (!cpiFirstChild(&rc, element)) && (pc->iCurrentElement)) { pc->iCurrentElement = parseNextItem(parser, context, pc->iCurrentElement); } } return; }
Il broker richiamerà la funzione di output quando è necessario che il programma definito dall'utente serializzi una struttura ad albero dell'elemento di sintassi in un flusso di bit di output. Ad esempio, un nodo Compute potrebbe aver creato una struttura ad albero nel dominio del programma di analisi definito dall'utente. Quando deve essere eseguito l'output di tale struttura ad albero da parte, ad esempio, di un nodo MQOutput, il programma di analisi è responsabile dell'accodamento del buffer del flusso di bit di output ai dati che rappresentano la struttura ad albero creata.
int cpiWriteBufferEncoded( CciParser* parser, CciContext* context, int encoding, int ccsid ){ PARSER_CONTEXT_ST* pc = (PARSER_CONTEXT_ST *)context ; int initialSize = 0; int rc = 0; const void* a; CciByte b; initialSize = cpiBufferSize(&rc, parser); a = cpiBufferPointer(&rc, parser); b = cpiBufferByte(&rc, parser, 0); cpiAppendToBuffer(&rc, parser, (char *)"Some test data", 14); return cpiBufferSize(0, parser) - initialSize; }
Di solito, i dati dei messaggi in entrata sono di un unico formato, quindi un programma di analisi è responsabile dell'analisi dell'intero contenuto del messaggio. Il nome di classe del programma di analisi necessario è definito nel campo Formato nell'intestazione MQMD o MQRFH2 del messaggio di input.
Tuttavia, il messaggio potrebbe essere composto da più formati, ad esempio, la parte dell'intestazione di un formato seguita dai dati in un altro formato. In tale caso, il primo programma di analisi deve individuare il nome di classe del programma di analisi responsabile del formato successivo nella catena, e così via. In un programma di analisi definito dall'utente, la funzione di implementazione cpiNextParserClassName viene richiamata dal broker quando deve navigare in una catena di classi di programmi di analisi per un messaggio che comprende più formati.
Se il programma di analisi definito dall'utente supporta l'analisi di un formato del messaggio che fa parte di più formati, il programma di analisi definito dall'utente deve implementare la funzione cpiNextParserClassName.
void cpiNextParserClassName( CciParser* parser, CciContext* context, CciChar* buffer, int size ){ PARSER_CONTEXT_ST* pc = (PARSER_CONTEXT_ST *)context ; int rc = 0;
CciCharNCpy(buffer, pc->iNextParserClassName, size); return; }