Vorbereitungen:
Die einzelnen Funktionstypen werden im Folgenden beschrieben.
Der Broker ruft die Eingabefunktion auf, wenn Ihr benutzerdefinierter Parser eine Eingabenachricht syntaktisch analysieren muss. Der Parser muss dem Broker mitteilen, welchen Anteil des Eingabebitstrompuffers er für sich reklamiert. Wenn der Header eine feste Größe hat, fordert der Parser die Größe des Headers. Wenn der Parser die gesamte Nachricht verarbeiten soll, reklamiert er den verbleibenden Puffer.
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); }
Allgemeine Syntaxanalysefunktionen (z. B. cpiParseFirstChild) werden vom Broker aufgerufen, wenn die Syntaxelementstruktur erstellt werden muss, damit ein ESQL- oder Java-Ausdruck ausgewertet werden kann. Ein Filterknoten verwendet z. B. einen ESQL-Feldverweis in einem ESQL-Ausdruck. Dieser Feldverweis muss aufgelöst werden, damit der Ausdruck ausgewertet werden kann. Die allgemeine Syntaxanalysefunktion Ihres Parsers wird möglicherweise wiederholt aufgerufen, bis das angeforderte Element erstellt wird oder vom Parser erkannt wird, dass es nicht vorhanden ist.
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; }
Der Broker ruft die Ausgabefunktion auf, wenn Ihr benutzerdefinierter Parser für die Serialisierung einer Syntaxelement-Baumstruktur in einem Ausgabebitstrom erforderlich ist. Beispielsweise kann ein Rechenknoten eine Baumstruktur in der Domäne Ihres benutzerdefinierten Parsers erstellt haben. Wenn diese Baumstruktur z. B. von einem MQSendeknoten ausgegeben werden muss, muss der Parser zum Ausgabebitstrompuffer Daten hinzufügen, die die erstellte Baumstruktur darstellen.
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; }
Normalerweise haben die eingehenden Nachrichtendaten nur ein Nachrichtenformat, so dass ein Parser für die Syntaxanalyse des gesamten Inhalts der Nachricht zuständig ist. Der Klassenname des Parsers, der benötigt wird, ist im Feld Format im MQMD- oder MQRFH2-Header der Eingabenachricht definiert.
Die Nachricht besteht jedoch möglicherweise aus mehreren Formaten, z. B. wenn ein Header in einem Format und die nachfolgenden Daten in einem anderen Format vorliegen. In diesem Fall muss der erste Parser den Klassennamen des Parsers identifizieren, der für das nächste Format in der Kette zuständig ist usw. In einem benutzerdefinierten Parser wird die Implementierungsfunktion cpiNextParserClassName von dem Broker aufgerufen, wenn er für eine Nachricht, die aus mehreren Nachrichtenformaten besteht, durch eine Kette von Parser-Klassen navigieren muss.
Wenn Ihr benutzerdefinierter Parser die Syntaxanalyse eines Nachrichtenformats unterstützt, das Teil einer Nachricht mit mehreren Nachrichtenformaten ist, muss der benutzerdefinierte Parser die Funktion cpiNextParserClassName implementieren.
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; }