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 bei Brokerinitialisierung definieren
  2. Instanz des Parsers erstellen
  3. Instanz des benutzerdefinierten Parsers löschen

Parser bei Brokerinitialisierung definieren

Die Initialisierungsfunktion für benutzerdefinierte Parser wird bei der Brokerinitialisierung automatisch aufgerufen. Der benutzerdefinierte Parser ist für Folgendes zuständig:
  • Erstellung und Benennung der Nachrichten-Parser-Factory, die vom benutzerdefinierten Parser implementiert wird. Die Parser-Factory ist ein Container für zugehörige Parser-Implementierungen. Parser-Factory-Namen müssen innerhalb eines Brokers eindeutig sein.
  • Definition der unterstützten Klassennamen für Nachrichten-Parser und Angabe eines Zeigers auf eine virtuelle Funktionstabelle, die Zeiger auf die Implementierungsfunktionen des benutzerdefinierten Parsers enthält. Parser-Klassennamen müssen innerhalb eines Brokers eindeutig sein.

Jede LIL, die einen benutzerdefinierten Parser implementiert, muss eine Funktion mit dem Namen bipGetParserFactory als Initialisierungsfunktion exportieren. Die Initialisierungsfunktion definiert den Namen der Factory, die der benutzerdefinierte Parser unterstützt, und die Objektklassen oder Klassen von gemeinsam genutzten Objekten, die von der Factory unterstützt werden.

Die Initialisierungsfunktion muss auch das Factory-Objekt erstellen und die Namen aller Parser definieren, die von der LIL unterstützt werden. Eine Factory kann eine beliebige Anzahl von Objektklassen (Parsern) unterstützen. Wenn ein Parser definiert wird, wird eine Liste mit Zeigern auf die Implementierungsfunktionen für diesen Parser an de Broker übermittelt. Wenn bereits ein Parser mit demselben Namen vorhanden ist, wird die Anforderung zurückgewiesen.

So definieren Sie beispielsweise den Parser:
  1. Exportieren Sie die Initialisierungsfunktion bipGetParserFactory:
    void LilFactoryExportPrefix * LilFactoryExportSuffix bipGetParserFactory()
    {
  2. Deklarieren Sie die Variablen:
     CciFactory*     factoryObject;
      int             rc;
      static CPI_VFT  vftable = {CPI_VFT_DEFAULT};
  3. Initialisieren Sie alle statischen Konstanten:
      initParserConstants();
  4. Konfigurieren Sie eine 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;

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

Wenn eine Instanz eines benutzerdefinierten Parser-Objekts erstellt wird, wird die Implementierungsfunktion zur Kontexterstellung, cpiCreateContext, vom Nachrichtenbroker aufgerufen. Dies ermöglicht dem benutzerdefinierten Parser die Zuordnung von Instanzdaten, die dem Parser zugeordnet sind.

Beispiel:
  1. Rufen Sie cpiCreateContext auf:
    CciContext* cpiCreateContext(
      CciParser* parser
    ){
      PARSER_CONTEXT_ST *p;
    
  2. Ordnen Sie dem lokalen Kontext einen Zeiger zu:
      p = (PARSER_CONTEXT_ST *)malloc(sizeof(PARSER_CONTEXT_ST));
    
  3. Löschen Sie den Kontextbereich:
      if (p) {
         memset(p, 0, sizeof(PARSER_CONTEXT_ST));
        }
      else {
        /* Error: Unable to allocate memory */
      }
  4. Geben Sie den Zeiger auf den lokalen Kontext zurück:
      return((CciContext*)p);
    }

Instanz des benutzerdefinierten Parsers löschen

Zum Löschen einer Instanz eines Parsers verwenden Sie 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, 2005 Letzte Aktualisierung: Nov 17, 2005
as10010_