TextWriterTraceListener.cs source code in C# .NET

Source code for the .NET framework in C#

                        

Code:

/ 4.0 / 4.0 / untmp / DEVDIV_TFS / Dev10 / Releases / RTMRel / ndp / fx / src / CompMod / System / Diagnostics / TextWriterTraceListener.cs / 1305376 / TextWriterTraceListener.cs

                            //------------------------------------------------------------------------------ 
// 
//     Copyright (c) Microsoft Corporation.  All rights reserved.
// 
//----------------------------------------------------------------------------- 

/* 
 */ 
namespace System.Diagnostics {
    using System; 
    using System.IO;
    using System.Text;
    using System.Security.Permissions;
    using System.Runtime.InteropServices; 
    using System.IO.Ports;
    using Microsoft.Win32; 
    using System.Runtime.Versioning; 

    ///  
    ///    Directs tracing or debugging output to
    ///       a  or to a ,
    ///       such as  or .
    ///  
    [HostProtection(Synchronization=true)]
    public class TextWriterTraceListener : TraceListener { 
        internal TextWriter writer; 
        String fileName = null;
 
        /// 
        /// Initializes a new instance of the  class with
        /// 
        /// as the output recipient. 
        /// 
        public TextWriterTraceListener() { 
        } 

        ///  
        /// Initializes a new instance of the  class, using the
        ///    stream as the recipient of the debugging and tracing output.
        /// 
        public TextWriterTraceListener(Stream stream) 
            : this(stream, string.Empty) {
        } 
 
        /// 
        /// Initializes a new instance of the  class with the 
        ///    specified name and using the stream as the recipient of the debugging and tracing output.
        /// 
        public TextWriterTraceListener(Stream stream, string name)
            : base(name) { 
            if (stream == null) throw new ArgumentNullException("stream");
            this.writer = new StreamWriter(stream); 
        } 

        ///  
        /// Initializes a new instance of the  class using the
        ///    specified writer as recipient of the tracing or debugging output.
        /// 
        public TextWriterTraceListener(TextWriter writer) 
            : this(writer, string.Empty) {
        } 
 
        /// 
        /// Initializes a new instance of the  class with the 
        ///    specified name and using the specified writer as recipient of the tracing or
        ///    debugging
        ///    output.
        ///  
        public TextWriterTraceListener(TextWriter writer, string name)
            : base(name) { 
            if (writer == null) throw new ArgumentNullException("writer"); 
            this.writer = writer;
        } 

        /// 
        ///    [To be supplied.]
        ///  
        [ResourceExposure(ResourceScope.Machine)]
        public TextWriterTraceListener(string fileName) { 
            this.fileName = fileName; 
        }
 
        /// 
        ///    [To be supplied.]
        /// 
        [ResourceExposure(ResourceScope.Machine)] 
        public TextWriterTraceListener(string fileName, string name) : base(name) {
            this.fileName = fileName; 
        } 

        ///  
        ///     Indicates the text writer that receives the tracing
        ///       or debugging output.
        /// 
        public TextWriter Writer { 
            get {
                EnsureWriter(); 
                return writer; 
            }
 
            set {
                writer = value;
            }
        } 

        ///  
        /// Closes the  so that it no longer 
        ///    receives tracing or debugging output.
        ///  
        public override void Close() {
            if (writer != null) {
                try {
                    writer.Close(); 
                } catch (ObjectDisposedException) { }
            } 
 
            writer = null;
        } 

        /// 
        /// 
        ///  
        protected override void Dispose(bool disposing) {
            try { 
                if (disposing) { 
                    this.Close();
                } 
                else {
                    // clean up resources
                    if (writer != null)
                        try { 
                            writer.Close();
                        } catch (ObjectDisposedException) { } 
                    writer = null; 
                }
            } 
            finally {
                base.Dispose(disposing);
            }
        } 

        ///  
        /// Flushes the output buffer for the . 
        /// 
        public override void Flush() { 
            if (!EnsureWriter()) return;
            try {
                writer.Flush();
            } catch (ObjectDisposedException) { } 
        }
 
        ///  
        ///    Writes a message
        ///       to this instance's . 
        /// 
        public override void Write(string message) {
            if (!EnsureWriter()) return;
            if (NeedIndent) WriteIndent(); 
            try {
                writer.Write(message); 
            } catch (ObjectDisposedException) { } 
        }
 
        /// 
        ///    Writes a message
        ///       to this instance's  followed by a line terminator. The
        ///       default line terminator is a carriage return followed by a line feed (\r\n). 
        /// 
        public override void WriteLine(string message) { 
            if (!EnsureWriter()) return; 
            if (NeedIndent) WriteIndent();
            try { 
                writer.WriteLine(message);
                NeedIndent = true;
            } catch (ObjectDisposedException) { }
        } 

        private static Encoding GetEncodingWithFallback(Encoding encoding) 
        { 
            // Clone it and set the "?" replacement fallback
            Encoding fallbackEncoding = (Encoding)encoding.Clone(); 
            fallbackEncoding.EncoderFallback = EncoderFallback.ReplacementFallback;
            fallbackEncoding.DecoderFallback = DecoderFallback.ReplacementFallback;

            return fallbackEncoding; 
        }
 
        // This uses a machine resource, scoped by the fileName variable. 
        [ResourceExposure(ResourceScope.None)]
        [ResourceConsumption(ResourceScope.Machine, ResourceScope.Machine)] 
        internal bool EnsureWriter() {
            bool ret = true;

            if (writer == null) { 
                ret = false;
 
                if (fileName == null) 
                    return ret;
 
                // StreamWriter by default uses UTF8Encoding which will throw on invalid encoding errors.
                // This can cause the internal StreamWriter's state to be irrecoverable. It is bad for tracing
                // APIs to throw on encoding errors. Instead, we should provide a "?" replacement fallback
                // encoding to substitute illegal chars. For ex, In case of high surrogate character 
                // D800-DBFF without a following low surrogate character DC00-DFFF
                // NOTE: We also need to use an encoding that does't emit BOM whic is StreamWriter's default 
                Encoding noBOMwithFallback = GetEncodingWithFallback(new UTF8Encoding(false)); 

 
                // To support multiple appdomains/instances tracing to the same file,
                // we will try to open the given file for append but if we encounter
                // IO errors, we will prefix the file name with a unique GUID value
                // and try one more time 
                string fullPath = Path.GetFullPath(fileName);
                string dirPath = Path.GetDirectoryName(fullPath); 
                string fileNameOnly = Path.GetFileName(fullPath); 

                for (int i=0; i<2; i++) { 
                    try {
                        writer = new StreamWriter(fullPath, true, noBOMwithFallback, 4096);
                        ret = true;
                        break; 
                    }
                    catch (IOException ) { 
 
                        // Should we do this only for ERROR_SHARING_VIOLATION?
                        //if (InternalResources.MakeErrorCodeFromHR(Marshal.GetHRForException(ioexc)) == InternalResources.ERROR_SHARING_VIOLATION) { 

                        fileNameOnly = Guid.NewGuid().ToString() + fileNameOnly;
                        fullPath = Path.Combine(dirPath, fileNameOnly);
                        continue; 
                    }
                    catch (UnauthorizedAccessException ) { 
                        //ERROR_ACCESS_DENIED, mostly ACL issues 
                        break;
                    } 
                    catch (Exception ) {
                        break;
                    }
                } 

                if (!ret) { 
                    // Disable tracing to this listener. Every Write will be nop. 
                    // We need to think of a central way to deal with the listener
                    // init errors in the future. The default should be that we eat 
                    // up any errors from listener and optionally notify the user
                    fileName = null;
                }
            } 
            return ret;
        } 
 
    }
} 

// File provided for Reference Use Only by Microsoft Corporation (c) 2007.


                        

Link Menu

Network programming in C#, Network Programming in VB.NET, Network Programming in .NET
This book is available now!
Buy at Amazon US or
Buy at Amazon UK