Ejemplo n.º 1
0
        public static IDictionary ParseIDictionary(ReadOnlySpan <char> value, Type dictType)
        {
            if (value.IsEmpty)
            {
                return(null);
            }

            var index = VerifyAndGetStartIndex(value, dictType);

            var valueParseMethod = Serializer.GetParseStringSpanFn(typeof(object));

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

            var to = ActivatorUtils.FastCreateInstance <IDictionary>(dictType);

            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.IsEmpty)
                {
                    continue;
                }

                var mapKey = valueParseMethod(keyValue);

                if (elementStartIndex < valueLength)
                {
                    Serializer.EatWhitespace(value, ref elementStartIndex);
                    to[mapKey] = DeserializeType <TSerializer> .ParsePrimitive(elementValue.Value(), value[elementStartIndex]);
                }
                else
                {
                    to[mapKey] = valueParseMethod(elementValue);
                }

                Serializer.EatItemSeperatorOrMapEndChar(value, ref index);
            }

            return(to);
        }
Ejemplo n.º 2
0
        public static object ConvertFromCollection(object enumerable)
        {
            //var to = (ICollection<T>)typeof(TCollection).CreateInstance();
            var to   = ActivatorUtils.FastCreateInstance <ICollection <T> >(typeof(TCollection));
            var from = (IEnumerable <T>)enumerable;

            foreach (var item in from)
            {
                to.Add(item);
            }
            return(to);
        }
Ejemplo n.º 3
0
        internal static object GetFormatter(Type t)
        {
#if !TEST40
            if (typeof(ITestMessage).GetTypeInfo().IsAssignableFrom(t.GetTypeInfo()))
#else
            if (typeof(ITestMessage).IsAssignableFrom(t))
#endif
            {
                return(ActivatorUtils.FastCreateInstance(typeof(TestMessageFormatter <>).GetCachedGenericType(t)));
            }

            return(null);
        }
Ejemplo n.º 4
0
        public override ValueSerializer BuildSerializer(Serializer serializer, Type type,
                                                        CachedReadConcurrentDictionary <Type, ValueSerializer> typeMapping)
        {
            var preserveObjectReferences = serializer.Options.PreserveObjectReferences;
            var ser = new ObjectSerializer(type);

            typeMapping.TryAdd(type, ser);
            var elementSerializer = serializer.GetSerializerByType(typeof(DictionaryEntry));

            ObjectReader reader = (stream, session) =>
            {
                var instance = ActivatorUtils.FastCreateInstance(type) as IDictionary <string, object>;

                if (preserveObjectReferences)
                {
                    session.TrackDeserializedObject(instance);
                }
                var count = stream.ReadInt32(session);
                for (var i = 0; i < count; i++)
                {
                    var entry = (KeyValuePair <string, object>)stream.ReadObject(session);
                    instance.Add(entry);
                }
                return(instance);
            };

            ObjectWriter writer = (stream, obj, session) =>
            {
                if (preserveObjectReferences)
                {
                    session.TrackSerializedObject(obj);
                }
                var dict = obj as IDictionary <string, object>;
                // ReSharper disable once PossibleNullReferenceException
                Int32Serializer.WriteValueImpl(stream, dict.Count, session);
                foreach (var item in dict)
                {
                    stream.WriteObject(item, typeof(DictionaryEntry), elementSerializer,
                                       serializer.Options.PreserveObjectReferences, session);
                    // elementSerializer.WriteValue(stream,item,session);
                }
            };

            ser.Initialize(reader, writer);

            return(ser);
        }
            static FormatterCache()
            {
                Interlocked.CompareExchange(ref s_isFreezed, Locked, Unlocked);

                var formatters = Volatile.Read(ref s_formatters);

                foreach (var item in formatters)
                {
                    foreach (var implInterface in item.GetType().GetTypeInfo().ImplementedInterfaces)
                    {
#if NET40
                        if (implInterface.IsGenericType && implInterface.GenericTypeArguments()[0] == typeof(T))
#else
                        if (implInterface.IsGenericType && implInterface.GenericTypeArguments[0] == typeof(T))
#endif
                        {
                            Formatter = (IMessagePackFormatter <T>)item;
                            return;
                        }
                    }
                }

                var resolvers = Volatile.Read(ref s_resolvers);
                foreach (var item in resolvers)
                {
                    var f = item.GetFormatter <T>();
                    if (f != null)
                    {
                        Formatter = f;
                        return;
                    }
                }

                {
                    var f = MessagePackStandardResolver.TypelessObjectResolver.GetFormatter <T>();
                    if (f != null)
                    {
                        Formatter = f;
                        return;
                    }
                }

                Formatter = ActivatorUtils.FastCreateInstance <IMessagePackFormatter <T> >(typeof(DynamicProxyFormatter <>).GetCachedGenericType(typeof(T)));
            }
        object CreateInstance(ProtoReader source, bool includeLocalCallback)
        {
            //Helpers.DebugWriteLine("* creating : " + forType.FullName);
            object obj;

            if (factory != null)
            {
                obj = InvokeCallback(factory, null, source.Context);
            }
            else if (useConstructor)
            {
                if (!hasConstructor)
                {
                    TypeModel.ThrowCannotCreateInstance(constructType);
                }
                // ## 苦竹 修改 ##
                //        obj = Activator.CreateInstance(constructType
                //#if !(CF || SILVERLIGHT || WINRT || PORTABLE || NETSTANDARD1_3 || NETSTANDARD1_4)
                //                    , nonPublic: true
                //#endif
                //                    );
                obj = ActivatorUtils.FastCreateInstance(constructType);
            }
            else
            {
                obj = BclHelpers.GetUninitializedObject(constructType);
            }
            ProtoReader.NoteObject(obj, source);
            if (baseCtorCallbacks != null)
            {
                for (int i = 0; i < baseCtorCallbacks.Length; i++)
                {
                    InvokeCallback(baseCtorCallbacks[i], obj, source.Context);
                }
            }
            if (includeLocalCallback && callbacks != null)
            {
                InvokeCallback(callbacks.BeforeDeserialize, obj, source.Context);
            }
            return(obj);
        }
Ejemplo n.º 7
0
        public override object Read(object untyped, ProtoReader source)
        {
            TDictionary typed = AppendToCollection ? ((TDictionary)untyped) : null;

            //if (typed == null) typed = (TDictionary)Activator.CreateInstance(concreteType);
            if (typed == null)
            {
                typed = (TDictionary)ActivatorUtils.FastCreateInstance(concreteType);
            }

            do
            {
                var          key   = DefaultKey;
                var          value = DefaultValue;
                SubItemToken token = ProtoReader.StartSubItem(source);
                int          field;
                while ((field = source.ReadFieldHeader()) > 0)
                {
                    switch (field)
                    {
                    case 1:
                        key = (TKey)keyTail.Read(null, source);
                        break;

                    case 2:
                        value = (TValue)Tail.Read(Tail.RequiresOldValue ? (object)value : null, source);
                        break;

                    default:
                        source.SkipField();
                        break;
                    }
                }

                ProtoReader.EndSubItem(token, source);
                typed[key] = value;
            } while (source.TryReadFieldHeader(fieldNumber));

            return(typed);
        }
Ejemplo n.º 8
0
        public static object ParseTuple(Type tupleType, StringSegment value)
        {
            var index = 0;

            Serializer.EatMapStartChar(value, ref index);
            if (JsonTypeSerializer.IsEmptyMap(value, index))
            {
                //return tupleType.CreateInstance();
                return(ActivatorUtils.FastCreateInstance(tupleType));
            }

            var genericArgs = tupleType.GetGenericArguments();
            var argValues   = new object[genericArgs.Length];
            var valueLength = value.Length;

            while (index < valueLength)
            {
                var keyValue = Serializer.EatMapKey(value, ref index);
                Serializer.EatMapKeySeperator(value, ref index);
                var elementValue = Serializer.EatValue(value, ref index);
                if (!keyValue.HasValue)
                {
                    continue;
                }

                var keyIndex = keyValue.Substring("Item".Length).ToInt() - 1;
                var parseFn  = Serializer.GetParseStringSegmentFn(genericArgs[keyIndex]);
                argValues[keyIndex] = parseFn(elementValue);

                Serializer.EatItemSeperatorOrMapEndChar(value, ref index);
            }

            var ctor = tupleType.GetConstructors()
                       .First(x => x.GetParameters().Length == genericArgs.Length);

            return(ctor.Invoke(argValues));
        }
        public static ICollection <T> CreateAndPopulate <T>(Type ofCollectionType, T[] withItems)
        {
            if (withItems == null)
            {
                return(null);
            }

            if (ofCollectionType == null)
            {
                return(new List <T>(withItems));
            }

            var genericType           = ofCollectionType.FirstGenericType();
            var genericTypeDefinition = genericType != null
                ? genericType.GetGenericTypeDefinition()
                : null;

            if (genericTypeDefinition == typeof(HashSet <>))
            {
                return(new HashSet <T>(withItems));
            }

            if (genericTypeDefinition == typeof(LinkedList <>))
            {
                return(new LinkedList <T>(withItems));
            }

            //var collection = (ICollection<T>)ofCollectionType.CreateInstance();
            var collection = ActivatorUtils.FastCreateInstance <ICollection <T> >(ofCollectionType);

            foreach (var item in withItems)
            {
                collection.Add(item);
            }
            return(collection);
        }
Ejemplo n.º 10
0
        public static Expression GetNewExpression(Type type)
        {
            if (type.IsValueType)
            {
                var x       = Expression.Constant(ActivatorUtils.FastCreateInstance(type));
                var convert = Expression.Convert(x, typeof(object));
                return(convert);
            }
//#if SERIALIZATION
            var defaultCtor        = type.GetConstructor(new Type[] { });
            var il                 = defaultCtor?.GetMethodBody()?.GetILAsByteArray();
            var sideEffectFreeCtor = il != null && il.Length <= 8; //this is the size of an empty ctor

            if (sideEffectFreeCtor)
            {
                //the ctor exists and the size is empty. lets use the New operator
                return(Expression.New(defaultCtor));
            }
//#endif
            var emptyObjectMethod = typeof(TypeEx).GetMethod(nameof(TypeEx.GetEmptyObject));
            var emptyObject       = Expression.Call(null, emptyObjectMethod, type.ToConstant());

            return(emptyObject);
        }
Ejemplo n.º 11
0
        internal static object StringToType(
            TypeConfig typeConfig,
            StringSegment strType,
            EmptyCtorDelegate ctorFn,
            Dictionary <HashedStringSegment, TypeAccessor> typeAccessorMap)
        {
            var index = 0;
            var type  = typeConfig.Type;

            if (!strType.HasValue)
            {
                return(null);
            }

            var buffer        = strType.Buffer;
            var offset        = strType.Offset;
            var strTypeLength = strType.Length;

            //if (!Serializer.EatMapStartChar(strType, ref index))
            for (; index < strTypeLength; index++)
            {
                if (!JsonUtils.IsWhiteSpace(buffer[offset + index]))
                {
                    break;
                }
            }                                                                                                      //Whitespace inline
            if (buffer[offset + index] != JsWriter.MapStartChar)
            {
                throw DeserializeTypeRef.CreateSerializationError(type, strType.Value);
            }

            index++;
            if (JsonTypeSerializer.IsEmptyMap(strType, index))
            {
                return(ctorFn());
            }

            object instance = null;

            var propertyResolver = JsConfig.PropertyConvention == PropertyConvention.Lenient
                ? ParseUtils.LenientPropertyNameResolver
                : ParseUtils.DefaultPropertyNameResolver;

            while (index < strTypeLength)
            {
                var propertyName = JsonTypeSerializer.ParseJsonString(strType, ref index);

                //Serializer.EatMapKeySeperator(strType, ref index);
                for (; index < strTypeLength; index++)
                {
                    if (!JsonUtils.IsWhiteSpace(buffer[offset + index]))
                    {
                        break;
                    }
                }                                                                                                      //Whitespace inline
                if (strTypeLength != index)
                {
                    index++;
                }

                var propertyValueStr = Serializer.EatValue(strType, ref index);
                var possibleTypeInfo = propertyValueStr != null && propertyValueStr.Length > 1;

                //if we already have an instance don't check type info, because then we will have a half deserialized object
                //we could throw here or just use the existing instance.
                if (instance == null && possibleTypeInfo && propertyName == typeAttr)
                {
                    var explicitTypeName = Serializer.ParseString(propertyValueStr);
                    var explicitType     = JsConfig.TypeFinder(explicitTypeName);

                    if (explicitType == null || explicitType.IsInterface || explicitType.IsAbstract)
                    {
                        Tracer.Instance.WriteWarning("Could not find type: " + propertyValueStr);
                    }
                    else if (!type.IsAssignableFrom(explicitType))
                    {
                        Tracer.Instance.WriteWarning("Could not assign type: " + propertyValueStr);
                    }
                    else
                    {
                        JsWriter.AssertAllowedRuntimeType(explicitType);
                        //instance = explicitType.CreateInstance();
                        instance = ActivatorUtils.FastCreateInstance(explicitType);
                    }

                    if (instance != null)
                    {
                        //If __type info doesn't match, ignore it.
                        if (!type.IsInstanceOfType(instance))
                        {
                            instance = null;
                        }
                        else
                        {
                            var derivedType = instance.GetType();
                            if (derivedType != type)
                            {
                                var derivedTypeConfig = new TypeConfig(derivedType);
                                var map = DeserializeTypeRef.GetTypeAccessorMap(derivedTypeConfig, Serializer);
                                if (map != null)
                                {
                                    typeAccessorMap = map;
                                }
                            }
                        }
                    }

                    Serializer.EatItemSeperatorOrMapEndChar(strType, ref index);
                    continue;
                }

                if (instance == null)
                {
                    instance = ctorFn();
                }

                var typeAccessor = propertyResolver.GetTypeAccessorForProperty(propertyName, typeAccessorMap);

                var propType = possibleTypeInfo && propertyValueStr.GetChar(0) == '_' ? TypeAccessor.ExtractType(Serializer, propertyValueStr) : null;
                if (propType != null)
                {
                    try
                    {
                        if (typeAccessor != null)
                        {
                            //var parseFn = Serializer.GetParseFn(propType);
                            var parseFn = JsonReader.GetParseStringSegmentFn(propType);

                            var propertyValue = parseFn(propertyValueStr);
                            if (typeConfig.OnDeserializing != null)
                            {
                                propertyValue = typeConfig.OnDeserializing(instance, propertyName.Value, propertyValue);
                            }
                            typeAccessor.SetProperty(instance, propertyValue);
                        }

                        //Serializer.EatItemSeperatorOrMapEndChar(strType, ref index);
                        for (; index < strTypeLength; index++)
                        {
                            if (!JsonUtils.IsWhiteSpace(buffer[offset + index]))
                            {
                                break;
                            }
                        }                                                                                                      //Whitespace inline
                        if (index != strTypeLength)
                        {
                            var success = buffer[offset + index] == JsWriter.ItemSeperator || buffer[offset + index] == JsWriter.MapEndChar;
                            index++;
                            if (success)
                            {
                                for (; index < strTypeLength; index++)
                                {
                                    if (!JsonUtils.IsWhiteSpace(buffer[offset + index]))
                                    {
                                        break;
                                    }
                                }                                                                                                      //Whitespace inline
                            }
                        }

                        continue;
                    }
                    catch (Exception e)
                    {
                        if (JsConfig.OnDeserializationError != null)
                        {
                            JsConfig.OnDeserializationError(instance, propType, propertyName.Value, propertyValueStr.Value, e);
                        }
                        if (JsConfig.ThrowOnError)
                        {
                            throw DeserializeTypeRef.GetSerializationException(propertyName.Value, propertyValueStr.Value, propType, e);
                        }
                        else
                        {
                            Tracer.Instance.WriteWarning("WARN: failed to set dynamic property {0} with: {1}", propertyName, propertyValueStr.Value);
                        }
                    }
                }

                if (typeAccessor?.GetProperty != null && typeAccessor.SetProperty != null)
                {
                    try
                    {
                        var propertyValue = typeAccessor.GetProperty(propertyValueStr);
                        if (typeConfig.OnDeserializing != null)
                        {
                            propertyValue = typeConfig.OnDeserializing(instance, propertyName.Value, propertyValue);
                        }
                        typeAccessor.SetProperty(instance, propertyValue);
                    }
                    catch (NotSupportedException) { throw; }
                    catch (Exception e)
                    {
                        if (JsConfig.OnDeserializationError != null)
                        {
                            JsConfig.OnDeserializationError(instance, propType ?? typeAccessor.PropertyType, propertyName.Value, propertyValueStr.Value, e);
                        }
                        if (JsConfig.ThrowOnError)
                        {
                            throw DeserializeTypeRef.GetSerializationException(propertyName.Value, propertyValueStr.Value, typeAccessor.PropertyType, e);
                        }
                        else
                        {
                            Tracer.Instance.WriteWarning("WARN: failed to set property {0} with: {1}", propertyName, propertyValueStr.Value);
                        }
                    }
                }
                else
                {
                    // the property is not known by the DTO
                    typeConfig.OnDeserializing?.Invoke(instance, propertyName.Value, propertyValueStr.Value);
                }

                //Serializer.EatItemSeperatorOrMapEndChar(strType, ref index);
                for (; index < strTypeLength; index++)
                {
                    if (!JsonUtils.IsWhiteSpace(buffer[offset + index]))
                    {
                        break;
                    }
                }                                                                                                      //Whitespace inline
                if (index != strType.Length)
                {
                    var success = buffer[offset + index] == JsWriter.ItemSeperator || buffer[offset + index] == JsWriter.MapEndChar;
                    index++;
                    if (success)
                    {
                        for (; index < strTypeLength; index++)
                        {
                            if (!JsonUtils.IsWhiteSpace(buffer[offset + index]))
                            {
                                break;
                            }
                        }                                                                                                      //Whitespace inline
                    }
                }
            }

            return(instance);
        }
        public override ValueSerializer BuildSerializer(Serializer serializer, Type type,
                                                        CachedReadConcurrentDictionary <Type, ValueSerializer> typeMapping)
        {
            var exceptionSerializer = new ObjectSerializer(type);

            exceptionSerializer.Initialize((stream, session) =>
            {
                var exception         = ActivatorUtils.FastCreateInstance(type);
                var sessionSerializer = session.Serializer;
                if (sessionSerializer.Options.PreserveObjectReferences)
                {
                    session.TrackDeserializedObject(exception);
                }

                var fields = s_filedCache.GetOrAdd(type, s_getFieldsFunc);
                foreach (var(field, getter, setter) in fields)
                {
                    var fieldType = field.FieldType;
                    object fieldValue;
                    if (!sessionSerializer.Options.VersionTolerance && fieldType.IsHyperionPrimitive())
                    {
                        var valueSerializer = sessionSerializer.GetSerializerByType(fieldType);
                        fieldValue          = valueSerializer.ReadValue(stream, session);
                    }
                    else
                    {
                        var valueType = fieldType;
                        if (fieldType.IsNullableType())
                        {
                            valueType = Nullable.GetUnderlyingType(fieldType);
                        }
                        var valueSerializer = sessionSerializer.GetSerializerByType(valueType);
                        fieldValue          = stream.ReadObject(session);
                    }
                    setter(exception, fieldValue);
                }

                return(exception);
            }, (stream, exception, session) =>
            {
                var sessionSerializer = session.Serializer;
                if (sessionSerializer.Options.PreserveObjectReferences)
                {
                    session.TrackSerializedObject(exception);
                }
                var fields = s_filedCache.GetOrAdd(type, s_getFieldsFunc);
                foreach (var(field, getter, setter) in fields)
                {
                    var fieldType = field.FieldType;
                    var v         = getter(exception);
                    //if the type is one of our special primitives, ignore manifest as the content will always only be of this type
                    if (!sessionSerializer.Options.VersionTolerance && fieldType.IsHyperionPrimitive())
                    {
                        var valueSerializer = sessionSerializer.GetSerializerByType(fieldType);
                        valueSerializer.WriteValue(stream, v, session);
                    }
                    else
                    {
                        var valueType = fieldType;
                        if (fieldType.IsNullableType())
                        {
                            valueType = Nullable.GetUnderlyingType(fieldType);
                        }
                        var valueSerializer = sessionSerializer.GetSerializerByType(valueType);
                        stream.WriteObject(v, valueType, valueSerializer, true, session);
                    }
                }
            });
            typeMapping.TryAdd(type, exceptionSerializer);
            return(exceptionSerializer);
        }
        internal static object StringToType(ReadOnlySpan <char> strType,
                                            TypeConfig typeConfig,
                                            EmptyCtorDelegate ctorFn,
                                            KeyValuePair <string, TypeAccessor>[] typeAccessors)
        {
            var index = 0;
            var type  = typeConfig.Type;

            if (strType.IsEmpty)
            {
                return(null);
            }

            //if (!Serializer.EatMapStartChar(strType, ref index))
            if (strType[index++] != JsWriter.MapStartChar)
            {
                throw DeserializeTypeRef.CreateSerializationError(type, strType.ToString());
            }

            if (JsonTypeSerializer.IsEmptyMap(strType))
            {
                return(ctorFn());
            }

            var config = JsConfig.GetConfig();

            object instance = null;
            var    lenient  = config.PropertyConvention == PropertyConvention.Lenient;

            var strTypeLength = strType.Length;

            while (index < strTypeLength)
            {
                var propertyName = Serializer.EatMapKey(strType, ref index).Trim();

                //Serializer.EatMapKeySeperator(strType, ref index);
                index++;

                var propertyValueStr = Serializer.EatValue(strType, ref index);
                var possibleTypeInfo = propertyValueStr != null && propertyValueStr.Length > 1;

                if (possibleTypeInfo && propertyName.Equals(typeAttr.Span, StringComparison.OrdinalIgnoreCase))
                {
                    var explicitTypeName = Serializer.ParseString(propertyValueStr);
                    var explicitType     = config.TypeFinder(explicitTypeName);

                    if (explicitType == null || explicitType.IsInterface || explicitType.IsAbstract)
                    {
                        Tracer.Instance.WriteWarning("Could not find type: " + propertyValueStr.ToString());
                    }
                    else if (!type.IsAssignableFrom(explicitType))
                    {
                        Tracer.Instance.WriteWarning("Could not assign type: " + propertyValueStr.ToString());
                    }
                    else
                    {
                        JsWriter.AssertAllowedRuntimeType(explicitType);
                        instance = ActivatorUtils.FastCreateInstance(explicitType);
                    }

                    if (instance != null)
                    {
                        //If __type info doesn't match, ignore it.
                        if (!type.IsInstanceOfType(instance))
                        {
                            instance = null;
                        }
                        else
                        {
                            var derivedType = instance.GetType();
                            if (derivedType != type)
                            {
                                var map = DeserializeTypeRef.GetCachedTypeAccessors(derivedType, Serializer);
                                if (map != null)
                                {
                                    typeAccessors = map;
                                }
                            }
                        }
                    }

                    //Serializer.EatItemSeperatorOrMapEndChar(strType, ref index);
                    if (index != strType.Length)
                    {
                        index++;
                    }

                    continue;
                }

                if (instance == null)
                {
                    instance = ctorFn();
                }

                var typeAccessor = typeAccessors.Get(propertyName, lenient);

                var propType = possibleTypeInfo && propertyValueStr[0] == '_' ? TypeAccessor.ExtractType(Serializer, propertyValueStr) : null;
                if (propType != null)
                {
                    try
                    {
                        if (typeAccessor != null)
                        {
                            var parseFn       = Serializer.GetParseStringSpanFn(propType);
                            var propertyValue = parseFn(propertyValueStr);
                            if (typeConfig.OnDeserializing != null)
                            {
                                propertyValue = typeConfig.OnDeserializing(instance, propertyName.ToString(), propertyValue);
                            }
                            typeAccessor.SetProperty(instance, propertyValue);
                        }

                        //Serializer.EatItemSeperatorOrMapEndChar(strType, ref index);
                        if (index != strType.Length)
                        {
                            index++;
                        }

                        continue;
                    }
                    catch (Exception e)
                    {
                        config.OnDeserializationError?.Invoke(instance, propType, propertyName.ToString(), propertyValueStr.ToString(), e);
                        if (config.ThrowOnError)
                        {
                            throw DeserializeTypeRef.GetSerializationException(propertyName.ToString(), propertyValueStr.ToString(), propType, e);
                        }
                        else
                        {
                            Tracer.Instance.WriteWarning("WARN: failed to set dynamic property {0} with: {1}", propertyName.ToString(), propertyValueStr.ToString());
                        }
                    }
                }

                if (typeAccessor?.GetProperty != null && typeAccessor.SetProperty != null)
                {
                    try
                    {
                        var propertyValue = typeAccessor.GetProperty(propertyValueStr);
                        if (typeConfig.OnDeserializing != null)
                        {
                            propertyValue = typeConfig.OnDeserializing(instance, propertyName.ToString(), propertyValue);
                        }
                        typeAccessor.SetProperty(instance, propertyValue);
                    }
                    catch (NotSupportedException) { throw; }
                    catch (Exception e)
                    {
                        config.OnDeserializationError?.Invoke(instance, propType ?? typeAccessor.PropertyType, propertyName.ToString(), propertyValueStr.ToString(), e);
                        if (config.ThrowOnError)
                        {
                            throw DeserializeTypeRef.GetSerializationException(propertyName.ToString(), propertyValueStr.ToString(), propType, e);
                        }
                        else
                        {
                            Tracer.Instance.WriteWarning("WARN: failed to set property {0} with: {1}", propertyName.ToString(), propertyValueStr.ToString());
                        }
                    }
                }
                else
                {
                    // the property is not known by the DTO
                    typeConfig.OnDeserializing?.Invoke(instance, propertyName.ToString(), propertyValueStr.ToString());
                }

                //Serializer.EatItemSeperatorOrMapEndChar(strType, ref index);
                if (index != strType.Length)
                {
                    index++;
                }
            }

            return(instance);
        }
 static object CreateInstance(Type genericType, params Type[] genericTypeArguments)
 {
     return(ActivatorUtils.FastCreateInstance(genericType.GetCachedGenericType(genericTypeArguments)));
 }
Ejemplo n.º 15
0
        //public static bool IsHyperionPrimitive(this Type type)
        //{
        //  return type == Int32Type ||
        //         type == Int64Type ||
        //         type == Int16Type ||
        //         type == UInt32Type ||
        //         type == UInt64Type ||
        //         type == UInt16Type ||
        //         type == ByteType ||
        //         type == SByteType ||
        //         type == DateTimeType ||
        //         type == BoolType ||
        //         type == StringType ||
        //         type == GuidType ||
        //         type == CombGuidType ||
        //         type == FloatType ||
        //         type == DoubleType ||
        //         type == DecimalType ||
        //         type == CharType;
        //  //add TypeSerializer with null support
        //}

        //#if !SERIALIZATION
        //    //HACK: the GetUnitializedObject actually exists in .NET Core, its just not public
        //        private static readonly Func<Type, object> getUninitializedObjectDelegate = (Func<Type, object>)
        //            typeof(string)
        //                .GetTypeInfo()
        //                .Assembly
        //                .GetType("System.Runtime.Serialization.FormatterServices")
        //                ?.GetTypeInfo()
        //                ?.GetMethod("GetUninitializedObject", BindingFlags.NonPublic | BindingFlags.Public | BindingFlags.Static)
        //                ?.CreateDelegate(typeof(Func<Type, object>));

        //        public static object GetEmptyObject(this Type type)
        //        {
        //            return getUninitializedObjectDelegate(type);
        //        }
        //#else
        public static object GetEmptyObject(this Type type)
        {
            //return FormatterServices.GetUninitializedObject(type);
            return(ActivatorUtils.FastCreateInstance(type));
        }
        // Reduce IL2CPP code generate size(don't write long code in <T>)
        internal static object GetFormatter(Type t)
        {
            var ti = t.GetTypeInfo();

            if (t.IsArray)
            {
                var rank = t.GetArrayRank();
                if (rank == 1)
                {
                    if (t.GetElementType() == typeof(byte)) // byte[] is also supported in builtin formatter.
                    {
                        return(ByteArrayFormatter.Instance);
                    }

                    return(ActivatorUtils.FastCreateInstance(typeof(ArrayFormatter <>).GetCachedGenericType(t.GetElementType())));
                }
                else if (rank == 2)
                {
                    return(ActivatorUtils.FastCreateInstance(typeof(TwoDimentionalArrayFormatter <>).GetCachedGenericType(t.GetElementType())));
                }
                else if (rank == 3)
                {
                    return(ActivatorUtils.FastCreateInstance(typeof(ThreeDimentionalArrayFormatter <>).GetCachedGenericType(t.GetElementType())));
                }
                else if (rank == 4)
                {
                    return(ActivatorUtils.FastCreateInstance(typeof(FourDimentionalArrayFormatter <>).GetCachedGenericType(t.GetElementType())));
                }
                else
                {
                    return(null); // not supported built-in
                }
            }
            else if (t.IsGenericType)
            {
                var genericType          = t.GetGenericTypeDefinition();
                var isNullable           = genericType.IsNullable();
                var genericTypeArguments = t.GenericTypeArguments;
                var nullableElementType  = isNullable ? genericTypeArguments[0] : null;

                const string _systemTupleType      = "System.Tuple";
                const string _systemValueTupleType = "System.ValueTuple";

                if (genericType == typeof(KeyValuePair <,>))
                {
                    return(CreateInstance(typeof(KeyValuePairFormatter <,>), genericTypeArguments));
                }
                else if (isNullable && nullableElementType.IsConstructedGenericType && nullableElementType.GetGenericTypeDefinition() == typeof(KeyValuePair <,>))
                {
                    return(CreateInstance(typeof(NullableFormatter <>), new[] { nullableElementType }));
                }

                // ValueTask
                else if (genericType == typeof(ValueTask <>))
                {
                    return(CreateInstance(typeof(ValueTaskFormatter <>), genericTypeArguments));
                }
                else if (isNullable && nullableElementType.IsConstructedGenericType && nullableElementType.GetGenericTypeDefinition() == typeof(ValueTask <>))
                {
                    return(CreateInstance(typeof(NullableFormatter <>), new[] { nullableElementType }));
                }

                // Tuple
                else if (t.FullName.StartsWith(_systemTupleType, StringComparison.Ordinal))
                {
                    Type tupleFormatterType = null;
                    switch (genericTypeArguments.Length)
                    {
                    case 1:
                        tupleFormatterType = typeof(TupleFormatter <>);
                        break;

                    case 2:
                        tupleFormatterType = typeof(TupleFormatter <,>);
                        break;

                    case 3:
                        tupleFormatterType = typeof(TupleFormatter <, ,>);
                        break;

                    case 4:
                        tupleFormatterType = typeof(TupleFormatter <, , ,>);
                        break;

                    case 5:
                        tupleFormatterType = typeof(TupleFormatter <, , , ,>);
                        break;

                    case 6:
                        tupleFormatterType = typeof(TupleFormatter <, , , , ,>);
                        break;

                    case 7:
                        tupleFormatterType = typeof(TupleFormatter <, , , , , ,>);
                        break;

                    case 8:
                        tupleFormatterType = typeof(TupleFormatter <, , , , , , ,>);
                        break;

                    default:
                        break;
                    }

                    return(CreateInstance(tupleFormatterType, genericTypeArguments));
                }

                // ValueTuple
                else if (t.FullName.StartsWith(_systemValueTupleType, StringComparison.Ordinal))
                {
                    Type tupleFormatterType = null;
                    switch (genericTypeArguments.Length)
                    {
                    case 1:
                        tupleFormatterType = typeof(ValueTupleFormatter <>);
                        break;

                    case 2:
                        tupleFormatterType = typeof(ValueTupleFormatter <,>);
                        break;

                    case 3:
                        tupleFormatterType = typeof(ValueTupleFormatter <, ,>);
                        break;

                    case 4:
                        tupleFormatterType = typeof(ValueTupleFormatter <, , ,>);
                        break;

                    case 5:
                        tupleFormatterType = typeof(ValueTupleFormatter <, , , ,>);
                        break;

                    case 6:
                        tupleFormatterType = typeof(ValueTupleFormatter <, , , , ,>);
                        break;

                    case 7:
                        tupleFormatterType = typeof(ValueTupleFormatter <, , , , , ,>);
                        break;

                    case 8:
                        tupleFormatterType = typeof(ValueTupleFormatter <, , , , , , ,>);
                        break;

                    default:
                        break;
                    }

                    return(CreateInstance(tupleFormatterType, genericTypeArguments));
                }

                // ArraySegement
                else if (genericType == typeof(ArraySegment <>))
                {
                    if (genericTypeArguments[0] == typeof(byte))
                    {
                        return(ByteArraySegmentFormatter.Instance);
                    }
                    else
                    {
                        return(CreateInstance(typeof(ArraySegmentFormatter <>), genericTypeArguments));
                    }
                }
                else if (isNullable && nullableElementType.IsConstructedGenericType && nullableElementType.GetGenericTypeDefinition() == typeof(ArraySegment <>))
                {
                    if (nullableElementType == typeof(ArraySegment <byte>))
                    {
                        return(new StaticNullableFormatter <ArraySegment <byte> >(ByteArraySegmentFormatter.Instance));
                    }
                    else
                    {
                        return(CreateInstance(typeof(NullableFormatter <>), new[] { nullableElementType }));
                    }
                }

                // Mapped formatter
                else
                {
                    Type formatterType;
                    if (formatterMap.TryGetValue(genericType, out formatterType))
                    {
                        return(CreateInstance(formatterType, genericTypeArguments));
                    }

                    // generic collection
                    else if (genericTypeArguments.Length == 1 &&
                             ti.ImplementedInterfaces.Any(x => x.IsConstructedGenericType && x.GetGenericTypeDefinition() == typeof(ICollection <>)) &&
                             ti.DeclaredConstructors.Any(x => 0u >= (uint)x.GetParameters().Length))
                    {
                        var elemType = genericTypeArguments[0];
                        return(CreateInstance(typeof(GenericCollectionFormatter <,>), new[] { elemType, t }));
                    }
                    // generic dictionary
                    else if (genericTypeArguments.Length == 2 &&
                             ti.ImplementedInterfaces.Any(x => x.IsConstructedGenericType && x.GetGenericTypeDefinition() == typeof(IDictionary <,>)) &&
                             ti.DeclaredConstructors.Any(x => 0u >= (uint)x.GetParameters().Length))
                    {
                        var keyType   = genericTypeArguments[0];
                        var valueType = genericTypeArguments[1];
                        return(CreateInstance(typeof(GenericDictionaryFormatter <, ,>), new[] { keyType, valueType, t }));
                    }

                    if (typeof(Delegate).IsAssignableFrom(t))
                    {
                        return(ActivatorUtils.FastCreateInstance(typeof(DelegateFormatter <>).GetCachedGenericType(t)));
                    }
                    if (typeof(Exception).IsAssignableFrom(t))
                    {
                        return(ActivatorUtils.FastCreateInstance(typeof(SimpleExceptionFormatter <>).GetCachedGenericType(t)));
                    }
                    if (typeof(Expression).IsAssignableFrom(t))
                    {
                        return(ActivatorUtils.FastCreateInstance(typeof(SimpleExpressionFormatter <>).GetCachedGenericType(t)));
                    }
                    if (typeof(SymbolDocumentInfo).IsAssignableFrom(t))
                    {
                        return(ActivatorUtils.FastCreateInstance(typeof(SymbolDocumentInfoFormatter <>).GetCachedGenericType(t)));
                    }
                    if (typeof(MemberBinding).IsAssignableFrom(t))
                    {
                        return(ActivatorUtils.FastCreateInstance(typeof(MemberBindingFormatter <>).GetCachedGenericType(t)));
                    }
                }
            }
            else
            {
                // NonGeneric Collection
                if (t == typeof(IList))
                {
                    return(NonGenericInterfaceListFormatter.Instance);
                }
                else if (t == typeof(IDictionary))
                {
                    return(NonGenericInterfaceDictionaryFormatter.Instance);
                }
                if (typeof(IList).IsAssignableFrom(t) && ti.DeclaredConstructors.Any(x => 0u >= (uint)x.GetParameters().Length))
                {
                    return(ActivatorUtils.FastCreateInstance(typeof(NonGenericListFormatter <>).GetCachedGenericType(t)));
                }
                else if (typeof(IDictionary).IsAssignableFrom(t) && ti.DeclaredConstructors.Any(x => 0u >= (uint)x.GetParameters().Length))
                {
                    return(ActivatorUtils.FastCreateInstance(typeof(NonGenericDictionaryFormatter <>).GetCachedGenericType(t)));
                }

                if (typeof(Type).IsAssignableFrom(t))
                {
                    return(ActivatorUtils.FastCreateInstance(typeof(SimpleTypeFormatter <>).GetCachedGenericType(t)));
                }
                if (typeof(ConstructorInfo).IsAssignableFrom(t))
                {
                    return(ActivatorUtils.FastCreateInstance(typeof(ConstructorInfoFormatter <>).GetCachedGenericType(t)));
                }
                if (typeof(EventInfo).IsAssignableFrom(t))
                {
                    return(ActivatorUtils.FastCreateInstance(typeof(EventInfoFormatter <>).GetCachedGenericType(t)));
                }
                if (typeof(FieldInfo).IsAssignableFrom(t))
                {
                    return(ActivatorUtils.FastCreateInstance(typeof(FieldInfoFormatter <>).GetCachedGenericType(t)));
                }
                if (typeof(PropertyInfo).IsAssignableFrom(t))
                {
                    return(ActivatorUtils.FastCreateInstance(typeof(PropertyInfoFormatter <>).GetCachedGenericType(t)));
                }
                if (typeof(MethodInfo).IsAssignableFrom(t))
                {
                    return(ActivatorUtils.FastCreateInstance(typeof(MethodInfoFormatter <>).GetCachedGenericType(t)));
                }
                if (typeof(MemberInfo).IsAssignableFrom(t)) // 是否无用
                {
                    return(ActivatorUtils.FastCreateInstance(typeof(MemberInfoFormatter <>).GetCachedGenericType(t)));
                }
                if (typeof(Delegate).IsAssignableFrom(t))
                {
                    return(ActivatorUtils.FastCreateInstance(typeof(DelegateFormatter <>).GetCachedGenericType(t)));
                }
                if (typeof(Exception).IsAssignableFrom(t))
                {
                    return(ActivatorUtils.FastCreateInstance(typeof(SimpleExceptionFormatter <>).GetCachedGenericType(t)));
                }
                if (typeof(Expression).IsAssignableFrom(t))
                {
                    return(ActivatorUtils.FastCreateInstance(typeof(SimpleExpressionFormatter <>).GetCachedGenericType(t)));
                }
                if (typeof(SymbolDocumentInfo).IsAssignableFrom(t))
                {
                    return(ActivatorUtils.FastCreateInstance(typeof(SymbolDocumentInfoFormatter <>).GetCachedGenericType(t)));
                }
                if (typeof(MemberBinding).IsAssignableFrom(t))
                {
                    return(ActivatorUtils.FastCreateInstance(typeof(MemberBindingFormatter <>).GetCachedGenericType(t)));
                }
            }

            return(null);
        }
Ejemplo n.º 17
0
        public static IDictionary <TKey, TValue> ParseDictionary <TKey, TValue>(
            StringSegment value, Type createMapType,
            ParseStringSegmentDelegate parseKeyFn, ParseStringSegmentDelegate parseValueFn)
        {
            if (!value.HasValue)
            {
                return(null);
            }

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

            var index = VerifyAndGetStartIndex(value, createMapType);

            var to = (createMapType == null)
                ? new Dictionary <TKey, TValue>()
                : ActivatorUtils.FastCreateInstance <IDictionary <TKey, TValue> >(createMapType); //(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.HasValue)
                {
                    continue;
                }

                TKey mapKey = (TKey)parseKeyFn(keyValue);

                if (tryToParseItemsAsDictionaries)
                {
                    Serializer.EatWhitespace(value, ref elementStartIndex);
                    if (elementStartIndex < valueLength && value.GetChar(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.GetChar(elementStartIndex) == JsWriter.ListStartChar)
                    {
                        to[mapKey] = (TValue)DeserializeList <List <object>, TSerializer> .ParseStringSegment(elementValue);
                    }
                    else
                    {
                        to[mapKey] = (TValue)(tryToParseItemsAsPrimitiveTypes && elementStartIndex < valueLength
                                        ? DeserializeType <TSerializer> .ParsePrimitive(elementValue.Value, value.GetChar(elementStartIndex))
                                        : parseValueFn(elementValue));
                    }
                }
                else
                {
                    if (tryToParseItemsAsPrimitiveTypes && elementStartIndex < valueLength)
                    {
                        Serializer.EatWhitespace(value, ref elementStartIndex);
                        to[mapKey] = (TValue)DeserializeType <TSerializer> .ParsePrimitive(elementValue.Value, value.GetChar(elementStartIndex));
                    }
                    else
                    {
                        to[mapKey] = (TValue)parseValueFn(elementValue);
                    }
                }

                Serializer.EatItemSeperatorOrMapEndChar(value, ref index);
            }

            return(to);
        }
Ejemplo n.º 18
0
        public static T ConvertTo <T>(this object from)
        {
            if (from == null)
            {
                return(default(T));
            }

            var fromType = from.GetType();

            if (fromType == typeof(T))
            {
                return((T)from);
            }

            if (fromType.IsValueType || typeof(T).IsValueType)
            {
                if (!fromType.IsEnum && !typeof(T).IsEnum)
                {
                    if (typeof(T) == typeof(char) && from is string s)
                    {
                        return((T)(s.Length > 0 ? (object)s[0] : null));
                    }
                    if (typeof(T) == typeof(string) && from is char c)
                    {
                        return((T)(object)c.ToString());
                    }

                    var destNumberType = DynamicNumber.GetNumber(typeof(T));
                    var value          = destNumberType?.ConvertFrom(from);
                    if (value != null)
                    {
                        if (typeof(T) == typeof(char))
                        {
                            return((T)(object)value.ToString()[0]);
                        }

                        return((T)value);
                    }

                    if (typeof(T) == typeof(string))
                    {
                        var srcNumberType = DynamicNumber.GetNumber(from.GetType());
                        if (srcNumberType != null)
                        {
                            return((T)(object)srcNumberType.ToString(from));
                        }
                    }
                }

                return((T)ChangeValueType(from, typeof(T)));
            }

            if (typeof(IEnumerable).IsAssignableFrom(typeof(T)))
            {
                var listResult = TranslateListWithElements.TryTranslateCollections(
                    fromType, typeof(T), from);

                return((T)listResult);
            }

            var to = ActivatorUtils.FastCreateInstance <T>();// typeof(T).CreateInstance<T>();

            return(to.PopulateWith(from));
        }