public static ParseListDelegate GetListTypeParseStringSpanFn(
            Type createListType, Type elementType, ParseStringSpanDelegate parseFn)
        {
            if (ParseDelegateCache.TryGetValue(elementType, out var parseDelegate))
            {
                return(parseDelegate.Invoke);
            }

            var genericType = typeof(DeserializeListWithElements <,>).MakeGenericType(elementType, typeof(TSerializer));
            var mi          = genericType.GetStaticMethod("ParseGenericList", signature);

            parseDelegate = (ParseListDelegate)mi.MakeDelegate(typeof(ParseListDelegate));

            Dictionary <Type, ParseListDelegate> snapshot, newCache;

            do
            {
                snapshot = ParseDelegateCache;
                newCache = new Dictionary <Type, ParseListDelegate>(ParseDelegateCache)
                {
                    [elementType] = parseDelegate
                };
            } while (!ReferenceEquals(
                         Interlocked.CompareExchange(ref ParseDelegateCache, newCache, snapshot), snapshot));

            return(parseDelegate.Invoke);
        }
        public static object ParseKeyValuePairType(ReadOnlySpan <char> value, Type createMapType, Type[] argTypes,
                                                   ParseStringSpanDelegate keyParseFn, ParseStringSpanDelegate valueParseFn)
        {
            var key = GetTypesKey(argTypes);

            if (ParseDelegateCache.TryGetValue(key, out var parseDelegate))
            {
                return(parseDelegate(value, createMapType, keyParseFn, valueParseFn));
            }

            var mi        = typeof(DeserializeKeyValuePair <TSerializer>).GetStaticMethod("ParseKeyValuePair", signature);
            var genericMi = mi.MakeGenericMethod(argTypes);

            parseDelegate = (ParseKeyValuePairDelegate)genericMi.MakeDelegate(typeof(ParseKeyValuePairDelegate));

            Dictionary <string, ParseKeyValuePairDelegate> snapshot, newCache;

            do
            {
                snapshot      = ParseDelegateCache;
                newCache      = new Dictionary <string, ParseKeyValuePairDelegate>(ParseDelegateCache);
                newCache[key] = parseDelegate;
            } while (!ReferenceEquals(
                         Interlocked.CompareExchange(ref ParseDelegateCache, newCache, snapshot), snapshot));

            return(parseDelegate(value, createMapType, keyParseFn, valueParseFn));
        }
Пример #3
0
    /// <summary>
    /// Parses the dictionary.
    /// </summary>
    /// <typeparam name="TKey">The type of the t key.</typeparam>
    /// <typeparam name="TValue">The type of the t value.</typeparam>
    /// <param name="value">The value.</param>
    /// <param name="createMapType">Type of the create map.</param>
    /// <param name="parseKeyFn">The parse key function.</param>
    /// <param name="parseValueFn">The parse value function.</param>
    /// <returns>IDictionary&lt;TKey, TValue&gt;.</returns>
    public static IDictionary <TKey, TValue> ParseDictionary <TKey, TValue>(
        ReadOnlySpan <char> value, Type createMapType,
        ParseStringSpanDelegate parseKeyFn, ParseStringSpanDelegate parseValueFn)
    {
        if (value.IsEmpty)
        {
            return(null);
        }

        var to = createMapType == null
                     ? new Dictionary <TKey, TValue>()
                     : (IDictionary <TKey, TValue>)createMapType.CreateInstance();

        var objDeserializer = Json.JsonTypeSerializer.Instance.ObjectDeserializer;

        if (to is Dictionary <string, object> && objDeserializer != null && typeof(TSerializer) == typeof(Json.JsonTypeSerializer))
        {
            return((IDictionary <TKey, TValue>)objDeserializer(value));
        }

        var config = JsConfig.GetConfig();

        var tryToParseItemsAsDictionaries =
            config.ConvertObjectTypesIntoStringDictionary && typeof(TValue) == typeof(object);
        var tryToParseItemsAsPrimitiveTypes =
            config.TryToParsePrimitiveTypeValues && typeof(TValue) == typeof(object);

        var index = VerifyAndGetStartIndex(value, createMapType);

        if (Json.JsonTypeSerializer.IsEmptyMap(value, index))
        {
            return(to);
        }

        var valueLength = value.Length;

        while (index < valueLength)
        {
            var keyValue = Serializer.EatMapKey(value, ref index);
            Serializer.EatMapKeySeperator(value, ref index);
            var elementStartIndex = index;
            var elementValue      = Serializer.EatTypeValue(value, ref index);
            if (keyValue.IsNullOrEmpty())
            {
                continue;
            }

            TKey mapKey = (TKey)parseKeyFn(keyValue);

            if (tryToParseItemsAsDictionaries)
            {
                Serializer.EatWhitespace(value, ref elementStartIndex);
                if (elementStartIndex < valueLength && value[elementStartIndex] == JsWriter.MapStartChar)
                {
                    var tmpMap = ParseDictionary <TKey, TValue>(elementValue, createMapType, parseKeyFn, parseValueFn);
                    if (tmpMap is { Count : > 0 })
        public static object ParseKeyValuePair <TKey, TValue>(
            ReadOnlySpan <char> value, Type createMapType,
            ParseStringSpanDelegate parseKeyFn, ParseStringSpanDelegate parseValueFn)
        {
            if (value.IsEmpty)
            {
                return(default(KeyValuePair <TKey, TValue>));
            }

            var index = VerifyAndGetStartIndex(value, createMapType);

            if (JsonTypeSerializer.IsEmptyMap(value, index))
            {
                return(new KeyValuePair <TKey, TValue>());
            }
            var keyValue   = default(TKey);
            var valueValue = default(TValue);

            var valueLength = value.Length;

            while (index < valueLength)
            {
                var key = Serializer.EatMapKey(value, ref index);
                Serializer.EatMapKeySeperator(value, ref index);
                var keyElementValue = Serializer.EatTypeValue(value, ref index);

                if (key.CompareIgnoreCase("key".AsSpan()))
                {
                    keyValue = (TKey)parseKeyFn(keyElementValue);
                }
                else if (key.CompareIgnoreCase("value".AsSpan()))
                {
                    valueValue = (TValue)parseValueFn(keyElementValue);
                }
                else
                {
                    throw new SerializationException("Incorrect KeyValuePair property: " + key.ToString());
                }

                Serializer.EatItemSeperatorOrMapEndChar(value, ref index);
            }

            return(new KeyValuePair <TKey, TValue>(keyValue, valueValue));
        }
        public static ParseStringSpanDelegate GetParseStringSpanFn <T>(string parseMethod)
        {
            // Get the static Parse(string) method on the type supplied
            var parseMethodInfo = typeof(T).GetStaticMethod(parseMethod, new[] { typeof(string) });

            if (parseMethodInfo == null)
            {
                return(null);
            }

            ParseStringSpanDelegate parseDelegate = null;

            try
            {
                if (parseMethodInfo.ReturnType != typeof(T))
                {
                    parseDelegate = (ParseStringSpanDelegate)parseMethodInfo.MakeDelegate(typeof(ParseStringSpanDelegate), false);
                }
                if (parseDelegate == null)
                {
                    //Try wrapping strongly-typed return with wrapper fn.
                    var typedParseDelegate = (ParseStringSpanGenericDelegate <T>)parseMethodInfo.MakeDelegate(typeof(ParseStringSpanGenericDelegate <T>));
                    parseDelegate = x => typedParseDelegate(x);
                }
            }
            catch (ArgumentException)
            {
                Tracer.Instance.WriteDebug("Nonstandard Parse method on type {0}", typeof(T));
            }

            if (parseDelegate != null)
            {
                return(value => parseDelegate(value.ToString().FromCsvField().AsSpan()));
            }

            return(null);
        }
Пример #6
0
    /// <summary>
    /// Parses the collection.
    /// </summary>
    /// <typeparam name="T"></typeparam>
    /// <param name="value">The value.</param>
    /// <param name="createType">Type of the create.</param>
    /// <param name="parseFn">The parse function.</param>
    /// <returns>ICollection&lt;T&gt;.</returns>
    public static ICollection <T> ParseCollection <T>(ReadOnlySpan <char> value, Type createType, ParseStringSpanDelegate parseFn)
    {
        if (value.IsEmpty)
        {
            return(null);
        }

        var items = DeserializeArrayWithElements <T, TSerializer> .ParseGenericArray(value, parseFn);

        return(CollectionExtensions.CreateAndPopulate(createType, items));
    }
 static StaticParseRefTypeMethod()
 {
     CacheFn           = ParseMethodUtilities.GetParseFn <T>(ParseMethod);
     CacheStringSpanFn = ParseMethodUtilities.GetParseStringSpanFn <T>(ParseStringSpanMethod);
 }
Пример #8
0
 /// <summary>
 /// Initializes static members of the <see cref="StaticParseMethod{T}" /> class.
 /// </summary>
 static StaticParseMethod()
 {
     Parse           = ParseMethodUtilities.GetParseFn <T>(ParseMethod);
     ParseStringSpan = ParseMethodUtilities.GetParseStringSpanFn <T>(ParseMethod);
 }
 static DeserializeSpecializedCollections()
 {
     CacheFn = GetParseStringSpanFn();
 }
 static DeserializeDynamic()
 {
     CachedParseFn = ParseDynamic;
 }
Пример #11
0
 static DeserializeBuiltin()
 {
     CachedParseFn = GetParseStringSpanFn();
 }
Пример #12
0
 static StaticParseMethod()
 {
     CacheFn           = ParseMethodUtilities.GetParseFn <T>(ParseMethod);
     CacheStringSpanFn = ParseMethodUtilities.GetParseStringSegmentFn <T>(ParseMethod);
 }
Пример #13
0
        public static IDictionary <TKey, TValue> ParseDictionary <TKey, TValue>(
            ReadOnlySpan <char> value, Type createMapType,
            ParseStringSpanDelegate parseKeyFn, ParseStringSpanDelegate parseValueFn)
        {
            if (value.IsEmpty)
            {
                return(null);
            }

            var config = JsConfig.GetConfig();

            var tryToParseItemsAsDictionaries =
                config.ConvertObjectTypesIntoStringDictionary && typeof(TValue) == typeof(object);
            var tryToParseItemsAsPrimitiveTypes =
                config.TryToParsePrimitiveTypeValues && typeof(TValue) == typeof(object);

            var index = VerifyAndGetStartIndex(value, createMapType);

            var to = (createMapType == null)
                ? new Dictionary <TKey, TValue>()
                : (IDictionary <TKey, TValue>)createMapType.CreateInstance();

            if (JsonTypeSerializer.IsEmptyMap(value, index))
            {
                return(to);
            }

            var valueLength = value.Length;

            while (index < valueLength)
            {
                var keyValue = Serializer.EatMapKey(value, ref index);
                Serializer.EatMapKeySeperator(value, ref index);
                var elementStartIndex = index;
                var elementValue      = Serializer.EatTypeValue(value, ref index);
                if (keyValue.IsNullOrEmpty())
                {
                    continue;
                }

                TKey mapKey = (TKey)parseKeyFn(keyValue);

                if (tryToParseItemsAsDictionaries)
                {
                    Serializer.EatWhitespace(value, ref elementStartIndex);
                    if (elementStartIndex < valueLength && value[elementStartIndex] == JsWriter.MapStartChar)
                    {
                        var tmpMap = ParseDictionary <TKey, TValue>(elementValue, createMapType, parseKeyFn, parseValueFn);
                        if (tmpMap != null && tmpMap.Count > 0)
                        {
                            to[mapKey] = (TValue)tmpMap;
                        }
                    }
                    else if (elementStartIndex < valueLength && value[elementStartIndex] == JsWriter.ListStartChar)
                    {
                        to[mapKey] = (TValue)DeserializeList <List <object>, TSerializer> .ParseStringSpan(elementValue);
                    }
                    else
                    {
                        to[mapKey] = (TValue)(tryToParseItemsAsPrimitiveTypes && elementStartIndex < valueLength
                            ? DeserializeType <TSerializer> .ParsePrimitive(elementValue.Value(), value[elementStartIndex])
                            : parseValueFn(elementValue));
                    }
                }
                else
                {
                    if (tryToParseItemsAsPrimitiveTypes && elementStartIndex < valueLength)
                    {
                        Serializer.EatWhitespace(value, ref elementStartIndex);
                        to[mapKey] = (TValue)DeserializeType <TSerializer> .ParsePrimitive(elementValue.Value(), value[elementStartIndex]);
                    }
                    else
                    {
                        to[mapKey] = (TValue)parseValueFn(elementValue);
                    }
                }

                Serializer.EatItemSeperatorOrMapEndChar(value, ref index);
            }

            return(to);
        }
Пример #14
0
        public static object ParseCollectionType(ReadOnlySpan <char> value, Type createType, Type elementType, ParseStringSpanDelegate parseFn)
        {
            if (ParseDelegateCache.TryGetValue(elementType, out var parseDelegate))
            {
                return(parseDelegate(value, createType, parseFn));
            }

            var mi        = typeof(DeserializeCollection <TSerializer>).GetStaticMethod("ParseCollection", arguments);
            var genericMi = mi.MakeGenericMethod(new[] { elementType });

            parseDelegate = (ParseCollectionDelegate)genericMi.MakeDelegate(typeof(ParseCollectionDelegate));

            Dictionary <Type, ParseCollectionDelegate> snapshot, newCache;

            do
            {
                snapshot = ParseDelegateCache;
                newCache = new Dictionary <Type, ParseCollectionDelegate>(ParseDelegateCache);
                newCache[elementType] = parseDelegate;
            } while (!ReferenceEquals(
                         Interlocked.CompareExchange(ref ParseDelegateCache, newCache, snapshot), snapshot));

            return(parseDelegate(value, createType, parseFn));
        }