Skip to content

Commit

Permalink
WebServiceTarget - Improved conversion of boolean parameters (Fixed l…
Browse files Browse the repository at this point in the history
…owercase), and merged the JSON serializer code (Fixed DateTime)
  • Loading branch information
snakefoot committed Mar 19, 2017
1 parent e37aca8 commit 60576a1
Show file tree
Hide file tree
Showing 10 changed files with 424 additions and 263 deletions.
93 changes: 93 additions & 0 deletions src/NLog/Internal/XmlHelper.cs
Expand Up @@ -98,6 +98,99 @@ private static string CreateValidXmlString(string text)
}
#endif

/// <summary>
/// Converts object value to invariant format, and strips any invalid xml-characters
/// </summary>
/// <param name="value">Object value</param>
/// <returns>Object value converted to string</returns>
internal static string XmlConvertToStringSafe(object value)
{
string valueString = XmlConvertToString(value);
return RemoveInvalidXmlChars(valueString);
}

/// <summary>
/// Converts object value to invariant format (understood by JavaScript)
/// </summary>
/// <param name="value">Object value</param>
/// <returns>Object value converted to string</returns>
internal static string XmlConvertToString(object value)
{
TypeCode objTypeCode;
return XmlConvertToString(value, out objTypeCode);
}

/// <summary>
/// Converts object value to invariant format (understood by JavaScript)
/// </summary>
/// <param name="value">Object value</param>
/// <param name="objTypeCode">Object TypeCode</param>
/// <returns>Object value converted to string</returns>
internal static string XmlConvertToString(object value, out TypeCode objTypeCode)
{
if (value == null)
{
objTypeCode = TypeCode.Empty;
return "null";
}

objTypeCode = Convert.GetTypeCode(value);
switch (objTypeCode)
{
case TypeCode.Boolean:
return XmlConvert.ToString((Boolean)value); // boolean as lowercase
case TypeCode.Byte:
return XmlConvert.ToString((Byte)value);
case TypeCode.SByte:
return XmlConvert.ToString((SByte)value);
case TypeCode.Int16:
return XmlConvert.ToString((Int16)value);
case TypeCode.Int32:
return XmlConvert.ToString((Int32)value);
case TypeCode.Int64:
return XmlConvert.ToString((Int64)value);
case TypeCode.UInt16:
return XmlConvert.ToString((UInt16)value);
case TypeCode.UInt32:
return XmlConvert.ToString((UInt32)value);
case TypeCode.UInt64:
return XmlConvert.ToString((UInt64)value);
case TypeCode.Single:
{
float singleValue = (Single)value;
if (float.IsInfinity(singleValue))
return Convert.ToString(singleValue, System.Globalization.CultureInfo.InvariantCulture); // Infinity instead of INF
else
return XmlConvert.ToString(singleValue); // 8 digits scale
}
case TypeCode.Double:
{
double doubleValue = (Double)value;
if (double.IsInfinity(doubleValue))
return Convert.ToString(doubleValue, System.Globalization.CultureInfo.InvariantCulture); // Infinity instead of INF
else
return XmlConvert.ToString(doubleValue); // 16 digits scale
}
case TypeCode.Decimal:
return XmlConvert.ToString((Decimal)value);
case TypeCode.DateTime:
return XmlConvert.ToString((DateTime)value, XmlDateTimeSerializationMode.Utc);
case TypeCode.Char:
return XmlConvert.ToString((Char)value);
case TypeCode.String:
return (string)value;
default:
try
{
return Convert.ToString(value, System.Globalization.CultureInfo.InvariantCulture);
}
catch
{
return null;
}
}
}

/// <summary>
/// Safe version of WriteAttributeString
/// </summary>
Expand Down
44 changes: 28 additions & 16 deletions src/NLog/LayoutRenderers/Log4JXmlEventLayoutRenderer.cs
Expand Up @@ -259,34 +259,47 @@ protected override void Append(StringBuilder builder, LogEventInfo logEvent)
{
xtw.WriteAttributeSafeString("assembly", type.Assembly.FullName);
}

xtw.WriteEndElement();
}
}
}

xtw.WriteStartElement("nlog", "properties", dummyNLogNamespace);
if (logEvent.HasProperties)
{
foreach (var contextProperty in logEvent.Properties)
{
xtw.WriteStartElement("nlog", "data", dummyNLogNamespace);
xtw.WriteAttributeSafeString("name", Convert.ToString(contextProperty.Key, CultureInfo.InvariantCulture));
xtw.WriteAttributeSafeString("value", Convert.ToString(contextProperty.Value, CultureInfo.InvariantCulture));
xtw.WriteEndElement();
}
}
if (this.IncludeNLogData)
{
xtw.WriteStartElement("nlog", "properties", dummyNLogNamespace);
if (logEvent.HasProperties)
{
foreach (var contextProperty in logEvent.Properties)
{
string propertyKey = XmlHelper.XmlConvertToString(contextProperty.Key);
if (string.IsNullOrEmpty(propertyKey))
continue;

string propertyValue = XmlHelper.XmlConvertToString(contextProperty.Value);
if (propertyValue == null)
continue;

xtw.WriteStartElement("nlog", "data", dummyNLogNamespace);
xtw.WriteAttributeSafeString("name", propertyKey);
xtw.WriteAttributeSafeString("value", propertyValue);
xtw.WriteEndElement();
}

}
xtw.WriteEndElement();
}

xtw.WriteStartElement("log4j", "properties", dummyNamespace);
if (this.IncludeMdc)
{
foreach (string key in MappedDiagnosticsContext.GetNames())
{
string propertyValue = XmlHelper.XmlConvertToString(MappedDiagnosticsContext.GetObject(key));
if (propertyValue == null)
continue;

xtw.WriteStartElement("log4j", "data", dummyNamespace);
xtw.WriteAttributeSafeString("name", key);
xtw.WriteAttributeSafeString("value", String.Format(logEvent.FormatProvider, "{0}", MappedDiagnosticsContext.GetObject(key)));
xtw.WriteAttributeSafeString("value", propertyValue);
xtw.WriteEndElement();
}
}
Expand All @@ -309,10 +322,9 @@ protected override void Append(StringBuilder builder, LogEventInfo logEvent)

xtw.WriteStartElement("log4j", "data", dummyNamespace);
xtw.WriteAttributeSafeString("name", "log4jmachinename");

xtw.WriteAttributeSafeString("value", this.machineName);

xtw.WriteEndElement();

xtw.WriteEndElement();

xtw.WriteEndElement();
Expand Down
Expand Up @@ -68,95 +68,7 @@ public JsonEncodeLayoutRendererWrapper()
/// <returns>JSON-encoded string.</returns>
protected override string Transform(string text)
{
return this.JsonEncode ? DoJsonEscape(text) : text;
}

private static string DoJsonEscape(string text)
{
StringBuilder sb = null;
for (int i = 0; i < text.Length; ++i)
{
char ch = text[i];
if (sb == null)
{
// Check if we need to upgrade to StringBuilder
if (!NeedsEscaping(ch))
{
switch (ch)
{
case '"':
case '\\':
case '/':
break;

default:
continue; // StringBuilder not needed, yet
}
}

// StringBuilder needed
sb = new StringBuilder(text.Length + 4);
sb.Append(text, 0, i);
}

switch (text[i])
{
case '"':
sb.Append("\\\"");
break;

case '\\':
sb.Append("\\\\");
break;

case '/':
sb.Append("\\/");
break;

case '\b':
sb.Append("\\b");
break;

case '\r':
sb.Append("\\r");
break;

case '\n':
sb.Append("\\n");
break;

case '\f':
sb.Append("\\f");
break;

case '\t':
sb.Append("\\t");
break;

default:
if (NeedsEscaping(text[i]))
{
sb.Append("\\u");
sb.Append(Convert.ToString((int)text[i], 16).PadLeft(4, '0'));
}
else
{
sb.Append(text[i]);
}

break;
}
}

if (sb != null)
return sb.ToString();
else
return text;
}

private static bool NeedsEscaping(char ch)
{
return ch < 32 || ch > 127;
return this.JsonEncode ? Targets.DefaultJsonSerializer.JsonStringEscape(text) : text;
}
}
}

0 comments on commit 60576a1

Please sign in to comment.