Parser in C erstellen

Vorbereitungen

Stellen Sie sicher, dass Sie die folgenden 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 die Quelle für einen benutzerdefinierten Parser mit der Bezeichnung 'BipSampPluginParser.c' zur Verfügung. Dies ist ein einfacher Pseudo-XML-Parser, den Sie im 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. Diese sind in den folgenden Abschnitten enthalten:
  1. Parser deklarieren und definieren
  2. Instanz des Parsers erstellen
  3. Instanz des Parsers löschen

Parser deklarieren und definieren

Sie 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:

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};
    
    /* Funktionstabelle mit Zeigern auf Parserimplementierungsfunktionen erstellen */
    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);
    	}
    
    	/* Return address of this factory object to the broker */
    	return(factoryObject);
    }

    Durch die Initialisierungsfunktion muss anschließend eine Parser-Factory erstellt werden, indem cpiCreateParserFactory aufgerufen wird. Die von der Factory unterstützten Parserklassen werden durch das Aufrufen von cpiDefineParserClass definiert. Die Adresse des Factory-Objekts (von cpiCreateParserFactory zurückgegeben) muss von der Initialisierungsfunktion als Rückgabewert an den Broker zurückgegeben werden.

    Beispiel:
    1. Erstellen Sie die Parser-Factory mit Hilfe der Funktion cpiCreateParserFactory:
        factoryObject = cpiCreateParserFactory(&rc, constParserFactory);
        
    2. Definieren Sie die Klasse der Nachrichten, die von der Factory unterstützt werden, mit Hilfe 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. Geben Sie den Parserkontext zurück:
    return (CciContext*) p;

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: 23. Aug. 2006
as10010_