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