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