00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011 using System;
00012 using System.Text;
00013 using System.Collections;
00014 using System.Reflection;
00015 using System.Runtime.InteropServices;
00016 using System.Threading;
00017
00018 [assembly:AssemblyVersionAttribute("2.0.0.0")]
00019
00021 namespace Freiburg {
00022
00024 public unsafe class Timer
00025 {
00026 private const string MSGQUE_DLL = "libFreiburg20";
00027
00028 private IntPtr timer;
00029
00030 public IntPtr value
00031 {
00032 get { return timer; }
00033 }
00034
00035 [DllImport(MSGQUE_DLL)]
00036 private static extern IntPtr MqStatCreate (IntPtr msgque);
00037
00038 public Timer (IntPtr msgque)
00039 {
00040 timer = MqStatCreate (msgque);
00041 }
00042
00043 [DllImport(MSGQUE_DLL)]
00044 private static extern void MqStatDelete (IntPtr *timerP);
00045
00046 ~Timer ()
00047 {
00048 fixed (IntPtr *timerP = &timer) {
00049 MqStatDelete (timerP);
00050 }
00051 }
00052
00053 [DllImport(MSGQUE_DLL)]
00054 private static extern void MqStatInit (IntPtr timer);
00055
00056 public void Init ()
00057 {
00058 MqStatInit (timer);
00059 }
00060 }
00061
00063 public unsafe class Stat
00064 {
00065 private const string MSGQUE_DLL = "libFreiburg20";
00066
00069 [StructLayout(LayoutKind.Sequential)]
00070 private struct StatCtxS {
00071 public IntPtr msgque;
00072 public IntPtr name;
00073 public short level;
00074 public int count;
00075 public double val;
00076 };
00077
00078 private StatCtxS *stat;
00079
00080 [DllImport(MSGQUE_DLL)]
00081 private static extern StatCtxS* MqStatCtxCreate(IntPtr msgque, string name, int count, short level);
00082
00083 public Stat (IntPtr msgque, string name, int count, short level)
00084 {
00085 stat = MqStatCtxCreate (msgque, name, count, level);
00086 }
00087
00088 [DllImport(MSGQUE_DLL)]
00089 private static extern void MqStatCtxDelete (StatCtxS **stat);
00090
00091 ~Stat() {
00092 fixed (StatCtxS **statP = &stat) {
00093 MqStatCtxDelete (statP);
00094 }
00095 }
00096
00097 public double value
00098 {
00099 get { return stat->val; }
00100 set { stat->val = value; }
00101 }
00102
00103 [DllImport(MSGQUE_DLL, CharSet=CharSet.Ansi)]
00104 private static extern IntPtr MqBufferGetC (IntPtr buf);
00105
00106 public string name
00107 {
00108 get { return Marshal.PtrToStringAnsi (MqBufferGetC(stat->name)); }
00109 }
00110
00111 [DllImport(MSGQUE_DLL)]
00112 private static extern void MqStatCtxCalc (StatCtxS *stat, IntPtr timer);
00113
00114 public void Calc (Timer timer)
00115 {
00116 MqStatCtxCalc (stat, timer.value);
00117 }
00118
00119 [DllImport(MSGQUE_DLL)]
00120 private static extern void MqStatCtxPrint (StatCtxS *stat);
00121
00122 public void Print ()
00123 {
00124 MqStatCtxPrint (stat);
00125 }
00126 }
00127
00129 public unsafe abstract class Msgque
00130 {
00131 private const string MSGQUE_DLL = "libFreiburg20";
00132
00133 private static Mutex createMutex = new Mutex();
00134 private static Mutex deleteMutex = new Mutex();
00135
00136
00137 protected delegate int HdlF(CsS *msgque, IntPtr data);
00138
00141 public enum ErrorE { OK, ERROR, WARNING, CONTINUE };
00142
00145 private enum CsE { CLIENT, SERVER };
00146
00150 [StructLayout(LayoutKind.Sequential)]
00151 protected struct CsS {
00152 public IntPtr myCtx;
00153 public IntPtr temp;
00154 public BufferS* name;
00155
00156 public short debug;
00157 public short stat;
00158 public short silent;
00159 public short binary;
00160
00161 public IntPtr send;
00162 public IntPtr read;
00163 public IntPtr io;
00164 public IntPtr error;
00165 public IntPtr statistic;
00166 }
00167 protected CsS *msgque;
00168
00169
00170
00171
00172
00173
00174
00175 [DllImport(MSGQUE_DLL)]
00176 private static extern IntPtr MqBufferLCreate(IntPtr error, int num);
00177 [DllImport(MSGQUE_DLL)]
00178 private static extern void MqBufferLAppendHC(IntPtr lbuf, string option, string value);
00179 [DllImport(MSGQUE_DLL)]
00180 private static extern void MqBufferLAppendH2(IntPtr lbuf, string option, short value);
00181 [DllImport(MSGQUE_DLL)]
00182 private static extern void MqBufferLAppendHP(IntPtr lbuf, string option, IntPtr value);
00183 [DllImport(MSGQUE_DLL)]
00184 private static extern void MqBufferLAppend(IntPtr lbuf, IntPtr value);
00185 [DllImport(MSGQUE_DLL)]
00186 private static extern IntPtr MqBufferCreateC(IntPtr error, string value);
00187 [DllImport(MSGQUE_DLL)]
00188 private static extern ErrorE MqCreate(IntPtr context, IntPtr argv, CsS **msgqueP);
00189 [DllImport(MSGQUE_DLL)]
00190 private static extern void MqDelete(CsS **msgqueP);
00191 [DllImport(MSGQUE_DLL)]
00192 private static extern void MqBufferLLog(IntPtr lbuf, string name);
00193
00194
00195 public Msgque(Msgque parent, string name, string server, string[] argv) {
00196 ErrorE ret;
00197 IntPtr largv = MqBufferLCreate (IntPtr.Zero, 10);
00198
00199
00200 if (parent != null)
00201 MqBufferLAppendHP (largv, "-parent", (IntPtr) parent.msgque);
00202 MqBufferLAppendHC (largv, "-name", name);
00203 MqBufferLAppendHC (largv, "-server", server);
00204 MqBufferLAppendH2 (largv, "-type", (short) CsE.CLIENT);
00205
00206
00207 foreach (string item in argv ) {
00208 MqBufferLAppend (largv, MqBufferCreateC (IntPtr.Zero, item));
00209 }
00210
00211
00212
00213
00214 createMutex.WaitOne();
00215 fixed (CsS **msgqueP = &msgque) {
00216 ret = (MqCreate(IntPtr.Zero, largv, msgqueP));
00217 }
00218 createMutex.ReleaseMutex();
00219 ErrorCheck(ret);
00220 }
00221
00222
00223 ~Msgque() {
00224 deleteMutex.WaitOne();
00225 fixed (CsS **msgqueP = &msgque) {
00226 MqDelete (msgqueP);
00227 }
00228 deleteMutex.ReleaseMutex();
00229 }
00230
00231
00232
00233
00234
00235
00236
00237 [DllImport(MSGQUE_DLL, CharSet=CharSet.Ansi)]
00238 public static extern string MqErrorGetString(IntPtr error);
00239 [DllImport(MSGQUE_DLL)]
00240 protected static extern void MqErrorReset (IntPtr error);
00241 [DllImport(MSGQUE_DLL)]
00242 protected static extern ErrorE MqErrorGetStatus (IntPtr error);
00243
00244 protected void ErrorCheck( ErrorE err ) {
00245 if (err == ErrorE.ERROR)
00246 throw new ApplicationException(MqErrorGetString(msgque->error));
00247 }
00248
00249
00250
00251
00252
00253
00254
00255 [DllImport(MSGQUE_DLL)]
00256 protected static extern ErrorE MqServiceCreate(IntPtr msgque, string token, HdlF handle, IntPtr data);
00257
00258 [DllImport(MSGQUE_DLL)]
00259 private static extern ErrorE MqServiceDelete(IntPtr msgque, string token);
00260
00261
00262
00263
00264
00265
00266
00269 public enum AllocE {
00270 DYNAMIC,
00271 STATIC
00272 }
00273
00276 public enum TypeE{
00277 BIN = 'B',
00278 STR = 'C',
00279 INT2 = '2',
00280 INT4 = '4',
00281 INT8 = '8',
00282 FLT4 = 'F',
00283 FLT8 = 'D',
00284 PTR = 'P',
00285 LST = 'L',
00286 RET = 'R',
00287 STA = 'S'
00288 };
00289
00292 [StructLayout(LayoutKind.Explicit, CharSet=CharSet.Ansi)]
00293 public struct BufferU {
00294 [ FieldOffset( 0 )]
00295 public IntPtr B;
00296 [ FieldOffset( 0 )]
00297 public IntPtr C;
00298 [ FieldOffset( 0 )]
00299 public short *I2;
00300 [ FieldOffset( 0 )]
00301 public int *I4;
00302 [ FieldOffset( 0 )]
00303 public long *I8;
00304 [ FieldOffset( 0 )]
00305 public float *F;
00306 [ FieldOffset( 0 )]
00307 public double *D;
00308 [ FieldOffset( 0 )]
00309 public IntPtr *P;
00310 [ FieldOffset( 0 )]
00311 public IntPtr L;
00312 [ FieldOffset( 0 )]
00313 public IntPtr R;
00314 };
00315
00318 [StructLayout(LayoutKind.Sequential, CharSet=CharSet.Ansi)]
00319 public struct BufferS {
00320 public IntPtr error;
00321 public IntPtr data;
00322 public int size;
00323 public int cursize;
00324 public int numItems;
00325 public BufferU cur;
00326 public AllocE alloc;
00327 public TypeE type;
00328 };
00329
00330
00331
00332
00333
00334
00335
00336 [DllImport(MSGQUE_DLL)]
00337 private static extern void MqSendSTART(IntPtr send);
00338
00339 [DllImport(MSGQUE_DLL)]
00340 private static extern void MqSendC(IntPtr send, string val);
00341 [DllImport(MSGQUE_DLL)]
00342 private static extern void MqSend2(IntPtr send, short val);
00343 [DllImport(MSGQUE_DLL)]
00344 private static extern void MqSend4(IntPtr send, int val);
00345 [DllImport(MSGQUE_DLL)]
00346 private static extern void MqSend8(IntPtr send, long val);
00347 [DllImport(MSGQUE_DLL)]
00348 private static extern void MqSendF(IntPtr send, float val);
00349 [DllImport(MSGQUE_DLL)]
00350 private static extern void MqSendD(IntPtr send, double val);
00351 [DllImport(MSGQUE_DLL)]
00352 private static extern void MqSendB(IntPtr send, byte[] val, int size);
00353 [DllImport(MSGQUE_DLL)]
00354 private static extern void MqSend_LST_START(IntPtr send);
00355 [DllImport(MSGQUE_DLL)]
00356 private static extern void MqSend_LST_END(IntPtr send);
00357
00358 private void sendO (Object oObj)
00359 {
00360 Type type = oObj.GetType();
00361
00362
00363 if (msgque->binary == 0)
00364 MqErrorReset (msgque->error);
00365
00366 if (type == typeof(string)) {
00367 MqSendC(msgque->send, (string) oObj);
00368 } else if (type == typeof(short)) {
00369 MqSend2(msgque->send, (short) oObj);
00370 } else if (type == typeof(int)) {
00371 MqSend4(msgque->send, (int) oObj);
00372 } else if (type == typeof(long)) {
00373 MqSend8(msgque->send, (long) oObj);
00374 } else if (type == typeof(float)) {
00375 MqSendF(msgque->send, (float) oObj);
00376 } else if (type == typeof(double)) {
00377 MqSendD(msgque->send, (double) oObj);
00378 } else if (type.IsArray) {
00379 if (type == typeof(byte[])) {
00380 MqSendB(msgque->send, (byte[]) oObj, ((byte[]) oObj).Length);
00381 } else {
00382 MqSend_LST_START (msgque->send);
00383 sendL((Object[])oObj);
00384 MqSend_LST_END (msgque->send);
00385 }
00386 } else {
00387 MqSendC(msgque->send, oObj.ToString());
00388 }
00389
00390
00391 if (msgque->binary == 0)
00392 ErrorCheck (MqErrorGetStatus(msgque->error));
00393 }
00394
00395 private void sendL (Object[] oList)
00396 {
00397 foreach (Object oEle in oList) {
00398 sendO (oEle);
00399 }
00400 }
00401
00402 [DllImport(MSGQUE_DLL)]
00403 private static extern ErrorE MqReadU(IntPtr read, BufferS **buf);
00404 [DllImport(MSGQUE_DLL)]
00405 private static extern void MqReadCreate_LST_Ref(IntPtr read, BufferS *buf, IntPtr *readRef);
00406 [DllImport(MSGQUE_DLL)]
00407 private static extern void MqReadDelete_LST_Ref(IntPtr *read);
00408 [DllImport(MSGQUE_DLL)]
00409 private static extern void MqReadRET(IntPtr read, BufferS *buf);
00410
00411 protected Object readO ( IntPtr read ) {
00412 BufferS *buf;
00413 ErrorCheck(MqReadU (read, &buf));
00414
00415 switch (buf->type) {
00416 case TypeE.STR:
00417 return Marshal.PtrToStringAnsi(buf->cur.C);
00418 case TypeE.BIN:
00419 byte[] ret = new byte[buf->cursize];
00420 Marshal.Copy(buf->cur.B, ret, 0, buf->cursize);
00421 return ret;
00422 case TypeE.INT2:
00423 return (*buf->cur.I2);
00424 case TypeE.INT4:
00425 return (*buf->cur.I4);
00426 case TypeE.INT8:
00427 return (*buf->cur.I8);
00428 case TypeE.FLT4:
00429 return (*buf->cur.F);
00430 case TypeE.FLT8:
00431 return (*buf->cur.D);
00432 case TypeE.PTR:
00433 return (*buf->cur.P);
00434 case TypeE.LST:
00435 IntPtr readRef;
00436 MqReadCreate_LST_Ref (read, buf, &readRef);
00437 Object[] oRet = ReadL (readRef);
00438 MqReadDelete_LST_Ref (&readRef);
00439 return oRet;
00440 case TypeE.RET:
00441 MqReadRET (read, buf);
00442 return null;
00443 case TypeE.STA:
00444 throw new ApplicationException("unable to read a STA object");
00445 }
00446 throw new ApplicationException("unknown buffer->type");
00447 }
00448
00449 [DllImport(MSGQUE_DLL)]
00450 private static extern int MqReadGetNumItems(IntPtr read);
00451
00452 protected Object[] ReadLR( IntPtr read ) {
00453 int num = MqReadGetNumItems (read)-1;
00454 Object[] oList = new Object[num];
00455 for (int i=0; i<num; i++) {
00456 oList[i] = readO (read);
00457 }
00458 readO (read);
00459 return oList;
00460 }
00461
00462 protected Object[] ReadL( IntPtr read ) {
00463 int num = MqReadGetNumItems (read);
00464 Object[] oList = new Object[num];
00465 for (int i=0; i<num; i++) {
00466 oList[i] = readO (read);
00467 }
00468 return oList;
00469 }
00470
00471
00472
00473
00474
00475 [DllImport(MSGQUE_DLL)]
00476 private static extern ErrorE MqSendEND_AND_WAIT(IntPtr send, string token, int timeout);
00477 [DllImport(MSGQUE_DLL)]
00478 private static extern char MqReadGetReturnCode(IntPtr read);
00479 [DllImport(MSGQUE_DLL)]
00480 private static extern short MqReadGetReturnNum(IntPtr read);
00481 [DllImport(MSGQUE_DLL)]
00482 private static extern void MqReadCreate_RET_Ref(IntPtr read, IntPtr *readRef);
00483 [DllImport(MSGQUE_DLL)]
00484 private static extern void MqReadDelete_RET_Ref(IntPtr *readRef);
00485
00486 protected Object[] CallService (string token, int timeout, params Object[] argv)
00487 {
00488 MqSendSTART (msgque->send);
00489 if (argv != null) sendL (argv);
00490 ErrorCheck(MqSendEND_AND_WAIT(msgque->send, token, timeout));
00491 Object [] oList = ReadLR (msgque->read);
00492 if (MqReadGetReturnCode(msgque->read) != 'O') {
00493 IntPtr read = msgque->read;
00494 IntPtr readRef;
00495 char retCode = MqReadGetReturnCode (read);
00496 int retNum = MqReadGetReturnNum (read);
00497 MqReadCreate_RET_Ref (read, &readRef);
00498 Object[] retL = ReadL (readRef);
00499 MqReadDelete_RET_Ref (&readRef);
00500 StringBuilder msg = new StringBuilder(Marshal.PtrToStringAnsi(msgque->name->data));
00501 msg.AppendFormat (" <Tok|{0}> <Nr|{1}>", token, retNum);
00502 char[] delimiter = new char[1] {'\n'};
00503 foreach (Object oElm in retL) {
00504 foreach (string strE in oElm.ToString().Split(delimiter)) {
00505 msg.Append ("\n -> ");
00506 msg.Append (strE);
00507 }
00508 }
00509 if (retCode == 'W') {
00510 Console.WriteLine ("WARNING: {0}", msg);
00511 }
00512 throw new ApplicationException(msg.ToString());
00513 }
00514
00515 return oList;
00516 }
00517
00518
00519
00520
00521
00522 [DllImport(MSGQUE_DLL)]
00523 private static extern ErrorE MqSendEND(IntPtr send, string token, IntPtr trans);
00524
00525 protected void CallService (string token, params Object[] argv)
00526 {
00527 MqSendSTART (msgque->send);
00528 sendL (argv);
00529 ErrorCheck(MqSendEND(msgque->send, token, IntPtr.Zero));
00530 }
00531
00532
00533
00534
00535
00536 protected enum RetCodeE { OK = 'O', WARNING = 'W', ERROR = 'E' };
00537
00538 [DllImport(MSGQUE_DLL)]
00539 private static extern void MqSend_RET_OK(IntPtr send);
00540 [DllImport(MSGQUE_DLL)]
00541 private static extern void MqSend_RET_START(IntPtr send, RetCodeE retcode, int retnum);
00542 [DllImport(MSGQUE_DLL)]
00543 private static extern ErrorE MqSendEND_RETR(IntPtr send, IntPtr trans);
00544
00545 protected void SendReturnAndWait (RetCodeE retcode, int retnum, string rettext, params Object[] argv)
00546 {
00547 MqSendSTART (msgque->send);
00548 sendL (argv);
00549 if (retcode == RetCodeE.OK) {
00550 MqSend_RET_OK (msgque->send);
00551 } else {
00552 MqSend_RET_START (msgque->send, retcode, retnum);
00553 MqSendC (msgque->send, rettext);
00554 }
00555 ErrorCheck (MqSendEND_RETR (msgque->send, IntPtr.Zero));
00556 }
00557
00558
00559
00560
00561
00562 public Stat StatCreate (string name, int count, short level)
00563 {
00564 return new Stat((IntPtr) msgque, name, count, level);
00565 }
00566
00567 public Timer TimerCreate ()
00568 {
00569 return new Timer((IntPtr) msgque);
00570 }
00571
00572 }
00573
00574
00575 }