Main Page | Namespace List | Class Hierarchy | Class List | Directories | File List | Class Members | Related Pages

csLibFbg.cs

Go to the documentation of this file.
00001 /*
00002  *  csharpFreiburg - src/CSharpFreiburg/src/CsLibFbg/csLibFbg.cs
00003  *  
00004  *  (C) 2004 - Freiburg - Project - Group
00005  *  ------------------------------------------------------
00006  *  EMail: freiburg AT compiler-factory DOT de
00007  *  ------------------------------------------------------
00008  *  all rights reserved
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     // this is the delegate declaration
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 /*                            context management                             */
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   // create a context
00195     public Msgque(Msgque parent, string name, string server, string[] argv) {
00196         ErrorE ret;
00197         IntPtr largv = MqBufferLCreate (IntPtr.Zero, 10);
00198 
00199       // 1. system data
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       // 2. all other arguments
00207         foreach (string item in argv ) {
00208           MqBufferLAppend (largv, MqBufferCreateC (IntPtr.Zero, item));
00209         }
00210 
00211         //MqBufferLLog (largv, "largv");
00212 
00213       // 3. create msgque
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   // delete a context
00223     ~Msgque() {
00224         deleteMutex.WaitOne();
00225         fixed (CsS **msgqueP = &msgque) {
00226             MqDelete (msgqueP);
00227         }
00228         deleteMutex.ReleaseMutex();
00229     }
00230 
00231 /*****************************************************************************/
00232 /*                                                                           */
00233 /*                            ErrorS related                                 */
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 /*                            service handle                                 */
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 /*                                   read                                    */
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 /*                                   send                                    */
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       // error test only in STRING mode
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       // error test only in STRING mode
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);     // read return-item
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     /*                    call service and wait for answer                       */
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     /*                 call service and don't wait for answer                    */
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     /*                      answer for a service call                            */
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     /*                              statistics                                   */
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 // END - NameSpace Freiburg
00575 }

Generated on Tue Nov 23 16:15:58 2004 for csharpFreiburg by  doxygen 1.3.8-20040928