コード例 #1
0
ファイル: DefaultJsonSerializer.cs プロジェクト: zauggm/NLog
        private bool SerializeTypeCodeValue(object value, StringBuilder destination, JsonSerializeOptions options, SingleItemOptimizedHashSet <object> objectsInPath, int depth)
        {
            TypeCode objTypeCode = Convert.GetTypeCode(value);

            if (objTypeCode == TypeCode.Object)
            {
                if (value is Guid || value is TimeSpan || value is MemberInfo || value is Assembly)
                {
                    //object without property, to string
                    QuoteValue(destination, Convert.ToString(value, CultureInfo.InvariantCulture));
                    return(true);
                }
                else if (value is DateTimeOffset)
                {
                    QuoteValue(destination, $"{value:yyyy-MM-dd HH:mm:ss zzz}");
                    return(true);
                }
                else
                {
                    return(SerializeObjectWithProperties(value, destination, options, ref objectsInPath, depth));
                }
            }
            else
            {
                return(SerializeSimpleTypeCodeValue(value, objTypeCode, destination, options));
            }
        }
コード例 #2
0
ファイル: DefaultJsonSerializer.cs プロジェクト: krivtom/NLog
 /// <summary>
 /// Returns a serialization of an object into JSON format.
 /// </summary>
 /// <param name="value">The object to serialize to JSON.</param>
 /// <param name="options">serialisation options</param>
 /// <returns>Serialized value.</returns>
 public string SerializeObject(object value, JsonSerializeOptions options)
 {
     if (value == null)
     {
         return("null");
     }
     else if (value is string str)
     {
         for (int i = 0; i < str.Length; ++i)
         {
             if (RequiresJsonEscape(str[i], options))
             {
                 StringBuilder sb = new StringBuilder(str.Length + 4);
                 sb.Append('"');
                 AppendStringEscape(sb, str, options);
                 sb.Append('"');
                 return(sb.ToString());
             }
         }
         return(QuoteValue(str));
     }
     else
     {
         IConvertible convertibleValue = value as IConvertible;
         TypeCode     objTypeCode      = convertibleValue?.GetTypeCode() ?? TypeCode.Object;
         if (objTypeCode != TypeCode.Object && objTypeCode != TypeCode.Char && StringHelpers.IsNullOrWhiteSpace(options.Format) && options.FormatProvider == null)
         {
             Enum enumValue;
             if (!options.EnumAsInteger && IsNumericTypeCode(objTypeCode, false) && (enumValue = value as Enum) != null)
             {
                 return(QuoteValue(EnumAsString(enumValue)));
             }
             else
             {
                 string xmlStr = XmlHelper.XmlConvertToString(convertibleValue, objTypeCode);
                 if (SkipQuotes(convertibleValue, objTypeCode))
                 {
                     return(xmlStr);
                 }
                 else
                 {
                     return(QuoteValue(xmlStr));
                 }
             }
         }
         else
         {
             StringBuilder sb = new StringBuilder();
             if (!SerializeObject(value, sb, options))
             {
                 return(null);
             }
             return(sb.ToString());
         }
     }
 }
コード例 #3
0
        /// <summary>
        /// Serialization of the object in JSON format to the destination StringBuilder
        /// </summary>
        /// <param name="value">The object to serialize to JSON.</param>
        /// <param name="destination">Write the resulting JSON to this destination.</param>
        /// <param name="options">serialisation options</param>
        /// <param name="objectsInPath">The objects in path (Avoid cyclic reference loop).</param>
        /// <param name="depth">The current depth (level) of recursion.</param>
        /// <returns>Object serialized succesfully (true/false).</returns>
        private bool SerializeObject(object value, StringBuilder destination, JsonSerializeOptions options,
                                     SingleItemOptimizedHashSet <object> objectsInPath, int depth)
        {
            if (objectsInPath.Contains(value))
            {
                return(false); // detected reference loop, skip serialization
            }
            if (depth > MaxRecursionDepth)
            {
                return(false); // reached maximum recursion level, no further serialization
            }

            if (value == null)
            {
                destination.Append("null");
            }
            else if (value is string str)
            {
                QuoteValue(destination, EscapeString(str, options.EscapeUnicode));
            }
            else if (value is IDictionary dict)
            {
                using (new SingleItemOptimizedHashSet <object> .SingleItemScopedInsert(dict, ref objectsInPath, true))
                {
                    SerializeDictionaryObject(dict, destination, options, objectsInPath, depth);
                }
            }
            else if (value is IEnumerable enumerable)
            {
                using (new SingleItemOptimizedHashSet <object> .SingleItemScopedInsert(value, ref objectsInPath, true))
                {
                    SerializeCollectionObject(enumerable, destination, options, objectsInPath, depth);
                }
            }
            else
            {
                var format    = options.Format;
                var hasFormat = !StringHelpers.IsNullOrWhiteSpace(format);
                if ((options.FormatProvider != null || hasFormat) && (value is IFormattable formattable))
                {
                    if (!SerializeWithFormatProvider(value, destination, options, formattable, format, hasFormat))
                    {
                        return(false);
                    }
                }
                else
                {
                    if (!SerializeTypeCodeValue(value, destination, options, objectsInPath, depth))
                    {
                        return(false);
                    }
                }
            }

            return(true);
        }
コード例 #4
0
ファイル: DefaultJsonSerializer.cs プロジェクト: zauggm/NLog
        /// <summary>
        /// Serialization of the object in JSON format to the destination StringBuilder
        /// </summary>
        /// <param name="value">The object to serialize to JSON.</param>
        /// <param name="destination">Write the resulting JSON to this destination.</param>
        /// <param name="options">serialisation options</param>
        /// <param name="objectsInPath">The objects in path (Avoid cyclic reference loop).</param>
        /// <param name="depth">The current depth (level) of recursion.</param>
        /// <returns>Object serialized succesfully (true/false).</returns>
        private bool SerializeObject(object value, StringBuilder destination, JsonSerializeOptions options,
                                     SingleItemOptimizedHashSet <object> objectsInPath, int depth)
        {
            if (objectsInPath.Contains(value))
            {
                return(false); // detected reference loop, skip serialization
            }

            if (value == null)
            {
                destination.Append("null");
            }
            else if (value is string str)
            {
                destination.Append('"');
                AppendStringEscape(destination, str, options.EscapeUnicode);
                destination.Append('"');
            }
            else if (value is IDictionary dict)
            {
                using (StartScope(ref objectsInPath, dict))
                {
                    SerializeDictionaryObject(dict, destination, options, objectsInPath, depth);
                }
            }
            else if (value is IEnumerable enumerable)
            {
                using (StartScope(ref objectsInPath, value))
                {
                    SerializeCollectionObject(enumerable, destination, options, objectsInPath, depth);
                }
            }
            else
            {
                var format    = options.Format;
                var hasFormat = !StringHelpers.IsNullOrWhiteSpace(format);
                if ((options.FormatProvider != null || hasFormat) && (value is IFormattable formattable))
                {
                    if (!SerializeWithFormatProvider(value, destination, options, formattable, format, hasFormat))
                    {
                        return(false);
                    }
                }
                else
                {
                    if (!SerializeTypeCodeValue(value, destination, options, objectsInPath, depth))
                    {
                        return(false);
                    }
                }
            }

            return(true);
        }
コード例 #5
0
        private void SerializeNumber(object value, StringBuilder destination, JsonSerializeOptions options, TypeCode objTypeCode)
        {
            Enum enumValue;

            if (!options.EnumAsInteger && (enumValue = value as Enum) != null)
            {
                QuoteValue(destination, EnumAsString(enumValue));
            }
            else
            {
                destination.AppendIntegerAsString(value, objTypeCode);
            }
        }
コード例 #6
0
        /// <summary>
        /// Returns a serialization of an object
        /// int JSON format.
        /// </summary>
        /// <param name="value">The object to serialize to JSON.</param>
        /// <param name="options">Options</param>
        /// <returns>Serialized value.</returns>
        public string SerializeObject(object value, JsonSerializeOptions options)
        {
            string str;

            if (value == null)
            {
                return("null");
            }
            else if ((str = value as string) != null)
            {
                return(QuoteValue(EscapeString(str, options.EscapeUnicode)));
            }
            else
            {
                TypeCode objTypeCode = Convert.GetTypeCode(value);
                if (objTypeCode != TypeCode.Object && StringHelpers.IsNullOrWhiteSpace(options.Format) && options.FormatProvider == null)
                {
                    Enum enumValue;
                    if (!options.EnumAsInteger && IsNumericTypeCode(objTypeCode, false) && (enumValue = value as Enum) != null)
                    {
                        return(QuoteValue(EnumAsString(enumValue)));
                    }
                    else
                    {
                        str = XmlHelper.XmlConvertToString(value, objTypeCode);
                        if (SkipQuotes(objTypeCode))
                        {
                            return(str);
                        }
                        else
                        {
                            return(QuoteValue(str));
                        }
                    }
                }
                else
                {
                    StringBuilder sb = new StringBuilder();
                    if (!SerializeObject(value, sb, options))
                    {
                        return(null);
                    }
                    return(sb.ToString());
                }
            }
        }
コード例 #7
0
ファイル: DefaultJsonSerializer.cs プロジェクト: krivtom/NLog
        /// <summary>
        /// Serialization of the object in JSON format to the destination StringBuilder
        /// </summary>
        /// <param name="value">The object to serialize to JSON.</param>
        /// <param name="destination">Write the resulting JSON to this destination.</param>
        /// <param name="options">serialisation options</param>
        /// <param name="objectsInPath">The objects in path (Avoid cyclic reference loop).</param>
        /// <param name="depth">The current depth (level) of recursion.</param>
        /// <returns>Object serialized successfully (true/false).</returns>
        private bool SerializeObject(object value, StringBuilder destination, JsonSerializeOptions options, SingleItemOptimizedHashSet <object> objectsInPath, int depth)
        {
            int originalLength = destination.Length;

            try
            {
                if (SerializeSimpleObjectValue(value, destination, options))
                {
                    return(true);
                }

                return(SerializeObjectWithReflection(value, destination, options, ref objectsInPath, depth));
            }
            catch
            {
                destination.Length = originalLength;
                return(false);
            }
        }
コード例 #8
0
ファイル: DefaultJsonSerializer.cs プロジェクト: krivtom/NLog
        private void SerializeCollectionObject(IEnumerable value, StringBuilder destination, JsonSerializeOptions options, SingleItemOptimizedHashSet <object> objectsInPath, int depth)
        {
            bool first = true;

            int nextDepth = objectsInPath.Count <= 1 ? depth : (depth + 1); // Allow serialization of list-items

            if (nextDepth > options.MaxRecursionLimit)
            {
                destination.Append("[]");
                return;
            }

            int originalLength;

            destination.Append('[');
            foreach (var val in value)
            {
                originalLength = destination.Length;
                if (originalLength > MaxJsonLength)
                {
                    break;
                }

                if (!first)
                {
                    destination.Append(',');
                }

                if (!SerializeObject(val, destination, options, objectsInPath, nextDepth))
                {
                    destination.Length = originalLength;
                }
                else
                {
                    first = false;
                }
            }
            destination.Append(']');
        }
コード例 #9
0
ファイル: DefaultJsonSerializer.cs プロジェクト: krivtom/NLog
        private bool SerializeObjectWithProperties(object value, StringBuilder destination, JsonSerializeOptions options, ref SingleItemOptimizedHashSet <object> objectsInPath, int depth)
        {
            if (depth < options.MaxRecursionLimit)
            {
                var objectPropertyList = _objectReflectionCache.LookupObjectProperties(value);
                if (!objectPropertyList.ConvertToString)
                {
                    if (ReferenceEquals(options, Instance._serializeOptions) && value is Exception)
                    {
                        // Exceptions are seldom under control, and can include random Data-Dictionary-keys, so we sanitize by default
                        options = Instance._exceptionSerializeOptions;
                    }

                    using (new SingleItemOptimizedHashSet <object> .SingleItemScopedInsert(value, ref objectsInPath, false, _referenceEqualsComparer))
                    {
                        return(SerializeObjectProperties(objectPropertyList, destination, options, objectsInPath, depth));
                    }
                }
            }

            return(SerializeObjectAsString(value, destination, options));
        }
コード例 #10
0
        private bool SerializeWithFormatProvider(object value, StringBuilder destination, JsonSerializeOptions options, IFormattable formattable, string format, bool hasFormat)
        {
            int originalLength = destination.Length;

            try
            {
                TypeCode objTypeCode   = Convert.GetTypeCode(value);
                bool     includeQuotes = !SkipQuotes(objTypeCode);
                if (includeQuotes)
                {
                    destination.Append('"');
                }

                if (hasFormat)
                {
                    var formatProvider = options.FormatProvider ?? _defaultFormatProvider;
                    destination.AppendFormat(formatProvider, string.Concat("{0:", format, "}"), value);
                }
                else
                {
                    //format provider passed without FormatProvider
                    destination.Append(EscapeString(formattable.ToString("", options.FormatProvider), options.EscapeUnicode));
                }

                if (includeQuotes)
                {
                    destination.Append('"');
                }

                return(true);
            }
            catch
            {
                destination.Length = originalLength;
                return(false);
            }
        }
コード例 #11
0
ファイル: DefaultJsonSerializer.cs プロジェクト: krivtom/NLog
        private void SerializeDictionaryObject(IDictionary dictionary, StringBuilder destination, JsonSerializeOptions options, SingleItemOptimizedHashSet <object> objectsInPath, int depth)
        {
            bool first = true;

            int nextDepth = objectsInPath.Count <= 1 ? depth : (depth + 1);

            if (nextDepth > options.MaxRecursionLimit)
            {
                destination.Append("{}");
                return;
            }

            destination.Append('{');
            foreach (var item in new DictionaryEntryEnumerable(dictionary))
            {
                var originalLength = destination.Length;
                if (originalLength > MaxJsonLength)
                {
                    break;
                }

                if (!first)
                {
                    destination.Append(',');
                }

                var itemKey = item.Key;
                if (options.QuoteKeys)
                {
                    if (!SerializeObjectAsString(itemKey, destination, options))
                    {
                        destination.Length = originalLength;
                        continue;
                    }
                }
                else
                {
                    if (!SerializeObject(itemKey, destination, options, objectsInPath, nextDepth))
                    {
                        destination.Length = originalLength;
                        continue;
                    }
                }

                if (options.SanitizeDictionaryKeys)
                {
                    int quoteSkipCount = options.QuoteKeys ? 1 : 0;
                    int keyEndIndex    = destination.Length - quoteSkipCount;
                    int keyStartIndex  = originalLength + (first ? 0 : 1) + quoteSkipCount;
                    if (!SanitizeDictionaryKey(destination, keyStartIndex, keyEndIndex - keyStartIndex))
                    {
                        destination.Length = originalLength;    // Empty keys are not allowed
                        continue;
                    }
                }

                destination.Append(':');

                //only serialize, if key and value are serialized without error (e.g. due to reference loop)
                var itemValue = item.Value;
                if (!SerializeObject(itemValue, destination, options, objectsInPath, nextDepth))
                {
                    destination.Length = originalLength;
                }
                else
                {
                    first = false;
                }
            }
            destination.Append('}');
        }
コード例 #12
0
ファイル: DefaultJsonSerializer.cs プロジェクト: krivtom/NLog
 internal static bool RequiresJsonEscape(char ch, JsonSerializeOptions options)
 {
     return(RequiresJsonEscape(ch, options.EscapeUnicode, options.EscapeForwardSlash));
 }
コード例 #13
0
ファイル: DefaultJsonSerializer.cs プロジェクト: krivtom/NLog
        private bool SerializeObjectAsString(object value, StringBuilder destination, JsonSerializeOptions options)
        {
            var originalLength = destination.Length;

            try
            {
                if (SerializeSimpleObjectValue(value, destination, options, true))
                {
                    return(true);
                }

                var hasFormat = !StringHelpers.IsNullOrWhiteSpace(options.Format);
                if ((options.FormatProvider != null || hasFormat) && (value is IFormattable formattable))
                {
                    SerializeWithFormatProvider(formattable, true, destination, options, hasFormat);
                    return(true);
                }

                var str = Convert.ToString(value, CultureInfo.InvariantCulture);
                destination.Append('"');
                AppendStringEscape(destination, str, options);
                destination.Append('"');
                return(true);
            }
            catch
            {
                // skip bad object
                destination.Length = originalLength;
                return(false);
            }
        }
コード例 #14
0
ファイル: DefaultJsonSerializer.cs プロジェクト: krivtom/NLog
 /// <summary>
 /// Serialization of the object in JSON format to the destination StringBuilder
 /// </summary>
 /// <param name="value">The object to serialize to JSON.</param>
 /// <param name="destination">Write the resulting JSON to this destination.</param>
 /// <param name="options">serialisation options</param>
 /// <returns>Object serialized successfully (true/false).</returns>
 public bool SerializeObject(object value, StringBuilder destination, JsonSerializeOptions options)
 {
     return(SerializeObject(value, destination, options, default(SingleItemOptimizedHashSet <object>), 0));
 }
コード例 #15
0
ファイル: DefaultJsonSerializer.cs プロジェクト: krivtom/NLog
 private void SerializeSimpleNumericValue(IConvertible value, TypeCode objTypeCode, StringBuilder destination, JsonSerializeOptions options, bool forceToString)
 {
     if (!options.EnumAsInteger && value is Enum enumValue)
     {
         QuoteValue(destination, EnumAsString(enumValue));
     }
     else
     {
         if (forceToString)
         {
             destination.Append('"');
         }
         destination.AppendIntegerAsString(value, objTypeCode);
         if (forceToString)
         {
             destination.Append('"');
         }
     }
 }
コード例 #16
0
        private bool SerializeProperties(object value, StringBuilder destination, JsonSerializeOptions options,
                                         SingleItemOptimizedHashSet <object> objectsInPath, int depth)
        {
            var props = GetProps(value);

            if (props.Key.Length == 0)
            {
                try
                {
                    //no props
                    QuoteValue(destination, EscapeString(Convert.ToString(value, CultureInfo.InvariantCulture), options.EscapeUnicode));
                    return(true);
                }
                catch
                {
                    return(false);
                }
            }

            destination.Append('{');

            bool first               = true;
            int  originalLength      = 0;
            bool useLateBoundMethods = props.Key.Length == props.Value.Length;

            for (var i = 0; i < props.Key.Length; i++)
            {
                originalLength = destination.Length;

                try
                {
                    var prop      = props.Key[i];
                    var propValue = useLateBoundMethods ? props.Value[i](value, null) : prop.GetValue(value, null);
                    if (propValue != null)
                    {
                        if (!first)
                        {
                            destination.Append(", ");
                        }

                        if (options.QuoteKeys)
                        {
                            QuoteValue(destination, prop.Name);
                        }
                        else
                        {
                            destination.Append(prop.Name);
                        }
                        destination.Append(':');

                        if (!SerializeObject(propValue, destination, options, objectsInPath, depth + 1))
                        {
                            destination.Length = originalLength;
                        }
                        else
                        {
                            first = false;
                        }
                    }
                }
                catch
                {
                    //skip this property
                    destination.Length = originalLength;
                }
            }

            destination.Append('}');
            return(true);
        }
コード例 #17
0
ファイル: DefaultJsonSerializer.cs プロジェクト: zauggm/NLog
        private bool SerializeSimpleTypeCodeValue(object value, TypeCode objTypeCode, StringBuilder destination, JsonSerializeOptions options, bool forceQuotes = false)
        {
            if (objTypeCode == TypeCode.String || objTypeCode == TypeCode.Char)
            {
                destination.Append('"');
                AppendStringEscape(destination, value.ToString(), options.EscapeUnicode);
                destination.Append('"');
            }
            else if (IsNumericTypeCode(objTypeCode, false))
            {
                if (!options.EnumAsInteger && value is Enum enumValue)
                {
                    QuoteValue(destination, EnumAsString(enumValue));
                }
                else
                {
                    if (forceQuotes)
                    {
                        destination.Append('"');
                    }
                    destination.AppendIntegerAsString(value, objTypeCode);
                    if (forceQuotes)
                    {
                        destination.Append('"');
                    }
                }
            }
            else
            {
                string str = XmlHelper.XmlConvertToString(value, objTypeCode);
                if (str == null)
                {
                    return(false);
                }

                if (!forceQuotes && SkipQuotes(value, objTypeCode))
                {
                    destination.Append(str);
                }
                else
                {
                    QuoteValue(destination, str);
                }
            }
            return(true);
        }
コード例 #18
0
        private bool SerializeTypeCodeValue(object value, StringBuilder destination, JsonSerializeOptions options, SingleItemOptimizedHashSet <object> objectsInPath, int depth)
        {
            TypeCode objTypeCode = Convert.GetTypeCode(value);

            if (objTypeCode == TypeCode.Object)
            {
                if (value is Guid || value is TimeSpan)
                {
                    //object without property, to string
                    QuoteValue(destination, Convert.ToString(value, CultureInfo.InvariantCulture));
                }
                else if (value is DateTimeOffset)
                {
                    QuoteValue(destination, string.Format("{0:yyyy-MM-dd HH:mm:ss zzz}", value));
                }
                else
                {
                    int originalLength = destination.Length;
                    try
                    {
                        using (new SingleItemOptimizedHashSet <object> .SingleItemScopedInsert(value, ref objectsInPath, false))
                        {
                            return(SerializeProperties(value, destination, options, objectsInPath, depth));
                        }
                    }
                    catch
                    {
                        //nothing to add, so return is OK
                        destination.Length = originalLength;
                        return(false);
                    }
                }
            }
            else
            {
                if (IsNumericTypeCode(objTypeCode, false))
                {
                    Enum enumValue;
                    if (!options.EnumAsInteger && (enumValue = value as Enum) != null)
                    {
                        QuoteValue(destination, EnumAsString(enumValue));
                    }
                    else
                    {
                        AppendIntegerAsString(destination, value, objTypeCode);
                    }
                }
                else
                {
                    string str = XmlHelper.XmlConvertToString(value, objTypeCode);
                    if (str == null)
                    {
                        return(false);
                    }
                    if (SkipQuotes(objTypeCode))
                    {
                        destination.Append(str);
                    }
                    else
                    {
                        QuoteValue(destination, str);
                    }
                }
            }

            return(true);
        }
コード例 #19
0
        private void SerializeCollectionObject(IEnumerable value, StringBuilder destination, JsonSerializeOptions options, SingleItemOptimizedHashSet <object> objectsInPath, int depth)
        {
            bool first = true;

            int originalLength;

            destination.Append('[');
            foreach (var val in value)
            {
                originalLength = destination.Length;
                if (!first)
                {
                    destination.Append(',');
                }

                if (!SerializeObject(val, destination, options, objectsInPath, depth + 1))
                {
                    destination.Length = originalLength;
                }
                else
                {
                    first = false;
                }
            }
            destination.Append(']');
        }
コード例 #20
0
        private void SerializeDictionaryObject(IDictionary value, StringBuilder destination, JsonSerializeOptions options, SingleItemOptimizedHashSet <object> objectsInPath, int depth)
        {
            bool first = true;

            int originalLength;

            destination.Append('{');
            foreach (DictionaryEntry de in value)
            {
                originalLength = destination.Length;
                if (!first)
                {
                    destination.Append(',');
                }

                //only serialize, if key and value are serialized without error (e.g. due to reference loop)
                if (!SerializeObject(de.Key, destination, options, objectsInPath, depth + 1))
                {
                    destination.Length = originalLength;
                }
                else
                {
                    destination.Append(':');
                    if (!SerializeObject(de.Value, destination, options, objectsInPath, depth + 1))
                    {
                        destination.Length = originalLength;
                    }
                    else
                    {
                        first = false;
                    }
                }
            }
            destination.Append('}');
        }
コード例 #21
0
ファイル: DefaultJsonSerializer.cs プロジェクト: krivtom/NLog
 private void SerializeSimpleTypeCodeValue(IConvertible value, TypeCode objTypeCode, StringBuilder destination, JsonSerializeOptions options, bool forceToString = false)
 {
     if (objTypeCode == TypeCode.Empty || value == null)
     {
         destination.Append(forceToString ? "\"\"" : "null");
     }
     else if (objTypeCode == TypeCode.String || objTypeCode == TypeCode.Char)
     {
         destination.Append('"');
         AppendStringEscape(destination, value.ToString(), options);
         destination.Append('"');
     }
     else
     {
         var hasFormat = !StringHelpers.IsNullOrWhiteSpace(options.Format);
         if ((options.FormatProvider != null || hasFormat) && (value is IFormattable formattable))
         {
             bool includeQuotes = forceToString || objTypeCode == TypeCode.Object || !SkipQuotes(value, objTypeCode);
             SerializeWithFormatProvider(formattable, includeQuotes, destination, options, hasFormat);
         }
         else
         {
             SerializeSimpleTypeCodeValueNoEscape(value, objTypeCode, destination, options, forceToString);
         }
     }
 }
コード例 #22
0
ファイル: DefaultJsonSerializer.cs プロジェクト: zauggm/NLog
        private bool SerializeObjectWithProperties(object value, StringBuilder destination, JsonSerializeOptions options, ref SingleItemOptimizedHashSet <object> objectsInPath, int depth)
        {
            int originalLength = destination.Length;

            if (originalLength > MaxJsonLength)
            {
                return(false);
            }

            if (depth < options.MaxRecursionLimit)
            {
                try
                {
                    if (value is Exception && ReferenceEquals(options, instance._serializeOptions))
                    {
                        // Exceptions are seldom under control, and can include random Data-Dictionary-keys, so we sanitize by default
                        options = instance._exceptionSerializeOptions;
                    }

                    using (new SingleItemOptimizedHashSet <object> .SingleItemScopedInsert(value, ref objectsInPath, false, _referenceEqualsComparer))
                    {
                        return(SerializeProperties(value, destination, options, objectsInPath, depth));
                    }
                }
                catch
                {
                    //nothing to add, so return is OK
                    destination.Length = originalLength;
                    return(false);
                }
            }
            else
            {
                return(SerializeObjectAsString(value, TypeCode.Object, destination, options));
            }
        }
コード例 #23
0
ファイル: DefaultJsonSerializer.cs プロジェクト: krivtom/NLog
 private void SerializeSimpleTypeCodeValueNoEscape(IConvertible value, TypeCode objTypeCode, StringBuilder destination, JsonSerializeOptions options, bool forceToString)
 {
     if (IsNumericTypeCode(objTypeCode, false))
     {
         SerializeSimpleNumericValue(value, objTypeCode, destination, options, forceToString);
     }
     else if (objTypeCode == TypeCode.DateTime)
     {
         destination.Append('"');
         destination.AppendXmlDateTimeRoundTrip(value.ToDateTime(CultureInfo.InvariantCulture));
         destination.Append('"');
     }
     else
     {
         string str = XmlHelper.XmlConvertToString(value, objTypeCode);
         if (!forceToString && SkipQuotes(value, objTypeCode) && !string.IsNullOrEmpty(str))
         {
             destination.Append(str);
         }
         else
         {
             QuoteValue(destination, str);
         }
     }
 }
コード例 #24
0
ファイル: DefaultJsonSerializer.cs プロジェクト: yhking/NLog
        private bool SerializeSimpleObjectValue(object value, StringBuilder destination, JsonSerializeOptions options, bool forceToString = false)
        {
            var convertibleValue = value as IConvertible;
            var objTypeCode      = value == null ? TypeCode.Empty : (convertibleValue?.GetTypeCode() ?? TypeCode.Object);

            if (objTypeCode != TypeCode.Object)
            {
                SerializeSimpleTypeCodeValue(convertibleValue, objTypeCode, destination, options, forceToString);
                return(true);
            }

            if (value is DateTimeOffset)
            {
                QuoteValue(destination, $"{value:yyyy-MM-dd HH:mm:ss zzz}");
                return(true);
            }

            return(false);   // Not simple
        }
コード例 #25
0
ファイル: DefaultJsonSerializer.cs プロジェクト: krivtom/NLog
 /// <summary>
 /// Checks input string if it needs JSON escaping, and makes necessary conversion
 /// </summary>
 /// <param name="destination">Destination Builder</param>
 /// <param name="text">Input string</param>
 /// <param name="options">all options</param>
 /// <returns>JSON escaped string</returns>
 private static void AppendStringEscape(StringBuilder destination, string text, JsonSerializeOptions options)
 {
     AppendStringEscape(destination, text, options.EscapeUnicode, options.EscapeForwardSlash);
 }
コード例 #26
0
ファイル: DefaultJsonSerializer.cs プロジェクト: krivtom/NLog
        private bool SerializeSimpleObjectValue(object value, StringBuilder destination, JsonSerializeOptions options, bool forceToString = false)
        {
            var convertibleValue = value as IConvertible;
            var objTypeCode      = value == null ? TypeCode.Empty : (convertibleValue?.GetTypeCode() ?? TypeCode.Object);

            if (objTypeCode != TypeCode.Object)
            {
                SerializeSimpleTypeCodeValue(convertibleValue, objTypeCode, destination, options, forceToString);
                return(true);
            }

            if (value is DateTimeOffset dateTimeOffset)
            {
                QuoteValue(destination, dateTimeOffset.ToString("yyyy-MM-dd HH:mm:ss zzz", CultureInfo.InvariantCulture));
                return(true);
            }

            if (value is IFormattable formattable)
            {
                var hasFormat = !StringHelpers.IsNullOrWhiteSpace(options.Format);
                SerializeWithFormatProvider(formattable, true, destination, options, hasFormat);
                return(true);
            }

            return(false);   // Not simple
        }
コード例 #27
0
ファイル: DefaultJsonSerializer.cs プロジェクト: krivtom/NLog
        private bool SerializeObjectProperties(ObjectReflectionCache.ObjectPropertyList objectPropertyList, StringBuilder destination, JsonSerializeOptions options,
                                               SingleItemOptimizedHashSet <object> objectsInPath, int depth)
        {
            destination.Append('{');

            bool first = true;

            foreach (var propertyValue in objectPropertyList)
            {
                var originalLength = destination.Length;

                try
                {
                    if (HasNameAndValue(propertyValue))
                    {
                        if (!first)
                        {
                            destination.Append(", ");
                        }

                        if (options.QuoteKeys)
                        {
                            QuoteValue(destination, propertyValue.Name);
                        }
                        else
                        {
                            destination.Append(propertyValue.Name);
                        }
                        destination.Append(':');

                        var objTypeCode = propertyValue.TypeCode;
                        if (objTypeCode != TypeCode.Object)
                        {
                            SerializeSimpleTypeCodeValue((IConvertible)propertyValue.Value, objTypeCode, destination, options);
                            first = false;
                        }
                        else
                        {
                            if (!SerializeObject(propertyValue.Value, destination, options, objectsInPath, depth + 1))
                            {
                                destination.Length = originalLength;
                            }
                            else
                            {
                                first = false;
                            }
                        }
                    }
                }
                catch
                {
                    // skip single property
                    destination.Length = originalLength;
                }
            }

            destination.Append('}');
            return(true);
        }
コード例 #28
0
ファイル: DefaultJsonSerializer.cs プロジェクト: krivtom/NLog
        private void SerializeWithFormatProvider(IFormattable formattable, bool includeQuotes, StringBuilder destination, JsonSerializeOptions options, bool hasFormat)
        {
            if (includeQuotes)
            {
                destination.Append('"');
            }

            var formatProvider = options.FormatProvider ?? (hasFormat ? _defaultFormatProvider : null);
            var str            = formattable.ToString(hasFormat ? options.Format : "", formatProvider);

            if (includeQuotes)
            {
                AppendStringEscape(destination, str, options);
            }
            else
            {
                destination.Append(str);
            }

            if (includeQuotes)
            {
                destination.Append('"');
            }
        }
コード例 #29
0
ファイル: DefaultJsonSerializer.cs プロジェクト: krivtom/NLog
        private bool SerializeObjectWithReflection(object value, StringBuilder destination, JsonSerializeOptions options, ref SingleItemOptimizedHashSet <object> objectsInPath, int depth)
        {
            int originalLength = destination.Length;

            if (originalLength > MaxJsonLength)
            {
                return(false);
            }

            if (objectsInPath.Contains(value))
            {
                return(false);
            }

            if (value is IDictionary dict)
            {
                using (StartCollectionScope(ref objectsInPath, dict))
                {
                    SerializeDictionaryObject(dict, destination, options, objectsInPath, depth);
                    return(true);
                }
            }

            if (value is IEnumerable enumerable)
            {
                if (_objectReflectionCache.TryLookupExpandoObject(value, out var propertyValues))
                {
                    if (propertyValues.ConvertToString || depth >= options.MaxRecursionLimit)
                    {
                        return(SerializeObjectAsString(value, destination, options));
                    }
                    else
                    {
                        using (new SingleItemOptimizedHashSet <object> .SingleItemScopedInsert(value, ref objectsInPath, false, _referenceEqualsComparer))
                        {
                            return(SerializeObjectProperties(propertyValues, destination, options, objectsInPath, depth));
                        }
                    }
                }

                using (StartCollectionScope(ref objectsInPath, value))
                {
                    SerializeCollectionObject(enumerable, destination, options, objectsInPath, depth);
                    return(true);
                }
            }
            else
            {
                return(SerializeObjectWithProperties(value, destination, options, ref objectsInPath, depth));
            }
        }
コード例 #30
0
ファイル: DefaultJsonSerializer.cs プロジェクト: zauggm/NLog
 private bool SerializeObjectAsString(object value, TypeCode objTypeCode, StringBuilder destination, JsonSerializeOptions options)
 {
     try
     {
         if (objTypeCode == TypeCode.Object)
         {
             var str = Convert.ToString(value, CultureInfo.InvariantCulture);
             destination.Append('"');
             AppendStringEscape(destination, str, options.EscapeUnicode);
             destination.Append('"');
             return(true);
         }
         else
         {
             return(SerializeSimpleTypeCodeValue(value, objTypeCode, destination, options, true));
         }
     }
     catch
     {
         return(false);
     }
 }