1 // This file is part of Smuxi and is licensed under the terms of MIT/X11
2 //
3 // Copyright (c) 2005-2006 Mirco Bauer <meebey@meebey.net>
4 //
5 // Permission is hereby granted, free of charge, to any person obtaining a copy
6 // of this software and associated documentation files (the "Software"), to deal
7 // in the Software without restriction, including without limitation the rights
8 // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9 // copies of the Software, and to permit persons to whom the Software is
10 // furnished to do so, subject to the following conditions:
11 //
12 // The above copyright notice and this permission notice shall be included in
13 // all copies or substantial portions of the Software.
14 //
15 // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16 // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17 // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18 // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19 // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20 // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
21 // THE SOFTWARE.
22 using System;
23 using System.Text;
24 using System.Runtime.Remoting;
25 using System.Reflection;
26 using System.Collections;
27 using System.Diagnostics;
28 using SysTrace = System.Diagnostics.Trace;
29 
30 namespace Smuxi.Common
31 {
32     public sealed class Trace
33     {
34 #if LOG4NET
35         private static readonly log4net.ILog _Logger = log4net.LogManager.GetLogger("TRACE");
36 #else
37         static Trace()
38         {
39             TextWriterTraceListener myWriter = new TextWriterTraceListener(Console.Out);
40             SysTrace.Listeners.Add(myWriter);
41         }
42 #endif
43 
GetMethodBase()44         public static MethodBase GetMethodBase()
45         {
46             return new StackTrace(new StackFrame(1)).GetFrame(0).GetMethod();
47         }
48 
GetStackTrace()49         public static string GetStackTrace()
50         {
51             string line = null;
52             StackTrace st = new StackTrace();
53             for (int i = st.FrameCount - 1; i >= 1 ; i--) {
54                 StackFrame sf = new StackFrame();
55                 sf = st.GetFrame(i);
56                 MethodBase method = sf.GetMethod();
57                 string methodname = method.DeclaringType + "." + method.Name;
58                 line += methodname + "()" + Environment.NewLine;
59             }
60 
61             return line;
62         }
63 
64         [Conditional("TRACE")]
CallFull(params object[] args)65         public static void CallFull(params object[] args)
66         {
67             MethodBase mb = new StackTrace(new StackFrame(1)).GetFrame(0).GetMethod();
68             string methodname = mb.DeclaringType.Name + "." + mb.Name;
69             string line = GetStackTrace();
70             line += methodname + "(" + _Parameterize(mb, args) + ")";
71 #if LOG4NET
72             _Logger.Debug(line);
73 #else
74             SysTrace.Write(line);
75 #endif
76         }
77 
78         [Conditional("TRACE")]
Call(params object[] args)79         public static void Call(params object[] args)
80         {
81             MethodBase mb = new StackTrace(new StackFrame(1)).GetFrame(0).GetMethod();
82             Call(mb, args);
83         }
84 
85         [Conditional("TRACE")]
Call(MethodBase mb, params object[] args)86         public static void Call(MethodBase mb, params object[] args)
87         {
88             if (mb == null) {
89                 throw new ArgumentNullException("mb");
90             }
91 
92             StringBuilder line = new StringBuilder();
93             line.Append("[");
94             line.Append(System.IO.Path.GetFileName(mb.DeclaringType.Assembly.Location));
95             line.Append("] ");
96             line.Append(mb.DeclaringType.Name);
97             line.Append(".");
98             line.Append(mb.Name);
99             line.Append("(");
100             line.Append(_Parameterize(mb, args));
101             line.Append(")");
102 
103 #if LOG4NET
104             _Logger.Debug(line.ToString());
105 #else
106             SysTrace.WriteLine(line.ToString());
107 #endif
108         }
109 
_Parameterize(MethodBase method, params object[] parameters)110         private static string _Parameterize(MethodBase method, params object[] parameters)
111         {
112             ParameterInfo[] parameter_info = method.GetParameters();
113             if (parameter_info.Length == 0) {
114                 return String.Empty;
115             }
116             StringBuilder res = new StringBuilder();
117             for (int i = 0; i < parameter_info.Length; i++) {
118                 res.Append(parameter_info[i].Name).Append(" = ");
119                 if (parameters == null) {
120                     res.Append(_ParameterizeQuote(null));
121                 } else if (parameters != null && parameters.Length > i) {
122                     res.Append(_ParameterizeQuote(parameters[i]));
123                 } else {
124                     // empty array
125                     res.Append("[]");
126                 }
127                 res.Append(", ");
128             }
129             res.Remove(res.Length - 2, 2);
130             return res.ToString();
131         }
132 
_ParameterizeQuote(object obj)133         private static string _ParameterizeQuote(object obj)
134         {
135             if (obj == null) {
136                 return "(null)";
137             }
138 
139             // OPT: tracing over remote objects is too expensive!
140             if (RemotingServices.IsTransparentProxy(obj)) {
141                 return obj.GetType().ToString();
142             }
143 
144             StringBuilder line = new StringBuilder();
145             if (obj is string) {
146                 line.Append("'").Append(obj).Append("'");
147             } else if (obj is ITraceable) {
148                 line.AppendFormat("<{0}>", ((ITraceable) obj).ToTraceString());
149             } else if (obj is IList) {
150                 line.Append("[");
151                 foreach (object val in (IList) obj) {
152                     if (val is IList || val is IDictionary) {
153                         line.Append(_ParameterizeQuote(val));
154                         line.Append(", ");
155                         continue;
156                     }
157                     line.Append((val == null ? "(null)" : val.ToString()));
158                     line.Append(", ");
159                 }
160                 // remove last ", "
161                 if (line.Length > 1) {
162                     line.Remove(line.Length - 2, 2);
163                 }
164                 line.Append("]");
165             } else if (obj is IDictionary) {
166                 line.Append("{");
167                 foreach (DictionaryEntry de in (IDictionary) obj) {
168                     if (de.Value is IList || de.Value is IDictionary) {
169                         line.Append(de.Key.ToString());
170                         line.Append("=");
171                         line.Append(_ParameterizeQuote(de.Value));
172                         line.Append(", ");
173                         continue;
174                     }
175                     line.Append(de.Key.ToString());
176                     line.Append("=");
177                     line.Append((de.Value == null ? "(null)" : de.Value.ToString()));
178                     line.Append(", ");
179                 }
180                 if (line.Length > 1) {
181                     line.Remove(line.Length - 2, 2);
182                 }
183                 line.Append("}");
184             } else {
185                 line.Append(obj.ToString());
186             }
187 
188             return line.ToString();
189         }
190 
191         /*
192         private static string Dump(Hashtable ht)
193         {
194             string line = null;
195             line += "{";
196             foreach (DictionaryEntry de in (Hashtable)obj) {
197                 line += de.Key.ToString();
198                 line += "=";
199                 line += (de.Value == null ? "(null)" : de.Value.ToString());
200                 line += ", ";
201             }
202             line = line.Substring(0, line.Length - 2);
203             line += "}";
204             return line;
205         }
206         */
207     }
208 }
209