public unsafe string Format(Entry entry)
{
int len = 25 + entry.Tag.Length + entry.Message.Length;
// This fallback is needed because of possible huge stack allocation.
if (len > 100*1024)
{
return FormatSlow(entry);
}
string categoryString = null;
string exceptionString = null;
if (_categoryFormatter != null)
{
categoryString = _categoryFormatter.GetString(entry.Category);
len += categoryString.Length + 1;
}
if (entry.Exception != null)
{
exceptionString = entry.Exception.ToString();
if (_doAsyncExceptionCleanup)
{
exceptionString = ExceptionUtil.CleanStackTrace(exceptionString);
}
len += exceptionString.Length + 5;
}
char* charBuffer = stackalloc char[len];
char* ptr = charBuffer;
var dt = entry.TimeStamp;
AppendDigitsFast(ref ptr, dt.Hour, 2);
Append(&ptr, ':');
AppendDigitsFast(ref ptr, dt.Minute, 2);
Append(&ptr, ':');
AppendDigitsFast(ref ptr, dt.Second, 2);
Append(&ptr, ':');
AppendDigitsFast(ref ptr, dt.Millisecond, 3);
Append(&ptr, '|');
Append(&ptr, LogLevels.Levels[(int) entry.Level]);
Append(&ptr, '|');
AppendDigitsFast(ref ptr, LogEnvironment.CurrentManagedThreadId, 2, ' ');
Append(&ptr, '|');
Append(&ptr, entry.Tag);
Append(&ptr, '|');
if (_categoryFormatter != null)
{
Append(&ptr, categoryString);
Append(&ptr, '|');
}
Append(&ptr, entry.Message);
if (entry.Exception != null)
{
Append(&ptr, " --> ");
Append(&ptr, exceptionString);
}
switch (_lineEnding)
{
case LineEnding.CR:
Append(&ptr, '\r');
break;
case LineEnding.LF:
Append(&ptr, '\n');
break;
case LineEnding.CRLF:
Append(&ptr, '\r');
Append(&ptr, '\n');
break;
}
return new string(charBuffer, 0, len);
}