private static IExceptionInfo[] ExceptionToArray(Exception exception) { // This must accept a null Exception and never return a null, use empty array; if (exception == null) { return(new IExceptionInfo[0]); } int count = 1; // Otherwise, we have at least one Exception innerException = exception.InnerException; while (innerException != null) // Count up how big to make the array { count++; innerException = innerException.InnerException; } IExceptionInfo[] exceptions = new IExceptionInfo[count]; //now start serializing them into the array... exceptions[0] = new ExceptionInfoPacket(exception); innerException = exception.InnerException; int index = 0; while (innerException != null) { index++; exceptions[index] = new ExceptionInfoPacket(innerException); ((ExceptionInfoPacket)exceptions[index - 1]).InnerException = exceptions[index]; //we are the inner exception to the previous one. innerException = innerException.InnerException; } return(exceptions); }
/// <summary> /// Optimized deserialization of a LogMessagePacket based on the current packet definition /// </summary> public new void ReadFieldsFast(IFieldReader reader) { base.ReadFieldsFast(reader); m_ID = reader.ReadGuid(); m_Caption = reader.ReadString(); m_Severity = (LogMessageSeverity)reader.ReadInt32(); m_LogSystem = reader.ReadString(); m_CategoryName = reader.ReadString(); m_UserName = reader.ReadString(); m_Description = reader.ReadString(); m_Details = reader.ReadString(); m_ThreadIndex = reader.ReadInt32(); m_ThreadId = reader.ReadInt32(); m_MethodName = reader.ReadString(); m_ClassName = reader.ReadString(); m_FileName = reader.ReadString(); m_LineNumber = reader.ReadInt32(); string[] typeNames = reader.ReadStringArray(); string[] messages = reader.ReadStringArray(); string[] sources = reader.ReadStringArray(); string[] stackTraces = reader.ReadStringArray(); Guid applicationUserId = reader.ReadGuid(); if (m_ThreadIndex == 0) { m_ThreadIndex = m_ThreadId; // Zero isn't legal, so it must not have had it. Fall back to ThreadId. } if (applicationUserId != Guid.Empty) { ApplicationUser applicationUser; m_SessionPacketCache.Users.TryGetValue(applicationUserId, out applicationUser); UserPacket = applicationUser.Packet; } //these are supposed to be parallel arrays - assume they're all the same size. int arrayLength = typeNames.GetLength(0); var exceptions = new IExceptionInfo[arrayLength]; // local holder to build it up IExceptionInfo lastException = null; for (int i = 0; i < arrayLength; i++) { IExceptionInfo exception = new ExceptionInfoPacket() { TypeName = typeNames[i], Message = messages[i], Source = sources[i], StackTrace = stackTraces[i], }; exceptions[i] = exception; if (lastException != null) { ((ExceptionInfoPacket)lastException).InnerException = exception; //we are the inner exception to our parent. } lastException = exception; } m_ExceptionChain = exceptions; // Set the rehydrated ExceptionInfo[] array property }
/// <summary> /// This is the method that is invoked on an IPacketFactory to create an IPacket /// from the data in an IFieldReader given a specified PacketDefinition. /// </summary> /// <param name="definition">Definition of the fields expected in the next packet</param> /// <param name="reader">Data stream to be read</param> /// <returns>An IPacket corresponding to the PacketDefinition and the stream data</returns> public IPacket CreatePacket(PacketDefinition definition, IFieldReader reader) { IPacket packet; //what we create varies by what specific definition they're looking for if (definition.TypeName == m_LogMessagePacketType) { var logPacket = new LogMessagePacket(m_SessionPacketCache); packet = logPacket; if (!ReferenceEquals(definition, m_CachedLogMessagePacketDefinition)) { var currentDefinition = PacketDefinition.CreatePacketDefinition(packet); m_UseFastDeserialization = definition.Equals(currentDefinition); m_CachedLogMessagePacketDefinition = definition; } if (m_UseFastDeserialization) { logPacket.ReadFieldsFast(reader); } else { definition.ReadFields(packet, reader); } } else if (definition.TypeName == m_ExceptionInfoPacketType) { packet = new ExceptionInfoPacket(); definition.ReadFields(packet, reader); } else if (definition.TypeName == m_ApplicationUserPacketType) { packet = new ApplicationUserPacket(); definition.ReadFields(packet, reader); } else { //crap, we don't know what to do here. throw new ArgumentOutOfRangeException(nameof(definition), definition.TypeName, "This packet factory doesn't understand how to create packets for the provided type."); } return(packet); }
void IPacket.ReadFields(PacketDefinition definition, SerializedPacket packet) { switch (definition.Version) { case 1: case 2: //two just adds fields. case 3: //three just adds one field. packet.GetField("ID", out m_ID); packet.GetField("Caption", out m_Caption); // Hmmm, it's tricky to handle the enum with an out parameter; use a temporary int and cast it. int severity; packet.GetField("Severity", out severity); m_Severity = (LogMessageSeverity)severity; packet.GetField("LogSystem", out m_LogSystem); packet.GetField("CategoryName", out m_CategoryName); packet.GetField("UserName", out m_UserName); if (definition.Version >= 2) { packet.GetField("Description", out m_Description); packet.GetField("Details", out m_Details); } // These have now been fully integrated here from the former CallInfoPacket packet.GetField("ThreadId", out m_ThreadId); packet.GetField("MethodName", out m_MethodName); packet.GetField("ClassName", out m_ClassName); packet.GetField("FileName", out m_FileName); packet.GetField("LineNumber", out m_LineNumber); if (definition.Fields.ContainsKey("ThreadIndex")) { packet.GetField("ThreadIndex", out m_ThreadIndex); if (m_ThreadIndex == 0) { m_ThreadIndex = m_ThreadId; // Zero isn't legal, so it must not have had it. Fall back to ThreadId. } } else { m_ThreadIndex = m_ThreadId; // Oops, older code doesn't have it, so use the ThreadId to fake it. } //we now know enough to get our thread info packet (if we don't, we can't re-serialize ourselves) ThreadInfo threadInfo; if (m_SessionPacketCache.Threads.TryGetValue(m_ThreadIndex, out threadInfo)) { ThreadInfoPacket = threadInfo.Packet; } // Now the Exception info... string[] typeNames; string[] messages; string[] sources; string[] stackTraces; packet.GetField("TypeNames", out typeNames); packet.GetField("Messages", out messages); packet.GetField("Sources", out sources); packet.GetField("StackTraces", out stackTraces); //these are supposed to be parallel arrays - assume they're all the same size. int arrayLength = typeNames.GetLength(0); IExceptionInfo[] exceptions = new IExceptionInfo[arrayLength]; // local holder to build it up IExceptionInfo lastException = null; for (int i = 0; i < arrayLength; i++) { IExceptionInfo exception = new ExceptionInfoPacket() { TypeName = typeNames[i], Message = messages[i], Source = sources[i], StackTrace = stackTraces[i] }; exceptions[i] = exception; if (lastException != null) { ((ExceptionInfoPacket)lastException).InnerException = exception; //we are the inner exception to our parent. } lastException = exception; } m_ExceptionChain = exceptions; // Set the rehydrated ExceptionInfo[] array property if (definition.Version >= 3) { Guid applicationUserId; packet.GetField("ApplicationUserId", out applicationUserId); //we now know enough to get our user packet now if it was specified.. ApplicationUser applicationUser; if (m_SessionPacketCache.Users.TryGetValue(applicationUserId, out applicationUser)) { UserPacket = applicationUser.Packet; } } break; } }