123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328 |
- #region --------------- Copyright Dresser Wayne Pignone -------------
- /*
- * $Log: /Wrk/WayneLibraries/Wrk/Log/StringLogObject.cs $
- *
- * 5 08-02-13 9:30 Mattias.larsson
- * FxCop fixes.
- *
- * 4 07-03-19 17:12 roger.månsson
- * Allow null as LogObject.
- */
- #endregion
- using System;
- using System.Text;
- using System.Diagnostics.CodeAnalysis;
- namespace Wayne.Lib.Log
- {
- /// <summary>
- /// The StringLogObject-class serves as a helpclass to convert one or more
- /// objects into one or more strings to log. Also provides format abilities.
- /// </summary>
- public class StringLogObject : ILogObject
- {
- #region Fields
- private object[] logObjects;
- private string format;
- private IFormatProvider provider;
- #endregion
- #region Construction
- /// <summary>
- /// Constructor.
- /// </summary>
- /// <param name="logObjects">A number of objects to log.</param>
- [SuppressMessage("Microsoft.Naming", "CA1720:IdentifiersShouldNotContainTypeNames", MessageId = "objects")]
- public StringLogObject(params object[] logObjects)
- {
- this.logObjects = logObjects;
- }
- /// <summary>
- /// Constructor.
- /// </summary>
- /// <param name="format">A format-string to format the items of an array.</param>
- /// <param name="provider">An IFormatProvider to format the items of an array.</param>
- /// <param name="array">An array of objects to log.</param>
- public StringLogObject(string format, IFormatProvider provider, Array array)
- {
- this.format = format;
- this.provider = provider;
- this.logObjects = new object[] { array };
- }
- /// <summary>
- /// Constructor.
- /// </summary>
- /// <param name="format">A format-string to format the items of an array.</param>
- /// <param name="provider">An IFormatProvider to format the items of an array.</param>
- /// <param name="logObjects">A number of objects to log.</param>
- [SuppressMessage("Microsoft.Naming", "CA1720:IdentifiersShouldNotContainTypeNames", MessageId = "objects")]
- public StringLogObject(string format, IFormatProvider provider, params object[] logObjects)
- {
- this.format = format;
- this.provider = provider;
- this.logObjects = logObjects;
- }
- #endregion
- #region Properties
- bool ILogObject.UsesFormat
- {
- get { return true; }
- }
- string ILogObject.Format
- {
- get { return format; }
- set { format = value; }
- }
- IFormatProvider ILogObject.Provider
- {
- get { return provider; }
- set { provider = value; }
- }
- #endregion
- #region Methods
- /// <summary>
- /// Appends this object's logObjects to a StringBuilder-output.
- /// </summary>
- /// <param name="output">The StringBuilder.</param>
- /// <param name="logWriter">The LogWriter to write the logObject.</param>
- /// <param name="indentLength">The indent to be used if many lines.</param>
- /// <param name="isFirstLine">Is this the first line to log?</param>
- /// <param name="indent">A string holding a generated indent-text (=a number of spaces). Use AppendIndent() to append the indent.</param>
- void ILogObject.AppendToStringBuilder(LogWriter logWriter, StringBuilder output,
- int indentLength, ref bool isFirstLine, ref string indent)
- {
- foreach (object logObject in logObjects)
- AppendObjectToStringBuilder(logObject, output, logWriter, indentLength, ref isFirstLine, ref indent, format, provider);
- }
- #endregion
- #region Static Support Methods
- /// <summary>
- /// Appends an object to a StringBuilder-output.
- /// </summary>
- /// <param name="logObject">The object to log.</param>
- /// <param name="output">The StringBuilder.</param>
- /// <param name="logWriter">The LogWriter to write the logObject.</param>
- /// <param name="indentLength">The indent to be used if many lines.</param>
- /// <param name="isFirstLine">Is this the first line to log?</param>
- /// <param name="indent">A string holding a generated indent-text (=a number of spaces). Use AppendIndent() to append the indent.</param>
- internal static void AppendObjectToStringBuilder(object logObject, StringBuilder output, LogWriter logWriter,
- int indentLength, ref bool isFirstLine, ref string indent)
- {
- AppendObjectToStringBuilder(logObject, output, logWriter, indentLength,
- ref isFirstLine, ref indent, null, null);
- }
- /// <summary>
- /// Appends an object to a StringBuilder-output.
- /// </summary>
- /// <param name="logObject">The object to log.</param>
- /// <param name="output">The StringBuilder.</param>
- /// <param name="logWriter">The LogWriter to write the logObject.</param>
- /// <param name="indentLength">The indent to be used if many lines.</param>
- /// <param name="isFirstLine">Is this the first line to log?</param>
- /// <param name="indent">A string holding a generated indent-text (=a number of spaces). Use AppendIndent() to append the indent.</param>
- /// <param name="format">A format-string to format the objects.</param>
- /// <param name="provider">An IFormatProvider to format the objects.</param>
- private static void AppendObjectToStringBuilder(object logObject, StringBuilder output, LogWriter logWriter,
- int indentLength, ref bool isFirstLine, ref string indent, string format, IFormatProvider provider)
- {
- // Check if the logObject is an ILogObject.
- ILogObject iLogObject = logObject as ILogObject;
- if (iLogObject != null)
- {
- if (iLogObject.UsesFormat && (format != null) && (iLogObject.Format == null))
- {
- // Copy my format to the stringLogObject.
- iLogObject.Format = format;
- iLogObject.Provider = provider;
- }
- iLogObject.AppendToStringBuilder(logWriter, output, indentLength, ref isFirstLine, ref indent);
- }
- else
- {
- string[] logLines = logObject as string[];
- if (logLines != null)
- {
- // The logObject is an array of strings.
- AppendStringsToStringBuilder(logLines, output, logWriter, indentLength, ref isFirstLine, ref indent);
- }
- else
- {
- Array logObjectArray = logObject as Array;
- if (logObjectArray != null)
- {
- // This is an array. Was there a format provided?
- if (format != null)
- {
- // There is a format provided. In this case, write all the items in one string.
- StringBuilder arrayBuilder = new StringBuilder();
- bool firstItem = true;
- foreach (object logObjectItem in logObjectArray)
- {
- // Append a separator character.
- if (firstItem)
- {
- firstItem = false;
- arrayBuilder.Append(" ");
- }
- else
- arrayBuilder.Append(", ");
- // try to format the object with the provided format and IFormatProvider.
- IFormattable formattableItem = logObjectItem as IFormattable;
- if (formattableItem != null)
- arrayBuilder.Append(formattableItem.ToString(format, provider));
- else
- arrayBuilder.Append(logObjectItem.ToString());
- }
- AppendStringToStringBuilder(arrayBuilder.ToString(), output, logWriter, indentLength, ref isFirstLine, ref indent);
- }
- else
- {
- // No format provided. Just write the objects one by one in a normal fashion.
- foreach (object arrayItem in logObjectArray)
- AppendObjectToStringBuilder(arrayItem, output, logWriter, indentLength, ref isFirstLine, ref indent);
- }
- }
- else
- {
- if (format != null)
- {
- IFormattable formattableItem = logObject as IFormattable;
- if (formattableItem != null)
- {
- // Format the logObject with the given format-string and IFormatProvider.
- try
- {
- AppendStringToStringBuilder(formattableItem.ToString(format, provider), output, logWriter, indentLength, ref isFirstLine, ref indent);
- }
- catch (FormatException)
- {
- // Simply convert the logObject to a string.
- AppendStringToStringBuilder(logObject.ToString(), output, logWriter, indentLength, ref isFirstLine, ref indent);
- }
- }
- else
- {
- // Simply convert the logObject to a string.
- AppendStringToStringBuilder(logObject.ToString(), output, logWriter, indentLength, ref isFirstLine, ref indent);
- }
- }
- else
- {
- // Simply convert the logObject to a string.
- if (logObject != null)
- AppendStringToStringBuilder(logObject.ToString(), output, logWriter, indentLength, ref isFirstLine, ref indent);
- else
- AppendStringToStringBuilder("null", output, logWriter, indentLength, ref isFirstLine, ref indent);
- }
- }
- }
- }
- }
- /// <summary>
- /// Appends a string to a StringBuilder-output.
- /// </summary>
- /// <param name="logString">The string to log.</param>
- /// <param name="output">The StringBuilder.</param>
- /// <param name="logWriter">The LogWriter to write the logObject.</param>
- /// <param name="indentLength">The indent to be used if many lines.</param>
- /// <param name="isFirstLine">Is this the first line to log?</param>
- /// <param name="indent">A string holding a generated indent-text (=a number of spaces). Use AppendIndent() to append the indent.</param>
- internal static void AppendStringToStringBuilder(string logString, StringBuilder output,
- LogWriter logWriter, int indentLength, ref bool isFirstLine, ref string indent)
- {
- // Check if the string contains new line-characters.
- if (logString.IndexOf("\r\n", StringComparison.Ordinal) > -1)
- {
- // Create an array of strings cutting after each new line-character.
- string[] logLines = logString.Replace("\r\n", "\uFFFF").Split('\uFFFF');
- AppendStringsToStringBuilder(logLines, output, logWriter, indentLength, ref isFirstLine, ref indent);
- }
- else
- {
- if (isFirstLine)
- isFirstLine = false;
- else
- AppendIndent(output, indentLength, ref indent);
- output.Append(logString); // A normal single line string.
- output.Append("\r\n");
- }
- }
- /// <summary>
- /// Appends a string-array to a StringBuilder-output.
- /// </summary>
- /// <param name="logLines">The array of strings.</param>
- /// <param name="output">The StringBuilder.</param>
- /// <param name="logWriter">The logwriter to be used for logging.</param>
- /// <param name="indentLength">The indent to be used if many lines.</param>
- /// <param name="isFirstLine">Is this the first line to log?</param>
- /// <param name="indent">A string holding a generated indent-text (=a number of spaces). Use AppendIndent() to append the indent.</param>
- internal static void AppendStringsToStringBuilder(string[] logLines, StringBuilder output,
- LogWriter logWriter, int indentLength, ref bool isFirstLine, ref string indent)
- {
- // Remove any empty lines at the end.
- int logLinesLength = logLines.Length;
- for (int i = logLines.Length - 1; i >= 0; i--)
- {
- if (string.IsNullOrEmpty(logLines[i]))
- logLinesLength--;
- else
- break; // The first non-empty line from the end is found. Stop.
- }
- // Log an array of strings.
- if (logLinesLength > 1)
- {
- for (int i = 0; i < logLinesLength; i++)
- AppendStringToStringBuilder(logLines[i], output, logWriter, indentLength, ref isFirstLine, ref indent);
- }
- else if (logLinesLength == 1)
- AppendStringToStringBuilder(logLines[0], output, logWriter, indentLength, ref isFirstLine, ref indent);
- }
- /// <summary>
- /// Appends the indent to a StringBuilder-output.
- /// (After this call the 'indent' is defined.)
- /// </summary>
- /// <param name="indentLength">The indent to be used if many lines.</param>
- /// <param name="indent">A string holding a generated indent-text (=a number of spaces). Use AppendIndent() to append the indent.</param>
- internal static void EnsureIndent(int indentLength, ref string indent)
- {
- if (indent == null)
- indent = Strings.Indent(indentLength, true);
- }
- /// <summary>
- /// Appends the indent to a StringBuilder-output.
- /// (After this call the 'indent' is defined.)
- /// </summary>
- /// <param name="output">The StringBuilder.</param>
- /// <param name="indentLength">The indent to be used if many lines.</param>
- /// <param name="indent">A string holding a generated indent-text (=a number of spaces). Use AppendIndent() to append the indent.</param>
- internal static void AppendIndent(StringBuilder output, int indentLength, ref string indent)
- {
- EnsureIndent(indentLength, ref indent);
- output.Append(indent);
- }
- #endregion
- }
- }
|