1 /*----------------------------------------------------------------------------
  2 Name:      XmlBlasterUnmanaged.c
  3 Project:   xmlBlaster.org
  4 Copyright: xmlBlaster.org, see xmlBlaster-LICENSE file
  5 Comment:   Simple access layer to be used from .net or Mono
  6 Author:    "Marcel Ruff" <xmlBlaster@marcelruff.info>
  7 See:       http://www.xmlblaster.org/xmlBlaster/doc/requirements/protocol.socket.html
  8 -----------------------------------------------------------------------------*/
  9 #include <string.h> /* memset */

 10 #include <stdio.h> /* printf */

 11 #include <XmlBlasterUnmanaged.h>

 12 
 13 #ifndef WINCE

 14 
 15 /*
 16  To access this .dll as unmanaged code, the C-API must be simplified,
 17  for example fixed size arrays like "char errorCode[256]" are tricky.
 18  We implement here a simple wrapper around XmlBlasterAccessUnparsed.h
 19  TODO: How to pass byte[] to C and back to C#
 20  */
 21 
 22 static void convert(XmlBlasterException *in, XmlBlasterUnmanagedException *out) {
 23    out->errorCode = strcpyAlloc(in->errorCode);
 24    out->message = strcpyAlloc(in->message);
 25    out->remote = in->remote;
 26 }
 27 
 28 /**
 29  * We intercept the callbacks here and convert it to a more simple form to
 30  * be easy transferable to C# (Csharp). 
 31  */
 32 static XMLBLASTER_C_bool interceptUpdate(MsgUnitArr *msgUnitArr, void *userData, XmlBlasterException *exception) {
 33    size_t i;
 34    XmlBlasterUnmanagedException unmanagedException;
 35    
 36    XmlBlasterAccessUnparsed *xa = (XmlBlasterAccessUnparsed *)userData;
 37    XmlBlasterUnmanagedUpdateFp unmanagedUpdate = (XmlBlasterUnmanagedUpdateFp)(xa->userFp);
 38    
 39    if (userData != 0) ;  /* Supress compiler warning */
 40    if (unmanagedUpdate == 0) return false;
 41    
 42    /*memset(&unmanagedException, 0, sizeof(struct XmlBlasterUnmanagedException));*/
 43    unmanagedException.remote = false;
 44    unmanagedException.errorCode = (char)0;
 45    unmanagedException.message = (char)0;
 46    
 47 
 48    for (i=0; i<msgUnitArr->len; i++) {
 49       char *cbSessionId = strcpyAlloc(msgUnitArr->secretSessionId);
 50       const char *ret = 0;
 51       /*
 52       char *xml = messageUnitToXml(&msgUnitArr->msgUnitArr[i]);
 53       printf("[client] CALLBACK update(): Asynchronous message update arrived:%s\n",
 54              xml);
 55       xmlBlasterFree(xml);
 56       
 57       printf("XmlBlasterUnmanaged.c: before update() %d\n", (int)msgUnitArr->len);
 58       */
 59       
 60       /* Call C# ... TODO: how to pass a byte[], the Marshal does not know the contentLen */
 61       {
 62       char * contentStr = 
 63          strFromBlobAlloc(msgUnitArr->msgUnitArr[i].content, msgUnitArr->msgUnitArr[i].contentLen);
 64       ret = unmanagedUpdate(cbSessionId, msgUnitArr->msgUnitArr[i].key, contentStr,
 65          (int32_t)msgUnitArr->msgUnitArr[i].contentLen, msgUnitArr->msgUnitArr[i].qos, &unmanagedException);
 66       xmlBlasterFree(contentStr);
 67       xmlBlasterFree(cbSessionId);
 68       }
 69 
 70       if (unmanagedException.errorCode != 0) {
 71          /* catch first exception set and return */
 72          strncpy0(exception->errorCode, unmanagedException.errorCode, EXCEPTIONSTRUCT_ERRORCODE_LEN);
 73          if (unmanagedException.message != 0)
 74             strncpy0(exception->message, unmanagedException.message, EXCEPTIONSTRUCT_MESSAGE_LEN);
 75          exception->remote = unmanagedException.remote;
 76       }
 77    
 78       msgUnitArr->msgUnitArr[i].responseQos = strcpyAlloc(ret);
 79       printf("XmlBlasterUnmanaged.c: update() done with %s\n", ret);
 80       /* Return QoS: Everything is OK */
 81    }
 82    printf("XmlBlasterUnmanaged.c: update() done\n");
 83    
 84    return true;
 85 }
 86 
 87 Dll_Export XmlBlasterAccessUnparsed *getXmlBlasterAccessUnparsedUnmanaged(int argc, const char* const* argv){
 88    /** argv seems to be freed by C#, so we clone it here */
 89    int i=0;
 90    const char ** ptr = (const char **)malloc(argc*sizeof(char *));
 91    for (i=0; i<argc; ++i) {
 92       ptr[i] = strcpyAlloc(argv[i]);
 93    }
 94    return getXmlBlasterAccessUnparsed(argc, ptr);
 95 }
 96 
 97 Dll_Export void freeXmlBlasterAccessUnparsedUnmanaged(XmlBlasterAccessUnparsed *xmlBlasterAccess) {
 98    if (xmlBlasterAccess != 0) {
 99       int i;
100       for (i=0; i<xmlBlasterAccess->argc; ++i)
101          free((void*)xmlBlasterAccess->argv[i]);
102       free((void*)xmlBlasterAccess->argv);
103       freeXmlBlasterAccessUnparsed(xmlBlasterAccess);
104    }
105 }
106 
107 Dll_Export bool xmlBlasterUnmanagedInitialize(struct XmlBlasterAccessUnparsed *xa, XmlBlasterUnmanagedUpdateFp update, XmlBlasterUnmanagedException *exception) {
108    XmlBlasterException e;
109    bool ret = false;
110    xa->userFp = (XmlBlasterAccessGenericFp)update;
111    ret = xa->initialize(xa, interceptUpdate, &e);
112    convert(&e, exception);
113    return ret; 
114 }
115 
116 Dll_Export char *xmlBlasterUnmanagedConnect(struct XmlBlasterAccessUnparsed *xa, const char * const qos, XmlBlasterUnmanagedUpdateFp update, XmlBlasterUnmanagedException *exception) {
117    XmlBlasterException e;
118    char *ret = 0;
119    if (update != 0)
120       xa->userFp = (XmlBlasterAccessGenericFp)update;
121    ret = xa->connect(xa, qos, interceptUpdate, &e);
122    convert(&e, exception);
123    return ret; 
124 }
125 
126 Dll_Export extern bool xmlBlasterUnmanagedDisconnect(struct XmlBlasterAccessUnparsed *xa, const char * qos, XmlBlasterUnmanagedException *exception) {
127    XmlBlasterException e;
128    bool ret = xa->disconnect(xa, qos, &e);
129    convert(&e, exception);
130    return ret; 
131 }
132 
133 Dll_Export extern char *xmlBlasterUnmanagedPublish(struct XmlBlasterAccessUnparsed *xa, MsgUnit *msgUnit, XmlBlasterUnmanagedException *exception) {
134    XmlBlasterException e;
135    char *ret = xa->publish(xa, msgUnit, &e);
136    convert(&e, exception);
137    return ret; 
138 }
139 
140 Dll_Export extern QosArr *xmlBlasterUnmanagedPublishArr(struct XmlBlasterAccessUnparsed *xa, MsgUnitArr *msgUnitArr, XmlBlasterUnmanagedException *exception) {
141    XmlBlasterException e;
142    QosArr *ret = xa->publishArr(xa, msgUnitArr, &e);
143    convert(&e, exception);
144    return ret; 
145 }
146 
147 Dll_Export extern void xmlBlasterUnmanagedPublishOneway(struct XmlBlasterAccessUnparsed *xa, MsgUnit *msgUnitArr, int length, XmlBlasterUnmanagedException *exception) {
148    XmlBlasterException e;
149    MsgUnitArr arr;
150    /*printf("C: xmlBlasterUnmanagedPublishOneway %d", length);*/
151    arr.isOneway = true;
152    arr.len = length;
153    arr.msgUnitArr = msgUnitArr;
154    *arr.secretSessionId = 0;
155    xa->publishOneway(xa, &arr, &e);
156    convert(&e, exception);
157 }
158 
159 Dll_Export extern char *xmlBlasterUnmanagedSubscribe(struct XmlBlasterAccessUnparsed *xa, const char * const key, const char * qos, XmlBlasterUnmanagedException *exception) {
160    XmlBlasterException e;
161    char *ret = xa->subscribe(xa, key, qos, &e);
162    convert(&e, exception);
163    return ret; 
164 }
165 
166 Dll_Export void xmlBlasterUnmanagedUnSubscribe(struct XmlBlasterAccessUnparsed *xa, const char * const key, const char * qos, XmlBlasterUnmanagedException *exception, uint32_t* pSize, XmlBlasterUnmanagedStringArr** ppStruct) {
167    XmlBlasterException e;
168    QosArr *ret = 0;
169    initializeXmlBlasterException(&e);
170    ret = xa->unSubscribe(xa, key, qos, &e);
171    convert(&e, exception);
172    if (*e.errorCode != 0) {
173       /*printf("C: Caught exception in unSubscribe errorCode=%s, message=%s\n", e.errorCode, e.message);*/
174       if (ret) freeQosArr(ret);
175       return;
176    }
177    if (ret) {
178       size_t i;
179       XmlBlasterUnmanagedStringArr* pCurStruct = 0;
180       const uint32_t cArraySize = ret->len;
181       *pSize = cArraySize;
182       *ppStruct = (XmlBlasterUnmanagedStringArr*)malloc( cArraySize * sizeof( XmlBlasterUnmanagedStringArr ));
183       pCurStruct = *ppStruct;
184       for (i=0; i<ret->len; i++, pCurStruct++) {
185          /*printf("C: Unsubscribe success, returned status is '%s'\n", ret->qosArr[i]);*/
186          pCurStruct->str = strcpyAlloc(ret->qosArr[i]);
187       }
188       freeQosArr(ret);
189    }
190 }
191 
192 Dll_Export void xmlBlasterUnmanagedErase(struct XmlBlasterAccessUnparsed *xa, const char * const key, const char * qos, XmlBlasterUnmanagedException *exception, uint32_t* pSize, XmlBlasterUnmanagedStringArr** ppStruct) {
193    XmlBlasterException e;
194    QosArr *ret = 0;
195    initializeXmlBlasterException(&e);
196    ret = xa->erase(xa, key, qos, &e);
197    convert(&e, exception);
198    if (*e.errorCode != 0) {
199       if (ret) freeQosArr(ret);
200       return;
201    }
202    if (ret) {
203       size_t i;
204       XmlBlasterUnmanagedStringArr* pCurStruct = 0;
205       const uint32_t cArraySize = ret->len;
206       *pSize = cArraySize;
207       *ppStruct = (XmlBlasterUnmanagedStringArr*)malloc( cArraySize * sizeof( XmlBlasterUnmanagedStringArr ));
208       pCurStruct = *ppStruct;
209       for (i=0; i<ret->len; i++, pCurStruct++) {
210          pCurStruct->str = strcpyAlloc(ret->qosArr[i]);
211       }
212       freeQosArr(ret);
213    }
214 }
215 
216 Dll_Export void xmlBlasterUnmanagedGet(struct XmlBlasterAccessUnparsed *xa,
217         const char * const key, const char * qos, XmlBlasterUnmanagedException *exception,
218         uint32_t* pSize, MsgUnit** ppStruct) {
219    XmlBlasterException e;
220    uint32_t i;
221    MsgUnitArr *msgUnitArr = xa->get(xa, key, qos, &e);
222    convert(&e, exception);
223    if (*e.errorCode != 0) {
224       return;
225    }
226    if (msgUnitArr != (MsgUnitArr *)0) {
227       const uint32_t cArraySize = msgUnitArr->len;
228       MsgUnit* pCurStruct = 0;
229       *pSize = cArraySize;
230       *ppStruct = (MsgUnit*)malloc( cArraySize * sizeof( MsgUnit ));
231       pCurStruct = *ppStruct;
232       /*printf("C: xmlBlasterUnmanagedGet %ud\n", cArraySize);*/
233       for( i=0; i < cArraySize; i++, pCurStruct++ ) {
234          MsgUnit *msgUnit = &msgUnitArr->msgUnitArr[i];
235          /* TODO: pass as byte[] */
236          pCurStruct->content = strFromBlobAlloc(msgUnit->content, msgUnit->contentLen);
237          pCurStruct->contentLen = msgUnit->contentLen;
238          pCurStruct->key = strcpyAlloc(msgUnit->key);
239          pCurStruct->qos = strcpyAlloc(msgUnit->qos);
240          pCurStruct->responseQos = strcpyAlloc("<qos/>");
241       }
242       freeMsgUnitArr(msgUnitArr);
243    }
244 }
245 
246 Dll_Export char *xmlBlasterUnmanagedPing(struct XmlBlasterAccessUnparsed *xa, const char * const qos, XmlBlasterUnmanagedException *exception) {
247    XmlBlasterException e;
248    char *ret = xa->ping(xa, qos, &e);
249    convert(&e, exception);
250    return ret; 
251 }
252 
253 Dll_Export bool xmlBlasterUnmanagedIsConnected(struct XmlBlasterAccessUnparsed *xa) {
254    return xa->isConnected(xa);
255 }
256 
257 Dll_Export const char *xmlBlasterUnmanagedUsage(void) {
258 
259    char *usage = (char *)malloc(XMLBLASTER_MAX_USAGE_LEN*sizeof(char));
260    return xmlBlasterAccessUnparsedUsage(usage);
261 }
262 
263 #endif /*!defined(WINCE)*/



syntax highlighted by Code2HTML, v. 0.9.1