Criando um Analisador em C

Antes de começar

Uma biblioteca de implementação carregável, ou uma LIL, é o módulo de implementação para um analisador (ou nó) em C. Uma LIL é um objeto compartilhado do Linux ou UNIX ou uma DLL (Dynamic Link Library) do Windows que não tem a extensão de arquivo .dll, mas .lil.

As funções de implementação que precisam ser escritas pelo desenvolvedor estão relacionadas em Funções de Implementação do Analisador C.As funções utilitárias fornecidas pelo WebSphere Message Broker para auxiliar esse processo estão relacionadas em Funções de Utilitários do Analisador C.

O WebSphere Message Broker fornece a origem para um analisador de amostra definido pelo usuário chamado BipSampPluginParser.c. Esse é um analisador pseudo XML simples que pode ser utilizado em seu estado atual ou pode ser modificado.

A tarefa de escrever um analisador varia consideravelmente de acordo com a complexidade do fluxo de bits a ser analisado. Somente as etapas básicas são descritas aqui. Elas são descritas nas seguintes seções:
  1. Definindo o Analisador durante a Inicialização do Intermediário
  2. Criando uma Instância do Analisador
  3. Excluindo uma Instância do Analisador Definido pelo Usuário

Definindo o Analisador durante a Inicialização do Intermediário

A função de inicialização do analisador definido pelo usuário é chamada automaticamente durante a inicialização do intermediário. O analisador definido pelo usuário é responsável por:
  • Criar e nomear a fábrica de analisador de mensagem que é implementada pelo analisador definido pelo usuário. A fábrica de analisador é um contêiner para implementações de analisadores relacionados. Os nomes de fábricas de analisador precisam ser exclusivos dentro de um intermediário.
  • Definir os nomes de classes de analisador de mensagem suportadas e fornecer um ponteiro para uma tabela de funções virtuais que contém ponteiros para as funções de implementação do analisador definido pelo usuário. Os nomes de classes de analisador precisam ser exclusivos dentro de um intermediário.

Cada LIL que implementa um analisador definido pelo usuário deve exportar uma função chamada bipGetParserFactory como sua função de inicialização. A função de inicialização define o nome da fábrica que o analisador definido pelo usuário suporta e as classes de objetos ou o objeto compartilhado suportado pela fábrica.

A função de inicialização precisa também criar o objeto de fábrica e definir os nomes de todos os analisadores suportados pela LIL. Uma fábrica pode suportar qualquer número de classes de objetos (analisadores). Quando um analisador é definido, uma lista de ponteiros para as funções de implementação para esse analisador é transmitida ao intermediário. Se já existir um analisador com o mesmo nome, o pedido será rejeitado.

Por exemplo, para definir o analisador:
  1. Exportar a função de inicialização bipGetParserFactory:
    void LilFactoryExportPrefix * LilFactoryExportSuffix bipGetParserFactory()
    {
  2. Declarar as variáveis:
     CciFactory*     factoryObject;
      int             rc;
      static CPI_VFT  vftable = {CPI_VFT_DEFAULT};
  3. Inicializar todas as constantes estáticas:
      initParserConstants();
  4. Configurar a tabela de funções com ponteiros para funções de implementação do analisador:
      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;

A função de inicialização deve então criar uma fábrica de analisador chamando cpiCreateParserFactory. As classes de analisador suportadas pela fábrica são definidas chamando cpiDefineParserClass. O endereço do objeto fábrica (retornado por cpiCreateParserFactory) deve ser retornado ao intermediário como o valor de retorno da função de inicialização.

Por exemplo:
  1. Criar a fábrica de analisador utilizando a função cpiCreateParserFactory:
      factoryObject = cpiCreateParserFactory(&rc, constParserFactory);
      
  2. Definir as classes de mensagem suportadas pela fábrica utilizando a função cpiDefineParserClass:
    if (factoryObject) {
       cpiDefineParserClass(&rc, factoryObject, constPXML, &vftable);
      }
    else {
        /* Erro: Incapaz de criar a fábrica de analisador */
      }
  3. Retorne o endereço desse objeto fábrica ao intermediário:
      return(factoryObject);
    }

Criando uma Instância do Analisador

Sempre que uma instância de um objeto do analisador definido pelo usuário é criada, a função de implementação de criação de contexto cpiCreateContext é chamada pelo intermediário de mensagens. Isso permite ao analisador definido pelo usuário alocar dados da instância associados ao analisador.

Por exemplo:
  1. Chamar cpiCreateContext:
    CciContext* cpiCreateContext(
      CciParser* parser
    ){
      PARSER_CONTEXT_ST *p;
    
  2. Alocar um ponteiro para o contexto local:
      p = (PARSER_CONTEXT_ST *)malloc(sizeof(PARSER_CONTEXT_ST));
    
  3. Limpar a área do contexto:
      if (p) {
         memset(p, 0, sizeof(PARSER_CONTEXT_ST));
        }
      else {
            /* Erro: Incapaz de alocar memória */
      }
  4. Retornar o ponteiro para o contexto local:
      return((CciContext*)p);
    }

Excluindo uma Instância do Analisador Definido pelo Usuário

Para excluir uma instância de um analisador, é utilizada a função cpiDeleteContext. Por exemplo:
void cpiDeleteContext(
  CciParser*  parser,
  CciContext* context
){
  PARSER_CONTEXT_ST* pc = (PARSER_CONTEXT_ST *)context ;
  int                rc = 0;

  return;
}
Referências relacionadas
API de Nó C Definido pelo Usuário
Avisos | Marcas Registradas | Downloads | Biblioteca | Suporte | Feedback
Direitos Autorais IBM Corporation 1999, 2005 Última Atualização: 04/11/2005
as10010_