//******************************************************************************************************
// LogMessageSaveHelper.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.Collections.Generic;
using System.Data;
using System.IO;
using GSF.IO;
namespace GSF.Diagnostics
{
///
/// Assists in the saving of a LogMessage. This class is here to help de-duplicate classes so they don't take so much
/// space or memory.
///
internal class LogMessageSaveHelper
{
private static readonly LogMessageSaveHelper Simple = new LogMessageSaveHelper(true);
public static LogMessageSaveHelper Create(bool isSimple = false)
{
if (isSimple)
return Simple;
return new LogMessageSaveHelper(false);
}
private bool m_isSimple;
private Dictionary m_ownerSaveLookup;
private List m_ownerLoadLookup;
private Dictionary m_stackMessagesSaveLookup;
private List m_stackMessagesLoadLookup;
private Dictionary m_stackTraceSaveLookup;
private List m_stackTraceLoadLookup;
private Dictionary m_publisherTypeDefinitionSaveLookup;
private List m_publisherTypeDefinitionLoadLookup;
private Dictionary m_stringSaveLookup;
private List m_stringLoadLookup;
private LogMessageSaveHelper(bool isSimple)
{
if (isSimple)
{
m_isSimple = true;
}
else
{
m_isSimple = false;
m_ownerSaveLookup = new Dictionary();
m_ownerLoadLookup = new List();
m_stackMessagesSaveLookup = new Dictionary();
m_stackMessagesLoadLookup = new List();
m_stackTraceSaveLookup = new Dictionary();
m_stackTraceLoadLookup = new List();
m_publisherTypeDefinitionSaveLookup = new Dictionary();
m_publisherTypeDefinitionLoadLookup = new List();
m_stringSaveLookup = new Dictionary();
m_stringLoadLookup = new List();
}
}
#region [ LogMessageOwner ]
public void SaveEventPublisherDetails(Stream stream, LogEventPublisherDetails publisherDetails)
{
if (publisherDetails == null)
throw new ArgumentNullException(nameof(publisherDetails));
if (m_isSimple)
{
stream.Write((byte)0);
publisherDetails.Save(stream, this);
}
else
{
int lookupId;
if (m_ownerSaveLookup.TryGetValue(publisherDetails, out lookupId))
{
stream.Write((byte)1);
stream.Write(lookupId);
}
else
{
lookupId = m_ownerSaveLookup.Count;
stream.Write((byte)3);
publisherDetails.Save(stream, this);
m_ownerSaveLookup.Add(publisherDetails, lookupId);
}
}
}
public LogEventPublisherDetails LoadEventPublisherDetails(Stream stream)
{
byte version = stream.ReadNextByte();
switch (version)
{
case 0:
return new LogEventPublisherDetails(stream, this);
case 1:
{
if (m_isSimple)
throw new Exception("Cannot load without a LogMessageSaveHelper");
int id = stream.ReadInt32();
return m_ownerLoadLookup[id];
}
case 2:
{
if (m_isSimple)
throw new Exception("Cannot load without a LogMessageSaveHelper");
int id = stream.ReadInt32();
var details = new LogEventPublisherDetails(stream, this);
m_ownerLoadLookup.Add(details);
return details;
}
case 3:
{
if (m_isSimple)
throw new Exception("Cannot load without a LogMessageSaveHelper");
var details = new LogEventPublisherDetails(stream, this);
m_ownerLoadLookup.Add(details);
return details;
}
default:
throw new VersionNotFoundException();
}
}
#endregion
#region [ PublisherTypeDefinition ]
public void SavePublisherTypeDefinition(Stream stream, PublisherTypeDefinition publisherDetails)
{
if (publisherDetails == null)
throw new ArgumentNullException(nameof(publisherDetails));
if (m_isSimple)
{
stream.Write((byte)0);
publisherDetails.Save(stream);
}
else
{
int lookupId;
if (m_publisherTypeDefinitionSaveLookup.TryGetValue(publisherDetails, out lookupId))
{
stream.Write((byte)1);
stream.Write(lookupId);
}
else
{
lookupId = m_publisherTypeDefinitionSaveLookup.Count;
stream.Write((byte)3);
publisherDetails.Save(stream);
m_publisherTypeDefinitionSaveLookup.Add(publisherDetails, lookupId);
}
}
}
public PublisherTypeDefinition LoadPublisherTypeDefinition(Stream stream)
{
byte version = stream.ReadNextByte();
switch (version)
{
case 0:
return new PublisherTypeDefinition(stream);
case 1:
{
if (m_isSimple)
throw new Exception("Cannot load without a LogMessageSaveHelper");
int id = stream.ReadInt32();
return m_publisherTypeDefinitionLoadLookup[id];
}
case 2:
{
if (m_isSimple)
throw new Exception("Cannot load without a LogMessageSaveHelper");
int id = stream.ReadInt32();
var details = new PublisherTypeDefinition(stream);
m_publisherTypeDefinitionLoadLookup.Add(details);
return details;
}
case 3:
{
if (m_isSimple)
throw new Exception("Cannot load without a LogMessageSaveHelper");
var details = new PublisherTypeDefinition(stream);
m_publisherTypeDefinitionLoadLookup.Add(details);
return details;
}
default:
throw new VersionNotFoundException();
}
}
#endregion
#region [ StackMessages ]
public void SaveStackMessages(Stream stream, LogStackMessages message)
{
if (message == null)
throw new ArgumentNullException(nameof(message));
if (ReferenceEquals(message, LogStackMessages.Empty))
{
stream.Write((byte)0);
}
else if (m_isSimple)
{
stream.Write((byte)1);
message.Save(stream);
}
else
{
int lookupId;
if (m_stackMessagesSaveLookup.TryGetValue(message, out lookupId))
{
stream.Write((byte)2);
stream.Write(lookupId);
}
else
{
lookupId = m_stackMessagesSaveLookup.Count;
stream.Write((byte)4);
message.Save(stream);
m_stackMessagesSaveLookup.Add(message, lookupId);
}
}
}
public LogStackMessages LoadStackMessages(Stream stream)
{
byte version = stream.ReadNextByte();
switch (version)
{
case 0:
return LogStackMessages.Empty;
case 1:
return new LogStackMessages(stream);
case 2:
{
if (m_isSimple)
throw new Exception("Cannot load without a LogMessageSaveHelper");
int id = stream.ReadInt32();
return m_stackMessagesLoadLookup[id];
}
case 3:
{
if (m_isSimple)
throw new Exception("Cannot load without a LogMessageSaveHelper");
int id = stream.ReadInt32();
var messages = new LogStackMessages(stream);
m_stackMessagesLoadLookup.Add(messages);
return messages;
}
case 4:
{
if (m_isSimple)
throw new Exception("Cannot load without a LogMessageSaveHelper");
var messages = new LogStackMessages(stream);
m_stackMessagesLoadLookup.Add(messages);
return messages;
}
default:
throw new VersionNotFoundException();
}
}
#endregion
#region [ StackTrace ]
public void SaveStackTrace(Stream stream, LogStackTrace trace)
{
if (trace == null)
throw new ArgumentNullException(nameof(trace));
if (ReferenceEquals(trace, LogStackTrace.Empty))
{
stream.Write((byte)0);
}
else if (m_isSimple)
{
stream.Write((byte)1);
trace.Save(stream);
}
else
{
int lookupId;
if (m_stackTraceSaveLookup.TryGetValue(trace, out lookupId))
{
stream.Write((byte)2);
stream.Write(lookupId);
}
else
{
lookupId = m_stackTraceSaveLookup.Count;
stream.Write((byte)4);
trace.Save(stream);
m_stackTraceSaveLookup.Add(trace, lookupId);
}
}
}
public LogStackTrace LoadStackTrace(Stream stream)
{
byte version = stream.ReadNextByte();
switch (version)
{
case 0:
return LogStackTrace.Empty;
case 1:
return new LogStackTrace(stream);
case 2:
{
if (m_isSimple)
throw new Exception("Cannot load without a LogMessageSaveHelper");
int id = stream.ReadInt32();
return m_stackTraceLoadLookup[id];
}
case 3:
{
if (m_isSimple)
throw new Exception("Cannot load without a LogMessageSaveHelper");
int id = stream.ReadInt32();
var trace = new LogStackTrace(stream);
m_stackTraceLoadLookup.Add(trace);
return trace;
}
case 4:
{
if (m_isSimple)
throw new Exception("Cannot load without a LogMessageSaveHelper");
var trace = new LogStackTrace(stream);
m_stackTraceLoadLookup.Add(trace);
return trace;
}
default:
throw new VersionNotFoundException();
}
}
#endregion
#region [ String ]
public void SaveString(Stream stream, string value)
{
if (value == null)
throw new ArgumentNullException(nameof(value));
if (value.Length == 0)
{
stream.Write((byte)3);
}
else if (m_isSimple)
{
stream.Write((byte)0);
stream.Write(value);
}
else
{
int lookupId;
if (m_stringSaveLookup.TryGetValue(value, out lookupId))
{
stream.Write((byte)1);
stream.Write(lookupId);
}
else
{
lookupId = m_stringSaveLookup.Count;
stream.Write((byte)4);
stream.Write(value);
m_stringSaveLookup.Add(value, lookupId);
}
}
}
public string LoadString(Stream stream)
{
byte version = stream.ReadNextByte();
switch (version)
{
case 0:
return stream.ReadString();
case 1:
{
if (m_isSimple)
throw new Exception("Cannot load without a LogMessageSaveHelper");
int id = stream.ReadInt32();
return m_stringLoadLookup[id];
}
case 2:
{
if (m_isSimple)
throw new Exception("Cannot load without a LogMessageSaveHelper");
int id = stream.ReadInt32();
var value = stream.ReadString();
m_stringLoadLookup.Add(value);
return value;
}
case 3:
{
return string.Empty;
}
case 4:
{
if (m_isSimple)
throw new Exception("Cannot load without a LogMessageSaveHelper");
var value = stream.ReadString();
m_stringLoadLookup.Add(value);
return value;
}
default:
throw new VersionNotFoundException();
}
}
#endregion
}
}