Beispiel #1
0
        object ReadObject(ReflectType ts, ulong oid, object possibleValue)
        {
            Func <object, object> RETURN_REGISTER = (value) =>
            {
                // register everything, value types might have been written as objects!
                if (oid > 0)
                {
                    Context.Register(oid, value);
                }
                return(value);
            };

            switch (ts.Kind)
            {
            default:
            case PrimitiveType.Object:
            {
                if (ts.IsArray)
                {
                    var ranks = Enumerable.Range(0, ts.ArrayRank).Select(x => (int)Reader.ReadVInt()).ToArray();
                    var array = Array.CreateInstance(ts.Element.Type ?? typeof(Missing), ranks);
                    if (oid != 0)
                    {
                        Context.Register(oid, array);
                    }
                    if (ranks.All(x => x > 0))
                    {
                        var indices = new int[ranks.Length];
                        do
                        {
                            var value = Read(ts.Element, null);
                            array.SetValue(value, indices);
                        }while (Inc(indices, ranks));
                    }
                    return(array);
                }
                else if (ts.IsNullable)
                {
                    object o       = null;
                    var    isThere = Reader.ReadBool();
                    if (isThere)
                    {
                        o = Read(ts.GenericArguments[0], null);
                    }
                    if (oid != 0)
                    {
                        Context.Register(oid, o);
                    }
                    return(o);
                }
                else if (ts.IsEnum)
                {
                    var eoVal = Read(ts.Element, null);
                    var eVal  = ts.Type != null?Enum.ToObject(ts.Type, eoVal) : eoVal;

                    if (oid != 0)
                    {
                        Context.Register(oid, eVal);
                    }
                    return(eVal);
                }
                else
                {
                    object o = null;
                    if (ts.Type == null)
                    {
                        var missing = new Missing(ts);
                        o = missing;
                        if (oid != 0)
                        {
                            Context.Register(oid, missing);
                        }
                        foreach (var p in ts.Members)
                        {
                            var value = Read(p.Type, null);
                            missing.Members[p.Name].Value = value;
                        }
                        var colt = ts.CollectionInterface;
                        switch (colt.CollectionType)
                        {
                        case ReflectCollectionType.IList:
                        case ReflectCollectionType.ICollectionT:
                        {
                            var list = new List <Tuple <object, object> >();
                            missing.Collection = list;
                            var N    = (int)Reader.ReadVInt();
                            var coll = colt.Collection1 ?? ReflectType.RObject;
                            for (int i = 0; i < N; i++)
                            {
                                var value = Read(coll, null);
                                list.Add(Tuple.Create <object, object>(value, null));
                            }
                        }
                        break;

                        case ReflectCollectionType.IDictionary:
                        case ReflectCollectionType.IDictionaryKV:
                        {
                            var list = new List <Tuple <object, object> >();
                            missing.Collection = list;
                            var N     = (int)Reader.ReadVInt();
                            var coll1 = colt.Collection1 ?? ReflectType.RObject;
                            var coll2 = colt.Collection2 ?? ReflectType.RObject;
                            for (int i = 0; i < N; i++)
                            {
                                var key   = Read(coll1, null);
                                var value = Read(coll2, null);
                                list.Add(Tuple.Create <object, object>(key, value));
                            }
                        }
                        break;
                        }
                        return(o);
                    }
                    else
                    {
                        o = possibleValue ?? ts.FastType.TryConstruct();
                        if (oid != 0)
                        {
                            Context.Register(oid, o);
                        }
                        foreach (var m in ts.RuntimeMembers)
                        {
                            if (m.RuntimeMember == null || !m.RuntimeMember.TryFastReadSet(this.Reader, o))
                            {
                                object org = null;
                                if (m.Type.IsReference)
                                {
                                    org = m.RuntimeMember?.GetValue(o);
                                }
                                var value = Read(m.Type, org);
                                m.RuntimeMember?.SetValue(o, value);
                            }
                        }

                        var colt = ts.CollectionInterface;
                        switch (colt.CollectionType)
                        {
                        case ReflectCollectionType.IList:
                            ReadList((IList)o);
                            break;

                        case ReflectCollectionType.IDictionary:
                            ReadDict((IDictionary)o);
                            break;

                        case ReflectCollectionType.ICollectionT:
                            if (colt.listRead == null)
                            {
                                colt.listRead = FastMethod.GetMethod(GetType().TryGetMethods("ReadCollectionT", new[] { colt.Collection1.Type }, ts.Type, typeof(ReflectType)).First());
                            }
                            if (colt.listRead != null)
                            {
                                colt.listRead.Invoke(this, o, colt.Collection1);
                            }
                            break;

                        case ReflectCollectionType.IDictionaryKV:
                            if (colt.listRead == null)
                            {
                                colt.listRead = FastMethod.GetMethod(GetType().TryGetMethods("ReadDictKV", new[] { colt.Collection1.Type, colt.Collection2.Type }, ts.Type, typeof(ReflectType), typeof(ReflectType)).First());
                            }
                            if (colt.listRead != null)
                            {
                                colt.listRead.Invoke(this, o, colt.Collection1, colt.Collection2);
                            }
                            break;
                        }
                    }
                    return(o);
                }
            }

            case PrimitiveType.String:
                return(RETURN_REGISTER(this.Reader.ReadString()));

            case PrimitiveType.Bytes:
                return(RETURN_REGISTER(this.Reader.ReadBytes()));

            case PrimitiveType.Guid:
                return(RETURN_REGISTER(this.Reader.ReadGuid()));

            case PrimitiveType.Bool:
                return(RETURN_REGISTER(this.Reader.ReadBool()));

            case PrimitiveType.Char:
                return(RETURN_REGISTER(this.Reader.ReadChar()));

            case PrimitiveType.Byte:
                return(RETURN_REGISTER(this.Reader.ReadByte()));

            case PrimitiveType.SByte:
                return(RETURN_REGISTER(this.Reader.ReadSByte()));

            case PrimitiveType.Int16:
                return(RETURN_REGISTER(this.Reader.ReadInt16()));

            case PrimitiveType.UInt16:
                return(RETURN_REGISTER(this.Reader.ReadUInt16()));

            case PrimitiveType.Int32:
                return(RETURN_REGISTER(this.Reader.ReadInt32()));

            case PrimitiveType.UInt32:
                return(RETURN_REGISTER(this.Reader.ReadUInt32()));

            case PrimitiveType.Int64:
                return(RETURN_REGISTER(this.Reader.ReadInt64()));

            case PrimitiveType.UInt64:
                return(RETURN_REGISTER(this.Reader.ReadUInt64()));

            case PrimitiveType.Single:
                return(RETURN_REGISTER(this.Reader.ReadSingle()));

            case PrimitiveType.Double:
                return(RETURN_REGISTER(this.Reader.ReadDouble()));

            case PrimitiveType.Decimal:
                return(RETURN_REGISTER(this.Reader.ReadDecimal()));
            }
        }
Beispiel #2
0
        object ReadISerializable(ReflectType ts, ulong oid, object possibleValue)
        {
#if __PCL__
            throw new PlatformNotSupportedException("PCL");
#elif __NETCORE__
            var missing = new Missing(ts);
            var list    = new List <Tuple <object, object> >();
            missing.Collection = list;
            var N = Reader.ReadVInt();
            for (int i = 0; i < N; i++)
            {
                var s = (string)Read(ReflectType.RString, null);
                var o = Read(ReflectType.RObject, null);
                list.Add(Tuple.Create <object, object>(s, o));
            }
            if (ts.Type != null)
            {
                return(possibleValue);
            }
            return(missing);
#else
            var info = new SRS.SerializationInfo(typeof(object), new SRS.FormatterConverter());
            var ctx  = new SRS.StreamingContext(SRS.StreamingContextStates.Persistence);
            var N    = (int)Reader.ReadVInt();
            for (int i = 0; i < N; i++)
            {
                var s = (string)Read(ReflectType.RString, null);
                var o = Read(ReflectType.RObject, null);
                info.AddValue(s, o);
            }
            if (ts.Type != null)
            {
                if (possibleValue != null && ts.Type.IsInstanceOf(possibleValue))
                {
                    var ctor = ts.Type.TryGetConstructors(info.GetType(), ctx.GetType()).FirstOrDefault();
                    // No FastMethod(): couldn't manage to call constructor on existing instance
                    if (ctor != null)
                    {
                        ctor.Invoke(possibleValue, new object[] { info, ctx }); // Dare to do it! Call constructor on existing instance!!
                    }
                    if (oid > 0)
                    {
                        Context.Register(oid, possibleValue);
                    }
                    return(possibleValue);
                }
                var o = ts.Type.TryConstruct(info, ctx) ?? ts.FastType.TryConstruct();
                if (oid > 0)
                {
                    Context.Register(oid, o);
                }
                return(o);
            }
            var missing = new Missing(ts);
            if (oid > 0)
            {
                Context.Register(oid, missing);
            }
            var list = new List <Tuple <object, object> >();
            missing.Collection = list;
            foreach (var kv in info)
            {
                list.Add(Tuple.Create <object, object>(kv.Name, kv.Value));
            }
            return(missing);
#endif
        }