Quando você tiver criado um analisador C, você poderá estender a sua capacidade.
O intermediário chama a função input 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.
int cpiParseBufferEncoded( CciParser* parser, CciContext* context, int encoding, int ccsid ){ PARSER_CONTEXT_ST* pc = (PARSER_CONTEXT_ST *)context ; int rc;
pc->iBuffer = (void *)cpiBufferPointer(&rc, parser); pc->iIndex = 0;
pc->iEncoding = encoding; pc->iCcsid = ccsid;
pc->iSize = cpiBufferSize(&rc, parser);
pc->iCurrentCharacter = cpiBufferByte(&rc, parser, pc->iIndex);
pc->iCurrentElement = cpiRootElement(&rc, parser);
pc->iInTag = 0;
return(pc->iSize); }
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ó Filter 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.
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; }
O intermediário chama a função output quando o analisador definido pelo usuário for necessário para serializar uma árvore de elementos 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 um nó, como um nó MQOutput, precisar serializar essa árvore, o analisador é responsável poe anexar o buffer de fluxo de bits de saída com dados que representam a árvore que foi construída.
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; }
Geralmente, os dados da mensagem de entrada são de um único formato da mensagem; 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 navega por uma cadeia de classes de analisador para uma mensagem composta por 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.
void cpiNextParserClassName( CciParser* parser, CciContext* context, CciChar* buffer, int size ){ PARSER_CONTEXT_ST* pc = (PARSER_CONTEXT_ST *)context ; int rc = 0;
CciCharNCpy(buffer, pc->iNextParserClassName, size); return; }