Ampliación de las posibilidades de un analizador definido por el usuario en C
Cuando haya creado un analizador en C, podrá ampliar sus posibilidades.
Antes de empezar
Acerca de esta tarea
Implementación de la funcionalidad de analizador
Acerca de esta tarea
- Funciones de entrada
- Funciones de análisis
- Funciones de salida
Implementación de funciones de entrada
Acerca de esta tarea
El nodo de integración invoca la función de entrada cuando se necesita el analizador definido por el usuario para analizar un mensaje de entrada. El analizador debe indicar al nodo de integración qué cantidad de almacenamiento intermedio de corriente de bits de entrada reclama como propietario. En el caso de una cabecera de tamaño fijo, el analizador reclama el tamaño de la cabecera. Si el analizador está destinado a manejar el mensaje completo, reclama el resto del almacenamiento intermedio.
- El nodo de integración invoca la función de entrada cpiParseBufferEncoded:
int cpiParseBufferEncoded( CciParser* parser, CciContext* context, int encoding, int ccsid ){ PARSER_CONTEXT_ST* pc = (PARSER_CONTEXT_ST *)context ; int rc; - Obtenga un puntero al almacenamiento intermedio de mensajes y
establezca el desplazamiento utilizando la función de utilidad
cpiBufferPointer:
pc->iBuffer = (void *)cpiBufferPointer(&rc, parser); pc->iIndex = 0; - Guarde el formato del almacenamiento intermedio:
pc->iEncoding = encoding; pc->iCcsid = ccsid; - Guarde el tamaño del almacenamiento intermedio utilizando la función de utilidad cpiBufferSize:
pc->iSize = cpiBufferSize(&rc, parser); - Cargue el primer byte de la corriente utilizando la función de
utilidad cpiBufferByte:
pc->iCurrentCharacter = cpiBufferByte(&rc, parser, pc->iIndex); - Establezca el elemento actual en el elemento raíz utilizando la
función de utilidad cpiRootElement:
pc->iCurrentElement = cpiRootElement(&rc, parser); - Restablezca el distintivo para asegurarse de que el análisis se restablece correctamente:
pc->iInTag = 0; - Reclame la propiedad del resto del almacenamiento intermedio:
return(pc->iSize); }
Implementación de funciones de análisis
Acerca de esta tarea
Las funciones de análisis generales (por ejemplo, cpiParseFirstChild) son las invocadas por el nodo de integración cuando es necesario crear el árbol de elementos de sintaxis para evaluar una expresión ESQL o Java™ . Por ejemplo, un nodo Filtrar utiliza una referencia de campo ESQL en una expresión ESQL. Esta referencia de campo se debe resolver a fin de evaluar la expresión. Se llama a la función de análisis general del analizador, quizá repetidamente, hasta que el elemento solicitado se crea o hasta que el analizador reconoce que dicho elemento no existe.
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;
}Implementación de funciones de salida
Acerca de esta tarea
El nodo de integración invoca la función de salida cuando se necesita el analizador definido por el usuario para serializar un árbol de elementos de sintaxis en una corriente de bits de salida. Por ejemplo, un nodo Compute puede haber creado un árbol en el dominio del analizador definido por el usuario. Cuando un nodo, como un nodo MQOutput , necesita serializar este árbol, el analizador es responsable de añadir el almacenamiento intermedio de corriente de bits de salida con datos que representan el árbol que se ha creado.
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;
}Implementación del analizador de cabeceras de mensajes
Acerca de esta tarea
Normalmente, dado que los datos de mensaje de entrada
tienen un solo formato de mensaje, un analizador es responsable de analizar el contenido
entero del mensaje. El nombre de clase del analizador necesario se define en el campo Format del MQMD o la cabecera MQRFH2 del mensaje de entrada.
Sin embargo, es posible que el mensaje conste de varios formatos, donde, por ejemplo, hay una cabecera en un formato seguida de datos en otro formato. En este caso, el primer analizador tiene que identificar el nombre de clase del analizador que es responsable del siguiente formato de la cadena, y así sucesivamente. En un analizador definido por el usuario, el nodo de integración invoca la función de implementación cpiNextParserClassName cuando navega hacia abajo en una cadena de clases de analizador para un mensaje que está formado por varios formatos de mensaje.
Si el analizador definido por el usuario soporta el análisis de un formato de mensaje que forma parte de un formato de mensaje múltiple, el analizador definido por el usuario debe implementar la función cpiNextParserClassName.
- Invoque la función
cpiNextParserClassName:
void cpiNextParserClassName( CciParser* parser, CciContext* context, CciChar* buffer, int size ){ PARSER_CONTEXT_ST* pc = (PARSER_CONTEXT_ST *)context ; int rc = 0; - Copie el nombre de la siguiente clase de analizador en el nodo de integración:
CciCharNCpy(buffer, pc->iNextParserClassName, size); return; }