#ifdef __WIN32 #include <windows.h> #endif #include <BipCos.h> #include <BipCci.h> #include <BipCni.h> #include <malloc.h> #define BIP_DEF_COMP_CCSID 437 CciChar* constNodeFactory = 0; CciChar* constNodeName = 0; CciChar* constTerminalName = 0; CciChar* constOutTerminalName = 0; CciChar* CciString( const char* source, int codepage ){ /* Número máximo de caracteres en representación Unicode */ int maxChars = strlen(source) + 1 ; CciChar* buffer = (CciChar*)malloc(maxChars * sizeof(CciChar)) ; int rc; cciMbsToUcs(&rc, source, buffer, maxChars, codepage) ; return buffer ; } void initNodeConstants(){ constNodeFactory = CciString("myNodeFactory", BIP_DEF_COMP_CCSID); constNodeName = CciString("myNode",BIP_DEF_COMP_CCSID); constTerminalName = CciString("in",BIP_DEF_COMP_CCSID); constOutTerminalName = CciString("out",BIP_DEF_COMP_CCSID); } typedef struct { CciTerminal* iOutTerminal; }MyNodeContext; CciContext* createNodeContext( CciFactory* factoryObject, CciChar* nodeName, CciNode* nodeObject ){ MyNodeContext * p = (MyNodeContext *)malloc(sizeof(MyNodeContext)); /*aquí se crearía una instancia de una estructura de datos donde se podría almacenar contexto sobre esta instancia de nodo. Devolveríamos un puntero a esta estructura y ese puntero se pasaría a otras funciones de implementación */ /* ahora creamos un terminal de entrada para el nodo */ cniCreateInputTerminal(NULL, nodeObject, (CciChar*)constTerminalName); p->iOutTerminal = cniCreateOutputTerminal(NULL, nodeObject, (CciChar*)constOutTerminalName); return((CciContext*)p); } /****************************************************************/ /* */ /* Función de implementación de nodo de conexión: cniEvaluate() */ /* */ /****************************************************************/ void evaluate( CciContext* context, CciMessage* destinationList, CciMessage* exceptionList, CciMessage* message ){ /* aquí pondríamos la lógica de proceso de nuestro nodo */ return; } int run( CciContext* context, CciMessage* destinationList, CciMessage* exceptionList, CciMessage* message ) { char* buffer="<doc><test>hello</test></doc>"; CciChar* wBuffer=CciString(buffer,BIP_DEF_COMP_CCSID); //cniSetInputBuffer(NULL,message,(void*)wBuffer,strlen(buffer) * sizeof(CciChar)); cniSetInputBuffer(NULL,message,(void*)buffer,strlen(buffer)); cniFinalize(NULL,message,0); cniPropagate(NULL,((MyNodeContext*)context)->iOutTerminal,destinationList,exceptionList,message); return CCI_SUCCESS_CONTINUE; } #ifdef __cplusplus extern "C"{ #endif CciFactory LilFactoryExportPrefix * LilFactoryExportSuffix bipGetMessageflowNodeFactory() { CciFactory* factoryObject; /* Antes de continuar es necesario inicializar todas las constantes estáticas */ /* que es posible que el plug-in utilice. */ initNodeConstants(); /* Crear la fábrica de nodos para este plug-in */ /* Si se produce algún error/excepción durante */ /* la ejecución de esta función de programa de utilidad, como no se ha */ /* proporcionado el argumento returnCode, la excepción ignorará el plugin */ /* y la manejará directamente el intermediario. */ factoryObject = cniCreateNodeFactory(0, (unsigned short *)constNodeFactory); if (factoryObject == CCI_NULL_ADDR) { /* Aquí puede ir cualquier manejo de errores locales adicional */ } else { /* Definir el nodo soportado por esta fábrica */ static CNI_VFT vftable = {CNI_VFT_DEFAULT}; /* Configurar tabla de funciones con punteros a funciones de implementación de nodo */ vftable.iFpCreateNodeContext = createNodeContext; vftable.iFpEvaluate = evaluate; vftable.iFpRun = run; /* Definir un tipo de nodo soportado por nuestra fábrica. Si hay un error en */ /* la ejecución de esta función de programa de utilidad, como no se ha */ /* proporcionado el argumento returnCode, la excepción ignorará el plugin */ /* y la manejará directamente el intermediario. */ cniDefineNodeClass(NULL, factoryObject, (CciChar*)constNodeName, &vftable); } /* Devolver la dirección de este objeto de fábrica al intermediario */ return(factoryObject); } #ifdef __cplusplus } #endif
A continuación se muestra un archivo make que lista los archivos, las dependencias y las normas que deben satisfacerse al compilar el nodo definido por el usuario en C.
.SUFFIXES : .so .a .o .c R1INC = . R1LIB = . # WMQI MQSIDIR = /cmvc/back/inst.images/x86_linux_2/shipdata/opt/mqsi MQSIINC = $(MQSIDIR)/include MQSILIB = $(MQSIDIR)/lib # WMQ MQIDIR = /usr/mqm CC = /usr/bin/g++ LD = ${CC} OBJ = .o LIL = .lil THINGSTOCLEAN = *${OBJ} CFLAGS = -fpic -c #-pedantic -x c -Wall CFLAGSADD = -I${R1INC} -I${MQSIINC} -I${MQSIINC}/plugin ${DEFINES} DEFINES = -DLINUX LIBADD = -L${MQSILIB} -limbdfplg LDFLAG = -shared ${LIBADD} #CC = /usr/bin/gcc #LD = ${CC} OBJECTS = skeleton${OBJ} .c.o : ; ${CC} ${CFLAGS} ${CFLAGSADD} $< ALL : ${OBJECTS} Samples${LIL} clean: rm *${OBJ} *${LIL} skeleton${OBJ}: skeleton.c Samples${LIL}: ${OBJECTS} ${LD} -o $@ ${OBJECTS} ${LDFLAG}