Merge pull request #439 from mono-soc-2012/garyb/iconfix
[mono.git] / mcs / class / System / System.Diagnostics / TraceListener.cs
index d93f7be28fbd5e419b22d327d49184779273c8d2..f2d3c76610574efb4e4ddf214298f256b7155b32 100644 (file)
@@ -3,11 +3,13 @@
 //
 // Authors:
 //   Jonathan Pryor (jonpryor@vt.edu)
+//   Atsushi Enomoto (atsushi@ximian.com)
 //
 // Comments from John R. Hicks <angryjohn69@nc.rr.com> original implementation 
 // can be found at: /mcs/docs/apidocs/xml/en/System.Diagnostics
 //
 // (C) 2002 Jonathan Pryor
+// (C) 2007 Novell, Inc.
 //
 
 //
 //
 
 using System;
+using System.Collections;
+using System.Collections.Specialized;
+using System.Runtime.InteropServices;
 using System.Diagnostics;
 
 namespace System.Diagnostics {
 
        public abstract class TraceListener : MarshalByRefObject, IDisposable {
 
+#if TARGET_JVM
+               readonly LocalDataStoreSlot _indentLevelStore = System.Threading.Thread.AllocateDataSlot ();
+               readonly LocalDataStoreSlot _indentSizeStore = System.Threading.Thread.AllocateDataSlot ();
+               readonly LocalDataStoreSlot _attributesStore = System.Threading.Thread.AllocateDataSlot ();
+               readonly LocalDataStoreSlot _filterStore = System.Threading.Thread.AllocateDataSlot ();
+               readonly LocalDataStoreSlot _optionsStore = System.Threading.Thread.AllocateDataSlot ();
+               
+               private int indentLevel {
+                       get {
+                               object o = System.Threading.Thread.GetData (_indentLevelStore);
+                               if (o == null)
+                                       return 0;
+                               return (int) o;
+                       }
+                       set { System.Threading.Thread.SetData (_indentLevelStore, value); }
+               }
+               
+               private int indentSize {
+                       get {
+                               object o = System.Threading.Thread.GetData (_indentSizeStore);
+                               if (o == null)
+                                       return 4;
+                               return (int) o;
+                       }
+                       set { System.Threading.Thread.SetData (_indentSizeStore, value); }
+               }
+
+               private StringDictionary attributes {
+                       get { return (StringDictionary) System.Threading.Thread.GetData (_attributesStore); }
+                       set { System.Threading.Thread.SetData (_attributesStore, value); }
+               }
+
+#if !MOBILE
+               private TraceFilter filter {
+                       get { return (TraceFilter) System.Threading.Thread.GetData (_filterStore); }
+                       set { System.Threading.Thread.SetData (_filterStore, value); }
+               }
+#endif
+
+               private TraceOptions options {
+                       get {
+                               object o = System.Threading.Thread.GetData (_optionsStore);
+                               if (o == null)
+                                       return TraceOptions.None;
+                               return (TraceOptions) o;
+                       }
+                       set { System.Threading.Thread.SetData (_optionsStore, value); }
+               }
+#else
                [ThreadStatic]
                private int indentLevel = 0;
 
                [ThreadStatic]
                private int indentSize = 4;
 
-               private string name = null;
+               [ThreadStatic]
+               private StringDictionary attributes = new StringDictionary ();
+#if !MOBILE
+               [ThreadStatic]
+               private TraceFilter filter;
+#endif
+               [ThreadStatic]
+               private TraceOptions options;
+#endif
+
+               private string name;
                private bool needIndent = true;
 
                protected TraceListener () : this ("")
@@ -76,6 +140,11 @@ namespace System.Diagnostics {
                        set {needIndent = value;}
                }
 
+               [MonoLimitation ("This property exists but is never considered.")]
+               public virtual bool IsThreadSafe {
+                       get { return false; }
+               }
+
                public virtual void Close ()
                {
                        Dispose ();
@@ -152,6 +221,105 @@ namespace System.Diagnostics {
                {
                        WriteLine (category + ": " + message);
                }
+
+               internal static string FormatArray (ICollection list, string joiner)
+               {
+                       string [] arr = new string [list.Count];
+                       int i = 0;
+                       foreach (object o in list)
+                               arr [i++] = o != null ? o.ToString () : String.Empty;
+                       return String.Join (joiner, arr);
+               }
+
+#if !MOBILE
+               [ComVisible (false)]
+               public virtual void TraceData (TraceEventCache eventCache, string source,
+                       TraceEventType eventType, int id, object data)
+               {
+                       if (Filter != null &&
+                           !Filter.ShouldTrace (eventCache, source, eventType,
+                                                id, null, null, data, null))
+                               return;
+
+                       WriteLine (String.Format ("{0} {1}: {2} : {3}", source, eventType, id, data));
+
+                       if (eventCache == null)
+                               return;
+
+                       if ((TraceOutputOptions & TraceOptions.ProcessId) != 0)
+                               WriteLine ("    ProcessId=" + eventCache.ProcessId);
+                       if ((TraceOutputOptions & TraceOptions.LogicalOperationStack) != 0)
+                               WriteLine ("    LogicalOperationStack=" + FormatArray (eventCache.LogicalOperationStack, ", "));
+                       if ((TraceOutputOptions & TraceOptions.ThreadId) != 0)
+                               WriteLine ("    ThreadId=" + eventCache.ThreadId);
+                       if ((TraceOutputOptions & TraceOptions.DateTime) != 0)
+                               WriteLine ("    DateTime=" + eventCache.DateTime.ToString ("o"));
+                       if ((TraceOutputOptions & TraceOptions.Timestamp) != 0)
+                               WriteLine ("    Timestamp=" + eventCache.Timestamp);
+                       if ((TraceOutputOptions & TraceOptions.Callstack) != 0)
+                               WriteLine ("    Callstack=" + eventCache.Callstack);
+               }
+
+               [ComVisible (false)]
+               public virtual void TraceData (TraceEventCache eventCache, string source,
+                       TraceEventType eventType, int id, params object [] data)
+               {
+                       if (Filter != null &&
+                           !Filter.ShouldTrace (eventCache, source, eventType,
+                                                id, null, null, null, data))
+                               return;
+
+                       TraceData (eventCache, source, eventType, id, FormatArray (data, " "));
+               }
+
+               [ComVisible (false)]
+               public virtual void TraceEvent (TraceEventCache eventCache, string source, TraceEventType eventType, int id)
+               {
+                       TraceEvent (eventCache, source, eventType, id, null);
+               }
+
+               [ComVisible (false)]
+               public virtual void TraceEvent (TraceEventCache eventCache, string source, TraceEventType eventType,
+                       int id, string message)
+               {
+                       TraceData (eventCache, source, eventType, id, message);
+               }
+
+               [ComVisible (false)]
+               public virtual void TraceEvent (TraceEventCache eventCache, string source, TraceEventType eventType, int id, string format, params object [] args)
+               {
+                       TraceEvent (eventCache, source, eventType, id, String.Format (format, args));
+               }
+
+               [ComVisible (false)]
+               public virtual void TraceTransfer (TraceEventCache eventCache, string source, int id, string message, Guid relatedActivityId)
+               {
+                       TraceEvent (eventCache, source, TraceEventType.Transfer, id, String.Format ("{0}, relatedActivityId={1}", message, relatedActivityId));
+               }
+#endif
+
+               protected internal virtual string [] GetSupportedAttributes ()
+               {
+                       return null;
+               }
+
+               public StringDictionary Attributes {
+                       get { return attributes; }
+               }
+
+#if !MOBILE
+               [ComVisibleAttribute (false)]
+               public TraceFilter Filter {
+                       get { return filter; }
+                       set { filter = value; }
+               }
+#endif
+
+               [ComVisibleAttribute (false)]
+               public TraceOptions TraceOutputOptions {
+                       get { return options; }
+                       set { options = value; }
+               }
        }
 }