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 gravar um analisador varia de forma considerável 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. Declarando e Definindo o Analisador
  2. Criando uma Instância do Analisador
  3. Excluindo uma instância do analisador

Declarando e Definindo o Analisador

Para declarar e definir um analisador definido pelo usuário para o intermediário, é necessário incluir uma função de inicialização, bipGetParserFactory, no LIL. As seguintes etapas descrevem como o intermediário chama a função de inicialização e como sua função de inicialização declara e define o analisador definido pelo usuário:

O seguinte procedimento mostra como declarar e definir seu analisador para o intermediário:

  1. A função de inicialização, bipGetParserFactory, será chamada pelo intermediário depois que a LIL tiver sido carregada e inicializada pelo sistema operacional. O intermediário chama essa função para compreender o que a LIL é capaz de fazer e como o intermediário deve chamar a LIL. Exemplo:
    CciFactory LilFactoryExportPrefix * LilFactoryExportSuffix
    bipGetParserFactory()
  2. A função bipGetParserFactory deve então chamar a função de utilitário cpiCreateParserFactory. Essa função transmite de volta um nome de fábrica exclusivo (ou nome do grupo) para todos os analisadores que a LIL suporta. Cada nome de depósito de informações do provedor (ou nome de grupo) retransmitido deve ser exclusivo por todas as LILs no intermediário.
  3. A LIL deve chamar a função de utilitário cpiDefineParserClass para transmitir o nome exclusivo de cada analisador e uma tabela de função virtual dos endereços das funções de implementação.
    Por exemplo, o seguinte código declara e define um único analisador denominado 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) {
    		
    			/* Qualquer tratamento de erro local pode ir aqui */
    	}
    	else {
    /* Define the parsers supported by this factory */
    	static CNI_VFT vftable = {CNI_VFT_DEFAULT};
    
      /* Configurar a tabela de função com ponteiros para funções de
    implementação de 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;
    cpiDefineParserClass(0, factoryObject, L"InputxParser", &vftable);
    	}
    
    	/* Retornar o endereço deste objeto de fábrica para o intermediário */
    	return(factoryObject);
    }

    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

O seguinte procedimento mostra como instanciar o analisador:

Quando o intermediário tiver recebido a tabela de ponteiros de função, ele chamará a função cpiCreateContext para cada instanciação definida pelo usuário. Se houver três fluxos de mensagens que utilizem analisadores definidos pelo usuário, a função cpiCreateContext será chamada para cada um deles. Essa função deve alocar memória para que a instanciação do analisador definido pelo usuário contenha os valores para os atributos configurados. Exemplo:
  1. Chame a função cpiCreateContext:
    CciContext* _createContext(
        CciFactory* factoryObject,
      CciChar* parserName,
      CciNode* parserObject
    ){
      static char* functionName = (char *)"_createContext()";
      PARSER_CONTEXT_ST* p;
      CciChar          buffer[256];
  2. Alocar um ponteiro para o contexto local e limpar a área do contexto:
      p = (PARSER_CONTEXT_ST *)malloc(sizeof(PARSER_CONTEXT_ST));
    
      if (p) {
         memset(p, 0, sizeof(PARSER_CONTEXT_ST));
  3. Salve o ponteiro do objeto analisador no contexto:
       p->parserObject = parserObject;
  4. Save the parser name:
     CciCharNCpy((CciChar*)&p->parserName, parserName, MAX_NODE_NAME_LEN);
  5. Retorne o contexto do analisador:
    return (CciContext*) p;

Excluindo uma instância do analisador

Os analisadores são destruídos quando um fluxo de mensagens é excluído ou reimplementado, ou quando o processo do grupo de execução é parado (utilizando o comando mqsistop). Quando um analisador for destruído, ele deverá liberar qualquer memória utilizada e quaisquer recursos retidos. Isso é feito utilizando a função cpiDeleteContext. Exemplo:

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

  return;
}
Avisos | Marcas Registradas | Downloads | Biblioteca | Suporte | Feedback
Direitos Autorais IBM Corporation 1999, 2006 Última Atualização: 1 Sep 2006
as10010_