//****************************************************************************************************** // LogStackFrame.cs - Gbtc // // Copyright © 2016, Grid Protection Alliance. All Rights Reserved. // // Licensed to the Grid Protection Alliance (GPA) under one or more contributor license agreements. See // the NOTICE file distributed with this work for additional information regarding copyright ownership. // The GPA licenses this file to you under the Eclipse Public License -v 1.0 (the "License"); you may // not use this file except in compliance with the License. You may obtain a copy of the License at: // // http://www.opensource.org/licenses/eclipse-1.0.php // // Unless agreed to in writing, the subject software distributed under the License is distributed on an // "AS-IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. Refer to the // License for the specific language governing permissions and limitations. // // Code Modification History: // ---------------------------------------------------------------------------------------------------- // 10/24/2016 - Steven E. Chisholm // Generated original version of source code. // // //****************************************************************************************************** using System; using System.Data; using System.Diagnostics; using System.IO; using System.Security; using System.Text; using GSF.IO; using GSF.Reflection; namespace GSF.Diagnostics { /// /// Provides information about the specific stack frame. /// public class LogStackFrame : IEquatable { /// /// The name of the method's type. /// /// /// Example: System.Collections.Generic.List`1+Enumerable /// public readonly string ClassName; /// /// The name of the method /// /// /// Example: MethodName<TKey,TValue>(String key, String value) /// public readonly string MethodName; /// /// The file name if debug symbols were compiled with the assembly /// public readonly string FileName; /// /// Gets the offset position in the IL Code. /// public readonly int NativeOffset; /// /// The line number of the data. /// public readonly int LineNumber; /// /// The column number of the execution point. /// public readonly int ColumnNumber; /// /// Creates a from a /// /// public LogStackFrame(StackFrame frame) { if (frame == null) { ClassName = string.Empty; MethodName = string.Empty; FileName = string.Empty; NativeOffset = 0; LineNumber = 0; ColumnNumber = 0; return; } ClassName = frame.GetMethod().GetFriendlyClassName(); MethodName = frame.GetMethod().GetFriendlyMethodName(); using (Logger.SuppressFirstChanceExceptionLogMessages()) { try { FileName = frame.GetFileName() ?? string.Empty; } catch (SecurityException) { FileName = string.Empty; } } NativeOffset = frame.GetNativeOffset(); LineNumber = frame.GetFileLineNumber(); ColumnNumber = frame.GetFileColumnNumber(); } /// /// Creates a from a . /// /// the stream to load from public LogStackFrame(Stream stream) { byte version = stream.ReadNextByte(); switch (version) { case 1: ClassName = stream.ReadString(); MethodName = stream.ReadString(); FileName = stream.ReadString(); NativeOffset = stream.ReadInt32(); LineNumber = stream.ReadInt32(); ColumnNumber = stream.ReadInt32(); break; default: throw new VersionNotFoundException("Unknown StackTraceDetails Version"); } } /// /// Saves this class to a /// /// the stream to write to. public void Save(Stream stream) { stream.Write((byte)1); stream.Write(ClassName); stream.Write(MethodName); stream.Write(FileName); stream.Write(NativeOffset); stream.Write(LineNumber); stream.Write(ColumnNumber); } /// /// Makes a string /// /// public override string ToString() { StringBuilder sb = new StringBuilder(); ToString(sb); return sb.ToString(); } /// /// Appends the details of this stack frame to the provided . /// /// where to append this class information /// /// Does not append a to the end of the line. /// public void ToString(StringBuilder stringBuilder) { if (ClassName.Length > 0) { stringBuilder.Append(ClassName); stringBuilder.Append('.'); } stringBuilder.Append(MethodName); if (FileName.Length == 0) { stringBuilder.Append(" IL offset: "); stringBuilder.Append(NativeOffset); } else { stringBuilder.Append(" in "); stringBuilder.Append(FileName); stringBuilder.Append(": line "); stringBuilder.Append(LineNumber); stringBuilder.Append(':'); stringBuilder.Append(ColumnNumber); } } /// /// Gets the hash code data from this frame /// internal int ComputeHashCode() { return ClassName.GetHashCode() ^ MethodName.GetHashCode() ^ FileName.GetHashCode() ^ NativeOffset.GetHashCode() ^ LineNumber.GetHashCode() ^ ColumnNumber.GetHashCode(); } /// /// Gets of the two classes are equal /// /// the class to compare. /// public bool Equals(LogStackFrame other) { return (object)other != null && NativeOffset == other.NativeOffset && LineNumber == other.LineNumber && ColumnNumber == other.ColumnNumber && ClassName == other.ClassName && MethodName == other.MethodName && FileName == other.FileName; } } }