private static void FillMethods(Type type, ReflectType newType, ReflectAssembly newassembly, ReflectNamespace currNamespace)
        {
            foreach (var methodInfo in type.GetMethods())
            {
                // Finds or crates a new Type on this assembly
                Tuple <ReflectNamespace, ReflectAssembly> asmns = FindNamespaceAndAssembly(methodInfo.ReturnType);

                var newMethod =
                    new ReflectMethod()
                {
                    Name       = methodInfo.Name,
                    Parameters = new List <ReflectParameter>(),
                    Return     =
                        AddNewSimpleReflectType(methodInfo.ReturnType, asmns.Item2, asmns.Item1)
                };
                foreach (var parameterInfo in methodInfo.GetParameters())
                {
                    Tuple <ReflectNamespace, ReflectAssembly> asmns2 = FindNamespaceAndAssembly(parameterInfo.ParameterType);

                    newMethod.Parameters.Add(new ReflectParameter()
                    {
                        Name = parameterInfo.Name,
                        Type = AddNewSimpleReflectType(parameterInfo.ParameterType, asmns2.Item2, asmns2.Item1)
                    });
                }

                newType.Methods.Add(newMethod);
            }
        }
예제 #2
0
        static ObjectContext()
        {
            WellKnownContext = new ObjectContext();
            // 0 <==> null
            ulong index = 1;

            // essential type that must be shared by all serialized stream
            WellKnownContext.Register(index++, ReflectType.RObject);
            WellKnownContext.Register(index++, ReflectType.RString);
            WellKnownContext.Register(index++, ReflectType.RType);
            WellKnownContext.Register(index++, ReflectType.RReflectType);
            WellKnownContext.Register(index++, ReflectType.RNullable);
            // other well known values, to speed up read-write and reduce stream size
            WellKnownContext.Register(index++, "");
            WellKnownContext.Register(index++, ReflectType.GetType(typeof(byte[])));
            WellKnownContext.Register(index++, ReflectType.GetType(typeof(Guid)));
            WellKnownContext.Register(index++, ReflectType.GetType(typeof(bool)));
            WellKnownContext.Register(index++, ReflectType.GetType(typeof(char)));
            WellKnownContext.Register(index++, ReflectType.GetType(typeof(byte)));
            WellKnownContext.Register(index++, ReflectType.GetType(typeof(sbyte)));
            WellKnownContext.Register(index++, ReflectType.GetType(typeof(short)));
            WellKnownContext.Register(index++, ReflectType.GetType(typeof(ushort)));
            WellKnownContext.Register(index++, ReflectType.GetType(typeof(int)));
            WellKnownContext.Register(index++, ReflectType.GetType(typeof(uint)));
            WellKnownContext.Register(index++, ReflectType.GetType(typeof(long)));
            WellKnownContext.Register(index++, ReflectType.GetType(typeof(ulong)));
            WellKnownContext.Register(index++, ReflectType.GetType(typeof(float)));
            WellKnownContext.Register(index++, ReflectType.GetType(typeof(double)));
            WellKnownContext.Register(index++, ReflectType.GetType(typeof(decimal)));
        }
        private static void FillConstructors(Type type, ReflectType newType, ReflectAssembly newassembly, ReflectNamespace currNamespace)
        {
            foreach (var constructorInfo in type.GetConstructors())
            {
                var newMethod =
                    new ReflectMethod()
                {
                    Name       = constructorInfo.Name,
                    Parameters = new List <ReflectParameter>(),
                    Return     = null
                };

                foreach (var parameterInfo in constructorInfo.GetParameters())
                {
                    Tuple <ReflectNamespace, ReflectAssembly> asmns2 = FindNamespaceAndAssembly(parameterInfo.ParameterType);

                    newMethod.Parameters.Add(new ReflectParameter()
                    {
                        Name = parameterInfo.Name,
                        Type = AddNewSimpleReflectType(parameterInfo.ParameterType, asmns2.Item2, asmns2.Item1)
                    });
                }

                newType.Contructors.Add(newMethod);
            }
        }
예제 #4
0
        void WriteISerializable(ReflectType ots, object o)
        {
            if (o is Missing)
            {
                var m = (Missing)o;
                Writer.WriteVInt(m.Collection.Count);
                foreach (var item in m.Collection)
                {
                    Write(ReflectType.RString, (string)item.Item1);
                    Write(ReflectType.RObject, item.Item2);
                }
            }
            else
            {
#if __NETCORE__
                throw new PlatformNotSupportedException(".NETCore + ISerializable");
#elif !__PCL__
                var serial = (SRS.ISerializable)o;
                var info   = new SRS.SerializationInfo(typeof(object), new SRS.FormatterConverter());
                var ctx    = new SRS.StreamingContext(SRS.StreamingContextStates.Persistence);
                serial.GetObjectData(info, ctx);
                Writer.WriteVInt(info.MemberCount);
                foreach (var item in info)
                {
                    Write(ReflectType.RString, item.Name);
                    Write(ReflectType.RObject, item.Value);
                }
#endif
            }
        }
예제 #5
0
        string ToTypeName(ReflectType type)
        {
            var sb = new StringBuilder();

            ToTypeName(sb, type);
            return(sb.ToString());
        }
예제 #6
0
        object ReadConverter(ReflectType ts, ulong oid)
        {
#if __PCL__
            throw new PlatformNotSupportedException("PCL");
#else
            var s  = (string)Read(ReflectType.RString, null);
            var tc = ts.GetTypeConverter();
            if (tc != null)
            {
                var o = tc.ConvertFromInvariantString(s);
                if (oid > 0)
                {
                    Context.Register(oid, o);
                }
                return(o);
            }
            var missing = new Missing(ts);
            if (oid > 0)
            {
                Context.Register(oid, missing);
            }
            missing.ConverterString = s;
            return(missing);
#endif
        }
예제 #7
0
            public static ReflectType Create(Type t)
            {
                if (t.IsPrimitive)
                {
                    return(null);
                }

                if (t.IsEnum)
                {
                    return(null);
                }

                if (primitiveTypes.Contains(t))
                {
                    return(null);
                }

                ReflectType rt;

                if (lookup.TryGetValue(t, out rt) == false)
                {
                    rt        = new ReflectType();
                    rt.Fields = t.GetFields(BindingFlags.Public | BindingFlags.NonPublic | BindingFlags.Instance);

                    lookup.Add(t, rt);
                }

                return(rt);
            }
예제 #8
0
 void BegingSurrogate(ReflectType ots, object o)
 {
     for (int i = 0; i < currentSurrogates.Count; i++)
     {
         var t = currentSurrogates[i];
         if (t.Item2 == o)
         {
             throw new ArgumentException($"Failed to write object({o}) with surrogate({ots.Surrogate}), as it reference itself.");
         }
     }
     currentSurrogates.Add(Tuple.Create(ots, o));
 }
예제 #9
0
 internal Missing(ReflectType type)
 {
     this.Type = type;
     foreach (var m in type.RuntimeMembers)
     {
         var mm = new Member
         {
             Name = m.Name,
             Type = m.Type,
         };
         Members.Add(mm);
     }
 }
예제 #10
0
        /// <summary>
        /// Generates the C# class that can be used to deserialize all given types.
        /// </summary>
        /// <param name="namespace">The namespace of the generated class.</param>
        /// <param name="types">The types that will be rewritten with only the serialization information.</param>
        /// <returns>A generated C# code file as string.</returns>
        public static string GenerateCSharpCode(string @namespace, params Type[] types)
        {
            var ctxt = new ObjectContext();

            foreach (var t in types)
            {
                var rt = ReflectType.GetType(t);
                ctxt.RecursizeAdd(rt);
            }
            var sb = new StringBuilder(256);

            ctxt.GenerateCSharpCode(new StringWriter(sb), @namespace);
            return(sb.ToString());
        }
        private static void FillProperties(Type type, ReflectType newType, ReflectAssembly newassembly, ReflectNamespace currNamespace)
        {
            foreach (var propertyInfo in type.GetProperties())
            {
                // Finds or crates a new Type on this assembly
                Tuple <ReflectNamespace, ReflectAssembly> asmns = FindNamespaceAndAssembly(propertyInfo.PropertyType);

                newType.Properties.Add(new ReflectProperty()
                {
                    Name = propertyInfo.Name,
                    Type =
                        AddNewSimpleReflectType(propertyInfo.PropertyType, asmns.Item2, asmns.Item1)
                });
            }
        }
        private static void FillFields(Type type, ReflectType newType, ReflectAssembly newassembly, ReflectNamespace currNamespace)
        {
            foreach (var fieldInfo in type.GetFields())
            {
                // Finds or crates a new Type on this assembly
                Tuple <ReflectNamespace, ReflectAssembly> asmns = FindNamespaceAndAssembly(fieldInfo.FieldType);


                newType.Fields.Add(new ReflectField()
                {
                    Name = fieldInfo.Name,
                    Type =
                        AddNewSimpleReflectType(fieldInfo.FieldType, asmns.Item2, asmns.Item1)
                });
            }
        }
        private static ReflectType AddNewSimpleReflectType(Type type, ReflectAssembly newassembly, ReflectNamespace currNamespace)
        {
            var newType = new ReflectType()
            {
                Name        = type.Name,
                FullName    = type.FullName,
                Namespace   = currNamespace,
                Assembly    = newassembly,
                Contructors = new List <ReflectMethod>(),
                Methods     = new List <ReflectMethod>(),
                Fields      = new List <ReflectField>(),
                Properties  = new List <ReflectProperty>(),
                Events      = new List <ReflectEvent>(),
                CSharpName  = ToGenericTypeString(type)
            };

            return(newType);
        }
예제 #14
0
        static void Calculate(StringBuilder sb, String name, Object value, Int32 depth)
        {
            var rt = ReflectType.Create(value.GetType());

            if (rt == null)
            {
                sb.AppendLine(new String(' ', depth * 2) + name + ": " + value.ToString());
            }
            else
            {
                sb.AppendLine(new String(' ', depth * 2) + name);

                foreach (var field in rt.Fields)
                {
                    Calculate(sb, field.Name, field.GetValue(value), depth + 1);
                }
            }
        }
        private static void FillEvents(Type type, ReflectType newType)
        {
            foreach (var eventInfo in type.GetEvents())
            {
                // Finds or crates a new Type on this assembly
                Tuple <ReflectNamespace, ReflectAssembly> asmns = FindNamespaceAndAssembly(eventInfo.EventHandlerType);


                var newEvent = new ReflectEvent()
                {
                    Name = eventInfo.Name,
                    Type =
                        AddNewSimpleReflectType(eventInfo.EventHandlerType, asmns.Item2, asmns.Item1)
                };

                newType.Events.Add(newEvent);
            }
        }
예제 #16
0
        void ReadCollectionT <T>(ICollection <T> col, ReflectType tT)
        {
            var isRO = Reader.ReadBool();

            if (isRO)
            {
                return;
            }
            var count = (int)Reader.ReadVInt();

            for (int i = 0; i < count; i++)
            {
                var value = Read(tT, null);
                if (value is T && col != null)
                {
                    col.Add((T)value);
                }
            }
        }
예제 #17
0
        void ReadDictKV <K, V>(IDictionary <K, V> dict, ReflectType tKey, ReflectType tVal)
        {
            var isRO = Reader.ReadBool();

            if (isRO)
            {
                return;
            }
            var count = (int)Reader.ReadVInt();

            for (int i = 0; i < count; i++)
            {
                var key   = Read(tKey, null);
                var value = Read(tVal, null);
                if (key is K && value is V && dict != null)
                {
                    dict.Add((K)key, (V)value);
                }
            }
        }
예제 #18
0
        void WriteConverter(ReflectType ots, object value)
        {
            if (value is Missing)
            {
                var m = (Missing)value;
                Write(ReflectType.RString, m.ConverterString);
            }
            else
            {
#if !__PCL__
                var tc = ots.GetTypeConverter();
                if (tc == null)
                {
                    throw new InvalidOperationException("Failed to get converter.");
                }
                var s = tc.ConvertToInvariantString(value);
                Write(ReflectType.RString, s);
#endif
            }
        }
예제 #19
0
        void WriteCollection <T>(ICollection <T> list)
        {
            Writer.Write(list.IsReadOnly);
            if (list.IsReadOnly)
            {
                return;
            }
            var count = list.Count;

            Writer.WriteVInt(count);
            var surt = ReflectType.GetType(typeof(T));

            foreach (var item in list)
            {
                count--;
                Write(surt, item);
            }
            if (count != 0)
            {
                throw new ArgumentException($"({list}.Count reported an incorrect value ({list.Count})");
            }
        }
예제 #20
0
        void WriteDictionary <K, V>(IDictionary <K, V> list)
        {
            Writer.Write(list.IsReadOnly);
            if (list.IsReadOnly)
            {
                return;
            }
            var count = list.Count;

            Writer.WriteVInt(count);
            var surk = ReflectType.GetType(typeof(K));
            var surv = ReflectType.GetType(typeof(V));

            foreach (var kv in list)
            {
                count--;
                Write(surk, kv.Key);
                Write(surv, kv.Value);
            }
            if (count != 0)
            {
                throw new ArgumentException($"({list}.Count reported an incorrect value ({list.Count})");
            }
        }
예제 #21
0
        void RecursizeAdd(ReflectType type)
        {
            if (Contains(type))
            {
                return;
            }
            var id = NewId();

            Register(id, type);

            RecursizeAdd(type.Element);
            RecursizeAdd(type.Surrogate);
            RecursizeAdd(type.BaseType);
            RecursizeAdd(type.Collection1);
            RecursizeAdd(type.Collection2);
            foreach (var item in type.GenericArguments)
            {
                RecursizeAdd(item);
            }
            foreach (var item in type.Members)
            {
                RecursizeAdd(item.Type);
            }
        }
예제 #22
0
        internal object Read(ReflectType expected, object possibleValue)
        {
            object result;
            ulong  oid = 0;

            if (expected.IsReference)
            {
                oid = Reader.ReadVUInt();
                if (Context.TryGetObject(oid, out result))
                {
                    return(result);
                }
            }

            var actual = expected;

            if (!expected.IsFinal) // if expected type is not final then write actual type
            {
                actual = (ReflectType)Read(ReflectType.RReflectType, null);
            }

            object o = null;

            if (actual.IsIgnored)
            {
                o = null;
                if (oid > 0)
                {
                    Context.Register(oid, null);
                }
            }
            else if (actual == ReflectType.RReflectType)
            {
                var rt = new ReflectType();
                Context.Register(oid, rt);
                o = rt;
                rt.Read(this);
            }
            else if (actual == ReflectType.RType)
            {
                var rf = (ReflectType)Read(ReflectType.RReflectType, null);
                o = rf.Type;
                Context.Register(oid, o);
            }
            else if (actual.IsISerializable && !settings.IgnoreISerializable)
            {
                o = ReadISerializable(actual, oid, possibleValue);
            }
            else if (actual.HasConverter && !settings.IgnoreTypeConverter)
            {
                o = ReadConverter(actual, oid);
            }
            else if (actual.HasSurrogate)
            {
                o = ReadObject(actual.Surrogate, 0, null);
                object o2 = o;
                if (!(o is Missing) && !actual.TryGetOriginal(o, out o2))
                {
                    throw new InvalidOperationException("surrogate failure: couldn't get normal instance");
                }
                if (oid != 0)
                {
                    Context.Register(oid, o2);
                }
                o = o2;
            }
            else
            {
                o = ReadObject(actual, oid, possibleValue);
            }
            // since value types are not saved in the context, awake them now!
            if (oid == 0)
            {
                if (o is IDeserialized)
                {
                    ((IDeserialized)o).Deserialized();
                }
#if !__PCL__ && !__NETCORE__
                if (o is SRS.IDeserializationCallback)
                {
                    ((SRS.IDeserializationCallback)o).OnDeserialization(null);
                }
#endif
            }
            return(o);
        }
예제 #23
0
 void ToTypeName(StringBuilder sb, ReflectType type)
 {
     if (type.IsArray)
     {
         ToTypeName(sb, type.Element);
         for (int i = 1; i < type.ArrayRank; i++)
         {
             sb.Append(',');
         }
         sb.Append(']');
     }
     else if (type.IsPointer)
     {
         ToTypeName(sb, type.Element);
         sb.Append('*');
     }
     else if (type.IsGenericParameter)
     {
         sb.Append('T').Append(type.GenericParameterIndex + 1);
     }
     else if (type.Kind == PrimitiveType.Object)
     {
         if (type.IsGeneric)
         {
             if (type.IsGenericTypeDefinition)
             {
                 if (type.FastType != null && type.FastType.IsMscorlib)
                 {
                     var sm = 0;
                     var gm = type.TypeName.LastIndexOf('`');
                     if (type.TypeName.StartsWith("System.ComponentModel."))
                     {
                         sm = "System.ComponentModel.".Length;
                     }
                     else if (type.TypeName.StartsWith("System.Collections.Generic."))
                     {
                         sm = "System.Collections.Generic.".Length;
                     }
                     else if (type.TypeName.StartsWith("System.Collections."))
                     {
                         sm = "System.Collections.".Length;
                     }
                     sb.Append(type.TypeName.Substring(sm, gm - sm));
                 }
                 else
                 {
                     sb.Append("Type").Append(objectsToIds[type]);
                 }
             }
             else
             {
                 ToTypeName(sb, type.Element);
                 sb.Append('<');
                 for (int i = 0; i < type.GenericArguments.Count; i++)
                 {
                     if (i > 0)
                     {
                         sb.Append(",");
                     }
                     ToTypeName(sb, type.GenericArguments[i]);
                 }
                 sb.Append('>');
             }
         }
         else
         {
             if (type.Type != null && type.Type == typeof(object))
             {
                 sb.Append("object");
             }
             else if (type.FastType != null && type.FastType.IsMscorlib)
             {
                 sb.Append(type.TypeName);
             }
             else
             {
                 sb.Append("Type").Append(objectsToIds[type]);
             }
         }
     }
     else
     {
         sb.Append(type.ToString());
     }
 }
예제 #24
0
        internal void Write(ReflectType expected, object o)
        {
            // 1st write the ID of the object, return if already written
            if (expected.IsReference)
            {
                ulong oid;
                var   isKnown = Context.TryGetId(o, out oid);
                if (!isKnown)
                {
                    oid = Context.NewId();
                    Context.Register(oid, o);
                }
                Writer.WriteVInt(oid);
                if (isKnown)
                {
                    return;
                }
            }

            // 2nd write class info, **if needed**
            var ots = expected;

            if (!expected.IsFinal)
            {
                ots = ReflectType.GetType(o);
                Write(ReflectType.RReflectType, ots);
            }

            // finally write the item
            if (ots.IsIgnored)
            {
                // nothing!
            }
            else if (ots == ReflectType.RReflectType)
            {
                ((ReflectType)o).Write(this);
            }
            else if (ots == ReflectType.RType)
            {
                var rf = ReflectType.GetType((Type)o);
                Write(ReflectType.RReflectType, rf);
            }
            else if (ots.IsISerializable && !settings.IgnoreISerializable)
            {
                WriteISerializable(ots, o);
            }
            else if (ots.HasConverter && !settings.IgnoreTypeConverter)
            {
                WriteConverter(ots, o);
            }
            else if (ots.HasSurrogate)
            {
                BegingSurrogate(ots, o);
                try
                {
                    object o2;
                    if (!ots.TryGetSurrogate(o, out o2))
                    {
                        throw new InvalidOperationException("surrogate failure: couldn't get surrogate instance");
                    }
                    WriteObject(ots.Surrogate, o2);
                }
                finally { EndSurrogate(); }
            }
            else
            {
                WriteObject(ots, o);
            }
        }
예제 #25
0
        void GenerateCSharpCode(TextWriter w, ReflectType type, ReflectType isSurrogateFor = null)
        {
            if (type.HasConverter && type.IsGeneric) // TODO: IsGeneric only... because not sure...
            {
                w.WriteLine($"\tpublic class {ToCSharp(type.TypeName)}Converter : TypeConverter {{");
                w.WriteLine("\t\t// TODO ...");
                w.WriteLine("\t}");
                w.WriteLine($"\t[TypeConverter({ToCSharp(type.TypeName)}Converter)]");
            }
            w.WriteLine($"\t[{nameof(SerializationNameAttribute)}({ToCSharp(type.TypeName)}, {ToCSharp(type.AssemblyName)})]");
            if (type.IsEnum)
            {
                w.WriteLine($"\tpublic enum Type{objectsToIds[type]} : {type.Element}");
                w.WriteLine("\t{");
                w.WriteLine("\t\t// TODO: Values need be entered manually ...");
                w.WriteLine("\t}");
            }
            else
            {
                w.Write("\tpublic ");
                w.Write(type.IsReference ? "class " : "struct ");
                w.Write(ToTypeName(type));
                if (type.IsGenericTypeDefinition)
                {
                    w.Write("<");
                    int N = type.GenericArguments.Count;
                    for (int i = 0; i < N; i++)
                    {
                        if (i > 0)
                        {
                            w.Write(",");
                        }
                        w.Write("T");
                        w.Write(i + 1);
                    }
                    w.Write(">");
                }
            }
            int    interface_count = 0;
            Action addInterface    = () =>
            {
                if (interface_count == 0)
                {
                    interface_count = 1;
                    w.Write(" : ");
                }
                else
                {
                    interface_count++;
                    w.Write(", ");
                }
            };

            if (type.BaseType != null && type.BaseType != ReflectType.RObject)
            {
                addInterface();
                w.Write(ToTypeName(type.BaseType));
            }
            if (isSurrogateFor != null)
            {
                addInterface();
                w.WriteLine($"ISurrogate<{ToTypeName(isSurrogateFor)}>");
            }
            if (type.IsISerializable)
            {
                addInterface();
                w.Write("ISerializable");
            }
            switch (type.CollectionType)
            {
            case ReflectCollectionType.IList:
                addInterface();
                w.Write("Ilist");
                break;

            case ReflectCollectionType.ICollectionT:
                addInterface();
                w.Write($"ICollection<{ToTypeName(type.Collection1)}>");
                break;

            case ReflectCollectionType.IDictionary:
                addInterface();
                w.Write("IDictionary");
                break;

            case ReflectCollectionType.IDictionaryKV:
                addInterface();
                w.Write($"IDictionary<{ToTypeName(type.Collection1)}, {ToTypeName(type.Collection2)}>");
                break;
            }
            w.WriteLine();
            w.WriteLine("\t{");
            w.WriteLine($"\t\tpublic Type{objectsToIds[type]}() {{ }}");
            if (type.IsISerializable)
            {
                w.WriteLine($"\t\tType{objectsToIds[type]}(SerializationInfo info, StreamingContext context) {{ throw new NotImplementedException(\"TODO\"); }}");
                w.WriteLine("\t\tvoid ISerializable.GetObjectData(SerializationInfo info, StreamingContext context) { throw new NotImplementedException(\"TODO\"); }");
            }
            if (isSurrogateFor != null)
            {
                w.WriteLine($"\t\tvoid Initialize({ToTypeName(isSurrogateFor)} value) {{ throw new NotImplementedException(\"TODO\"); }}");
                w.WriteLine($"\t\t{ToTypeName(isSurrogateFor)} Instantiate() {{ throw new NotImplementedException(\"TODO\"); }}");
            }
            foreach (var m in type.Members)
            {
                w.Write("\t\tpublic ");
                w.Write(ToTypeName(m.Type));
                w.Write(' ');
                w.Write(m.Name);
                w.Write(" { get; set; }");
                w.WriteLine();
            }
            w.WriteLine("\t}");
            if (type.Surrogate != null)
            {
                GenerateCSharpCode(w, type.Surrogate, type);
            }
        }
예제 #26
0
        void WriteObject(ReflectType ts, object o)
        {
            switch (ts.Kind)
            {
            default:
            case PrimitiveType.Object:
                if (ts.IsArray)
                {
                    var aa = (Array)o;
                    if (aa.Rank != ts.ArrayRank)
                    {
                        throw new ArgumentException($"{aa} Rank is {aa.Rank} instead of expected {ts.ArrayRank}");
                    }
                    for (int i = 0; i < ts.ArrayRank; i++)
                    {
                        Writer.WriteVInt(aa.GetLength(i));
                    }
                    foreach (var item in aa)
                    {
                        Write(ts.Element, item);
                    }
                }
                else if (ts.IsNullable)
                {
                    if (o == null)
                    {
                        Writer.Write(false);
                    }
                    else
                    {
                        Writer.Write(true);
                        Write(ts.GenericArguments[0], o);
                    }
                }
                else if (ts.IsEnum)
                {
                    // TODO: Missing for Enum
                    WriteObject(ts.Element, o);
                }
                else
                {
                    if (o is Missing)
                    {
                        var miss = (Missing)o;
                        foreach (var f in miss.Members)
                        {
                            Write(f.Type, f.Value);
                        }
                        var colt = ts.CollectionInterface;
                        switch (colt.CollectionType)
                        {
                        case ReflectCollectionType.IList:
                        case ReflectCollectionType.ICollectionT:
                            Writer.WriteVInt(miss.Collection.Count);
                            var coll = colt.Collection1 ?? ReflectType.RObject;
                            foreach (var item in miss.Collection)
                            {
                                Write(coll, item.Item1);
                            }
                            break;

                        case ReflectCollectionType.IDictionary:
                        case ReflectCollectionType.IDictionaryKV:
                            Writer.WriteVInt(miss.Collection.Count);
                            var coll1 = colt.Collection1 ?? ReflectType.RObject;
                            var coll2 = colt.Collection2 ?? ReflectType.RObject;
                            foreach (var item in miss.Collection)
                            {
                                Write(coll1, item.Item1);
                                Write(coll2, item.Item2);
                            }
                            break;
                        }
                    }
                    else
                    {
                        foreach (var m in ts.RuntimeMembers)
                        {
                            var p = m.RuntimeMember.GetValue(o);
                            Write(m.Type, p);
                        }

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

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

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

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

            case PrimitiveType.String:
                Writer.Write((string)o);
                break;

            case PrimitiveType.Bytes:
                Writer.Write((byte[])o);
                break;

            case PrimitiveType.Guid:
                Writer.Write((Guid)o);
                break;

            case PrimitiveType.Bool:
                Writer.Write((bool)o);
                break;

            case PrimitiveType.Char:
                Writer.Write((char)o);
                break;

            case PrimitiveType.Byte:
                Writer.Write((byte)o);
                break;

            case PrimitiveType.SByte:
                Writer.Write((sbyte)o);
                break;

            case PrimitiveType.Int16:
                Writer.Write((short)o);
                break;

            case PrimitiveType.UInt16:
                Writer.Write((ushort)o);
                break;

            case PrimitiveType.Int32:
                Writer.Write((int)o);
                break;

            case PrimitiveType.UInt32:
                Writer.Write((uint)o);
                break;

            case PrimitiveType.Int64:
                Writer.Write((long)o);
                break;

            case PrimitiveType.UInt64:
                Writer.Write((ulong)o);
                break;

            case PrimitiveType.Single:
                Writer.Write((float)o);
                break;

            case PrimitiveType.Double:
                Writer.Write((double)o);
                break;

            case PrimitiveType.Decimal:
                Writer.Write((decimal)o);
                break;
            }
        }
예제 #27
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
        }
예제 #28
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()));
            }
        }