socket/XmlBlasterUnmanaged.c

Go to the documentation of this file.
00001 /*----------------------------------------------------------------------------
00002 Name:      XmlBlasterUnmanaged.c
00003 Project:   xmlBlaster.org
00004 Copyright: xmlBlaster.org, see xmlBlaster-LICENSE file
00005 Comment:   Simple access layer to be used from .net or Mono
00006 Author:    "Marcel Ruff" <xmlBlaster@marcelruff.info>
00007 See:       http://www.xmlblaster.org/xmlBlaster/doc/requirements/protocol.socket.html
00008 -----------------------------------------------------------------------------*/
00009 #include <string.h> /* memset */
00010 #include <stdio.h> /* printf */
00011 #include <XmlBlasterUnmanaged.h>
00012 
00013 #ifndef WINCE
00014 
00015 /*
00016  To access this .dll as unmanaged code, the C-API must be simplified,
00017  for example fixed size arrays like "char errorCode[256]" are tricky.
00018  We implement here a simple wrapper around XmlBlasterAccessUnparsed.h
00019  TODO: How to pass byte[] to C and back to C#
00020  */
00021 
00022 static void convert(XmlBlasterException *in, XmlBlasterUnmanagedException *out) {
00023    out->errorCode = strcpyAlloc(in->errorCode);
00024    out->message = strcpyAlloc(in->message);
00025    out->remote = in->remote;
00026 }
00027 
00032 static XMLBLASTER_C_bool interceptUpdate(MsgUnitArr *msgUnitArr, void *userData, XmlBlasterException *exception) {
00033    size_t i;
00034    XmlBlasterUnmanagedException unmanagedException;
00035    
00036    XmlBlasterAccessUnparsed *xa = (XmlBlasterAccessUnparsed *)userData;
00037    XmlBlasterUnmanagedUpdateFp unmanagedUpdate = (XmlBlasterUnmanagedUpdateFp)(xa->userFp);
00038    
00039    if (userData != 0) ;  /* Supress compiler warning */
00040    if (unmanagedUpdate == 0) return false;
00041    
00042    /*memset(&unmanagedException, 0, sizeof(struct XmlBlasterUnmanagedException));*/
00043    unmanagedException.remote = false;
00044    unmanagedException.errorCode = (char)0;
00045    unmanagedException.message = (char)0;
00046    
00047 
00048    for (i=0; i<msgUnitArr->len; i++) {
00049       char *cbSessionId = strcpyAlloc(msgUnitArr->secretSessionId);
00050       const char *ret = 0;
00051       /*
00052       char *xml = messageUnitToXml(&msgUnitArr->msgUnitArr[i]);
00053       printf("[client] CALLBACK update(): Asynchronous message update arrived:%s\n",
00054              xml);
00055       xmlBlasterFree(xml);
00056       
00057       printf("XmlBlasterUnmanaged.c: before update() %d\n", (int)msgUnitArr->len);
00058       */
00059       
00060       /* Call C# ... TODO: how to pass a byte[], the Marshal does not know the contentLen */
00061       {
00062       char * contentStr = 
00063          strFromBlobAlloc(msgUnitArr->msgUnitArr[i].content, msgUnitArr->msgUnitArr[i].contentLen);
00064       ret = unmanagedUpdate(cbSessionId, msgUnitArr->msgUnitArr[i].key, contentStr,
00065          (int32_t)msgUnitArr->msgUnitArr[i].contentLen, msgUnitArr->msgUnitArr[i].qos, &unmanagedException);
00066       xmlBlasterFree(contentStr);
00067       xmlBlasterFree(cbSessionId);
00068       }
00069 
00070       if (unmanagedException.errorCode != 0) {
00071          /* catch first exception set and return */
00072          strncpy0(exception->errorCode, unmanagedException.errorCode, EXCEPTIONSTRUCT_ERRORCODE_LEN);
00073          if (unmanagedException.message != 0)
00074             strncpy0(exception->message, unmanagedException.message, EXCEPTIONSTRUCT_MESSAGE_LEN);
00075          exception->remote = unmanagedException.remote;
00076       }
00077    
00078       msgUnitArr->msgUnitArr[i].responseQos = strcpyAlloc(ret);
00079       printf("XmlBlasterUnmanaged.c: update() done with %s\n", ret);
00080       /* Return QoS: Everything is OK */
00081    }
00082    printf("XmlBlasterUnmanaged.c: update() done\n");
00083    
00084    return true;
00085 }
00086 
00087 Dll_Export XmlBlasterAccessUnparsed *getXmlBlasterAccessUnparsedUnmanaged(int argc, const char* const* argv){
00089    int i=0;
00090    const char ** ptr = (const char **)malloc(argc*sizeof(char *));
00091    for (i=0; i<argc; ++i) {
00092       ptr[i] = strcpyAlloc(argv[i]);
00093    }
00094    return getXmlBlasterAccessUnparsed(argc, ptr);
00095 }
00096 
00097 Dll_Export void freeXmlBlasterAccessUnparsedUnmanaged(XmlBlasterAccessUnparsed *xmlBlasterAccess) {
00098    if (xmlBlasterAccess != 0) {
00099       int i;
00100       for (i=0; i<xmlBlasterAccess->argc; ++i)
00101          free((void*)xmlBlasterAccess->argv[i]);
00102       free((void*)xmlBlasterAccess->argv);
00103       freeXmlBlasterAccessUnparsed(xmlBlasterAccess);
00104    }
00105 }
00106 
00107 Dll_Export bool xmlBlasterUnmanagedInitialize(struct XmlBlasterAccessUnparsed *xa, XmlBlasterUnmanagedUpdateFp update, XmlBlasterUnmanagedException *exception) {
00108    XmlBlasterException e;
00109    bool ret = false;
00110    xa->userFp = (XmlBlasterAccessGenericFp)update;
00111    ret = xa->initialize(xa, interceptUpdate, &e);
00112    convert(&e, exception);
00113    return ret; 
00114 }
00115 
00116 Dll_Export char *xmlBlasterUnmanagedConnect(struct XmlBlasterAccessUnparsed *xa, const char * const qos, XmlBlasterUnmanagedUpdateFp update, XmlBlasterUnmanagedException *exception) {
00117    XmlBlasterException e;
00118    char *ret = 0;
00119    if (update != 0)
00120       xa->userFp = (XmlBlasterAccessGenericFp)update;
00121    ret = xa->connect(xa, qos, interceptUpdate, &e);
00122    convert(&e, exception);
00123    return ret; 
00124 }
00125 
00126 Dll_Export extern bool xmlBlasterUnmanagedDisconnect(struct XmlBlasterAccessUnparsed *xa, const char * qos, XmlBlasterUnmanagedException *exception) {
00127    XmlBlasterException e;
00128    bool ret = xa->disconnect(xa, qos, &e);
00129    convert(&e, exception);
00130    return ret; 
00131 }
00132 
00133 Dll_Export extern char *xmlBlasterUnmanagedPublish(struct XmlBlasterAccessUnparsed *xa, MsgUnit *msgUnit, XmlBlasterUnmanagedException *exception) {
00134    XmlBlasterException e;
00135    char *ret = xa->publish(xa, msgUnit, &e);
00136    convert(&e, exception);
00137    return ret; 
00138 }
00139 
00140 Dll_Export extern QosArr *xmlBlasterUnmanagedPublishArr(struct XmlBlasterAccessUnparsed *xa, MsgUnitArr *msgUnitArr, XmlBlasterUnmanagedException *exception) {
00141    XmlBlasterException e;
00142    QosArr *ret = xa->publishArr(xa, msgUnitArr, &e);
00143    convert(&e, exception);
00144    return ret; 
00145 }
00146 
00147 Dll_Export extern void xmlBlasterUnmanagedPublishOneway(struct XmlBlasterAccessUnparsed *xa, MsgUnit *msgUnitArr, int length, XmlBlasterUnmanagedException *exception) {
00148    XmlBlasterException e;
00149    MsgUnitArr arr;
00150    /*printf("C: xmlBlasterUnmanagedPublishOneway %d", length);*/
00151    arr.isOneway = true;
00152    arr.len = length;
00153    arr.msgUnitArr = msgUnitArr;
00154    *arr.secretSessionId = 0;
00155    xa->publishOneway(xa, &arr, &e);
00156    convert(&e, exception);
00157 }
00158 
00159 Dll_Export extern char *xmlBlasterUnmanagedSubscribe(struct XmlBlasterAccessUnparsed *xa, const char * const key, const char * qos, XmlBlasterUnmanagedException *exception) {
00160    XmlBlasterException e;
00161    char *ret = xa->subscribe(xa, key, qos, &e);
00162    convert(&e, exception);
00163    return ret; 
00164 }
00165 
00166 Dll_Export void xmlBlasterUnmanagedUnSubscribe(struct XmlBlasterAccessUnparsed *xa, const char * const key, const char * qos, XmlBlasterUnmanagedException *exception, uint32_t* pSize, XmlBlasterUnmanagedStringArr** ppStruct) {
00167    XmlBlasterException e;
00168    QosArr *ret = 0;
00169    initializeXmlBlasterException(&e);
00170    ret = xa->unSubscribe(xa, key, qos, &e);
00171    convert(&e, exception);
00172    if (*e.errorCode != 0) {
00173       /*printf("C: Caught exception in unSubscribe errorCode=%s, message=%s\n", e.errorCode, e.message);*/
00174       if (ret) freeQosArr(ret);
00175       return;
00176    }
00177    if (ret) {
00178       size_t i;
00179       XmlBlasterUnmanagedStringArr* pCurStruct = 0;
00180       const uint32_t cArraySize = ret->len;
00181       *pSize = cArraySize;
00182       *ppStruct = (XmlBlasterUnmanagedStringArr*)malloc( cArraySize * sizeof( XmlBlasterUnmanagedStringArr ));
00183       pCurStruct = *ppStruct;
00184       for (i=0; i<ret->len; i++, pCurStruct++) {
00185          /*printf("C: Unsubscribe success, returned status is '%s'\n", ret->qosArr[i]);*/
00186          pCurStruct->str = strcpyAlloc(ret->qosArr[i]);
00187       }
00188       freeQosArr(ret);
00189    }
00190 }
00191 
00192 Dll_Export void xmlBlasterUnmanagedErase(struct XmlBlasterAccessUnparsed *xa, const char * const key, const char * qos, XmlBlasterUnmanagedException *exception, uint32_t* pSize, XmlBlasterUnmanagedStringArr** ppStruct) {
00193    XmlBlasterException e;
00194    QosArr *ret = 0;
00195    initializeXmlBlasterException(&e);
00196    ret = xa->erase(xa, key, qos, &e);
00197    convert(&e, exception);
00198    if (*e.errorCode != 0) {
00199       if (ret) freeQosArr(ret);
00200       return;
00201    }
00202    if (ret) {
00203       size_t i;
00204       XmlBlasterUnmanagedStringArr* pCurStruct = 0;
00205       const uint32_t cArraySize = ret->len;
00206       *pSize = cArraySize;
00207       *ppStruct = (XmlBlasterUnmanagedStringArr*)malloc( cArraySize * sizeof( XmlBlasterUnmanagedStringArr ));
00208       pCurStruct = *ppStruct;
00209       for (i=0; i<ret->len; i++, pCurStruct++) {
00210          pCurStruct->str = strcpyAlloc(ret->qosArr[i]);
00211       }
00212       freeQosArr(ret);
00213    }
00214 }
00215 
00216 Dll_Export void xmlBlasterUnmanagedGet(struct XmlBlasterAccessUnparsed *xa,
00217         const char * const key, const char * qos, XmlBlasterUnmanagedException *exception,
00218         uint32_t* pSize, MsgUnit** ppStruct) {
00219    XmlBlasterException e;
00220    uint32_t i;
00221    MsgUnitArr *msgUnitArr = xa->get(xa, key, qos, &e);
00222    convert(&e, exception);
00223    if (*e.errorCode != 0) {
00224       return;
00225    }
00226    if (msgUnitArr != (MsgUnitArr *)0) {
00227       const uint32_t cArraySize = msgUnitArr->len;
00228       MsgUnit* pCurStruct = 0;
00229       *pSize = cArraySize;
00230       *ppStruct = (MsgUnit*)malloc( cArraySize * sizeof( MsgUnit ));
00231       pCurStruct = *ppStruct;
00232       /*printf("C: xmlBlasterUnmanagedGet %ud\n", cArraySize);*/
00233       for( i=0; i < cArraySize; i++, pCurStruct++ ) {
00234          MsgUnit *msgUnit = &msgUnitArr->msgUnitArr[i];
00235          /* TODO: pass as byte[] */
00236          pCurStruct->content = strFromBlobAlloc(msgUnit->content, msgUnit->contentLen);
00237          pCurStruct->contentLen = msgUnit->contentLen;
00238          pCurStruct->key = strcpyAlloc(msgUnit->key);
00239          pCurStruct->qos = strcpyAlloc(msgUnit->qos);
00240          pCurStruct->responseQos = strcpyAlloc("<qos/>");
00241       }
00242       freeMsgUnitArr(msgUnitArr);
00243    }
00244 }
00245 
00246 Dll_Export char *xmlBlasterUnmanagedPing(struct XmlBlasterAccessUnparsed *xa, const char * const qos, XmlBlasterUnmanagedException *exception) {
00247    XmlBlasterException e;
00248    char *ret = xa->ping(xa, qos, &e);
00249    convert(&e, exception);
00250    return ret; 
00251 }
00252 
00253 Dll_Export bool xmlBlasterUnmanagedIsConnected(struct XmlBlasterAccessUnparsed *xa) {
00254    return xa->isConnected(xa);
00255 }
00256 
00257 Dll_Export const char *xmlBlasterUnmanagedUsage() {
00258    char *usage = (char *)malloc(XMLBLASTER_MAX_USAGE_LEN*sizeof(char));
00259    return xmlBlasterAccessUnparsedUsage(usage);
00260 }
00261 
00262 #endif