1 // NativeC.cs
2 // deprecated: Please use the PInvokeCE.cs plugin
3 // Remains for .NET 1.x code and for older Mono 'mcs' compiler.
4 //
5 // Simple layer to delegate C# calls to xmlBlaster client C library (using P/Invoke).
6 // libxmlBlasterClientC.so on Mono/Linux is accessed and must be available
7 // xmlBlasterClientC.dll on Windows is needed and must be available
8 //
9 // This code is functional but still beta (2006-08)
10 //
11 // Currently only tested on Linux with Mono and on Windows XP
12 //
13 // It will NOT work with Windows CE because of the limited compact framework .net (CF)
14 // Please use the PInvokeCE.cs plugin instead.
15 //
16 // Mono/Linux 1.2 ships with complete C# 1.0 and C# 2.0 compilers, both of them can be used here
17 //
18 // Features: All features of the client C library (compression, tunnel callbacks), see
19 // http://www.xmlblaster.org/xmlBlaster/doc/requirements/client.c.socket.html
20 //
21 // IMPORTANT: Please edit/change the lookup path below for xmlBlasterClientC.dll
22 // and set the PATH to access it
23 //
24 // @todo port content from 'string' to byte[]
25 // publishOneway crashes
26 // OnUpdate() throwing exception seems not to be passed to C
27 // logging with log4net
28 // port C to WindowsCE
29 // write a testsuite
30 // write a requirement
31 // create an assembly with ant or nant
32 // create the same wrapper for the xmlBlaster C++ library
33 //
34 // @author mr@marcelruff.info
35 //
36 // @prepare Linux: cd ~/xmlBlaster; build c-lib; cd ~/xmlBlaster/src/csharp; ln -s ../../lib/libxmlBlasterClientCD.so .
37 // @compile Linux: mcs /d:NATIVE_C_MAIN /d:XMLBLASTER_MONO -debug+ -out:NativeC.exe NativeC.cs XmlBlasterAccess.cs
38 //
39 // @prepare Windows: Compile the C client library first (see xmlBlaster\src\c\xmlBlasterClientC.sln)
40 // @compile Windows: csc /d:NATIVE_C_MAIN -debug+ -out:NativeC.exe NativeC.cs XmlBlasterAccess.cs (Windows)
41 //
42 // @run mono NativeC.exe
43 // mono NativeC.exe --help
44 // mono NativeC.exe -logLevel TRACE
45 // @see http://www.xmlblaster.org/xmlBlaster/doc/requirements/client.csharp.html
46 // @c http://www.xmlBlaster/org
47 //
48 /*
49 Usage:
50 XmlBlaster C SOCKET client
51
52 -dispatch/connection/plugin/socket/hostname [localhost]
53 Where to find xmlBlaster.
54 -dispatch/connection/plugin/socket/port [7607]
55 The port where xmlBlaster listens.
56 -dispatch/connection/plugin/socket/localHostname [NULL]
57 Force the local IP, useful on multi homed computers.
58 -dispatch/connection/plugin/socket/localPort [0]
59 Force the local port, useful to tunnel firewalls.
60 -dispatch/connection/plugin/socket/compress/type []
61 Switch on compression with 'zlib:stream'.
62 -dispatch/connection/plugin/socket/useUdpForOneway [false]
63 Use UDP for publishOneway() calls.
64 -dispatch/callback/plugin/socket/hostname [localhost]
65 The IP where to establish the callback server.
66 Can be useful on multi homed hosts.
67 -dispatch/callback/plugin/socket/port [7611]
68 The port of the callback server.
69 -plugin/socket/multiThreaded [true]
70 If true the update() call to your client code is a separate thread.
71 -plugin/socket/responseTimeout [60000 (one minute)]
72 The time in millis to wait on a response, 0 is forever.
73 -logLevel ERROR | WARN | INFO | TRACE | DUMP [WARN]
74
75 Example:
76 mono NativeC -logLevel TRACE -dispatch/connection/plugin/socket/hostname 192.168.2.9
77 */
78 using System;
79 using System.Runtime.InteropServices;
80 using System.Collections;
81
82 namespace org.xmlBlaster.client
83 {
84 /// Calling unmanagegd code: libxmlBlasterClientC.so (Mono) or xmlBlasterClientC.dll (Windows)
85 public class NativeC : I_XmlBlasterAccess
86 {
87 bool verbose = false; // TODO: log4net
88
89 # if XMLBLASTER_MONO // Linux Debug, set LD_LIBRARY_PATH to find the shared library
90 const string XMLBLASTER_C_LIBRARY = "xmlBlasterClientCD"; //libxmlBlasterClientCD.so
91 # else // Windows
92 // http://msdn2.microsoft.com/en-us/library/e765dyyy.aspx
93 //[DllImport("user32.dll", CharSet = CharSet.Auto)]
94 // Throw the DLL to the current directory or set your PATH pointing to the dll:
95 const string XMLBLASTER_C_LIBRARY = "xmlBlasterClientC.dll";
96 // or provide an absolute name:
97 //const string XMLBLASTER_C_LIBRARY = "..\\..\\lib\\xmlBlasterClientC.dll";
98 # endif
99
100 // Helper struct for DLL calls to avoid 'fixed' and unsafe
101 struct XmlBlasterUnmanagedException
102 {
103 public int remote;
104 public string errorCode;
105 public string message;
106 }
107
108 public struct QosArr
109 {
110 public int len; /* Number of XML QoS strings */
111 public string[] qosArr;
112 }
113
114 public struct MsgUnitUnmanagedArr
115 {
116 public string secretSessionId;
117 public int len;
118 public MsgUnit_[] msgUnitArr;
119 }
120
121 // SEE http://msdn2.microsoft.com/en-us/library/2k1k68kw.aspx
122 // Declares a class member for each structure element.
123 // Must match exactly the C struct MsgUnit (sequence!)
124 [StructLayout(LayoutKind.Sequential/*, CharSet=CharSet.Unicode*/ )]
125 public class MsgUnit_
126 {
127 public string key;
128 public int contentLen;
129 // Without MarshalAs: ** ERROR **: Structure field of type Byte[] can't be marshalled as LPArray
130 //[MarshalAs (UnmanagedType.ByValArray, SizeConst=100)] // does not work unlimited without SizeConst -> SIGSEGV
131 // public byte[] content; // Ensure UTF8 encoding for strings
132 public string content;
133 public string qos;
134 public string responseQos;
135 public MsgUnit_() { }
136 public MsgUnit_(string key, string contentStr, string qos)
137 {
138 this.key = key;
139 this.contentLen = contentStr.Length;
140 setContentStr(contentStr);
141 this.qos = qos;
142 }
143 /// We return a string in the default codeset
144 public string getContentStr()
145 {
146 //System.Text.ASCIIEncoding enc = new System.Text.ASCIIEncoding();
147 //return enc.GetString(this.content);
148 // How does this work? System.Text.Decoder d = System.Text.Encoding.UTF8.GetDecoder();
149 return this.content;
150 }
151 /// The binary string is UTF8 encoded (xmlBlaster default)
152 public void setContentStr(string contentStr)
153 {
154 //this.content = System.Text.Encoding.UTF8.GetBytes(contentStr);
155 this.content = contentStr;
156 }
157 public byte[] getContent()
158 {
159 return System.Text.Encoding.UTF8.GetBytes(content);
160 }
161 public override string ToString()
162 {
163 return key + "\n" + content + "\n" + qos;
164 }
165 }
166
167
168 [StructLayout(LayoutKind.Sequential)]
169 public class StringArr
170 {
171 public string str;
172 }
173
174 public void logger(String str)
175 {
176 if (verbose) Console.WriteLine(str);
177 }
178
179 // How to pass byte[] content, how to tell the Marshal the contentLen to allocate for byte[]?
180 # if !XMLBLASTER_MONO
181 [UnmanagedFunctionPointer(CallingConvention.Cdecl)]
182 # endif
183 delegate string UpdateUnmanagedFp(string cbSessionId, string key, string content, int contentLen, string qos, ref XmlBlasterUnmanagedException exception);
184
185 string updateUnmanaged(string cbSessionId, string key, string content, int contentLen, string qos, ref XmlBlasterUnmanagedException exception)
186 {
187 byte[] bytes = new byte[contentLen];
188 for (int i = 0; i < bytes.Length; i++)
189 bytes[i] = (byte)content[i];
190 MsgUnitUpdate msgUnit = new MsgUnitUpdate(key, bytes, qos);
191 if (null != onUpdate)
192 {
193 try
194 {
195 return onUpdate(cbSessionId, msgUnit);
196 //onUpdate(cbSessionId, msgUnit);
197 //return;
198 }
199 // TODO: Exception seems not to reach the C code
200 catch (XmlBlasterException e)
201 {
202 logger("OnUpdate() exception: " + e.ToString());
203 exception.errorCode = e.ErrorCode;
204 exception.message = e.Message;
205 exception.remote = 1;
206 return null;
207 }
208 catch (Exception e)
209 {
210 logger("OnUpdate() exception: " + e.ToString());
211 exception.errorCode = "user.update.internalError";
212 exception.message = e.ToString();
213 exception.remote = 1;
214 return null;
215 }
216 }
217 logger("C# updateUnmanaged invoked START ==================");
218 logger(msgUnit.GetKeyStr());
219 logger(msgUnit.GetContentStr());
220 logger(msgUnit.GetQosStr());
221 string ret = "<qos><state id='OK'/></qos>";
222 logger("C# updateUnmanaged invoked DONE ===================");
223 return ret;
224 }
225
226 // Convert a string to a byte array.
227 public static byte[] StrToByteArray(string str)
228 {
229 //return (new UnicodeEncoding()).GetBytes(stringToConvert);
230 //byte[] data = System.Text.Encoding.UTF8.GetBytes(str); // TODO
231 System.Text.ASCIIEncoding encoding = new System.Text.ASCIIEncoding();
232 return encoding.GetBytes(str);
233 }
234
235 // Convert a byte array to a string.
236 public static string ByteArrayToString(byte[] dBytes)
237 {
238 string str;
239 System.Text.ASCIIEncoding enc = new System.Text.ASCIIEncoding();
240 str = enc.GetString(dBytes, 0, dBytes.Length);
241 return str;
242 }
243
244 /*
245 [StructLayout(LayoutKind.Explicit)]
246 public struct Rect {
247 [FieldOffset(0)] public int left;
248 [FieldOffset(4)] public int top;
249 [FieldOffset(8)] public int right;
250 [FieldOffset(12)] public int bottom;
251 }
252 */
253
254 [DllImport(XMLBLASTER_C_LIBRARY)]
255 private extern static IntPtr getXmlBlasterAccessUnparsedUnmanaged(int argc, string[] argv);
256
257 [DllImport(XMLBLASTER_C_LIBRARY)]
258 private extern static void freeXmlBlasterAccessUnparsedUnmanaged(IntPtr xa);
259
260 [DllImport(XMLBLASTER_C_LIBRARY)]
261 private extern static string xmlBlasterUnmanagedConnect(IntPtr xa, string qos, UpdateUnmanagedFp updateUnmanaged, ref XmlBlasterUnmanagedException exception);
262
263 [DllImport(XMLBLASTER_C_LIBRARY)]
264 private extern static bool xmlBlasterUnmanagedInitialize(IntPtr xa, UpdateUnmanagedFp updateUnmanaged, ref XmlBlasterUnmanagedException exception);
265
266 [DllImport(XMLBLASTER_C_LIBRARY)]
267 private extern static bool xmlBlasterUnmanagedDisconnect(IntPtr xa, string qos, ref XmlBlasterUnmanagedException exception);
268
269 [DllImport(XMLBLASTER_C_LIBRARY)]
270 private extern static string xmlBlasterUnmanagedPublish(IntPtr xa, MsgUnit_ msgUnit, ref XmlBlasterUnmanagedException exception);
271
272 //[DllImport(XMLBLASTER_C_LIBRARY )]
273 //private extern static QosArr xmlBlasterUnmanagedPublishArr(IntPtr xa, MsgUnitArr msgUnitArr, ref XmlBlasterUnmanagedException exception);
274
275 [DllImport(XMLBLASTER_C_LIBRARY)]
276 private extern static void xmlBlasterUnmanagedPublishOneway(IntPtr xa, MsgUnit_[] msgUnitArr, int length, ref XmlBlasterUnmanagedException exception);
277
278 [DllImport(XMLBLASTER_C_LIBRARY)]
279 private extern static string xmlBlasterUnmanagedSubscribe(IntPtr xa, string key, string qos, ref XmlBlasterUnmanagedException exception);
280
281 [DllImport(XMLBLASTER_C_LIBRARY)]
282 private extern static void xmlBlasterUnmanagedUnSubscribe(IntPtr xa, string key, string qos, ref XmlBlasterUnmanagedException exception, out int size, out IntPtr ptr);
283
284 [DllImport(XMLBLASTER_C_LIBRARY)]
285 private extern static void xmlBlasterUnmanagedErase(IntPtr xa, string key, string qos, ref XmlBlasterUnmanagedException exception, out int size, out IntPtr ptr);
286
287 [DllImport(XMLBLASTER_C_LIBRARY)]
288 private extern static void xmlBlasterUnmanagedGet(IntPtr xa, string key, string qos, ref XmlBlasterUnmanagedException exception, out int size, out IntPtr ptr);
289
290 [DllImport(XMLBLASTER_C_LIBRARY)]
291 private extern static string xmlBlasterUnmanagedPing(IntPtr xa, string qos, ref XmlBlasterUnmanagedException exception);
292
293 [DllImport(XMLBLASTER_C_LIBRARY)]
294 private extern static bool xmlBlasterUnmanagedIsConnected(IntPtr xa);
295
296 [DllImport(XMLBLASTER_C_LIBRARY)]
297 private extern static string xmlBlasterUnmanagedUsage();
298
299
300 private IntPtr xa;
301 private UpdateUnmanagedFp updateUnmanagedFp;
302
303 public NativeC()
304 {
305 }
306
307 public void Initialize(string[] argv)
308 {
309 if (argv == null) argv = new String[0];
310
311 updateUnmanagedFp = new UpdateUnmanagedFp(this.updateUnmanaged);
312
313 // Convert command line arguments: C client lib expects the executable name as first entry
314 string[] c_argv = new string[argv.Length + 1];
315 c_argv[0] = "NativC"; // my executable name
316 for (int i = 0; i < argv.Length; ++i)
317 {
318 if (argv[i] == "--help")
319 {
320 Console.WriteLine("Usage:\n" + xmlBlasterUnmanagedUsage());
321 throw new XmlBlasterException("user.usage", "Good bye");
322 }
323 c_argv[i + 1] = argv[i];
324 }
325
326 xa = getXmlBlasterAccessUnparsedUnmanaged(c_argv.Length, c_argv);
327
328 logger("NativeC() ...");
329 }
330
331 public void Initialize(Hashtable properties)
332 {
333 throw new XmlBlasterException("internal.notImplemented", "Please call initialize(string[]");
334 }
335
336 /**
337 * @see org.xmlBlaster.client.I_XmlBlasterAccess#registerConnectionListener(I_ConnectionStateListener)
338 */
339 public void RegisterConnectionListener(I_ConnectionStateListener connectionListener) {
340 logger("RegisterConnectionListener() is not implemented, TODO");
341 //this.connectionListener = connectionListener;
342 }
343
344 ~NativeC()
345 {
346 if (xa != new IntPtr(0))
347 freeXmlBlasterAccessUnparsedUnmanaged(xa);
348 logger("~NativeC() ...");
349 }
350
351 void check(string methodName)
352 {
353 logger(methodName + "() ...");
354 if (xa == new IntPtr(0))
355 throw new XmlBlasterException("internal.illegalState", "Can't process " + methodName + ", xmlBlaster pointer is reset, please create a new instance of NativeC.cs class after a disconnect() call");
356 }
357
358 private delegate string OnUpdate(string cbSessionId, MsgUnitUpdate msgUnit);
359 private event OnUpdate onUpdate;
360
361 public ConnectReturnQos Connect(string qos, I_Callback listener)
362 {
363 check("connect");
364 if (listener != null)
365 {
366 onUpdate += new OnUpdate(listener.OnUpdate);
367 }
368 try
369 {
370 XmlBlasterUnmanagedException exception = new XmlBlasterUnmanagedException();
371 bool bb = xmlBlasterUnmanagedInitialize(xa, updateUnmanagedFp, ref exception);
372 if (exception.errorCode.Length > 0)
373 {
374 logger("xmlBlasterUnmanagedInitialize: Got exception from C: exception=" + exception.errorCode + " - " + exception.message);
375 throw new XmlBlasterException(exception.remote != 0, exception.errorCode, exception.message);
376 }
377 else
378 logger("xmlBlasterUnmanagedInitialize: SUCCESS '" + bb + "' xa:"/* + xa.isInitialized*/);
379
380 string ret = xmlBlasterUnmanagedConnect(xa, qos, updateUnmanagedFp, ref exception);
381 if (exception.errorCode.Length > 0)
382 {
383 logger("xmlBlasterUnmanagedConnect: Got exception from C: '" + ret + "' exception=" + exception.errorCode + " - " + exception.message);
384 throw new XmlBlasterException(exception.remote != 0, exception.errorCode, exception.message);
385 }
386 else
387 logger("xmlBlasterUnmanagedConnect: SUCCESS '" + ret + "'");
388 return new ConnectReturnQos(ret);
389 }
390 catch (XmlBlasterException e)
391 {
392 throw e;
393 }
394 catch (Exception e)
395 {
396 throw new XmlBlasterException("internal.unknown", "connect failed", e);
397 }
398 }
399
400 public void LeaveServer()
401 {
402 check("LeaveServer");
403 try
404 {
405 IntPtr tmp = xa;
406 xa = IntPtr.Zero;
407 freeXmlBlasterAccessUnparsedUnmanaged(tmp);
408 logger("freeXmlBlasterAccessUnparsedUnmanaged: SUCCESS freed all resources");
409 }
410 catch (Exception e)
411 {
412 throw new XmlBlasterException("internal.unknown", "LeaveServer failed", e);
413 }
414 }
415
416 /// After calling diconnect() this class is not usable anymore
417 /// you need to create a new instance to connect again
418 public bool Disconnect(string qos)
419 {
420 check("disconnect");
421 try
422 {
423 XmlBlasterUnmanagedException exception = new XmlBlasterUnmanagedException();
424 bool bb = xmlBlasterUnmanagedDisconnect(xa, qos, ref exception);
425 if (exception.errorCode.Length > 0)
426 {
427 logger("xmlBlasterUnmanagedDisconnect: Got exception from C: exception=" + exception.errorCode + " - " + exception.message);
428 throw new XmlBlasterException(exception.remote != 0, exception.errorCode, exception.message);
429 }
430 else
431 logger("xmlBlasterUnmanagedDisconnect: SUCCESS '" + bb + "'");
432
433 freeXmlBlasterAccessUnparsedUnmanaged(xa);
434 xa = new IntPtr(0);
435 logger("xmlBlasterUnmanagedDisconnect: SUCCESS freed all resources");
436
437 return bb;
438 }
439 catch (XmlBlasterException e)
440 {
441 throw e;
442 }
443 catch (Exception e)
444 {
445 throw new XmlBlasterException("internal.unknown", "disconnect failed", e);
446 }
447 }
448
449 public PublishReturnQos Publish(string key, string content, string qos)
450 {
451 return Publish(new MsgUnit(key, content, qos));
452 }
453
454 public PublishReturnQos Publish(MsgUnit msgUnit)
455 {
456 check("publish");
457 try
458 {
459 XmlBlasterUnmanagedException exception = new XmlBlasterUnmanagedException();
460 MsgUnit_ msgUnit_ = new MsgUnit_(msgUnit.GetKeyStr(), msgUnit.GetContentStr(), msgUnit.GetQosStr());
461 string ret = xmlBlasterUnmanagedPublish(xa, msgUnit_, ref exception);
462 if (exception.errorCode.Length > 0)
463 {
464 logger("xmlBlasterUnmanagedPublish: Got exception from C: exception=" + exception.errorCode + " - " + exception.message);
465 throw new XmlBlasterException(exception.remote != 0, exception.errorCode, exception.message);
466 }
467 else
468 logger("xmlBlasterUnmanagedPublish: SUCCESS '" + ret + "'");
469 return new PublishReturnQos(ret);
470 }
471 catch (XmlBlasterException e)
472 {
473 throw e;
474 }
475 catch (Exception e)
476 {
477 throw new XmlBlasterException("internal.unknown", "publish failed", e);
478 }
479 }
480
481 // TODO: Crashs for array size > 2
482 /*
483 Invalid read of size 1
484 at 0x63FFF14: encodeMsgUnitArr (xmlBlasterSocket.c:222)
485 by 0x63FD11E: xmlBlasterPublishOneway (XmlBlasterConnectionUnparsed.c:1004)
486 by 0x63F9125: xmlBlasterPublishOneway (XmlBlasterAccessUnparsed.c:726)
487 by 0x63FF0B8: xmlBlasterUnmanagedPublishOneway (XmlBlasterUnmanaged.c:365)
488 by 0x6524CC8: ???
489 */
490 public void PublishOneway(MsgUnit[] msgUnitArr)
491 {
492 check("publishOneway");
493 try
494 {
495 XmlBlasterUnmanagedException exception = new XmlBlasterUnmanagedException();
496 MsgUnit_[] msgUnitArr_ = new MsgUnit_[msgUnitArr.Length];
497 for (int i = 0; i < msgUnitArr.Length; i++)
498 msgUnitArr_[i] = new MsgUnit_(msgUnitArr[i].GetKeyStr(), msgUnitArr[i].GetContentStr(), msgUnitArr[i].GetQosStr());
499 xmlBlasterUnmanagedPublishOneway(xa, msgUnitArr_, msgUnitArr.Length, ref exception);
500 if (exception.errorCode.Length > 0)
501 {
502 logger("publishOneway: Got exception from C: exception=" + exception.errorCode + " - " + exception.message);
503 throw new XmlBlasterException(exception.remote != 0, exception.errorCode, exception.message);
504 }
505 else
506 logger("publishOneway: SUCCESS");
507 }
508 catch (XmlBlasterException e)
509 {
510 throw e;
511 }
512 catch (Exception e)
513 {
514 throw new XmlBlasterException("internal.unknown", "publishOneway failed", e);
515 }
516 }
517
518 public SubscribeReturnQos Subscribe(string key, string qos)
519 {
520 check("subscribe");
521 try
522 {
523 XmlBlasterUnmanagedException exception = new XmlBlasterUnmanagedException();
524 string ret = xmlBlasterUnmanagedSubscribe(xa, key, qos, ref exception);
525 if (exception.errorCode.Length > 0)
526 {
527 logger("xmlBlasterUnmanagedSubscribe: Got exception from C: exception=" + exception.errorCode + " - " + exception.message);
528 throw new XmlBlasterException(exception.remote != 0, exception.errorCode, exception.message);
529 }
530 else
531 logger("xmlBlasterUnmanagedSubscribe: SUCCESS '" + ret + "'");
532 return new SubscribeReturnQos(ret);
533 }
534 catch (XmlBlasterException e)
535 {
536 throw e;
537 }
538 catch (Exception e)
539 {
540 throw new XmlBlasterException("internal.unknown", "subscribe failed", e);
541 }
542 }
543
544 public UnSubscribeReturnQos[] UnSubscribe(string key, string qos)
545 {
546 check("unSubscribe");
547 try
548 {
549 XmlBlasterUnmanagedException exception = new XmlBlasterUnmanagedException();
550 int size;
551 IntPtr outArray;
552 xmlBlasterUnmanagedUnSubscribe(xa, key, qos, ref exception, out size, out outArray);
553 if (exception.errorCode.Length > 0)
554 {
555 logger("xmlBlasterUnmanagedUnSubscribe: Got exception from C: exception=" + exception.errorCode + " - " + exception.message);
556 throw new XmlBlasterException(exception.remote != 0, exception.errorCode, exception.message);
557 }
558 StringArr[] manArray = new StringArr[size];
559 UnSubscribeReturnQos[] retQosArr = new UnSubscribeReturnQos[size];
560 IntPtr current = outArray;
561 for (int i = 0; i < size; i++)
562 {
563 manArray[i] = new StringArr();
564 Marshal.PtrToStructure(current, manArray[i]);
565 # if PocketPC || Smartphone
566 # else
567 Marshal.DestroyStructure(current, typeof(StringArr));
568 # endif
569 current = (IntPtr)((long)current + Marshal.SizeOf(manArray[i]));
570 //Console.WriteLine( "Element {0}: str={1}", i, manArray[ i ].str );
571 retQosArr[i] = new UnSubscribeReturnQos(manArray[i].str);
572 }
573 # if Smartphone
574 # else
575 Marshal.FreeCoTaskMem(outArray);
576 # endif
577 logger("xmlBlasterUnmanagedUnSubscribe: SUCCESS");
578 return retQosArr;
579 }
580 catch (XmlBlasterException e)
581 {
582 throw e;
583 }
584 catch (Exception e)
585 {
586 //try {
587 // disconnect("<qos/>");
588 //}
589 //catch (Exception e2) {
590 // logger("xmlBlasterUnmanagedUnSubscribe: Ignoring " + e2.ToString() + " root was " +e.ToString());
591 //}
592 throw new XmlBlasterException("internal.unknown", "unSubscribe failed", e);
593 }
594 }
595
596 public EraseReturnQos[] Erase(string key, string qos)
597 {
598 check("erase");
599 try
600 {
601 XmlBlasterUnmanagedException exception = new XmlBlasterUnmanagedException();
602 int size;
603 IntPtr outArray;
604 xmlBlasterUnmanagedErase(xa, key, qos, ref exception, out size, out outArray);
605 if (exception.errorCode.Length > 0)
606 {
607 logger("xmlBlasterUnmanagedErase: Got exception from C: exception=" + exception.errorCode + " - " + exception.message);
608 throw new XmlBlasterException(exception.remote != 0, exception.errorCode, exception.message);
609 }
610 StringArr[] manArray = new StringArr[size];
611 EraseReturnQos[] retQosArr = new EraseReturnQos[size];
612 IntPtr current = outArray;
613 for (int i = 0; i < size; i++)
614 {
615 manArray[i] = new StringArr();
616 Marshal.PtrToStructure(current, manArray[i]);
617 # if PocketPC || Smartphone
618 # else
619 Marshal.DestroyStructure(current, typeof(StringArr));
620 # endif
621 current = (IntPtr)((long)current + Marshal.SizeOf(manArray[i]));
622 //Console.WriteLine( "Element {0}: str={1}", i, manArray[ i ].str );
623 string ret = manArray[i].str;
624 retQosArr[i] = new EraseReturnQos(ret);
625 }
626 # if Smartphone
627 # else
628 Marshal.FreeCoTaskMem(outArray);
629 # endif
630 logger("xmlBlasterUnmanagedErase: SUCCESS");
631 return retQosArr;
632 }
633 catch (XmlBlasterException e)
634 {
635 throw e;
636 }
637 catch (Exception e)
638 {
639 throw new XmlBlasterException("internal.unknown", "erase failed", e);
640 }
641 }
642
643 public MsgUnitGet[] Get(string key, string qos)
644 {
645 check("get");
646 try
647 {
648 XmlBlasterUnmanagedException exception = new XmlBlasterUnmanagedException();
649 int size;
650 IntPtr outArray;
651 xmlBlasterUnmanagedGet(xa, key, qos, ref exception, out size, out outArray);
652 if (exception.errorCode.Length > 0)
653 {
654 logger("xmlBlasterUnmanagedGet: Got exception from C: exception=" + exception.errorCode + " - " + exception.message);
655 throw new XmlBlasterException(exception.remote != 0, exception.errorCode, exception.message);
656 }
657
658 logger("get() size=" + size);
659 MsgUnitGet[] msgUnitArr = new MsgUnitGet[size];
660 IntPtr current = outArray;
661 for (int i = 0; i < size; i++)
662 {
663 MsgUnit_ msgUnit_ = new MsgUnit_();
664 Marshal.PtrToStructure(current, msgUnit_);
665 //Marshal.FreeCoTaskMem( (IntPtr)Marshal.ReadInt32( current ));
666 # if PocketPC || Smartphone
667 # else
668 Marshal.DestroyStructure(current, typeof(MsgUnit_));
669 # endif
670 current = (IntPtr)((long)current +
671 Marshal.SizeOf(msgUnit_));
672 //Console.WriteLine( "Element {0}: key={1} qos={2} buffer={3} contentLength={4}", i,
673 // manArray[ i ].key, manArray[ i ].qos, manArray[ i ].content, manArray[ i ].contentLen );
674 msgUnitArr[i] = new MsgUnitGet(msgUnit_.key, msgUnit_.getContent(), msgUnit_.qos);
675 }
676 # if Smartphone
677 # else
678 Marshal.FreeCoTaskMem(outArray);
679 # endif
680 logger("xmlBlasterUnmanagedGet: SUCCESS");
681 return msgUnitArr;
682 }
683 catch (XmlBlasterException e)
684 {
685 throw e;
686 }
687 catch (Exception e)
688 {
689 throw new XmlBlasterException("internal.unknown", "get failed", e);
690 }
691 }
692
693 public string Ping(string qos)
694 {
695 check("ping");
696 try
697 {
698 XmlBlasterUnmanagedException exception = new XmlBlasterUnmanagedException();
699 string ret = xmlBlasterUnmanagedPing(xa, qos, ref exception);
700 if (exception.errorCode.Length > 0)
701 {
702 logger("xmlBlasterUnmanagedPing: Got exception from C: exception=" + exception.errorCode + " - " + exception.message);
703 throw new XmlBlasterException(exception.remote != 0, exception.errorCode, exception.message);
704 }
705 else
706 logger("xmlBlasterUnmanagedPing: SUCCESS '" + ret + "'");
707 return ret;
708 }
709 catch (XmlBlasterException e)
710 {
711 throw e;
712 }
713 catch (Exception e)
714 {
715 throw new XmlBlasterException("internal.unknown", "ping failed", e);
716 }
717 }
718
719 public bool IsConnected()
720 {
721 logger("isConnected() ...");
722 if (xa == new IntPtr(0)) return false;
723 try
724 {
725 bool bb = xmlBlasterUnmanagedIsConnected(xa);
726 logger("xmlBlasterUnmanagedIsConnected: SUCCESS '" + bb + "'");
727 return bb;
728 }
729 catch (XmlBlasterException e)
730 {
731 throw e;
732 }
733 catch (Exception e)
734 {
735 throw new XmlBlasterException("internal.unknown", "isConnected failed", e);
736 }
737 }
738
739 public void AddLoggingListener(I_LoggingCallback listener)
740 {
741 logger("Sorry, AddLoggingListener() is not implemented");
742 //throw new XmlBlasterException("internal.notImplemented", "Sorry, addLoggingListener is not implemented");
743 }
744
745 public void RemoveLoggingListener(I_LoggingCallback listener)
746 {
747 logger("Sorry, RemoveLoggingListener() is not implemented");
748 }
749
750 public void AddCallbackProgressListener(I_ProgressCallback listener)
751 {
752 logger("Sorry, AddCallbackProgressListener() is not implemented");
753 }
754
755 public void RemoveCallbackProgressListener(I_ProgressCallback listener)
756 {
757 logger("Sorry, RemoveCallbackProgressListener() is not implemented");
758 }
759
760 public string GetUsage()
761 {
762 return xmlBlasterUnmanagedUsage();
763 }
764
765 public string GetVersion()
766 {
767 return "?";
768 }
769
770 public string GetEmeiId()
771 {
772 logger("Sorry, getEmeiId() is not implemented");
773 return null;
774 }
775
776 public string GetDeviceUniqueId()
777 {
778 logger("Sorry, getDeviceUniqueId() is not implemented");
779 return null;
780 }
781 }
782 }
syntax highlighted by Code2HTML, v. 0.9.1