Estendendo o Recurso de um Analisador C

Antes de começar

Certifique-se de que tenha lido e entendido o seguinte tópico:

Implementando a Funcionalidade do Analisador

Um analisador precisa implementar os seguintes tipos de funções de implementação:
  1. funções de entrada
  2. funções de análise
  3. funções de saída

Cada tipo de função é descrito a seguir.

Implementando Funções de Entrada

Existem três funções input: Seu analisador deve implementar uma, e apenas uma, dessas funções de entrada.

O intermediário deve chamar a função entrada quando o analisador definido pelo usuário for necessário para analisar uma mensagem de entrada. O analisador deve instruir ao intermediário de quanto do buffer do fluxo de bits de entrada ele reclama para si. No caso de um cabeçalho de comprimento fixo, o analisador reclama o tamanho do cabeçalho. Caso o analisador deva manipular a mensagem inteira, ele reclamará o restante do buffer.

Exemplo:
  1. O intermediário chama a função de entrada cpiParseBufferEncoded:
    int cpiParseBufferEncoded(
        CciParser*  parser,
      CciContext*    context,
        int            encoding,
        int         ccsid
    ){
        PARSER_CONTEXT_ST* pc = (PARSER_CONTEXT_ST *)context ;
        int                rc;
  2. Obter um ponteiro para o buffer de mensagem e, em seguida, configurar o deslocamento utilizando a função de utilitário cpiBufferPointer:
      pc->iBuffer = (void *)cpiBufferPointer(&rc, parser);
      pc->iIndex = 0;
  3. Salvar o formato do buffer:
      pc->iEncoding = encoding;
      pc->iCcsid = ccsid;
  4. Salvar o tamanho do buffer utilizando a função de utilitário cpiBufferSize:
      pc->iSize = cpiBufferSize(&rc, parser);
  5. Obter o primeiro byte no fluxo utilizando a função de utilitário cpiBufferByte:
      pc->iCurrentCharacter = cpiBufferByte(&rc, parser, pc->iIndex);
  6. Configurar o elemento atual para o elemento raiz utilizando a função de utilitário cpiRootElement:
      pc->iCurrentElement = cpiRootElement(&rc, parser);
  7. Reconfigurar o sinalizador para assegurar-se de que a análise seja redefinida corretamente:
      pc->iInTag = 0;
  8. Reclamar a propriedade do restante do buffer:
      return(pc->iSize);
    }

Implementando Funções de Análise

As funções de análise geral (por exemplo, cpiParseFirstChild) são aquelas chamadas pelo intermediário quando a árvore de elementos da sintaxe precisar ser criada para avaliar uma expressão ESQL ou Java. Por exemplo, um nó de filtro utiliza uma referência de campo ESQL em uma expressão ESQL. Essa referência de campo precisa ser resolvida para avaliar a expressão. A função geral de análise do analisador é chamada, talvez repetidamente, até que o elemento pedido seja criado ou seja reconhecido pelo analisador como não existente.

Exemplo:
void cpiParseFirstChild(
    CciParser*  parser,
  CciContext*    context,
    CciElement* element
){
    PARSER_CONTEXT_ST* pc = (PARSER_CONTEXT_ST *)context ;
    int                rc;

  if ((!cpiElementCompleteNext(&rc, element)) &&
            (cpiElementType(&rc, element) == CCI_ELEMENT_TYPE_NAME)) {

    while ((!cpiElementCompleteNext(&rc, element))     &&
                      (!cpiFirstChild(&rc, element)) &&
           (pc->iCurrentElement))
    {
      pc->iCurrentElement = parseNextItem(parser, context, pc->iCurrentElement);
    }
  }
           return;
}

Implementando Funções de Saída

Existem três funções saída: Seu analisador deve implementar uma, e apenas uma, dessas funções de saída.

O intermediário deve chamar a função saída quando o analisador definido pelo usuário for necessário para serializar uma árvore de elemento de sintaxe para um fluxo de bits de saída. Por exemplo, um nó Compute pode ter criado uma árvore no domínio do analisador definido pelo usuário. Quando essa árvore precisar ser enviada para a saída, por exemplo, um nó MQOutput, o analisador é responsável por anexar o buffer do fluxo de bits de saída com dados que representam a árvore que foi construída.

Exemplo:
int cpiWriteBufferEncoded(
    CciParser*  parser,
  CciContext*    context,
    int            encoding,
    int         ccsid
){
    PARSER_CONTEXT_ST* pc = (PARSER_CONTEXT_ST *)context ;
    int                initialSize = 0;
    int                rc = 0;
    const void* a;
    CciByte b;

    initialSize = cpiBufferSize(&rc, parser);
    a = cpiBufferPointer(&rc, parser);
    b = cpiBufferByte(&rc, parser, 0);

    cpiAppendToBuffer(&rc, parser, (char *)"Some test data", 14);

    return cpiBufferSize(0, parser) - initialSize;
}

Implementando um Analisador de Cabeçalho da Mensagem

Normalmente, os dados da mensagem de entrada são de um único formato da mensagem, e portanto um analisador é responsável por analisar todo o conteúdo da mensagem. O nome da classe do analisador que é necessário é definido no campo Format no cabeçalho MQMD ou MQRFH2 da mensagem de entrada.

Entretanto, a mensagem pode consistir em vários formatos, por exemplo, onde exista um cabeçalho em um formato seguido por dados em outro formato. Nesse caso, o primeiro analisador tem que identificar o nome da classe do analisador que é responsável pelo próximo formato na cadeia, e assim por diante. Em um analisador definido pelo usuário, a função de implementação cpiNextParserClassName é chamada pelo intermediário quando ele precisa navegar por uma cadeia de classes de analisador para uma mensagem composta de vários formatos da mensagem.

Se o analisador definido pelo usuário suportar a análise de um formato de mensagem que faz parte de um formato de várias mensagens, o analisador definido pelo usuário deve implementar a função cpiNextParserClassName.

Exemplo:
  1. Chamar a função cpiNextParserClassName:
    void cpiNextParserClassName(
        CciParser*  parser,
      CciContext*    context,
        CciChar*    buffer,
        int         size
    ){
        PARSER_CONTEXT_ST* pc = (PARSER_CONTEXT_ST *)context ;
        int                rc = 0;
  2. Copiar o nome da próxima classe de analisador para o intermediário:
      CciCharNCpy(buffer, pc->iNextParserClassName, size);
    
               return;
    }
Avisos | Marcas Registradas | Downloads | Biblioteca | Suporte | Feedback
Direitos Autorais IBM Corporation 1999, 2006 Última Atualização: 1 Sep 2006
as24980_