[Mono-list] Patch for System.Diagnostics.Trace
Jonathan Pryor
jonpryor@vt.edu
08 Mar 2002 23:38:01 -0500
--=-r0ao501ZDD932v+6dx2I
Content-Type: text/plain
Content-Transfer-Encoding: 7bit
Attached are patches to provide the System.Diagnostics.Trace,
System.Diagnostics.Debug, and related classes.
I'm aware that some of these classes are already present, but the
attached versions have some improvements:
- Debug.cs: Clean up (lots of code can be shared with Trace.cs, which
is why TraceImpl.cs is introduced), "DEBUG" conditional support.
- TraceListener.cs: Proper implementation of Dispose pattern;
implementation of non-abstract methods in terms of abstract methods.
- TraceListenerCollection.cs: check `object' types before adding
- TextWriterTraceListener.cs: properly implement Dispose pattern;
handle NeedIndent and WriteIndent
- Trace.cs: new file; provides Trace functionality, "TRACE" conditional
support
- TraceImpl.cs: new file; actual implementation of Debug & Trace
classes; thread support
- DefaultTraceListener.cs: new file; the default trace listener
Thanks,
- Jon
--=-r0ao501ZDD932v+6dx2I
Content-Disposition: attachment; filename=DefaultTraceListener.cs
Content-Transfer-Encoding: quoted-printable
Content-Type: text/plain; charset=UTF-8
//
// System.Diagnostics.DefaultTraceListener.cs
//
// Authors:
// Jonathan Pryor (jonpryor@vt.edu)
//
// (C) 2002 Jonathan Pryor
//
using System;
using System.IO;
using System.Runtime.InteropServices;
using System.Diagnostics;
namespace System.Diagnostics {
// This needs help, as MSDN specifies that GUI widgets be used.
// The short-term solution is to just send output to OutputDebugString.
[ComVisible(false)]
public class DefaultTraceListener : TraceListener {
public DefaultTraceListener () : base ("Default")
{
}
[MonoTODO]
public bool AssertUiEnabled {
get {return false;}
set {/* ignore */}
}
[MonoTODO]
public string LogFileName {
get {return "";}
set {/* ignore */}
}
#if USE_NATIVE_OUTPUT_DEBUG_STRING
[DllImport ("kernel32.dll")]
private extern static void OutputDebugString (string message);
#else
private static void OutputDebugString (string message)
{
Console.Write ("**ods** " + message);
}
#endif
public override void Write (string message)
{
if (NeedIndent)
WriteIndent ();
OutputDebugString (message);
}
public override void WriteLine (string message)
{
if (NeedIndent)
WriteIndent ();
OutputDebugString (message + Environment.NewLine);
NeedIndent =3D true;
}
}
}
--=-r0ao501ZDD932v+6dx2I
Content-Disposition: attachment; filename=TextWriterTraceListener.cs
Content-Transfer-Encoding: quoted-printable
Content-Type: text/plain; charset=UTF-8
//
// System.Diagnostics.TextWriterTraceListener.cs
//
// Authors:
// Jonathan Pryor (jonpryor@vt.edu)
//
// (C) 2002 Jonathan Pryor
//
using System;
using System.IO;
using System.Diagnostics;
namespace System.Diagnostics {
public class TextWriterTraceListener : TraceListener {
private TextWriter writer;
public TextWriterTraceListener () : base ("TextWriter") {
}
public TextWriterTraceListener (Stream stream)
: this (stream, "")
{
}
public TextWriterTraceListener (string fileName)
: this (fileName, "")
{
}
public TextWriterTraceListener (TextWriter writer)
: this (writer, "")
{
}
public TextWriterTraceListener (Stream stream, string name)=20
: base (name !=3D null ? name : "")
{
if (stream =3D=3D null)=20
throw new ArgumentNullException ("stream");
writer =3D new StreamWriter (stream);
}
public TextWriterTraceListener (string fileName, string name)=20
: base (name !=3D null ? name : "")
{
if (fileName =3D=3D null)
throw new ArgumentNullException ("fileName");
writer =3D new StreamWriter (File.OpenWrite (fileName));
}
public TextWriterTraceListener (TextWriter writer, string name)=20
: base (name !=3D null ? name : "")
{
if (writer =3D=3D null)
throw new ArgumentNullException ("writer");
this.writer =3D writer;
}
public TextWriter Writer {
get {return writer;}
set {writer =3D value;}
}
public override void Close ()
{
if (writer !=3D null) {
writer.Flush ();
writer.Close ();
writer =3D null;
}
}
protected override void Dispose (bool disposing)
{
if (disposing)
Close ();
}
public override void Flush ()
{
writer.Flush ();
}
public override void Write (string message)
{
if (NeedIndent)
WriteIndent ();
writer.Write (message);
}
public override void WriteLine (string message)
{
if (NeedIndent)
WriteIndent ();
writer.WriteLine (message);
NeedIndent =3D true;
}
}
}
--=-r0ao501ZDD932v+6dx2I
Content-Disposition: attachment; filename=Trace.cs
Content-Transfer-Encoding: quoted-printable
Content-Type: text/plain; charset=UTF-8
//
// System.Diagnostics.Trace.cs
//
// Authors:
// Jonathan Pryor (jonpryor@vt.edu)
//
// (C) 2002 Jonathan Pryor
//
using System;
using System.Diagnostics;
namespace System.Diagnostics {
public sealed class Trace {
public static bool AutoFlush {
get {return TraceImpl.AutoFlush;}
set {TraceImpl.AutoFlush =3D value;}
}
public static int IndentLevel {
get {return TraceImpl.IndentLevel;}
set {TraceImpl.IndentLevel =3D value;}
}
public static int IndentSize {
get {return TraceImpl.IndentSize;}
set {TraceImpl.IndentSize =3D value;}
}
public static TraceListenerCollection Listeners {
get {return TraceImpl.Listeners;}
}
[Conditional("TRACE")]
public static void Assert (bool condition)
{
TraceImpl.Assert (condition);
}
[Conditional("TRACE")]
public static void Assert (bool condition, string message)
{
TraceImpl.Assert (condition, message);
}
[Conditional("TRACE")]
public static void Assert (bool condition, string message,=20
string detailMessage)
{
TraceImpl.Assert (condition, message, detailMessage);
}
[Conditional("TRACE")]
public static void Close ()
{
TraceImpl.Close ();
}
[Conditional("TRACE")]
public static void Fail (string message)
{
TraceImpl.Fail (message);
}
[Conditional("TRACE")]
public static void Fail (string message, string detailMessage)
{
TraceImpl.Fail (message, detailMessage);
}
[Conditional("TRACE")]
public static void Flush ()
{
TraceImpl.Flush ();
}
[Conditional("TRACE")]
public static void Indent ()
{
TraceImpl.Indent ();
}
[Conditional("TRACE")]
public static void Unindent ()
{
TraceImpl.Unindent ();
}
[Conditional("TRACE")]
public static void Write (object value)
{
TraceImpl.Write (value);
}
[Conditional("TRACE")]
public static void Write (string message)
{
TraceImpl.Write (message);
}
[Conditional("TRACE")]
public static void Write (object value, string category)
{
TraceImpl.Write (value, category);
}
[Conditional("TRACE")]
public static void Write (string message, string category)
{
TraceImpl.Write (message, category);
}
[Conditional("TRACE")]
public static void WriteIf (bool condition, object value)
{
TraceImpl.WriteIf (condition, value);
}
[Conditional("TRACE")]
public static void WriteIf (bool condition, string message)
{
TraceImpl.WriteIf (condition, message);
}
[Conditional("TRACE")]
public static void WriteIf (bool condition, object value,=20
string category)
{
TraceImpl.WriteIf (condition, value, category);
}
[Conditional("TRACE")]
public static void WriteIf (bool condition, string message,=20
string category)
{
TraceImpl.WriteIf (condition, message, category);
}
[Conditional("TRACE")]
public static void WriteLine (object value)
{
TraceImpl.WriteLine (value);
}
[Conditional("TRACE")]
public static void WriteLine (string message)
{
TraceImpl.WriteLine (message);
}
[Conditional("TRACE")]
public static void WriteLine (object value, string category)
{
TraceImpl.WriteLine (value, category);
}
[Conditional("TRACE")]
public static void WriteLine (string message, string category)
{
TraceImpl.WriteLine (message, category);
}
[Conditional("TRACE")]
public static void WriteLineIf (bool condition, object value)
{
TraceImpl.WriteLineIf (condition, value);
}
[Conditional("TRACE")]
public static void WriteLineIf (bool condition, string message)
{
TraceImpl.WriteLineIf (condition, message);
}
[Conditional("TRACE")]
public static void WriteLineIf (bool condition, object value,=20
string category)
{
TraceImpl.WriteLineIf (condition, value, category);
}
[Conditional("TRACE")]
public static void WriteLineIf (bool condition, string message,=20
string category)
{
TraceImpl.WriteLineIf (condition, message, category);
}
}
}
--=-r0ao501ZDD932v+6dx2I
Content-Disposition: attachment; filename=TraceImpl.cs
Content-Transfer-Encoding: quoted-printable
Content-Type: text/plain; charset=UTF-8
//
// System.Diagnostics.TraceImpl.cs
//
// Authors:
// Jonathan Pryor (jonpryor@vt.edu)
//
// (C) 2002 Jonathan Pryor
//
using System;
using System.Diagnostics;
namespace System.Diagnostics {
internal class TraceImpl {
private static object lock_ =3D new object ();
private static bool autoFlush =3D false;
public static bool AutoFlush {
get {return autoFlush;}
set {autoFlush =3D value;}
}
// From MSDN: "This property is stored on=20
// per-thread/pre-reqeust basis"
//
// What exactly does this mean? Sure, we can mark it
// [ThreadStatic], which make a per-thread value, but what
// does this mean for each of the writers? Do *they* need to
// store this as a thread-static value?
[MonoTODO, ThreadStatic]
private static int indentLevel =3D 0;
public static int IndentLevel {
get {return indentLevel;}
set {indentLevel =3D value;}
}
// From MSDN: "This property is stored on=20
// per-thread/pre-reqeust basis"
//
// What exactly does this mean? Sure, we can mark it
// [ThreadStatic], which make a per-thread value, but what
// does this mean for each of the writers? Do *they* need to
// store this as a thread-static value?
[MonoTODO, ThreadStatic]
private static int indentSize =3D 4;
public static int IndentSize {
get {return indentSize;}
set {indentSize =3D value;}
}
private static TraceListenerCollection listeners =3D=20
new TraceListenerCollection ();
public static TraceListenerCollection Listeners {
get {return listeners;}
}
// According to MSDN, this method should display a dialog box
[MonoTODO]
public static void Assert (bool condition)
{
if (!condition)
Fail (new StackTrace().ToString());
}
// According to MSDN, this method should display a dialog box
[MonoTODO]
public static void Assert (bool condition, string message)
{
if (!condition)
Fail (message);
}
// According to MSDN, this method should display a dialog box
[MonoTODO]
public static void Assert (bool condition, string message,=20
string detailMessage)
{
if (!condition)
Fail (message, detailMessage);
}
public static void Close ()
{
lock (lock_) {
foreach (TraceListener listener in Listeners) {
listener.Close ();
}
}
}
// From testing .NET, this method should display a dialog
[MonoTODO]
public static void Fail (string message)
{
lock (lock_) {
foreach (TraceListener listener in Listeners) {
listener.Fail (message);
}
}
}
// From testing .NET, this method should display a dialog
[MonoTODO]
public static void Fail (string message, string detailMessage)
{
lock (lock_) {
foreach (TraceListener listener in Listeners) {
listener.Fail (message, detailMessage);
}
}
}
public static void Flush ()
{
lock (lock_) {
foreach (TraceListener listener in Listeners){
listener.Flush ();
}
}
}
public static void Indent ()
{
lock (lock_) {
foreach (TraceListener listener in Listeners) {
listener.IndentLevel++;
}
}
}
public static void Unindent ()
{
lock (lock_) {
foreach (TraceListener listener in Listeners) {
listener.IndentLevel--;
}
}
}
public static void Write (object value)
{
lock (lock_) {
foreach (TraceListener listener in Listeners) {
listener.Write (value);
if (AutoFlush)
listener.Flush ();
}
}
}
public static void Write (string message)
{
lock (lock_) {
foreach (TraceListener listener in Listeners) {
listener.Write (message);
if (AutoFlush)
listener.Flush ();
}
}
}
public static void Write (object value, string category)
{
lock (lock_) {
foreach (TraceListener listener in Listeners) {
listener.Write (value, category);
if (AutoFlush)
listener.Flush ();
}
}
}
public static void Write (string message, string category)
{
lock (lock_) {
foreach (TraceListener listener in Listeners) {
listener.Write (message, category);
if (AutoFlush)
listener.Flush ();
}
}
}
public static void WriteIf (bool condition, object value)
{
if (condition)
Write (value);
}
public static void WriteIf (bool condition, string message)
{
if (condition)
Write (message);
}
public static void WriteIf (bool condition, object value,=20
string category)
{
if (condition)
Write (value, category);
}
public static void WriteIf (bool condition, string message,=20
string category)
{
if (condition)
Write (message, category);
}
public static void WriteLine (object value)
{
lock (lock_) {
foreach (TraceListener listener in Listeners) {
listener.WriteLine (value);
if (AutoFlush)
listener.Flush ();
}
}
}
public static void WriteLine (string message)
{
lock (lock_) {
foreach (TraceListener listener in Listeners) {
listener.WriteLine (message);
if (AutoFlush)
listener.Flush ();
}
}
}
public static void WriteLine (object value, string category)
{
lock (lock_) {
foreach (TraceListener listener in Listeners) {
listener.WriteLine (value, category);
if (AutoFlush)
listener.Flush ();
}
}
}
public static void WriteLine (string message, string category)
{
lock (lock_) {
foreach (TraceListener listener in Listeners) {
listener.WriteLine (message, category);
if (AutoFlush)
listener.Flush ();
}
}
}
public static void WriteLineIf (bool condition, object value)
{
if (condition)
WriteLine (value);
}
public static void WriteLineIf (bool condition, string message)
{
if (condition)
WriteLine (message);
}
public static void WriteLineIf (bool condition, object value,=20
string category)
{
if (condition)
WriteLine (value, category);
}
public static void WriteLineIf (bool condition, string message,=20
string category)
{
if (condition)
WriteLine (message, category);
}
}
}
--=-r0ao501ZDD932v+6dx2I
Content-Disposition: attachment; filename=Debug.cs
Content-Transfer-Encoding: quoted-printable
Content-Type: text/plain; charset=UTF-8
//
// System.Diagnostics.Debug.cs
//
// Authors:
// Jonathan Pryor (jonpryor@vt.edu)
//
// (C) 2002 Jonathan Pryor
//
using System;
using System.Diagnostics;
namespace System.Diagnostics {
public sealed class Debug {
public static bool AutoFlush {
get {return TraceImpl.AutoFlush;}
set {TraceImpl.AutoFlush =3D value;}
}
public static int IndentLevel {
get {return TraceImpl.IndentLevel;}
set {TraceImpl.IndentLevel =3D value;}
}
public static int IndentSize {
get {return TraceImpl.IndentSize;}
set {TraceImpl.IndentSize =3D value;}
}
public static TraceListenerCollection Listeners {
get {return TraceImpl.Listeners;}
}
[Conditional("DEBUG")]
public static void Assert (bool condition)
{
TraceImpl.Assert (condition);
}
[Conditional("DEBUG")]
public static void Assert (bool condition, string message)
{
TraceImpl.Assert (condition, message);
}
[Conditional("DEBUG")]
public static void Assert (bool condition, string message,=20
string detailMessage)
{
TraceImpl.Assert (condition, message, detailMessage);
}
[Conditional("DEBUG")]
public static void Close ()
{
TraceImpl.Close ();
}
[Conditional("DEBUG")]
public static void Fail (string message)
{
TraceImpl.Fail (message);
}
[Conditional("DEBUG")]
public static void Fail (string message, string detailMessage)
{
TraceImpl.Fail (message, detailMessage);
}
[Conditional("DEBUG")]
public static void Flush ()
{
TraceImpl.Flush ();
}
[Conditional("DEBUG")]
public static void Indent ()
{
TraceImpl.Indent ();
}
[Conditional("DEBUG")]
public static void Unindent ()
{
TraceImpl.Unindent ();
}
[Conditional("DEBUG")]
public static void Write (object value)
{
TraceImpl.Write (value);
}
[Conditional("DEBUG")]
public static void Write (string message)
{
TraceImpl.Write (message);
}
[Conditional("DEBUG")]
public static void Write (object value, string category)
{
TraceImpl.Write (value, category);
}
[Conditional("DEBUG")]
public static void Write (string message, string category)
{
TraceImpl.Write (message, category);
}
[Conditional("DEBUG")]
public static void WriteIf (bool condition, object value)
{
TraceImpl.WriteIf (condition, value);
}
[Conditional("DEBUG")]
public static void WriteIf (bool condition, string message)
{
TraceImpl.WriteIf (condition, message);
}
[Conditional("DEBUG")]
public static void WriteIf (bool condition, object value,=20
string category)
{
TraceImpl.WriteIf (condition, value, category);
}
[Conditional("DEBUG")]
public static void WriteIf (bool condition, string message,=20
string category)
{
TraceImpl.WriteIf (condition, message, category);
}
[Conditional("DEBUG")]
public static void WriteLine (object value)
{
TraceImpl.WriteLine (value);
}
[Conditional("DEBUG")]
public static void WriteLine (string message)
{
TraceImpl.WriteLine (message);
}
[Conditional("DEBUG")]
public static void WriteLine (object value, string category)
{
TraceImpl.WriteLine (value, category);
}
[Conditional("DEBUG")]
public static void WriteLine (string message, string category)
{
TraceImpl.WriteLine (message, category);
}
[Conditional("DEBUG")]
public static void WriteLineIf (bool condition, object value)
{
TraceImpl.WriteLineIf (condition, value);
}
[Conditional("DEBUG")]
public static void WriteLineIf (bool condition, string message)
{
TraceImpl.WriteLineIf (condition, message);
}
[Conditional("DEBUG")]
public static void WriteLineIf (bool condition, object value,=20
string category)
{
TraceImpl.WriteLineIf (condition, value, category);
}
[Conditional("DEBUG")]
public static void WriteLineIf (bool condition, string message,=20
string category)
{
TraceImpl.WriteLineIf (condition, message, category);
}
}
}
--=-r0ao501ZDD932v+6dx2I
Content-Disposition: attachment; filename=TraceListener.cs
Content-Transfer-Encoding: quoted-printable
Content-Type: text/plain; charset=UTF-8
//
// System.Diagnostics.TraceListener.cs
//
// Authors:
// Jonathan Pryor (jonpryor@vt.edu)
//
// (C) 2002 Jonathan Pryor
//
using System;
using System.Diagnostics;
namespace System.Diagnostics {
public abstract class TraceListener : MarshalByRefObject, IDisposable {
private int indentLevel =3D 0;
private int indentSize =3D 4;
private string name =3D null;
private bool needIndent =3D false;
protected TraceListener () : this ("")
{
}
protected TraceListener (string name)
{
Name =3D name;
}
public int IndentLevel {
get {return indentLevel;}
set {indentLevel =3D value;}
}
public int IndentSize {
get {return indentSize;}
set {indentSize =3D value;}
}
public virtual string Name {
get {return name;}
set {name =3D value;}
}
protected bool NeedIndent {
get {return needIndent;}
set {needIndent =3D value;}
}
public virtual void Close ()
{
}
public void Dispose ()
{
Dispose (true);
GC.SuppressFinalize (this);
}
protected virtual void Dispose (bool disposing)
{
}
public virtual void Fail (string message)
{
Fail (message, "");
}
public virtual void Fail (string message, string detailMessage)
{
WriteLine ("---- DEBUG ASSERTION FAILED ----");
WriteLine ("---- Assert Short Message ----");
WriteLine (message);
WriteLine ("---- Assert Long Message ----");
WriteLine (detailMessage);
WriteLine ("");
}
public virtual void Flush ()
{
}
public virtual void Write (object o)
{
Write (o.ToString());
}
public abstract void Write (string message);
public virtual void Write (object o, string category)
{
Write (o.ToString(), category);
}
public virtual void Write (string message, string category)
{
Write (category + ": " + message);
}
protected virtual void WriteIndent ()
{
String indent =3D new String (' ', IndentLevel*IndentSize);
Write (indent);
NeedIndent =3D false;
}
public virtual void WriteLine (object o)
{
WriteLine (o.ToString());
}
public abstract void WriteLine (string message);
public virtual void WriteLine (object o, string category)
{
WriteLine (o.ToString(), category);
}
public virtual void WriteLine (string message, string category)
{
WriteLine (category + ": " + message);
}
}
}
--=-r0ao501ZDD932v+6dx2I
Content-Disposition: attachment; filename=TraceListenerCollection.cs
Content-Transfer-Encoding: quoted-printable
Content-Type: text/plain; charset=UTF-8
//
// System.Diagnostics.TraceListenerCollection.cs
//
// Authors:
// Jonathan Pryor (jonpryor@vt.edu)
//
// (C) 2002 Jonathan Pryor
//
using System;
using System.Collections;
using System.Diagnostics;
using System.Globalization;
namespace System.Diagnostics {
public class TraceListenerCollection : IList, ICollection, IEnumerable {
private ArrayList listeners =3D new ArrayList ();
public TraceListenerCollection ()
{
Add (new DefaultTraceListener ());
}
public int Count{
get {return listeners.Count;}
}
public TraceListener this [string name] {
get {
foreach (TraceListener listener in listeners) {
if (listener.Name =3D=3D name)
return listener;
}
return null;
}
}
public object this [int index] {
get {return listeners[index];}
set {listeners[index] =3D value;}
}
bool ICollection.IsSynchronized {
get {return listeners.IsSynchronized;}
}
object ICollection.SyncRoot {
get {return listeners.SyncRoot;}
}
bool IList.IsFixedSize {
get {return listeners.IsFixedSize;}
}
bool IList.IsReadOnly {
get {return listeners.IsReadOnly;}
}
public int Add (TraceListener listener)
{
return listeners.Add (listener);
}
public void AddRange (TraceListener[] value)
{
listeners.AddRange (value);
}
public void AddRange (TraceListenerCollection value)
{
listeners.AddRange (value.listeners);
}
public void Clear ()
{
listeners.Clear ();
}
public bool Contains (TraceListener listener)
{
return listeners.Contains (listener);
}
public void CopyTo (TraceListener[] listeners, int index)
{
listeners.CopyTo (listeners, index);
}
public IEnumerator GetEnumerator ()
{
return listeners.GetEnumerator ();
}
void ICollection.CopyTo (Array array, int index)
{
listeners.CopyTo (array, index);
}
int IList.Add (object value)
{
if (value is TraceListener)
return listeners.Add (value);
throw new NotSupportedException (Locale.GetText (
"You can only add TraceListener objects to the collection"));
}
bool IList.Contains (object value)
{
if (value is TraceListener)
return listeners.Contains (value);
return false;
}
int IList.IndexOf (object value)
{
if (value is TraceListener)
return listeners.IndexOf (value);
return -1;
}
void IList.Insert (int index, object value)
{
if (value is TraceListener) {
listeners.Insert (index, value);
return;
}
throw new NotSupportedException (Locale.GetText (
"You can only insert TraceListener objects into the collection"));
}
void IList.Remove (object value)
{
if (value is TraceListener)
listeners.Remove (value);
}
public int IndexOf (TraceListener listener)
{
return listeners.IndexOf (listener);
}
public void Insert (int index, TraceListener listener)
{
listeners.Insert (index, listener);
}
public void Remove (string name)
{
TraceListener found =3D null;
foreach (TraceListener listener in listeners) {
if (listener.Name =3D=3D name) {
found =3D listener;
break;
}
}
if (found !=3D null)
listeners.Remove (found);
else
throw new ArgumentException (Locale.GetText (
"TraceListener " + name + " was not in the collection"));
}
public void Remove (TraceListener listener)
{
listeners.Remove (listener);
}
public void RemoveAt (int index)
{
listeners.RemoveAt (index);
}
}
}
--=-r0ao501ZDD932v+6dx2I--