Funktionalität eines C-Parsers erweitern

Vorbereitungen:

Stellen Sie sicher, dass Sie folgenden Abschnitt gelesen und verstanden haben:

Parser-Funktionen implementieren

Ein Parser muss folgende Implementierungsfunktionstypen implementieren:
  1. Eingabefunktionen
  2. Syntaxanalysefunktionen
  3. Ausgabefunktionen

Die einzelnen Funktionstypen werden im Folgenden beschrieben.

Eingabefunktionen implementieren

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.

Beispiel:
  1. Rufen Sie die Funktion cpiParseBufferEncoded auf:
    int cpiParseBufferEncoded(
      CciParser*      parser,
      CciContext* context,                
      int            encoding,
      int         ccsid
    ){
      PARSER_CONTEXT_ST* pc = (PARSER_CONTEXT_ST *)context ;
      int             rc;
    
  2. Rufen Sie einen Zeiger auf den Nachrichtenpuffer ab, und legen Sie mit der Funktion cpiBufferPointer die relative Position fest:
      pc->iBuffer = (void *)cpiBufferPointer(&rc, parser);
      pc->iIndex = 0;
  3. Speichern Sie das Format des Puffers:
      pc->iEncoding = encoding;
      pc->iCcsid = ccsid;
  4. Speichern Sie die Größe des Puffers mit der Funktion cpiBufferSize:
      pc->iSize = cpiBufferSize(&rc, parser);
  5. Setzen Sie das erste Byte im Datenstrom mit der Funktion cpiBufferByte ein:
      pc->iCurrentCharacter = cpiBufferByte(&rc, parser, pc->iIndex);
  6. Setzen Sie das aktuelle Element mit der Funktion cpiRootElement auf das Stammelement:
      pc->iCurrentElement = cpiRootElement(&rc, parser);
  7. Setzen Sie die Markierung zurück, um sicherzustellen, dass die Syntaxanalyse richtig zurückgesetzt wird:
      pc->iInTag = 0;
    
  8. Reklamieren Sie den verbleibenden Puffer für sich:
      return(pc->iSize);
    }

Syntaxanalysefunktionen implementieren

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.

Beispiel:
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;
}

Ausgabefunktionen implementieren

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.

Beispiel:
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;
}

Nachrichten mit mehreren Nachrichtenformaten

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.

Beispiel:
  1. Rufen Sie die Funktion cpiNextParserClassName auf:
    void cpiNextParserClassName(
      CciParser*      parser,
      CciContext* context,                
      CciChar*    buffer,
      int         size
    ){
      PARSER_CONTEXT_ST* pc = (PARSER_CONTEXT_ST *)context ;
      int                rc = 0;
    
  2. Kopieren Sie den Namen der nächsten Parser-Klasse in den Broker:
      CciCharNCpy(buffer, pc->iNextParserClassName, size);
    
      return;
    }
Zugehörige Verweise
Benutzerdefinierte C-Parser-API
Bemerkungen | Marken | Downloads | Bibliothek | Unterstützung | Rückmeldung
Copyright IBM Corporation 1999, 2005 Letzte Aktualisierung: Nov 17, 2005
as24980_