Creación de un analizador en C

Antes de empezar

Una biblioteca de implementación cargable, o LIL, es el módulo de implementación para un analizador (o nodo) C. Una LIL es un objeto Linux o UNIX compartido o una biblioteca de enlaces dinámicos (DLL) Windows, que no tiene la extensión de archivo .dll sino .lil.

Las funciones de implementación que el desarrollador tiene que escribir se listan en el apartado Funciones de implementación de analizador en C. Las funciones de programa de utilidad que WebSphere Message Broker proporciona para ayudar en este proceso se listan en el apartado Funciones de programa de utilidad de analizador en C.

WebSphere Message Broker proporciona el origen para un analizador definido por el usuario de ejemplo denominado BipSampPluginParser.c. Se trata de un analizador pseudo XML simple que se puede utilizar en su estado actual o que se puede modificar.

La tarea de escribir un analizador varía considerablemente de acuerdo con la complejidad de la corriente de bits que se debe analizar. Aquí sólo se describen los pasos básicos. Se describen en los apartados siguientes:
  1. Declaración y definición del analizador
  2. Creación de una instancia del analizador
  3. Supresión de una instancia del analizador

Declaración y definición del analizador

Para declarar y definir un analizador definido por el usuario en el intermediario, debe incluir una función de inicialización bipGetParserFactory, en su LIL. Los pasos siguientes indican cómo llama el intermediario a su función de inicialización y cómo esa función declara y define el analizador definido por el usuario:

El procedimiento siguiente muestra cómo declarar y definir el analizador en el intermediario:

  1. El intermediario invoca la función de inicialización, bipGetParserFactory, después de que el sistema operativo haya cargado e inicializado la LIL. El intermediario invoca esta función para saber qué es capaz de hacer la biblioteca de implementación cargable y cómo la debe invocar. Por ejemplo:
    CciFactory LilFactoryExportPrefix * LilFactoryExportSuffix
    bipGetParserFactory()
  2. Entonces la función bipGetParserFactory debe llamar a la función de utilidad cpiCreateParserFactory. Esta función devuelve un nombre de fábrica (o nombre de grupo) exclusivo para todos los analizadores soportados por la LIL. Todos los nombres de fábrica (o nombres de grupo) que se devuelven, deben ser exclusivos en todas las LIL en el intermediario.
  3. Entonces la biblioteca de implementación cargable (LIL) debe llamar a la función de utilidad cpiDefineParserClass para pasar el nombre exclusivo de cada analizador y una tabla de funciones virtual de las direcciones de las funciones de implementación.
    Por ejemplo, el código siguiente declara y define un solo analizador denominado InputxParser:
    {
    CciFactory* factoryObject;
    int                rc = 0;
    CciChar factoryName[] = L"MyParserFactory";
    CCI_EXCEPTION_ST exception_st;
    
    /* Crear la fábrica de analizadores para este analizador */
    factoryObject = cpiCreateParserFactory(0, factoryName);
    if (factoryObject == CCI_NULL_ADDR) {
    		
    /* Aquí puede ir cualquier manejo de errores locales */
    	}
    	else {
    /* Definir los analizadores soportados por esta fábrica */
    	static CNI_VFT vftable = {CNI_VFT_DEFAULT};
    
    /* Configurar tabla de funciones con punteros a funciones de implementación de analizador */
    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);
    	}
    
    /* Devolver la dirección de este objeto de fábrica al intermediario */
    return(factoryObject);
    }

    Entonces la función de inicialización debe crear una fábrica de analizador invocando cpiCreateParserFactory. Las clases de analizador soportadas por la fábrica se definen invocando cpiDefineParserClass. La dirección del objeto de fábrica (devuelto por cpiCreateParserFactory) se debe devolver al intermediario como valor de retorno desde la función de inicialización.

    Por ejemplo:
    1. Cree la fábrica de analizador utilizando la función cpiCreateParserFactory:
        factoryObject = cpiCreateParserFactory(&rc, constParserFactory);
        
    2. Defina las clases de mensaje soportadas por la fábrica utilizando la función cpiDefineParserClass:
      if (factoryObject) {
         cpiDefineParserClass(&rc, factoryObject, constPXML, &vftable);
        }
      else {
          /* Error: No se ha podido crear fábrica de analizador */
        }
    3. Devuelva la dirección de este objeto de fábrica al intermediario:
        return(factoryObject);
      }

Creación de una instancia del analizador

El procedimiento siguiente muestra cómo crear instancias del analizador:

Cuando el intermediario ha recibido la tabla de punteros de función, invoca la función cpiCreateContext para cada creación de instancia del analizador definido por el usuario. Si tiene tres flujos de mensajes que están utilizando el analizador definido por el usuario, se invoca la función cpiCreateContext para cada uno de ellos. Esta función debe asignar memoria para esa creación de instancia del analizador definido por el usuario para que contenga los valores de los atributos configurados. Por ejemplo:
  1. Invoque la función cpiCreateContext:
    CciContext* _createContext(
      CciFactory* factoryObject,
      CciChar* parserName,
      CciNode* parserObject
    ){
      static char* functionName = (char *)"_createContext()";
      PARSER_CONTEXT_ST* p;
      CciChar          buffer[256];
  2. Asigne un puntero al contexto local y borre el área de contexto:
      p = (PARSER_CONTEXT_ST *)malloc(sizeof(PARSER_CONTEXT_ST));
    
      if (p) {
         memset(p, 0, sizeof(PARSER_CONTEXT_ST));
  3. Guarde el puntero de objeto de analizador en el contexto:
       p->parserObject = parserObject;
  4. Guarde el nombre de analizador:
     CciCharNCpy((CciChar*)&p->parserName, parserName, MAX_NODE_NAME_LEN);
  5. Devuelva el contexto de analizador:
    return (CciContext*) p;

Supresión de una instancia del analizador

Los analizadores se destruyen cuando se suprime o se vuelve a desplegar un flujo de mensajes, o cuando se detiene el proceso de grupo de ejecución (utilizando el mandato mqsistop). Cuando un analizador se destruye, debe liberar la memoria utilizada así como los recursos retenidos. Para ello, utilice la función cpiDeleteContext. Por ejemplo:

void cpiDeleteContext(
  CciParser*  parser,
  CciContext* context
){
  PARSER_CONTEXT_ST* pc = (PARSER_CONTEXT_ST *)context ;
  int                rc = 0;

  return;
}
Avisos | Marcas registradas | Descargas | Biblioteca | Soporte | Su opinión
Copyright IBM Corporation 1999, 2006 Última actualización: 22/08/2006
as10010_