Vorbereitungen:
Die einzelnen Funktionstypen werden im Folgenden beschrieben.
Die Eingabefunktionen (z. B. cpiParseBuffer) werden vom Broker aufgerufen, wenn ein Parser eine Eingabenachricht 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-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; }
Die Ausgabefunktionen (z. B. cpiWriteBuffer) werden vom Broker aufgerufen, wenn ein Parser eine Syntaxelementstruktur in einen Ausgabebitstrom serialisieren muss. 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; }