GtkSharp/Source/Libs/GLibSharp/Log.cs

291 lines
9 KiB
C#
Raw Normal View History

// Log.cs - Wrapper for message logging functions
//
// Authors:
// Gonzalo Paniagua Javier (gonzalo@ximian.com)
//
//
// Copyright (c) 2002 Gonzalo Paniagua
//
// This program is free software; you can redistribute it and/or
// modify it under the terms of version 2 of the Lesser GNU General
// Public License as published by the Free Software Foundation.
//
// This program is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
// Lesser General Public License for more details.
//
// You should have received a copy of the GNU Lesser General Public
// License along with this program; if not, write to the
// Free Software Foundation, Inc., 59 Temple Place - Suite 330,
// Boston, MA 02111-1307, USA.
//
namespace GLib {
using System;
using System.Runtime.InteropServices;
public delegate void LogFunc (string log_domain, LogLevelFlags log_level, string message);
public delegate void PrintFunc (string message);
[Flags]
public enum LogLevelFlags : int
{
/* log flags */
FlagRecursion = 1 << 0,
FlagFatal = 1 << 1,
/* GLib log levels */
Error = 1 << 2, /* always fatal */
Critical = 1 << 3,
Warning = 1 << 4,
Message = 1 << 5,
Info = 1 << 6,
Debug = 1 << 7,
/* Convenience values */
AllButFatal = 253,
AllButRecursion = 254,
All = 255,
FlagMask = 3,
LevelMask = unchecked ((int) 0xFFFFFFFC)
}
public class Log {
[UnmanagedFunctionPointer (CallingConvention.Cdecl)]
delegate void LogFuncNative (IntPtr log_domain, LogLevelFlags flags, IntPtr message, IntPtr user_data);
static LogFuncNative native_handler;
static void NativeCallback (IntPtr log_domain_native, LogLevelFlags flags, IntPtr message_native, IntPtr user_data)
{
if (user_data == IntPtr.Zero)
return;
string log_domain = Marshaller.Utf8PtrToString (log_domain_native);
string message = Marshaller.Utf8PtrToString (message_native);
GCHandle gch = (GCHandle) user_data;
LogFunc func = gch.Target as LogFunc;
if (func != null)
func (log_domain, flags, message);
}
[UnmanagedFunctionPointer (CallingConvention.Cdecl)]
delegate void PrintFuncNative (IntPtr message);
class PrintHelper {
PrintFuncNative native;
PrintFunc managed;
public PrintHelper (PrintFuncNative native)
{
this.native = native;
}
public PrintHelper (PrintFunc managed)
{
this.managed = managed;
GCHandle.Alloc (this);
}
void Callback (IntPtr nmessage)
{
string message = Marshaller.Utf8PtrToString (nmessage);
managed (message);
}
void Invoke (string message)
{
IntPtr nmessage = Marshaller.StringToPtrGStrdup (message);
native (nmessage);
Marshaller.Free (nmessage);
}
public PrintFuncNative Handler {
get { return new PrintFuncNative (Callback); }
}
public PrintFunc Invoker {
get { return new PrintFunc (Invoke); }
}
}
static System.Collections.Generic.Dictionary<uint, GCHandle> handlers;
static void EnsureHash ()
{
if (handlers == null)
handlers = new System.Collections.Generic.Dictionary<uint, GCHandle> ();
}
[DllImport (Global.GLibNativeDll, CallingConvention = CallingConvention.Cdecl)]
static extern void g_logv (IntPtr log_domain, LogLevelFlags flags, IntPtr message);
public void WriteLog (string logDomain, LogLevelFlags flags, string format, params object [] args)
{
IntPtr ndom = Marshaller.StringToPtrGStrdup (logDomain);
IntPtr nmessage = Marshaller.StringToPtrGStrdup (String.Format (format, args));
g_logv (ndom, flags, nmessage);
Marshaller.Free (ndom);
Marshaller.Free (nmessage);
}
[DllImport (Global.GLibNativeDll, CallingConvention = CallingConvention.Cdecl)]
static extern uint g_log_set_handler (IntPtr log_domain, LogLevelFlags flags, LogFuncNative log_func, IntPtr user_data);
public static uint SetLogHandler (string logDomain, LogLevelFlags flags, LogFunc logFunc)
{
if (native_handler == null)
native_handler = new LogFuncNative (NativeCallback);
IntPtr ndom = Marshaller.StringToPtrGStrdup (logDomain);
GCHandle gch = GCHandle.Alloc (logFunc);
uint result = g_log_set_handler (ndom, flags, native_handler, (IntPtr) gch);
Marshaller.Free (ndom);
EnsureHash ();
handlers [result] = gch;
return result;
}
[DllImport (Global.GLibNativeDll, CallingConvention = CallingConvention.Cdecl)]
static extern uint g_log_remove_handler (IntPtr log_domain, uint handler_id);
public static void RemoveLogHandler (string logDomain, uint handlerID)
{
if (handlers != null && handlers.ContainsKey (handlerID)) {
handlers [handlerID].Free ();
handlers.Remove (handlerID);
}
IntPtr ndom = Marshaller.StringToPtrGStrdup (logDomain);
g_log_remove_handler (ndom, handlerID);
Marshaller.Free (ndom);
}
[DllImport (Global.GLibNativeDll, CallingConvention = CallingConvention.Cdecl)]
static extern PrintFuncNative g_set_print_handler (PrintFuncNative handler);
public static PrintFunc SetPrintHandler (PrintFunc handler)
{
PrintHelper helper = new PrintHelper (handler);
PrintFuncNative prev = g_set_print_handler (helper.Handler);
helper = new PrintHelper (prev);
return helper.Invoker;
}
[DllImport (Global.GLibNativeDll, CallingConvention = CallingConvention.Cdecl)]
static extern PrintFuncNative g_set_printerr_handler (PrintFuncNative handler);
public static PrintFunc SetPrintErrorHandler (PrintFunc handler)
{
PrintHelper helper = new PrintHelper (handler);
PrintFuncNative prev = g_set_printerr_handler (helper.Handler);
helper = new PrintHelper (prev);
return helper.Invoker;
}
[DllImport (Global.GLibNativeDll, CallingConvention = CallingConvention.Cdecl)]
static extern void g_log_default_handler (IntPtr log_domain, LogLevelFlags log_level, IntPtr message, IntPtr unused_data);
public static void DefaultHandler (string logDomain, LogLevelFlags logLevel, string message)
{
IntPtr ndom = Marshaller.StringToPtrGStrdup (logDomain);
IntPtr nmess = Marshaller.StringToPtrGStrdup (message);
g_log_default_handler (ndom, logLevel, nmess, IntPtr.Zero);
Marshaller.Free (ndom);
Marshaller.Free (nmess);
}
[DllImport (Global.GLibNativeDll, CallingConvention = CallingConvention.Cdecl)]
extern static LogLevelFlags g_log_set_always_fatal (LogLevelFlags fatal_mask);
public static LogLevelFlags SetAlwaysFatal (LogLevelFlags fatalMask)
{
return g_log_set_always_fatal (fatalMask);
}
[DllImport (Global.GLibNativeDll, CallingConvention = CallingConvention.Cdecl)]
extern static LogLevelFlags g_log_set_fatal_mask (IntPtr log_domain, LogLevelFlags fatal_mask);
public static LogLevelFlags SetAlwaysFatal (string logDomain, LogLevelFlags fatalMask)
{
IntPtr ndom = Marshaller.StringToPtrGStrdup (logDomain);
LogLevelFlags result = g_log_set_fatal_mask (ndom, fatalMask);
Marshaller.Free (ndom);
return result;
}
class Invoker {
LogFuncNative native;
public Invoker (LogFuncNative native)
{
this.native = native;
}
void Invoke (string log_domain, LogLevelFlags flags, string message)
{
IntPtr ndom = Marshaller.StringToPtrGStrdup (log_domain);
IntPtr nmess = Marshaller.StringToPtrGStrdup (message);
native (ndom, flags, nmess, IntPtr.Zero);
Marshaller.Free (ndom);
Marshaller.Free (nmess);
}
public LogFunc Handler {
get { return new LogFunc (Invoke); }
}
}
[DllImport (Global.GLibNativeDll, CallingConvention = CallingConvention.Cdecl)]
extern static LogFuncNative g_log_set_default_handler (LogFuncNative log_func, IntPtr user_data);
public static LogFunc SetDefaultHandler (LogFunc log_func)
{
if (native_handler == null)
native_handler = new LogFuncNative (NativeCallback);
LogFuncNative prev = g_log_set_default_handler (native_handler, (IntPtr) GCHandle.Alloc (log_func));
if (prev == null)
return null;
Invoker invoker = new Invoker (prev);
return invoker.Handler;
}
/*
* Some common logging methods.
*
* Sample usage:
*
* // Print the messages for the NULL domain
* LogFunc logFunc = new LogFunc (Log.PrintLogFunction);
* Log.SetLogHandler (null, LogLevelFlags.All, logFunc);
*
* // Print messages and stack trace for Gtk critical messages
* logFunc = new LogFunc (Log.PrintTraceLogFunction);
* Log.SetLogHandler ("Gtk", LogLevelFlags.Critical, logFunc);
*
*/
public static void PrintLogFunction (string domain, LogLevelFlags level, string message)
{
Console.WriteLine ("Domain: '{0}' Level: {1}", domain, level);
Console.WriteLine ("Message: {0}", message);
}
public static void PrintTraceLogFunction (string domain, LogLevelFlags level, string message)
{
PrintLogFunction (domain, level, message);
Console.WriteLine ("Trace follows:\n{0}", new System.Diagnostics.StackTrace ());
}
}
}