Parser in C erstellen

Vorbereitungen

Stellen Sie sicher, dass Sie folgende Abschnitte gelesen und verstanden haben:

Eine ladbare Implementierungsbibliothek (Loadable Implementation Library, LIL) ist das Implementierungsmodul für einen C-Parser (oder -Knoten). Eine LIL-Datei ist ein gemeinsam genutztes Linux- oder UNIX-Objekt oder eine Windows-DLL-Datei, die nicht die Dateierweiterung .dll, sondern .lil hat.

Die Implementierungsfunktionen, die vom Entwickler geschrieben werden müssen, sind unter C-Parser-Implementierungsfunktionen aufgelistet. Die Dienstprogrammfunktionen, die von WebSphere Message Broker bereitgestellt werden, um diesen Prozess zu unterstützen, sind unter C-Parser-Dienstprogrammfunktionen aufgelistet.

WebSphere Message Broker stellt den Quellcode für einen benutzerdefinierten Beispiel-Parser mit dem Namen 'BipSampPluginParser.c' bereit. Dies ist ein einfacher Pseudo-XML-Parser, den Sie in seinem aktuellen Zustand verwenden oder ändern können.

Der Schreibvorgang für einen Parser kann je nach Komplexität des Bitstroms, der analysiert werden soll, beträchtlich variieren. Hier werden nur die grundlegenden Schritte beschrieben. Sie werden in den folgenden Abschnitten beschrieben:
  1. Parser deklarieren und definieren
  2. Instanz des Parsers erstellen
  3. Instanz des Parsers löschen

Parser deklarieren und definieren

Beginn der ÄnderungSie müssen zum Deklarieren und Definieren eines benutzerdefinierten Parsers für den Broker eine Initialisierungsfunktion, bipGetParserFactory, in Ihrer LIL einfügen. Im Folgenden wird erläutert, wie die Initialisierungsfunktion vom Broker aufgerufen wird und wie durch diese Funktion der benutzerdefinierte Parser deklariert und definiert wird:Ende der Änderung

In der folgenden Prozedur wird beschrieben, wie Sie Ihren Parser im Broker deklarieren und definieren:

  1. Die Initialisierungsfunktion bipGetParserFactory wird vom Broker aufgerufen, nachdem die LIL-Datei vom Betriebssystem geladen und initialisiert wurde. Der Broker ruft diese Funktion auf, um zu erkennen, wozu Ihre LIL in der Lage ist und wie der Broker die LIL aufrufen soll. Beispiel:
    CciFactory LilFactoryExportPrefix * LilFactoryExportSuffix
    bipGetParserFactory()
  2. Durch die Funktion bipGetParserFactory wird anschließend die Dienstprogrammfunktion cpiCreateParserFactory aufgerufen. Diese Funktion gibt für alle Parser, die von der LIL-Datei unterstützt werden, einen eindeutigen Factory-Namen (oder Gruppennamen) zurück. Jeder zurückgegebene Factory-Name (oder Gruppenname) muss für alle LIL-Dateien im Broker eindeutig sein.
  3. Durch die LIL-Datei muss anschließend die Dienstprogrammfunktion cpiDefineParserClass für die Übergabe der eindeutigen Namen der einzelnen Parser und eine virtuelle Funktionstabelle mit den Adressen der Implementierungsfunktionen aufgerufen werden.
    Der folgende Code deklariert und definiert beispielsweise einen einzelnen Parser namens InputxParser:
    {
    CciFactory*     factoryObject;
    int                rc = 0;
    CciChar factoryName[] = L"MyParserFactory";
    	CCI_EXCEPTION_ST exception_st;
    /* Create the Parser Factory for this parser */
    factoryObject = cpiCreateParserFactory(0, factoryName);
    if (factoryObject == CCI_NULL_ADDR) {
    			/* Any local error handling can go here */
    }
    else {
    /* Define the parsers supported by this factory */
    	static CNI_VFT vftable = {CNI_VFT_DEFAULT};
    /* Konfigurations-Funktionstabelle mit Zeigern auf Parser-Implementierungsfunktionen */
    vftable.iFpCreateContext            = cpiCreateContext;
    vftable.iFpParseBufferEncoded       = cpiParseBufferEncoded;
    vftable.iFpParseFirstChild          = cpiParseFirstChild;
    vftable.iFpParseLastChild           = cpiParseLastChild;
    vftable.iFpParsePreviousSibling     = cpiParsePreviousSibling;
    vftable.iFpParseNextSibling         = cpiParseNextSibling;
    vftable.iFpWriteBufferEncoded       = cpiWriteBufferEncoded;
    vftable.iFpDeleteContext            = cpiDeleteContext;
    vftable.iFpSetElementValue          = cpiSetElementValue;
    vftable.iFpElementValue             = cpiElementValue;
    vftable.iFpNextParserClassName      = cpiNextParserClassName;
    vftable.iFpSetNextParserClassName   = cpiSetNextParserClassName;
    vftable.iFpNextParserEncoding       = cpiNextParserEncoding;
    vftable.iFpNextParserCodedCharSetId = cpiNextParserCodedCharSetId;
    cpiDefineParserClass(0, factoryObject, L"InputxParser", &vftable);
    }
    /* Rückkehradresse dieses Factory-Objekts zum Broker */
    return(factoryObject);
    }

    Die Initialisierungsfunktion muss anschließend durch den Aufruf von cpiCreateParserFactory eine Parser-Factory erstellen. Die von der Factory unterstützten Parser-Klasse werden durch den Aufruf von cpiDefineParserClass definiert. Die Adresse des Factory-Objekts (von cpiCreateParserFactory zurückgegeben) muss als Rückgabewert aus der Initialisierungsfunktion an den Broker zurückgegeben werden.

    Beispiel:
    1. Erstellen Sie die Parser-Factory mit der Funktion cpiCreateParserFactory :
      factoryObject = cpiCreateParserFactory(&rc, constParserFactory);
    2. Definieren Sie die von der Factory unterstützten Nachrichtenklassen mit der Funktion cpiDefineParserClass:
      if (factoryObject) {
      cpiDefineParserClass(&rc, factoryObject, constPXML, &vftable);
      }
      else {
      /* Error: Unable to create parser factory */
      }
    3. Geben Sie die Adresse dieses Factory-Objekts an den Broker zurück:
      return(factoryObject);
      }

Instanz des Parsers erstellen

In der folgenden Prozedur wird beschrieben, wie Sie für Ihren Parser eine Instanz erstellen können:

Wenn der Broker die Tabelle mit den Funktionszeigern erhalten hat, ruft er für jede Instanzerstellung des benutzerdefinierten Parsers die Funktion cpiCreateContext auf. Wenn drei Nachrichtenflüsse vorhanden sind, die Ihren benutzerdefinierten Parser verwenden, wird die FunktioncpiCreateContext für jeden dieser Parser aufgerufen. Durch diese Funktion soll Speicher für die Instanzerstellung des benutzerdefinierten Parsers reserviert werden, damit dort die Werte der konfigurierten Attribute gespeichert werden können. Beispiel:
  1. Rufen Sie die Funktion cpiCreateContext auf:
    CciContext* _createContext(
    CciFactory* factoryObject,
    CciChar* parserName,
    CciNode* parserObject
    ){
    static char* functionName = (char *)"_createContext()";
    PARSER_CONTEXT_ST* p;
    CciChar          buffer[256];
  2. Ordnen Sie dem lokalen Kontext einen Zeiger zu, und löschen Sie den Kontextbereich:
    p = (PARSER_CONTEXT_ST *)malloc(sizeof(PARSER_CONTEXT_ST));
    if (p) {
    memset(p, 0, sizeof(PARSER_CONTEXT_ST));
  3. Speichern Sie den Zeiger des Parserobjekts im Kontext:
    p->parserObject = parserObject;
  4. Speichern Sie den Parsernamen:
    CciCharNCpy((CciChar*)&p->parserName, parserName, MAX_NODE_NAME_LEN);
  5. Beginn der ÄnderungGeben Sie den Parserkontext zurück:
    return (CciContext*) p;
    Ende der Änderung

Instanz des Parsers löschen

Parser werden beim Löschen oder erneuten Implementieren eines Nachrichtenflusses oder beim Stoppen des Prozesses der Ausführungsgruppe mit Hilfe des Befehls mqsistop gelöscht. Durch das Löschen des Parsers sollte der verwendete Speicher und darin enthaltene Ressourcen freigegeben werden. Verwenden Sie dazu die Funktion cpiDeleteContext. Beispiel:

void cpiDeleteContext(
CciParser*  parser,
CciContext* context
){
PARSER_CONTEXT_ST* pc = (PARSER_CONTEXT_ST *)context ;
int                rc = 0;
return;
}
Zugehörige Verweise
Benutzerdefinierte C-Parser-API
Bemerkungen | Marken | Downloads | Bibliothek | Unterstützung | Rückmeldung
Copyright IBM Corporation 1999, 2006 Letzte Aktualisierung: 18.05.2006
as10010_